tizen 2.3.1 release submit/tizen_2.3.1/20150915.083008 tizen_2.3.1_release
authorjk7744.park <jk7744.park@samsung.com>
Tue, 8 Sep 2015 13:48:57 +0000 (22:48 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Tue, 8 Sep 2015 13:48:57 +0000 (22:48 +0900)
641 files changed:
AUTHORS
COPYING
COPYING.Zlib [new file with mode: 0644]
ChangeLog
Makefile.am
NEWS
README
configure.ac
data/Makefile.am [new file with mode: 0644]
data/checkme [new file with mode: 0644]
debian/changelog [deleted file]
debian/compat [deleted file]
debian/control [deleted file]
debian/copyright [deleted file]
debian/jobs [deleted file]
debian/libevas-dev.install [deleted file]
debian/libevas-doc.dirs [deleted file]
debian/libevas-doc.doc-base [deleted file]
debian/libevas-engines-extras.install [deleted file]
debian/libevas-engines-extras.install.default [deleted file]
debian/libevas-engines-extras.install.i386 [deleted file]
debian/libevas-engines.install [deleted file]
debian/libevas.install [deleted file]
debian/libevas.shlibs [deleted file]
debian/rules [deleted file]
doc/Doxyfile.in
doc/e.css
doc/evas_examples.dox [moved from doc/examples.dox with 99% similarity]
evas-software-16-wince.pc.in [deleted file]
evas-software-16-x11.pc.in [deleted file]
evas.manifest [new file with mode: 0644]
evas.spec.in
m4/evas_check_engine.m4
m4/evas_check_loader.m4
packaging/evas.spec
src/Makefile.am
src/benchmarks/evas/.gitignore [new file with mode: 0644]
src/benchmarks/evas/Makefile.am [new file with mode: 0644]
src/benchmarks/evas/evas_bench.c [new file with mode: 0644]
src/benchmarks/evas/evas_bench.h [new file with mode: 0644]
src/benchmarks/evas/evas_bench_loader.c [new file with mode: 0644]
src/benchmarks/evas/evas_bench_saver.c [new file with mode: 0644]
src/benchmarks/evas/images/Light-50.tgv [new file with mode: 0644]
src/benchmarks/evas/images/Pic1-50.tgv [new file with mode: 0644]
src/benchmarks/evas/images/Sunrise-100.tgv [new file with mode: 0644]
src/benchmarks/evas/images/mars_rover_panorama_half-size.jpg [new file with mode: 0644]
src/bin/Makefile.am
src/bin/evas_cserve2.h
src/bin/evas_cserve2_cache.c
src/bin/evas_cserve2_fonts.c
src/bin/evas_cserve2_main.c
src/bin/evas_cserve2_slave.c
src/bin/loaders/Makefile.am
src/bin/loaders/bmp/Makefile.am
src/bin/loaders/eet/Makefile.am
src/bin/loaders/ico/Makefile.am
src/bin/loaders/jpeg/Makefile.am
src/bin/loaders/pmaps/Makefile.am
src/bin/loaders/png/Makefile.am
src/bin/loaders/psd/Makefile.am
src/bin/loaders/tga/Makefile.am
src/bin/loaders/tiff/Makefile.am
src/bin/loaders/wbmp/Makefile.am
src/bin/loaders/webp/Makefile.am [new file with mode: 0644]
src/bin/loaders/webp/evas_image_load_webp.c [new file with mode: 0644]
src/bin/loaders/xpm/Makefile.am
src/bin/loaders/xpm/evas_image_load_xpm.c
src/examples/Makefile.am
src/examples/evas-aspect-hints.c [changed mode: 0644->0755]
src/examples/evas-smart-object.c
src/lib/Evas.h [changed mode: 0644->0755]
src/lib/Evas_GL.h [changed mode: 0644->0755]
src/lib/Evas_GL_GLES1_Helpers.h [new file with mode: 0644]
src/lib/Evas_GL_GLES2_Helpers.h [new file with mode: 0644]
src/lib/Makefile.am
src/lib/cache/Makefile.am
src/lib/cache/evas_cache_engine_image.c
src/lib/cache/evas_cache_image.c
src/lib/cache/evas_preload.c
src/lib/cache2/Makefile.am
src/lib/canvas/Makefile.am
src/lib/canvas/evas_async_events.c
src/lib/canvas/evas_callbacks.c
src/lib/canvas/evas_clip.c
src/lib/canvas/evas_device.c [new file with mode: 0644]
src/lib/canvas/evas_events.c [changed mode: 0644->0755]
src/lib/canvas/evas_font_dir.c
src/lib/canvas/evas_gl.c [changed mode: 0644->0755]
src/lib/canvas/evas_key_grab.c
src/lib/canvas/evas_layer.c
src/lib/canvas/evas_main.c
src/lib/canvas/evas_map.c
src/lib/canvas/evas_object_box.c
src/lib/canvas/evas_object_image.c
src/lib/canvas/evas_object_inform.c
src/lib/canvas/evas_object_line.c
src/lib/canvas/evas_object_main.c
src/lib/canvas/evas_object_polygon.c
src/lib/canvas/evas_object_rectangle.c
src/lib/canvas/evas_object_smart.c
src/lib/canvas/evas_object_table.c
src/lib/canvas/evas_object_text.c [changed mode: 0644->0755]
src/lib/canvas/evas_object_textblock.c [changed mode: 0644->0755]
src/lib/canvas/evas_object_textgrid.c
src/lib/canvas/evas_render.c [changed mode: 0644->0755]
src/lib/canvas/evas_smart.c
src/lib/canvas/evas_stack.c
src/lib/cserve/Makefile.am
src/lib/cserve2/Makefile.am
src/lib/cserve2/evas_cs2_client.c
src/lib/engines/Makefile.am
src/lib/engines/common/Makefile.am
src/lib/engines/common/evas_alpha_main.c [new file with mode: 0644]
src/lib/engines/common/evas_blend_private.h
src/lib/engines/common/evas_convert_color.c
src/lib/engines/common/evas_convert_color.h
src/lib/engines/common/evas_convert_colorspace.c
src/lib/engines/common/evas_convert_main.c
src/lib/engines/common/evas_convert_rgb_24.c
src/lib/engines/common/evas_convert_rgb_32.c
src/lib/engines/common/evas_cpu.c
src/lib/engines/common/evas_draw_main.c
src/lib/engines/common/evas_font.h
src/lib/engines/common/evas_font_compress.c [new file with mode: 0644]
src/lib/engines/common/evas_font_compress_draw.c [new file with mode: 0644]
src/lib/engines/common/evas_font_default_walk.x
src/lib/engines/common/evas_font_draw.c
src/lib/engines/common/evas_font_load.c [changed mode: 0644->0755]
src/lib/engines/common/evas_font_main.c
src/lib/engines/common/evas_font_ot.c
src/lib/engines/common/evas_font_private.h
src/lib/engines/common/evas_font_query.c
src/lib/engines/common/evas_image.h
src/lib/engines/common/evas_image_data.c
src/lib/engines/common/evas_image_load.c
src/lib/engines/common/evas_image_main.c
src/lib/engines/common/evas_image_save.c
src/lib/engines/common/evas_image_scalecache.c
src/lib/engines/common/evas_line_main.c
src/lib/engines/common/evas_map_image.c
src/lib/engines/common/evas_map_image_core.c
src/lib/engines/common/evas_map_image_internal.c
src/lib/engines/common/evas_map_image_loop.c
src/lib/engines/common/evas_op_blend/Makefile.am
src/lib/engines/common/evas_op_blend/op_blend_mask_color_.c
src/lib/engines/common/evas_op_blend/op_blend_mask_color_neon.c [changed mode: 0644->0755]
src/lib/engines/common/evas_op_blend/op_blend_pixel_color_neon.c
src/lib/engines/common/evas_op_blend/op_blend_pixel_mask_.c
src/lib/engines/common/evas_op_blend/op_blend_pixel_mask_i386.c
src/lib/engines/common/evas_op_blend/op_blend_pixel_mask_neon.c
src/lib/engines/common/evas_op_blend/op_blend_pixel_mask_sse3.c
src/lib/engines/common/evas_op_blend/op_blend_pixel_neon.c
src/lib/engines/common/evas_pipe.c
src/lib/engines/common/evas_pipe.h
src/lib/engines/common/evas_polygon_main.c
src/lib/engines/common/evas_rectangle.h
src/lib/engines/common/evas_rectangle_main.c
src/lib/engines/common/evas_scale_main.c
src/lib/engines/common/evas_scale_main.h
src/lib/engines/common/evas_scale_sample.c
src/lib/engines/common/evas_scale_smooth.c
src/lib/engines/common/evas_scale_smooth_scaler.c
src/lib/engines/common/evas_scale_smooth_scaler_down.c
src/lib/engines/common/evas_scale_smooth_scaler_downx.c
src/lib/engines/common/evas_scale_smooth_scaler_downx_downy.c
src/lib/engines/common/evas_scale_smooth_scaler_downy.c
src/lib/engines/common/evas_scale_smooth_scaler_noscale.c [deleted file]
src/lib/engines/common/evas_scale_smooth_scaler_up.c
src/lib/engines/common/evas_text_utils.c
src/lib/engines/common/evas_text_utils.h
src/lib/engines/common/evas_tiler.c [changed mode: 0644->0755]
src/lib/engines/common/language/evas_bidi_utils.c
src/lib/engines/common/language/evas_bidi_utils.h
src/lib/engines/common_16/Makefile.am [deleted file]
src/lib/engines/common_16/evas_soft16_dither_mask.c [deleted file]
src/lib/engines/common_16/evas_soft16_font.c [deleted file]
src/lib/engines/common_16/evas_soft16_image_scaled_sampled.c [deleted file]
src/lib/engines/common_16/evas_soft16_image_unscaled.c [deleted file]
src/lib/engines/common_16/evas_soft16_line.c [deleted file]
src/lib/engines/common_16/evas_soft16_main.c [deleted file]
src/lib/engines/common_16/evas_soft16_point_blend.c [deleted file]
src/lib/engines/common_16/evas_soft16_polygon.c [deleted file]
src/lib/engines/common_16/evas_soft16_rectangle.c [deleted file]
src/lib/engines/common_16/evas_soft16_scanline_blend.c [deleted file]
src/lib/engines/common_16/evas_soft16_scanline_fill.c [deleted file]
src/lib/engines/common_8/Makefile.am
src/lib/file/Makefile.am
src/lib/file/evas_module.c [changed mode: 0644->0755]
src/lib/filters/Makefile.am [new file with mode: 0644]
src/lib/filters/blur/blur_box_alpha_.c [new file with mode: 0644]
src/lib/filters/blur/blur_box_alpha_i386.c [new file with mode: 0644]
src/lib/filters/blur/blur_box_alpha_neon.c [new file with mode: 0644]
src/lib/filters/blur/blur_box_alpha_sse3.c [new file with mode: 0644]
src/lib/filters/blur/blur_box_rgba_.c [new file with mode: 0644]
src/lib/filters/blur/blur_box_rgba_i386.c [new file with mode: 0644]
src/lib/filters/blur/blur_box_rgba_neon.c [new file with mode: 0644]
src/lib/filters/blur/blur_box_rgba_sse3.c [new file with mode: 0644]
src/lib/filters/blur/blur_gaussian_alpha_.c [new file with mode: 0644]
src/lib/filters/blur/blur_gaussian_rgba_.c [new file with mode: 0644]
src/lib/filters/evas_filter.c [new file with mode: 0644]
src/lib/filters/evas_filter_blend.c [new file with mode: 0644]
src/lib/filters/evas_filter_blur.c [new file with mode: 0644]
src/lib/filters/evas_filter_bump.c [new file with mode: 0644]
src/lib/filters/evas_filter_curve.c [new file with mode: 0644]
src/lib/filters/evas_filter_displace.c [new file with mode: 0644]
src/lib/filters/evas_filter_mask.c [new file with mode: 0644]
src/lib/filters/evas_filter_parser.c [new file with mode: 0644]
src/lib/filters/evas_filter_private.h [new file with mode: 0644]
src/lib/filters/evas_filter_tizen_compat.h [new file with mode: 0644]
src/lib/filters/evas_filter_transform.c [new file with mode: 0644]
src/lib/filters/evas_filter_utils.c [new file with mode: 0644]
src/lib/include/Makefile.am
src/lib/include/evas_blend_ops.h
src/lib/include/evas_common.h
src/lib/include/evas_filter.h [new file with mode: 0644]
src/lib/include/evas_inline.x
src/lib/include/evas_private.h [changed mode: 0644->0755]
src/lib/main.c
src/modules/engines/Makefile.am
src/modules/engines/buffer/Evas_Engine_Buffer.h
src/modules/engines/buffer/Makefile.am
src/modules/engines/buffer/evas_outbuf.c
src/modules/engines/direct3d/Makefile.am
src/modules/engines/directfb/Makefile.am
src/modules/engines/fb/Makefile.am
src/modules/engines/fb/evas_engine.c
src/modules/engines/fb/evas_fb_main.c
src/modules/engines/gl_cocoa/Makefile.am
src/modules/engines/gl_cocoa/evas_engine.c [changed mode: 0644->0755]
src/modules/engines/gl_common/Makefile.am
src/modules/engines/gl_common/evas_gl_api.c [new file with mode: 0755]
src/modules/engines/gl_common/evas_gl_api_ext.c [new file with mode: 0755]
src/modules/engines/gl_common/evas_gl_api_ext.h [new file with mode: 0644]
src/modules/engines/gl_common/evas_gl_api_ext_def.h [new file with mode: 0644]
src/modules/engines/gl_common/evas_gl_api_gles1.c [new file with mode: 0644]
src/modules/engines/gl_common/evas_gl_common.h [changed mode: 0644->0755]
src/modules/engines/gl_common/evas_gl_context.c [changed mode: 0644->0755]
src/modules/engines/gl_common/evas_gl_core.c [changed mode: 0644->0755]
src/modules/engines/gl_common/evas_gl_core.h [changed mode: 0644->0755]
src/modules/engines/gl_common/evas_gl_core_private.h [new file with mode: 0755]
src/modules/engines/gl_common/evas_gl_file_cache.c [new file with mode: 0644]
src/modules/engines/gl_common/evas_gl_font.c
src/modules/engines/gl_common/evas_gl_image.c [changed mode: 0644->0755]
src/modules/engines/gl_common/evas_gl_line.c
src/modules/engines/gl_common/evas_gl_polygon.c
src/modules/engines/gl_common/evas_gl_rectangle.c
src/modules/engines/gl_common/evas_gl_shader.c [changed mode: 0644->0755]
src/modules/engines/gl_common/evas_gl_texture.c [changed mode: 0644->0755]
src/modules/engines/gl_common/shader/compile-s3c6410.sh [deleted file]
src/modules/engines/gl_common/shader/compile-sgx.sh [deleted file]
src/modules/engines/gl_common/shader/compile.sh [new file with mode: 0755]
src/modules/engines/gl_common/shader/font_frag_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/font_frag_s3c6410.asm [deleted file]
src/modules/engines/gl_common/shader/font_mask_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/font_mask_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/font_mask_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/font_mask_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/font_vert_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/img_12_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_bgra_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_bgra_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_bgra_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_bgra_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_bgra_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_bgra_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_bgra_nomul_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_bgra_nomul_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_bgra_nomul_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_bgra_nomul_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_bgra_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_bgra_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_bgra_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_bgra_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_bgra_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_bgra_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_nomul_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_nomul_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_nomul_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_nomul_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_12_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_bgra_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_bgra_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_bgra_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_bgra_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_bgra_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_bgra_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_bgra_nomul_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_bgra_nomul_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_bgra_nomul_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_bgra_nomul_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_bgra_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_bgra_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_bgra_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_bgra_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_bgra_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_bgra_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_nomul_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_nomul_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_nomul_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_nomul_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_21_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_bgra_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_bgra_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_bgra_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_bgra_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_bgra_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_bgra_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_bgra_nomul_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_bgra_nomul_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_bgra_nomul_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_bgra_nomul_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_bgra_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_bgra_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_bgra_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_bgra_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_bgra_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_bgra_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_nomul_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_nomul_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_nomul_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_nomul_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_22_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_bgra_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_bgra_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_bgra_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_bgra_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_bgra_frag_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/img_bgra_nomul_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_bgra_nomul_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_bgra_nomul_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_bgra_nomul_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_bgra_nomul_frag_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/img_bgra_nomul_vert_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/img_bgra_vert_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/img_frag_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/img_frag_s3c6410.asm [deleted file]
src/modules/engines/gl_common/shader/img_map_mask_bgra_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_map_mask_bgra_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_mask_bgra_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_mask_bgra_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_mask_bgra_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_mask_bgra_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_mask_bgra_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_mask_bgra_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_mask_bgra_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_mask_bgra_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_mask_frag.h
src/modules/engines/gl_common/shader/img_mask_frag.shd
src/modules/engines/gl_common/shader/img_mask_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_mask_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_mask_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_mask_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_mask_vert.h
src/modules/engines/gl_common/shader/img_mask_vert.shd
src/modules/engines/gl_common/shader/img_nomul_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_nomul_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_nomul_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_nomul_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/img_nomul_frag_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/img_nomul_vert_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/img_vert_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/make-c-bin.sh [deleted file]
src/modules/engines/gl_common/shader/map_mask_bgra_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/map_mask_bgra_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/map_mask_bgra_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/map_mask_bgra_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/map_mask_bgra_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/map_mask_bgra_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/map_mask_bgra_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/map_mask_bgra_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/map_mask_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/map_mask_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/map_mask_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/map_mask_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/map_mask_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/map_mask_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/map_mask_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/map_mask_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/nv12_mask_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/nv12_mask_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/nv12_mask_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/nv12_mask_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/rect_frag_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/rect_frag_s3c6410.asm [deleted file]
src/modules/engines/gl_common/shader/rect_mask_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/rect_mask_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/rect_mask_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/rect_mask_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/rect_vert_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/rgb_a_pair_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/rgb_a_pair_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/rgb_a_pair_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/rgb_a_pair_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/rgb_a_pair_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/rgb_a_pair_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/rgb_a_pair_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/rgb_a_pair_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_12_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_12_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_12_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_12_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_12_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_12_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_12_nomul_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_12_nomul_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_12_nomul_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_12_nomul_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_12_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_12_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_12_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_12_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_12_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_12_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_21_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_21_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_21_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_21_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_21_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_21_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_21_nomul_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_21_nomul_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_21_nomul_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_21_nomul_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_21_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_21_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_21_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_21_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_21_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_21_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_22_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_22_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_22_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_22_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_22_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_22_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_22_nomul_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_22_nomul_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_22_nomul_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_22_nomul_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_22_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_22_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_22_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_22_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_22_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_22_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_frag_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/tex_frag_s3c6410.asm [deleted file]
src/modules/engines/gl_common/shader/tex_nomul_afill_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_nomul_afill_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_nomul_afill_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_nomul_afill_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_nomul_frag_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/tex_nomul_vert_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/tex_rgb_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_rgb_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tex_vert_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/tizen_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tizen_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tizen_mask_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tizen_mask_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tizen_mask_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tizen_mask_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tizen_mask_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tizen_mask_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tizen_mask_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tizen_mask_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tizen_nomul_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tizen_nomul_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tizen_nomul_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tizen_nomul_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/tizen_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/tizen_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/yuv_frag_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/yuv_frag_s3c6410.asm [deleted file]
src/modules/engines/gl_common/shader/yuv_mask_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/yuv_mask_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/yuv_mask_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/yuv_mask_vert.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/yuv_nomul_frag_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/yuv_nomul_vert_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/yuv_vert_bin_s3c6410.h [deleted file]
src/modules/engines/gl_common/shader/yuy2_mask_frag.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/yuy2_mask_frag.shd [new file with mode: 0644]
src/modules/engines/gl_common/shader/yuy2_mask_vert.h [new file with mode: 0644]
src/modules/engines/gl_common/shader/yuy2_mask_vert.shd [new file with mode: 0644]
src/modules/engines/gl_sdl/Makefile.am
src/modules/engines/gl_sdl/evas_engine.c [changed mode: 0644->0755]
src/modules/engines/gl_sdl/evas_engine.h
src/modules/engines/gl_x11/Evas_Engine_GL_X11.h [changed mode: 0644->0755]
src/modules/engines/gl_x11/Makefile.am
src/modules/engines/gl_x11/evas_engine.c
src/modules/engines/gl_x11/evas_engine.h [changed mode: 0644->0755]
src/modules/engines/gl_x11/evas_x_main.c [changed mode: 0644->0755]
src/modules/engines/psl1ght/Makefile.am
src/modules/engines/software_16/Makefile.am [deleted file]
src/modules/engines/software_16/evas_engine.c [deleted file]
src/modules/engines/software_16_sdl/Evas_Engine_SDL_16.h [deleted file]
src/modules/engines/software_16_sdl/Makefile.am [deleted file]
src/modules/engines/software_16_sdl/evas_engine.c [deleted file]
src/modules/engines/software_16_sdl/evas_engine.h [deleted file]
src/modules/engines/software_16_wince/Evas_Engine_Software_16_WinCE.h [deleted file]
src/modules/engines/software_16_wince/Makefile.am [deleted file]
src/modules/engines/software_16_wince/evas_engine.c [deleted file]
src/modules/engines/software_16_wince/evas_engine.h [deleted file]
src/modules/engines/software_16_wince/evas_wince_ddraw_buffer.cpp [deleted file]
src/modules/engines/software_16_wince/evas_wince_fb_buffer.c [deleted file]
src/modules/engines/software_16_wince/evas_wince_gapi_buffer.c [deleted file]
src/modules/engines/software_16_wince/evas_wince_gdi_buffer.c [deleted file]
src/modules/engines/software_16_x11/Makefile.am
src/modules/engines/software_16_x11/evas_engine.c
src/modules/engines/software_8/Makefile.am
src/modules/engines/software_8_x11/Makefile.am
src/modules/engines/software_ddraw/Makefile.am
src/modules/engines/software_gdi/Makefile.am
src/modules/engines/software_generic/Makefile.am
src/modules/engines/software_generic/evas_engine.c [changed mode: 0644->0755]
src/modules/engines/software_x11/Evas_Engine_Software_X11.h
src/modules/engines/software_x11/Makefile.am
src/modules/engines/software_x11/evas_engine.c [changed mode: 0644->0755]
src/modules/engines/software_x11/evas_engine.h [changed mode: 0644->0755]
src/modules/engines/software_x11/evas_native_buffer.c [new file with mode: 0755]
src/modules/engines/software_x11/evas_native_tbm.c [new file with mode: 0755]
src/modules/engines/software_x11/evas_x_egl.c [new file with mode: 0755]
src/modules/engines/software_x11/evas_x_egl.h [new file with mode: 0644]
src/modules/engines/software_x11/evas_xcb_color.c
src/modules/engines/software_x11/evas_xcb_outbuf.c
src/modules/engines/software_x11/evas_xlib_buffer.c
src/modules/engines/software_x11/evas_xlib_color.c
src/modules/engines/software_x11/evas_xlib_image.c [new file with mode: 0644]
src/modules/engines/software_x11/evas_xlib_image.h [new file with mode: 0644]
src/modules/engines/software_x11/evas_xlib_outbuf.c
src/modules/engines/software_x11/evas_xlib_swapbuf.c [new file with mode: 0755]
src/modules/engines/software_x11/evas_xlib_swapbuf.h [new file with mode: 0644]
src/modules/engines/software_x11/evas_xlib_swapper.c [new file with mode: 0755]
src/modules/engines/software_x11/evas_xlib_swapper.h [new file with mode: 0755]
src/modules/engines/wayland_egl/Evas_Engine_Wayland_Egl.h
src/modules/engines/wayland_egl/Makefile.am
src/modules/engines/wayland_egl/evas_engine.c [changed mode: 0644->0755]
src/modules/engines/wayland_egl/evas_wl_main.c [changed mode: 0644->0755]
src/modules/engines/wayland_shm/Evas_Engine_Wayland_Shm.h
src/modules/engines/wayland_shm/Makefile.am
src/modules/engines/wayland_shm/evas_engine.c
src/modules/loaders/Makefile.am
src/modules/loaders/bmp/Makefile.am
src/modules/loaders/bmp/evas_image_load_bmp.c
src/modules/loaders/edb/Makefile.am
src/modules/loaders/eet/Makefile.am
src/modules/loaders/eet/evas_image_load_eet.c
src/modules/loaders/generic/Makefile.am
src/modules/loaders/generic/evas_image_load_generic.c
src/modules/loaders/gif/Makefile.am
src/modules/loaders/gif/evas_image_load_gif.c
src/modules/loaders/ico/Makefile.am
src/modules/loaders/jpeg/Makefile.am
src/modules/loaders/jpeg/evas_image_load_jpeg.c
src/modules/loaders/pmaps/Makefile.am
src/modules/loaders/png/Makefile.am
src/modules/loaders/png/evas_image_load_png.c
src/modules/loaders/psd/Makefile.am
src/modules/loaders/svg/Makefile.am
src/modules/loaders/svg/evas_image_load_esvg.c
src/modules/loaders/tga/Makefile.am
src/modules/loaders/tgv/Makefile.am [new file with mode: 0644]
src/modules/loaders/tgv/evas_image_load_tgv.c [new file with mode: 0644]
src/modules/loaders/tiff/Makefile.am
src/modules/loaders/wbmp/Makefile.am
src/modules/loaders/webp/Makefile.am [new file with mode: 0644]
src/modules/loaders/webp/evas_image_load_webp.c [new file with mode: 0644]
src/modules/loaders/xpm/Makefile.am
src/modules/loaders/xpm/evas_image_load_xpm.c
src/modules/savers/Makefile.am
src/modules/savers/edb/Makefile.am
src/modules/savers/eet/Makefile.am
src/modules/savers/eet/evas_image_save_eet.c
src/modules/savers/jpeg/Makefile.am
src/modules/savers/jpeg/evas_image_save_jpeg.c
src/modules/savers/png/Makefile.am
src/modules/savers/png/evas_image_save_png.c
src/modules/savers/tgv/Makefile.am [new file with mode: 0644]
src/modules/savers/tgv/evas_image_save_tgv.c [new file with mode: 0644]
src/modules/savers/tiff/Makefile.am
src/modules/savers/tiff/evas_image_save_tiff.c
src/static_deps/Makefile.am
src/static_deps/liblinebreak/linebreak.c
src/static_deps/liblinebreak/linebreakdata.c
src/static_deps/liblinebreak/linebreakdef.c
src/static_deps/lz4/Makefile.am [new file with mode: 0644]
src/static_deps/lz4/README [new file with mode: 0644]
src/static_deps/lz4/lz4.c [new file with mode: 0644]
src/static_deps/lz4/lz4.h [new file with mode: 0644]
src/static_deps/lz4/lz4hc.c [new file with mode: 0644]
src/static_deps/lz4/lz4hc.h [new file with mode: 0644]
src/static_deps/rg_etc/Makefile.am [new file with mode: 0644]
src/static_deps/rg_etc/README [new file with mode: 0644]
src/static_deps/rg_etc/etc2_encoder.c [new file with mode: 0644]
src/static_deps/rg_etc/rg_etc1.c [new file with mode: 0644]
src/static_deps/rg_etc/rg_etc1.h [new file with mode: 0644]
src/static_deps/rg_etc/rg_etc2.c [new file with mode: 0644]
src/tests/Makefile.am
src/tests/evas_test_text.c
src/tests/evas_test_textblock.c

diff --git a/AUTHORS b/AUTHORS
index 82f644e..f8c2a51 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -36,3 +36,5 @@ Hyoyoung Chang <hyoyoung@gmail.com>
 Jérôme Pinot <ngc891@gmail.com>
 Rafael Antognolli <antognolli@profusion.mobi>
 Daniel Zaoui <daniel.zaoui@samsung.com>
+Christophe Sadoine <chris@indefini.org>
+Igor Murzov <e-mail@date.by>
diff --git a/COPYING b/COPYING
index 8ba7688..8c51ce4 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -1,6 +1,6 @@
 Copyright notice for Evas:
 
-Copyright (C) 2000-2011 Carsten Haitzler and various contributors (see AUTHORS)
+Copyright (C) 2000-2014 Carsten Haitzler and various contributors (see AUTHORS)
 
 All rights reserved.
 
diff --git a/COPYING.Zlib b/COPYING.Zlib
new file mode 100644 (file)
index 0000000..9b9984f
--- /dev/null
@@ -0,0 +1,18 @@
+Copyright (C) 2008-2010 Wu Yongwei <wuyongwei at gmail dot com>
+
+This software is provided 'as-is', without any express or implied
+warranty.  In no event will the author be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+   claim that you wrote the original software.  If you use this software
+   in a product, an acknowledgement in the product documentation would
+   be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not
+   be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source
+   distribution.
index f1dcfb3..a08a5e4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 2012-08-01  Jiyoun Park(jypark)
 
         * Fix gif load bug. we initialize first frame buffer of gif loader
+
+2012-08-01  Jiyoun Park(jypark)
+
+        * Fix evas pointer count problem, if press/release events occurs not pair,
+       it screws up the evas event process. We are not deal with release event if
+       there is no pressed pointer.
+
+2012-08-01  Carsten Haitzler (The Rasterman)
+
+        * Provide share (Data) file for prefix finding and use
+        eina_prefix for modules too so we work with debian multiarch
+
+
+2012-08-02  Sung W. Park (sung_)
+
+        * Fix evas_gl's internal resource surface bug. For optimzation evas_gl
+        was using evas' window surface to do its resource creation and it 
+        wans't properly updated when a window is destroyed and recreated.
+
+2012-08-07  Cedric Bail
+
+       * Properly warn when user try to link object from different canvas.
+
+2012-08-13  Carsten Haitzler (The Rasterman)
+
+       * Fix async fd stuff to generate new pipe after a fork (pid mismatch)
+
+2012-08-14  Tom Hacohen (TAsn)
+
+       * Textblock: Fixed range geometry when the last item is a format.
+
+2012-08-17  Hermet (ChunEon Park)
+
+       * Let clip the mapped obj even if it is a child of the mapped obj and do
+       it only when clipper exists
+
+2012-08-20  Hermet (ChunEon Park)
+
+       * Removed unnessesary lines which causes the gles resource leak and
+       corruption.
+
+2012-08-21  Sung W. Park (sung_)
+
+        * Fix evas_gl current_context update issue when evas_gl context is deleted.
+
+2012-08-23  Tom Hacohen (TAsn)
+
+       * Textblock: Fixed bug with 1 char word separators at the start of the
+       text when going to the start of the word (e.g: "=test").
+
+2012-08-26  Jiyoun Park(jypark)
+
+       * Jpeg loader: fix orientation didn't work if jpeg file format is JFIF.
+       Add code deal with JFIF file format.
+
+2012-08-27  Tom Hacohen (TAsn)
+
+       * Textblock: Make sure scale changes causes a complete recalc.
+
+2012-08-29  Christopher Michael (devilhorns)
+
+       * Wayland Egl Engine: Add support for Multi-Sample Anti-Aliasing and GL Direct Images.
+                              Add support for using native image binding.
+                              Add support for setting GL surface capabilities.
+
+2012-08-30  Carsten Haitzler (The Rasterman)
+
+        1.7.0 release
+
+2012-08-31  Christophe Sadoine
+
+       * Added a function: evas_map_util_quat_rotate().
+
+2012-09-02  Vincent Torri
+
+       * Fix seg fault in the esvg loader, latest code is required, and
+        enable it on Windows.
+
+2012-09-03  Igor Murzov
+
+       * Add WEBP loader module and cserve2 binary loader patch.
+
+2012-09-03  Christopher Michael (devilhorns)
+
+       * When doing a move or geometry_get, we need to make sure that we 
+        don't try to do these on the framespace clip object. Also, since we
+        need the evas to get the framespace clip object, just directly use the
+        framespace values from the canvas, rather than function call to get
+        those values.
+
+2012-09-05  ChunEon Park (Hermet)
+
+       * Added EVAS_CALLBACK_IMAGE_RESIZE. Now user have a notify when image data size of the image object is changed.
+
+2012-09-05  Carsten Haitzler (The Rasterman)
+
+       * Fix EGL/GLES bug when setting up rgba dest alpha windows where they
+       cease to be rendered to. use a shared context and it works.
+
+2012-09-07  Carsten Haitzler (The Rasterman)
+
+       * Fix image alpha set bug if the image data has not been loaded
+       yet from disk. Fixes across software and gl engines needed.
+       * Fix map surface leak.
+
+2012-09-14  Carsten Haitzler (The Rasterman)
+
+       * Add env EVAS_GL_NO_BLACKLIST to disable blacklisting.
+
+2012-09-17  Carsten Haitzler (The Rasterman)
+
+       * Add evas_device API for being able to register devices, set
+       their names, descriptions, classes, parents, sources etc. etc.
+
+2012-09-20  Carsten Haitzler (The Rasterman)
+
+       * Fix native surface crash when setting to null in some
+       situations in gl engine.
+
+2012-09-24  Sung W. Park (sung_)
+
+       * Refactored Evas GL engine code so wayland_egl and gl_x11 and other
+       engines can share the same code. The common codes are in gl_common/
+       directory and evas_engine just has to implement a few engine functions.
+
+2012-09-26  Carsten Haitzler (The Rasterman)
+
+       * Add the ability via env vars to do partial swaps in the gl
+       engine. This requires that we also can get from gl info as to
+       if a swap was a copy, swap, discard and if a swap with 2 or 3 
+       buffers. don't have that but env var will do for now for testing.
+
+2012-09-27  Jiyoun Park (jypark)
+
+       * Add the object display mode hint. this can be used to check object
+       mode like compress or expand or etc
+
+2012-10-03  Mike Blumenkrantz
+
+       * evas_object_del() now accepts NULL more peacefully
+
+2012-10-05  Sung W. Park (sung_)
+
+       * Added Debug feature for Evas GL's GL APIs. It can be set with 
+       EVAS_GL_API_DEBUG=1 and when it is set, all the GL calls will check
+       if make_current has been properly called.  Also, it'll check if all
+       the GL calls are called within the Pixel Getter function for Direct
+       Rendering option.
+
+2012-10-09 Daniel Zaoui and Tom Hacohen
+
+       * Evas: change Evas to use Eo.
+       This change adds Eo support to Evas while keeping the old API intact.
+       For more information, go to Eo.
+
+2012-10-10  Carsten Haitzler (The Rasterman)
+
+       * Fix font sizing issues when size scaling happens to down down
+       when it should round up. happens in rare sizing situations and fonts.
+
+2012-10-11 Sohyun Kim 
+
+       * Fix texture size issues when the image has nv12 format
+
+2012-10-11  Carsten Haitzler (The Rasterman)
+
+       * Fix C code fallback line rendering path in software
+
+2012-10-16  Carsten Haitzler (The Rasterman)
+
+       * Like 16bpp engine, 8bpp engine goes the way of the dodo.
+
+2012-10-16  ChunEon Park (Hermet)
+
+       * Fix the vertical line drawing on gl backened.
+
+2012-10-20  Cedric Bail
+       1.7.1 release
+
+2012-10-25  Cedric Bail
+
+       * Make XPM loader faster.
+
+2012-11-02  Carsten Haitzler (The Rasterman)
+
+       * Fix evas textblock tag parser to respect escaped spaces and
+         escaped single quotes. This fixes an edje text class restyling bug.
+
+2012-11-09  Vincent Torri
+
+       * Fixed longstanding memset bug in evas box.
+
+2012-11-13  Carsten Haitzler (The Rasterman)
+
+        * Fixed GLX native surface handling to use glXChooseFBConfig.
+        This frixes a break in compositing on new intel mesa drivers.
+
+2012-11-20  ChunEon Park (Hermet)
+
+        * Fix the evas memory leak - eina_rectangles allocated internally.
+
+2012-11-21  Carsten Haitzler (The Rasterman)
+
+        * Fixed leak in textblock and text props in general that made
+        textblock recalcs lead very badly. Required changed to textgrid
+        though a sit relied on the leaky behavior.
+
+2012-11-22  Sung W. Park (sung_)
+
+        * Fixed a bug where if an image object rendered using Evas GL
+        direct rendering and then another image object using Native
+        Surface rendering, there was a potential for it to fall into
+        the same direct rendering path.
+
+2012-11-23  Luis Felipe Strano Moraes
+
+        1.7.2 release
+
+2012-11-29  Cedric Bail
+
+       * Only unreference font when text is not used anymore.
+
+2012-11-30  Gustavo Sverzut Barbieri (k-s)
+
+       * Fix evas_object_box.c to properly reset size_hint_min to zero if
+       there are no objects packed into the box.
+
+2012-12-07  Cedric Bail
+
+       * Don't leak fd on exec.
+
+2012-12-07  Luis Felipe Strano Moraes
+
+       * Release 1.7.3
+
+2012-12-12  ChunEon park <hermet@hermet.pe.kr>
+
+        * Fix the evas gl line incorrect position problem.
+
+2012-12-13  Cedric Bail
+
+       * Fix uninitialized data in Evas_Smart initialization code.
+       * Fix potential segv in software engine native_set call.
+       * Fix uninitialized data in OpenGL engine native_set call.
+
+2012-12-13  Rafael Antognolli (antognolli)
+
+       * Remove strange image_put from image_is_inside. Fixes crashes when
+       precise_is_inside is set on image objects.
+
+2012-12-14  Cedric Bail
+
+       * Properly close async pipe fd on exec.
+
+2012-12-17 Vincent Torri
+
+       * Add XML output to doc
+       * Add installation rule for doc
+
+2012-12-19  Gustavo Sverzut Barbierie (k-s)
+
+       * Fixed RGBA_Image->flags.loaded for copied images.
+       * Fixed evas_object_image_is_inside() implementation.
+
+2012-12-19  Carsten Haitzler (The Rasterman)
+
+        * Fixed 24bpp issue with rendering in evas. It shows itself
+        only under qemu/kvm with the cirruse driver that I have found.
+        In this case the screen is really 24bpp packed and this case
+        just never comes up on any vaguely modern gfx system.
+
+2012-12-21  Stefan Schmidt
+
+        * Fix small memory leak in evas_bidi_utils error path
+
+2012-12-21  Luis Felipe Strano Moraes
+
+       * 1.7.4 release
+
+2013-01-02  Carsten Haitzler (The Rasterman)
+
+        * Fixed evas_software_xlib_x_write_mask_line() issue - it was
+        finding a segment in the shm cache of the wrong size for masks!
+
+2013-01-04  Luis Felipe Strano Moraes
+
+       * 1.7.5 release
+
+2013-01-05  Joel Klinghed
+
+        * fribidi header include path fix.
+
+2013-01-07  Thomas Petazzoni
+
+       * Fix build of Evas XCB backend.
+
+2013-01-09  Jiyoun Park (jypark)
+
+       * Fix evas bmp loader code which deal with image size.
+
+2013-01-11  Cedric Bail
+
+       * Fix not up to date clip cache for Evas_Object_Text.
+
+2013-01-11  Tom Hacohen (TAsn)
+
+       * Static libs: Updated liblinebreak to libunibreak's latest version.
+       * Evas texblock: Fixed a bug with breaking after format items.
+
+2013-01-14  Tom Hacohen (TAsn)
+
+       * Evas textblock: Fixed issue with line height when breaking on a
+       format.
+
+2013-01-15  ChunEon Park (Hermet) <hermet@hermet.pe.kr>
+
+        * Fix SIGFPE in evas map update if image size is 0.
+
+2013-01-15  Tom Hacohen (TAsn)
+
+       * Evas texblock: Fixed issue and simplified cursor_geometry_get.
+       * Evas text: Fixed issue with horiz advance.
+       * Evas text utils: Fixed issue with no-harfbuzz bidi.
+
+2013-01-16  Carsten Haitzler (The Rasterman)
+
+        * Fixed pixman image wrapping to handle allocated size instead
+        of image size (unless allocated is 0/wrong).
+
+2013-02-19 Daniel Zaoui
+
+        * Fix Evas_Object_Text when LTR and RTL are used in the same
+        paragraph.
+
+2013-04-04  Yakov Goldberg
+
+        * Evas font: char position, returned by
+          evas_common_font_query_char_at_coords(),
+          depends on left/right half of char and its direction.
+
+2013-04-10 Tom Hacohen (Tasn) Yakov Goldberg
+
+        * Evas textblock : Added split cursor for BiDi text
+
+2013-06-11  Stefan Schmidt
+
+        * Fix memory leak in error path of textgrid
+
+2013-06-26  Daniel Willmann
+       * Evas: Fix evas_common_convert_yuv_42* functions to actually return
+       the converted data.
+
+2013-11-18  Tom Hacohen
+
+       * Evas textblock: Fixed order of tags inserted with markup_app/prepend.
+
index d8cb45a..c9fcfe0 100644 (file)
@@ -1,6 +1,6 @@
 ACLOCAL_AMFLAGS = -I m4
 
-SUBDIRS = src doc
+SUBDIRS = src doc data
 
 MAINTAINERCLEANFILES = \
 Makefile.in \
@@ -36,12 +36,10 @@ evas-opengl-x11.pc.in \
 evas-opengl-sdl.pc.in \
 evas-software-buffer.pc.in \
 evas-software-x11.pc.in \
-evas-software-16-x11.pc.in \
 evas-software-8-x11.pc.in \
 evas-software-gdi.pc.in \
 evas-software-ddraw.pc.in \
 evas-direct3d.pc.in \
-evas-software-16-wince.pc.in \
 evas-psl1ght.pc.in \
 evas-wayland-shm.pc.in \
 evas-wayland-egl.pc.in \
@@ -68,10 +66,6 @@ if BUILD_ENGINE_SOFTWARE_X11
 pkgconfig_DATA += evas-software-x11.pc
 endif
 
-if BUILD_ENGINE_SOFTWARE_16_X11
-pkgconfig_DATA += evas-software-16-x11.pc
-endif
-
 if BUILD_ENGINE_SOFTWARE_8_X11
 pkgconfig_DATA += evas-software-8-x11.pc
 endif
@@ -112,14 +106,6 @@ if BUILD_ENGINE_DIRECT3D
 pkgconfig_DATA += evas-direct3d.pc
 endif
 
-if BUILD_ENGINE_SOFTWARE_16_WINCE
-pkgconfig_DATA += evas-software-16-wince.pc
-endif
-
-if BUILD_ENGINE_SOFTWARE_16_SDL
-pkgconfig_DATA += evas-software-sdl.pc
-endif
-
 if BUILD_ENGINE_PSL1GHT
 pkgconfig_DATA += evas-psl1ght.pc
 endif
diff --git a/NEWS b/NEWS
index ea0dede..00cf601 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,122 @@
-Evas 1.3.0
+Evas 1.8.0
+
+Changes since Evas 1.7.7
+-------------------------
+
+Additions:
+   * Add EVAS_GL_LINE_OFFSET_HACK_DISABLE to turn off line shift correction by evas.
+
+Fixes:
+   * Fix evas textblock tag parser to respect escaped spaces and escaped single quotes
+   * Fix the line drawing clipping problem on arm gl driver.
+   * Evas: Fix Evas_Object_Text when LTR and RTL are used in the same paragraph.
+   * Evas font: click on left/right half of char does matter now.
+   * Fix memory leak in textgrid
+   * Fix evas_common_convert_yuv_42* functions to actually return the converted data.
+   * Evas textblock: Fixed order of tags inserted with markup_app/prepend.
+
+Improvements:
+   * Evas textblock : Added split cursor for BiDi text
+
+Evas 1.7.7
+
+Changes since Evas 1.7.6
+-------------------------
+
+    * Fix SIGFPE in evas map update if image is 0.
+    * Evas textblock: Fixed issue and simplified cursor_geometry_get.
+    * Evas text: Fixed issue with horiz advance.
+    * Evas text utils: Fixed issue with no-harfbuzz bidi.
+    * Fixed pixman surface alloc where allocated and image size differ.
+
+Changes since Evas 1.7.5:
+-------------------------
+
+   * Fix build of Evas XCB backend.
+   * Fix evas bmp loader code which deal with image size.
+   * Fix not up to date clip cache for Evas_Object_Text.
+   * Evas texblock: Fixed a bug with breaking after format items.
+   * Evas textblock: Fixed issue with line height when breaking on a format.
+   
+Changes since Evas 1.7.4:
+-------------------------
+
+   * Fix mask write lines to not choose too small segments
+
+Evas 1.7.4
+
+Changes since Evas 1.7.3:
+-------------------------
+
+Fixes:
+   * Fix the gl line incorrect position drawing.
+   * Fix uninitialized data in Evas_Smart initialization code.
+   * Fix potential segv in software engine native_set call.
+   * Fix uninitialized data in OpenGL engine native_set call.
+   * Fix crash when precise_is_inside is set on an image, and events are generated from it.
+   * Properly close async pipe fd on exec.
+   * Fix the line drawing clipping problem on arm gl driver.
+   * Fix big rendering/conversion problem in kvm/qemu 24bpp.
+   * Fix Evas RGBA_Image->flags.loaded for copied images. 
+   * Fix evas_object_image_is_inside()
+   * Fix small memory leak in evas_bidi_utils error path
+    
+    
+Evas 1.7.3
+
+Changes since Evas 1.7.2
+-------------------------
+
+Fixes:
+   * Fixed evas_object_box to reset size_hint_min to zero when no child.
+   * Don't leak fd on exec.
+
+Evas 1.7.2
+
+Changes since Evas 1.7.1
+-------------------------
+
+Fixes:
+   * Fix evas textblock tag parser to respect escaped spaces and escaped single quotes
+   * Fixed longstanding memset bug in evas box.
+   * Fixed GLX native surface handling (fixes new mesa+intel comp bug).
+   * Fixed textblock textprop leak.
+    
+Changes since Evas 1.7.0:
+-------------------------
+
+Additions:
+
+   * WEBP image loader support.
+   * EVAS_CALLBACK_IMAGE_RESIZE.
+   * Evas_Device registration/manipulation/querying API
+   * Evas_Object_Display_Mode querying API
+   * EVAS_GL_API_DEBUG=1 env. var option for outputting debug logs related to Evas GL's GL calls.
+
+Improvements:
+
+   * Function to rotate an evas map with a quaternion: evas_map_util_quat_rotate().
+   * EVAS_GL_NO_BLACKLIST env var to turn off blacklisted drivers in gl
+   * Evas gl engine can do partial swaps now.
+   * evas_object_del() now takes NULL parameters
+   * make xpm loader faster (from O(N) to O(log(N))).
+
+Fixes:
+
+   * Fix segmentation fault with the esvg loader.
+   * Fix EGL/GLES dest alpha rendering bug (no rendering).
+   * Fix evas_object_image_alpha_set when image data not loaded yet.
+   * Fix map surface leak.
+   * Fix native surface set to null crash bug in gl engine.
+   * Fix font sizing issue with some rare sizes and fonts when rounding wrong.
+   * Fix software line drawing c fallback code.
+   * Update move event when object freeze event is off.
+   * coordinate compute bug for Evas GL direct rendering.
+    
+Removal:
+   * No more support s3c6410.
+
+Evas 1.7.0
 
 Changes since Evas 1.2.0:
 -------------------------
@@ -16,6 +134,7 @@ Improvements:
    * Cache convertion from Evas_Map to RGBA_Map.
    * evas_object_smart_members_get() now returns NULL on non-smart objects.
    * Pipeline rendering use prepare stage more extensively.
+   * Properly warn when user try to link object from different canvas.
 
 Fixes:
    * Add missing files in the tarball.
@@ -26,6 +145,8 @@ Fixes:
    * Don't crash when calling evas_object_smart_type_check without type.
    * Handle proxy with the right context.
    * Force proxied object to stay active to keep track of change in them.
+   * Fix evas_gl's internal resource surface bug when evas' window is deleted/recreated.
+   * Fix evas_gl current_context update issue when evas_gl context is deleted.
 
 Removal:
    * Remove EVAS_FRAME_QUEUING, EVAS_SLI, METRIC_CACHE and WORD_CACHE.
diff --git a/README b/README
index 81fd85b..7660890 100644 (file)
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-Evas 1.7.0
+Evas 1.7.99
 
 ******************************************************************************
 
@@ -27,7 +27,7 @@ Recommended:
   liblinebreak
 
 Optional:
-  XCB SDL OpenGL esvg/librsvg libtiff libgif edb DirectFB evas_generic_loaders
+  XCB SDL OpenGL esvg libtiff libgif edb DirectFB evas_generic_loaders
 
 Evas is a clean display canvas API for several target display systems
 that can draw anti-aliased text, smooth super and sub-sampled scaled
@@ -506,11 +506,10 @@ bitmap data in binary or ascii format
 
 --enable-image-loader-svg[=static]
 
-this loader can load svg files via esvg or librsvg (thus it is a
-dependency). This loader supports load options to set the dpi to
-decode the svg at etc. which can then be used to create scalable
-images that scale to any size without becoming blocky or blurry, if
-the source is an svg file.
+this loader can load svg files via esvg (thus it is a dependency). This
+loader supports load options to set the dpi to decode the svg at etc. which
+can then be used to create scalable images that scale to any size without
+becoming blocky or blurry, if the source is an svg file.
 
 Esvg can be found here:
 
@@ -528,6 +527,9 @@ egueb
 
 this loader uses libtiff to load tiff image files
 
+--enable-image-loader-webp[=static]
+
+this loader uses libwebp to load webp image files
 
 --enable-image-loader-xpm[=static]
 
@@ -553,6 +555,35 @@ this loader load tga format files. these files are very old-fashioned
 but found often in the 3d graphics world.
 
 
+--enable-image-loader-generic[=static]
+
+this loader will execute a given binary to decode an image and read
+the resulting image data via a shared memory segment, a mmaped file or
+stdout. it uses the command-line to pass the filename and any load
+parameters, and reads stdout from the loader binary to get metadata like
+width, height, alpha channel flag and location of pixel data. this
+loader has no dependencies as the binaries run are to be found in
+PREIFX/lib/evas/utils and are named evas_image_loader.EXTENSION where
+.EXTENSION is replaced by the filename extension to be decoded. if
+this binary does not exist then evas_image_loader (with no extension) is
+tried as a last fallback allowing it to handle "all cases".
+
+since this loader doesn't use any libraires, it relies on runtime
+dependencies and executables existing in the utils directory. note that
+images loaded via this mechanism will have slower load times due to the
+overhead of execution of another binary, but any instability in the
+loaders themselves will not affect the application using evas.
+
+this also means that licenses such as GPL for the binaries in this
+utils directory do not affect evas and the applications or libraries
+using evas.
+
+there is a separately released evas_generic_loaders package which
+builds stand-alone binaries that can do this style of decoding for for
+evas. this package currently handles XCF, PDF, PS, RAW, SVG (via
+librsvg) and video formats (via gstreamer).
+
+
 ------------------------------------------------------------------------------
 FONT LOADERS:
 --enable-font-loader-eet[=static]
@@ -760,76 +791,13 @@ with --enable-pthreads and --enable-async-events. you really want all
 of these available.
 
 
---enable-async-render **CAUTION - MAY NOT WORK RIGHT**
-
-this enables a software multi-frame threaded renderer. this will
-allocate (for example) 2 frames to 2 cores, with one core of the cpu
-rendering the previous frame while the next frame starts rendering on
-another core in the meantime allowing for higher framerates with
-software rendering, using more cpu resources that are available on
-modern multi-core cpu's.
-
-This is buggy! it will likely cause crashes and rendering corruption.
-Do not enable it unless you plan to actually work on it. This requires you
-also set the environment variable EVAS_RENDER_MODE to "non-blocking" to
-enable it at runtime, as the compile-time enable simply sets up the feature
-to be ready to work. The runtime switch actually turns it on. If you don't
-plan to use this feature, don't enable it in the build as there is a general
-performance hit of maintaining this feature at all, so beware that
-enabling it for single core systems will likely take a performance hit.
-
-
---enable-pipe-render **DISABLED DUE TO BUGS**
+--enable-pipe-render **NOT ON BY DEFAULT DUE TO DUBIOUS IMPROVEMENTS**
 
 this enables a multiple-thread renderer that divides the rendering
 into N regions (1 per core) to speed up rendering in software when you
 have multiple cpu cores.
 
 
---enable-word-cache **DISABLED DUE TO BUGS**
-
-Cache rendered words and draw them as a single object, instead of
-individual characters.  This is a big gain for things like neon which
-draw large runs effectively.
-
-However it is useless on GL and similar back-ends as the cost in
-sending a word sized texture kills the performance gain (and GL is
-pretty good at drawing lots of small things anyway).  If it detects a GL
-backend is in use, it disables itself.
-
-By default words (strings) of more then 50 characters are not cached.
-The system caches 40 words by default, but this can be changed by
-setting EVAS_WORD_CACHE_MAX_WORDS to another number.  Setting it to 0
-will disable word-cache at run time.
-
-Text based benchmarks are 50-100% quicker.
-
-If you have any issues with word caching, please report them to either
-the e-devel mailing list or Brett Nash <nash@nash.id.uau>
-
-For GL see metric caching...
-
-
---enable-metric-cache **DISABLED DUE TO BUGS**
-
-Metric caching saves character metrics between characters in words.
-This enables it to render words much quicker as it avoids things like
-space calculations and kerning calculation.
-
-The cache size is also controlled by EVAS_WORD_CACHE_MAX_WORDS.
-
-It is useful for GL in particular, although software engines do get
-some gain.
-
-Generally it is recommended you enable one or both of word or metric caching,
-depending on your engine use.  If you are only using software, enable word
-caching (and neon on arm if you can), for GL, turn on metric caching.
-A simple solution is enable both, and let the engine sort it out at run time.
-
-If you have any issues with metric caching, please report them to either
-the e-devel mailing list or Brett Nash <nash@nash.id.uau>
-
-
 --enable-fontconfig
 
 this enables fontconfig support for loading font files by using
index 46ebb80..52d8f91 100644 (file)
@@ -1,7 +1,7 @@
 ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
 ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
 m4_define([v_maj], [1])
-m4_define([v_min], [6])
+m4_define([v_min], [7])
 m4_define([v_mic], [99])
 m4_define([v_rev], m4_esyscmd([(svnversion "${SVN_REPO_PATH:-.}" | grep -v '\(export\|Unversioned directory\)' || echo 0) | awk -F : '{printf("%s\n", $1);}' | tr -d ' :MSP\n']))
 m4_if(v_rev, [0], [m4_define([v_rev], m4_esyscmd([git log 2> /dev/null | (grep -m1 git-svn-id || echo 0) | sed -e 's/.*@\([0-9]*\).*/\1/' | tr -d '\n']))])
@@ -100,9 +100,6 @@ want_evas_engine_software_xcb="no"
 want_evas_engine_software_gdi="no"
 want_evas_engine_software_ddraw="no"
 want_evas_engine_software_8_x11="no"
-want_evas_engine_software_16_x11="no"
-want_evas_engine_software_16_wince="no"
-want_evas_engine_software_16_sdl="no"
 want_evas_engine_gl_xlib="no"
 want_evas_engine_gl_xcb="no"
 want_evas_engine_gl_sdl="no"
@@ -126,8 +123,10 @@ want_evas_image_loader_xpm="yes"
 want_evas_image_loader_bmp="yes"
 want_evas_image_loader_tga="yes"
 want_evas_image_loader_wbmp="yes"
+want_evas_image_loader_webp="yes"
 want_evas_image_loader_ico="yes"
 want_evas_image_loader_psd="yes"
+want_evas_image_loader_tgv="yes"
 want_evas_image_loader_generic="yes"
 
 want_evas_font_loader_eet="yes"
@@ -135,7 +134,6 @@ want_evas_font_loader_eet="yes"
 case "$host_os" in
    mingw32ce*)
       want_fontconfig="no"
-      want_evas_engine_software_16_wince="yes"
       want_evas_image_loader_edb="no"
       want_evas_image_loader_gif="no"
       want_evas_image_loader_svg="no"
@@ -146,7 +144,7 @@ case "$host_os" in
       want_evas_engine_software_ddraw="yes"
       want_evas_engine_direct3d="yes"
       want_evas_image_loader_edb="no"
-      want_evas_image_loader_svg="no"
+      want_evas_image_loader_svg="yes"
       ;;
    darwin*)
       want_evas_engine_software_xlib="auto"
@@ -162,7 +160,6 @@ case "$host_os" in
       want_evas_engine_wayland_egl="auto"
 ### no - not ready/usable/complete
 #      want_evas_engine_software_8_x11="auto"
-#      want_evas_engine_software_16_x11="auto"
       ;;
 esac
 
@@ -544,7 +541,7 @@ AC_SUBST(lt_enable_auto_import)
 ### Checks for library functions
 
 AC_ISC_POSIX
-AC_CHECK_FUNCS([siglongjmp])
+AC_CHECK_FUNCS([siglongjmp fcntl])
 
 # alloca
 AC_FUNC_ALLOCA
@@ -669,7 +666,9 @@ AC_ARG_ENABLE(gl-flavor-gles,
   [
       if test "x$enableval" = "xyes" ; then
         AC_MSG_RESULT(yes)
+        AC_DEFINE(GL_GLES, 1, [GLSL runtime shader GLES2 support])
         gl_flavor_gles="yes"
+        gles_variety_sgx="yes"
       else
         AC_MSG_RESULT(no)
         gl_flavor_gles="no"
@@ -680,65 +679,6 @@ AC_ARG_ENABLE(gl-flavor-gles,
   ]
 )
 
-#######################################
-## GLES variety sgx
-gles_variety_sgx="no"
-AC_MSG_CHECKING(whether to build GLES variety for SGX)
-AC_ARG_ENABLE(gles-variety-sgx,
-  AC_HELP_STRING([--enable-gles-variety-sgx], [GLES variety SGX 3D unit]),
-  [
-      if test "x$enableval" = "xyes" ; then
-        AC_MSG_RESULT(yes)
-        AC_DEFINE(GLES_VARIETY_SGX, 1, [Imagination SGX GLES2 support])
-        gles_variety_sgx="yes"
-      else
-        AC_MSG_RESULT(no)
-        gles_variety_sgx="no"
-      fi
-  ], [
-      AC_MSG_RESULT(no)
-      gles_variety_sgx="no"
-  ]
-)
-
-#######################################
-## GLES variety s3c6410
-gles_variety_s3c6410="no"
-AC_MSG_CHECKING(whether to build GLES variety for s3c6410)
-AC_ARG_ENABLE(gles-variety-s3c6410,
-  AC_HELP_STRING([--enable-gles-variety-s3c6410], [GLES variety s3c6410 3D unit]),
-  [
-      if test "x$enableval" = "xyes" ; then
-        AC_MSG_RESULT(yes)
-        AC_DEFINE(GLES_VARIETY_S3C6410, 1, [Samsung S3c6410 GLES2 support])
-        gles_variety_s3c6410="yes"
-      else
-        AC_MSG_RESULT(no)
-        gles_variety_s3c6410="no"
-      fi
-  ], [
-      AC_MSG_RESULT(no)
-      gles_variety_s3c6410="no"
-  ]
-)
-
-if test "x$gl_flavor_gles" = "xyes"; then
-  eng=""
-  if test "x$gles_variety_sgx" = "xyes"; then eng="x"$eng; fi
-  if test "x$gles_variety_s3c6410" = "xyes"; then eng="x"$eng; fi
-  if test "x$eng" = "xx"; then
-    eng=""
-  else
-     AC_MSG_ERROR(
-       [Please enable just 1 OpenGL-ES flavor. Choices are:
-          --enable-gles-variety-sgx (Most GL-ES2 GPUs with shader compiler)
-          --enable-gles-variety-s3c6410 (s3c6410 with offline shader compiler)
-        You will also need to enable the OpenGL engine for X11 with:
-          --enable-gl-xlib or --enable-gl-xcb
-       ])
-  fi
-fi
-
 #####################################################################
 ## Engines
 
@@ -762,12 +702,6 @@ EVAS_CHECK_ENGINE([directfb], [${want_evas_engine_directfb}], [no], [DirectFB])
 
 EVAS_CHECK_ENGINE([software-8-x11], [${want_evas_engine_software_8_x11}], [no], [Software X11 8 bits grayscale])
 
-EVAS_CHECK_ENGINE([software-16-x11], [${want_evas_engine_software_16_x11}], [no], [Software X11 16 bits])
-
-EVAS_CHECK_ENGINE([software-16-wince], [${want_evas_engine_software_16_wince}], [no], [Software Windows CE 16 bits])
-
-EVAS_CHECK_ENGINE([software-16-sdl], [${want_evas_engine_software_16_sdl}], [no], [Software SDL 16 bits])
-
 EVAS_CHECK_ENGINE([wayland-shm], [${want_evas_engine_wayland_shm}], [no], [Wayland Shm])
 
 EVAS_CHECK_ENGINE([wayland-egl], [${want_evas_engine_wayland_egl}], [no], [Wayland Egl])
@@ -964,34 +898,6 @@ if test "x$gl_flavor_gles" = "xyes"; then
       [#include <SDL/SDL_video.h>])
 fi
 
-# if software 16 x11 is enabled - build software_16 (the generic 16bit
-# engine). later enable it fb_16 or other "16" bit engines are enabled.
-have_evas_engine_software_16="no"
-if test "x$have_evas_engine_software_16_x11" = "xyes" -o "x$have_evas_engine_software_16_x11" = "xstatic"; then
-   have_evas_engine_software_16="yes"
-fi
-if test "x$have_evas_engine_software_16_sdl" = "xyes" -o "x$have_evas_engine_software_16_sdl" = "xstatic"; then
-   have_evas_engine_software_16="yes"
-fi
-if test "x$have_evas_engine_software_16_wince" = "xyes" -o "x$have_evas_engine_software_16_wince" = "xstatic"; then
-   have_evas_engine_software_16="yes"
-fi
-AM_CONDITIONAL(BUILD_ENGINE_SOFTWARE_16, test "x$have_evas_engine_software_16" = "xyes")
-
-# if software 16 need to be build as part of libevas.so
-have_static_software_16="no"
-AC_ARG_ENABLE([static-software-16],
-   [AC_HELP_STRING([--enable-static-software-16], [Build software 16 engine as part of libevas])],
-   [have_static_software_16=${enableval}]
-)
-AC_MSG_CHECKING([Whether to build software 16 engine as part of libevas])
-AC_MSG_RESULT([${have_static_software_16}])
-
-AM_CONDITIONAL(EVAS_STATIC_BUILD_SOFTWARE_16, test "x${have_static_software_16}" = "xyes")
-if test "x${have_static_software_16}" = "xyes"; then
-   AC_DEFINE(EVAS_STATIC_BUILD_SOFTWARE_16, [1], [Build software 16 engine as part of libevas])
-fi
-
 # if software 8 x11 is enabled - build software_8 (the generic 8bit
 # engine).
 have_evas_engine_software_8="no"
@@ -1056,8 +962,12 @@ EVAS_CHECK_IMAGE_LOADER([BMP], [${want_evas_image_loader_bmp}])
 
 EVAS_CHECK_IMAGE_LOADER([TGA], [${want_evas_image_loader_tga}])
 
+EVAS_CHECK_IMAGE_LOADER([TGV], [${want_evas_image_loader_tgv}])
+
 EVAS_CHECK_IMAGE_LOADER([WBMP], [${want_evas_image_loader_wbmp}])
 
+EVAS_CHECK_IMAGE_LOADER([WEBP], [${want_evas_image_loader_webp}])
+
 EVAS_CHECK_IMAGE_LOADER([ICO], [${want_evas_image_loader_ico}])
 
 EVAS_CHECK_IMAGE_LOADER([PSD], [${want_evas_image_loader_psd}])
@@ -1519,45 +1429,6 @@ if test "x$want_evas_magic_debug" = "xyes"; then
   AC_DEFINE(EVAS_MAGIC_DEBUG, 1, [complain when people pass in wrong object types etc.])
 fi
 
-
-#######################################
-## Word Caching
-want_word_cache="no"
-AC_MSG_CHECKING(whether to enable caching of rendered words)
-AC_ARG_ENABLE(word-cache,
-  AC_HELP_STRING(
-    [--enable-word-cache],
-    [Enable experimental word caching to speed up rendering [[default=disabled]]]
-  ),
-  [ want_word_cache="$enableval" ]
-)
-AC_MSG_RESULT($want_word_cache)
-
-AM_CONDITIONAL(WORD_CACHE, test "x$want_word_cache" = "xyes")
-if test "x$want_word_cache" = "xyes"; then
-  AC_DEFINE(WORD_CACHE, 1, [Experimental word caching to speed up text rendering.])
-fi
-
-#######################################
-## Metric Caching
-want_metric_cache="no"
-AC_MSG_CHECKING(whether to enable caching of rendered metrics)
-AC_ARG_ENABLE(metric-cache,
-  AC_HELP_STRING(
-    [--enable-metric-cache],
-    [Enable experimental metric caching to speed up rendering [[default=disabled]]]
-  ),
-  [ want_metric_cache="$enableval" ]
-)
-AC_MSG_RESULT($want_metric_cache)
-
-AM_CONDITIONAL(METRIC_CACHE, test "x$want_metric_cache" = "xyes")
-if test "x$want_metric_cache" = "xyes"; then
-  AC_DEFINE(METRIC_CACHE, 1, [Experimental metric caching to speed up text rendering.])
-fi
-
-
-
 #####################################################################
 ## ARGB engine options
 
@@ -1829,6 +1700,13 @@ fi
 AC_SUBST(EVAS_CFLAGS)
 AC_SUBST(EVAS_LIBS)
 
+# General CFLAGS
+
+EVAS_GENERAL_CFLAGS="${EINA_CFLAGS}"
+EVAS_GENERAL_LIBS="${EINA_LIBS}"
+AC_SUBST(EVAS_GENERAL_CFLAGS)
+AC_SUBST(EVAS_GENERAL_LIBS)
+
 #####################################################################
 ## Fill in flags
 
@@ -1851,11 +1729,9 @@ evas-opengl-cocoa.pc
 evas-software-buffer.pc
 evas-software-x11.pc
 evas-software-8-x11.pc
-evas-software-16-x11.pc
 evas-software-gdi.pc
 evas-software-ddraw.pc
 evas-direct3d.pc
-evas-software-16-wince.pc
 evas-software-sdl.pc
 evas-psl1ght.pc
 evas-wayland-shm.pc
@@ -1877,6 +1753,7 @@ src/bin/loaders/ico/Makefile
 src/bin/loaders/tga/Makefile
 src/bin/loaders/pmaps/Makefile
 src/bin/loaders/wbmp/Makefile
+src/bin/loaders/webp/Makefile
 src/bin/loaders/psd/Makefile
 src/lib/Makefile
 src/lib/canvas/Makefile
@@ -1894,14 +1771,13 @@ src/lib/engines/common/evas_op_mask/Makefile
 src/lib/engines/common/evas_op_mul/Makefile
 src/lib/engines/common/evas_op_sub/Makefile
 src/lib/engines/common_8/Makefile
-src/lib/engines/common_16/Makefile
+src/lib/filters/Makefile
 src/modules/Makefile
 src/modules/engines/Makefile
 src/modules/engines/software_generic/Makefile
 src/modules/engines/software_gdi/Makefile
 src/modules/engines/software_ddraw/Makefile
 src/modules/engines/direct3d/Makefile
-src/modules/engines/software_16_wince/Makefile
 src/modules/engines/software_x11/Makefile
 src/modules/engines/fb/Makefile
 src/modules/engines/buffer/Makefile
@@ -1913,9 +1789,6 @@ src/modules/engines/gl_cocoa/Makefile
 src/modules/engines/psl1ght/Makefile
 src/modules/engines/software_8/Makefile
 src/modules/engines/software_8_x11/Makefile
-src/modules/engines/software_16/Makefile
-src/modules/engines/software_16_x11/Makefile
-src/modules/engines/software_16_sdl/Makefile
 src/modules/engines/wayland_shm/Makefile
 src/modules/engines/wayland_egl/Makefile
 src/modules/loaders/Makefile
@@ -1929,9 +1802,11 @@ src/modules/loaders/xpm/Makefile
 src/modules/loaders/bmp/Makefile
 src/modules/loaders/ico/Makefile
 src/modules/loaders/tga/Makefile
+src/modules/loaders/tgv/Makefile
 src/modules/loaders/svg/Makefile
 src/modules/loaders/pmaps/Makefile
 src/modules/loaders/wbmp/Makefile
+src/modules/loaders/webp/Makefile
 src/modules/loaders/psd/Makefile
 src/modules/loaders/generic/Makefile
 src/modules/savers/Makefile
@@ -1940,11 +1815,16 @@ src/modules/savers/eet/Makefile
 src/modules/savers/jpeg/Makefile
 src/modules/savers/png/Makefile
 src/modules/savers/tiff/Makefile
+src/modules/savers/tgv/Makefile
 src/static_deps/Makefile
 src/static_deps/liblinebreak/Makefile
+src/static_deps/lz4/Makefile
+src/static_deps/rg_etc/Makefile
 src/lib/include/Makefile
 src/examples/Makefile
 src/tests/Makefile
+src/benchmarks/evas/Makefile
+data/Makefile
 evas.spec
 ])
 
@@ -1984,7 +1864,7 @@ echo "  Software Memory Buffer.....: $have_evas_engine_buffer"
 echo "  Software X11...............: $have_evas_engine_software_x11 (Xlib: $have_evas_engine_software_xlib) (XCB: $have_evas_engine_software_xcb)"
 echo $ECHO_N "  OpenGL X11.................: $have_evas_engine_gl_x11 (Xlib: $have_evas_engine_gl_xlib) (XCB: $have_evas_engine_gl_xcb) $ECHO_C"
 if test "x$have_evas_engine_gl_x11" = "xyes"; then
-  echo "(GLES: $gl_flavor_gles) (SGX: $gles_variety_sgx) (s3c6410: $gles_variety_s3c6410)"
+  echo "(GLES: $gl_flavor_gles)"
 else
   echo
 fi
@@ -1993,7 +1873,7 @@ echo "  Software DirectDraw........: $have_evas_engine_software_ddraw"
 echo "  Direct3d...................: $have_evas_engine_direct3d"
 echo "  OpenGL SDL.................: $have_evas_engine_gl_sdl $ECHO_C"
 if test "x$have_evas_engine_gl_sdl" = "xyes"; then
-  echo "(GLES: $gl_flavor_gles) (SGX: $gles_variety_sgx) (s3c6410: $gles_variety_s3c6410)"
+  echo "(GLES: $gl_flavor_gles)"
 else
   echo
 fi
@@ -2002,11 +1882,6 @@ echo "  Software Framebuffer.......: $have_evas_engine_fb"
 echo "  DirectFB...................: $have_evas_engine_directfb"
 echo "  PSL1GHT....................: $have_evas_engine_psl1ght"
 echo "  Software 8bit grayscale....: $have_evas_engine_software_8"
-# FIXME: kill software 16bit
-echo "  Software 16bit ............: $have_evas_engine_software_16"
-echo "  Software 16bit X11.........: $have_evas_engine_software_16_x11"
-echo "  Software 16bit WinCE.......: $have_evas_engine_software_16_wince"
-echo "  Software 16bit SDL.........: $have_evas_engine_software_16_sdl (primitive: $sdl_primitive)"
 echo "  Wayland Shm................: $have_evas_engine_wayland_shm"
 echo "  Wayland Egl................: $have_evas_engine_wayland_egl"
 echo
@@ -2025,7 +1900,9 @@ echo "  SVG.....................: $have_evas_image_loader_svg"
 echo "  TGA.....................: $have_evas_image_loader_tga"
 echo "  TIFF....................: $have_evas_image_loader_tiff"
 echo "  WBMP....................: $have_evas_image_loader_wbmp"
+echo "  WEBP....................: $have_evas_image_loader_webp"
 echo "  XPM.....................: $have_evas_image_loader_xpm"
+echo "  TGV.....................: $have_evas_image_loader_tgv"
 echo
 echo "Font Sourcing Systems:"
 echo "  EET.....................: $have_evas_font_loader_eet"
@@ -2063,9 +1940,6 @@ echo "  Threaded Pipe Rendering.: $build_pipe_render"
 echo "  Async Events............: $build_async_events"
 echo "  Async Image Preload.....: $build_async_preload"
 echo
-echo "  Word Cache..............: $want_word_cache"
-echo "  Metric Cache............: $want_metric_cache"
-echo
 echo "  Pixman..................: $have_pixman"
 echo "  Pixman Fonts............: $have_pixman_font"
 echo "  Pixman Rects............: $have_pixman_rect"
diff --git a/data/Makefile.am b/data/Makefile.am
new file mode 100644 (file)
index 0000000..80a8cc6
--- /dev/null
@@ -0,0 +1,6 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+filesdir = $(datadir)/evas
+files_DATA = checkme
+
+EXTRA_DIST = $(files_DATA)
diff --git a/data/checkme b/data/checkme
new file mode 100644 (file)
index 0000000..987063d
--- /dev/null
@@ -0,0 +1,2 @@
+This is just a test file used to help evas determine its prefix
+location.
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644 (file)
index 536add3..0000000
+++ /dev/null
@@ -1,1837 +0,0 @@
-evas (1.2.0+svn.70433slp2+build08) unstable; urgency=low
-
-  * Msaa api function pointer symbol modification
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.2.0+svn.70433slp2+build08
-
- -- Sanghee Park <sh15.park@samsung.com>  Tue, 05 Jun 2012 19:44:34 +0900
-
-evas (1.2.0+svn.70433slp2+build07) unstable; urgency=low
-
-  * Enable msaa feature(fix build bug on i386)
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.2.0+svn.70433slp2+build07
-
- -- Sanghee Park <sh15.park@samsung.com>  Tue, 05 Jun 2012 16:05:38 +0900
-
-evas (1.2.0+svn.70433slp2+build06) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.2.0+svn.70433slp2+build06
-
- -- ChunEon Park <chuneon.park@samsung.com>  Fri, 01 Jun 2012 19:29:32 +0900
-
-evas (1.2.0+svn.70433slp2+build05) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.2.0+svn.70433slp2+build05
-
- -- ChunEon Park <chuneon.park@samsung.com>  Tue, 22 May 2012 09:44:48 +0900
-
-evas (1.2.0+svn.70433slp2+build04) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.2.0+svn.70433slp2+build04
-
- -- ChunEon Park <chuneon.park@samsung.com>  Mon, 21 May 2012 13:38:48 +0900
-
-evas (1.2.0+svn.70433slp2+build03) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.2.0+svn.70433slp2+build03
-
- -- Sanghee Park <sh15.park@samsung.com>  Tue, 08 May 2012 19:47:07 +0900
-
-evas (1.2.0+svn.70433slp2+build02) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.2.0+svn.70433slp2+build02
-
- -- Myungjae Lee <mjae.lee@samsung.com>  Wed, 25 Apr 2012 17:28:22 +0900
-
-evas (1.2.0+svn.70433slp2+build01) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.2.0+svn.70433slp2+build01
-
- -- Myungjae Lee <mjae.lee@samsung.com>  Wed, 25 Apr 2012 15:13:11 +0900
-
-evas (1.2.0+svn.70276slp2+build03) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.2.0+svn.70276slp2+build03
-
- -- Sanghee Park <sh15.park@samsung.com>  Tue, 24 Apr 2012 17:58:02 +0900
-
-evas (1.2.0+svn.70276slp2+build02) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.2.0+svn.70276slp2+build02
-
- -- Minsu Seo <minsu15.seo@samsung.com>  Mon, 23 Apr 2012 14:46:07 +0900
-
-evas (1.2.0+svn.70276slp2+build01) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.2.0+svn.70276slp2+build01
-
- -- Hyoyoung Chang <hyoyoung.chang@samsung.com>  Wed, 18 Apr 2012 18:06:17 +0900
-
-evas (1.2.0+svn.70130slp2+build04) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.2.0+svn.70130slp2+build04
-
- -- Sanghee Park <sh15.park@samsung.com>  Wed, 18 Apr 2012 22:04:41 +0900
-
-evas (1.2.0+svn.70130slp2+build03) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.2.0+svn.70130slp2+build03
-
- -- Sanghee Park <sh15.park@samsung.com>  Mon, 16 Apr 2012 22:08:22 +0900
-
-evas (1.2.0+svn.70130slp2+build02) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.2.0+svn.70130slp2+build02
-
- -- ChunEon Park <chuneon.park@samsung.com>  Mon, 16 Apr 2012 15:23:09 +0900
-
-evas (1.2.0+svn.70130slp2+build01) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.2.0+svn.70130slp2+build01
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Fri, 13 Apr 2012 18:31:41 +0900
-
-evas (1.2.0+svn.69910slp2+build01) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.2.0+svn.69910slp2+build01
-
- -- Jeonghyun Yun <jh0506.yun@samsung.com>  Fri, 06 Apr 2012 18:12:56 +0900
-
-evas (1.1.0+svn.69627slp2+build01) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.69627slp2+build01
-
- -- Jeonghyun Yun <jh0506.yun@samsung.com>  Wed, 28 Mar 2012 14:28:23 +0900
-
-evas (1.1.0+svn.69113slp2+build05) unstable; urgency=low
-
-  * Upload package
-  * Add gl module.so for i386
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.69113slp2+build05
-
- -- Seungsoo Woo <om101.woo@samsung.com>  Tue, 20 Mar 2012 18:05:44 +0900
-
-evas (1.1.0+svn.69113slp2+build04) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.69113slp2+build04
-
- -- Jeonghyun Yun <jh0506.yun@samsung.com>  Sun, 18 Mar 2012 14:02:02 +0900
-
-evas (1.1.0+svn.69113slp2+build03) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.69113slp2+build03
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Fri, 16 Mar 2012 17:23:56 +0900
-
-evas (1.1.0+svn.69113slp2+build02) unstable; urgency=low
-
-  * Package Upload
-  * remove evas_gl_context_dirty api
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.69113slp2+build02
-
- -- Sanghee Park <sh15.park@samsung.com>  Tue, 13 Mar 2012 13:06:47 +0900
-
-evas (1.1.0+svn.69113slp2+build01) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.69113slp2+build01
-
- -- Jeonghyun Yun <jh0506.yun@samsung.com>  Sat, 10 Mar 2012 13:51:22 +0900
-
-evas (1.1.0+svn.68831slp2+build02) unstable; urgency=low
-
-  * 69113
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.68831slp2+build02
-
- -- Jeonghyun Yun <jh0506.yun@samsung.com>  Sat, 10 Mar 2012 13:20:26 +0900
-
-evas (1.1.0+svn.68831slp2+build01) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.68831slp2+build01
-
- -- Jeonghyun Yun <jh0506.yun@samsung.com>  Wed, 07 Mar 2012 16:43:55 +0900
-
-evas (1.1.0+svn.68518slp2+build02) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.68518slp2+build02
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Tue, 06 Mar 2012 21:26:18 +0900
-
-evas (1.1.0+svn.68518slp2+build01) unstable; urgency=low
-
-  * Package upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.68518slp2+build01
-
- -- Jeonghyun Yun <jh0506.yun@samsung.com>  Fri, 02 Mar 2012 06:31:25 -0500
-
-evas (1.1.0+svn.67705slp2+build07) unstable; urgency=low
-
-  * Upload package
-  * Fastpath refactoring
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.67705slp2+build07
-
- -- Seungsoo Woo <om101.woo@samsung.com>  Fri, 02 Mar 2012 18:46:30 +0900
-
-evas (1.1.0+svn.67705slp2+build06) unstable; urgency=low
-
-  * Upload Package
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.67705slp2+build06
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Tue, 28 Feb 2012 19:53:24 +0900
-
-evas (1.1.0+svn.67705slp2+build05) unstable; urgency=low
-
-  * Package Upload
-  * Enabling pixman flag(Additional work to libevas-dev)
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.67705slp2+build05
-
- -- Sanghee Park <sh15.park@samsung.com>  Tue, 28 Feb 2012 18:06:06 +0900
-
-evas (1.1.0+svn.67705slp2+build04) unstable; urgency=low
-
-  * Package Upload
-  * Enabling pixman flag
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.67705slp2+build04
-
- -- Sanghee Park <sh15.park@samsung.com>  Tue, 28 Feb 2012 15:18:38 +0900
-
-evas (1.1.0+svn.67705slp2+build03) unstable; urgency=low
-
-  * Upload Package
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.67705slp2+build03
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Fri, 24 Feb 2012 18:40:14 +0900
-
-evas (1.1.0+svn.67705slp2+build02) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.67705slp2+build02
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Fri, 24 Feb 2012 18:19:49 +0900
-
-evas (1.1.0+svn.67705slp2+build01) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.67705slp2+build01
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Wed, 15 Feb 2012 19:00:39 +0900
-
-evas (1.1.0+svn.66966slp2+build04) unstable; urgency=low
-
-  * Package Upload
-  * Important Changes
-       [evas_textblock] fixed a bug about deleting REPLACEMENT_CHAR
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.66966slp2+build04
-
- -- WooHyun Jung <wh0705.jung@samsung.com>  Fri, 10 Feb 2012 10:00:47 +0900
-
-evas (1.1.0+svn.66966slp2+build03) unstable; urgency=low
-
-  * Package Upload
-  * Applying direct rendering
-  * Applying fastpath
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.66966slp2+build03
-
- -- Sanghee Park <sh15.park@samsung.com>  Thu, 09 Feb 2012 17:03:02 +0900
-
-evas (1.1.0+svn.66966slp2+build02) unstable; urgency=low
-
-  * Package Upload
-  * Important Changes
-       [textblock] merge with 67696 for fixing BS when trying markup_to_utf8 with invalid escapes
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.66966slp2+build02
-
- -- WooHyun Jung <wh0705.jung@samsung.com>  Mon, 06 Feb 2012 12:09:21 +0900
-
-evas (1.1.0+svn.66966slp2+build01) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.66966slp2+build01
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Mon, 16 Jan 2012 18:29:22 +0900
-
-evas (1.1.0+svn.65865slp2+build05) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.65865slp2+build05
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Thu, 12 Jan 2012 15:51:52 +0900
-
-evas (1.1.0+svn.65865slp2+build04) unstable; urgency=low
-
-  * Repackaging
-  * Git: slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.65865slp2+build04
-
- -- ChunEon Park <chuneon.park@samsung.com>  Fri, 30 Dec 2011 15:06:07 +0900
-
-evas (1.1.0+svn.65865slp2+build03) unstable; urgency=low
-
-  * Upstream merge r66111
-  * Git: slp-scm.sec.samsung.net:slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.65865slp2+build03
-
- -- Tae-Hwan Kim <the81.kim@samsung.com>  Fri, 23 Dec 2011 18:09:02 +0900
-
-evas (1.1.0+svn.65865slp2+build02) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp-scm.sec.samsung.net:slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.65865slp2+build02
-
- -- ChunEon Park <chuneon.park@samsung.com>  Wed, 21 Dec 2011 19:37:00 +0900
-
-evas (1.1.0+svn.65865slp2+build01) unstable; urgency=low
-
-  * Package Upload for migration
-  * Git: slp-scm.sec.samsung.net:slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.65865slp2+build01
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Thu, 08 Dec 2011 13:46:34 +0900
-
-evas (1.1.0+svn.65614slp2+build01) unstable; urgency=low
-
-  * Package Upload
-  * Git: slp-scm.sec.samsung.net:slp/pkgs/e/evas
-  * Tag: evas_1.1.0+svn.65614slp2+build01
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Tue, 29 Nov 2011 13:49:32 +0900
-
-evas (1.1.0+svn.65326slp2+build01) unstable; urgency=low
-
-  * Merge with upstream @65326
-
- -- Mike McCormack <mj.mccormack@samsung.com>  Thu, 17 Nov 2011 15:23:54 +0900
-
-evas (1.1.0+svn.65301slp2+build01) unstable; urgency=low
-
-  * Merge with upstream @65301
-
- -- Mike McCormack <mj.mccormack@samsung.com>  Thu, 17 Nov 2011 08:36:59 +0900
-
-evas (1.0.0.001+svn.65044slp2+build02) unstable; urgency=low
-
-  * enable the Evas_GL
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.65044slp2+build02
-
- -- ChunEon Park <chuneon.park@samsung.com>  Fri, 11 Nov 2011 16:59:30 +0900
-
-evas (1.0.0.001+svn.65044slp2+build01) unstable; urgency=low
-
-  * Merge with upstream @65044
-
- -- ChunEon Park <chuneon.park@samsung.com>  Fri, 11 Nov 2011 16:35:00 +0900
-
-evas (1.0.0.001+svn.64979slp2+build01) unstable; urgency=low
-
-  * Merge with upstream @64979
-
- -- Mike McCormack <mj.mccormack@samsung.com>  Thu, 10 Nov 2011 13:52:01 +0900
-
-evas (1.0.0.001+svn.64664slp2+build04) unstable; urgency=low
-
-  * Upload Package
-  * Important Changes
-       add ENV related with font dpi
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.64664slp2+build04
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Wed, 09 Nov 2011 17:19:23 +0900
-
-evas (1.0.0.001+svn.64664slp2+build03) unstable; urgency=low
-
-  * Upload package
-  * Important Changes
-       add animation image code to gl engine.
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.64664slp2+build03
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Fri, 04 Nov 2011 00:14:12 +0900
-
-evas (1.0.0.001+svn.64664slp2+build02) unstable; urgency=low
-
-  * Make sure elementary builds correctly
-
- -- Mike McCormack <mj.mccormack@samsung.com>  Thu, 03 Nov 2011 17:48:25 +0900
-
-evas (1.0.0.001+svn.64664slp2+build01) unstable; urgency=low
-
-  * Merge with upstream @64664
-
- -- Mike McCormack <mj.mccormack@samsung.com>  Thu, 03 Nov 2011 16:41:02 +0900
-
-evas (1.0.0.001+svn.62695slp2+build45) unstable; urgency=low
-
-  * Upload package
-  * partial merge - fixed side effect (map clipping problem)
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build45
-
- -- ChunEon Park <chuneon.park@samsung.com>  Fri, 28 Oct 2011 14:39:05 +0900
-
-evas (1.0.0.001+svn.62695slp2+build44) unstable; urgency=low
-
-  * Upload package
-  * The left and right pixel duplication for interpolation had the WRONG PIXELS.
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build44
-
- -- Seungsoo woo <om101.woo@samsung.com>  Thu, 27 Oct 2011 13:06:32 +0900
-
-evas (1.0.0.001+svn.62695slp2+build43) unstable; urgency=low
-
-  * Upload package
-  * Evas GL Extensions + a bug fix by Sung W. Park from svn(64139)
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build43
-
- -- Seungsoo Woo <om101.woo@samsung.com>  Tue, 25 Oct 2011 16:18:25 +0900
-
-evas (1.0.0.001+svn.62695slp2+build42) unstable; urgency=low
-
-  * Upload Package
-  * partial merge
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build42
-
- -- ChunEon Park <chuneon.park@samsung.com>  Tue, 25 Oct 2011 15:26:52 +0900
-
-evas (1.0.0.001+svn.62695slp2+build41) unstable; urgency=low
-
-  * Upload Package
-  * Optimized harfbuzz usage
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build41
-
- -- ChunEon Park <chuneon.park@samsung.com>  Thu, 20 Oct 2011 14:49:01 +0900
-
-evas (1.0.0.001+svn.62695slp2+build40) unstable; urgency=low
-
-  * Upload Package
-  * Unnecessary image_dirty_set is removed.
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build40
-
- -- Seungsoo Woo <om101.woo@samsung.com>  Wed, 19 Oct 2011 21:37:54 +0900
-
-evas (1.0.0.001+svn.62695slp2+build39) unstable; urgency=low
-
-  * Upload Package
-  * Important Changes
-        fix the gl engine's animated code.
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build39
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Wed, 19 Oct 2011 10:23:23 +0900
-
-evas (1.0.0.001+svn.62695slp2+build38) unstable; urgency=low
-
-  * upload package
-  * evas_object_image about map and unmap pairing
-  * Git :* Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build38
-
- -- Sanghee Park <sh15.park@samsung.com>  Mon, 17 Oct 2011 19:39:46 +0900
-
-evas (1.0.0.001+svn.62695slp2+build37) unstable; urgency=low
-
-  * Upload package
-  * fix gl pipeline problem with textures and map and the wrong program id
-  * fix shader for nv12
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build37
-
- -- Seungsoo woo <om101.woo@samsung.com>  Thu, 13 Oct 2011 13:49:21 +0900
-
-evas (1.0.0.001+svn.63811+build02) unstable; urgency=low
-
-  * cherry-pick 64030 from upstream (depends on new eina)
-
- -- Mike McCormack <mj.mccormack@samsung.com>  Thu, 13 Oct 2011 12:49:22 +0900
-
-evas (1.0.0.001+svn.62695slp2+build36) unstable; urgency=low
-
-  * Upload Package
-  * Important Changes
-        modify gifloader's interace code
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build36
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Wed, 12 Oct 2011 22:58:00 +0900
-
-evas (1.0.0.001+svn.62695slp2+build35) unstable; urgency=low
-
-  * Upload package
-  * Float precision of vertex shader is fixed
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build35
-
- -- Seungsoo Woo <om101.woo@samsung.com>  Wed, 12 Oct 2011 13:45:30 +0900
-
-evas (1.0.0.001+svn.62695slp2+build34) unstable; urgency=low
-
-  * Package Upload
-  * Important Changes
-        partial rollback: evas_object_smart.c
-  * Git: slp-scm.sec.samsung.net:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build34
-
- -- Shinwoo Kim <cinoo.kim@samsung.com>  Tue, 11 Oct 2011 18:04:21 +0900
-
-evas (1.0.0.001+svn.62695slp2+build33) unstable; urgency=low
-
-  * Upload package
-  * Changing image format of egl_image to BGRA
-  * Update shaders from svn
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build33
-
- -- Seungsoo Woo <om101.woo@samsung.com>  Tue, 11 Oct 2011 09:10:47 +0900
-
-evas (1.0.0.001+svn.63811slp2+build01) unstable; urgency=low
-
-  * Merge with upstream
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.63811slp2+build01
-
- -- Mike McCormack <mj.mccormack@samsung.com>  Wed, 05 Oct 2011 14:39:09 +0900
-
-evas (1.0.0.001+svn.62695slp2+build32) unstable; urgency=low
-
-  * Package Upload.
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build32
-
- -- Daniel Juyung Seo <juyung.seo@samsung.com>  Thu, 06 Oct 2011 20:04:55 +0900
-
-evas (1.0.0.001+svn.62695slp2+build31) unstable; urgency=low
-
-  * Upload Package
-  * Important Changes
-        impelment scale down decoding feature.
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build31
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Tue, 04 Oct 2011 21:20:24 +0900
-
-evas (1.0.0.001+svn.62695slp2+build30) unstable; urgency=low
-
-  * Font vertex shader float precision is modified.
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build30
-
- -- Seungsoo Woo <om101.woo@samsung.com>  Tue, 04 Oct 2011 13:16:00 +0900
-
-evas (1.0.0.001+svn.62695slp2+build29) unstable; urgency=low
-
-  * Upload Package
-  * Important Changes
-        evas grab event bug fix
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build29
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Tue, 27 Sep 2011 16:37:38 +0900
-
-evas (1.0.0.001+svn.62695slp2+build28) unstable; urgency=low
-
-  * Rollback critical event handling commit.
-  * Important Changes
-    Revert "    evas grab event bug fix"
-    Revert "    evas_object_main remove duplicated code related with grap count"
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build28
-
- -- Daniel Juyung Seo <juyung.seo@samsung.com>  Mon, 26 Sep 2011 09:41:54 +0900
-
-evas (1.0.0.001+svn.62695slp2+build27) unstable; urgency=low
-
-  * Upload Package
-  * Important Changes
-        evas_object_main remove duplicated code related with grap count
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build27
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Sat, 24 Sep 2011 18:43:47 +0900
-
-evas (1.0.0.001+svn.62695slp2+build26) unstable; urgency=low
-
-  * Upload Package
-  * Important Changes
-        evas grab event bug fix
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build26
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Fri, 23 Sep 2011 19:01:55 +0900
-
-evas (1.0.0.001+svn.62695slp2+build25) unstable; urgency=low
-
-  * Upload Package
-  * Important Changes
-        evas_jpeg_loader
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build25
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Wed, 21 Sep 2011 20:44:31 +0900
-
-evas (1.0.0.001+svn.62695slp2+build24) unstable; urgency=low
-
-  * Package Upload
-  * Important Changes
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build24
-
- -- WooHyun Jung <wh0705.jung@samsung.com>  Tue, 20 Sep 2011 18:18:42 +0900
-
-evas (1.0.0.001+svn.62695slp2+build23) unstable; urgency=low
-
-  * Package Upload.
-  * Important Changes
-       [Textblock] Replace the rbtree index with a fixed ptr array (changeset 63474)
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build23
-
- -- Myungjae Lee <mjae.lee@samsung.com>  Mon, 19 Sep 2011 20:31:31 +0900
-
-evas (1.0.0.001+svn.62695slp2+build22) unstable; urgency=low
-
-  * Package Upload.
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build22
-
- -- Ilkook Yun <ilkook.yun@samsung.com>  Sat, 17 Sep 2011 19:48:41 +0900
-
-evas (1.0.0.001+svn.62695slp2+build21) unstable; urgency=low
-
-  * Package Upload.
-  * Important Changes
-       Rollback to evas_1.0.0.001+svn.62695slp2+build18.
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build21
-
- -- Daniel Juyung Seo <juyung.seo@samsung.com>  Fri, 16 Sep 2011 11:13:32 +0900
-
-evas (1.0.0.001+svn.62695slp2+build20) unstable; urgency=low
-
-  * Package Upload.
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build20
-
- -- Daniel Juyung Seo <juyung.seo@samsung.com>  Thu, 15 Sep 2011 17:56:29 +0900
-
-evas (1.0.0.001+svn.62695slp2+build19) unstable; urgency=low
-
-  * Upload Package
-  * Important Changes
-       cherrypick upstream r62856 for elm_factory.
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build19
-
- -- Daniel Juyung Seo <juyung.seo@samsung.com>  Thu, 15 Sep 2011 15:56:32 +0900
-
-evas (1.0.0.001+svn.62695slp2+build18) unstable; urgency=low
-
-  * Upload Package
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build18
-
- -- ChunEon Park <chuneon.park@samsung.com>  Wed, 14 Sep 2011 09:48:50 +0900
-
-evas (1.0.0.001+svn.62695slp2+build17) unstable; urgency=low
-
-  * Upload Package
-  * Fixed font noise issue
-  * Implement rotation decoding for image viewer
-  * fix after image problem of gif
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build17
-
- -- ChunEon Park <chuneon.park@samsung.com>  Fri, 09 Sep 2011 18:50:03 +0900
-
-evas (1.0.0.001+svn.62695slp2+build01) unstable; urgency=low
-
-  * [SVN EFL Migration] evas in SLP is merged with SVN r62695
-  * Important Changes
-       [Migration upstream r62695]
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.62695slp2+build01
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Fri, 02 Sep 2011 18:42:21 +0900
-
-evas (1.0.0.001+svn.60295slp2+build15) unstable; urgency=low
-
-  * Upload Package
-  * Fixed the BindFramebuffer issue
-  * Adding BGRA support
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.60295slp2+build15
-
- -- Seungsoo Woo <om101.woo@samsung.com>  Fri, 26 Aug 2011 08:18:35 +0900
-
-evas (1.0.0.001+svn.60295slp2+build14) unstable; urgency=low
-
-  * Upload Package
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.60295slp2+build14
-
- -- Seungsoo Woo <om101.woo@samsung.com>  Thu, 18 Aug 2011 16:35:43 +0900
-
-evas (1.0.0.001+svn.60295slp2+build13) unstable; urgency=low
-
-  * Upload Package
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.60295slp2+build13
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Thu, 11 Aug 2011 14:00:15 +0900
-
-evas (1.0.0.001+svn.60295slp2+build12) unstable; urgency=low
-
-  * Upload Package
-  * Important Changes
-    Merge "   [Evas_image_load_gif] deal with the case frame's size is wrong if frame size exceed logigal screen size, we only draw logigal screen size area"
-       [Evas_image_load_gif] deal with the case frame's size is wrong
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.60295slp2+build12
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Tue, 09 Aug 2011 13:14:46 +0900
-
-evas (1.0.0.001+svn.60295slp2+build11) unstable; urgency=low
-
-  * Upload Package
-  * Important Changes
-       [evas_image_load_gif] fix gif loader memory leak
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.60295slp2+build11
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Fri, 05 Aug 2011 22:21:27 +0900
-
-evas (1.0.0.001+svn.60295slp2+build10) unstable; urgency=low
-
-  * Upload Package
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.60295slp2+build10
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Mon, 01 Aug 2011 17:57:53 +0900
-
-evas (1.0.0.001+svn.60295slp2+build09) unstable; urgency=low
-
-  * Upload Package:animation gif feature
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.60295slp2+build09
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Fri, 22 Jul 2011 22:39:41 +0900
-
-evas (1.0.0.001+svn.60295slp2+build08) unstable; urgency=low
-
-  * Added evas_event_refeed_event, evas_object_table_pack_get.
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.60295slp2+build08
-
- -- Daniel Juyung Seo <juyung.seo@samsung.com>  Wed, 20 Jul 2011 17:40:11 +0900
-
-evas (1.0.0.001+svn.60295slp2+build07) unstable; urgency=low
-
-  * Upload Package
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.60295slp2+build07
-
- -- Seungsoo Woo <om101.woo@samsung.com>  Mon, 18 Jul 2011 21:30:46 +0900
-
-evas (1.0.0.001+svn.60295slp2+build06) unstable; urgency=low
-
-  * Upload Package
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.60295slp2+build06
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Thu, 14 Jul 2011 22:37:51 +0900
-
-evas (1.0.0.001+svn.60295slp2+build05) unstable; urgency=low
-
-  * Upload Package : A routine to check Mali is added.
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.60295slp2+build05
-
- -- Seungsoo Woo <om101.woo@samsung.com>  Tue, 12 Jul 2011 11:04:12 +0900
-
-evas (1.0.0.001+svn.60295slp2+build04) unstable; urgency=low
-
-  * Package Upload : for fixing single line entry error
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.60295slp2+build04
-
- -- WooHyun Jung <wh0705.jung@samsung.com>  Thu, 07 Jul 2011 16:14:37 +0900
-
-evas (1.0.0.001+svn.60295slp2+build03) unstable; urgency=low
-
-  * Upload Package
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.60295slp2+build03
-
- -- Shinwoo Kim <cinoo.kim@samsung.com>  Wed, 06 Jul 2011 14:24:44 +0900
-
-evas (1.0.0.001+svn.60295slp2+build02) unstable; urgency=low
-
-  * Upload Package 
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.60295slp2+build02
-
- -- ChunEon Park <chuneon.park@samsung.com>  Tue, 05 Jul 2011 19:51:07 +0900
-
-evas (1.0.0.001+svn.60295slp2+build01) unstable; urgency=low
-
-  * [SVN EFL Migration] evas in SLP is merged with SVN r60295
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.60295slp2+build01
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Fri, 24 Jun 2011 18:09:50 +0900
-
-evas (1.0.0.001+svn.58227slp2+build15) unstable; urgency=low
-
-  * Upload Package
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58227slp2+build15
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Mon, 13 Jun 2011 18:01:27 +0900
-
-evas (1.0.0.001+svn.58227slp2+build14) unstable; urgency=low
-
-  * Added evas_event_thaw_eval API. Upstream merge with r59727.
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58227slp2+build14
-
- -- Daniel Juyung Seo <juyung.seo@samsung.com>  Thu, 02 Jun 2011 11:15:41 +0900
-
-evas (1.0.0.001+svn.58227slp2+build13) unstable; urgency=low
-
-  * Upload Package
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58227slp2+build13
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Mon, 16 May 2011 13:26:07 +0900
-
-evas (1.0.0.001+svn.58227slp2+build12) unstable; urgency=low
-
-  * Upload Package for fixing of smart_object caching problem
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58227slp2+build12
-
- -- ChunEon Park <chuneon.park@samsung.com>  Mon, 09 May 2011 15:12:27 +0900
-
-evas (1.0.0.001+svn.58227slp2+build11) unstable; urgency=low
-
-  * Upload Package for preload fix
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58227slp2+build11
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Wed, 04 May 2011 14:36:01 +0900
-
-evas (1.0.0.001+svn.58227slp2+build10) unstable; urgency=low
-
-  * Upload Package for binary shader
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58227slp2+build10
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Thu, 28 Apr 2011 20:29:28 +0900
-
-evas (1.0.0.001+svn.58227slp2+build09) unstable; urgency=low
-
-  * Upload Package
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58227slp2+build09
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Mon, 25 Apr 2011 16:53:30 +0900
-
-evas (1.0.0.001+svn.58227slp2+build08) unstable; urgency=low
-
-  * Package Upload : Delete Build results
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58227slp2+build08
-
- -- WooHyun Jung <wh0705.jung@samsung.com>  Tue, 19 Apr 2011 19:59:11 +0900
-
-evas (1.0.0.001+svn.58227slp2+build07) unstable; urgency=low
-
-  * Evas_cache_image : fix double deletion
-  * Git: git:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58227slp2+build07
-
- -- Myoungwoon Kim <myoungwoon.kim@samsung.com>  Tue, 19 Apr 2011 19:31:03 +0900
-
-evas (1.0.0.001+svn.58227slp2+build06) unstable; urgency=low
-
-  * Evas_cache_image : fix double deletion
-  * Git: git:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58227slp2+build06
-
- -- Myoungwoon Kim <myoungwoon.kim@samsung.com>  Tue, 19 Apr 2011 19:15:39 +0900
-
-evas (1.0.0.001+svn.58227slp2+build05) unstable; urgency=low
-
-  * [Fix Bug] fix evas cache inactive problem
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58227slp2+build05
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Tue, 19 Apr 2011 18:48:32 +0900
-
-evas (1.0.0.001+svn.58227slp2+build04) unstable; urgency=low
-
-  * [Fix Bug] fix evas cache double free problem
-     - reference : http://trac.enlightenment.org/e/changeset/58683
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58227slp2+build04
-
- -- Jiyoun Park <jy0703.park@samsung.com>  Fri, 15 Apr 2011 20:12:14 +0900
-
-evas (1.0.0.001+svn.58227slp2+build03) unstable; urgency=low
-
-  * [Fix Bug] fix evas-GL backend's screen rotation clip region.
-     - reference : http://trac.enlightenment.org/e/changeset/58381
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58227slp2+build03
-
- -- Gwangyeong Mun <kk.moon@samsung.com>  Mon, 11 Apr 2011 15:06:15 +0900
-
-evas (1.0.0.001+svn.58227slp2+build02) unstable; urgency=low
-
-  * Package Upload
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58227slp2+build02
-
- -- WooHyun Jung <wh0705.jung@samsung.com>  Mon, 11 Apr 2011 11:06:15 +0900
-
-evas (1.0.0.001+svn.58227slp2+build01) unstable; urgency=low
-
-  * [SVN EFL Migration] evas in SLP is merged with SVN r58227
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58227slp2+build01
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Tue, 05 Apr 2011 15:54:55 +0900
-
-evas (1.0.0.001+svn.58050slp2+build03) unstable; urgency=low
-
-  * Package upload for gcc 4.5
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58050slp2+build03
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Thu, 31 Mar 2011 22:32:07 +0900
-
-evas (1.0.0.001+svn.58050slp2+build02) unstable; urgency=low
-
-  * Rollback
-  * Git: slp-scm.sec.samsung.net:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58050slp2+build02
-
- -- Shinwoo Kim <cinoo.kim@samsung.com>  Tue, 29 Mar 2011 23:45:12 +0900
-
-evas (1.0.0.001+svn.58050slp2+build01) unstable; urgency=low
-
-  * [SVN EFL Migration] evas in SLP is merged with SVN r58050
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.58050slp2+build01
-
- -- Shinwoo Kim <cinoo.kim@samsung.com>  Tue, 29 Mar 2011 18:55:20 +0900
-
-evas (1.0.0.001+svn.57457slp2+build11) unstable; urgency=low
-
-  * Package Upload
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.57457slp2+build11
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Mon, 28 Mar 2011 11:52:53 +0900
-
-evas (1.0.0.001+svn.57457slp2+build10) unstable; urgency=low
-
-  * package upload
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.57457slp2+build10
-
- -- Hyoyoung Chang <hyoyoung.chang@samsung.com>  Fri, 18 Mar 2011 11:24:55 +0900
-
-evas (1.0.0.001+svn.57457slp2+build09) unstable; urgency=low
-
-  * package upload
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.57457slp2+build09
-
- -- Hyoyoung Chang <hyoyoung.chang@samsung.com>  Fri, 18 Mar 2011 09:59:17 +0900
-
-evas (1.0.0.001+svn.57457slp2+build08) unstable; urgency=low
-
-  * [SVN 57761] Fixed bug with different sizes in Korean text
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.57457slp2+build08
-
- -- Myungjae Lee <mjae.lee@samsung.com>  Tue, 15 Mar 2011 20:51:26 +0900
-
-evas (1.0.0.001+svn.57457slp2+build07) unstable; urgency=low
-
-  * [SVN EFL Migration] evas in SLP is merged with SVN r57457
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.57457slp2+build07
-
- -- Myungjae Lee <mjae.lee@samsung.com>  Wed, 09 Mar 2011 11:29:31 +0900
-
-evas (1.0.0.001+svn.57457slp2+build06) unstable; urgency=low
-
-  * [SVN EFL Migration] evas in SLP is merged with SVN r57457
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.57457slp2+build06
-
- -- Myungjae Lee <mjae.lee@samsung.com>  Wed, 09 Mar 2011 11:14:45 +0900
-
-evas (1.0.0.001+svn.57457slp2+build05) unstable; urgency=low
-
-  * Package Upload : Rollback
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.57457slp2+build05
-
- -- WooHyun Jung <wh0705.jung@samsung.com>  Tue, 08 Mar 2011 14:46:55 +0900
-
-evas (1.0.0.001+svn.57457slp2+build04) unstable; urgency=low
-
-  * Package Upload : Rollback
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.57457slp2+build04
-
- -- WooHyun Jung <wh0705.jung@samsung.com>  Tue, 08 Mar 2011 13:57:14 +0900
-
-evas (1.0.0.001+svn.57457slp2+build03) unstable; urgency=low
-
-  * Package Upload : Rollback
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.57457slp2+build03
-
- -- WooHyun Jung <wh0705.jung@samsung.com>  Tue, 08 Mar 2011 12:31:29 +0900
-
-evas (1.0.0.001+svn.57457slp2+build02) unstable; urgency=low
-
-  * Package upload : rollback
-  * Git: 165.213.180.234:/slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.57457slp2+build02
-
- -- WooHyun Jung <wh0705.jung@samsung.com>  Tue, 08 Mar 2011 11:06:18 +0900
-
-evas (1.0.0.001+svn.57457slp2+build01) unstable; urgency=low
-
-  * [SVN EFL Migration] evas in SLP is merged with SVN r57457
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.57457slp2+build01
-
- -- Myungjae Lee <mjae.lee@samsung.com>  Mon, 07 Mar 2011 17:28:02 +0900
-
-evas (1.0.0.001+svn.56240slp2+build04) unstable; urgency=low
-
-  * [textblock & encoding] 56806 & 56808 are updated
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.56240slp2+build04
-
- -- WooHyun Jung <wh0705.jung@samsung.com>  Fri, 11 Feb 2011 17:49:44 +0900
-
-evas (1.0.0.001+svn.56240slp2+build03) unstable; urgency=low
-
-  * [textblock & encoding] 56806 & 56808 are updated
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.56240slp2+build03 
-
- -- WooHyun Jung <wh0705.jung@samsung.com>  Thu, 10 Feb 2011 11:37:25 +0900
-
-evas (1.0.0.001+svn.56240slp2+build02) unstable; urgency=low
-
-  * [textblock & encoding] 56806 & 56808 are updated
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.56240slp2+build02
-
- -- Myungjae Lee <mjae.lee@samsung.com>  Thu, 10 Feb 2011 10:18:00 +0900
-
-evas (1.0.0.001+svn.56240slp2+build01) unstable; urgency=low
-
-  * [SVN EFL Migration] evas in SLP is merged with SVN r56240
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.56240slp2+build01
-
- -- WooHyun Jung <wh0705.jung@samsung.com>  Thu, 27 Jan 2011 12:21:12 +0900
-
-evas (1.0.0.001+svn.56068slp2+build01) unstable; urgency=low
-
-  * [SVN EFL Migration] evas in SLP is merged with SVN r56068
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.56068slp2+build01
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.56068slp2+build01
-
- -- WooHyun Jung <wh0705.jung@samsung.com>  Wed, 19 Jan 2011 16:15:15 +0900
-
-evas (1.0.0.001+svn.55757slp2+build03) unstable; urgency=low
-
-  * Apply SVN revision 56020 for fixing the bug of evas_object_textblock
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.55757slp2+build03 
-
- -- MyoungWoon Kim <myoungwoon.kim@samsung.com>  Tue, 11 Jan 2011 10:50:02 +0900
-
-evas (1.0.0.001+svn.55757slp2+build02) unstable; urgency=low
-
-  * Apply SVN revision 55977 for fps
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.55757slp2+build02
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Mon, 10 Jan 2011 14:27:38 +0900
-
-evas (1.0.0.001+svn.55757slp2+build01) unstable; urgency=low
-
-  * [SVN EFL Migration] evas in SLP is merged with SVN r55757
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.55757slp2+build01
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Mon, 03 Jan 2011 21:16:52 +0900
-
-evas (1.0.0.001+svn.55559slp2+build01) unstable; urgency=low
-
-  * [SVN EFL Migration] evas in SLP is merged with SVN r55559
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.55559slp2+build01
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Wed, 22 Dec 2010 19:58:54 +0900
-
-evas (1.0.0.001+svn.55375slp2+build03) unstable; urgency=low
-
-  * [src/lib/canvas/evas_map.c] Rollbacked cedric's patch.
-  * Changeset 55335
-  * Timestamp: 12/06/10 14:28:38 (8 days ago)
-  * Author: cedric
-  * Message: evas: notice object change on map color change.
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.55375slp2+build03
-
- -- Juyung Seo <juyung.seo@samsung.com>  Wed, 15 Dec 2010 19:52:30 +0900
-
-evas (1.0.0.001+svn.55375slp2+build02) unstable; urgency=low
-
-  * [SVN EFL Migration] evas in SLP is merged into SVN r55375
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.55375slp2+build02
-
- -- Juyung Seo <juyung.seo@samsung.com>  Wed, 15 Dec 2010 10:25:52 +0900
-
-evas (1.0.0.001+svn.55375slp2+build01) unstable; urgency=low
-
-  * [SVN EFL Migration] evas in SLP is merged into SVN r55375
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.55375slp2+build01
-
- -- Juyung Seo <juyung.seo@samsung.com>  Tue, 14 Dec 2010 17:46:15 +0900
-
-evas (1.0.0.001+svn.55064slp2+build08) unstable; urgency=low
-
-  * merged image masking code (brett's work)
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.55064slp2+build08
-
- -- ChunEon Park <chuneon.park@samsung.com>  Tue, 14 Dec 2010 15:50:37 +0900
-
-evas (1.0.0.001+svn.55064slp2+build07) unstable; urgency=low
-
-  * [SVN EFL Migration] evas in SLP is merged into SVN r55375
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.55064slp2+build07
-
- -- Juyung Seo <juyung.seo@samsung.com>  Tue, 14 Dec 2010 14:51:30 +0900
-
-evas (1.0.0.001+svn.55064slp2+build06) unstable; urgency=low
-
-  * [debian/rules] removed -lm -ldl options
-    + fixed '--as-needed' bug in opengl-es-mali400mp driver.
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.55064slp2+build06
-
- -- Gwanglim Lee <gl77.lee@samsung.com>  Sat, 11 Dec 2010 01:09:54 +0900
-
-evas (1.0.0.001+svn.55064slp2+build05) unstable; urgency=low
-
-  * [debian/rules] Added -lm -ldl in front of as-needed.
-  * Git: 165.213.180.234:slp/pkgs/e/evas
-  * Tag: evas_1.0.0.001+svn.55064slp2+build05
-
- -- Juyung Seo <juyung.seo@samsung.com>  Fri, 10 Dec 2010 11:45:56 +0900
-
-evas (1.0.0.001+svn.55064slp2+build04) unstable; urgency=low
-
-  * [debian/rules] Added -lm -ldl in front of as-needed.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.55064slp2+build04
-
- -- Juyung Seo <juyung.seo@samsung.com>  Fri, 10 Dec 2010 11:31:53 +0900
-
-evas (1.0.0.001+svn.55064slp2+build03) unstable; urgency=low
-
-  * [SVN 55064 Merge]
-  * Update to SVN Revision 55064.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.55064slp2+build03
-
- -- MyoungWoon Kim <myoungwoon.kim@samsung.com>  Thu, 02 Dec 2010 14:19:20 +0900
-
-evas (1.0.0.001+svn.55064slp2+build02) unstable; urgency=low
-
-  * Rollback to evas_1.0.0.001+svn.51480slp2+build26.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.55064slp2+build02
-
- -- Juyung Seo <juyung.seo@samsung.com>  Thu, 02 Dec 2010 09:44:45 +0900
-
-evas (1.0.0.001+svn.55064slp2+build01) unstable; urgency=low
-
-  * [SVN 55064 Merge]
-  * Update to SVN Revision 55064.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.55064slp2+build01
-
- -- MyoungWoon Kim <myoungwoon.kim@samsung.com>  Thu, 02 Dec 2010 09:08:43 +0900
-
-evas (1.0.0.001+svn.51480slp2+build26) unstable; urgency=low
-
-  * [SVN 54790 Merge]
-  * Update to SVN Revision 54790.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build26
-
- -- Juyung Seo <juyung.seo@samsung.com>  Fri, 26 Nov 2010 15:15:40 +0900
-
-evas (1.0.0.001+svn.51480slp2+build22) unstable; urgency=low
-
-  * SVN(54355) merged - add FLAG_ON_SCROLL.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build22 
-
- -- WooHyun Jung <wh0705.jung@samsung.com>  Wed, 10 Nov 2010 10:26:52 +0900
-
-evas (1.0.0.001+svn.51480slp2+build21) unstable; urgency=low
-
-  * SVN(54157) merged - Fixed the bug about searching the glyph.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build21
-
- -- MyoungWoon Kim <myoungwoon.kim@samsung.com>  Wed, 10 Nov 2010 09:16:46 +0900
-
-evas (1.0.0.001+svn.51480slp2+build20) unstable; urgency=low
-
-  * add libsm-dev dependency - requested by Mike
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build20
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Tue, 09 Nov 2010 11:18:04 +0900
-
-evas (1.0.0.001+svn.51480slp2+build19) unstable; urgency=low
-
-  * bugfix text selection range
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build19
-
- -- Hyoyoung Chang <hyoyoung.chang@samsung.com>  Sat, 30 Oct 2010 16:57:13 +0900
-
-evas (1.0.0.001+svn.51480slp2+build18) unstable; urgency=low
-
-  * SVN 52782 merged: evas: fix rendering of object with color (*,*,*,0) and
-    render_op != BLEND
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build18
-
- -- Seokjae Jeong <seok.j.jeong@samsung.com>  Mon, 25 Oct 2010 23:58:18 +0900
-
-evas (1.0.0.001+svn.51480slp2+build17) unstable; urgency=low
-
-  * [SVN Merge] 53434
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build17
-
- -- Jeonghyun Yun <jh0506.yun@samsung.com>  Fri, 15 Oct 2010 16:57:30 +0900
-
-evas (1.0.0.001+svn.51480slp2+build16) unstable; urgency=low
-
-  * [Last character show - Password feature]
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build16
-
- -- ChunEon Park <chuneon.park@samsung.com>  Thu, 14 Oct 2010 16:26:19 +0900
-
-evas (1.0.0.001+svn.51480slp2+build15) unstable; urgency=low
-
-  * [Last character show - Password feature]
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build15
-
- -- Juyung Seo <juyung.seo@samsung.com>  Wed, 13 Oct 2010 16:35:21 +0900
-
-evas (1.0.0.001+svn.51480slp2+build14) unstable; urgency=low
-
-  * [SVN Merge] Applied SVN merge.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build14
-
- -- Juyung Seo <juyung.seo@samsung.com>  Tue, 12 Oct 2010 10:42:41 +0900
-
-evas (1.0.0.001+svn.51480slp2+build13) unstable; urgency=low
-
-  * [Patch Rollback] Rollbacked below patch. [SVN 53093 Merge]
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build13
-
- -- Juyung Seo <juyung.seo@samsung.com>  Fri, 08 Oct 2010 20:53:37 +0900
-
-evas (1.0.0.001+svn.51480slp2+build12) unstable; urgency=low
-
-  * [SVN Merge] rev from 51648 to 51738, and rev 51741
-  * [eng_image_size_set] fix resize bug for the dynamic texture.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build12
-
- -- Gwanglim Lee <gl77.lee@samsung.com>  Thu, 07 Oct 2010 22:06:26 +0900
-
-evas (1.0.0.001+svn.51480slp2+build11) unstable; urgency=low
-
-  * [SVN 53093 Patch] evas_font_load patch.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build11
-
- -- Juyung Seo <juyung.seo@samsung.com>  Wed, 06 Oct 2010 19:23:10 +0900
-
-evas (1.0.0.001+svn.51480slp2+build10) unstable; urgency=low
-
-  * [evas_gl_engine] dynamic texture bug fixes.
-    + fix wrong reference count (rev.53207)
-    + fix invalid stride (rev.53207)
-  * [evas_gl_context] fix texture mapping bug.
-  * [evas_blit_main] (rev.51557)
-  * [evas_map] fix dirty areas bug when maps got enalbed and disabled.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build10
-
- -- Gwanglim Lee <gl77.lee@samsung.com>  Tue, 05 Oct 2010 00:04:54 +0900
-
-evas (1.0.0.001+svn.51480slp2+build09) unstable; urgency=low
-
-  * [textblock] added evas_textblock_cursor_content_get function for edje
-  entry
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build09
-
- -- Myungjae Lee <mjae.lee@samsung.com>  Wed, 29 Sep 2010 00:54:00 +0900
-
-evas (1.0.0.001+svn.51480slp2+build08) unstable; urgency=low
-
-  * repackaging 
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build07
-
- -- ChunEon Park <chuneon.park@samsung.com>  Tue, 28 Sep 2010 22:31:22 +0900
-
-evas (1.0.0.001+svn.51480slp2+build06) unstable; urgency=low
-
-  * repackaging for entry password. 
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build06
-
- -- ChunEon Park <chuneon.park@samsung.com>  Mon, 20 Sep 2010 20:18:48 +0900
-
-evas (1.0.0.001+svn.51480slp2+build05) unstable; urgency=low
-
-  * [textblock] bug fix about evas_textblock_cursor_range_text_get by Tom
-  * [textblock] fixed bug related to password mode
-  * svn update: 51515: fixed most of the cases on which a cursor was not drawn correctly.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build05
-
- -- Jihoon Kim <jihoon48.kim@samsung.com>  Fri, 17 Sep 2010 11:32:13 +0900
-
-evas (1.0.0.001+svn.51480slp2+build03) unstable; urgency=low
-
-  * add as-needed
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build03
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Wed, 15 Sep 2010 09:38:24 +0900
-
-evas (1.0.0.001+svn.51480slp2+build02) unstable; urgency=low
-
-  * repackaging
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build02
-
- -- ChunEon Park <chuneon.park@samsung.com>  Sat, 11 Sep 2010 00:23:51 +0900
-
-evas (1.0.0.001+svn.51480slp2+build01) unstable; urgency=low
-
-  * efl 1.0 alpha upgrade
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_1.0.0.001+svn.51480slp2+build01
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Tue, 31 Aug 2010 22:42:34 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build19) unstable; urgency=low
-
-  * Disabled word cache.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build19
-
- -- Juyung Seo <juyung.seo@samsung.com>  Wed, 25 Aug 2010 08:51:38 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build18) unstable; urgency=low
-
-  * Fixed segfault problem with GL engine when rotating.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build18
-
- -- Sangjin Lee <lsj119@samsung.com>  Fri, 30 Jul 2010 22:51:48 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build17) unstable; urgency=low
-
-  * Fixed segfault problem with GL engine when rotating.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build17
-
- -- Gwanglim Lee <gl77.lee@samsung.com>  Fri, 30 Jul 2010 22:27:37 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build16) unstable; urgency=low
-
-  * Fixed segfault problem with GL engine when rotating.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build16
-
- -- Gwanglim Lee <gl77.lee@samsung.com>  Fri, 30 Jul 2010 21:21:34 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build15) unstable; urgency=low
-
-  * Fixed word cache & gl bug (from Brett Nash)
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build15
-
- -- Juyung Seo <juyung.seo@samsung.com>  Fri, 30 Jul 2010 14:16:57 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build14) unstable; urgency=low
-
-  * Disabled word cache 
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build14
-
- -- ChunEon Park <chuneon.park@samsung.com>  Fri, 30 Jul 2010 11:42:47 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build13) unstable; urgency=low
-
-  * [word cache] Disabled again. 
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build13
-
- -- ChunEon Park <chuneon.park@samsung.com>  Thu, 29 Jul 2010 20:27:09 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build12) unstable; urgency=low
-
-  * [word cache] Enabled word cache only not metric cache.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build12
-
- -- Juyung Seo <juyung.seo@samsung.com>  Wed, 28 Jul 2010 18:21:38 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build11) unstable; urgency=low
-
-  * [word cache & metric cache] Disabled word cache & metric cache.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build11
-
- -- Juyung Seo <juyung.seo@samsung.com>  Wed, 28 Jul 2010 18:10:37 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build10) unstable; urgency=low
-
-  * [Neon&WordCache] Added wordcache and neon features.
-  * [rotation] 90 degree rotation with neon bug is fixed.
-  * Git: 165.213.180.234:/git/slp/pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build10
-
- -- Juyung Seo <juyung.seo@samsung.com>  Wed, 28 Jul 2010 14:01:06 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build09) unstable; urgency=low
-
-  * Modified no_swap codes in order to ensure the correct screen appearance.
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build09
-
- -- ChunEon Park <chuneon.park@samsung.com>  Wed, 07 Jul 2010 20:07:28 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build08) unstable; urgency=low
-
-  * Modified no_swap codes in order to ensure the correct screen appearance.
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build08
-
- -- Gwanglim Lee <gl77.lee@samsung.com>  Fri, 02 Jul 2010 13:55:18 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build07) unstable; urgency=low
-
-  * add no_swap info to GLES engine for supporting lock/unlock feature.
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build07
-
- -- Gwanglim Lee <gl77.lee@samsung.com>  Tue, 29 Jun 2010 18:47:33 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build06) unstable; urgency=low
-
-  * rev 49790 partial update to resolve rotation bug when using GLES backend.
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build06
-
- -- Gwanglim Lee <gl77.lee@samsung.com>  Tue, 22 Jun 2010 16:38:28 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build05) unstable; urgency=low
-
-  * Neonize on.
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build05
-
- -- Daniel Juyung Seo <juyung.seo@samsung.com>  Mon, 14 Jun 2010 14:51:16 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build04) unstable; urgency=low
-
-  * Packaging.
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build04
-
- -- Daniel Juyung Seo <juyung.seo@samsung.com>  Thu, 10 Jun 2010 21:09:50 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build03) unstable; urgency=low
-
-  * Packaging.
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build03
-
- -- Daniel Juyung Seo <juyung.seo@samsung.com>  Thu, 10 Jun 2010 21:04:35 +0900
-
-evas (0.9.9.060+svn.49540slp2+3build02) unstable; urgency=low
-
-  * Packaging.
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3build02
-
- -- Daniel Juyung Seo <juyung.seo@samsung.com>  ëª? 10  6??2010 21:00:53 +0900
-
-evas (0.9.9.060+svn.49540slp2+3) unstable; urgency=low
-
-  * Packaging.
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+3
-
- -- Daniel Juyung Seo <juyung.seo@samsung.com>  Thu, 10 Jun 2010 20:46:54 +0900
-
-evas (0.9.9.060+svn.49540slp2+2) unstable; urgency=low
-
-  * Packaging.
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+2
-
- -- Daniel Juyung Seo <juyung.seo@samsung.net>  Thu, 10 Jun 2010 20:46:08 +0900
-
-evas (0.9.9.060+svn.49540slp2+1) unstable; urgency=low
-
-  * Packaging.
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs/evas
-  * Tag: evas_0.9.9.060+svn.49540slp2+1
-
- -- Daniel Juyung Seo <juyung.seo@samsung.com>  Thu, 10 Jun 2010 20:35:05 +0900
-
-evas (0.9.9.060+svn.49540slp2+0) unstable; urgency=low
-
-  * Update opensource EFL from SVN
-  * SVN revision: 49540 (Total EFL revision: 49550)
-  * Tag: evas_0.9.9.060+svn.49540slp2+0
-
- -- Daniel Juyung Seo <juyung.seo@samsung.com>  Thu, 10 Jun 2010 15:50:44 +0900
-
-evas (0.9.9.060+svn20100304slp2+7) unstable; urgency=low
-
-  * Implemented bmp and wbmp image loader module without 3rd party codec.
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL
-  * Tag: evas_0.9.9.060+svn20100304slp2+7
-
- -- YoungHoon Jung <yhoon.jung@samsung.com>  Wed, 21 Apr 2010 17:09:32 +0900
-
-evas (0.9.9.060+svn20100304slp2+6) unstable; urgency=low
-
-  * Bug fix - evas textblock cursor problem
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL
-  * Tag: evas_0.9.9.060+svn20100304slp2+6
-
- -- Myungjae Lee <mjae.lee@samsung.com>  Thu, 16 Apr 2010 20:53:00 +0900
-
-evas (0.9.9.060+svn20100304slp2+5) unstable; urgency=low
-
-  * Rollback entry cursor bug fix
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL
-  * Tag: evas_0.9.9.060+svn20100304slp2+5
-
- -- Myungjae Lee <mjae.lee@samsung.com>  Thu, 16 Apr 2010 11:28:00 +0900
-
-evas (0.9.9.060+svn20100304slp2+4) unstable; urgency=low
-
-  * Updated package version due to tag
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL
-  * Tag: evas_0.9.9.060+svn20100304slp2+4
-
- -- Myungjae Lee <mjae.lee@samsung.com>  Thu, 15 Apr 2010 20:37:00 +0900
-
-evas (0.9.9.060+svn20100304slp2+3) unstable; urgency=low
-
-  * Bug fix - evas textblock cursor problem
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL
-  * Tag: evas_0.9.9.060+svn20100304slp2+3
-
- -- Myungjae Lee <mjae.lee@samsung.com>  Thu, 15 Apr 2010 19:57:00 +0900
-
-evas (0.9.9.060+svn20100304slp2+2) unstable; urgency=low
-
-  * change control - add libfribidi-dev, libharfbuzz-dev
-  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL
-  * Tag: evas_0.9.9.060+svn20100304slp2+2
-
- -- Jihoon Kim <jihoon48.kim@samsung.com>  Wed, 07 Apr 2010 17:15:28 +0900
-
-evas (0.9.9.060+svn20100304slp2+1) unstable; urgency=low
-
-  * change package version
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Thu, 25 Mar 2010 15:06:27 +0900
-
-evas (0.9.9.060+svn20100304-8) unstable; urgency=low
-
-  * added dependencies to libevas-dev.
-
- -- YoungHoon Jung <yhoon.jung@samsung.com>  Wed, 24 Mar 2010 11:19:14 +0900
-
-evas (0.9.9.060+svn20100304-7) unstable; urgency=low
-
-  * Remove fribidi, haffbuzz from evas 
-
- -- Jihoon Kim <jihoon48.kim@samsung.com>  Wed, 24 Mar 2010 11:32:22 +0900
-
-evas (0.9.9.060+svn20100304-6) unstable; urgency=low
-
-  * Clean up GLES/EGL stubs on EGL window surface gone.
-   + based on r47461, r47362 and r47386.
-    (upon a request from Gwanglim Lee<gl77.lee@samsung.com>)
-
- -- YoungHoon Jung <yhoon.jung@samsung.com>  Tue, 23 Mar 2010 20:38:02 +0900
-
-evas (0.9.9.060+svn20100304-5) unstable; urgency=low
-
-  * patched evas_wink.h and minor modifications.
-
- -- YoungHoon Jung <yhoon.jung@samsung.com>  Tue, 23 Mar 2010 16:19:47 +0900
-
-evas (0.9.9.060+svn20100304-4) unstable; urgency=low
-
-  * Change control file. (Add dependencies for harfbuzz, fribidi)
-
- -- Doyoun Kang <doyoun.kang@samsung.com>  Tue, 23 Mar 2010 15:12:52 +0900
-
-evas (0.9.9.060+svn20100304-3) unstable; urgency=low
-
-  * disabled wink codec for PNG, JPG, and GIF.
-
- -- YoungHoon Jung <yhoon.jung@samsung.com>  Mon, 22 Mar 2010 16:09:40 +0900
-
-evas (0.9.9.060+svn20100304-2) unstable; urgency=low
-
-  * implemented PNG/BMP/WBMP/JPEG/GIF image loaders using Wink Codec
-
- -- YoungHoon Jung <yhoon.jung@samsung.com>  Thu, 18 Mar 2010 13:52:18 +0900
-
-evas (0.9.9.060+svn20100304-1) unstable; urgency=low
-
-  * EFL_update_revision_46864
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Wed, 10 Mar 2010 16:06:34 +0900
-
-evas (0.9.9.060+svn20100203-8) unstable; urgency=low
-
-  * revision up to 46421 (Full merge)
-
- -- Sangjin Lee <lsj119@samsung.com>  Thu, 25 Feb 2010 19:29:30 +0900
-
-evas (0.9.9.060+svn20100203-7) unstable; urgency=low
-
-  * revision up to 46263 (partial merge)
-
- -- Doyoun Kang <doyoun.kang@samsung.com>  Thu, 18 Feb 2010 19:27:04 +0900
-
-evas (0.9.9.060+svn20100203-6) unstable; urgency=low
-
-  * revision up to 45829
-
- -- wonguk.jeong <wonguk.jeong@samsung.com>  Fri, 05 Feb 2010 20:52:34 +0900
-
-evas (0.9.9.060+svn20100203-5) unstable; urgency=low
-
-  * repack
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Thu, 04 Feb 2010 20:24:23 +0900
-
-evas (0.9.9.060+svn20100203-4) unstable; urgency=low
-
-  * force revision for i386
-
- -- sangho park <sangho.g.park@samsung.com>  Thu, 04 Feb 2010 18:54:47 +0900
-
-evas (0.9.9.060+svn20100203-3) unstable; urgency=low
-
-  * reupload
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Thu, 04 Feb 2010 11:27:11 +0900
-
-evas (0.9.9.060+svn20100203-2) unstable; urgency=low
-
-  * reupload
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Thu, 04 Feb 2010 05:45:58 +0900
-
-evas (0.9.9.060+svn20100203-1) unstable; urgency=low
-
-  * EFL_update_revision_45828
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Wed, 03 Feb 2010 16:39:20 +0900
-
-evas (0.9.9.060+svn20100119-1) unstable; urgency=low
-
-  * EFL_update_revision_45322
-
- -- Jihoon Kim <jihoon48.kim@samsung.com>  Tue, 19 Jan 2010 20:44:46 +0900
-
-evas (0.9.9.060+svn20100111-5) unstable; urgency=low
-
-  * Change required GLES deb package to opengl-es metapackage
-
- -- Gwanglim Lee <gl77.lee@samsung.com>  Thu, 14 Jan 2010 19:15:22 +0900
-
-evas (0.9.9.060+svn20100111-4) unstable; urgency=low
-
-  * libpng12 dependency add
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Tue, 12 Jan 2010 21:01:14 +0900
-
-evas (0.9.9.060+svn20100111-3) unstable; urgency=low
-
-  * reupload EFL i686
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Tue, 12 Jan 2010 17:35:26 +0900
-
-evas (0.9.9.060+svn20100111-2) unstable; urgency=low
-
-  * reupload EFL
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Mon, 11 Jan 2010 22:16:31 +0900
-
-evas (0.9.9.060+svn20100111-1) unstable; urgency=low
-
-  * update EFL revision 45026
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Mon, 11 Jan 2010 13:28:03 +0900
-
-evas (0.9.9.060+svn20091229-3) unstable; urgency=low
-
-  * Patch for i386 build (exclude opengl-es)
-
- -- Youmin Ha <youmin.ha@samsung.com>  Thu, 07 Jan 2010 21:28:44 +0900
-
-evas (0.9.9.060+svn20091229-2) unstable; urgency=low
-
-  * add depends (opengl-es-sgx540)
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Wed, 30 Dec 2009 19:31:45 +0900
-
-evas (0.9.9.060+svn20091229-1) unstable; urgency=low
-
-  * update EFL
-
- -- Jaehwan Kim <jae.hwan.kim@samsung.com>  Tue, 29 Dec 2009 14:27:02 +0900
-
-evas (0.9.9.060+svn20091112-3) unstable; urgency=low
-
-  * modify architecture value from all to any 
-
- -- Sangho Park <sangho.g.park@sangho.g.park>  Fri, 27 Nov 2009 15:39:53 +0900
-
-evas (0.9.9.060+svn20091112-2) unstable; urgency=low
-
-  * svn stable version
-
- -- Sangho Park <sangho.g.park@sangho.g.park>  Thu, 19 Nov 2009 17:39:02 +0900
-
-evas (0.9.9.060+svn20091112-1) unstable; urgency=low
-
-  * Clean up changelog
-
- -- Sangho Park <sangho.g.park@sangho.g.park>  Thu, 12 Nov 2009 23:27:21 +0100
-
-evas (0.9.9.060+svnYYYYMMDD-1) unstable; urgency=low
-
-  * Clean up changelog
-
- -- quaker <quaker66@gmail.com>  Thu, 22 Apr 2009 18:27:21 +0100
-
-evas (0.9.9.050+svnYYYYMMDD-1) unstable; urgency=low
-
-  * Clean up changelog
-
- -- quaker <quaker66@gmail.com>  Tue, 21 Apr 2009 19:13:59 +0100
diff --git a/debian/compat b/debian/compat
deleted file mode 100644 (file)
index 7ed6ff8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-5
diff --git a/debian/control b/debian/control
deleted file mode 100755 (executable)
index b60132f..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-Source: evas
-Section: libs
-Priority: optional
-Maintainer: Jaehwan Kim <jae.hwan.kim@samsung.com>,
- Sangjin Lee <lsj119@samsung.com>,
- Doyoun Kang <doyoun.kang@samsung.com>,
- YoungHoon Jung <yhoon.jung@samsung.com>,
- Myungjae Lee <mjae.lee@samsung.com>,
- Juyung Seo <juyung.seo@samsung.com>,
- Gwanglim Lee <gl77.lee@samsung.com>,
- Jeonghyun Yun <jh0506.yun@samsung.com>,
- Seokjae Jeong <seok.j.jeong@samsung.com>,
- MyoungWoon Kim <myoungwoon.kim@samsung.com>,
- ChunEon Park <chuneon.park@samsung.com>,
- Hyoyoung Chang <hyoyoung.chang@samsung.com>,
- WooHyun Jung <wh0705.jung@samsung.com>,
- Gwangyeong Mun <kk.moon@samsung.com>,
- Jiyoun Park <jy0703.park@samsung.com>,
- Shinwoo Kim <cinoo.kim@samsung.com>,
- Mike McCormack <mj.mccormack@samsung.com>
-Build-Depends: debhelper (>= 6),
- cdbs,
- libeet-dev (>= 1.1.0),
- libeina-dev (>= 0.0.2.060+svn20100304),
- libfreetype6-dev,
- libpng12-dev | libpng-dev,
- libx11-dev,
- libxrender-dev,
- x11proto-xext-dev,
- zlib1g,
- libjpeg8-dev,
- libtiff-dev,
- libfontconfig1-dev,
- libxpm-dev,
- doxygen,
- pkg-config,
- libtool,
- libxext-dev,
- opengl-es-dev,
- libfribidi-dev,
- libharfbuzz-dev,
- libgif-dev,
- libpixman-1-dev,
- libsm-dev
-Standards-Version: 3.8.1
-Homepage: http://www.enlightenment.org
-
-Package: libevas
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, libevas-engines (>= 0.9.9.060+svn20100304), libpng12-0
-Provides: libevas
-Conflicts: libevas
-Description: Enlightenment DR17 advanced canvas library
- Evas is an advanced canvas library, providing six engines for rendering: X11,
- OpenGL (hardware accelerated), DirectFB, the framebuffer, Microsoft Windows
- and Qtopia.
- .
- Due to its simple API, evas can be developed with rapidly, and cleanly.
- .
- This package contains the core library and a set of image loaders and/or savers
- for various formats: eet, gif, jpeg, png, svg, tiff, bmp, wbmp and xpm
-
-Package: libevas-doc
-Architecture: any
-Section: doc
-Depends: ${misc:Depends}
-Enhances: libevas-dev
-Description: Evas API Documentation
- Evas is an advanced canvas library, providing six engines for rendering: X11,
- OpenGL (hardware accelerated), DirectFB, the framebuffer, Microsoft Windows
- and Qtopia.
- Due to its simple API, evas can be developed with rapidly, and cleanly.
- .
- This package provides development documentation (html and manpages) for the
- Evas library.
-
-Package: libevas-dev
-Section: libdevel
-Architecture: any
-Depends: ${misc:Depends}, libevas (= ${binary:Version}), libtiff-dev, libjpeg8-dev, libx11-dev,
- libfreetype6-dev, libfontconfig1-dev, libeet-dev, pkg-config, libeina-dev (>= 0.0.2.060+svn20100304), libxext-dev, libpng12-dev, libfribidi-dev, libharfbuzz-dev, libpixman-1-dev,
- libgif-dev
-Suggests: libevas-doc
-Description: Enlightenment DR17 advanced canvas library development files
- Evas is an advanced canvas library, providing six engines for rendering: X11,
- OpenGL (hardware accelerated), DirectFB, the framebuffer, Microsoft Windows
- and Qtopia.
- .
- Due to its simple API, evas can be developed with rapidly, and cleanly.
- .
- This package provides headers and static libraries required to develop against
- evas.
-
-Package: libevas-dbg
-Architecture: any
-Section: debug
-Depends: ${misc:Depends}, libevas (= ${binary:Version})
-Priority: extra
-Description: enlightenment advanced canvas library
- Evas is an advanced canvas library, providing six engines for rendering: X11,
- OpenGL (hardware accelerated), DirectFB, the framebuffer, Microsoft Windows
- and Qtopia.
- .
- This package contains unstripped shared libraries. It is provided primarily
- to provide a backtrace with names in a debugger, this makes it somewhat
- easier to interpret core dumps. The libraries are installed in
- /usr/lib/debug and are automatically used by gdb.
-
-Package: libevas-engines
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
-Conflicts: libevas-0.9.9.050a-engines
-Description: Evas module providingg the framebuffer render engine
- Evas is an advanced canvas library, providing six engines for rendering: X11,
- OpenGL (hardware accelerated), DirectFB, the framebuffer, Microsoft Windows
- and Qtopia.
- Due to its simple API, evas can be developed with rapidly, and cleanly.
- .
- This package contains the following Evas engine modules:
-  - buffer
-  - software/genenric
-  - software/X11
-  - xrender/X11
-
-Package: libevas-engines-extras
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, libevas-engines, opengl-es
-Conflicts: libevas-0.9.9.050a-engines-extras
-Description: Evas module providing the Xrender engine
- Evas is an advanced canvas library, providing six engines for rendering: X11,
- OpenGL (hardware accelerated), DirectFB, the framebuffer, Microsoft Windows
- and Qtopia.
- Due to its simple API, evas can be developed with rapidly, and cleanly.
- .
- This package contains some extra Evas engine modules:
-  - GL/X11
-  - Framebuffer
diff --git a/debian/copyright b/debian/copyright
deleted file mode 100644 (file)
index 3353e50..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-This package was debianized by Debian Pkg-e Team <pkg-e-devel@lists.alioth.debian.org> 
-Sat, 07 Jul 2007 09:29:10 +0000.
-
-It was downloaded from http://download.enlightenment.org/
-
-Upstream Authors: 
-
-       Enlightenment team <enlightenment-devel@lists.sourceforge.net>
-
-Copyright:
-
-       Copyright (C) 2000 Carsten Haitzler and various contributors (see AUTHORS)
-    src/modules/engines/fb/evas_fb.h: Copyright (c) 1999 - Carsten Haitzler
-    src/modules/engines/fb/evas_fb_main.c: Copyright (c) 1999 - Carsten Haitzler
-
-License:
-
-  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 of the Software, its documentation and marketing & publicity
-  materials, and acknowledgment shall be given in the documentation,
-  materials and software packages that this Software was used.
-
-  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 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.
-
-On Debian systems, the complete text of the BSD License can be found
-in `/usr/share/common-licenses/BSD'.
diff --git a/debian/jobs b/debian/jobs
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/debian/libevas-dev.install b/debian/libevas-dev.install
deleted file mode 100644 (file)
index bd6d932..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-debian/tmp/usr/include/*
-debian/tmp/usr/lib/lib*.a
-debian/tmp/usr/lib/lib*.la
-debian/tmp/usr/lib/pkgconfig/*
-debian/tmp/usr/lib/libevas.so
diff --git a/debian/libevas-doc.dirs b/debian/libevas-doc.dirs
deleted file mode 100644 (file)
index fc70dc0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-usr/share/doc/libevas-doc
diff --git a/debian/libevas-doc.doc-base b/debian/libevas-doc.doc-base
deleted file mode 100644 (file)
index 397f3dd..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-Document: evas
-Title: Evas Guide
-Author: Carsten Haitzler
-Abstract: This document describes Evas API
- and provides sample C code.
-Section: Programming/C
-
-Format: HTML
-Index: /usr/share/doc/libevas-doc/html/index.html
-Files: /usr/share/doc/libevas-doc/html/*.html
diff --git a/debian/libevas-engines-extras.install b/debian/libevas-engines-extras.install
deleted file mode 100644 (file)
index 30ef17d..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-debian/tmp/usr/lib/evas/modules/engines/fb/*/module.so
-debian/tmp/usr/lib/evas/modules/engines/gl_x11/*/module.so 
diff --git a/debian/libevas-engines-extras.install.default b/debian/libevas-engines-extras.install.default
deleted file mode 100755 (executable)
index 45a5936..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-debian/tmp/usr/lib/evas/modules/engines/fb/*/module.so
-debian/tmp/usr/lib/evas/modules/engines/gl_x11/*/module.so
diff --git a/debian/libevas-engines-extras.install.i386 b/debian/libevas-engines-extras.install.i386
deleted file mode 100755 (executable)
index 45a5936..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-debian/tmp/usr/lib/evas/modules/engines/fb/*/module.so
-debian/tmp/usr/lib/evas/modules/engines/gl_x11/*/module.so
diff --git a/debian/libevas-engines.install b/debian/libevas-engines.install
deleted file mode 100644 (file)
index 4d3c009..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-debian/tmp/usr/lib/evas/modules/engines/buffer/*/module.so
-debian/tmp/usr/lib/evas/modules/engines/software_generic/*/module.so
-debian/tmp/usr/lib/evas/modules/engines/software_x11/*/module.so
diff --git a/debian/libevas.install b/debian/libevas.install
deleted file mode 100644 (file)
index 6266691..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-debian/tmp/usr/lib/libevas*.so.*
-debian/tmp/usr/lib/evas/modules/loaders/*/*/*.so
-debian/tmp/usr/lib/evas/modules/savers/*/*/*.so
diff --git a/debian/libevas.shlibs b/debian/libevas.shlibs
deleted file mode 100644 (file)
index f70d2e4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-libevas 1 libevas (>= 0.9.9.060+svn20100203)
diff --git a/debian/rules b/debian/rules
deleted file mode 100755 (executable)
index 9fe6fb3..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/make -f
-
-include /usr/share/cdbs/1/class/autotools.mk
-include /usr/share/cdbs/1/rules/debhelper.mk
-
-DEB_CONFIGURE_SCRIPT := ./autogen.sh
-DEB_MAKE_CLEAN_TARGET := distclean
-
-CFLAGS += -fvisibility=hidden -ffast-math -fPIC
-LDFLAGS += -fvisibility=hidden -Wl,--hash-style=both -Wl,--as-needed
-
-DEB_DH_STRIP_ARGS := --dbg-package=libevas-dbg
-
-ifeq (hppa,$(DEB_HOST_ARCH))
-       arch_flags += --disable-pthreads
-else ifeq (armel,$(DEB_HOST_ARCH))
-       arch_flags += --enable-pthreads --enable-cpu-neon
-else
-       arch_flags += --enable-pthreads
-endif
-
-ifeq (amd64,$(DEB_HOST_ARCH))
-       arch_flags += --enable-cpu-sse
-endif
-
-ifeq (armel,$(DEB_HOST_ARCH))
-       arch_flags += --enable-winkcodec=yes
-else
-       arch_flags += --enable-winkcodec=no
-endif
-
-#arch_flags += --enable-word-cache #--enable-metric-cache
-
-DEB_CONFIGURE_EXTRA_FLAGS := --disable-image-loader-svg \
-       --enable-simple-x11 \
-       --with-x \
-       --enable-fb \
-       --enable-xrender-x11 \
-       --enable-line-dither-mask \
-       --disable-image-loader-edb \
-       --disable-rpath $(arch_flags) \
-       --enable-gl-x11 \
-       --enable-gl-flavor-gles \
-       --enable-pixman \
-       --enable-pixman-image \
-       --enable-pixman-image-scale-sample \
-       --enable-tile-rotate \
-       --enable-gles-variety-sgx
-
-#build/libevas-doc::
-#      cd $(DEB_SRCDIR)/doc && make doc
-
-install::
-ifeq (i386,$(DEB_HOST_ARCH))
-       cp -f $(DEB_SRCDIR)/debian/libevas-engines-extras.install.i386 $(DEB_SRCDIR)/debian/libevas-engines-extras.install
-else
-       cp -f $(DEB_SRCDIR)/debian/libevas-engines-extras.install.default $(DEB_SRCDIR)/debian/libevas-engines-extras.install
-endif
-
-#install/libevas-doc::
-#      mkdir -p debian/libevas-doc/usr/share/doc/libevas-doc
-#      cp -R $(DEB_SRCDIR)/doc/html debian/libevas-doc/usr/share/doc/libevas-doc/
-
-clean::
-       [ ! -f Makefile ] || make distclean
-       rm -f evas-*.tar.bz2 evas-*.cdbs-config_list
index 54456fe..edd53b3 100644 (file)
@@ -50,7 +50,7 @@ GENERATE_TODOLIST      = YES
 GENERATE_TESTLIST      = YES
 GENERATE_BUGLIST       = YES
 GENERATE_DEPRECATEDLIST= YES
-ALIASES                =
+ALIASES                = "since_tizen=@par \"Since (Tizen):\""
 ENABLED_SECTIONS       =
 MAX_INITIALIZER_LINES  = 30
 OPTIMIZE_OUTPUT_FOR_C  = YES
index 2dd6b44..0803ef6 100644 (file)
--- a/doc/e.css
+++ b/doc/e.css
@@ -271,3 +271,13 @@ td.nav_active {
        width: 100%;
 }
 
+div.fragment {
+       font-family: monospace, mono, fixed;
+       font-size: 9pt;
+       white-space: pre;
+}
+
+.line {
+       line-height: 0%;
+}
+
similarity index 99%
rename from doc/examples.dox
rename to doc/evas_examples.dox
index 65dd513..67f0e18 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * @page Examples Examples
+ * @page evas_examples Evas Examples
  *
  * Here is a page with examples.
  *
  *
  * @ref Example_Evas_Stacking
  *
+ * @internal
  * @ref Example_Evas_Smart_Objects
+ * @endinternal
  *
- * @ref Example_Evas_Box Evas box
+ * @ref Example_Evas_Box
  */
 
 /**
  */
 
 /**
+ * @internal
  * @page Example_Evas_Smart_Objects Evas object smart objects
  * @dontinclude evas-smart-object.c
  *
  */
 
 /**
+ * @internal
  * @page Example_Evas_Smart_Interfaces Evas object smart interfaces
  * @dontinclude evas-smart-interface.c
  *
diff --git a/evas-software-16-wince.pc.in b/evas-software-16-wince.pc.in
deleted file mode 100644 (file)
index 01fad48..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Name: evas-software-16-wince
-Description: Evas 16bit software WinCE engine
-Version: @VERSION@
diff --git a/evas-software-16-x11.pc.in b/evas-software-16-x11.pc.in
deleted file mode 100644 (file)
index 75040a0..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Name: evas-software-16-x11
-Description: Evas software X11 16bpp engine
-Version: @VERSION@
diff --git a/evas.manifest b/evas.manifest
new file mode 100644 (file)
index 0000000..97e8c31
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_"/>
+       </request>
+</manifest>
index 988e2dd..5f10da3 100644 (file)
@@ -19,7 +19,6 @@
 %bcond_with    module_saver_edb
 %bcond_with    module_engine_directfb
 %bcond_with    module_engine_gl_x11
-%bcond_with    module_engine_software_16_x11
 %bcond_with    module_engine_software_sdl
 %bcond_with    module_engine_software_xcb
 %bcond_with    module_loader_gif
@@ -77,7 +76,6 @@
 %define ac_with_module_engine_fb --%{?with_module_engine_fb:en}%{!?with_module_engine_fb:dis}able-fb
 %define ac_with_module_engine_gl_x11 --%{?with_module_engine_gl_x11:en}%{!?with_module_engine_gl_x11:dis}able-gl-x11
 %define ac_with_module_engine_directfb --%{?with_module_engine_directfb:en}%{!?with_module_engine_directfb:dis}able-directfb
-%define ac_with_module_engine_software_16_x11 --%{?with_module_engine_software_16_x11:en}%{!?with_module_engine_software_16_x11:dis}able-software-16-x11
 %define ac_with_module_engine_software_sdl --%{?with_module_engine_software_sdl:en}%{!?with_module_engine_software_sdl:dis}able-sdl
 %define ac_with_module_engine_software_xcb --%{?with_module_engine_software_xcb:en}%{!?with_module_engine_software_xcb:dis}able-software-xcb
 
@@ -233,7 +231,7 @@ XPM Image loader module for Evas
 %package module_loader_svg
 Summary: SVG Image loader module for Evas
 Group: System Environment/Libraries
-BuildRequires: librsvg-devel >= 2.14
+BuildRequires: esvg-devel >= 0.16
 %description module_loader_svg
 svg Image loader module for Evas
 %endif
@@ -351,16 +349,6 @@ Requires: evas
 Directfb rendering engine module for Evas
 %endif
 
-%if %{with module_engine_software_16_x11}
-%package module_engine_software_16_x11
-Summary: Software 16-bit X11 rendering engine module for Evas
-Group: System Environment/Libraries
-Requires: evas-module_engine_software_generic
-Requires: evas
-%description module_engine_software_16_x11
-Software 16-bit X11 rendering engine module for Evas
-%endif
-
 %if %{with module_engine_software_sdl}
 %package module_engine_software_sdl
 Summary: Software SDL X11 rendering engine module for Evas
@@ -414,7 +402,6 @@ Software XCB X11 rendering engine module for Evas
     %{?ac_with_module_engine_fb} \
     %{?ac_with_module_engine_gl_x11} \
     %{?ac_with_module_engine_directfb} \
-    %{?ac_with_module_engine_software_16_x11} \
     %{?ac_with_module_engine_software_sdl} \
     %{?ac_with_module_engine_software_xcb} \
     $RPM_CONFIGURE_OPTS
@@ -439,6 +426,10 @@ test "x$RPM_BUILD_ROOT" != "x/" && rm -rf $RPM_BUILD_ROOT
 %doc AUTHORS COPYING ChangeLog INSTALL README
 %{_bindir}/%{name}*
 %{_libdir}/*.so.*
+%{_libdir}/evas/modules/engines/wayland_shm/*/module.so
+%{_libdir}/evas/cserve2/loaders/*/*/module.*
+%{_prefix}/libexec/*
+%{_datadir}/evas/checkme
 
 %files devel
 %defattr(-, root, root)
@@ -602,13 +593,6 @@ test "x$RPM_BUILD_ROOT" != "x/" && rm -rf $RPM_BUILD_ROOT
 %{_libdir}/evas/modules/engines/directfb/*/module.so
 %endif
 
-%if %{with module_engine_software_16_x11}
-%files module_engine_software_16_x11
-%defattr(-, root, root)
-%{_libdir}/evas/modules/engines/software_16/*/module.so
-%{_libdir}/evas/modules/engines/software_16_x11/*/module.so
-%endif
-
 %if %{with module_engine_software_sdl}
 %files module_engine_software_sdl
 %defattr(-, root, root)
index d4db2aa..c643f92 100644 (file)
@@ -166,7 +166,7 @@ else
 #include <X11/Xresource.h>
       ])
    if test "x${have_egl}" = "xyes" ; then
-      AC_CHECK_LIB(GLESv2, glTexImage2D, [have_glesv2="yes"], , -lEGL ${x_libs} -lm $gl_pt_lib)
+      AC_CHECK_LIB(GLESv2, glTexImage2D, [have_glesv2="yes"], , -L/usr/lib -ldl -lEGL ${x_libs} -lm $gl_pt_lib)
       if test "x${have_glesv2}" = "xyes" ; then
          PKG_CHECK_MODULES([GL_EET], [eet >= 1.6.99], [have_dep="yes"], [have_dep="no"])
          if test "x${have_dep}" = "xyes" ; then
@@ -174,7 +174,7 @@ else
             evas_engine_[]$1[]_libs="${x_libs} -lGLESv2 -lEGL -lm $gl_pt_lib"
             evas_engine_gl_common_libs="-lGLESv2 -lm $gl_pt_lib"
             have_dep="yes"
-            AC_DEFINE(GLES_VARIETY_SGX, 1, [Imagination SGX GLES2 support])
+            AC_DEFINE(GL_GLES, 1, [GLSL runtime shader GLES2 support])
             gles_variety_sgx="yes"
          fi
       fi
@@ -335,7 +335,7 @@ else
 #include <EGL/egl.h>
       ])
    if test "x${have_egl}" = "xyes" ; then
-      AC_CHECK_LIB(GLESv2, glTexImage2D, [have_glesv2="yes"], , -lEGL ${x_libs} -lm $gl_pt_lib)
+      AC_CHECK_LIB(GLESv2, glTexImage2D, [have_glesv2="yes"], , -L/usr/lib -ldl -lEGL ${x_libs} -lm $gl_pt_lib)
       if test "x${have_glesv2}" = "xyes" ; then
          PKG_CHECK_MODULES([GL_EET], [eet >= 1.6.99], [have_dep="yes"], [have_dep="no"])
          if test "x${have_dep}" = "xyes" ; then
@@ -495,41 +495,6 @@ fi
 
 ])
 
-dnl use: EVAS_CHECK_ENGINE_DEP_SOFTWARE_16_SDL(engine, simple, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
-
-AC_DEFUN([EVAS_CHECK_ENGINE_DEP_SOFTWARE_16_SDL],
-[
-
-requirement=""
-have_dep="no"
-evas_engine_[]$1[]_cflags=""
-evas_engine_[]$1[]_libs=""
-
-PKG_CHECK_MODULES([SDL],
-   [sdl >= 1.2.0],
-   [
-    have_dep="yes"
-    requirement="sdl"
-    evas_engine_[]$1[]_cflags="${SDL_CFLAGS}"
-    evas_engine_[]$1[]_libs="${SDL_LIBS}"
-   ]
-)
-
-AC_SUBST([evas_engine_$1_cflags])
-AC_SUBST([evas_engine_$1_libs])
-
-if test "x$3" = "xstatic" ; then
-   requirement_evas="${requirement} ${requirement_evas}"
-fi
-
-if test "x${have_dep}" = "xyes" ; then
-  m4_default([$4], [:])
-else
-  m4_default([$5], [:])
-fi
-
-])
-
 dnl use: EVAS_CHECK_ENGINE_DEP_GL_SDL(engine, simple, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
 
 AC_DEFUN([EVAS_CHECK_ENGINE_DEP_GL_SDL],
@@ -720,70 +685,6 @@ fi
 
 ])
 
-dnl use: EVAS_CHECK_ENGINE_DEP_SOFTWARE_16_X11(engine, simple, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
-AC_DEFUN([EVAS_CHECK_ENGINE_DEP_SOFTWARE_16_X11],
-[
-
-have_dep="no"
-evas_engine_[]$1[]_cflags=""
-evas_engine_[]$1[]_libs=""
-
-AC_PATH_X
-AC_PATH_XTRA
-
-AC_CHECK_HEADER([X11/X.h], [have_dep="yes"])
-
-if test "x${have_dep}" = "xyes" ; then
-   AC_CHECK_LIB([X11], [XCreateImage], [have_dep="yes"], [have_dep="no"])
-fi
-
-if test "x${have_dep}" = "xyes" ; then
-   AC_CHECK_LIB([Xext], [XShmCreateImage], [have_dep="yes"], [have_dep="no"])
-fi
-
-if test "x${have_dep}" = "xyes" ; then
-   if test "x$2" = "xyes" ; then
-      x_libs="${x_libs} -lX11 -lXext"
-   else
-      x_dir=${x_dir:-/usr/X11R6}
-      x_cflags=${x_cflags:--I${x_includes:-$x_dir/include}}
-      x_libs="${x_libs:--L${x_libraries:-$x_dir/lib}} -lX11 -lXext"
-   fi
-   evas_engine_[]$1[]_cflags="${x_cflags}"
-   evas_engine_[]$1[]_libs="${x_libs}"
-fi
-
-AC_SUBST([evas_engine_$1_cflags])
-AC_SUBST([evas_engine_$1_libs])
-
-if test "x${have_dep}" = "xyes" ; then
-  m4_default([$4], [:])
-else
-  m4_default([$5], [:])
-fi
-
-])
-
-dnl use: EVAS_CHECK_ENGINE_DEP_SOFTWARE_16_WINCE(engine, simple, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
-
-AC_DEFUN([EVAS_CHECK_ENGINE_DEP_SOFTWARE_16_WINCE],
-[
-
-have_dep="yes"
-evas_engine_[]$1[]_cflags=""
-evas_engine_[]$1[]_libs=""
-
-AC_SUBST([evas_engine_$1_cflags])
-AC_SUBST([evas_engine_$1_libs])
-
-if test "x${have_dep}" = "xyes" ; then
-  m4_default([$4], [:])
-else
-  m4_default([$5], [:])
-fi
-
-])
-
 dnl use: EVAS_CHECK_ENGINE_DEP_PSL1GHT(engine, simple, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
 
 AC_DEFUN([EVAS_CHECK_ENGINE_DEP_PSL1GHT],
index c8c5248..79e1f21 100644 (file)
@@ -231,10 +231,12 @@ requirement=""
 have_esvg="no"
 evas_image_loader_[]$1[]_cflags=""
 evas_image_loader_[]$1[]_libs=""
+version_esvg="0.0.18"
+version_ender="0.0.6"
 
 PKG_CHECK_MODULES([SVG],
-   [esvg >= 0.0.16],
-   [have_dep="yes" have_esvg="yes" requirement="esvg"],
+   [esvg >= ${version_esvg} ender >= ${version_ender}],
+   [have_dep="yes" have_esvg="yes" requirement="esvg >= ${version_esvg} ender >= ${version_ender}"],
    [have_dep="no"])
 
 if test "x${have_dep}" = "xyes" ; then
@@ -389,6 +391,26 @@ fi
 
 ])
 
+dnl use: EVAS_CHECK_LOADER_DEP_TGV(loader, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+
+AC_DEFUN([EVAS_CHECK_LOADER_DEP_TGV],
+[
+
+have_dep="yes"
+evas_image_loader_[]$1[]_cflags=""
+evas_image_loader_[]$1[]_libs=""
+
+AC_SUBST([evas_image_loader_$1_cflags])
+AC_SUBST([evas_image_loader_$1_libs])
+
+if test "x${have_dep}" = "xyes" ; then
+  m4_default([$3], [:])
+else
+  m4_default([$4], [:])
+fi
+
+])
+
 dnl use: EVAS_CHECK_LOADER_DEP_WBMP(loader, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
 
 AC_DEFUN([EVAS_CHECK_LOADER_DEP_WBMP],
@@ -429,6 +451,38 @@ fi
 
 ])
 
+dnl use: EVAS_CHECK_LOADER_DEP_WEBP(loader, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+
+AC_DEFUN([EVAS_CHECK_LOADER_DEP_WEBP],
+[
+
+have_dep="no"
+evas_image_loader_[]$1[]_cflags=""
+evas_image_loader_[]$1[]_libs=""
+
+AC_CHECK_HEADER([webp/decode.h], [have_dep="yes"])
+
+if test "x${have_dep}"  = "xyes" ; then
+   AC_CHECK_LIB([webp],
+      [WebPDecodeRGBA],
+      [
+       evas_image_loader_[]$1[]_libs="-lwebp"
+      ],
+      [have_dep="no"]
+   )
+fi
+
+AC_SUBST([evas_image_loader_$1_cflags])
+AC_SUBST([evas_image_loader_$1_libs])
+
+if test "x${have_dep}" = "xyes" ; then
+  m4_default([$3], [:])
+else
+  m4_default([$4], [:])
+fi
+
+])
+
 dnl use: EVAS_CHECK_LOADER_DEP_GENERIC(loader, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
 
 AC_DEFUN([EVAS_CHECK_LOADER_DEP_GENERIC],
index df9cc9f..16b6941 100755 (executable)
@@ -1,10 +1,10 @@
 #sbs-git:slp/pkgs/e/evas evas 1.1.0+svn.69113slp2+build01 828d8bb285397266eb8985fd081fa2692fa3a7d6
 Name:       evas
 Summary:    Multi-platform Canvas Library
-Version:    1.6.0+svn.74704slp2+build15
+Version:    1.7.1+svn.77561+build188
 Release:    1
 Group:      System/Libraries
-License:    BSD
+License:    BSD 2-Clause and Zlib
 URL:        http://www.enlightenment.org/
 Source0:    %{name}-%{version}.tar.gz
 Requires(post): /sbin/ldconfig
@@ -19,21 +19,18 @@ BuildRequires:  pkgconfig(freetype2)
 BuildRequires:  pkgconfig(fribidi)
 BuildRequires:  pkgconfig(xext)
 BuildRequires:  pkgconfig(libpng)
-BuildRequires:  pkgconfig(xpm)
 BuildRequires:  pkgconfig(zlib)
 BuildRequires:  pkgconfig(harfbuzz)
-BuildRequires:  pkgconfig(sm)
 BuildRequires:  libjpeg-devel
 BuildRequires:  giflib-devel
 BuildRequires:  pkgconfig(pixman-1)
+
 %ifarch %{arm}
-BuildRequires:  pkgconfig(gles11)
 BuildRequires:  pkgconfig(gles20)
 BuildRequires:  pkgconfig(libdri2)
 BuildRequires:  pkgconfig(xfixes)
-BuildRequires:  pkgconfig(libdrm_slp)
 %else
-BuildRequires:  simulator-opengl-devel
+BuildRequires:  pkgconfig(gles20)
 %endif
 
 
@@ -62,41 +59,52 @@ Enlightenment DR17 advanced canvas library (devel)
 %setup -q
 
 %build
-export CFLAGS+=" -fvisibility=hidden -ffast-math -fPIC"
-export LDFLAGS+=" -fvisibility=hidden -Wl,--hash-style=both -Wl,--as-needed"
+%ifarch %{arm}
+       export CFLAGS+=" -fvisibility=hidden -ffast-math -mfpu=neon -ftree-vectorize -mfloat-abi=softfp -fPIC"
+       export CXXFLAGS+=" -mfpu=neon -ftree-vectorize -mfloat-abi=softfp"
+%else
+       export CFLAGS+=" -fvisibility=hidden -ffast-math -fPIC"
+%endif
+export LDFLAGS+=" -fvisibility=hidden -Wl,--hash-style=both -Wl,--as-needed "
 
-%autogen
-%configure --disable-static \
+%autogen --disable-static \
        --disable-image-loader-svg \
        --enable-simple-x11 \
        --with-x \
        --enable-fb \
-       --enable-xrender-x11 \
        --enable-line-dither-mask \
        --disable-image-loader-edb \
-       --disable-rpath \
-       --enable-gl-x11 \
        --enable-gl-flavor-gles \
-       --enable-gles-variety-sgx \
        --enable-pixman \
        --enable-pixman-image \
        --enable-pixman-image-scale-sample \
        --enable-tile-rotate \
+       --disable-wayland-shm \
+       --disable-wayland-egl \
+       --disable-evas-cserve \
+       --disable-evas-cserve2 \
+       --disable-image-loader-psd \
+       --disable-image-loader-tga \
+       --disable-image-loader-xpm \
 %ifarch %{arm}
-       --enable-pthreads \
+       --enable-pthreads \
        --enable-cpu-neon \
-       --enable-winkcodec=yes
 %else
        --enable-pthreads \
-       --enable-winkcodec=no
 %endif
-  
+
+# Add the following for the benchmarks
+#      --enable-build-examples \
+#      --enable-install-examples
+
 make %{?jobs:-j%jobs}
 
 
 %install
 rm -rf %{buildroot}
 %make_install
+mkdir -p %{buildroot}/usr/share/license
+cp %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/usr/share/license/%{name}
 
 
 %post -p /sbin/ldconfig
@@ -111,14 +119,17 @@ rm -rf %{buildroot}
 %{_libdir}/evas/modules/engines/*/*/module.so
 %{_libdir}/evas/modules/loaders/*/*/module.so
 %{_libdir}/evas/modules/savers/*/*/module.so
-%{_libdir}/evas/cserve2/loaders/*/*/module.so
-%{_bindir}/evas_cserve2_client
-%{_bindir}/evas_cserve2_usage
-%{_bindir}/evas_cserve2_debug
-%{_libexecdir}/evas_cserve2
-%{_libexecdir}/evas_cserve2_slave
-%{_libexecdir}/dummy_slave
-
+#%{_libdir}/evas/cserve2/loaders/*/*/module.so
+#%{_bindir}/evas_cserve2_client
+#%{_bindir}/evas_cserve2_usage
+#%{_bindir}/evas_cserve2_debug
+#%{_libexecdir}/evas_cserve2
+#%{_libexecdir}/evas_cserve2_slave
+#%{_libexecdir}/dummy_slave
+%manifest %{name}.manifest
+/usr/share/license/%{name}
+# The temp file for eina_prefix by raster
+%{_datadir}/evas/checkme
 
 %files devel
 %defattr(-,root,root,-)
@@ -126,3 +137,4 @@ rm -rf %{buildroot}
 %{_libdir}/libevas.so
 %{_libdir}/pkgconfig/*.pc
 %{_datadir}/evas/examples/*
+#%{_datadir}/evas/benchmarks/*
index c44a82e..81eb02e 100644 (file)
@@ -1,3 +1,3 @@
 MAINTAINERCLEANFILES = Makefile.in
 
-SUBDIRS = static_deps lib bin modules tests examples
+SUBDIRS = static_deps lib bin modules tests examples benchmarks/evas
diff --git a/src/benchmarks/evas/.gitignore b/src/benchmarks/evas/.gitignore
new file mode 100644 (file)
index 0000000..aee0b35
--- /dev/null
@@ -0,0 +1 @@
+/evas_bench
diff --git a/src/benchmarks/evas/Makefile.am b/src/benchmarks/evas/Makefile.am
new file mode 100644 (file)
index 0000000..ddd6801
--- /dev/null
@@ -0,0 +1,50 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/modules/engines/buffer \
+-DPACKAGE_BUILD_DIR=\"`pwd`/$(top_builddir)\" \
+@EVAS_CFLAGS@ @EINA_CFLAGS@
+
+if INSTALL_EXAMPLES
+AM_CPPFLAGS += -DTESTS_SRC_DIR=\"$(prefix)/share/evas/benchmarks\"
+else
+AM_CPPFLAGS += -DTESTS_SRC_DIR=\"$(abs_top_srcdir)/src/benchmarks/evas\"
+endif
+
+EXTRA_PROGRAMS = evas_bench
+
+benchmark: evas_bench
+
+evas_bench_SOURCES = \
+evas_bench.c \
+evas_bench_loader.c \
+evas_bench_saver.c \
+evas_bench.h
+
+nodist_EXTRA_evas_bench_SOURCES = dummy.cc
+evas_bench_LDADD = \
+$(top_builddir)/src/lib/libevas.la \
+@EVAS_LIBS@
+
+IMAGES = images/Light-50.tgv \
+images/mars_rover_panorama_half-size.jpg \
+images/Pic1-50.tgv \
+images/Sunrise-100.tgv
+
+EXTRA_DIST = $(IMAGES)
+
+clean-local:
+       rm -rf *.gcno ..\#..\#src\#*.gcov *.gcda
+
+#if ALWAYS_BUILD_EXAMPLES
+if BUILD_EXAMPLES
+if INSTALL_EXAMPLES
+benchmarkdir = $(datadir)/$(PACKAGE)/benchmarks
+benchmark_imagesdir = $(datadir)/$(PACKAGE)/benchmarks/images
+benchmark_PROGRAMS = $(EXTRA_PROGRAMS)
+benchmark_images_DATA = $(IMAGES)
+else
+noinst_PROGRAMS = $(EXTRA_PROGRAMS)
+endif
+endif
diff --git a/src/benchmarks/evas/evas_bench.c b/src/benchmarks/evas/evas_bench.c
new file mode 100644 (file)
index 0000000..58b806e
--- /dev/null
@@ -0,0 +1,54 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+
+#include "evas_bench.h"
+#include "Eina.h"
+#include "Evas.h"
+
+typedef struct _Evas_Benchmark_Case Evas_Benchmark_Case;
+struct _Evas_Benchmark_Case
+{
+   const char *bench_case;
+   void (*build)(Eina_Benchmark *bench);
+   Eina_Bool run_by_default;
+};
+
+static const Evas_Benchmark_Case etc[] = {
+   { "Loader", evas_bench_loader, EINA_TRUE },
+   { "Saver", evas_bench_saver, EINA_TRUE },
+   { NULL, NULL, EINA_FALSE }
+};
+
+int
+main(int argc, char **argv)
+{
+   Eina_Benchmark *test;
+   unsigned int i;
+
+   evas_init();
+
+   for (i = 0; etc[i].bench_case; ++i)
+     {
+        if (argc == 2 && strcasecmp(etc[i].bench_case, argv[1]))
+          continue;
+
+        test = eina_benchmark_new(etc[i].bench_case, "default");
+        if (!test)
+          continue;
+
+        etc[i].build(test);
+
+        eina_benchmark_run(test);
+
+        eina_benchmark_free(test);
+     }
+
+   evas_shutdown();
+
+   return 0;
+}
diff --git a/src/benchmarks/evas/evas_bench.h b/src/benchmarks/evas/evas_bench.h
new file mode 100644 (file)
index 0000000..cf57213
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef EVAS_BENCH_H_
+#define EVAS_BENCH_H_
+
+#include "eina_benchmark.h"
+
+void evas_bench_loader(Eina_Benchmark *bench);
+void evas_bench_saver(Eina_Benchmark *bench);
+
+#endif
+
diff --git a/src/benchmarks/evas/evas_bench_loader.c b/src/benchmarks/evas/evas_bench_loader.c
new file mode 100644 (file)
index 0000000..77c1684
--- /dev/null
@@ -0,0 +1,92 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "Evas.h"
+#include "Evas_Engine_Buffer.h"
+#include "evas_bench.h"
+
+static const char *
+_test_image_get(const char *name)
+{
+   static char filename[PATH_MAX];
+
+   snprintf(filename, PATH_MAX, TESTS_SRC_DIR"/images/%s", name);
+
+   return filename;
+}
+
+static Evas *
+_setup_evas()
+{
+   Evas *evas;
+   Evas_Engine_Info_Buffer *einfo;
+
+   evas = evas_new();
+
+   evas_output_method_set(evas, evas_render_method_lookup("buffer"));
+   einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(evas);
+
+   einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32;
+   einfo->info.dest_buffer = malloc(sizeof (char) * 500 * 500 * 4);
+   einfo->info.dest_buffer_row_bytes = 500 * sizeof (char) * 4;
+
+   evas_engine_info_set(evas, (Evas_Engine_Info *)einfo);
+
+   evas_output_size_set(evas, 500, 500);
+   evas_output_viewport_set(evas, 0, 0, 500, 500);
+
+   return evas;
+}
+
+static void
+evas_bench_loader_tgv(int request)
+{
+   Evas *e = _setup_evas();
+   char *large;
+   char *small;
+   char *computer;
+   Evas_Object *o;
+   Eina_List *l;
+   int i;
+
+   large = strdup(_test_image_get("Light-50.tgv"));
+   small = strdup(_test_image_get("Sunrise-100.tgv"));
+   computer = strdup(_test_image_get("Pic1-50.tgv"));
+
+   for (i = 0; i < request; i++)
+     {
+        o = evas_object_image_add(e);
+
+        evas_object_image_file_set(o, large, NULL);
+        if (!evas_object_image_data_get(o, 0)) break ;
+
+        evas_object_image_file_set(o, small, NULL);
+        if (!evas_object_image_data_get(o, 0)) break ;
+
+        evas_object_image_file_set(o, computer, NULL);
+        if (!evas_object_image_data_get(o, 0)) break ;
+
+        evas_object_del(o);
+
+        l = evas_render_updates(e);
+        evas_render_updates_free(l);
+
+        evas_render_idle_flush(e);
+        evas_render_dump(e);
+     }
+
+   fprintf(stderr, "i: %i (%s, %s, %s)\n",
+           i, large, small, computer);
+
+   free(large);
+   free(small);
+   free(computer);
+
+   evas_free(e);
+}
+
+void evas_bench_loader(Eina_Benchmark *bench)
+{
+   eina_benchmark_register(bench, "tgv-loader", EINA_BENCHMARK(evas_bench_loader_tgv), 20, 2000, 100);
+}
diff --git a/src/benchmarks/evas/evas_bench_saver.c b/src/benchmarks/evas/evas_bench_saver.c
new file mode 100644 (file)
index 0000000..ad7c9c0
--- /dev/null
@@ -0,0 +1,117 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "Evas.h"
+#include "Evas_Engine_Buffer.h"
+#include "evas_bench.h"
+
+static const char *
+_test_image_get(const char *name)
+{
+   static char filename[PATH_MAX];
+
+   snprintf(filename, PATH_MAX, TESTS_SRC_DIR"/images/%s", name);
+
+   return filename;
+}
+
+static Evas *
+_setup_evas()
+{
+   Evas *evas;
+   Evas_Engine_Info_Buffer *einfo;
+
+   evas = evas_new();
+
+   evas_output_method_set(evas, evas_render_method_lookup("buffer"));
+   einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(evas);
+
+   einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32;
+   einfo->info.dest_buffer = malloc(sizeof (char) * 500 * 500 * 4);
+   einfo->info.dest_buffer_row_bytes = 500 * sizeof (char) * 4;
+
+   evas_engine_info_set(evas, (Evas_Engine_Info *)einfo);
+
+   evas_output_size_set(evas, 500, 500);
+   evas_output_viewport_set(evas, 0, 0, 500, 500);
+
+   return evas;
+}
+
+// Compatibility import from EFL 1.10
+static int eina_file_mkstemp(const char *templatename, Eina_Tmpstr **path)
+{
+
+   char buffer[PATH_MAX];
+   const char *tmpdir = NULL;
+   const char *XXXXXX = NULL;
+   int fd, len;
+   mode_t old_umask;
+
+#ifndef HAVE_EVIL
+#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
+   if (getuid() == geteuid())
+#endif
+     tmpdir = getenv("TMPDIR");
+   if (!tmpdir) tmpdir = "/tmp";
+#else
+   tmpdir = (char *)evil_tmpdir_get();
+#endif /* ! HAVE_EVIL */
+
+   len = snprintf(buffer, PATH_MAX, "%s/%s", tmpdir, templatename);
+
+   /*
+    * Make sure temp file is created with secure permissions,
+    * http://man7.org/linux/man-pages/man3/mkstemp.3.html#NOTES
+    */
+   old_umask = umask(S_IRWXG|S_IRWXO);
+   if ((XXXXXX = strstr(buffer, "XXXXXX.")) != NULL)
+     {
+        int suffixlen = buffer + len - XXXXXX - 6;
+        fd = mkstemps(buffer, suffixlen);
+     }
+   else
+     fd = mkstemp(buffer);
+   umask(old_umask);
+
+   if (path) *path = eina_tmpstr_add(buffer);
+   if (fd < 0)
+     return -1;
+
+   return fd;
+}
+
+static void
+evas_bench_saver_tgv(int request)
+{
+   Evas *e = _setup_evas();
+   const char *source;
+   Eina_Tmpstr *dest;
+   Evas_Object *o;
+   int i;
+
+   source = _test_image_get("mars_rover_panorama_half-size.jpg");
+   eina_file_mkstemp("evas_saver_benchXXXXXX.tgv", &dest);
+
+   o = evas_object_image_add(e);
+   evas_object_image_file_set(o, source, NULL);
+
+   for (i = 0; i < request; i++)
+     {
+        evas_object_image_save(o, dest, NULL, "compress=1 quality=50");
+     }
+
+   unlink(dest);
+   eina_tmpstr_del(dest);
+
+   evas_free(e);
+}
+
+void evas_bench_saver(Eina_Benchmark *bench)
+{
+   eina_benchmark_register(bench, "tgv-saver", EINA_BENCHMARK(evas_bench_saver_tgv), 20, 2000, 100);
+}
diff --git a/src/benchmarks/evas/images/Light-50.tgv b/src/benchmarks/evas/images/Light-50.tgv
new file mode 100644 (file)
index 0000000..2bc0cef
Binary files /dev/null and b/src/benchmarks/evas/images/Light-50.tgv differ
diff --git a/src/benchmarks/evas/images/Pic1-50.tgv b/src/benchmarks/evas/images/Pic1-50.tgv
new file mode 100644 (file)
index 0000000..0e25b28
Binary files /dev/null and b/src/benchmarks/evas/images/Pic1-50.tgv differ
diff --git a/src/benchmarks/evas/images/Sunrise-100.tgv b/src/benchmarks/evas/images/Sunrise-100.tgv
new file mode 100644 (file)
index 0000000..ca28e20
Binary files /dev/null and b/src/benchmarks/evas/images/Sunrise-100.tgv differ
diff --git a/src/benchmarks/evas/images/mars_rover_panorama_half-size.jpg b/src/benchmarks/evas/images/mars_rover_panorama_half-size.jpg
new file mode 100644 (file)
index 0000000..79c7688
Binary files /dev/null and b/src/benchmarks/evas/images/mars_rover_panorama_half-size.jpg differ
index 6cddccd..84028ce 100644 (file)
@@ -10,7 +10,7 @@ AM_CPPFLAGS = \
 -DPACKAGE_BIN_DIR=\"$(bindir)\" \
 -DPACKAGE_LIB_DIR=\"$(libdir)\" \
 -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FREETYPE_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @EET_CFLAGS@ \
@@ -26,7 +26,7 @@ evas_cserve_main.c
 evas_cserve_LDADD = \
 $(top_builddir)/src/lib/libevas.la \
 @pthread_libs@ \
-@EINA_LIBS@
+@EVAS_GENERAL_LIBS@
 
 evas_cserve_tool_LDFLAGS =
 
@@ -36,7 +36,7 @@ evas_cserve_tool.c
 evas_cserve_tool_LDADD = \
 $(top_builddir)/src/lib/libevas.la \
 @pthread_libs@ \
-@EINA_LIBS@
+@EVAS_GENERAL_LIBS@
 
 endif
 
@@ -56,7 +56,7 @@ AM_CPPFLAGS = \
 -DPACKAGE_LIB_DIR=\"$(libdir)\" \
 -DPACKAGE_LIBEXEC_DIR=\"$(libexecdir)\" \
 @FREETYPE_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @EET_CFLAGS@
 
 evas_cserve2_SOURCES = \
@@ -75,7 +75,7 @@ libevas_cserve2_utils_la = $(top_builddir)/src/lib/cserve2/libevas_cserve2_utils
 
 evas_cserve2_LDADD = \
 @FREETYPE_LIBS@ \
-@EINA_LIBS@ \
+@EVAS_GENERAL_LIBS@ \
 @EFL_SHM_OPEN_LIBS@ \
 @EET_LIBS@ \
 $(libevas_cserve2_utils_la)
@@ -90,10 +90,10 @@ evas_cserve2_debug_SOURCES = \
 evas_cserve2_debug.c
 
 evas_cserve2_usage_LDADD = \
-@EINA_LIBS@
+@EVAS_GENERAL_LIBS@
 
 evas_cserve2_debug_LDADD = \
-@EINA_LIBS@
+@EVAS_GENERAL_LIBS@
 
 evas_cserve2_slave_SOURCES = \
 evas_cserve2_slave.c \
@@ -102,14 +102,14 @@ evas_cserve2_utils.c
 evas_cserve2_slave_LDFLAGS = -export-dynamic
 
 evas_cserve2_slave_LDADD = \
-@EINA_LIBS@ \
+@EVAS_GENERAL_LIBS@ \
 @EFL_SHM_OPEN_LIBS@
 
 dummy_slave_SOURCES = \
 dummy_slave.c
 
 dummy_slave_LDADD = \
-@EINA_LIBS@ \
+@EVAS_GENERAL_LIBS@ \
 @EFL_SHM_OPEN_LIBS@
 
 endif
index 3560387..8075106 100644 (file)
@@ -159,8 +159,6 @@ struct _Slave_Msg_Glyph {
    unsigned int rows;
    unsigned int width;
    unsigned int pitch;
-   unsigned int num_grays;
-   unsigned int pixel_mode;
 };
 
 typedef struct _Slave_Msg_Glyph Slave_Msg_Glyph;
index d87e1e1..a92982e 100644 (file)
@@ -1259,10 +1259,6 @@ _glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size)
              buf += intsize;
              memcpy(buf, &gl->pitch, intsize);
              buf += intsize;
-             memcpy(buf, &gl->num_grays, intsize);
-             buf += intsize;
-             memcpy(buf, &gl->pixel_mode, intsize);
-             buf += intsize;
           }
 
         /* We are removing SHMs from the beginning of the list, so this
@@ -1485,8 +1481,6 @@ _glyphs_load_request_response(Glyphs_Request *req, Slave_Msg_Font_Glyphs_Loaded
              gl->rows = c->glyphs[j].rows;
              gl->width = c->glyphs[j].width;
              gl->pitch = c->glyphs[j].pitch;
-             gl->num_grays = c->glyphs[j].num_grays;
-             gl->pixel_mode = c->glyphs[j].pixel_mode;
              font_mem_usage += sizeof(*gl);
              fc->glyphs = eina_inlist_append(fc->glyphs, EINA_INLIST_GET(gl));
              fc->nglyphs++;
index 759bec1..b69835b 100644 (file)
@@ -320,6 +320,9 @@ _font_slave_glyph_load(Font_Info *fi, unsigned int idx, unsigned int hint)
    return EINA_TRUE;
 }
 
+// import the 1 func we need
+EAPI void *evas_common_font_glyph_compress(void *data, int num_grays, int pixel_mode, int pitch_data, int w, int h, int *size_ret);
+
 /* This function will render the glyph currently in the glyph slot into the
  * given Font Cache.
  */
@@ -327,15 +330,21 @@ static Eina_Bool
 _font_slave_glyph_render(Font_Info *fi, Slave_Msg_Font_Cache *c, unsigned int idx)
 {
    Font_Source_Info *fsi = fi->fsi;
-   unsigned int glyphsize;
+   int glyphsize = 0;
    char *cachedata = cserve2_shm_map(c->shm);
    FT_Glyph glyph;
    FT_BitmapGlyph bglyph;
+   void *buf;
 
    FT_Get_Glyph(fsi->face->glyph, &glyph);
    FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
    bglyph = (FT_BitmapGlyph)glyph;
 
+    if ((bglyph->bitmap.pitch < 1) || (bglyph->bitmap.rows < 1))
+     {
+        FT_Done_Glyph(glyph);
+        return EINA_FALSE;
+     }
    glyphsize = bglyph->bitmap.pitch * bglyph->bitmap.rows;
 
    if (c->usage + glyphsize > cserve2_shm_size_get(c->shm))
@@ -343,8 +352,22 @@ _font_slave_glyph_render(Font_Info *fi, Slave_Msg_Font_Cache *c, unsigned int id
         FT_Done_Glyph(glyph);
         return EINA_FALSE;
      }
+   buf = evas_common_font_glyph_compress(bglyph->bitmap.buffer,
+                                         bglyph->bitmap.num_grays,
+                                         bglyph->bitmap.pixel_mode,
+                                         bglyph->bitmap.pitch,
+                                         bglyph->bitmap.width,
+                                         bglyph->bitmap.rows,
+                                         &glyphsize);
+   if (!buf)
+     {
+        FT_Done_Glyph(glyph);
+        return EINA_FALSE;
+     }
+
 
-   memcpy(cachedata + c->usage, bglyph->bitmap.buffer, glyphsize);
+   memcpy(cachedata + c->usage, buf, glyphsize)
+   free(buf);
 
    // TODO: Check if we have problems with alignment
    c->glyphs[c->nglyphs].index = idx;
@@ -353,8 +376,6 @@ _font_slave_glyph_render(Font_Info *fi, Slave_Msg_Font_Cache *c, unsigned int id
    c->glyphs[c->nglyphs].rows = bglyph->bitmap.rows;
    c->glyphs[c->nglyphs].width = bglyph->bitmap.width;
    c->glyphs[c->nglyphs].pitch = bglyph->bitmap.pitch;
-   c->glyphs[c->nglyphs].num_grays = bglyph->bitmap.num_grays;
-   c->glyphs[c->nglyphs].pixel_mode = bglyph->bitmap.pixel_mode;
    c->usage += glyphsize;
    c->nglyphs++;
 
index 0f4afcb..daf3bca 100644 (file)
@@ -269,6 +269,7 @@ cserve2_client_accept(int fd)
             eina_error_msg_get(err));
         free(client);
         close(fd);
+        return;
      }
 
    cserve2_fd_watch_add(fd, FD_READ | FD_ERROR, cserve2_message_handler,
index a11c635..9a1e01b 100644 (file)
@@ -50,6 +50,7 @@ static const struct ext_loader_s map_loaders[] =
    MATCHING(".bmp", "bmp"),
    MATCHING(".tga", "tga"),
    MATCHING(".wbmp", "wbmp"),
+   MATCHING(".webp", "webp"),
    MATCHING(".ico", "ico"),
    MATCHING(".cur", "ico"),
    MATCHING(".psd", "psd")
@@ -57,7 +58,7 @@ static const struct ext_loader_s map_loaders[] =
 
 static const char *loaders_name[] =
 { /* in order of most likely needed */
-  "png", "jpeg", "eet", "xpm", "tiff", "gif", "svg", "pmaps", "bmp", "tga", "wbmp", "ico", "psd", "edb"
+  "png", "jpeg", "eet", "xpm", "tiff", "gif", "svg", "webp", "pmaps", "bmp", "tga", "wbmp", "ico", "psd", "edb"
 };
 
 Eina_Bool
index 46222c8..96d0c5e 100644 (file)
@@ -42,6 +42,10 @@ if BUILD_LOADER_WBMP
 SUBDIRS += wbmp
 endif
 
+if BUILD_LOADER_WEBP
+SUBDIRS += webp
+endif
+
 if BUILD_LOADER_XPM
 SUBDIRS += xpm
 endif
index 113c19b..faba4a5 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 -I$(top_srcdir)/src/lib/cserve2 \
 -I$(top_srcdir)/src/bin \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @EVIL_CFLAGS@
 
 if BUILD_LOADER_BMP
@@ -18,7 +18,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_bmp.c
 
-module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ -lm
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@ -lm
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index b6aedfb..a164bcd 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/cserve2 \
 -I$(top_srcdir)/src/bin \
 @evas_image_loader_eet_cflags@ \
-@EINA_CFLAGS@
+@EVAS_GENERAL_CFLAGS@
 
 
 if BUILD_LOADER_EET
@@ -19,7 +19,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_eet.c
 
-module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_eet_libs@
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @evas_image_loader_eet_libs@
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 10d0d4e..9c045e0 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 -I$(top_srcdir)/src/lib/cserve2 \
 -I$(top_srcdir)/src/bin \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @EVIL_CFLAGS@
 
 if BUILD_LOADER_ICO
@@ -18,7 +18,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_ico.c
 
-module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 5bb093f..03e3928 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 -I$(top_srcdir)/src/lib/cserve2 \
 -I$(top_srcdir)/src/bin \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @evas_image_loader_jpeg_cflags@ \
 @EVIL_CFLAGS@
 
@@ -19,7 +19,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_jpeg.c
 
-module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ @evas_image_loader_jpeg_libs@
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@ @evas_image_loader_jpeg_libs@
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 1641041..07480b9 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 -I$(top_srcdir)/src/lib/cserve2 \
 -I$(top_srcdir)/src/bin \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @evas_image_loader_pmaps_cflags@ \
 @EVIL_CFLAGS@
 
@@ -19,7 +19,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_pmaps.c
 
-module_la_LIBADD = @evas_image_loader_pmaps_libs@ @EINA_LIBS@ @EVIL_LIBS@
+module_la_LIBADD = @evas_image_loader_pmaps_libs@ @EVAS_GENERAL_LIBS@ @EVIL_LIBS@
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index e99660c..554f44d 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 -I$(top_srcdir)/src/lib/cserve2 \
 -I$(top_srcdir)/src/bin \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @evas_image_loader_png_cflags@ \
 @EVIL_CFLAGS@
 
@@ -19,7 +19,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_png.c
 
-module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_png_libs@ @EVIL_LIBS@
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @evas_image_loader_png_libs@ @EVIL_LIBS@
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 55a3ab2..2b09650 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 -I$(top_srcdir)/src/lib/cserve2 \
 -I$(top_srcdir)/src/bin \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @EVIL_CFLAGS@
 
 if BUILD_LOADER_PSD
@@ -18,7 +18,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_psd.c
 
-module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 7b813ca..b861412 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 -I$(top_srcdir)/src/lib/cserve2 \
 -I$(top_srcdir)/src/bin \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @EVIL_CFLAGS@
 
 if BUILD_LOADER_TGA
@@ -18,7 +18,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_tga.c
 
-module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 19458eb..8c33b61 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 -I$(top_srcdir)/src/lib/cserve2 \
 -I$(top_srcdir)/src/bin \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @evas_image_loader_tiff_cflags@ \
 @EVIL_CFLAGS@
 
@@ -19,7 +19,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_tiff.c
 
-module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ @evas_image_loader_tiff_libs@
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@ @evas_image_loader_tiff_libs@
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index b96e179..bed8c29 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 -I$(top_srcdir)/src/lib/cserve2 \
 -I$(top_srcdir)/src/bin \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @EVIL_CFLAGS@
 
 if BUILD_LOADER_WBMP
@@ -18,7 +18,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_wbmp.c
 
-module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
diff --git a/src/bin/loaders/webp/Makefile.am b/src/bin/loaders/webp/Makefile.am
new file mode 100644 (file)
index 0000000..9f186ff
--- /dev/null
@@ -0,0 +1,33 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/cserve2 \
+-I$(top_srcdir)/src/bin \
+@EINA_CFLAGS@ \
+@evas_image_loader_webp_cflags@ \
+@EVIL_CFLAGS@
+
+if BUILD_LOADER_WEBP
+#if !EVAS_STATIC_BUILD_WEBP
+
+pkgdir = $(libdir)/evas/cserve2/loaders/webp/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_webp.c
+
+module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_webp_libs@ @EVIL_LIBS@
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+#else
+
+#noinst_LTLIBRARIES = libevas_loader_webp.la
+#libevas_loader_webp_la_SOURCES = evas_image_load_webp.c
+#libevas_loader_webp_la_LIBADD = @evas_image_loader_webp_libs@
+
+#endif
+endif
diff --git a/src/bin/loaders/webp/evas_image_load_webp.c b/src/bin/loaders/webp/evas_image_load_webp.c
new file mode 100644 (file)
index 0000000..125c581
--- /dev/null
@@ -0,0 +1,141 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <webp/decode.h>
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "evas_macros.h"
+
+#include "evas_cserve2.h"
+#include "evas_cserve2_slave.h"
+
+
+static Eina_Bool
+evas_image_load_file_head_webp(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int *error)
+{
+   WebPDecoderConfig config;
+   FILE *f;
+   size_t header_size = 30;
+   uint8_t header[30];
+   
+   f = fopen(file, "rb");
+   if (!f)
+   {
+      *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+      return EINA_FALSE;
+   }
+   if (fread(header, header_size, 1, f) != 1)
+   {
+      fclose(f);
+      *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+      return EINA_FALSE;
+   }
+   fclose(f);
+   
+   if (!WebPInitDecoderConfig(&config))
+   {
+      *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+      return EINA_FALSE;
+   }
+   if (WebPGetFeatures(header, header_size, &config.input) != VP8_STATUS_OK)
+   {
+      *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+      return EINA_FALSE;
+   }
+   
+   ilp->w = config.input.width;
+   ilp->h = config.input.height;
+   ilp->alpha = config.input.has_alpha;
+   
+   *error = EVAS_LOAD_ERROR_NONE;
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+evas_image_load_file_data_webp(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int *error)
+{
+   FILE *f;
+   size_t file_size;
+   uint8_t *data, *decoded;
+   int width, height;
+   
+   f = fopen(file, "rb");
+   if (!f)
+   {
+      *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+      return EINA_FALSE;
+   }
+
+   if (fseek(f, 0, SEEK_END) != 0)
+   {
+      *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+      goto close_file;
+   }
+   file_size = ftell(f);
+   if (fseek(f, 0, SEEK_SET) != 0)
+   {
+      *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+      goto close_file;
+   }
+
+   data = malloc(file_size);
+   if (!data)
+   {
+      *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+      goto close_file;
+   }
+   if (fread(data, file_size, 1, f) != 1)
+   {
+      free(data);
+      *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+      goto close_file;
+   }
+   fclose(f);
+
+   decoded = WebPDecodeBGRA(data, file_size, &width, &height);
+   if (!decoded)
+     {
+        *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+        free(data);
+        goto close_file;
+     }
+   memcpy(ilp->buffer, decoded, width * height * 4);
+   evas_cserve2_image_premul(ilp);
+   
+   free(decoded);
+   free(data);
+
+   *error = EVAS_LOAD_ERROR_NONE;
+   return EINA_TRUE;
+
+close_file:
+   fclose(f);
+   return EINA_FALSE;
+}
+
+static Evas_Loader_Module_Api modapi =
+{
+   EVAS_CSERVE2_MODULE_API_VERSION,
+   "webp",
+   evas_image_load_file_head_webp,
+   evas_image_load_file_data_webp
+};
+
+static Eina_Bool
+module_init(void)
+{
+   return evas_cserve2_loader_register(&modapi);
+}
+
+static void
+module_shutdown(void)
+{
+}
+
+EINA_MODULE_INIT(module_init);
+EINA_MODULE_SHUTDOWN(module_shutdown);
index 8edae6c..c8117d8 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 -I$(top_srcdir)/src/lib/cserve2 \
 -I$(top_srcdir)/src/bin \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @evas_image_loader_xpm_cflags@ \
 @EVIL_CFLAGS@
 
@@ -19,7 +19,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_xpm.c
 
-module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ @evas_image_loader_xpm_libs@
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@ @evas_image_loader_xpm_libs@
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 8404509..18eb127 100644 (file)
@@ -6,6 +6,8 @@
 # include <Evil.h>
 #endif
 
+#include <ctype.h>
+
 #include "evas_macros.h"
 
 #include "evas_cserve2.h"
 static Eina_File *rgb_txt;
 static void *rgb_txt_map;
 
+static int
+_xpm_hexa_int(const char *s, int len)
+{
+   const char *hexa = "0123456789abcdef";
+   const char *lookup;
+   int i, c, r;
+
+   for (r = 0, i = 0; i < len; i++)
+     {
+        c = s[i];
+        lookup = strchr(hexa, tolower(c));
+        r = (r << 4) | (lookup ? lookup - hexa : 0);
+     }
+
+   return r;
+}
+
 static void
 xpm_parse_color(char *color, int *r, int *g, int *b)
 {
@@ -26,26 +45,15 @@ xpm_parse_color(char *color, int *r, int *g, int *b)
    if (color[0] == '#')
      {
         int                 len;
-        char                val[32];
 
         len = strlen(color) - 1;
         if (len < 96)
           {
-             int                 i;
 
              len /= 3;
-             for (i = 0; i < len; i++)
-                val[i] = color[1 + i + (0 * len)];
-             val[i] = 0;
-             sscanf(val, "%x", r);
-             for (i = 0; i < len; i++)
-                val[i] = color[1 + i + (1 * len)];
-             val[i] = 0;
-             sscanf(val, "%x", g);
-             for (i = 0; i < len; i++)
-                val[i] = color[1 + i + (2 * len)];
-             val[i] = 0;
-             sscanf(val, "%x", b);
+             *r = _xpm_hexa_int(&(color[1 + (0 * len)]), len);
+             *g = _xpm_hexa_int(&(color[1 + (1 * len)]), len);
+             *b = _xpm_hexa_int(&(color[1 + (2 * len)]), len);
              if (len == 1)
                {
                   *r = (*r << 4) | *r;
@@ -75,7 +83,7 @@ xpm_parse_color(char *color, int *r, int *g, int *b)
              int rr, gg, bb;
              char name[4096];
 
-             /* FIXME: not really efficient */
+             /* FIXME: not really efficient, should be loaded once in memory with a lookup table */
              memcpy(buf, tmp, endline - tmp);
              buf[endline - tmp + 1] = '\0';
 
@@ -94,29 +102,56 @@ xpm_parse_color(char *color, int *r, int *g, int *b)
      }
 }
 
+typedef struct _CMap CMap;
+struct _CMap {
+   EINA_RBTREE;
+   short         r, g, b;
+   char          str[6];
+   unsigned char transp;
+};
+
+Eina_Rbtree_Direction
+_cmap_cmp_node_cb(const Eina_Rbtree *left, const Eina_Rbtree *right, void *data __UNUSED__)
+{
+   CMap *lcm;
+   CMap *rcm;
+
+   lcm = EINA_RBTREE_CONTAINER_GET(left, CMap);
+   rcm = EINA_RBTREE_CONTAINER_GET(right, CMap);
+
+   if (strcmp(lcm->str, rcm->str) < 0)
+     return EINA_RBTREE_LEFT;
+   return EINA_RBTREE_RIGHT;
+}
+
+int
+_cmap_cmp_key_cb(const Eina_Rbtree *node, const void *key, int length __UNUSED__, void *data __UNUSED__)
+{
+   CMap *root = EINA_RBTREE_CONTAINER_GET(node, CMap);
+
+   return strcmp(root->str, key);
+}
+
 /** FIXME: clean this up and make more efficient  **/
 static Eina_Bool
 evas_image_load_file_xpm(Evas_Img_Load_Params *ilp, const char *file, const char *key __UNUSED__, int load_data, int *error)
 {
-   DATA32             *ptr, *end;
-   Eina_File          *f;
-   const char         *map;
-   size_t              length;
-   size_t              position;
-
-   int                 pc, c, i, j, k, w, h, ncolors, cpp, comment, transp,
-                       quote, context, len, done, r, g, b, backslash, lu1, lu2;
-   char               *line = NULL;
-   char                s[256], tok[128], col[256], *tl;
-   int                 lsz = 256;
-   struct _cmap {
-      char             str[6];
-      unsigned char    transp;
-      short            r, g, b;
-   }                  *cmap = NULL;
-
-   short               lookup[128 - 32][128 - 32];
-   int                 count, pixels;
+   DATA32      *ptr, *end;
+   Eina_File   *f;
+   const char  *map;
+   size_t       length;
+   size_t       position;
+
+   int          pc, c, i, j, k, w, h, ncolors, cpp, comment, transp,
+                quote, context, len, done, r, g, b, backslash, lu1, lu2;
+   char        *line = NULL;
+   char         s[256], tok[128], col[256], *tl;
+   int          lsz = 256;
+   CMap        *cmap = NULL;
+   Eina_Rbtree *root = NULL;
+
+   short        lookup[128 - 32][128 - 32];
+   int          count, pixels;
 
    done = 0;
 //   transp = -1;
@@ -235,7 +270,7 @@ evas_image_load_file_xpm(Evas_Img_Load_Params *ilp, const char *file, const char
 
                        if (!cmap)
                          {
-                            cmap = malloc(sizeof(struct _cmap) * ncolors);
+                            cmap = malloc(sizeof(CMap) * ncolors);
                             if (!cmap)
                               {
                                *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
@@ -264,6 +299,7 @@ evas_image_load_file_xpm(Evas_Img_Load_Params *ilp, const char *file, const char
                             len = strlen(line);
                             strncpy(cmap[j].str, line, cpp);
                             cmap[j].str[cpp] = 0;
+                            if (load_data) root = eina_rbtree_inline_insert(root, EINA_RBTREE_GET(&cmap[j]), _cmap_cmp_node_cb, NULL);
                            for (slen = 0; slen < cpp; slen++)
                              {
                                 /* fix the ascii of the  color string - if its < 32 - just limit to 32 */
@@ -275,9 +311,11 @@ evas_image_load_file_xpm(Evas_Img_Load_Params *ilp, const char *file, const char
                               {
                                  if (line[k] != ' ')
                                    {
-                                      s[0] = 0;
-                                      sscanf(&line[k], "%255s", s);
-                                      slen = strlen(s);
+                                      const char *tmp = strchr(&line[k], ' ');
+                                      slen = tmp ? tmp - &line[k]: 255;
+
+                                      strncpy(s, &line[k], slen);
+                                      s[slen] = 0;
                                       k += slen;
                                       if (!strcmp(s, "c")) iscolor = 1;
                                       if ((!strcmp(s, "m")) || (!strcmp(s, "s"))
@@ -490,6 +528,8 @@ evas_image_load_file_xpm(Evas_Img_Load_Params *ilp, const char *file, const char
                                       ((i < 65536) && (ptr < end) && (line[i]));
                                       i++)
                                    {
+                                      Eina_Rbtree *l;
+
                                       for (j = 0; j < cpp; j++, i++)
                                        {
                                           col[j] = line[i];
@@ -497,30 +537,26 @@ evas_image_load_file_xpm(Evas_Img_Load_Params *ilp, const char *file, const char
                                        }
                                       col[j] = 0;
                                       i--;
-                                      for (j = 0; j < ncolors; j++)
+
+                                      l = eina_rbtree_inline_lookup(root, col, j, _cmap_cmp_key_cb, NULL);
+                                      if (l)
                                         {
-                                           if (!strcmp(col, cmap[j].str))
+                                           CMap *cm = EINA_RBTREE_CONTAINER_GET(l, CMap);
+
+                                           r = (unsigned char)cm->r;
+                                           g = (unsigned char)cm->g;
+                                           b = (unsigned char)cm->b;
+                                           if (cm->transp)
                                              {
-                                                if (cmap[j].transp)
-                                                  {
-                                                     r = (unsigned char)cmap[j].r;
-                                                     g = (unsigned char)cmap[j].g;
-                                                     b = (unsigned char)cmap[j].b;
-                                                    *ptr = RGB_JOIN(r, g, b);
-                                                    ptr++;
-                                                     count++;
-                                                  }
-                                                else
-                                                  {
-                                                    r = (unsigned char)cmap[j].r;
-                                                     g = (unsigned char)cmap[j].g;
-                                                     b = (unsigned char)cmap[j].b;
-                                                    *ptr = ARGB_JOIN(0xff, r, g, b);
-                                                    ptr++;
-                                                     count++;
-                                                  }
-                                               break;
+                                                *ptr = RGB_JOIN(r, g, b);
                                              }
+                                           else
+                                             {
+                                                *ptr = ARGB_JOIN(0xff, r, g, b);
+                                             }
+
+                                           ptr++;
+                                           count++;
                                         }
                                    }
                               }
@@ -530,24 +566,26 @@ evas_image_load_file_xpm(Evas_Img_Load_Params *ilp, const char *file, const char
                                       ((i < 65536) && (ptr < end) && (line[i]));
                                       i++)
                                    {
+                                      Eina_Rbtree *l;
+
                                       for (j = 0; j < cpp; j++, i++)
                                         {
                                            col[j] = line[i];
                                         }
                                       col[j] = 0;
                                       i--;
-                                      for (j = 0; j < ncolors; j++)
+
+                                      l = eina_rbtree_inline_lookup(root, col, 0, _cmap_cmp_key_cb, NULL);
+                                      if (l)
                                         {
-                                           if (!strcmp(col, cmap[j].str))
-                                             {
-                                                r = (unsigned char)cmap[j].r;
-                                                g = (unsigned char)cmap[j].g;
-                                                b = (unsigned char)cmap[j].b;
-                                               *ptr = ARGB_JOIN(0xff, r, g, b);
-                                               ptr++;
-                                               count++;
-                                                break;
-                                             }
+                                           CMap *cm = EINA_RBTREE_CONTAINER_GET(l, CMap);
+                                           
+                                           r = (unsigned char)cm->r;
+                                           g = (unsigned char)cm->g;
+                                           b = (unsigned char)cm->b;
+                                           *ptr = ARGB_JOIN(0xff, r, g, b);
+                                           ptr++;
+                                           count++;
                                         }
                                    }
                               }
index e03ff9e..276ac9f 100644 (file)
@@ -18,7 +18,7 @@ AM_CPPFLAGS = \
 -DPACKAGE_LIB_DIR=\"$(libdir)\" \
 -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
 -DPACKAGE_EXAMPLES_DIR=\"$(datadir)/$(PACKAGE)/examples\" \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
@@ -85,7 +85,7 @@ evas_smart_interface_LDADD = $(top_builddir)/src/lib/libevas.la @ECORE_EVAS_LIBS
 
 examples_PROGRAMS += evas_box
 evas_box_SOURCES = evas-box.c
-evas_box_LDADD = $(top_builddir)/src/lib/libevas.la @ECORE_EVAS_LIBS@ @EINA_LIBS@
+evas_box_LDADD = $(top_builddir)/src/lib/libevas.la @ECORE_EVAS_LIBS@ @EVAS_GENERAL_LIBS@
 
 #the ones using ecore_evas and edje follow
 AM_CPPFLAGS += @EDJE_CFLAGS@
old mode 100644 (file)
new mode 100755 (executable)
index de8ed50..4de6f2c
@@ -27,6 +27,9 @@
 #define WIDTH         320
 #define HEIGHT        480
 
+#define __UNUSED__
+#define PACKAGE_EXAMPLES_DIR "."
+
 static const char *border_img_path = PACKAGE_EXAMPLES_DIR "/red.png";
 static const char *edje_file_path = PACKAGE_EXAMPLES_DIR "/aspect.edj";
 
index 93c4d4a..8b65981 100644 (file)
@@ -39,6 +39,8 @@ static const char *commands = \
   "\td - decrease smart object's size\n"
   "\ti - increase smart object's size\n"
   "\tc - change smart object's clipper color\n"
+  "\t. - rotate object to the right\n"
+  "\t, - rotate object to the left\n"
   "\th - print help\n"
   "\tq - quit\n"
 ;
@@ -60,6 +62,7 @@ struct color_tuple
    int r, g, b, a;
 } clipper_colors[4] = {WHITE, RED, GREEN, BLUE};
 int cur_color = 0;
+int cur_angle = 0;
 
 static const char *
 _index_to_color(int i)
@@ -443,6 +446,21 @@ evas_smart_example_set_right(Evas_Object *o,
 /* END OF example smart object's own interface */
 
 static void
+_map_update(void)
+{
+   Evas_Map *m;
+   Evas_Coord x, y, w, h;
+
+   evas_object_geometry_get(d.smt, &x, &y, &w, &h);
+   m = evas_map_new(4);
+   evas_map_util_points_populate_from_object(m, d.smt);
+   evas_map_util_rotate(m, cur_angle, x + (w / 2), y + (h / 2));
+   evas_object_map_set(d.smt, m);
+   evas_object_map_enable_set(d.smt, EINA_TRUE);
+   evas_map_free(m);
+}
+
+static void
 _on_keydown(void *data __UNUSED__,
             Evas *evas __UNUSED__,
             Evas_Object *o __UNUSED__,
@@ -569,6 +587,7 @@ _on_keydown(void *data __UNUSED__,
           }
 
         evas_object_move(d.smt, x, y);
+        _map_update();
 
         return;
      }
@@ -584,6 +603,7 @@ _on_keydown(void *data __UNUSED__,
         h *= 1.1;
 
         evas_object_resize(d.smt, w, h);
+        _map_update();
 
         return;
      }
@@ -599,6 +619,7 @@ _on_keydown(void *data __UNUSED__,
         h *= 0.9;
 
         evas_object_resize(d.smt, w, h);
+        _map_update();
 
         return;
      }
@@ -617,6 +638,23 @@ _on_keydown(void *data __UNUSED__,
 
         return;
      }
+
+   /* rotate object to the right */
+   if (strcmp(ev->keyname, "period") == 0)
+     {
+        cur_angle = (cur_angle + 30) % 360;
+        _map_update();
+        return;
+     }
+
+   if (strcmp(ev->keyname, "comma") == 0)
+     {
+        cur_angle = (cur_angle - 30) % 360;
+        _map_update();
+        return;
+     }
+
+   fprintf(stderr, "Invalid key: '%s'\n", ev->keyname);
 }
 
 static void
old mode 100644 (file)
new mode 100755 (executable)
index df67c0c..e1661a0
 /**
-   @mainpage Evas
-
-   @version 1.2
-   @date 2000-2012
-
-   Please see the @ref authors page for contact details.
-   @link Evas.h Evas API @endlink
-
-   @link Evas.h Evas API @endlink
-
-   @section toc Table of Contents
-
-   @li @ref intro
-   @li @ref work
-   @li @ref compiling
-   @li @ref install
-   @li @ref next_steps
-   @li @ref intro_example
-
-
-   @section intro What is Evas?
-
-   Evas is a clean display canvas API for several target display systems
-   that can draw anti-aliased text, smooth super and sub-sampled scaled
-   images, alpha-blend objects and much more.
-
-   It abstracts any need to know much about what the characteristics of
-   your display system are or what graphics calls are used to draw them
-   and how. It deals on an object level where all you do is create and
-   manipulate objects in a canvas, set their properties, and the rest is
-   done for you.
-
-   Evas optimises the rendering pipeline to minimise effort in redrawing
-   changes made to the canvas and so takes this work out of the
-   programmers hand, saving a lot of time and energy.
-
-   It's small and lean, designed to work on embedded systems all the way
-   to large and powerful multi-cpu workstations. It can be compiled to
-   only have the features you need for your target platform if you so
-   wish, thus keeping it small and lean. It has several display
-   back-ends, letting it display on several display systems, making it
-   portable for cross-device and cross-platform development.
-
-   @subsection intro_not_evas What Evas is not?
-
-   Evas is not a widget set or widget toolkit, however it is their
-   base. See Elementary (http://docs.enlightenment.org/auto/elementary/)
-   for a toolkit based on Evas, Edje, Ecore and other Enlightenment
-   technologies.
-
-   It is not dependent or aware of main loops, input or output
-   systems. Input should be polled from various sources and fed to
-   Evas. Similarly, it will not create windows or report windows updates
-   to your system, rather just drawing the pixels and reporting to the
-   user the areas that were changed. Of course these operations are quite
-   common and thus they are ready to use in Ecore, particularly in
-   Ecore_Evas (http://docs.enlightenment.org/auto/ecore/).
-
-
-   @section work How does Evas work?
-
-   Evas is a canvas display library. This is markedly different from most
-   display and windowing systems as a canvas is structural and is also a
-   state engine, whereas most display and windowing systems are immediate
-   mode display targets. Evas handles the logic between a structural
-   display via its state engine, and controls the target windowing system
-   in order to produce rendered results of the current canvas' state on
-   the display.
-
-   Immediate mode display systems retain very little, or no state. A
-   program will execute a series of commands, as in the pseudo code:
-
-   @verbatim
-   draw line from position (0, 0) to position (100, 200);
-
-   draw rectangle from position (10, 30) to position (50, 500);
-
-   bitmap_handle = create_bitmap();
-   scale bitmap_handle to size 100 x 100;
-   draw image bitmap_handle at position (10, 30);
-   @endverbatim
-
-   The series of commands is executed by the windowing system and the
-   results are displayed on the screen (normally). Once the commands are
-   executed the display system has little or no idea of how to reproduce
-   this image again, and so has to be instructed by the application how
-   to redraw sections of the screen whenever needed. Each successive
-   command will be executed as instructed by the application and either
-   emulated by software or sent to the graphics hardware on the device to
-   be performed.
-
-   The advantage of such a system is that it is simple, and gives a
-   program tight control over how something looks and is drawn. Given the
-   increasing complexity of displays and demands by users to have better
-   looking interfaces, more and more work is needing to be done at this
-   level by the internals of widget sets, custom display widgets and
-   other programs. This means more and more logic and display rendering
-   code needs to be written time and time again, each time the
-   application needs to figure out how to minimise redraws so that
-   display is fast and interactive, and keep track of redraw logic. The
-   power comes at a high-price, lots of extra code and work.  Programmers
-   not very familiar with graphics programming will often make mistakes
-   at this level and produce code that is sub optimal. Those familiar
-   with this kind of programming will simply get bored by writing the
-   same code again and again.
-
-   For example, if in the above scene, the windowing system requires the
-   application to redraw the area from 0, 0 to 50, 50 (also referred as
-   "expose event"), then the programmer must calculate manually the
-   updates and repaint it again:
-
-   @verbatim
-   Redraw from position (0, 0) to position (50, 50):
-
-   // what was in area (0, 0, 50, 50)?
-
-   // 1. intersection part of line (0, 0) to (100, 200)?
-      draw line from position (0, 0) to position (25, 50);
-
-   // 2. intersection part of rectangle (10, 30) to (50, 500)?
-      draw rectangle from position (10, 30) to position (50, 50)
-
-   // 3. intersection part of image at (10, 30), size 100 x 100?
-      bitmap_subimage = subregion from position (0, 0) to position (40, 20)
-      draw image bitmap_subimage at position (10, 30);
-   @endverbatim
-
-   The clever reader might have noticed that, if all elements in the
-   above scene are opaque, then the system is doing useless paints: part
-   of the line is behind the rectangle, and part of the rectangle is
-   behind the image. These useless paints tend to be very costly, as
-   pixels tend to be 4 bytes in size, thus an overlapping region of 100 x
-   100 pixels is around 40000 useless writes! The developer could write
-   code to calculate the overlapping areas and avoid painting then, but
-   then it should be mixed with the "expose event" handling mentioned
-   above and quickly one realizes the initially simpler method became
-   really complex.
-
-   Evas is a structural system in which the programmer creates and
-   manages display objects and their properties, and as a result of this
-   higher level state management, the canvas is able to redraw the set of
-   objects when needed to represent the current state of the canvas.
-
-   For example, the pseudo code:
-
-   @verbatim
-   line_handle = create_line();
-   set line_handle from position (0, 0) to position (100, 200);
-   show line_handle;
-
-   rectangle_handle = create_rectangle();
-   move rectangle_handle to position (10, 30);
-   resize rectangle_handle to size 40 x 470;
-   show rectangle_handle;
-
-   bitmap_handle = create_bitmap();
-   scale bitmap_handle to size 100 x 100;
-   move bitmap_handle to position (10, 30);
-   show bitmap_handle;
-
-   render scene;
-   @endverbatim
-
-   This may look longer, but when the display needs to be refreshed or
-   updated, the programmer only moves, resizes, shows, hides etc. the
-   objects that need to change. The programmer simply thinks at the
-   object logic level, and the canvas software does the rest of the work
-   for them, figuring out what actually changed in the canvas since it
-   was last drawn, how to most efficiently redraw the canvas and its
-   contents to reflect the current state, and then it can go off and do
-   the actual drawing of the canvas.
-
-   This lets the programmer think in a more natural way when dealing with
-   a display, and saves time and effort of working out how to load and
-   display images, render given the current display system etc. Since
-   Evas also is portable across different display systems, this also
-   gives the programmer the ability to have their code ported and
-   displayed on different display systems with very little work.
-
-   Evas can be seen as a display system that stands somewhere between a
-   widget set and an immediate mode display system. It retains basic
-   display logic, but does very little high-level logic such as
-   scrollbars, sliders, push buttons etc.
-
-
-   @section compiling How to compile using Evas ?
-
-   Evas is a library your application links to. The procedure for this is
-   very simple. You simply have to compile your application with the
-   appropriate compiler flags that the @c pkg-config script outputs. For
-   example:
-
-   Compiling C or C++ files into object files:
-
-   @verbatim
-   gcc -c -o main.o main.c `pkg-config --cflags evas`
-   @endverbatim
-
-   Linking object files into a binary executable:
-
-   @verbatim
-   gcc -o my_application main.o `pkg-config --libs evas`
-   @endverbatim
-
-   You simply have to make sure that @c pkg-config is in your shell's @c
-   PATH (see the manual page for your appropriate shell) and @c evas.pc
-   in @c /usr/lib/pkgconfig or its path in the @c PKG_CONFIG_PATH
-   environment variable. It's that simple to link and use Evas once you
-   have written your code to use it.
-
-   Since the program is linked to Evas, it is now able to use any
-   advertised API calls to display graphics in a canvas managed by it, as
-   well as use the API calls provided to manage data.
-
-   You should make sure you add any extra compile and link flags to your
-   compile commands that your application may need as well. The above
-   example is only guaranteed to make Evas add it's own requirements.
-
-
-   @section install How is it installed?
-
-   Simple:
-
-   @verbatim
-   ./configure
-   make
-   su -
-   ...
-   make install
-   @endverbatim
-
-   @section next_steps Next Steps
-
-   After you understood what Evas is and installed it in your system you
-   should proceed understanding the programming interface for all
-   objects, then see the specific for the most used elements. We'd
-   recommend you to take a while to learn Ecore
-   (http://docs.enlightenment.org/auto/ecore/) and Edje
-   (http://docs.enlightenment.org/auto/edje/) as they will likely save
-   you tons of work compared to using just Evas directly.
-
-   Recommended reading:
-
-   @li @ref Evas_Object_Group, where you'll get how to basically
-    manipulate generic objects lying on an Evas canvas, handle canvas
-    and object events, etc.
-   @li @ref Evas_Object_Rectangle, to learn about the most basic object
-    type on Evas -- the rectangle.
-   @li @ref Evas_Object_Polygon, to learn how to create polygon elements
-    on the canvas.
-   @li @ref Evas_Line_Group, to learn how to create line elements on the
-    canvas.
-   @li @ref Evas_Object_Image, to learn about image objects, over which
-    Evas can do a plethora of operations.
-   @li @ref Evas_Object_Text, to learn how to create textual elements on
-    the canvas.
-   @li @ref Evas_Object_Textblock, to learn how to create multiline
-    textual elements on the canvas.
-   @li @ref Evas_Smart_Object_Group and @ref Evas_Smart_Group, to define
-    new objects that provide @b custom functions to handle clipping,
-    hiding, moving, resizing, color setting and more. These could
-    be as simple as a group of objects that move together (see @ref
-    Evas_Smart_Object_Clipped) up to implementations of what
-    ends to be a widget, providing some intelligence (thus the name)
-    to Evas objects -- like a button or check box, for example.
-
-   @section intro_example Introductory Example
-
-   @include evas-buffer-simple.c
- */
-
-/**
-   @page authors Authors
-   @author Carsten Haitzler <raster@@rasterman.com>
-   @author Till Adam <till@@adam-lilienthal.de>
-   @author Steve Ireland <sireland@@pobox.com>
-   @author Brett Nash <nash@@nash.id.au>
-   @author Tilman Sauerbeck <tilman@@code-monkey.de>
-   @author Corey Donohoe <atmos@@atmos.org>
-   @author Yuri Hudobin <glassy_ape@@users.sourceforge.net>
-   @author Nathan Ingersoll <ningerso@@d.umn.edu>
-   @author Willem Monsuwe <willem@@stack.nl>
-   @author Jose O Gonzalez <jose_ogp@@juno.com>
-   @author Bernhard Nemec <Bernhard.Nemec@@viasyshc.com>
-   @author Jorge Luis Zapata Muga <jorgeluis.zapata@@gmail.com>
-   @author Cedric Bail <cedric.bail@@free.fr>
-   @author Gustavo Sverzut Barbieri <barbieri@@profusion.mobi>
-   @author Vincent Torri <vtorri@@univ-evry.fr>
-   @author Tim Horton <hortont424@@gmail.com>
-   @author Tom Hacohen <tom@@stosb.com>
-   @author Mathieu Taillefumier <mathieu.taillefumier@@free.fr>
-   @author Iván Briano <ivan@@profusion.mobi>
-   @author Gustavo Lima Chaves <glima@@profusion.mobi>
-   @author Samsung Electronics
-   @author Samsung SAIT
-   @author Sung W. Park <sungwoo@@gmail.com>
-   @author Jiyoun Park <jy0703.park@@samsung.com>
-   @author Myoungwoon Roy Kim(roy_kim) <myoungwoon.kim@@samsung.com> <myoungwoon@@gmail.com>
-   @author Thierry el Borgi <thierry@@substantiel.fr>
-   @author Shilpa Singh <shilpa.singh@@samsung.com> <shilpasingh.o@@gmail.com>
-   @author ChunEon Park <hermet@@hermet.pe.kr>
-   @author Christopher 'devilhorns' Michael <cpmichael1@@comcast.net>
-   @author Seungsoo Woo <om101.woo@@samsung.com>
-   @author Youness Alaoui <kakaroto@@kakaroto.homelinux.net>
-   @author Jim Kukunas <james.t.kukunas@@linux.intel.com>
-   @author Nicolas Aguirre <aguirre.nicolas@@gmail.com>
-   @author Rafal Krypa <r.krypa@@samsung.com>
-   @author Hyoyoung Chang <hyoyoung@@gmail.com>
-   @author Jérôme Pinot <ngc891@@gmail.com>
-   @author Rafael Antognolli <antognolli@@profusion.mobi>
-
-   Please contact <enlightenment-devel@lists.sourceforge.net> to get in
-   contact with the developers and maintainers.
+ * @defgroup Evas Evas
+ * @ingroup EFL_Group
+ *
+ * @brief Evas provide a clean display canvas API.
+ *
+ * See @ref evas_main for more details
+ *
+ * @{
+ */
+
+/**
+ * @page evas_main Evas
+ *
+ * @date 2000 (created)
+ *
+ * @section toc Table of Contents
+ *
+ * @li @ref evas_main_intro
+ * @li @ref evas_main_work
+ * @li @ref evas_main_next_steps
+ *
+ *
+ * @section evas_main_intro Introduction
+ *
+ * Evas is a clean display canvas API for several target display systems
+ * that can draw anti-aliased text, smooth super and sub-sampled scaled
+ * images, alpha-blend objects, and much more.
+ *
+ * It abstracts any need to know much about what the characteristics of
+ * your display system are or what graphics calls are used to draw them
+ * and how. It deals on an object level where all you do is create and
+ * manipulate objects in a canvas, set their properties, and the rest is
+ * done for you.
+ *
+ * Evas optimises the rendering pipeline to minimise effort in redrawing
+ * changes made to the canvas and so takes this work out of the
+ * programmers hand, saving a lot of time and energy.
+ *
+ * It is small and lean, and is designed to work on embedded systems all the way
+ * to large and powerful multi-CPU workstations. It can be compiled to
+ * only have the features you need for your target platform if you so
+ * wish, thus keeping it small and lean. It has several display
+ * back-ends, letting it display on several display systems, making it
+ * portable for cross-device and cross-platform development.
+ *
+ * @subsection evas_main_intro_not_evas What Evas is not?
+ *
+ * Evas is not a widget set or widget toolkit, however it is their
+ * base. See @ref Elementary for a toolkit based on @ref Evas, @ref Edje_Group,
+ * @ref Ecore_Group and other Enlightenment technologies.
+ *
+ * It is not dependent or aware of main loops, input or output
+ * systems. Input should be polled from various sources and fed to
+ * Evas. Similarly, it does not create windows or report windows updates
+ * to your system, but just draws the pixels and report to the
+ * user the areas that were changed.
+ * @internal
+ * Of course, these operations are quite
+ * common and thus they are ready to use in Ecore, particularly in @ref
+ * Ecore_Evas_Group.
+ * @endinternal
+ *
+ *
+ * @section evas_main_work How does Evas work?
+ *
+ * Evas is a canvas display library. This is markedly different from most
+ * display and windowing systems as a canvas is structural and is also a
+ * state engine, whereas most display and windowing systems are immediate
+ * mode display targets. Evas handles the logic between a structural
+ * display via its state engine, and controls the target windowing system
+ * in order to produce rendered results of the current canvas' state on
+ * the display.
+ *
+ * Immediate mode display systems retain very little, or no state. A
+ * program executes a series of commands, as in the pseudo code:
+ *
+ * @verbatim
+ * draw line from position (0, 0) to position (100, 200);
+ *
+ * draw rectangle from position (10, 30) to position (50, 500);
+ *
+ * bitmap_handle = create_bitmap();
+ * scale bitmap_handle to size 100 x 100;
+ * draw image bitmap_handle at position (10, 30);
+ * @endverbatim
+ *
+ * The series of commands is executed by the windowing system and the
+ * results are displayed on the screen (normally). Once the commands are
+ * executed the display system has little or no idea of how to reproduce
+ * this image again, and so has to be instructed by the application on how
+ * to redraw sections of the screen whenever needed. Each successive
+ * command is executed as instructed by the application and either
+ * emulated by software or sent to the graphics hardware on the device to
+ * be performed.
+ *
+ * The advantage of such a system is that it is simple, and gives a
+ * program tight control over how something looks and is drawn. Given the
+ * increasing complexity of displays and demands by users to have better
+ * looking interfaces, more and more work is needing to be done at this
+ * level by the internals of widget sets, custom display widgets and
+ * other programs. This means that more and more logic and display rendering
+ * code needs to be written each time the application needs to figure
+ * out how to minimise redraws so that display is fast and interactive,
+ * and keeps track of redraw logic. The power comes at a high-price,
+ * with lots of extra code and work.  Programmers not very familiar with
+ * graphics programming often make mistakes at this level and produce
+ * code that is sub optimal. Those familiar with this kind of programming
+ * simply get bored by writing the same code again and again.
+ *
+ * For example, if in the above scene, the windowing system requires the
+ * application to redraw the area from 0, 0 to 50, 50 (also referred as
+ * "expose event"), then the programmer must calculate manually the
+ * updates and repaint it again:
+ *
+ * @verbatim
+ * Redraw from position (0, 0) to position (50, 50):
+ *
+ * // what is in area (0, 0, 50, 50)?
+ *
+ * // 1. intersection part of line (0, 0) to (100, 200)?
+ *    draw line from position (0, 0) to position (25, 50);
+ *
+ * // 2. intersection part of rectangle (10, 30) to (50, 500)?
+ *    draw rectangle from position (10, 30) to position (50, 50)
+ *
+ * // 3. intersection part of image at (10, 30), size 100 x 100?
+ *    bitmap_subimage = subregion from position (0, 0) to position (40, 20)
+ *    draw image bitmap_subimage at position (10, 30);
+ * @endverbatim
+ *
+ * You might have noticed that, if all elements in the above scene are
+ * opaque, then the system is doing useless paints: part of the line is
+ * behind the rectangle, and part of the rectangle is behind the image.
+ * These useless paints tend to be very costly, as pixels tend to be 4 bytes
+ * in size; thus an overlapping region of 100 x 100 pixels is around 40000
+ * useless writes! You could write code to calculate the overlapping
+ * areas and avoid painting then, but then it should be mixed with the
+ * "expose event" handling mentioned above and you quickly realize that
+ * the initially simpler method became really complex.
+ *
+ * Evas is a structural system in which the programmer creates and
+ * manages display objects and their properties, and as a result of this
+ * higher level state management, the canvas is able to redraw the set of
+ * objects when needed to represent the current state of the canvas.
+ *
+ * For example, the pseudo code:
+ *
+ * @verbatim
+ * line_handle = create_line();
+ * set line_handle from position (0, 0) to position (100, 200);
+ * show line_handle;
+ *
+ * rectangle_handle = create_rectangle();
+ * move rectangle_handle to position (10, 30);
+ * resize rectangle_handle to size 40 x 470;
+ * show rectangle_handle;
+ *
+ * bitmap_handle = create_bitmap();
+ * scale bitmap_handle to size 100 x 100;
+ * move bitmap_handle to position (10, 30);
+ * show bitmap_handle;
+ *
+ * render scene;
+ * @endverbatim
+ *
+ * This may look longer, but when the display needs to be refreshed or
+ * updated, you move, resize, show, or hide the objects that need to change.
+ * You can simply think at the object logic level, and the canvas software
+ * does the rest of the work for you, figuring out what actually changed in the
+ * canvas since it had been last drawn, how to most efficiently redraw the canvas and 
+ * its contents to reflect the current state, and then it can go off and do
+ * the actual drawing of the canvas.
+ *
+ * This lets you think in a more natural way when dealing with
+ * a display, and saves time and effort of working out how to load and
+ * display images, render given the current display system, and so on. Since
+ * Evas also is portable across different display systems, this also
+ * gives you the ability to have their code ported and
+ * displayed on different display systems with very little work.
+ *
+ * Evas can be seen as a display system that stands somewhere between a
+ * widget set and an immediate mode display system. It retains basic
+ * display logic, but does very little high-level logic such as
+ * scrollbars, sliders, and push buttons.
+ *
+ * @section evas_main_next_steps Next Steps
+ *
+ * After you understood what Evas is and installed it in your system you
+ * should proceed to understand the programming interface for all
+ * objects, and then see the specifics for the most used elements.
+ * You should take a while to learn @ref Ecore_Group and @ref Edje_Group as they
+ * likely save you tons of work compared to using just Evas directly.
+ *
+ * Recommended reading:
+ *
+ * @li @ref Evas_Object_Group, where you get information on how to basically
+ * manipulate generic objects lying on an Evas canvas, handle canvas
+ * and object events, and so on.
+ * @li @ref Evas_Object_Rectangle, to learn about the most basic object
+ * type on Evas -- the rectangle.
+ * @li @ref Evas_Object_Polygon, to learn how to create polygon elements
+ * on the canvas.
+ * @li @ref Evas_Line_Group, to learn how to create line elements on the
+ * canvas.
+ * @li @ref Evas_Object_Image, to learn about image objects, over which
+ * Evas can do a plethora of operations.
+ * @li @ref Evas_Object_Text, to learn how to create textual elements on
+ * the canvas.
+ * @li @ref Evas_Object_Textblock, to learn how to create multiline
+ * textual elements on the canvas.
+ * @internal
+ * @li @ref Evas_Smart_Object_Group and @ref Evas_Smart_Group, to define
+ * new objects that provide @b custom functions to handle clipping,
+ * hiding, moving, resizing, color setting and more. These could
+ * be as simple as a group of objects that move together (see @ref
+ * Evas_Smart_Object_Clipped) up to implementations of what
+ * ends to be a widget, providing some intelligence (thus the name)
+ * to Evas objects -- like a button or check box, for example.
+ * @endinternal
+ *
  */
 
 #ifndef _EVAS_H
@@ -352,14 +259,18 @@ extern "C" {
 #endif
 
 #define EVAS_VERSION_MAJOR 1
-#define EVAS_VERSION_MINOR 6
+#define EVAS_VERSION_MINOR 8
 
+/**
+ * @typedef Evas_Version
+ * @brief The version of Evas.
+ */
 typedef struct _Evas_Version
 {
-   int major;
-   int minor;
-   int micro;
-   int revision;
+   int major;     /**< Major component of the version */
+   int minor;     /**< Minor component of the version */
+   int micro;     /**< Micro component of the version */
+   int revision;  /**< Revision component of the version */
 } Evas_Version;
 
 EAPI extern Evas_Version * evas_version;
@@ -384,8 +295,7 @@ typedef enum _Evas_BiDi_Direction
 } Evas_BiDi_Direction;
 
 /**
- * Identifier of callbacks to be set for Evas canvases or Evas
- * objects.
+ * @brief Identifier of callbacks to be set for Evas canvases or Evas objects.
  *
  * The following figure illustrates some Evas callbacks:
  *
@@ -422,7 +332,7 @@ typedef enum _Evas_Callback_Type
    EVAS_CALLBACK_RESIZE, /**< Resize Event */
    EVAS_CALLBACK_RESTACK, /**< Restack Event */
    EVAS_CALLBACK_DEL, /**< Object Being Deleted (called before Free) */
-   EVAS_CALLBACK_HOLD, /**< Events go on/off hold */
+   EVAS_CALLBACK_HOLD, /**< Hold Event, Informational purpose event to indicate something */
    EVAS_CALLBACK_CHANGED_SIZE_HINTS, /**< Size hints changed event */
    EVAS_CALLBACK_IMAGE_PRELOADED, /**< Image has been preloaded */
 
@@ -445,24 +355,26 @@ typedef enum _Evas_Callback_Type
    EVAS_CALLBACK_RENDER_PRE, /**< Called just before rendering starts on the canvas target @since 1.2 */
    EVAS_CALLBACK_RENDER_POST, /**< Called just after rendering stops on the canvas target @since 1.2 */
 
-   EVAS_CALLBACK_LAST /**< kept as last element/sentinel -- not really an event */
+   EVAS_CALLBACK_IMAGE_RESIZE, /**< Image size is changed @since 1.8 */
+   EVAS_CALLBACK_DEVICE_CHANGED, /**< Devices added, removed or changed on canvas @since 1.8 */
+   EVAS_CALLBACK_LAST /**< Last element/sentinel -- not really an event */
 } Evas_Callback_Type; /**< The types of events triggering a callback */
 
 /**
  * @def EVAS_CALLBACK_PRIORITY_BEFORE
- * Slightly more prioritized than default.
+ * @brief Slightly more prioritized than default.
  * @since 1.1
  */
 #define EVAS_CALLBACK_PRIORITY_BEFORE  -100
 /**
  * @def EVAS_CALLBACK_PRIORITY_DEFAULT
- * Default callback priority level
+ * @brief Default callback priority level
  * @since 1.1
  */
 #define EVAS_CALLBACK_PRIORITY_DEFAULT 0
 /**
  * @def EVAS_CALLBACK_PRIORITY_AFTER
- * Slightly less prioritized than default.
+ * @brief Slightly less prioritized than default.
  * @since 1.1
  */
 #define EVAS_CALLBACK_PRIORITY_AFTER   100
@@ -470,39 +382,41 @@ typedef enum _Evas_Callback_Type
 /**
  * @typedef Evas_Callback_Priority
  *
- * Callback priority value. Range is -32k - 32k. The lower the number, the
- * bigger the priority.
+ * @brief Callback priority value. Range is -32k to 32k. The lower the number, the
+ * higher the priority.
+ *
+ * @since 1.1
  *
  * @see EVAS_CALLBACK_PRIORITY_AFTER
  * @see EVAS_CALLBACK_PRIORITY_BEFORE
  * @see EVAS_CALLBACK_PRIORITY_DEFAULT
- *
- * @since 1.1
  */
 typedef short Evas_Callback_Priority;
 
 /**
- * Flags for Mouse Button events
+ * @brief Enumeration for Mouse Button events.
  */
 typedef enum _Evas_Button_Flags
 {
    EVAS_BUTTON_NONE = 0, /**< No extra mouse button data */
-   EVAS_BUTTON_DOUBLE_CLICK = (1 << 0), /**< This mouse button press was the 2nd press of a double click */
-   EVAS_BUTTON_TRIPLE_CLICK = (1 << 1) /**< This mouse button press was the 3rd press of a triple click */
+   EVAS_BUTTON_DOUBLE_CLICK = (1 << 0), /**< Second press of a double click */
+   EVAS_BUTTON_TRIPLE_CLICK = (1 << 1) /**< Third press of a triple click */
 } Evas_Button_Flags; /**< Flags for Mouse Button events */
 
 /**
- * Flags for Events
+ * @brief Enumeration for events.
  */
 typedef enum _Evas_Event_Flags
 {
    EVAS_EVENT_FLAG_NONE = 0, /**< No fancy flags set */
-   EVAS_EVENT_FLAG_ON_HOLD = (1 << 0), /**< This event is being delivered but should be put "on hold" until the on hold flag is unset. the event should be used for informational purposes and maybe some indications visually, but not actually perform anything */
-   EVAS_EVENT_FLAG_ON_SCROLL = (1 << 1) /**< This event flag indicates the event occurs while scrolling; for example, DOWN event occurs during scrolling; the event should be used for informational purposes and maybe some indications visually, but not actually perform anything */
+   EVAS_EVENT_FLAG_ON_HOLD = (1 << 0), /**< The event is being delivered but should be put "on hold" until the on hold flag is unset \n 
+   The event should be used for informational purposes and maybe for some indications visually, but should not actually perform anything. */
+   EVAS_EVENT_FLAG_ON_SCROLL = (1 << 1) /**< The event occurs while scrolling \n 
+   For example, DOWN event occurs during scrolling; the event should be used for informational purposes and maybe for some indications visually, but should not actually perform anything. */
 } Evas_Event_Flags; /**< Flags for Events */
 
 /**
- * State of Evas_Coord_Touch_Point
+ * @brief Enumeration for touch point states.
  */
 typedef enum _Evas_Touch_Point_State
 {
@@ -514,7 +428,7 @@ typedef enum _Evas_Touch_Point_State
 } Evas_Touch_Point_State;
 
 /**
- * Flags for Font Hinting
+ * @brief Enumeration for font hinting.
  * @ingroup Evas_Font_Group
  */
 typedef enum _Evas_Font_Hinting_Flags
@@ -525,13 +439,13 @@ typedef enum _Evas_Font_Hinting_Flags
 } Evas_Font_Hinting_Flags; /**< Flags for Font Hinting */
 
 /**
- * Colorspaces for pixel data supported by Evas
+ * @brief Enumeration for pixel data of colorspaces supported by Evas.
  * @ingroup Evas_Object_Image
  */
 typedef enum _Evas_Colorspace
 {
    EVAS_COLORSPACE_ARGB8888, /**< ARGB 32 bits per pixel, high-byte is Alpha, accessed 1 32bit word at a time */
-   /* these are not currently supported - but planned for the future */
+   /* The following are not currently supported - but planned for the future */
    EVAS_COLORSPACE_YCBCR422P601_PL, /**< YCbCr 4:2:2 Planar, ITU.BT-601 specifications. The data pointed to is just an array of row pointer, pointing to the Y rows, then the Cb, then Cr rows */
    EVAS_COLORSPACE_YCBCR422P709_PL, /**< YCbCr 4:2:2 Planar, ITU.BT-709 specifications. The data pointed to is just an array of row pointer, pointing to the Y rows, then the Cb, then Cr rows */
    EVAS_COLORSPACE_RGB565_A5P, /**< 16bit rgb565 + Alpha plane at end - 5 bits of the 8 being used per alpha byte */
@@ -539,35 +453,41 @@ typedef enum _Evas_Colorspace
    EVAS_COLORSPACE_YCBCR422601_PL, /**<  YCbCr 4:2:2, ITU.BT-601 specifications. The data pointed to is just an array of row pointer, pointing to line of Y,Cb,Y,Cr bytes */
    EVAS_COLORSPACE_YCBCR420NV12601_PL, /**< YCbCr 4:2:0, ITU.BT-601 specification. The data pointed to is just an array of row pointer, pointing to the Y rows, then the Cb,Cr rows. */
    EVAS_COLORSPACE_YCBCR420TM12601_PL, /**< YCbCr 4:2:0, ITU.BT-601 specification. The data pointed to is just an array of tiled row pointer, pointing to the Y rows, then the Cb,Cr rows. */
+   EVAS_COLORSPACE_AGRY88, /**< AY 8bits Alpha and 8bits Grey, accessed 1 16bits at a time */
+   EVAS_COLORSPACE_ETC1, /**< OpenGL ETC1 encoding of RGB texture (4 bit per pixel) @since 1.10 */
+   EVAS_COLORSPACE_RGB8_ETC2, /**< OpenGL GL_COMPRESSED_RGB8_ETC2 texture compression format (4 bit per pixel) @since 1.10 */
+   EVAS_COLORSPACE_RGBA8_ETC2_EAC, /**< OpenGL GL_COMPRESSED_RGBA8_ETC2_EAC texture compression format, supports alpha (8 bit per pixel) @since 1.10 */
+   EVAS_COLORSPACE_ETC1_ALPHA, /**< ETC1 with alpha support using two planes: ETC1 RGB and ETC1 grey for alpha @since 1.11 */
 } Evas_Colorspace; /**< Colorspaces for pixel data supported by Evas */
 
 /**
- * How to pack items into cells in a table.
- * @ingroup Evas_Object_Table
+ * @brief   Enumeration for modes of packing items into cells in a table.
  *
- * @see evas_object_table_homogeneous_set() for an explanation of the function of
- * each one.
+ * @see     evas_object_table_homogeneous_set() for an explanation of the function of
+ *          each one.
+ * @ingroup Evas_Object_Table
  */
 typedef enum _Evas_Object_Table_Homogeneous_Mode
 {
    EVAS_OBJECT_TABLE_HOMOGENEOUS_NONE = 0,
    EVAS_OBJECT_TABLE_HOMOGENEOUS_TABLE = 1,
    EVAS_OBJECT_TABLE_HOMOGENEOUS_ITEM = 2
-} Evas_Object_Table_Homogeneous_Mode; /**< Table cell pack mode. */
+} Evas_Object_Table_Homogeneous_Mode; /**< Table cell pack mode */
 
-typedef struct _Evas_Coord_Rectangle       Evas_Coord_Rectangle; /**< A generic rectangle handle */
-typedef struct _Evas_Point                 Evas_Point;   /**< integer point */
+typedef struct _Evas_Coord_Rectangle       Evas_Coord_Rectangle; /**< @brief A generic rectangle handle */
+typedef struct _Evas_Point                 Evas_Point;   /**< @brief Integer point */
 
-typedef struct _Evas_Coord_Point           Evas_Coord_Point;    /**< Evas_Coord point */
-typedef struct _Evas_Coord_Precision_Point Evas_Coord_Precision_Point;   /**< Evas_Coord point with sub-pixel precision */
+typedef struct _Evas_Coord_Point           Evas_Coord_Point;    /**< @brief Evas_Coord point */
+typedef struct _Evas_Coord_Precision_Point Evas_Coord_Precision_Point;   /**< @brief Evas_Coord point with sub-pixel precision */
 
-typedef struct _Evas_Position              Evas_Position;   /**< associates given point in Canvas and Output */
-typedef struct _Evas_Precision_Position    Evas_Precision_Position;   /**< associates given point in Canvas and Output, with sub-pixel precision */
+typedef struct _Evas_Coord_Size            Evas_Coord_Size;    /**< @brief Evas_Coord size @since 1.8 */
+typedef struct _Evas_Position              Evas_Position;   /**< @brief Associates the given point in Canvas and Output */
+typedef struct _Evas_Precision_Position    Evas_Precision_Position;   /**< @brief Associates the given point in Canvas and Output, with sub-pixel precision */
 
 /**
  * @typedef Evas_Smart_Class
  *
- * A smart object's @b base class definition
+ * @brief   A smart object @b base class definition.
  *
  * @ingroup Evas_Smart_Group
  */
@@ -576,14 +496,14 @@ typedef struct _Evas_Smart_Class Evas_Smart_Class;
 /**
  * @typedef Evas_Smart_Interface
  *
- * A smart object's @b base interface definition
+ * @brief   A smart object @b base interface definition.
  *
- * An Evas interface is exactly like the OO-concept: an 'contract' or
- * API a given object is declared to support. A smart object may have
- * more than one interface, thus extending the behavior it gets from
- * sub-classing.
+ * @since   1.7
  *
- * @since 1.7
+ * @remarks An Evas interface is exactly like the OO-concept: It is a 'contract' or
+ *          API that the object is declared to support. A smart object may have
+ *          more than one interface, thus extending the behavior it gets from
+ *          sub-classing.
  *
  * @ingroup Evas_Smart_Group
  */
@@ -592,7 +512,7 @@ typedef struct _Evas_Smart_Interface         Evas_Smart_Interface;
 /**
  * @typedef Evas_Smart_Cb_Description
  *
- * A smart object callback description, used to provide introspection
+ * @brief   A smart object callback description, used to provide introspection.
  *
  * @ingroup Evas_Smart_Group
  */
@@ -601,7 +521,7 @@ typedef struct _Evas_Smart_Cb_Description Evas_Smart_Cb_Description;
 /**
  * @typedef Evas_Map
  *
- * An opaque handle to map points
+ * @brief  An opaque handle to map points.
  *
  * @see evas_map_new()
  * @see evas_map_free()
@@ -614,7 +534,7 @@ typedef struct _Evas_Map Evas_Map;
 /**
  * @typedef Evas
  *
- * An opaque handle to an Evas canvas.
+ * @brief  An opaque handle to an Evas canvas.
  *
  * @see evas_new()
  * @see evas_free()
@@ -625,39 +545,41 @@ typedef struct _Evas Evas;
 
 /**
  * @typedef Evas_Object
- * An Evas Object handle.
+ * @brief   An Evas Object handle.
  * @ingroup Evas_Object_Group
  */
 typedef struct _Evas_Object         Evas_Object;
 
-typedef void                        Evas_Performance; /**< An Evas Performance handle */
-typedef struct _Evas_Modifier       Evas_Modifier; /**< An opaque type containing information on which modifier keys are registered in an Evas canvas */
-typedef struct _Evas_Lock           Evas_Lock; /**< An opaque type containing information on which lock keys are registered in an Evas canvas */
-typedef struct _Evas_Smart          Evas_Smart; /**< An Evas Smart Object handle */
-typedef struct _Evas_Native_Surface Evas_Native_Surface; /**< A generic datatype for engine specific native surface information */
+typedef void                        Evas_Performance; /**< @brief Evas Performance handle */
+typedef struct _Evas_Modifier       Evas_Modifier; /**< @brief Opaque type containing information on which modifier keys are registered in an Evas canvas */
+typedef struct _Evas_Lock           Evas_Lock; /**< @brief Opaque type containing information on which lock keys are registered in an Evas canvas */
+typedef struct _Evas_Smart          Evas_Smart; /**< @brief Evas Smart Object handle */
+typedef struct _Evas_Native_Surface Evas_Native_Surface; /**< @brief Generic datatype for engine specific native surface information */
 
 /**
  * @typedef Evas_Video_Surface
  *
- * A generic datatype for video specific surface information
+ * @brief  A generic data type for video specific surface information.
+ *
+ * @since  1.1
+ *
  * @see evas_object_image_video_surface_set
  * @see evas_object_image_video_surface_get
- * @since 1.1
  */
 typedef struct _Evas_Video_Surface Evas_Video_Surface;
 
-typedef unsigned long long         Evas_Modifier_Mask;  /**< An Evas modifier mask type */
+typedef unsigned long long         Evas_Modifier_Mask;  /**< @brief An Evas modifier mask type */
 
-typedef int                        Evas_Coord;
-typedef int                        Evas_Font_Size;
-typedef int                        Evas_Angle;
+typedef int                        Evas_Coord;         /**< @brief Evas x y coordinates */
+typedef int                        Evas_Font_Size;     /**< @brief Evas Font Sizes */
+typedef int                        Evas_Angle;         /**< @brief Evas angle */
 
-struct _Evas_Coord_Rectangle /**< A rectangle in Evas_Coord */
+struct _Evas_Coord_Rectangle /**< @brief A rectangle in Evas_Coord */
 {
-   Evas_Coord x; /**< top-left x co-ordinate of rectangle */
-   Evas_Coord y; /**< top-left y co-ordinate of rectangle */
-   Evas_Coord w; /**< width of rectangle */
-   Evas_Coord h; /**< height of rectangle */
+   Evas_Coord x; /**< Top-left x co-ordinate of rectangle */
+   Evas_Coord y; /**< Top-left y co-ordinate of rectangle */
+   Evas_Coord w; /**< Width of rectangle */
+   Evas_Coord h; /**< Height of rectangle */
 };
 
 struct _Evas_Point
@@ -667,7 +589,14 @@ struct _Evas_Point
 
 struct _Evas_Coord_Point
 {
-   Evas_Coord x, y;
+   Evas_Coord x; /**< X co-ordinate */
+   Evas_Coord y; /**< Y co-ordinate */
+};
+
+struct _Evas_Coord_Size
+{
+   Evas_Coord w; /**< Width */
+   Evas_Coord h; /**< Height */
 };
 
 struct _Evas_Coord_Precision_Point
@@ -679,7 +608,7 @@ struct _Evas_Coord_Precision_Point
 struct _Evas_Position
 {
    Evas_Point       output;
-   Evas_Coord_Point canvas;
+   Evas_Coord_Point canvas; /**< Position on the canvas */
 };
 
 struct _Evas_Precision_Position
@@ -688,31 +617,49 @@ struct _Evas_Precision_Position
    Evas_Coord_Precision_Point canvas;
 };
 
+/**
+ * @brief  Enumeration for aspect types or policies for scaling size hints, used for evas_object_size_hint_aspect_set().
+ */
 typedef enum _Evas_Aspect_Control
 {
-   EVAS_ASPECT_CONTROL_NONE = 0, /**< Preference on scaling unset */
+   EVAS_ASPECT_CONTROL_NONE = 0, /**< Unset scaling preference */
    EVAS_ASPECT_CONTROL_NEITHER = 1, /**< Same effect as unset preference on scaling */
    EVAS_ASPECT_CONTROL_HORIZONTAL = 2, /**< Use all horizontal container space to place an object, using the given aspect */
    EVAS_ASPECT_CONTROL_VERTICAL = 3, /**< Use all vertical container space to place an object, using the given aspect */
    EVAS_ASPECT_CONTROL_BOTH = 4 /**< Use all horizontal @b and vertical container spaces to place an object (never growing it out of those bounds), using the given aspect */
-} Evas_Aspect_Control; /**< Aspect types/policies for scaling size hints, used for evas_object_size_hint_aspect_set() */
-
-typedef struct _Evas_Pixel_Import_Source Evas_Pixel_Import_Source; /**< A source description of pixels for importing pixels */
-typedef struct _Evas_Engine_Info         Evas_Engine_Info; /**< A generic Evas Engine information structure */
-typedef struct _Evas_Device              Evas_Device; /**< A source device handle - where the event came from */
-typedef struct _Evas_Event_Mouse_Down    Evas_Event_Mouse_Down; /**< Event structure for #EVAS_CALLBACK_MOUSE_DOWN event callbacks */
-typedef struct _Evas_Event_Mouse_Up      Evas_Event_Mouse_Up; /**< Event structure for #EVAS_CALLBACK_MOUSE_UP event callbacks */
-typedef struct _Evas_Event_Mouse_In      Evas_Event_Mouse_In; /**< Event structure for #EVAS_CALLBACK_MOUSE_IN event callbacks */
-typedef struct _Evas_Event_Mouse_Out     Evas_Event_Mouse_Out; /**< Event structure for #EVAS_CALLBACK_MOUSE_OUT event callbacks */
-typedef struct _Evas_Event_Mouse_Move    Evas_Event_Mouse_Move; /**< Event structure for #EVAS_CALLBACK_MOUSE_MOVE event callbacks */
-typedef struct _Evas_Event_Mouse_Wheel   Evas_Event_Mouse_Wheel; /**< Event structure for #EVAS_CALLBACK_MOUSE_WHEEL event callbacks */
-typedef struct _Evas_Event_Multi_Down    Evas_Event_Multi_Down; /**< Event structure for #EVAS_CALLBACK_MULTI_DOWN event callbacks */
-typedef struct _Evas_Event_Multi_Up      Evas_Event_Multi_Up; /**< Event structure for #EVAS_CALLBACK_MULTI_UP event callbacks */
-typedef struct _Evas_Event_Multi_Move    Evas_Event_Multi_Move; /**< Event structure for #EVAS_CALLBACK_MULTI_MOVE event callbacks */
-typedef struct _Evas_Event_Key_Down      Evas_Event_Key_Down; /**< Event structure for #EVAS_CALLBACK_KEY_DOWN event callbacks */
-typedef struct _Evas_Event_Key_Up        Evas_Event_Key_Up; /**< Event structure for #EVAS_CALLBACK_KEY_UP event callbacks */
-typedef struct _Evas_Event_Hold          Evas_Event_Hold; /**< Event structure for #EVAS_CALLBACK_HOLD event callbacks */
+} Evas_Aspect_Control; /**< Aspect types or policies for scaling size hints, used for evas_object_size_hint_aspect_set() */
 
+/**
+ * @brief  Enumeration for object's display modes.
+ */
+typedef enum _Evas_Display_Mode
+{
+   EVAS_DISPLAY_MODE_NONE = 0, /**<Default display mode */
+   EVAS_DISPLAY_MODE_INHERIT = 1, /**< Object display mode depends on its ancestor display mode */
+   EVAS_DISPLAY_MODE_COMPRESS = 2, /**< Give compress display mode hint to object */
+   EVAS_DISPLAY_MODE_EXPAND = 3, /**< Give expand display mode hint to object */
+   EVAS_DISPLAY_MODE_DONT_CHANGE = 4 /**< Object does not change display mode */
+} Evas_Display_Mode; /**< Object display mode type related with compress and expand or etc mode */
+
+typedef struct _Evas_Pixel_Import_Source Evas_Pixel_Import_Source; /**< @brief A source description of pixels for importing pixels */
+typedef struct _Evas_Engine_Info         Evas_Engine_Info; /**< @brief A generic Evas Engine information structure */
+typedef struct _Evas_Device              Evas_Device; /**< @brief A source device handle - where the event came from */
+typedef struct _Evas_Event_Mouse_Down    Evas_Event_Mouse_Down; /**< @brief Event structure for #EVAS_CALLBACK_MOUSE_DOWN event callbacks */
+typedef struct _Evas_Event_Mouse_Up      Evas_Event_Mouse_Up; /**< @brief Event structure for #EVAS_CALLBACK_MOUSE_UP event callbacks */
+typedef struct _Evas_Event_Mouse_In      Evas_Event_Mouse_In; /**< @brief Event structure for #EVAS_CALLBACK_MOUSE_IN event callbacks */
+typedef struct _Evas_Event_Mouse_Out     Evas_Event_Mouse_Out; /**< @brief Event structure for #EVAS_CALLBACK_MOUSE_OUT event callbacks */
+typedef struct _Evas_Event_Mouse_Move    Evas_Event_Mouse_Move; /**< @brief Event structure for #EVAS_CALLBACK_MOUSE_MOVE event callbacks */
+typedef struct _Evas_Event_Mouse_Wheel   Evas_Event_Mouse_Wheel; /**< @brief Event structure for #EVAS_CALLBACK_MOUSE_WHEEL event callbacks */
+typedef struct _Evas_Event_Multi_Down    Evas_Event_Multi_Down; /**< @brief Event structure for #EVAS_CALLBACK_MULTI_DOWN event callbacks */
+typedef struct _Evas_Event_Multi_Up      Evas_Event_Multi_Up; /**< @brief Event structure for #EVAS_CALLBACK_MULTI_UP event callbacks */
+typedef struct _Evas_Event_Multi_Move    Evas_Event_Multi_Move; /**< @brief Event structure for #EVAS_CALLBACK_MULTI_MOVE event callbacks */
+typedef struct _Evas_Event_Key_Down      Evas_Event_Key_Down; /**< @brief Event structure for #EVAS_CALLBACK_KEY_DOWN event callbacks */
+typedef struct _Evas_Event_Key_Up        Evas_Event_Key_Up; /**< @brief Event structure for #EVAS_CALLBACK_KEY_UP event callbacks */
+typedef struct _Evas_Event_Hold          Evas_Event_Hold; /**< @brief Event structure for #EVAS_CALLBACK_HOLD event callbacks */
+
+/**
+ * @brief  Enumeration for load errors.
+ */
 typedef enum _Evas_Load_Error
 {
    EVAS_LOAD_ERROR_NONE = 0, /**< No error on load */
@@ -720,27 +667,36 @@ typedef enum _Evas_Load_Error
    EVAS_LOAD_ERROR_DOES_NOT_EXIST = 2, /**< File (or file path) does not exist */
    EVAS_LOAD_ERROR_PERMISSION_DENIED = 3, /**< Permission denied to an existing file (or path) */
    EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED = 4, /**< Allocation of resources failure prevented load */
-   EVAS_LOAD_ERROR_CORRUPT_FILE = 5, /**< File corrupt (but was detected as a known format) */
+   EVAS_LOAD_ERROR_CORRUPT_FILE = 5, /**< File corrupt (but is detected as a known format) */
    EVAS_LOAD_ERROR_UNKNOWN_FORMAT = 6 /**< File is not a known format */
-} Evas_Load_Error; /**< Evas image load error codes one can get - see evas_load_error_str() too. */
+} Evas_Load_Error; /**< Evas image load error codes one can get - see evas_load_error_str() */
 
+/**
+ * @brief  Enumeration for allocation errors.
+ */
 typedef enum _Evas_Alloc_Error
 {
    EVAS_ALLOC_ERROR_NONE = 0, /**< No allocation error */
    EVAS_ALLOC_ERROR_FATAL = 1, /**< Allocation failed despite attempts to free up memory */
    EVAS_ALLOC_ERROR_RECOVERED = 2 /**< Allocation succeeded, but extra memory had to be found by freeing up speculative resources */
-} Evas_Alloc_Error; /**< Possible allocation errors returned by evas_alloc_error() */
+} Evas_Alloc_Error; /**< Possible allocation errors returned. */
 
+/**
+ * @brief  Enumeration for spread of image fill.
+ */
 typedef enum _Evas_Fill_Spread
 {
-   EVAS_TEXTURE_REFLECT = 0, /**< image fill tiling mode - tiling reflects */
-   EVAS_TEXTURE_REPEAT = 1, /**< tiling repeats */
-   EVAS_TEXTURE_RESTRICT = 2, /**< tiling clamps - range offset ignored */
-   EVAS_TEXTURE_RESTRICT_REFLECT = 3, /**< tiling clamps and any range offset reflects */
-   EVAS_TEXTURE_RESTRICT_REPEAT = 4, /**< tiling clamps and any range offset repeats */
-   EVAS_TEXTURE_PAD = 5 /**< tiling extends with end values */
+   EVAS_TEXTURE_REFLECT = 0, /**< Image fill tiling mode - tiling reflects */
+   EVAS_TEXTURE_REPEAT = 1, /**< Tiling repeats */
+   EVAS_TEXTURE_RESTRICT = 2, /**< Tiling clamps - range offset ignored */
+   EVAS_TEXTURE_RESTRICT_REFLECT = 3, /**< Tiling clamps and any range offset reflects */
+   EVAS_TEXTURE_RESTRICT_REPEAT = 4, /**< Tiling clamps and any range offset repeats */
+   EVAS_TEXTURE_PAD = 5 /**< Tiling extends with end values */
 } Evas_Fill_Spread; /**< Fill types used for evas_object_image_fill_spread_set() */
 
+/**
+ * @brief  Enumeration for aspect types or policies.
+ */
 typedef enum _Evas_Pixel_Import_Pixel_Format
 {
    EVAS_PIXEL_FORMAT_NONE = 0, /**< No pixel format */
@@ -750,88 +706,168 @@ typedef enum _Evas_Pixel_Import_Pixel_Format
 
 struct _Evas_Pixel_Import_Source
 {
-   Evas_Pixel_Import_Pixel_Format format; /**< pixel format type ie ARGB32, YUV420P_601 etc. */
-   int                            w, h; /**< width and height of source in pixels */
-   void                         **rows; /**< an array of pointers (size depends on format) pointing to left edge of each scanline */
+   Evas_Pixel_Import_Pixel_Format format; /**< Pixel format type i.e. ARGB32, YUV420P_601, and so on */
+   int                            w, h; /**< Width and height of source in pixels */
+   void                         **rows; /**< Array of pointers (size depends on format) pointing to left edge of each scanline */
 };
 
-/* magic version number to know what the native surf struct looks like */
-#define EVAS_NATIVE_SURFACE_VERSION 2
+/* Magic version number to know what the native surf struct looks like */
+#define EVAS_NATIVE_SURFACE_VERSION 3
 
+/**
+ * @brief Native surface types that image object supports
+ *
+ * @see Evas_Native_Surface
+ * @see evas_object_image_native_surface_set()
+ */
 typedef enum _Evas_Native_Surface_Type
 {
-   EVAS_NATIVE_SURFACE_NONE,
-   EVAS_NATIVE_SURFACE_X11,
-   EVAS_NATIVE_SURFACE_OPENGL
+   EVAS_NATIVE_SURFACE_NONE, /**< No surface type */
+   EVAS_NATIVE_SURFACE_X11,  /**< X Window system based type. pixmap id or visual of the pixmap */
+   EVAS_NATIVE_SURFACE_OPENGL, /**< OpenGL system based type. texture or framebuffer id*/
+   EVAS_NATIVE_SURFACE_TIZEN, /**< @internal don't use this type but @see EVAS_NATIVE_SURFACE_TBM */
+   EVAS_NATIVE_SURFACE_TBM,    /**< Tizen system based type. This is used for tizen buffer manager. */
+   EVAS_NATIVE_SURFACE_EVASGL, /**< Evas GL based type. evas gl surface */
 } Evas_Native_Surface_Type;
 
+/**
+ * @brief A generic datatype for engine specific native surface information.
+ *
+ * Please fill up Evas_Native_Surface fields that regarded with current surface
+ * type. If you want to set the native surface type to
+ * EVAS_NATIVE_SURFACE_X11, you need to set union data with x11.visual or
+ * x11.pixmap. If you need to set the native surface as
+ * EVAS_NATIVE_SURFACE_OPENGL, on the other hand, you need to set union data
+ * with opengl.texture_id or opengl.framebuffer_id and so on. The version field
+ * should be set with EVAS_NATIVE_SURFACE_VERSION in order to check abi
+ * break in your application on the different efl library versions.
+ *
+ * @warning Native surface types totally depend on the system. Please
+ *          be aware that the types are supported on your system before using
+ *          them.
+ * @see evas_object_image_native_surface_set()
+ */
 struct _Evas_Native_Surface
 {
-   int                      version;
-   Evas_Native_Surface_Type type;
+   int                      version; /**< Current Native Surface Version. Use EVAS_NATIVE_SURFACE_VERSION */
+   Evas_Native_Surface_Type type; /**< Surface type. @see Evas_Native_Surface_Type */
    union {
       struct
       {
-         void         *visual; /**< visual of the pixmap to use (Visual) */
-         unsigned long pixmap; /**< pixmap id to use (Pixmap) */
-      } x11;
+         void         *visual; /**< Visual of the pixmap to use (Visual) */
+         unsigned long pixmap; /**< Pixmap ID to use (Pixmap) */
+      } x11; /**< Set this struct fields if your surface data is X11 based. */
+      struct
+      {
+         unsigned int texture_id; /**< opengl texture ID to use from glGenTextures() */
+         unsigned int framebuffer_id; /**< 0 if this is not an FBO, otherwise FBO ID from glGenFramebuffers() */
+         unsigned int internal_format; /**< Same as 'internalFormat' for glTexImage2D() */
+         unsigned int format; /**< Same as 'format' for glTexImage2D() */
+         unsigned int x, y, w, h; /**< Region inside the texture to use (Image size is assumed as texture size, with 0, 0 being the top-left and co-ordinates working down to the right and bottom being positive) */
+      } opengl; /**< Set this struct fields if your surface data is OpenGL based. */
       struct
       {
-         unsigned int texture_id; /**< opengl texture id to use from glGenTextures() */
-         unsigned int framebuffer_id; /**< 0 if not a FBO, FBO id otherwise from glGenFramebuffers() */
-         unsigned int internal_format; /**< same as 'internalFormat' for glTexImage2D() */
-         unsigned int format; /**< same as 'format' for glTexImage2D() */
-         unsigned int x, y, w, h; /**< region inside the texture to use (image size is assumed as texture size, with 0, 0 being the top-left and co-ordinates working down to the right and bottom being positive) */
-      } opengl;
-   } data;
+         void *buffer; /**< tbm surface */
+         int   rot; /**< rotation (0, 90, 180, 270) */
+         float ratio; /**< width/height ratio of the source image */
+         int   flip; /**< flip (0:none, 1:horizontal, 2:vertical, 3:both) */
+      } tizen; /**< Set this struct fields if your surface data is Tizen based. */
+      struct
+      {
+         void *surface; /**< evas gl surface to use */
+      } evasgl; /**< Set this struct fields if surface data is Evas GL based. */
+   } data; /**< Choose one union data according to your surface. */
 };
 
 /**
  * @def EVAS_VIDEO_SURFACE_VERSION
- * Magic version number to know what the video surf struct looks like
- * @since 1.1
+ * @brief  Definition of the magic version number to know what the video surf struct looks like.
+ * @since  1.1
  */
 #define EVAS_VIDEO_SURFACE_VERSION 1
 
 typedef void (*Evas_Video_Cb)(void *data, Evas_Object *obj, const Evas_Video_Surface *surface);
 typedef void (*Evas_Video_Coord_Cb)(void *data, Evas_Object *obj, const Evas_Video_Surface *surface, Evas_Coord a, Evas_Coord b);
 
+/**
+ * @brief Struct of Evas Video Surface.
+ */
 struct _Evas_Video_Surface
 {
    int                 version;
 
-   Evas_Video_Coord_Cb move; /**< Move the video surface to this position */
-   Evas_Video_Coord_Cb resize; /**< Resize the video surface to that size */
-   Evas_Video_Cb       show; /**< Show the video overlay surface */
-   Evas_Video_Cb       hide; /**< Hide the video overlay surface */
-   Evas_Video_Cb       update_pixels; /**< Please update the Evas_Object_Image pixels when called */
+   Evas_Video_Coord_Cb move; /**< Moves the video surface to this position */
+   Evas_Video_Coord_Cb resize; /**< Resizes the video surface to that size */
+   Evas_Video_Cb       show; /**< Shows the video overlay surface */
+   Evas_Video_Cb       hide; /**< Hides the video overlay surface */
+   Evas_Video_Cb       update_pixels; /**< Updates the Evas_Object_Image pixels when called */
 
    Evas_Object        *parent;
    void               *data;
 };
 
-#define EVAS_LAYER_MIN                   -32768 /**< bottom-most layer number */
-#define EVAS_LAYER_MAX                   32767 /**< top-most layer number */
+#define EVAS_LAYER_MIN                   -32768 /**< @brief Bottom-most layer number */
+#define EVAS_LAYER_MAX                   32767 /**< @brief Top-most layer number */
+
+#define EVAS_COLOR_SPACE_ARGB            0 /**< @brief Not used for anything */
+#define EVAS_COLOR_SPACE_AHSV            1 /**< @brief Not used for anything */
+#define EVAS_TEXT_INVALID                -1 /**< @brief Not used for anything */
+#define EVAS_TEXT_SPECIAL                -2 /**< @brief Not used for anything */
+
+#define EVAS_HINT_EXPAND                 1.0 /**< @brief Use with evas_object_size_hint_weight_set(), evas_object_size_hint_weight_get(), evas_object_size_hint_expand_set(), evas_object_size_hint_expand_get() */
+#define EVAS_HINT_FILL                   -1.0 /**< @brief Use with evas_object_size_hint_align_set(), evas_object_size_hint_align_get(), evas_object_size_hint_fill_set(), evas_object_size_hint_fill_get() */
+
+/**
+ * @brief Convenience macro to make it easier to understand that align is also used for fill properties (as fill is mutually exclusive to align)
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @ingroup Evas_Object_Group_Size_Hints
+ */
+#define evas_object_size_hint_fill_set   evas_object_size_hint_align_set
+
+/**
+ * @brief Convenience macro to make it easier to understand that align is also used for fill properties (as fill is mutually exclusive to align)
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @ingroup Evas_Object_Group_Size_Hints
+ */
+#define evas_object_size_hint_fill_get   evas_object_size_hint_align_get
 
-#define EVAS_COLOR_SPACE_ARGB            0 /**< Not used for anything */
-#define EVAS_COLOR_SPACE_AHSV            1 /**< Not used for anything */
-#define EVAS_TEXT_INVALID                -1 /**< Not used for anything */
-#define EVAS_TEXT_SPECIAL                -2 /**< Not used for anything */
+/**
+ * @brief Convenience macro to make it easier to understand that weight is also used for expand properties
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @ingroup Evas_Object_Group_Size_Hints
+ */
+#define evas_object_size_hint_expand_set evas_object_size_hint_weight_set
 
-#define EVAS_HINT_EXPAND                 1.0 /**< Use with evas_object_size_hint_weight_set(), evas_object_size_hint_weight_get(), evas_object_size_hint_expand_set(), evas_object_size_hint_expand_get() */
-#define EVAS_HINT_FILL                   -1.0 /**< Use with evas_object_size_hint_align_set(), evas_object_size_hint_align_get(), evas_object_size_hint_fill_set(), evas_object_size_hint_fill_get() */
-#define evas_object_size_hint_fill_set   evas_object_size_hint_align_set /**< Convenience macro to make it easier to understand that align is also used for fill properties (as fill is mutually exclusive to align) */
-#define evas_object_size_hint_fill_get   evas_object_size_hint_align_get /**< Convenience macro to make it easier to understand that align is also used for fill properties (as fill is mutually exclusive to align) */
-#define evas_object_size_hint_expand_set evas_object_size_hint_weight_set /**< Convenience macro to make it easier to understand that weight is also used for expand properties */
-#define evas_object_size_hint_expand_get evas_object_size_hint_weight_get /**< Convenience macro to make it easier to understand that weight is also used for expand properties */
+/**
+ * @brief Convenience macro to make it easier to understand that weight is also used for expand properties
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @ingroup Evas_Object_Group_Size_Hints
+ */
+#define evas_object_size_hint_expand_get evas_object_size_hint_weight_get
 
 /**
- * How the object should be rendered to output.
+ * @brief   Enumeration for modes of object rendering to output.
  * @ingroup Evas_Object_Group_Extras
  */
 typedef enum _Evas_Render_Op
 {
-   EVAS_RENDER_BLEND = 0, /**< default op: d = d*(1-sa) + s */
+   EVAS_RENDER_BLEND = 0, /**< Default op: d = d*(1-sa) + s */
    EVAS_RENDER_BLEND_REL = 1, /**< d = d*(1 - sa) + s*da */
    EVAS_RENDER_COPY = 2, /**< d = s */
    EVAS_RENDER_COPY_REL = 3, /**< d = s*da */
@@ -843,8 +879,11 @@ typedef enum _Evas_Render_Op
    EVAS_RENDER_TINT_REL = 9, /**< d = d*(1 - sa + s) */
    EVAS_RENDER_MASK = 10, /**< d = d*sa */
    EVAS_RENDER_MUL = 11 /**< d = d*s */
-} Evas_Render_Op; /**< How the object should be rendered to output. */
+} Evas_Render_Op; /**< How the object should be rendered to output */
 
+/**
+ * @brief  Enumeration for border fill mode.
+ */
 typedef enum _Evas_Border_Fill_Mode
 {
    EVAS_BORDER_FILL_NONE = 0, /**< Image's center region is @b not to be rendered */
@@ -852,6 +891,9 @@ typedef enum _Evas_Border_Fill_Mode
    EVAS_BORDER_FILL_SOLID = 2 /**< Image's center region is to be made solid, even if it has transparency on it */
 } Evas_Border_Fill_Mode; /**< How an image's center region (the complement to the border region) should be rendered by Evas */
 
+/**
+ * @brief  Enumeration for image scale hints.
+ */
 typedef enum _Evas_Image_Scale_Hint
 {
    EVAS_IMAGE_SCALE_HINT_NONE = 0, /**< No scale hint at all */
@@ -859,6 +901,9 @@ typedef enum _Evas_Image_Scale_Hint
    EVAS_IMAGE_SCALE_HINT_STATIC = 2 /**< Image is not being re-scaled over time, thus turning scaling cache @b on for its data */
 } Evas_Image_Scale_Hint; /**< How an image's data is to be treated by Evas, with regard to scaling cache */
 
+/**
+ * @brief  Enumeration for animated loop hints.
+ */
 typedef enum _Evas_Image_Animated_Loop_Hint
 {
    EVAS_IMAGE_ANIMATED_HINT_NONE = 0,
@@ -866,25 +911,46 @@ typedef enum _Evas_Image_Animated_Loop_Hint
    EVAS_IMAGE_ANIMATED_HINT_PINGPONG = 2 /**< Image's animation mode is pingpong like 1->2->3->2->1-> ... */
 } Evas_Image_Animated_Loop_Hint;
 
+/**
+ * @brief  Enumeration for engine rendering modes.
+ */
 typedef enum _Evas_Engine_Render_Mode
 {
    EVAS_RENDER_MODE_BLOCKING = 0,
    EVAS_RENDER_MODE_NONBLOCKING = 1,
 } Evas_Engine_Render_Mode;
 
+/**
+ * @brief  Enumeration for image content hints.
+ */
 typedef enum _Evas_Image_Content_Hint
 {
    EVAS_IMAGE_CONTENT_HINT_NONE = 0, /**< No hint at all */
-   EVAS_IMAGE_CONTENT_HINT_DYNAMIC = 1, /**< The contents will change over time */
-   EVAS_IMAGE_CONTENT_HINT_STATIC = 2 /**< The contents won't change over time */
+   EVAS_IMAGE_CONTENT_HINT_DYNAMIC = 1, /**< The contents change over time */
+   EVAS_IMAGE_CONTENT_HINT_STATIC = 2 /**< The contents do not change over time */
 } Evas_Image_Content_Hint; /**< How an image's data is to be treated by Evas, for optimization */
 
-struct _Evas_Engine_Info /** Generic engine information. Generic info is useless */
+/**
+ * @brief  Enumeration for device class.
+ */
+typedef enum _Evas_Device_Class
+{
+   EVAS_DEVICE_CLASS_NONE, /**< Not a device @since 1.8 */
+   EVAS_DEVICE_CLASS_SEAT, /**< The user/seat (the user themselves) @since 1.8 */
+   EVAS_DEVICE_CLASS_KEYBOARD, /**< Regular keyboard, numberpad or attached buttons @since 1.8 */
+   EVAS_DEVICE_CLASS_MOUSE, /**< Mouse, trackball or touchpad relative motion device @since 1.8 */
+   EVAS_DEVICE_CLASS_TOUCH, /**< Touchscreen with fingers or stylus @since 1.8 */
+   EVAS_DEVICE_CLASS_PEN, /**< Special pen device @since 1.8 */
+   EVAS_DEVICE_CLASS_POINTER, /**< Laser pointer, wii-style or "minority report" pointing device @since 1.8 */
+   EVAS_DEVICE_CLASS_GAMEPAD /**<  Gamepad controller or joystick @since 1.8 */
+} Evas_Device_Class;
+   
+struct _Evas_Engine_Info /** @brief Generic engine information. Generic info is not of much use. */
 {
    int magic; /**< Magic number */
 };
 
-struct _Evas_Event_Mouse_Down /** Mouse button press event */
+struct _Evas_Event_Mouse_Down /** @brief Mouse button press event */
 {
    int               button; /**< Mouse button number that went down (1 - 32) */
 
@@ -892,93 +958,94 @@ struct _Evas_Event_Mouse_Down /** Mouse button press event */
    Evas_Coord_Point  canvas; /**< The X/Y location of the cursor */
 
    void             *data;
-   Evas_Modifier    *modifiers; /**< modifier keys pressed during the event */
+   Evas_Modifier    *modifiers; /**< Modifier keys pressed during the event */
    Evas_Lock        *locks;
 
-   Evas_Button_Flags flags; /**< button flags set during the event */
+   Evas_Button_Flags flags; /**< Button flags set during the event */
    unsigned int      timestamp;
    Evas_Event_Flags  event_flags;
    Evas_Device      *dev;
 };
 
-struct _Evas_Event_Mouse_Up /** Mouse button release event */
+struct _Evas_Event_Mouse_Up /** @brief Mouse button release event */
 {
-   int               button; /**< Mouse button number that was raised (1 - 32) */
+   int               button; /**< Mouse button number that is raised (1 - 32) */
 
-   Evas_Point        output;
-   Evas_Coord_Point  canvas;
+   Evas_Point        output; /**< The X/Y location of the cursor */
+   Evas_Coord_Point  canvas; /**< The X/Y location of the cursor */
 
    void             *data;
-   Evas_Modifier    *modifiers;
+   Evas_Modifier    *modifiers; /**< Modifier keys pressed during the event */
    Evas_Lock        *locks;
 
-   Evas_Button_Flags flags;
+   Evas_Button_Flags flags; /**< Button flags set during the event */
    unsigned int      timestamp;
    Evas_Event_Flags  event_flags;
    Evas_Device      *dev;
 };
 
-struct _Evas_Event_Mouse_In /** Mouse enter event */
+struct _Evas_Event_Mouse_In /** @brief Mouse enter event */
 {
-   int              buttons; /**< Button pressed mask, Bits set to 1 are buttons currently pressed (bit 0 = mouse button 1, bit 1 = mouse button 2 etc.) */
+   int              buttons; /**< Button pressed mask, Bits set to @c 1 are buttons currently pressed (bit 0 = mouse button 1, bit 1 = mouse button 2 and so on) */
 
-   Evas_Point       output;
-   Evas_Coord_Point canvas;
+   Evas_Point        output; /**< The X/Y location of the cursor */
+   Evas_Coord_Point  canvas; /**< The X/Y location of the cursor */
 
    void            *data;
-   Evas_Modifier   *modifiers;
+   Evas_Modifier    *modifiers; /**< Modifier keys pressed during the event */
    Evas_Lock       *locks;
    unsigned int     timestamp;
    Evas_Event_Flags event_flags;
    Evas_Device     *dev;
 };
 
-struct _Evas_Event_Mouse_Out /** Mouse leave event */
+struct _Evas_Event_Mouse_Out /** @brief Mouse leave event */
 {
-   int              buttons; /**< Button pressed mask, Bits set to 1 are buttons currently pressed (bit 0 = mouse button 1, bit 1 = mouse button 2 etc.) */
+   int              buttons; /**< Button pressed mask, Bits set to @c 1 are buttons currently pressed (bit 0 = mouse button 1, bit 1 = mouse button 2 and so on) */
 
-   Evas_Point       output;
-   Evas_Coord_Point canvas;
+   Evas_Point        output; /**< The X/Y location of the cursor */
+   Evas_Coord_Point  canvas; /**< The X/Y location of the cursor */
 
    void            *data;
-   Evas_Modifier   *modifiers;
+   Evas_Modifier    *modifiers; /**< Modifier keys pressed during the event */
    Evas_Lock       *locks;
    unsigned int     timestamp;
    Evas_Event_Flags event_flags;
    Evas_Device     *dev;
 };
 
-struct _Evas_Event_Mouse_Move /** Mouse button down event */
+struct _Evas_Event_Mouse_Move /** @brief Mouse move event */
 {
-   int              buttons; /**< Button pressed mask, Bits set to 1 are buttons currently pressed (bit 0 = mouse button 1, bit 1 = mouse button 2 etc.) */
+   int              buttons; /**< Button pressed mask, Bits set to @c 1 are buttons currently pressed (bit 0 = mouse button 1, bit 1 = mouse button 2 and so on) */
 
-   Evas_Position    cur, prev;
+   Evas_Position    cur; /**< Current mouse position */
+   Evas_Position    prev; /**< Previous mouse position */
 
    void            *data;
-   Evas_Modifier   *modifiers;
+   Evas_Modifier    *modifiers; /**< Modifier keys pressed during the event */
    Evas_Lock       *locks;
    unsigned int     timestamp;
    Evas_Event_Flags event_flags;
    Evas_Device     *dev;
 };
 
-struct _Evas_Event_Mouse_Wheel /** Wheel event */
+struct _Evas_Event_Mouse_Wheel /** @brief Wheel event */
 {
    int              direction; /* 0 = default up/down wheel FIXME: more wheel types */
    int              z; /* ...,-2,-1 = down, 1,2,... = up */
 
-   Evas_Point       output;
-   Evas_Coord_Point canvas;
+   Evas_Point        output; /**< The X/Y location of the cursor */
+   Evas_Coord_Point  canvas; /**< The X/Y location of the cursor */
 
    void            *data;
-   Evas_Modifier   *modifiers;
+   Evas_Modifier    *modifiers; /**< Modifier keys pressed during the event */
    Evas_Lock       *locks;
    unsigned int     timestamp;
    Evas_Event_Flags event_flags;
    Evas_Device     *dev;
 };
 
-struct _Evas_Event_Multi_Down /** Multi button press event */
+struct _Evas_Event_Multi_Down /** @brief Multi button press event */
 {
    int                        device; /**< Multi device number that went down (1 or more for extra touches) */
    double                     radius, radius_x, radius_y;
@@ -988,16 +1055,16 @@ struct _Evas_Event_Multi_Down /** Multi button press event */
    Evas_Coord_Precision_Point canvas;
 
    void                      *data;
-   Evas_Modifier             *modifiers;
+   Evas_Modifier    *modifiers; /**< Modifier keys pressed during the event */
    Evas_Lock                 *locks;
 
-   Evas_Button_Flags          flags;
+   Evas_Button_Flags flags; /**< Button flags set during the event */
    unsigned int               timestamp;
    Evas_Event_Flags           event_flags;
    Evas_Device               *dev;
 };
 
-struct _Evas_Event_Multi_Up /** Multi button release event */
+struct _Evas_Event_Multi_Up /** @brief Multi button release event */
 {
    int                        device; /**< Multi device number that went up (1 or more for extra touches) */
    double                     radius, radius_x, radius_y;
@@ -1007,16 +1074,16 @@ struct _Evas_Event_Multi_Up /** Multi button release event */
    Evas_Coord_Precision_Point canvas;
 
    void                      *data;
-   Evas_Modifier             *modifiers;
+   Evas_Modifier    *modifiers; /**< Modifier keys pressed during the event */
    Evas_Lock                 *locks;
 
-   Evas_Button_Flags          flags;
+   Evas_Button_Flags flags; /**< Button flags set during the event */
    unsigned int               timestamp;
    Evas_Event_Flags           event_flags;
    Evas_Device               *dev;
 };
 
-struct _Evas_Event_Multi_Move /** Multi button down event */
+struct _Evas_Event_Multi_Move /** @brief Multi button down event */
 {
    int                     device; /**< Multi device number that moved (1 or more for extra touches) */
    double                  radius, radius_x, radius_y;
@@ -1025,46 +1092,46 @@ struct _Evas_Event_Multi_Move /** Multi button down event */
    Evas_Precision_Position cur;
 
    void                   *data;
-   Evas_Modifier          *modifiers;
+   Evas_Modifier    *modifiers; /**< Modifier keys pressed during the event */
    Evas_Lock              *locks;
    unsigned int            timestamp;
    Evas_Event_Flags        event_flags;
    Evas_Device            *dev;
 };
 
-struct _Evas_Event_Key_Down /** Key press event */
+struct _Evas_Event_Key_Down /** @brief Key press event */
 {
-   char            *keyname; /**< the name string of the key pressed */
+   char            *keyname; /**< Name string of the key pressed */
    void            *data;
-   Evas_Modifier   *modifiers;
+   Evas_Modifier    *modifiers; /**< Modifier keys pressed during the event */
    Evas_Lock       *locks;
 
-   const char      *key; /**< The logical key : (eg shift+1 == exclamation) */
-   const char      *string; /**< UTF8 string if this keystroke has produced a visible string to be ADDED */
-   const char      *compose; /**< UTF8 string if this keystroke has modified a string in the middle of being composed - this string replaces the previous one */
+   const char      *key; /**< Logical key : (example, shift+1 == exclamation) */
+   const char      *string; /**< UTF8 string if this keystroke has produced a visible string to be ADDED */
+   const char      *compose; /**< UTF8 string if this keystroke has modified a string in the middle of being composed - this string replaces the previous one */
    unsigned int     timestamp;
    Evas_Event_Flags event_flags;
    Evas_Device     *dev;
 };
 
-struct _Evas_Event_Key_Up /** Key release event */
+struct _Evas_Event_Key_Up /** @brief Key release event */
 {
-   char            *keyname; /**< the name string of the key released */
+   char            *keyname; /**< Name string of the key released */
    void            *data;
-   Evas_Modifier   *modifiers;
+   Evas_Modifier    *modifiers; /**< Modifier keys pressed during the event */
    Evas_Lock       *locks;
 
-   const char      *key; /**< The logical key : (eg shift+1 == exclamation) */
-   const char      *string; /**< UTF8 string if this keystroke has produced a visible string to be ADDED */
-   const char      *compose; /**< UTF8 string if this keystroke has modified a string in the middle of being composed - this string replaces the previous one */
+   const char      *key; /**< Logical key : (example, shift+1 == exclamation) */
+   const char      *string; /**< UTF8 string if this keystroke has produced a visible string to be ADDED */
+   const char      *compose; /**< UTF8 string if this keystroke has modified a string in the middle of being composed - this string replaces the previous one */
    unsigned int     timestamp;
    Evas_Event_Flags event_flags;
    Evas_Device     *dev;
 };
 
-struct _Evas_Event_Hold /** Hold change event */
+struct _Evas_Event_Hold /** @brief Hold change event */
 {
-   int              hold; /**< The hold flag */
+   int              hold; /**< Hold flag */
    void            *data;
 
    unsigned int     timestamp;
@@ -1073,133 +1140,160 @@ struct _Evas_Event_Hold /** Hold change event */
 };
 
 /**
- * How the mouse pointer should be handled by Evas.
+ * @brief   Enumeration for handling mouse pointer.
  *
- * In the mode #EVAS_OBJECT_POINTER_MODE_AUTOGRAB, when a mouse button
- * is pressed down over an object and held, with the mouse pointer
- * being moved outside of it, the pointer still behaves as being bound
- * to that object, albeit out of its drawing region. When the button
- * is released, the event will be fed to the object, that may check if
- * the final position is over it or not and do something about it.
+ * @remarks In the mode #EVAS_OBJECT_POINTER_MODE_AUTOGRAB, when a mouse button
+ *          is pressed down over an object and held, with the mouse pointer
+ *          being moved outside of it, the pointer still behaves as being bound
+ *          to that object, albeit out of its drawing region. When the button
+ *          is released, the event is fed to the object, that may check if
+ *          the final position is over it or not and do something about it.
  *
- * In the mode #EVAS_OBJECT_POINTER_MODE_NOGRAB, the pointer will
- * always be bound to the object right below it.
+ * @remarks In the mode #EVAS_OBJECT_POINTER_MODE_NOGRAB, the pointer is
+ *          always bound to the object right below it.
  *
  * @ingroup Evas_Object_Group_Extras
  */
 typedef enum _Evas_Object_Pointer_Mode
 {
-   EVAS_OBJECT_POINTER_MODE_AUTOGRAB, /**< default, X11-like */
-   EVAS_OBJECT_POINTER_MODE_NOGRAB, /**< pointer always bound to the object right below it */
-   EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN /**< useful on object with "repeat events" enabled, where mouse/touch up and down events WONT be repeated to objects and these objects wont be auto-grabbed. @since 1.2 */
-} Evas_Object_Pointer_Mode; /**< How the mouse pointer should be handled by Evas. */
+   EVAS_OBJECT_POINTER_MODE_AUTOGRAB, /**< Default, X11-like */
+   EVAS_OBJECT_POINTER_MODE_NOGRAB, /**< Pointer always bound to the object right below it */
+   EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN /**< Useful on object with "repeat events" enabled, where mouse and touch up and down events ARE NOT repeated to objects and these objects are not auto-grabbed @since 1.2 */
+} Evas_Object_Pointer_Mode; /**< How the mouse pointer should be handled by Evas */
+
+/**
+ * @brief Evas smart objects' "smart callback" function signature
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ * @ingroup Evas_Smart_Object_Group
+ */
+typedef void      (*Evas_Smart_Cb)(void *data, Evas_Object *obj, void *event_info);
+
+/**
+ * @brief Evas event callback function signature
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ * @ingroup Evas_Canvas_Events
+ */
+typedef void      (*Evas_Event_Cb)(void *data, Evas *e, void *event_info);
 
-typedef void      (*Evas_Smart_Cb)(void *data, Evas_Object *obj, void *event_info);  /**< Evas smart objects' "smart callback" function signature */
-typedef void      (*Evas_Event_Cb)(void *data, Evas *e, void *event_info);  /**< Evas event callback function signature */
+/**
+ * @brief Evas event callback Post function signature
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ * @ingroup Evas_Canvas_Events
+ */
 typedef Eina_Bool (*Evas_Object_Event_Post_Cb)(void *data, Evas *e);
-typedef void      (*Evas_Object_Event_Cb)(void *data, Evas *e, Evas_Object *obj, void *event_info);  /**< Evas object event callback function signature */
+
+/**
+ * @brief Evas object event callback function signature
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ * @ingroup Evas_Object_Group_Events
+ */
+typedef void      (*Evas_Object_Event_Cb)(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+/**
+ * @brief Evas Async events put function signature
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ * @ingroup Evas_Top_Group
+ */
 typedef void      (*Evas_Async_Events_Put_Cb)(void *target, Evas_Callback_Type type, void *event_info);
 
 /**
- * @defgroup Evas_Group Top Level Functions
- *
- * Functions that affect Evas as a whole.
+ * @}
  */
 
 /**
- * Initialize Evas
+ * @internal
+ * @defgroup Evas_Top_Group Top Level Functions
+   @ingroup Evas
  *
- * @return The init counter value.
- *
- * This function initializes Evas and increments a counter of the
- * number of calls to it. It returns the new counter's value.
+ * @brief  This group provides functions that affect Evas as a whole.
+ * @{
+ */
+
+/**
+ * @brief    Initializes Evas.
  *
- * @see evas_shutdown().
+ * @details  This function initializes Evas and increments a counter of the
+ *           number of calls to it. It returns the new counter value. 
  *
- * Most EFL users wouldn't be using this function directly, because
- * they wouldn't access Evas directly by themselves. Instead, they
- * would be using higher level helpers, like @c ecore_evas_init().
- * See http://docs.enlightenment.org/auto/ecore/.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * You should be using this if your use is something like the
- * following. The buffer engine is just one of the many ones Evas
- * provides.
+ * @remarks  Most EFL users do not use this function directly, because
+ *           they do not access Evas directly by themselves. Instead, they
+ *           use higher level helpers, like @c ecore_evas_init().
+ *           See http://docs.enlightenment.org/auto/ecore/
  *
- * @dontinclude evas-buffer-simple.c
- * @skip int main
- * @until return -1;
- * And being the canvas creation something like:
- * @skip static Evas *create_canvas
- * @until    evas_output_viewport_set(canvas,
+ * @return  The init counter value
  *
- * Note that this is code creating an Evas canvas with no usage of
- * Ecore helpers at all -- no linkage with Ecore on this scenario,
- * thus. Again, this wouldn't be on Evas common usage for most
- * developers. See the full @ref Example_Evas_Buffer_Simple "example".
+ * @see     evas_shutdown()
  *
- * @ingroup Evas_Group
+ * @ingroup Evas_Top_Group
  */
 EAPI int               evas_init(void);
 
 /**
- * Shutdown Evas
- *
- * @return Evas' init counter value.
+ * @brief   Shuts down Evas.
  *
- * This function finalizes Evas, decrementing the counter of the
- * number of calls to the function evas_init(). This new value for the
- * counter is returned.
+ * @details This function finalizes Evas, decrementing the counter of the
+ *          number of calls to the function evas_init(). This new value for the
+ *          counter is returned.
  *
- * @see evas_init().
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * If you were the sole user of Evas, by means of evas_init(), you can
- * check if it's being properly shut down by expecting a return value
- * of 0.
+ * @remarks If you are the sole user of Evas, you can use evas_init() to
+ *          check if it is being properly shut down by expecting a return value
+ *          of @c 0.
  *
- * Example code follows.
- * @dontinclude evas-buffer-simple.c
- * @skip // NOTE: use ecore_evas_buffer_new
- * @until evas_shutdown
- * Where that function would contain:
- * @skip   evas_free(canvas)
- * @until   evas_free(canvas)
+ * @return  The Evas init counter value
  *
- * Most users would be using ecore_evas_shutdown() instead, like told
- * in evas_init(). See the full @ref Example_Evas_Buffer_Simple
- * "example".
+ * @see evas_init()
  *
- * @ingroup Evas_Group
+ * @ingroup Evas_Top_Group
  */
 EAPI int               evas_shutdown(void);
 
 /**
- * Return if any allocation errors have occurred during the prior function
- * @return The allocation error flag
+ * @brief   Gets the allocation errors that have occurred during the execution of the prior function.
  *
- * This function will return if any memory allocation errors occurred during,
- * and what kind they were. The return value will be one of
- * EVAS_ALLOC_ERROR_NONE, EVAS_ALLOC_ERROR_FATAL or EVAS_ALLOC_ERROR_RECOVERED
- * with each meaning something different.
+ * @details This function returns any memory allocation errors that occurred during the execution
+ *          and the kind of errors. Valid return values are @c EVAS_ALLOC_ERROR_NONE,
+ *          @c EVAS_ALLOC_ERROR_FATAL, and @c EVAS_ALLOC_ERROR_RECOVERED.
  *
- * EVAS_ALLOC_ERROR_NONE means that no errors occurred at all and the function
- * worked as expected.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * EVAS_ALLOC_ERROR_FATAL means the function was completely unable to perform
- * its job and will  have  exited as cleanly as possible. The programmer
- * should consider this as a sign of very low memory and should try and safely
- * recover from the prior functions failure (or try free up memory elsewhere
- * and try again after more memory is freed).
+ * @remarks @c EVAS_ALLOC_ERROR_NONE means that no errors occurred at all and the function
+ *          worked as expected.
  *
- * EVAS_ALLOC_ERROR_RECOVERED means that an allocation error occurred, but was
- * recovered from by evas finding memory of its own it has allocated and
- * freeing what it sees as not really usefully allocated memory. What is freed
- * may vary. Evas may reduce the resolution of images, free cached images or
- * fonts, trhow out pre-rendered data, reduce the complexity of change lists
- * etc. Evas and the program will function as per normal after this, but this
- * is a sign of low memory, and it is suggested that the program try and
- * identify memory it doesn't need, and free it.
+ * @remarks @c EVAS_ALLOC_ERROR_FATAL means the function is completely unable to perform
+ *          its job and exited as cleanly as possible. You should consider this as a
+ *          sign of very low memory and should try and safely recover from the prior function 
+ *          failure. You can also try to free up memory elsewhere and try again after memory is freed.
  *
- * Example:
+ * @remarks @c EVAS_ALLOC_ERROR_RECOVERED means that an allocation error occurred, but Evas
+ *          recovered from it by finding memory of its own that it has allocated and
+ *          freeing what it sees as not really usefully allocated memory. What is freed
+ *          may vary. Evas may reduce the resolution of images, free cached images or
+ *          fonts, throw out pre-rendered data, reduce the complexity of change lists,
+ *          and so on. Evas and the program functions as per normal after this, but this
+ *          is a sign of low memory, and it is suggested that your program try and
+ *          identify memory it does not need, and free it.
+ *
+ * @remarks The following is an example:
  * @code
  * extern Evas_Object *object;
  * void callback (void *data, Evas *e, Evas_Object *obj, void *event_info);
@@ -1221,286 +1315,337 @@ EAPI int               evas_shutdown(void);
  *   }
  * @endcode
  *
- * @ingroup Evas_Group
+ * @return  The allocation error flag
+ *
+ * @ingroup Evas_Top_Group
  */
 EAPI Evas_Alloc_Error  evas_alloc_error(void);
 
 /**
- * @brief Get evas' internal asynchronous events read file descriptor.
+ * @brief   Gets the Evas internal asynchronous events read file descriptor.
+ *
+ * @details This function returns the read file descriptor of the
+ *          asynchronous events of the canvas. Other mainloops,
+ *          apart from ecore, may make use of it.
  *
- * @return The canvas' asynchronous events read file descriptor.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Evas' asynchronous events are meant to be dealt with internally,
- * i. e., when building stuff to be glued together into the EFL
- * infrastructure -- a module, for example. The context which demands
- * its use is when calculations need to be done out of the main
- * thread, asynchronously, and some action must be performed after
- * that.
+ * @remarks The Evas asynchronous events are meant to be dealt with internally,
+ *          i.e., when building stuff to be glued together into the EFL
+ *          infrastructure - a module, for example. The context which demands
+ *          its use is when calculations need to be done out of the main
+ *          thread, asynchronously, and some action must be performed after
+ *          that.
  *
- * An example of actual use of this API is for image asynchronous
- * preload inside evas. If the canvas was instantiated through
- * ecore-evas usage, ecore itself will take care of calling those
- * events' processing.
+ * @remarks An example of the actual use of this API is for image asynchronous
+ *          preload inside Evas. If the canvas is instantiated through
+ *          ecore-evas usage, ecore itself takes care of calling those
+ *          event processing.
  *
- * This function returns the read file descriptor where to get the
- * asynchronous events of the canvas. Naturally, other mainloops,
- * apart from ecore, may make use of it.
+ * @return  The asynchronous events read file descriptor of the canvas
  *
- * @ingroup Evas_Group
+ * @ingroup Evas_Top_Group
  */
 EAPI int               evas_async_events_fd_get(void) EINA_WARN_UNUSED_RESULT;
 
 /**
- * @brief Trigger the processing of all events waiting on the file
- * descriptor returned by evas_async_events_fd_get().
+ * @brief   Triggers the processing of all events waiting on the file
+ *          descriptor returned by evas_async_events_fd_get().
  *
- * @return The number of events processed.
+ * @details All asynchronous events queued up by evas_async_events_put() are
+ *          processed here. More precisely, the callback functions, informed
+ *          together with other event parameters, when queued, get called (with
+ *          those parameters), in that order.
  *
- * All asynchronous events queued up by evas_async_events_put() are
- * processed here. More precisely, the callback functions, informed
- * together with other event parameters, when queued, get called (with
- * those parameters), in that order.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @ingroup Evas_Group
+ * @return  The number of events processed
+ *
+ * @ingroup Evas_Top_Group
  */
 EAPI int               evas_async_events_process(void);
 
 /**
- * Insert asynchronous events on the canvas.
+ * @brief   Inserts asynchronous events on the canvas.
+ *
+ * @details This is the way, for a routine running outside evas' main thread,
+ *          to report an asynchronous event. A callback function is informed,
+ *          whose call is to happen after evas_async_events_process() is
+ *          called. 
  *
- * @param target The target to be affected by the events.
- * @param type The type of callback function.
- * @param event_info Information about the event.
- * @param func The callback function pointer.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This is the way, for a routine running outside evas' main thread,
- * to report an asynchronous event. A callback function is informed,
- * whose call is to happen after evas_async_events_process() is
- * called.
+ * @param[in]   target      The target to be affected by the events
+ * @param[in]   type        The type of callback function
+ * @param[in]   event_info  The information about the event
+ * @param[in]   func        The callback function pointer
+ * @return  #EINA_TRUE if the events are inserted successfully, \n
+ *          otherwise #EINA_FALSE on failure
  *
- * @ingroup Evas_Group
+ * @ingroup Evas_Top_Group
  */
 EAPI Eina_Bool         evas_async_events_put(const void *target, Evas_Callback_Type type, void *event_info, Evas_Async_Events_Put_Cb func) EINA_ARG_NONNULL(1, 4);
 
 /**
+ * @}
+ */
+
+/**
  * @defgroup Evas_Canvas Canvas Functions
+ * @ingroup Evas
  *
- * Low level Evas canvas functions. Sub groups will present more high
- * level ones, though.
+ * @brief    This group provides low level Evas canvas functions. Sub-groups 
+ *           present more high level ones, though.
  *
- * Most of these functions deal with low level Evas actions, like:
- * @li create/destroy raw canvases, not bound to any displaying engine
- * @li tell a canvas i got focused (in a windowing context, for example)
- * @li tell a canvas a region should not be calculated anymore in rendering
- * @li tell a canvas to render its contents, immediately
+ * @remarks  Most of these functions deal with low level Evas actions, like:
+ *           @li creating or destroying raw canvases, not bound to any displaying engine
+ *           @li telling a canvas that it got focused (in a windowing context, for example)
+ *           @li telling a canvas that a region should not be calculated anymore in rendering
+ *           @li telling a canvas to render its contents, immediately
  *
- * Most users will be using Evas by means of the @c Ecore_Evas
- * wrapper, which deals with all the above mentioned issues
- * automatically for them. Thus, you'll be looking at this section
- * only if you're building low level stuff.
+ * @remarks  You mostly use Evas with the @c Ecore_Evas wrapper, which
+ *           deals with all the above mentioned issues automatically. Thus, you 
+ *           need this section only if you are building low level stuff.
  *
- * The groups within present you functions that deal with the canvas
- * directly, too, and not yet with its @b objects. They are the
- * functions you need to use at a minimum to get a working canvas.
+ * @remarks  The groups present you functions that deal with the canvas
+ *           directly, too, and not yet with its @b objects. They are the
+ *           functions you need to use at a minimum to get a working canvas.
  *
- * Some of the functions in this group are exemplified @ref
- * Example_Evas_Events "here".
+ * @{
  */
 
 /**
- * Creates a new empty evas.
+ * @brief    Creates a new empty evas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Note that before you can use the evas, you will to at a minimum:
- * @li Set its render method with @ref evas_output_method_set .
- * @li Set its viewport size with @ref evas_output_viewport_set .
- * @li Set its size of the canvas with @ref evas_output_size_set .
- * @li Ensure that the render engine is given the correct settings
- *     with @ref evas_engine_info_set .
+ * @remarks  This function should only fail if the memory allocation fails.
  *
- * This function should only fail if the memory allocation fails
+ * @remarks  This function is a very low level function.
  *
- * @note this function is very low level. Instead of using it
- *       directly, consider using the high level functions in
- *       Ecore_Evas such as @c ecore_evas_new(). See
- *       http://docs.enlightenment.org/auto/ecore/.
+ * @return   A new uninitialised Evas canvas on success, \n 
+ *           otherwise @c NULL on failure
  *
- * @attention it is recommended that one calls evas_init() before
- *       creating new canvas.
+ * @pre      Note that before you can use evas, you have to:
+ *           @li Set its render method with @ref evas_output_method_set.
+ *           @li Set its viewport size with @ref evas_output_viewport_set.
+ *           @li Set its size of the canvas with @ref evas_output_size_set.
+ *           @li Ensure that the render engine is given the correct settings
+ *               with @ref evas_engine_info_set.
  *
- * @return A new uninitialised Evas canvas on success. Otherwise, @c NULL.
  * @ingroup Evas_Canvas
  */
 EAPI Evas             *evas_new(void) EINA_WARN_UNUSED_RESULT EINA_MALLOC;
 
 /**
- * Frees the given evas and any objects created on it.
+ * @brief    Frees the given evas and any objects created on it.
  *
- * Any objects with 'free' callbacks will have those callbacks called
- * in this function.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param   e The given evas.
+ * @remarks  Any objects with 'free' callbacks have those callbacks called
+ *           in this function.
  *
- * @ingroup Evas_Canvas
+ * @param[in]    e  The given evas
+ *
+ * @ingroup  Evas_Canvas
  */
 EAPI void              evas_free(Evas *e)  EINA_ARG_NONNULL(1);
 
 /**
- * Inform to the evas that it got the focus.
+ * @brief    Informs evas that it has got focus.
  *
- * @param e The evas to change information.
- * @ingroup Evas_Canvas
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]    e  The evas to inform
+ * @ingroup  Evas_Canvas
  */
 EAPI void              evas_focus_in(Evas *e);
 
 /**
- * Inform to the evas that it lost the focus.
+ * @brief   Informs the evas that it has lost focus.
  *
- * @param e The evas to change information.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e  The evas to inform
  * @ingroup Evas_Canvas
  */
 EAPI void              evas_focus_out(Evas *e);
 
 /**
- * Get the focus state known by the given evas
+ * @brief   Gets the focus state of the given evas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The evas to query information.
+ * @param[in]   e  The evas to query information
+ * @return  #EINA_TRUE if it is focused, otherwise #EINA_FALSE.
  * @ingroup Evas_Canvas
  */
 EAPI Eina_Bool         evas_focus_state_get(const Evas *e);
 
 /**
- * Push the nochange flag up 1
+ * @brief    Pushes the nochange flag up @c 1.
  *
- * This tells evas, that while the nochange flag is greater than 0, do not
- * mark objects as "changed" when making changes.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The evas to change information.
- * @ingroup Evas_Canvas
+ * @remarks  This tells evas that while the nochange flag is greater than 0, do not
+ *           mark objects as "changed" when making changes.
+ *
+ * @param[in]    e  The evas to changes information
+ * @ingroup  Evas_Canvas
  */
 EAPI void              evas_nochange_push(Evas *e);
 
 /**
- * Pop the nochange flag down 1
+ * @brief   Pops the nochange flag down @c 1.
  *
- * This tells evas, that while the nochange flag is greater than 0, do not
- * mark objects as "changed" when making changes.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The evas to change information.
+ * @remarks This tells evas that while the nochange flag is greater than 0, do not
+ *          mark objects as "changed" when making changes.
+ *
+ * @param[in]   e  The evas to change information
  * @ingroup Evas_Canvas
  */
 EAPI void              evas_nochange_pop(Evas *e);
 
 /**
- * Attaches a specific pointer to the evas for fetching later
+ * @brief   Attaches a specific pointer to evas for fetching later.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The canvas to attach the pointer to
- * @param data The pointer to attach
+ * @param[in]   e       The canvas to attach the pointer to
+ * @param[in]   data    The pointer to attach
  * @ingroup Evas_Canvas
  */
 EAPI void              evas_data_attach_set(Evas *e, void *data) EINA_ARG_NONNULL(1);
 
 /**
- * Returns the pointer attached by evas_data_attach_set()
+ * @brief   Gets the pointer attached by evas_data_attach_set().
  *
- * @param e The canvas to attach the pointer to
- * @return The pointer attached
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e  The canvas to attach the pointer to
+ * @return  The pointer attached
  * @ingroup Evas_Canvas
  */
 EAPI void             *evas_data_attach_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Add a damage rectangle.
+ * @brief   Adds a damage rectangle.
+ *
+ * @details You can use this function to inform evas that a part of the
+ *          canvas has to be repainted.
  *
- * @param e The given canvas pointer.
- * @param x The rectangle's left position.
- * @param y The rectangle's top position.
- * @param w The rectangle's width.
- * @param h The rectangle's height.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This is the function by which one tells evas that a part of the
- * canvas has to be repainted.
+ * @remarks All newly created Evas rectangles get the default color values 
+ *          of 255 255 255 255 (opaque white). 
  *
- * @note All newly created Evas rectangles get the default color values of 255 255 255 255 (opaque white).
+ * @param[in]   e  The given canvas pointer
+ * @param[in]   x  The rectangle's left position
+ * @param[in]   y  The rectangle's top position
+ * @param[in]   w  The rectangle's width
+ * @param[in]   h  The rectangle's height
  *
  * @ingroup Evas_Canvas
  */
 EAPI void              evas_damage_rectangle_add(Evas *e, int x, int y, int w, int h) EINA_ARG_NONNULL(1);
 
 /**
- * Add an "obscured region" to an Evas canvas.
+ * @brief   Adds an "obscured region" to an Evas canvas.
  *
- * @param e The given canvas pointer.
- * @param x The rectangle's top left corner's horizontal coordinate.
- * @param y The rectangle's top left corner's vertical coordinate
- * @param w The rectangle's width.
- * @param h The rectangle's height.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This is the function by which one tells an Evas canvas that a part
- * of it <b>must not</b> be repainted. The region must be
- * rectangular and its coordinates inside the canvas viewport are
- * passed in the call. After this call, the region specified won't
- * participate in any form in Evas' calculations and actions during
- * its rendering updates, having its displaying content frozen as it
- * was just after this function took place.
+ * @remarks You can use this function to inform an Evas canvas that a part
+ *          of it <b>must not</b> be repainted. The region must be
+ *          rectangular and its coordinates inside the canvas viewport are
+ *          passed in the call. After this call, the region specified do not
+ *          participate in any form in Evas' calculations and actions during
+ *          its rendering updates, having its displaying content frozen as it
+ *          is just after this function is executed.
  *
- * We call it "obscured region" because the most common use case for
- * this rendering (partial) freeze is something else (most probably
- * other canvas) being on top of the specified rectangular region,
- * thus shading it completely from the user's final scene in a
- * display. To avoid unnecessary processing, one should indicate to the
- * obscured canvas not to bother about the non-important area.
+ * @remarks This is called "obscured region" because the most common use case for
+ *          this rendering (partial) freeze is something else (most probably
+ *          other canvas) being on top of the specified rectangular region,
+ *          thus shading it completely from the user's final scene in a
+ *          display. To avoid unnecessary processing, one should indicate to the
+ *          obscured canvas not to bother about the non-important area.
  *
- * The majority of users won't have to worry about this function, as
- * they'll be using just one canvas in their applications, with
- * nothing inset or on top of it in any form.
+ * @remarks The majority of users do not have to worry about this function, as
+ *          they use just one canvas in their applications, with
+ *          nothing inset or on top of it in any form.
  *
- * To make this region one that @b has to be repainted again, call the
- * function evas_obscured_clear().
+ * @remarks To make this region one that @b has to be repainted again, call the
+ *          function evas_obscured_clear().
  *
- * @note This is a <b>very low level function</b>, which most of
- * Evas' users wouldn't care about.
+ * @remarks This is a <b>very low level function</b>, which you may not use.
  *
- * @note This function does @b not flag the canvas as having its state
- * changed. If you want to re-render it afterwards expecting new
- * contents, you have to add "damage" regions yourself (see
- * evas_damage_rectangle_add()).
+ * @remarks This function does @b not flag the canvas as having its state
+ *          changed. If you want to re-render it afterwards expecting new
+ *          contents, you have to add "damage" regions yourself (see
+ *          evas_damage_rectangle_add()).
+ *
+ * @param[in]   e  The given canvas pointer
+ * @param[in]   x  The rectangle's top left corner's horizontal coordinate
+ * @param[in]   y  The rectangle's top left corner's vertical coordinate
+ * @param[in]   w  The rectangle's width
+ * @param[in]   h  The rectangle's height
  *
  * @see evas_obscured_clear()
  * @see evas_render_updates()
  *
- * Example code follows.
- * @dontinclude evas-events.c
- * @skip add an obscured
- * @until evas_obscured_clear(evas);
- *
- * In that example, pressing the "Ctrl" and "o" keys will impose or
- * remove an obscured region in the middle of the canvas. You'll get
- * the same contents at the time the key was pressed, if toggling it
- * on, until you toggle it off again (make sure the animation is
- * running on to get the idea better). See the full @ref
- * Example_Evas_Events "example".
- *
  * @ingroup Evas_Canvas
  */
 EAPI void              evas_obscured_rectangle_add(Evas *e, int x, int y, int w, int h) EINA_ARG_NONNULL(1);
 
 /**
- * Remove all "obscured regions" from an Evas canvas.
+ * @brief   Removes all "obscured regions" from an Evas canvas.
+ *
+ * @details This function removes all the rectangles from the obscured regions
+ *          list of the canvas @a e. It takes obscured areas added with
+ *          evas_obscured_rectangle_add() and make them again a regions that @b
+ *          have to be repainted on rendering updates.
  *
- * @param e The given canvas pointer.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function removes all the rectangles from the obscured regions
- * list of the canvas @p e. It takes obscured areas added with
- * evas_obscured_rectangle_add() and make them again a regions that @b
- * have to be repainted on rendering updates.
+ * @remarks This is a <b>very low level function</b>, which you may not use.
  *
- * @note This is a <b>very low level function</b>, which most of
- * Evas' users wouldn't care about.
+ * @remarks This function does @b not flag the canvas as having its state
+ *          changed. If you want to re-render it afterwards expecting new
+ *          contents, you have to add "damage" regions yourself (see
+ *          evas_damage_rectangle_add()).
  *
- * @note This function does @b not flag the canvas as having its state
- * changed. If you want to re-render it afterwards expecting new
- * contents, you have to add "damage" regions yourself (see
- * evas_damage_rectangle_add()).
+ * @param[in]   e  The given canvas pointer
  *
  * @see evas_obscured_rectangle_add() for an example
  * @see evas_render_updates()
@@ -1510,43 +1655,43 @@ EAPI void              evas_obscured_rectangle_add(Evas *e, int x, int y, int w,
 EAPI void              evas_obscured_clear(Evas *e) EINA_ARG_NONNULL(1);
 
 /**
- * Force immediate renderization of the given Evas canvas.
- *
- * @param e The given canvas pointer.
- * @return A newly allocated list of updated rectangles of the canvas
- *        (@c Eina_Rectangle structs). Free this list with
- *        evas_render_updates_free().
- *
- * This function forces an immediate renderization update of the given
- * canvas @p e.
+ * @brief   Forces immediate renderization of the given Evas canvas.
  *
- * @note This is a <b>very low level function</b>, which most of
- * Evas' users wouldn't care about. One would use it, for example, to
- * grab an Evas' canvas update regions and paint them back, using the
- * canvas' pixmap, on a displaying system working below Evas.
+ * @details This function forces an immediate renderization update of the given
+ *          canvas @a e.
  *
- * @note Evas is a stateful canvas. If no operations changing its
- * state took place since the last rendering action, you won't see no
- * changes and this call will be a no-op.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Example code follows.
- * @dontinclude evas-events.c
- * @skip add an obscured
- * @until d.obscured = !d.obscured;
+ * @remarks This is a <b>very low level function</b>, which you may not use. 
+ *          You would use it, for example, to grab an Evas' canvas update regions 
+ *          and paint them back, using the canvas' pixmap, on a displaying system 
+ *          working below Evas.
  *
- * See the full @ref Example_Evas_Events "example".
+ * @remarks Evas is a stateful canvas. If no operations changing its
+ *          state took place since the last rendering action, you do not see any
+ *          changes and this call becomes a no-op.
  *
+ * @param[in]   e  The given canvas pointer
+ * @return  A newly allocated list of updated rectangles of the canvas (@c Eina_Rectangle structs) \n 
+ *          Free this list with evas_render_updates_free().
+ * 
  * @ingroup Evas_Canvas
  */
 EAPI Eina_List        *evas_render_updates(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Free the rectangles returned by evas_render_updates().
+ * @brief   Frees the rectangles returned by evas_render_updates().
+ *
+ * @details This function removes the region from the render updates list.
+ *          The region does not get render updated anymore.
  *
- * @param updates The list of updated rectangles of the canvas.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function removes the region from the render updates list. It
- * makes the region doesn't be render updated anymore.
+ * @param[in]  updates The list of updated rectangles of the canvas
  *
  * @see evas_render_updates() for an example
  *
@@ -1555,152 +1700,133 @@ EAPI Eina_List        *evas_render_updates(Evas *e) EINA_WARN_UNUSED_RESULT EINA
 EAPI void              evas_render_updates_free(Eina_List *updates);
 
 /**
- * Force renderization of the given canvas.
+ * @brief   Forces rendering of the given canvas.
  *
- * @param e The given canvas pointer.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e  The given canvas pointer
  *
  * @ingroup Evas_Canvas
  */
 EAPI void              evas_render(Evas *e) EINA_ARG_NONNULL(1);
 
 /**
- * Update the canvas internal objects but not triggering immediate
- * renderization.
+ * @brief   Updates the canvas internal objects but does not trigger immediate rendering.
+ *
+ * @details This function updates the canvas internal objects not triggering
+ *          rendering. To force rendering, use evas_render().
  *
- * @param e The given canvas pointer.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function updates the canvas internal objects not triggering
- * renderization. To force renderization function evas_render() should
- * be used.
+ * @param[in]   e  The given canvas pointer
  *
- * @see evas_render.
+ * @see evas_render
  *
  * @ingroup Evas_Canvas
  */
 EAPI void              evas_norender(Evas *e) EINA_ARG_NONNULL(1);
 
 /**
- * Make the canvas discard internally cached data used for rendering.
+ * @brief   Makes the canvas discard internally cached data used for rendering.
  *
- * @param e The given canvas pointer.
+ * @details This function flushes the arrays of delete, active and render objects.
+ *          The other things it may discard include shared memory segments,
+ *          temporary scratch buffers, and cached data to avoid re-compute of that data.
  *
- * This function flushes the arrays of delete, active and render objects.
- * Other things it may also discard are: shared memory segments,
- * temporary scratch buffers, cached data to avoid re-compute of that data etc.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e  The given canvas pointer
  *
  * @ingroup Evas_Canvas
  */
 EAPI void              evas_render_idle_flush(Evas *e) EINA_ARG_NONNULL(1);
 
 /**
- * Make the canvas discard as much data as possible used by the engine at
- * runtime.
+ * @brief   Makes the canvas discard as much data as possible used by the engine at runtime.
+ *
+ * @details This function unloads images, deletes textures and much more, where
+ *          possible. You may also want to call evas_render_idle_flush() immediately
+ *          prior to this to perhaps discard a little more, though evas_render_dump()
+ *          should implicitly delete most of what evas_render_idle_flush() might
+ *          discard too.
  *
- * @param e The given canvas pointer.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function will unload images, delete textures and much more, where
- * possible. You may also want to call evas_render_idle_flush() immediately
- * prior to this to perhaps discard a little more, though evas_render_dump()
- * should implicitly delete most of what evas_render_idle_flush() might
- * discard too.
+ * @param[in]   e  The given canvas pointer
  *
  * @ingroup Evas_Canvas
  */
 EAPI void              evas_render_dump(Evas *e) EINA_ARG_NONNULL(1);
 
 /**
+ * @}
+ */
+
+/**
  * @defgroup Evas_Output_Method Render Engine Functions
+ * @ingroup Evas_Canvas
  *
- * Functions that are used to set the render engine for a given
- * function, and then get that engine working.
+ * @brief   This goup provides functions that are used to set the render engine for a given
+ *          function, and then get that engine working.
  *
- * The following code snippet shows how they can be used to
- * initialise an evas that uses the X11 software engine:
- * @code
- * Evas *evas;
- * Evas_Engine_Info_Software_X11 *einfo;
- * extern Display *display;
- * extern Window win;
- *
- * evas_init();
- *
- * evas = evas_new();
- * evas_output_method_set(evas, evas_render_method_lookup("software_x11"));
- * evas_output_size_set(evas, 640, 480);
- * evas_output_viewport_set(evas, 0, 0, 640, 480);
- * einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(evas);
- * einfo->info.display = display;
- * einfo->info.visual = DefaultVisual(display, DefaultScreen(display));
- * einfo->info.colormap = DefaultColormap(display, DefaultScreen(display));
- * einfo->info.drawable = win;
- * einfo->info.depth = DefaultDepth(display, DefaultScreen(display));
- * evas_engine_info_set(evas, (Evas_Engine_Info *)einfo);
- * @endcode
+ * @remarks The following code snippet shows how they can be used to
+ *          initialise an evas that uses the X11 software engine:
  *
- * @ingroup Evas_Canvas
+ * @{
  */
 
 /**
- * Look up a numeric ID from a string name of a rendering engine.
- *
- * @param name the name string of an engine
- * @return A numeric (opaque) ID for the rendering engine
- * @ingroup Evas_Output_Method
+ * @brief   Looks up a numeric ID from a string name of a rendering engine.
  *
- * This function looks up a numeric return value for the named engine
- * in the string @p name. This is a normal C string, NUL byte
- * terminated. The name is case sensitive. If the rendering engine is
- * available, a numeric ID for that engine is returned that is not
- * 0. If the engine is not available, 0 is returned, indicating an
- * invalid engine.
+ * @details This function looks up a numeric return value for the named engine
+ *          in the string @a name. This is a normal C string, NULL byte
+ *          terminated. The name is case sensitive. If the rendering engine is
+ *          available, a numeric ID for that engine is returned that is not
+ *          @c 0. If the engine is not available, @c 0 is returned, indicating an
+ *          invalid engine.
  *
- * The programmer should NEVER rely on the numeric ID of an engine
- * unless it is returned by this function. Programs should NOT be
- * written accessing render method ID's directly, without first
- * obtaining it from this function.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @attention it is mandatory that one calls evas_init() before
- *       looking up the render method.
+ * @remarks You should NEVER rely on the numeric ID of an engine unless it is returned 
+ *          by this function. You should NOT write programs written accessing render 
+ *          method ID's directly, without first obtaining it from this function.
  *
- * Example:
- * @code
- * int engine_id;
- * Evas *evas;
+ * @remarks The following is an example.
  *
- * evas_init();
+ * @param[in]   name  The name string of an engine
+ * @return  A numeric (opaque) ID for the rendering engine
  *
- * evas = evas_new();
- * if (!evas)
- *   {
- *     fprintf(stderr, "ERROR: Canvas creation failed. Fatal error.\n");
- *     exit(-1);
- *   }
- * engine_id = evas_render_method_lookup("software_x11");
- * if (!engine_id)
- *   {
- *     fprintf(stderr, "ERROR: Requested rendering engine is absent.\n");
- *     exit(-1);
- *   }
- * evas_output_method_set(evas, engine_id);
- * @endcode
+ * @ingroup Evas_Output_Method
  */
 EAPI int               evas_render_method_lookup(const char *name) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * List all the rendering engines compiled into the copy of the Evas library
+ * @brief   Lists all the rendering engines compiled into the copy of the Evas library.
  *
- * @return A linked list whose data members are C strings of engine names
- * @ingroup Evas_Output_Method
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Calling this will return a handle (pointer) to an Evas linked
- * list. Each node in the linked list will have the data pointer be a
- * (char *) pointer to the name string of the rendering engine
- * available. The strings should never be modified, neither should the
- * list be modified. This list should be cleaned up as soon as the
- * program no longer needs it using evas_render_method_list_free(). If
- * no engines are available from Evas, @c NULL will be returned.
  *
- * Example:
+ * @remarks Calling this returns a handle (pointer) to an Evas linked
+ *          list. Each node in the linked list has the data pointer be a
+ *          (char *) pointer to the name string of the rendering engine
+ *          available. The strings should never be modified, neither should the
+ *          list be modified. This list should be cleaned up as soon as the
+ *          program no longer needs it using evas_render_method_list_free(). If
+ *          no engines are available from Evas, @c NULL is returned.
+ *
+ * @remarks The following is an example:
  * @code
  * Eina_List *engine_list, *l;
  * char *engine_name;
@@ -1716,19 +1842,23 @@ EAPI int               evas_render_method_lookup(const char *name) EINA_WARN_UNU
  *     printf("%s\n", engine_name);
  * evas_render_method_list_free(engine_list);
  * @endcode
+ *
+ * @return  A linked list whose data members are C strings of engine names
+ *
+ * @ingroup Evas_Output_Method
  */
 EAPI Eina_List        *evas_render_method_list(void) EINA_WARN_UNUSED_RESULT;
 
 /**
- * This function should be called to free a list of engine names
+ * @brief   Frees the list of engine names.
  *
- * @param list The Eina_List base pointer for the engine list to be freed
- * @ingroup Evas_Output_Method
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * When this function is called it will free the engine list passed in
- * as @p list. The list should only be a list of engines generated by
- * calling evas_render_method_list(). If @p list is NULL, nothing will
- * happen.
+ * @remarks When this function is called it frees the engine list passed in
+ *          as @a list. The list should only be a list of engines generated by
+ *          calling evas_render_method_list(). If @a list is NULL, nothing happens.
  *
  * Example:
  * @code
@@ -1746,215 +1876,268 @@ EAPI Eina_List        *evas_render_method_list(void) EINA_WARN_UNUSED_RESULT;
  *     printf("%s\n", engine_name);
  * evas_render_method_list_free(engine_list);
  * @endcode
+ *
+ * @param[in]   list  The Eina_List base pointer for the engine list to be freed
+ * @ingroup Evas_Output_Method
  */
 EAPI void              evas_render_method_list_free(Eina_List *list);
 
 /**
- * Sets the output engine for the given evas.
+ * @brief   Sets the output engine for the given evas.
  *
- * Once the output engine for an evas is set, any attempt to change it
- * will be ignored.  The value for @p render_method can be found using
- * @ref evas_render_method_lookup .
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param   e             The given evas.
- * @param   render_method The numeric engine value to use.
+ * @remarks Once the output engine for an evas is set, any attempt to change it
+ *          is ignored. The value for @a render_method can be found using
+ *          @ref evas_render_method_lookup.
  *
- * @attention it is mandatory that one calls evas_init() before
- *       setting the output method.
+ * @param[in]   e               The given evas
+ * @param[in]   render_method   The numeric engine value to use
  *
  * @ingroup Evas_Output_Method
  */
 EAPI void              evas_output_method_set(Evas *e, int render_method) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the number of the output engine used for the given evas.
- * @param   e The given evas.
- * @return  The ID number of the output engine being used.  @c 0 is
- *          returned if there is an error.
+ * @brief   Gets the number of the output engines used for the given evas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e  The given evas
+ * @return  The ID number of the output engine being used \n 
+ *          @c 0 is returned if there is an error.
+ *
  * @ingroup Evas_Output_Method
  */
 EAPI int               evas_output_method_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the current render engine info struct from the given evas.
+ * @brief   Gets the current render engine info struct from the given evas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * The returned structure is publicly modifiable.  The contents are
- * valid until either @ref evas_engine_info_set or @ref evas_render
- * are called.
+ * @remarks The returned structure is publicly modifiable. The contents are
+ *          valid until either @ref evas_engine_info_set or @ref evas_render
+ *          are called.
  *
- * This structure does not need to be freed by the caller.
+ * @remarks You do not have to free this structure.
+ *
+ * @param[in]   e  The given evas
+ * @return  A pointer to the Engine Info structure \n
+ *          @c NULL is returned if an engine has not yet been assigned.
  *
- * @param   e The given evas.
- * @return  A pointer to the Engine Info structure.  @c NULL is returned if
- *          an engine has not yet been assigned.
  * @ingroup Evas_Output_Method
  */
 EAPI Evas_Engine_Info *evas_engine_info_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Applies the engine settings for the given evas from the given @c
- * Evas_Engine_Info structure.
+ * @brief   Applies the engine settings for the given evas from the given @c
+ *          Evas_Engine_Info structure.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * To get the Evas_Engine_Info structure to use, call @ref
- * evas_engine_info_get .  Do not try to obtain a pointer to an
- * @c Evas_Engine_Info structure in any other way.
+ * @remarks To get the Evas_Engine_Info structure to use, call @ref
+ *          evas_engine_info_get. Do not try to obtain a pointer to an
+ *          @c Evas_Engine_Info structure in any other way.
  *
- * You will need to call this function at least once before you can
- * create objects on an evas or render that evas.  Some engines allow
- * their settings to be changed more than once.
+ * @remarks You need to call this function at least once before you can
+ *          create objects on an evas or render that evas. Some engines allow
+ *          their settings to be changed more than once.
  *
- * Once called, the @p info pointer should be considered invalid.
+ * @remarks Once called, the @a info pointer should be considered invalid.
  *
- * @param   e    The pointer to the Evas Canvas
- * @param   info The pointer to the Engine Info to use
- * @return  @c EINA_TRUE if no error occurred, @c EINA_FALSE otherwise.
+ * @param[in]   e       The pointer to the Evas canvas
+ * @param[in]   info    The pointer to the Engine Info to use
+ * @return  #EINA_TRUE if the engine setting is applied successfully, \n
+ *          otherwise #EINA_FALSE if an error occurred
  * @ingroup Evas_Output_Method
  */
 EAPI Eina_Bool         evas_engine_info_set(Evas *e, Evas_Engine_Info *info) EINA_ARG_NONNULL(1);
 
 /**
+ * @}
+ */
+
+/**
  * @defgroup Evas_Output_Size Output and Viewport Resizing Functions
+ * @ingroup  Evas_Canvas
  *
- * Functions that set and retrieve the output and viewport size of an
- * evas.
+ * @brief    This group provides functions that set and retrieve the output and viewport size of an evas.
  *
- * @ingroup Evas_Canvas
+ * @{
  */
 
 /**
- * Sets the output size of the render engine of the given evas.
+ * @brief   Sets the output size of the render engine of the given evas.
  *
- * The evas will render to a rectangle of the given size once this
- * function is called.  The output size is independent of the viewport
- * size.  The viewport will be stretched to fill the given rectangle.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * The units used for @p w and @p h depend on the engine used by the
- * evas.
+ * @remarks The evas renders to a rectangle of the given size once this
+ *          function is called. The output size is independent of the viewport
+ *          size. The viewport is stretched to fill the given rectangle.
+ *
+ * @remarks The units used for @a w and @a h depend on the engine used by the evas.
+ *
+ * @param[in]   e  The given evas
+ * @param[in]   w  The width in output units, usually pixels
+ * @param[in]   h  The height in output units, usually pixels
  *
- * @param   e The given evas.
- * @param   w The width in output units, usually pixels.
- * @param   h The height in output units, usually pixels.
  * @ingroup Evas_Output_Size
  */
 EAPI void              evas_output_size_set(Evas *e, int w, int h) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve the output size of the render engine of the given evas.
+ * @brief   Gets the output size of the render engine of the given evas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks The output size is in the output units for the engine.
  *
- * The output size is given in whatever the output units are for the
- * engine.
+ * @remarks If either @a w or @a h is @c NULL, then it is ignored. If @a e is
+ *          invalid, the returned results are undefined.
  *
- * If either @p w or @p h is @c NULL, then it is ignored.  If @p e is
- * invalid, the returned results are undefined.
+ * @param[in]   e  The given evas
+ * @param[out]   w  The pointer to an integer to store the width in
+ * @param[out]   h  The pointer to an integer to store the height in
  *
- * @param   e The given evas.
- * @param   w The pointer to an integer to store the width in.
- * @param   h The pointer to an integer to store the height in.
  * @ingroup Evas_Output_Size
  */
 EAPI void              evas_output_size_get(const Evas *e, int *w, int *h) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the output viewport of the given evas in evas units.
+ * @brief   Sets the output viewport of the given evas in evas units.
  *
- * The output viewport is the area of the evas that will be visible to
- * the viewer.  The viewport will be stretched to fit the output
- * target of the evas when rendering is performed.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note The coordinate values do not have to map 1-to-1 with the output
- *       target.  However, it is generally advised that it is done for ease
- *       of use.
+ * @remarks The output viewport is the area of the evas that is visible to     the viewer.  
+ *          The viewport is stretched to fit the output target of the evas when 
+ *          rendering is performed.
  *
- * @param   e The given evas.
- * @param   x The top-left corner x value of the viewport.
- * @param   y The top-left corner y value of the viewport.
- * @param   w The width of the viewport.  Must be greater than 0.
- * @param   h The height of the viewport.  Must be greater than 0.
+ * @remarks The coordinate values do not have to map 1-to-1 with the output
+ *          target. However, it is generally advised that it is done for ease of use.
+ *
+ * @param[in]   e  The given evas
+ * @param[in]   x  The top-left corner x value of the viewport
+ * @param[in]   y  The top-left corner y value of the viewport
+ * @param[in]   w  The width of the viewport \n 
+ *             Must be greater than @c 0.
+ * @param[in]   h  The height of the viewport \n 
+ *             Must be greater than @c 0.
  * @ingroup Evas_Output_Size
  */
 EAPI void              evas_output_viewport_set(Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
 
 /**
- * Get the render engine's output viewport co-ordinates in canvas units.
- * @param e The pointer to the Evas Canvas
- * @param x The pointer to a x variable to be filled in
- * @param y The pointer to a y variable to be filled in
- * @param w The pointer to a width variable to be filled in
- * @param h The pointer to a height variable to be filled in
- * @ingroup Evas_Output_Size
+ * @brief   Gets the render engine's output viewport co-ordinates in canvas units.
  *
- * Calling this function writes the current canvas output viewport
- * size and location values into the variables pointed to by @p x, @p
- * y, @p w and @p h.  On success the variables have the output
- * location and size values written to them in canvas units. Any of @p
- * x, @p y, @p w or @p h that are @c NULL will not be written to. If @p e
- * is invalid, the results are undefined.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Example:
+ * @remarks Calling this function writes the current canvas output viewport
+ *          size and location values into the variables pointed to by @a x, @a y, 
+ *          @a w and @a h. On success, the variables have the output
+ *          location and size values written to them in canvas units. Any of @a x,
+ *          @a y, @a w or @a h that are @c NULL is not written to. If @a e
+ *          is invalid, the results are undefined.
+ *
+ * @remarks The following is an example.
  * @code
  * extern Evas *evas;
  * Evas_Coord x, y, width, height;
  *
  * evas_output_viewport_get(evas, &x, &y, &w, &h);
  * @endcode
+ *
+ * @param[in]   e  The pointer to the Evas Canvas
+ * @param[out]   x  The pointer to the x variable to be filled in
+ * @param[out]   y  The pointer to the y variable to be filled in
+ * @param[out]   w  The pointer to the width variable to be filled in
+ * @param[out]   h  The pointer to the height variable to be filled in
+ * @ingroup Evas_Output_Size 
  */
 EAPI void              evas_output_viewport_get(const Evas *e, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the output framespace size of the render engine of the given evas.
+ * @brief   Sets the output framespace size of the render engine of the given evas.
+ * @since   1.1
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * The framespace size is used in the Wayland engines to denote space where
- * the output is not drawn. This is mainly used in ecore_evas to draw borders
+ * @remarks The framespace size is used in the Wayland engines to denote space where
+ *          the output is not drawn. This is mainly used in ecore_evas to draw borders.
  *
- * The units used for @p w and @p h depend on the engine used by the
- * evas.
+ * @remarks The units used for @a w and @a h depend on the engine used by the evas.
  *
- * @param   e The given evas.
- * @param   x The left coordinate in output units, usually pixels.
- * @param   y The top coordinate in output units, usually pixels.
- * @param   w The width in output units, usually pixels.
- * @param   h The height in output units, usually pixels.
+ * @param[in]   e  The given evas
+ * @param[in]   x  The left coordinate in output units, usually pixels
+ * @param[in]   y  The top coordinate in output units, usually pixels
+ * @param[in]   w  The width in output units, usually pixels
+ * @param[in]   h  The height in output units, usually pixels
  * @ingroup Evas_Output_Size
- * @since 1.1
  */
 EAPI void              evas_output_framespace_set(Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
 
 /**
- * Get the render engine's output framespace co-ordinates in canvas units.
+ * @brief   Gets the render engine's output framespace co-ordinates in canvas units.
+ * @since   1.1
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The pointer to the Evas Canvas
- * @param x The pointer to a x variable to be filled in
- * @param y The pointer to a y variable to be filled in
- * @param w The pointer to a width variable to be filled in
- * @param h The pointer to a height variable to be filled in
+ * @param[in]   e  The pointer to the Evas Canvas
+ * @param[out]   x  The pointer to the x variable to be filled in
+ * @param[out]   y  The pointer to the y variable to be filled in
+ * @param[out]   w  The pointer to the width variable to be filled in
+ * @param[out]   h  The pointer to the height variable to be filled in
  * @ingroup Evas_Output_Size
- * @since 1.1
  */
 EAPI void              evas_output_framespace_get(const Evas *e, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
 
 /**
+ * @}
+ */
+
+/**
  * @defgroup Evas_Coord_Mapping_Group Coordinate Mapping Functions
+ * @ingroup Evas_Canvas
  *
- * Functions that are used to map coordinates from the canvas to the
- * screen or the screen to the canvas.
+ * @brief   This group provides functions that are used to map coordinates from the canvas to the
+ *          screen or the screen to the canvas.
  *
- * @ingroup Evas_Canvas
+ * @{
  */
 
 /**
- * Convert/scale an ouput screen co-ordinate into canvas co-ordinates
+ * @brief   Converts or scales an ouput screen co-ordinate into canvas co-ordinates.
  *
- * @param e The pointer to the Evas Canvas
- * @param x The screen/output x co-ordinate
- * @return The screen co-ordinate translated to canvas unit co-ordinates
- * @ingroup Evas_Coord_Mapping_Group
+ * @details This function takes in a horizontal co-ordinate as the @a x
+ *          parameter and converts it into canvas units, accounting for output
+ *          size, viewport size and location, returning it as the function
+ *          return value. If @a e is invalid, the results are undefined.
  *
- * This function takes in a horizontal co-ordinate as the @p x
- * parameter and converts it into canvas units, accounting for output
- * size, viewport size and location, returning it as the function
- * return value. If @p e is invalid, the results are undefined.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas *evas;
  * extern int screen_x;
@@ -1962,23 +2145,27 @@ EAPI void              evas_output_framespace_get(const Evas *e, Evas_Coord *x,
  *
  * canvas_x = evas_coord_screen_x_to_world(evas, screen_x);
  * @endcode
+ *
+ * @param[in]   e  The pointer to the Evas Canvas
+ * @param[in]   x  The screen or output x co-ordinate
+ * @return  The screen co-ordinate translated to canvas unit co-ordinates
+ * @ingroup Evas_Coord_Mapping_Group
  */
 EAPI Evas_Coord        evas_coord_screen_x_to_world(const Evas *e, int x) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Convert/scale an ouput screen co-ordinate into canvas co-ordinates
+ * @brief   Converts or scales an ouput screen co-ordinate into canvas co-ordinates.
  *
- * @param e The pointer to the Evas Canvas
- * @param y The screen/output y co-ordinate
- * @return The screen co-ordinate translated to canvas unit co-ordinates
- * @ingroup Evas_Coord_Mapping_Group
+ * @details This function takes in a vertical co-ordinate as the @a y parameter
+ *          and converts it into canvas units, accounting for output size,
+ *          viewport size and location, returning it as the function return
+ *          value. If @a e is invalid, the results are undefined.
  *
- * This function takes in a vertical co-ordinate as the @p y parameter
- * and converts it into canvas units, accounting for output size,
- * viewport size and location, returning it as the function return
- * value. If @p e is invalid, the results are undefined.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas *evas;
  * extern int screen_y;
@@ -1986,23 +2173,27 @@ EAPI Evas_Coord        evas_coord_screen_x_to_world(const Evas *e, int x) EINA_W
  *
  * canvas_y = evas_coord_screen_y_to_world(evas, screen_y);
  * @endcode
+ *
+ * @param[in]   e  The pointer to the Evas Canvas
+ * @param[in]   y  The screen or output y co-ordinate
+ * @return  The screen co-ordinate translated to canvas unit co-ordinates
+ * @ingroup Evas_Coord_Mapping_Group
  */
 EAPI Evas_Coord        evas_coord_screen_y_to_world(const Evas *e, int y) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Convert/scale a canvas co-ordinate into output screen co-ordinates
+ * @brief   Converts or scales a canvas co-ordinate into output screen co-ordinates.
  *
- * @param e The pointer to the Evas Canvas
- * @param x The canvas x co-ordinate
- * @return The output/screen co-ordinate translated to output co-ordinates
- * @ingroup Evas_Coord_Mapping_Group
+ * @details This function takes in a horizontal co-ordinate as the @a x
+ *          parameter and converts it into output units, accounting for output
+ *          size, viewport size and location, returning it as the function
+ *          return value. If @a e is invalid, the results are undefined.
  *
- * This function takes in a horizontal co-ordinate as the @p x
- * parameter and converts it into output units, accounting for output
- * size, viewport size and location, returning it as the function
- * return value. If @p e is invalid, the results are undefined.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas *evas;
  * int screen_x;
@@ -2010,23 +2201,27 @@ EAPI Evas_Coord        evas_coord_screen_y_to_world(const Evas *e, int y) EINA_W
  *
  * screen_x = evas_coord_world_x_to_screen(evas, canvas_x);
  * @endcode
+ *
+ * @param[in]   e  The pointer to the Evas canvas
+ * @param[in]   x  The canvas x co-ordinate
+ * @return  The output or screen co-ordinate translated to output co-ordinates
+ * @ingroup Evas_Coord_Mapping_Group
  */
 EAPI int               evas_coord_world_x_to_screen(const Evas *e, Evas_Coord x) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Convert/scale a canvas co-ordinate into output screen co-ordinates
+ * @brief   Converts or scales a canvas co-ordinate into output screen co-ordinates.
  *
- * @param e The pointer to the Evas Canvas
- * @param y The canvas y co-ordinate
- * @return The output/screen co-ordinate translated to output co-ordinates
- * @ingroup Evas_Coord_Mapping_Group
+ * @details This function takes in a vertical co-ordinate as the @a x parameter
+ *          and converts it into output units, accounting for output size,
+ *          viewport size and location, returning it as the function return
+ *          value. If @a e is invalid, the results are undefined.
  *
- * This function takes in a vertical co-ordinate as the @p x parameter
- * and converts it into output units, accounting for output size,
- * viewport size and location, returning it as the function return
- * value. If @p e is invalid, the results are undefined.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas *evas;
  * int screen_y;
@@ -2034,31 +2229,40 @@ EAPI int               evas_coord_world_x_to_screen(const Evas *e, Evas_Coord x)
  *
  * screen_y = evas_coord_world_y_to_screen(evas, canvas_y);
  * @endcode
+ *
+ * @param[in]   e  The pointer to the Evas Canvas
+ * @param[in]   y  The canvas y co-ordinate
+ * @return  The output or screen co-ordinate translated to output co-ordinates
+ * @ingroup Evas_Coord_Mapping_Group
  */
 EAPI int               evas_coord_world_y_to_screen(const Evas *e, Evas_Coord y) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
+ * @}
+ */
+
+/**
  * @defgroup Evas_Pointer_Group Pointer (Mouse) Functions
+ * @ingroup Evas_Canvas
  *
- * Functions that deal with the status of the pointer (mouse cursor).
+ * @brief   This group provides functions that deal with the status of the pointer (mouse cursor).
  *
- * @ingroup Evas_Canvas
+ * @{
  */
 
 /**
- * This function returns the current known pointer co-ordinates
+ * @brief   Gets the current known pointer co-ordinates.
  *
- * @param e The pointer to the Evas Canvas
- * @param x The pointer to an integer to be filled in
- * @param y The pointer to an integer to be filled in
- * @ingroup Evas_Pointer_Group
+ * @details This function returns the current known screen or output co-ordinates
+ *          of the mouse pointer and sets the contents of the integers pointed
+ *          to by @a x and @a y to contain these co-ordinates. If @a e is not a
+ *          valid canvas the results of this function are undefined.
  *
- * This function returns the current known screen/output co-ordinates
- * of the mouse pointer and sets the contents of the integers pointed
- * to by @p x and @p y to contain these co-ordinates. If @p e is not a
- * valid canvas the results of this function are undefined.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas *evas;
  * int mouse_x, mouse_y;
@@ -2066,23 +2270,27 @@ EAPI int               evas_coord_world_y_to_screen(const Evas *e, Evas_Coord y)
  * evas_pointer_output_xy_get(evas, &mouse_x, &mouse_y);
  * printf("Mouse is at screen position %i, %i\n", mouse_x, mouse_y);
  * @endcode
+ *
+ * @param[in]   e  The pointer to the Evas Canvas
+ * @param[out]   x  The pointer to an integer to be filled in
+ * @param[out]   y  The pointer to an integer to be filled in
+ * @ingroup Evas_Pointer_Group
  */
 EAPI void              evas_pointer_output_xy_get(const Evas *e, int *x, int *y) EINA_ARG_NONNULL(1);
 
 /**
- * This function returns the current known pointer co-ordinates
+ * @brief   Gets the current known pointer co-ordinates.
  *
- * @param e The pointer to the Evas Canvas
- * @param x The pointer to a Evas_Coord to be filled in
- * @param y The pointer to a Evas_Coord to be filled in
- * @ingroup Evas_Pointer_Group
+ * @details This function returns the current known canvas unit co-ordinates of
+ *          the mouse pointer and sets the contents of the Evas_Coords pointed
+ *          to by @a x and @a y to contain these co-ordinates. If @a e is not a
+ *          valid canvas the results of this function are undefined.
  *
- * This function returns the current known canvas unit co-ordinates of
- * the mouse pointer and sets the contents of the Evas_Coords pointed
- * to by @p x and @p y to contain these co-ordinates. If @p e is not a
- * valid canvas the results of this function are undefined.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas *evas;
  * Evas_Coord mouse_x, mouse_y;
@@ -2090,34 +2298,34 @@ EAPI void              evas_pointer_output_xy_get(const Evas *e, int *x, int *y)
  * evas_pointer_output_xy_get(evas, &mouse_x, &mouse_y);
  * printf("Mouse is at canvas position %f, %f\n", mouse_x, mouse_y);
  * @endcode
+ *
+ * @param[in]   e  The pointer to the Evas Canvas
+ * @param[out]   x  The pointer to a Evas_Coord to be filled in
+ * @param[out]   y  The pointer to a Evas_Coord to be filled in
+ * @ingroup Evas_Pointer_Group
  */
 EAPI void              evas_pointer_canvas_xy_get(const Evas *e, Evas_Coord *x, Evas_Coord *y) EINA_ARG_NONNULL(1);
 
 /**
- * Returns a bitmask with the mouse buttons currently pressed, set to 1
- *
- * @param e The pointer to the Evas Canvas
- * @return A bitmask of the currently depressed buttons on the canvas
- * @ingroup Evas_Pointer_Group
+ * @brief   Gets a bitmask with the mouse buttons currently pressed, set to @c 1.
  *
- * Calling this function will return a 32-bit integer with the
- * appropriate bits set to 1 that correspond to a mouse button being
- * depressed. This limits Evas to a mouse devices with a maximum of 32
- * buttons, but that is generally in excess of any host system's
- * pointing device abilities.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * A canvas by default begins with no mouse buttons being pressed and
- * only calls to evas_event_feed_mouse_down(),
- * evas_event_feed_mouse_down_data(), evas_event_feed_mouse_up() and
- * evas_event_feed_mouse_up_data() will alter that.
+ * @remarks This function returns a 32-bit integer with the
+ *          appropriate bits set to @c 1 that correspond to a mouse button being
+ *          depressed. This limits Evas to mouse devices with a maximum of 32
+ *          buttons, but that is generally in excess of any host system's
+ *          pointing device abilities.
  *
- * The least significant bit corresponds to the first mouse button
- * (button 1) and the most significant bit corresponds to the last
- * mouse button (button 32).
+ * @remarks The least significant bit corresponds to the first mouse button
+ *          (button 1) and the most significant bit corresponds to the last
+ *          mouse button (button 32).
  *
- * If @p e is not a valid canvas, the return value is undefined.
+ * @remarks If @a e is not a valid canvas, the return value is undefined.
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas *evas;
  * int button_mask, i;
@@ -2129,155 +2337,149 @@ EAPI void              evas_pointer_canvas_xy_get(const Evas *e, Evas_Coord *x,
  *     if ((button_mask & (1 << i)) != 0) printf("Button %i\n", i + 1);
  *   }
  * @endcode
+ *
+ * @param[in]   e  The pointer to the Evas canvas
+ * @return  A bitmask of the currently depressed buttons on the canvas
+ * @ingroup Evas_Pointer_Group
  */
 EAPI int               evas_pointer_button_down_mask_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Returns whether the mouse pointer is logically inside the canvas
+ * @brief   Checks whether the mouse pointer is logically inside the canvas.
  *
- * @param e The pointer to the Evas Canvas
- * @return An integer that is 1 if the mouse is inside the canvas, 0 otherwise
- * @ingroup Evas_Pointer_Group
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * When this function is called it will return a value of either 0 or
- * 1, depending on if evas_event_feed_mouse_in(),
- * evas_event_feed_mouse_in_data(), or evas_event_feed_mouse_out(),
- * evas_event_feed_mouse_out_data() have been called to feed in a
- * mouse enter event into the canvas.
+ * @remarks When this function is called it returns a value of either @c 0 or
+ *          @c 1.
  *
- * A return value of 1 indicates the mouse is logically inside the
- * canvas, and 0 implies it is logically outside the canvas.
+ * @remarks A return value of @c 1 indicates the mouse is logically inside the
+ *          canvas, and @c 0 implies it is logically outside the canvas.
  *
- * A canvas begins with the mouse being assumed outside (0).
+ * @remarks A canvas begins with the mouse being assumed outside (0).
  *
- * If @p e is not a valid canvas, the return value is undefined.
+ * @remarks If @a e is not a valid canvas, the return value is undefined.
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas *evas;
  *
  * if (evas_pointer_inside_get(evas)) printf("Mouse is in!\n");
  * else printf("Mouse is out!\n");
  * @endcode
+ *
+ * @param[in]   e  The pointer to the Evas Canvas
+ * @return  #EINA_TRUE if the mouse is inside the canvas, 
+ *          otherwise #EINA_FALSE
+ * @ingroup Evas_Pointer_Group
  */
 EAPI Eina_Bool         evas_pointer_inside_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+
 EAPI void              evas_sync(Evas *e) EINA_ARG_NONNULL(1);
 
 /**
- * @defgroup Evas_Canvas_Events Canvas Events
- *
- * Functions relating to canvas events, which are mainly reports on
- * its internal states changing (an object got focused, the rendering
- * is updated, etc).
- *
- * Some of the functions in this group are exemplified @ref
- * Example_Evas_Events "here".
- *
- * @ingroup Evas_Canvas
+ * @}
  */
 
 /**
- * @addtogroup Evas_Canvas_Events
+ * @defgroup Evas_Canvas_Events Canvas Events
+ * @ingroup Evas_Canvas
+ *
+ * @brief   This group provides functions relating to canvas events, which are mainly reports on
+ *          its internal states changing such as an object getting focused, the rendering being updated,
+ *          and so on.
+ *
  * @{
  */
 
 /**
- * Add (register) a callback function to a given canvas event.
- *
- * @param e Canvas to attach a callback to
- * @param type The type of event that will trigger the callback
- * @param func The (callback) function to be called when the event is
- *        triggered
- * @param data The data pointer to be passed to @p func
- *
- * This function adds a function callback to the canvas @p e when the
- * event of type @p type occurs on it. The function pointer is @p
- * func.
- *
- * In the event of a memory allocation error during the addition of
- * the callback to the canvas, evas_alloc_error() should be used to
- * determine the nature of the error, if any, and the program should
- * sensibly try and recover.
- *
- * A callback function must have the ::Evas_Event_Cb prototype
- * definition. The first parameter (@p data) in this definition will
- * have the same value passed to evas_event_callback_add() as the @p
- * data parameter, at runtime. The second parameter @p e is the canvas
- * pointer on which the event occurred. The third parameter @p
- * event_info is a pointer to a data structure that may or may not be
- * passed to the callback, depending on the event type that triggered
- * the callback. This is so because some events don't carry extra
- * context with them, but others do.
- *
- * The event type @p type to trigger the function may be one of
- * #EVAS_CALLBACK_RENDER_FLUSH_PRE, #EVAS_CALLBACK_RENDER_FLUSH_POST,
- * #EVAS_CALLBACK_CANVAS_FOCUS_IN, #EVAS_CALLBACK_CANVAS_FOCUS_OUT,
- * #EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN and
- * #EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT. This determines the kind of
- * event that will trigger the callback to be called. Only the last
- * two of the event types listed here provide useful event information
- * data -- a pointer to the recently focused Evas object. For the
- * others the @p event_info pointer is going to be @c NULL.
- *
- * Example:
- * @dontinclude evas-events.c
- * @skip evas_event_callback_add(d.canvas, EVAS_CALLBACK_RENDER_FLUSH_PRE
- * @until two canvas event callbacks
- *
- * Looking to the callbacks registered above,
- * @dontinclude evas-events.c
- * @skip called when our rectangle gets focus
- * @until let's have our events back
- *
- * we see that the canvas flushes its rendering pipeline
- * (#EVAS_CALLBACK_RENDER_FLUSH_PRE) whenever the @c _resize_cb
- * routine takes place: it has to redraw that image at a different
- * size. Also, the callback on an object being focused comes just
- * after we focus it explicitly, on code.
- *
- * See the full @ref Example_Evas_Events "example".
- *
- * @note Be careful not to add the same callback multiple times, if
- * that's not what you want, because Evas won't check if a callback
- * existed before exactly as the one being registered (and thus, call
- * it more than once on the event, in this case). This would make
- * sense if you passed different functions and/or callback data, only.
+ * @brief   Adds or registers a callback function to a given canvas event.
+ *
+ * @details This function adds a function callback to the canvas @a e when the
+ *          event of type @a type occurs on it. The function pointer is @a func.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks In the event of a memory allocation error during the addition of
+ *          the callback to the canvas.
+ *
+ * @remarks A callback function must have the ::Evas_Event_Cb prototype
+ *          definition. The first parameter (@a data) in this definition has
+ *          the same value passed to evas_event_callback_add() as the @a data
+ *          parameter, at runtime. The second parameter @a e is the canvas
+ *          pointer on which the event occurred. The third parameter @a
+ *          event_info is a pointer to a data structure that may or may not be
+ *          passed to the callback, depending on the event type that triggered
+ *          the callback. This is so because some events do not carry extra
+ *          context with them, but others do.
+ *
+ * @remarks The valid event types @a type to trigger the function are
+ *          #EVAS_CALLBACK_RENDER_FLUSH_PRE, #EVAS_CALLBACK_RENDER_FLUSH_POST,
+ *          #EVAS_CALLBACK_CANVAS_FOCUS_IN, #EVAS_CALLBACK_CANVAS_FOCUS_OUT,
+ *          #EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN and 
+ *          #EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT. This determines the kind of
+ *          event that triggers the callback to be called. Only the last
+ *          two event types listed here provide useful event information
+ *          data -- a pointer to the recently focused Evas object. For the
+ *          others the @a event_info pointer is going to be @c NULL.
+ *
+ * @remarks The canvas flushes its rendering pipeline
+ *          (#EVAS_CALLBACK_RENDER_FLUSH_PRE) whenever the @c _resize_cb
+ *          routine takes place: it has to redraw that image at a different
+ *          size. Also, the callback on an object being focused comes just
+ *          after you focus it explicitly, on code.
+ *
+ * @remarks Be careful not to add the same callback multiple times, if
+ *          that is not what you want, because Evas does not check if a callback
+ *          existed before exactly as the one being registered (and thus, call
+ *          it more than once on the event, in this case). This would make
+ *          sense if you passed different functions and/or callback data, only.
+ *
+ * @param[in]   e     The canvas to attach a callback to
+ * @param[in]   type  The type of event that triggers the callback
+ * @param[in]   func  The (callback) function to be called when the event is triggered
+ * @param[in]   data  The data pointer to be passed to @a func
  */
 EAPI void  evas_event_callback_add(Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
 
 /**
- * Add (register) a callback function to a given canvas event with a
- * non-default priority set. Except for the priority field, it's exactly the
- * same as @ref evas_event_callback_add
+ * @brief  Adds or registers a callback function to a given canvas event with a
+ *         non-default priority set. Except for the priority field, it is exactly the
+ *         same as @ref evas_event_callback_add
+ * @since  1.1
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e Canvas to attach a callback to
- * @param type The type of event that will trigger the callback
- * @param priority The priority of the callback, lower values called first.
- * @param func The (callback) function to be called when the event is
- *        triggered
- * @param data The data pointer to be passed to @p func
+ * @param[in]  e         The canvas to attach a callback to
+ * @param[in]  type      The type of event that triggers the callback
+ * @param[in]  priority  The priority of the callback, lower values called first
+ * @param[in]  func      The (callback) function to be called when the event is triggered
+ * @param[in]  data      The data pointer to be passed to @a func
  *
  * @see evas_event_callback_add
- * @since 1.1
  */
 EAPI void  evas_event_callback_priority_add(Evas *e, Evas_Callback_Type type, Evas_Callback_Priority priority, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 4);
 
 /**
- * Delete a callback function from the canvas.
+ * @brief   Deletes a callback function from the canvas.
  *
- * @param e Canvas to remove a callback from
- * @param type The type of event that was triggering the callback
- * @param func The function that was to be called when the event was triggered
- * @return The data pointer that was to be passed to the callback
+ * @details This function removes the most recently added callback from the
+ *          canvas @a e which is triggered by the event type @a type and is
+ *          calling the function @a func when triggered. If the removal is
+ *          successful it also returns the data pointer that is passed to
+ *          evas_event_callback_add() when the callback is added to the
+ *          canvas. If not successful @c NULL is returned.
  *
- * This function removes the most recently added callback from the
- * canvas @p e which was triggered by the event type @p type and was
- * calling the function @p func when triggered. If the removal is
- * successful it will also return the data pointer that was passed to
- * evas_event_callback_add() when the callback was added to the
- * canvas. If not successful @c NULL will be returned.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas *e;
  * void *my_data;
@@ -2285,229 +2487,244 @@ EAPI void  evas_event_callback_priority_add(Evas *e, Evas_Callback_Type type, Ev
  *
  * my_data = evas_event_callback_del(ebject, EVAS_CALLBACK_CANVAS_FOCUS_IN, focus_in_callback);
  * @endcode
+ *
+ * @param[in]   e     The canvas to remove a callback from
+ * @param[in]   type  The type of event that is triggering the callback
+ * @param[in]   func  The function that is to be called when the event is triggered
+ * @return  The data pointer that is to be passed to the callback
  */
 EAPI void *evas_event_callback_del(Evas *e, Evas_Callback_Type type, Evas_Event_Cb func) EINA_ARG_NONNULL(1, 3);
 
 /**
- * Delete (unregister) a callback function registered to a given
- * canvas event.
- *
- * @param e Canvas to remove an event callback from
- * @param type The type of event that was triggering the callback
- * @param func The function that was to be called when the event was
- *        triggered
- * @param data The data pointer that was to be passed to the callback
- * @return The data pointer that was to be passed to the callback
+ * @brief   Deletes (unregisters) a callback function registered to a given canvas event.
  *
- * This function removes <b>the first</b> added callback from the
- * canvas @p e matching the event type @p type, the registered
- * function pointer @p func and the callback data pointer @p data. If
- * the removal is successful it will also return the data pointer that
- * was passed to evas_event_callback_add() (that will be the same as
- * the parameter) when the callback(s) was(were) added to the
- * canvas. If not successful @c NULL will be returned. A common use
- * would be to remove an exact match of a callback.
+ * @details This function removes <b>the first</b> added callback from the
+ *          canvas @a e matching the event type @a type, the registered
+ *          function pointer @a func and the callback data pointer @a data. If
+ *          the removal is successful it also returns the data pointer that
+ *          is passed to evas_event_callback_add() (that is the same as
+ *          the parameter) when the callback(s) is (were) added to the
+ *          canvas. If not successful @c NULL is returned. A common use
+ *          would be to remove an exact match of a callback.
  *
- * Example:
- * @dontinclude evas-events.c
- * @skip evas_event_callback_del_full(evas, EVAS_CALLBACK_RENDER_FLUSH_PRE,
- * @until _object_focus_in_cb, NULL);
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * See the full @ref Example_Evas_Events "example".
+ * @remarks For deleting canvas events callbacks filtering by just
+ *          type and function pointer, use evas_event_callback_del().
  *
- * @note For deletion of canvas events callbacks filtering by just
- * type and function pointer, user evas_event_callback_del().
+ * @param[in]   e     The Canvas to remove an event callback from
+ * @param[in]   type  The type of event that triggers the callback
+ * @param[in]   func  The function that is to be called when the event is triggered
+ * @param[in]   data  The data pointer that is to be passed to the callback
+ * @return  The data pointer that is to be passed to the callback
  */
 EAPI void *evas_event_callback_del_full(Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
 
 /**
- * Push a callback on the post-event callback stack
+ * @brief   Pushes a callback on the post-event callback stack.
  *
- * @param e Canvas to push the callback on
- * @param func The function that to be called when the stack is unwound
- * @param data The data pointer to be passed to the callback
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Evas has a stack of callbacks that get called after all the callbacks for
- * an event have triggered (all the objects it triggers on and all the callbacks
- * in each object triggered). When all these have been called, the stack is
- * unwond from most recently to least recently pushed item and removed from the
- * stack calling the callback set for it.
+ * @remarks Evas has a stack of callbacks that get called after all the callbacks for
+ *          an event have triggered (all the objects it triggers on and all the callbacks
+ *          in each object triggered). When all these have been called, the stack is
+ *          unwound from most recently to least recently pushed item and removed from the
+ *          stack calling the callback set for it.
  *
- * This is intended for doing reverse logic-like processing, example - when a
- * child object that happens to get the event later is meant to be able to
- * "steal" functions from a parent and thus on unwind of this stack have its
- * function called first, thus being able to set flags, or return 0 from the
- * post-callback that stops all other post-callbacks in the current stack from
- * being called (thus basically allowing a child to take control, if the event
- * callback prepares information ready for taking action, but the post callback
- * actually does the action).
+ * @remarks This is intended for doing reverse logic-like processing, for example - when a
+ *          child object that happens to get the event later is meant to be able to
+ *          "steal" functions from a parent and when this stack is unwound, have its
+ *          function called first, thus being able to set flags, or return @c 0 from the
+ *          post-callback, that stops all other post-callbacks in the current stack from
+ *          being called (thus basically allowing a child to take control, if the event
+ *          callback prepares information ready for taking action, but the post callback
+ *          actually does the action).
  *
+ * @param[in]   e     The canvas to push the callback on
+ * @param[in]   func  The function that to be called when the stack is unwound
+ * @param[in]   data  The data pointer to be passed to the callback 
  */
 EAPI void  evas_post_event_callback_push(Evas *e, Evas_Object_Event_Post_Cb func, const void *data);
 
 /**
- * Remove a callback from the post-event callback stack
+ * @brief   Removes a callback from the post-event callback stack.
+ *
+ * @details This removes a callback from the stack added with
+ *          evas_post_event_callback_push(). The first instance of the function in
+ *          the callback stack is removed from being executed when the stack is
+ *          unwound. Further instances may still be run on unwind.
  *
- * @param e Canvas to push the callback on
- * @param func The function that to be called when the stack is unwound
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This removes a callback from the stack added with
- * evas_post_event_callback_push(). The first instance of the function in
- * the callback stack is removed from being executed when the stack is
- * unwound. Further instances may still be run on unwind.
+ * @param[in]   e     The canvas to push the callback on
+ * @param[in]   func  The function that to be called when the stack is unwound
  */
 EAPI void  evas_post_event_callback_remove(Evas *e, Evas_Object_Event_Post_Cb func);
 
 /**
- * Remove a callback from the post-event callback stack
+ * @brief   Removes a callback from the post-event callback stack.
  *
- * @param e Canvas to push the callback on
- * @param func The function that to be called when the stack is unwound
- * @param data The data pointer to be passed to the callback
+ * @details This removes a callback from the stack added with
+ *          evas_post_event_callback_push(). The first instance of the function and data
+ *          in the callback stack is removed from being executed when the stack is
+ *          unwound. Further instances may still be run on unwind.
  *
- * This removes a callback from the stack added with
- * evas_post_event_callback_push(). The first instance of the function and data
- * in the callback stack is removed from being executed when the stack is
- * unwound. Further instances may still be run on unwind.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e     The canvas to push the callback on
+ * @param[in]   func  The function that to be called when the stack is unwound
+ * @param[in]   data  The data pointer to be passed to the callback
  */
 EAPI void  evas_post_event_callback_remove_full(Evas *e, Evas_Object_Event_Post_Cb func, const void *data);
 
 /**
+ * @}
+ */
+
+/**
  * @defgroup Evas_Event_Freezing_Group Input Events Freezing Functions
+ * @ingroup Evas_Canvas_Events
  *
- * Functions that deal with the freezing of input event processing of
- * an Evas canvas.
+ * @brief   This group provides functions that deal with the freezing of input event processing of
+ *          an Evas canvas.
  *
- * There might be scenarios during a graphical user interface
- * program's use when the developer wishes the users wouldn't be able
- * to deliver input events to this application. It may, for example,
- * be the time for it to populate a view or to change some
- * layout. Assuming proper behavior with user interaction during this
- * exact time would be hard, as things are in a changing state. The
- * programmer can then tell the canvas to ignore input events,
- * bringing it back to normal behavior when he/she wants.
+ * @remarks There might be scenarios during a graphical user interface
+ *          program's use when the developer wishes the users would not be able
+ *          to deliver input events to this application. It may, for example,
+ *          be the time for it to populate a view or to change some
+ *          layout. Assuming proper behavior with user interaction during this
+ *          exact time would be hard, as things are in a changing state. The
+ *          programmer can then tell the canvas to ignore input events,
+ *          bringing it back to normal behavior when he or she wants.
  *
- * Most of the time use of freezing events is done like this:
+ * @remarks Most of the time, the freezing events is used like this:
  * @code
  * evas_event_freeze(my_evas_canvas);
  * function_that_does_work_which_cant_be_interrupted_by_events();
  * evas_event_thaw(my_evas_canvas);
  * @endcode
  *
- * Some of the functions in this group are exemplified @ref
- * Example_Evas_Events "here".
- *
- * @ingroup Evas_Canvas_Events
- */
-
-/**
- * @addtogroup Evas_Event_Freezing_Group
  * @{
  */
 
 /**
- * Set the default set of flags an event begins with
+ * @brief   Sets the default set of flags an event begins with.
+ * @since   1.2
  *
- * @param e The canvas to set the default event flags of
- * @param flags The default flags to use
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Events in evas can have an event_flags member. This starts out with
- * and initial value (no flags). this lets you set the default flags that
- * an event begins with to be @p flags
+ * @remarks Events in evas can have an event_flags member. This starts out with
+ *          an initial value (no flags). This lets you set the default flags that
+ *          an event begins with to be @a flags.
  *
- * @since 1.2
+ * @param[in]   e      The canvas to set the default event flags of
+ * @param[in]   flags  The default flags to use
  */
 EAPI void             evas_event_default_flags_set(Evas *e, Evas_Event_Flags flags) EINA_ARG_NONNULL(1);
 
 /**
- * Get the defaulty set of flags an event begins with
+ * @brief   Gets the default set of flags an event begins with.
+ * @since   1.2
  *
- * @param e The canvas to get the default event flags from
- * @return The default event flags for that canvas
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This gets the default event flags events are produced with when fed in.
+ * @remarks This gets the default event flags with which the events are produced.
+ *
+ * @param[in]   e  The canvas to get the default event flags from
+ * @return  The default event flags for that canvas
  *
  * @see evas_event_default_flags_set()
- * @since 1.2
  */
 EAPI Evas_Event_Flags evas_event_default_flags_get(const Evas *e) EINA_ARG_NONNULL(1);
 
 /**
- * Freeze all input events processing.
- *
- * @param e The canvas to freeze input events processing on.
- *
- * This function will indicate to Evas that the canvas @p e is to have
- * all input event processing frozen until a matching
- * evas_event_thaw() function is called on the same canvas. All events
- * of this kind during the freeze will get @b discarded. Every freeze
- * call must be matched by a thaw call in order to completely thaw out
- * a canvas (i.e. these calls may be nested). The most common use is
- * when you don't want the user to interact with your user interface
- * when you're populating a view or changing the layout.
+ * @brief   Freezes all input events processing.
  *
- * Example:
- * @dontinclude evas-events.c
- * @skip freeze input for 3 seconds
- * @until }
- * @dontinclude evas-events.c
- * @skip let's have our events back
- * @until }
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * See the full @ref Example_Evas_Events "example".
+ * @remarks This function indicates to Evas that the canvas @a e is to have
+ *          all input event processing frozen until a matching
+ *          evas_event_thaw() function is called on the same canvas. All events
+ *          of this kind during the freeze get @b discarded. Every freeze
+ *          call must be matched by a thaw call in order to completely thaw out
+ *          a canvas (i.e. these calls may be nested). The most common use is
+ *          when you do not want the user to interact with your user interface
+ *          when you are populating a view or changing the layout.
  *
- * If you run that example, you'll see the canvas ignoring all input
- * events for 3 seconds, when the "f" key is pressed. In a more
- * realistic code we would be freezing while a toolkit or Edje was
- * doing some UI changes, thawing it back afterwards.
+ * @param[in]   e  The canvas to freeze input events processing on
  */
 EAPI void             evas_event_freeze(Evas *e) EINA_ARG_NONNULL(1);
 
 /**
- * Thaw a canvas out after freezing (for input events).
+ * @brief   Thaws a canvas out after freezing (for input events).
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The canvas to thaw out.
+ * @remarks This thaws out a canvas after a matching evas_event_freeze()
+ *          call. If this call completely thaws out a canvas, i.e., there is no
+ *          other unbalanced call to evas_event_freeze(), events start to
+ *          be processed again, but any "missed" events are @b not be evaluated.
  *
- * This will thaw out a canvas after a matching evas_event_freeze()
- * call. If this call completely thaws out a canvas, i.e., there's no
- * other unbalanced call to evas_event_freeze(), events will start to
- * be processed again, but any "missed" events will @b not be
- * evaluated.
+ * @param[in]   e  The canvas to thaw out
  *
- * See evas_event_freeze() for an example.
+ * @see evas_event_freeze() for an example.
  */
 EAPI void             evas_event_thaw(Evas *e) EINA_ARG_NONNULL(1);
 
 /**
- * Return the freeze count on input events of a given canvas.
+ * @brief   Gets the freeze count on input events of a given canvas.
  *
- * @param e The canvas to fetch the freeze count from.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This returns the number of times the canvas has been told to freeze
- * input events. It is possible to call evas_event_freeze() multiple
- * times, and these must be matched by evas_event_thaw() calls. This
- * call allows the program to discover just how many times things have
- * been frozen in case it may want to break out of a deep freeze state
- * where the count is high.
+ * @remarks This returns the number of times the canvas has been told to freeze
+ *          input events. It is possible to call evas_event_freeze() multiple
+ *          times, and these must be matched by evas_event_thaw() calls. This
+ *          call allows the program to discover just how many times things have
+ *          been frozen in case it may want to break out of a deep freeze state
+ *          where the count is high.
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas *evas;
  *
  * while (evas_event_freeze_get(evas) > 0) evas_event_thaw(evas);
  * @endcode
  *
+ * @param[in]   e  The canvas to fetch the freeze count from
+ * @return The freeze count
  */
 EAPI int              evas_event_freeze_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * After thaw of a canvas, re-evaluate the state of objects and call callbacks
+ * @brief   Re-evaluates the state of objects and call callbacks after thaw of a canvas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The canvas to evaluate after a thaw
+ * @remarks This is normally called after evas_event_thaw() to re-evaluate mouse
+ *          containment and other states and thus also call callbacks for mouse in and
+ *          out on new objects if the state change demands it.
  *
- * This is normally called after evas_event_thaw() to re-evaluate mouse
- * containment and other states and thus also call callbacks for mouse in and
- * out on new objects if the state change demands it.
+ * @param[in]   e  The canvas to evaluate after a thaw
  */
 EAPI void             evas_event_thaw_eval(Evas *e) EINA_ARG_NONNULL(1);
 
@@ -2516,116 +2733,224 @@ EAPI void             evas_event_thaw_eval(Evas *e) EINA_ARG_NONNULL(1);
  */
 
 /**
+ * @internal
  * @defgroup Evas_Event_Feeding_Group Input Events Feeding Functions
+ * @ingroup Evas_Canvas_Events
  *
- * Functions to tell Evas that input events happened and should be
- * processed.
- *
- * @warning Most of the time these functions are @b not what you're looking for.
- * These functions should only be used if you're not working with ecore evas(or
- * another input handling system). If you're not using ecore evas please
- * consider using it, in most situation it will make life a lot easier.
+ * @brief   This group provides functions to tell Evas that input events happened and should be processed.
  *
- * As explained in @ref intro_not_evas, Evas does not know how to poll
- * for input events, so the developer should do it and then feed such
- * events to the canvas to be processed. This is only required if
- * operating Evas directly. Modules such as Ecore_Evas do that for
- * you.
+ * @remarks Most of the time these functions are @b not what you are looking for.
+ *          These functions should only be used if you are not working with ecore evas(or
+ *          another input handling system). If you are not using ecore evas, please
+ *          consider using it, as in most situation it makes life a lot easier.
  *
- * Some of the functions in this group are exemplified @ref
- * Example_Evas_Events "here".
+ * @remarks As explained in @ref evas_main_intro_not_evas, Evas does not know how to poll
+ *          for input events, so you should do it and then feed such
+ *          events to the canvas to be processed. This is only required if
+ *          operating Evas directly. Modules such as Ecore_Evas do that for you.
  *
- * @ingroup Evas_Canvas_Events
+ * @{
  */
 
 /**
- * @addtogroup Evas_Event_Feeding_Group
- * @{
+ * @internal
+ * @since 1.8
+ */
+EAPI Evas_Device *evas_device_new(Evas *e);
+
+/**
+ * @internal
+ * @since 1.8
  */
+EAPI void evas_device_free(Evas_Device *dev);
 
 /**
- * Get the number of mouse or multi presses currently active
+ * @internal
+ * @since 1.8
+ */
+EAPI void evas_device_push(Evas *e, Evas_Device *dev);
+
+/**
+ * @internal
+ * @since 1.8
+ */
+EAPI void evas_device_pop(Evas *e);
+
+/**
+ * @internal
+ * @since 1.8
+ */
+EAPI const Eina_List *evas_device_list(Evas *e, const Evas_Device *dev);
+
+/**
+ * @internal
+ * @since 1.8
+ */
+EAPI void evas_device_name_set(Evas_Device *dev, const char *name);
+
+/**
+ * @internal
+ * @since 1.8
+ */
+EAPI const char *evas_device_name_get(const Evas_Device *dev);
+
+/**
+ * @internal
+ * @since 1.8
+ */
+EAPI void evas_device_description_set(Evas_Device *dev, const char *desc);
+
+/**
+ * @internal
+ * @since 1.8
+ */
+EAPI const char *evas_device_description_get(const Evas_Device *dev);
+
+/**
+ * @internal
+ * @since 1.8
+ */
+EAPI void evas_device_parent_set(Evas_Device *dev, Evas_Device *parent);
+
+/**
+ * @internal
+ * @since 1.8
+ */
+EAPI const Evas_Device *evas_device_parent_get(const Evas_Device *dev);
+
+/**
+ * @internal
+ * @since 1.8
+ */
+EAPI void evas_device_class_set(Evas_Device *dev, Evas_Device_Class clas);
+
+/**
+ * @internal
+ * @since 1.8
+ */
+EAPI Evas_Device_Class evas_device_class_get(const Evas_Device *dev);
+
+/**
+ * @internal
+ * @since 1.8
+ */
+EAPI void evas_device_emulation_source_set(Evas_Device *dev, Evas_Device *src);
+
+/**
+ * @internal
+ * @since 1.8
+ */
+EAPI const Evas_Device *evas_device_emulation_source_get(const Evas_Device *dev);
+
+/**
+ * @internal
+ * @brief   Gets the number of mouse or multi presses currently active.
+ * @since   1.2
  *
- * @p e The given canvas pointer.
- * @return The numer of presses (0 if none active).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e  The given canvas pointer
+ * @return  The number of presses, \n
+ *          otherwise @c 0 if none active
  *
- * @since 1.2
  */
 EAPI int  evas_event_down_count_get(const Evas *e) EINA_ARG_NONNULL(1);
 
 /**
- * Mouse down event feed.
+ * @internal
+ * @brief   Feeds the mouse down event for the given canvas @a e.
  *
- * @param e The given canvas pointer.
- * @param b The button number.
- * @param flags The evas button flags.
- * @param timestamp The timestamp of the mouse down event.
- * @param data The data for canvas.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function will set some evas properties that is necessary when
- * the mouse button is pressed. It prepares information to be treated
- * by the callback function.
+ * @remarks This function sets some evas properties that is necessary when
+ *          the mouse button is pressed. It prepares information to be treated
+ *          by the callback function.
  *
+ * @param[in]   e           The given canvas pointer
+ * @param[in]   b           The button number
+ * @param[in]   flags       The evas button flags
+ * @param[in]   timestamp   The timestamp of the mouse down event
+ * @param[in]   data        The data for canvas
  */
 EAPI void evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
 
 /**
- * Mouse up event feed.
+ * @internal
+ * @brief   Feeds the mouse up event for the given canvas @a e.
  *
- * @param e The given canvas pointer.
- * @param b The button number.
- * @param flags evas button flags.
- * @param timestamp The timestamp of the mouse up event.
- * @param data The data for canvas.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function will set some evas properties that is necessary when
- * the mouse button is released. It prepares information to be treated
- * by the callback function.
+ * @remarks This function sets some evas properties that is necessary when
+ *          the mouse button is released. It prepares information to be treated
+ *          by the callback function.
  *
+ * @param[in]   e          The given canvas pointer
+ * @param[in]   b          The button number
+ * @param[in]   flags      The evas button flags
+ * @param[in]   timestamp  The timestamp of the mouse up event
+ * @param[in]   data       The data for canvas
  */
 EAPI void evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
 
 /**
- * Mouse move event feed.
+ * @internal
+ * @brief   Feeds the mouse move event for the given canvas @a e.
  *
- * @param e The given canvas pointer.
- * @param x The horizontal position of the mouse pointer.
- * @param y The vertical position of the mouse pointer.
- * @param timestamp The timestamp of the mouse up event.
- * @param data The data for canvas.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function will set some evas properties that is necessary when
- * the mouse is moved from its last position. It prepares information
- * to be treated by the callback function.
+ * @remarks This function sets some evas properties that is necessary when
+ *          the mouse is moved from its last position. It prepares information
+ *          to be treated by the callback function.
  *
+ * @param[in]   e          The given canvas pointer
+ * @param[in]   x          The horizontal position of the mouse pointer
+ * @param[in]   y          The vertical position of the mouse pointer
+ * @param[in]   timestamp  The timestamp of the mouse up event
+ * @param[in]   data       The data for canvas
  */
 EAPI void evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
 
 /**
- * Mouse in event feed.
+ * @internal
+ * @brief   Feeds the mouse in event for the given canvas @a e.
  *
- * @param e The given canvas pointer.
- * @param timestamp The timestamp of the mouse up event.
- * @param data The data for canvas.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function will set some evas properties that is necessary when
- * the mouse in event happens. It prepares information to be treated
- * by the callback function.
+ * @remarks This function sets some evas properties that is necessary when
+ *          the mouse in event happens. It prepares information to be treated
+ *          by the callback function.
  *
+ * @param[in]   e          The given canvas pointer
+ * @param[in]   timestamp  The timestamp of the mouse up event
+ * @param[in]   data       The data for canvas
  */
 EAPI void evas_event_feed_mouse_in(Evas *e, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
 
 /**
- * Mouse out event feed.
+ * @internal
+ * @brief   Feeds the mouse out event for the given canvas @a e.
  *
- * @param e The given canvas pointer.
- * @param timestamp Timestamp of the mouse up event.
- * @param data The data for canvas.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function will set some evas properties that is necessary when
- * the mouse out event happens. It prepares information to be treated
- * by the callback function.
+ * @remarks This function sets some evas properties that is necessary when
+ *          the mouse out event happens. It prepares information to be treated
+ *          by the callback function.
  *
+ * @param[in]   e          The given canvas pointer
+ * @param[in]   timestamp  The timestamp of the mouse up event
+ * @param[in]   data       The data for canvas
  */
 EAPI void evas_event_feed_mouse_out(Evas *e, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
 EAPI void evas_event_feed_multi_down(Evas *e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, Evas_Button_Flags flags, unsigned int timestamp, const void *data);
@@ -2633,173 +2958,211 @@ EAPI void evas_event_feed_multi_up(Evas *e, int d, int x, int y, double rad, dou
 EAPI void evas_event_feed_multi_move(Evas *e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, unsigned int timestamp, const void *data);
 
 /**
- * Mouse cancel event feed.
- *
- * @param e The given canvas pointer.
- * @param timestamp The timestamp of the mouse up event.
- * @param data The data for canvas.
+ * @internal
+ * @brief   Feeds the mouse cancel event for the given canvas @a e.
  *
- * This function will call evas_event_feed_mouse_up() when a
- * mouse cancel event happens.
+ * @remarks This function calls evas_event_feed_mouse_up() when a
+ *          mouse cancel event happens.
  *
+ * @param   e          The given canvas pointer
+ * @param   timestamp  The timestamp of the mouse up event
+ * @param   data       The data for canvas
  */
 EAPI void evas_event_feed_mouse_cancel(Evas *e, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
 
 /**
- * Mouse wheel event feed.
+ * @internal
+ * @brief   Feeds the mouse wheel event for the given canvas @a e.
  *
- * @param e The given canvas pointer.
- * @param direction The wheel mouse direction.
- * @param z How much mouse wheel was scrolled up or down.
- * @param timestamp The timestamp of the mouse up event.
- * @param data The data for canvas.
- *
- * This function will set some evas properties that is necessary when
- * the mouse wheel is scrolled up or down. It prepares information to
- * be treated by the callback function.
+ * @remarks This function sets some evas properties that is necessary when
+ *          the mouse wheel is scrolled up or down. It prepares information to
+ *          be treated by the callback function.
  *
+ * @param   e          The given canvas pointer
+ * @param   direction  The wheel mouse direction
+ * @param   z          The amount of up or down mouse wheel scrolling 
+ * @param   timestamp  The timestamp of the mouse up event
+ * @param   data       The data for canvas
  */
 EAPI void evas_event_feed_mouse_wheel(Evas *e, int direction, int z, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
 
 /**
- * Key down event feed
- *
- * @param e The canvas to thaw out
- * @param keyname  Name of the key
- * @param key The key pressed.
- * @param string A String
- * @param compose The compose string
- * @param timestamp Timestamp of the mouse up event
- * @param data Data for canvas.
+ * @internal
+ * @brief   Feeds the key down event for the given canvas @a e.
  *
- * This function will set some evas properties that is necessary when
- * a key is pressed. It prepares information to be treated by the
- * callback function.
+ * @remarks This function sets some evas properties that is necessary when
+ *          a key is pressed. It prepares information to be treated by the
+ *          callback function.
  *
+ * @param   e          The canvas to thaw out
+ * @param   keyname    The name of the key
+ * @param   key        The key pressed
+ * @param   string     The UTF8 string
+ * @param   compose    The compose string
+ * @param   timestamp  The timestamp of the mouse up event
+ * @param   data       The data for canvas
  */
 EAPI void evas_event_feed_key_down(Evas *e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
 
 /**
- * Key up event feed
+ * @internal
+ * @brief   Feeds the key up event feed  for the given canvas @a e.
  *
- * @param e The canvas to thaw out
- * @param keyname  Name of the key
- * @param key The key released.
- * @param string string
- * @param compose compose
- * @param timestamp Timestamp of the mouse up event
- * @param data Data for canvas.
- *
- * This function will set some evas properties that is necessary when
- * a key is released. It prepares information to be treated by the
- * callback function.
+ * @remarks This function sets some evas properties that is necessary when
+ *          a key is released. It prepares information to be treated by the
+ *          callback function.
  *
+ * @param   e          The canvas to thaw out
+ * @param   keyname    The name of the key
+ * @param   key        The key released
+ * @param   string     The UTF8 string
+ * @param   compose    The compose string
+ * @param   timestamp  The timestamp of the mouse up event
+ * @param   data       The data for canvas
  */
 EAPI void evas_event_feed_key_up(Evas *e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
 
 /**
- * Hold event feed
+ * @internal
+ * @brief   Feeds the hold event for the given canvas @a e.
  *
- * @param e The given canvas pointer.
- * @param hold The hold.
- * @param timestamp The timestamp of the mouse up event.
- * @param data The data for canvas.
+ * @remarks This function makes the object to stop sending events.
  *
- * This function makes the object to stop sending events.
+ * @param   e          The given canvas pointer
+ * @param   hold       The hold
+ * @param   timestamp  The timestamp of the mouse up event
+ * @param   data       The data for canvas
  *
  */
 EAPI void evas_event_feed_hold(Evas *e, int hold, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1);
 
 /**
- * Re feed event.
+ * @internal
+ * @brief   Re-feeds the event for the given canvas @a e.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The given canvas pointer.
- * @param event_copy the event to refeed
- * @param event_type Event type
+ * @remarks This function re-feeds the event pointed by event_copy.
  *
- * This function re-feeds the event pointed by event_copy
+ * @remarks This function call evas_event_feed_* functions, so it can
+ *          cause havoc if not used wisely. Please use it responsibly.
  *
- * This function call evas_event_feed_* functions, so it can
- * cause havoc if not used wisely. Please use it responsibly.
+ * @param[in]   e           The given canvas pointer
+ * @param[in]   event_copy  The event to re-feed
+ * @param[in]   event_type  The event type 
  */
 EAPI void evas_event_refeed_event(Evas *e, void *event_copy, Evas_Callback_Type event_type) EINA_ARG_NONNULL(1);
 
 /**
- * @}
+ * @internal
+ * @brief   Gets a list of Evas objects lying over a given position in a canvas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks This function traverses all the layers of the given canvas,
+ *          from top to bottom, querying for objects with areas covering the
+ *          given position. It enters the smart objects.
+ *
+ * @param[in]   eo_e     A handle to the canvas
+ * @param[in]   stop  The Evas object at which to stop searching
+ * @param[in]   x     The horizontal coordinate of the position
+ * @param[in]   y     The vertical coordinate of the position
  */
+EAPI Eina_List *evas_tree_objects_at_xy_get(Evas *eo_e, Evas_Object *stop, int x, int y) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
  * @}
  */
 
 /**
+ * @internal
  * @defgroup Evas_Image_Group Image Functions
+ * @ingroup Evas_Canvas
  *
- * Functions that deals with images at canvas level.
+ * @brief This group provides functions that deals with images at canvas level.
  *
- * @ingroup Evas_Canvas
- */
-
-/**
- * @addtogroup Evas_Image_Group
  * @{
  */
 
 /**
- * Flush the image cache of the canvas.
+ * @brief   Flushes the image cache of the canvas.
+ *
+ * @details This function flushes image cache of canvas.
  *
- * @param e The given evas pointer.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function flushes image cache of canvas.
+ * @param[in]   e  The given evas pointer
  *
  */
 EAPI void      evas_image_cache_flush(Evas *e) EINA_ARG_NONNULL(1);
 
 /**
- * Reload the image cache
+ * @brief   Reloads the image cache.
  *
- * @param e The given evas pointer.
+ * @details This function reloads the image cache of canvas. 
  *
- * This function reloads the image cache of canvas.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e  The given evas pointer
  *
  */
 EAPI void      evas_image_cache_reload(Evas *e) EINA_ARG_NONNULL(1);
 
 /**
- * Set the image cache.
+ * @brief   Sets the image cache.
  *
- * @param e The given evas pointer.
- * @param size The cache size.
+ * @details This function sets the image cache of canvas in bytes.
  *
- * This function sets the image cache of canvas in bytes.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
+ * @param[in]   e     The given evas pointer
+ * @param[in]   size  The cache size
  */
 EAPI void      evas_image_cache_set(Evas *e, int size) EINA_ARG_NONNULL(1);
 
 /**
- * Get the image cache
+ * @brief   Gets the image cache
  *
- * @param e The given evas pointer.
+ * @details This function returns the image cache size of canvas in bytes. 
  *
- * This function returns the image cache size of canvas in bytes.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
+ * @param[in]   e  The given evas pointer
+ * @return  The image cache size of canvas in bytes
  */
 EAPI int       evas_image_cache_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Get the maximum image size evas can possibly handle
+ * @brief   Gets the maximum image size evas can possibly handle.
+ * @since   1.1
  *
- * @param e The given evas pointer.
- * @param maxw Pointer to hold the return value in pixels of the maxumum width
- * @param maxh Pointer to hold the return value in pixels of the maximum height
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function returns the larges image or surface size that evas can handle
- * in pixels, and if there is one, returns @c EINA_TRUE. It returns
- * @c EINA_FALSE if no extra constraint on maximum image size exists. You still
- * should check the return values of @p maxw and @p maxh as there may still be
- * a limit, just a much higher one.
+ * @remarks This function returns the largest image or surface size that evas can handle
+ *          in pixels, and if there is one, returns #EINA_TRUE. It returns
+ *          #EINA_FALSE if no extra constraint on maximum image size exists. You still
+ *          should check the return values of @a maxw and @a maxh as there may still be
+ *          a limit, just a much higher one.
  *
- * @since 1.1
+ * @param[in]   e     The given evas pointer
+ * @param[out]   maxw  The pointer to hold the return value in pixels of the maximum width
+ * @param[out]   maxh  The pointer to hold the return value in pixels of the maximum height
+ * @return  #EINA_TRUE if there is a maximum size that evas can handle, \n
+ *          otherwise #EINA_FALSE if there is no maximum image size constraint
  */
 EAPI Eina_Bool evas_image_max_size_get(const Evas *e, int *maxw, int *maxh) EINA_ARG_NONNULL(1);
 
@@ -2808,306 +3171,434 @@ EAPI Eina_Bool evas_image_max_size_get(const Evas *e, int *maxw, int *maxh) EINA
  */
 
 /**
+ * @internal
  * @defgroup Evas_Font_Group Font Functions
  *
- * Functions that deals with fonts.
+ * @brief This group provides functions that deals with fonts.
  *
  * @ingroup Evas_Canvas
+ *
+ * @{
  */
 
 /**
- * Changes the font hinting for the given evas.
+ * @brief   Changes the font hinting for the given evas.
  *
- * @param e The given evas.
- * @param hinting The hinting to use, one of #EVAS_FONT_HINTING_NONE,
- *        #EVAS_FONT_HINTING_AUTO, #EVAS_FONT_HINTING_BYTECODE.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e       The given evas
+ * @param[in]   hinting The hinting to use \n
+ *                  Valid values are #EVAS_FONT_HINTING_NONE,
+ *                  #EVAS_FONT_HINTING_AUTO, and #EVAS_FONT_HINTING_BYTECODE.
  * @ingroup Evas_Font_Group
  */
 EAPI void                    evas_font_hinting_set(Evas *e, Evas_Font_Hinting_Flags hinting) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the font hinting used by the given evas.
+ * @brief   Gets the font hinting used by the given evas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The given evas to query.
- * @return The hinting in use, one of #EVAS_FONT_HINTING_NONE,
- *         #EVAS_FONT_HINTING_AUTO, #EVAS_FONT_HINTING_BYTECODE.
+ * @param[in]   e  The given evas to query
+ * @return  The hinting in use \n
+ *          Valid return values are #EVAS_FONT_HINTING_NONE,
+ *         #EVAS_FONT_HINTING_AUTO, and #EVAS_FONT_HINTING_BYTECODE.
  * @ingroup Evas_Font_Group
  */
 EAPI Evas_Font_Hinting_Flags evas_font_hinting_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Checks if the font hinting is supported by the given evas.
+ * @brief   Checks whether the font hinting is supported by the given evas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The given evas to query.
- * @param hinting The hinting to use, one of #EVAS_FONT_HINTING_NONE,
- *        #EVAS_FONT_HINTING_AUTO, #EVAS_FONT_HINTING_BYTECODE.
- * @return @c EINA_TRUE if it is supported, @c EINA_FALSE otherwise.
+ * @param[in]   e        The given evas to query
+ * @param[in]   hinting  The hinting to use \n
+ *                   Valid values are #EVAS_FONT_HINTING_NONE,
+ *                   #EVAS_FONT_HINTING_AUTO, and #EVAS_FONT_HINTING_BYTECODE.
+ * @return  #EINA_TRUE if it is supported, \n
+ *          otherwise #EINA_FALSE
  * @ingroup Evas_Font_Group
  */
 EAPI Eina_Bool               evas_font_hinting_can_hint(const Evas *e, Evas_Font_Hinting_Flags hinting) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Force the given evas and associated engine to flush its font cache.
+ * @brief   Forces the given evas and associated engine to flush its font cache.
  *
- * @param e The given evas to flush font cache.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e  The given evas to flush font cache
  * @ingroup Evas_Font_Group
  */
 EAPI void                    evas_font_cache_flush(Evas *e) EINA_ARG_NONNULL(1);
 
 /**
- * Changes the size of font cache of the given evas.
+ * @brief   Changes the size of font cache of the given evas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The given evas to flush font cache.
- * @param size The size, in bytes.
+ * @param[in]   e     The given evas to flush font cache
+ * @param[in]   size  The size in bytes
  *
  * @ingroup Evas_Font_Group
  */
 EAPI void                    evas_font_cache_set(Evas *e, int size) EINA_ARG_NONNULL(1);
 
 /**
- * Changes the size of font cache of the given evas.
+ * @brief   Changes the size of font cache of the given evas.
  *
- * @param e The given evas to flush font cache.
- * @return The size, in bytes.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e  The given evas to flush font cache
+ * @return  The size in bytes
  *
  * @ingroup Evas_Font_Group
  */
 EAPI int                     evas_font_cache_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * List of available font descriptions known or found by this evas.
+ * @brief   Gets the list of available font descriptions known or found by this evas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * The list depends on Evas compile time configuration, such as
- * fontconfig support, and the paths provided at runtime as explained
- * in @ref Evas_Font_Path_Group.
+ * @remarks The list depends on Evas compile time configuration, such as
+ *          fontconfig support, and the paths provided at runtime as explained
+ *          in @ref Evas_Font_Path_Group.
  *
- * @param e The evas instance to query.
- * @return a newly allocated list of strings. Do not change the
- *         strings.  Be sure to call evas_font_available_list_free()
- *         after you're done.
+ * @param[in]   e  The evas instance to query
+ * @return  The newly allocated list of strings \n 
+ *          Do not change the strings. Be sure to call evas_font_available_list_free()
+ *          after you are done.
  *
  * @ingroup Evas_Font_Group
  */
 EAPI Eina_List              *evas_font_available_list(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Free list of font descriptions returned by evas_font_dir_available_list().
+ * @brief   Frees the list of font descriptions returned by evas_font_dir_available_list().
  *
- * @param e The evas instance that returned such list.
- * @param available the list returned by evas_font_dir_available_list().
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e          The evas instance that returned such list
+ * @param[in]   available  The list returned by evas_font_dir_available_list()
  *
  * @ingroup Evas_Font_Group
  */
 EAPI void                    evas_font_available_list_free(Evas *e, Eina_List *available) EINA_ARG_NONNULL(1);
 
 /**
+ * @brief  Reinitializes Evas by orphaning existing font data until it is unreferenced and
+ *         starts with a fresh font configuration read from any appropriate
+ *         system resources for all newly loaded and created fonts.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @ingroup Evas_Font_Group
+ */
+EAPI void                    evas_font_reinit(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @internal
  * @defgroup Evas_Font_Path_Group Font Path Functions
  *
- * Functions that edit the paths being used to load fonts.
+ * @brief   This group provides functions that edit the paths being used to load fonts.
  *
  * @ingroup Evas_Font_Group
+ *
+ * @{
  */
 
 /**
- * Removes all font paths loaded into memory for the given evas.
- * @param   e The given evas.
+ * @brief   Removes all font paths loaded into memory for the given evas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e  The given evas
  * @ingroup Evas_Font_Path_Group
  */
 EAPI void                    evas_font_path_clear(Evas *e) EINA_ARG_NONNULL(1);
 
 /**
- * Appends a font path to the list of font paths used by the given evas.
- * @param   e    The given evas.
- * @param   path The new font path.
+ * @brief   Appends a font path to the list of font paths used by the given evas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e     The given evas
+ * @param[in]   path  The new font path
  * @ingroup Evas_Font_Path_Group
  */
 EAPI void                    evas_font_path_append(Evas *e, const char *path) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Prepends a font path to the list of font paths used by the given evas.
- * @param   e The given evas.
- * @param   path The new font path.
+ * @brief   Prepends a font path to the list of font paths used by the given evas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e     The given evas
+ * @param[in]   path  The new font path
  * @ingroup Evas_Font_Path_Group
  */
 EAPI void                    evas_font_path_prepend(Evas *e, const char *path) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Retrieves the list of font paths used by the given evas.
- * @param   e The given evas.
- * @return  The list of font paths used.
+ * @brief   Gets the list of font paths used by the given evas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e  The given evas
+ * @return  The list of font paths used
  * @ingroup Evas_Font_Path_Group
  */
 EAPI const Eina_List        *evas_font_path_list(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * @defgroup Evas_Object_Group Generic Object Functions
+ * @brief   Removes all font paths loaded into memory by evas_font_path_app_* APIs for the application.
+ * @since   1.9
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @ingroup Evas_Font_Path_Group
+ */
+EAPI void                    evas_font_path_global_clear(void);
+
+/**
+ * @brief   Appends a font path to the list of font paths used by the application.
+ * @since   1.9
  *
- * Functions that manipulate generic Evas objects.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * All Evas displaying units are Evas objects. One handles them all by
- * means of the handle ::Evas_Object. Besides Evas treats their
- * objects equally, they have @b types, which define their specific
- * behavior (and individual API).
+ * @param[in]   path  The new font path
+ * @ingroup Evas_Font_Path_Group
+ */
+EAPI void                    evas_font_path_global_append(const char *path) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief   Prepends a font path to the list of font paths used by the application.
+ * @since   1.9
  *
- * Evas comes with a set of built-in object types:
- *   - rectangle,
- *   - line,
- *   - polygon,
- *   - text,
- *   - textblock and
- *   - image.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   path  The new font path
+ * @ingroup Evas_Font_Path_Group
+ */
+EAPI void                    evas_font_path_global_prepend(const char *path) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief   Gets the list of font paths used by the application.
+ * @since   1.9
  *
- * These functions apply to @b any Evas object, whichever type that
- * may have.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note The built-in types which are most used are rectangles, text
- * and images. In fact, with these ones one can create 2D interfaces
- * of arbitrary complexity and EFL makes it easy.
+ * @return  The list of font paths used
+ * @ingroup Evas_Font_Path_Group
  */
+EAPI const Eina_List        *evas_font_path_global_list(void) EINA_WARN_UNUSED_RESULT;
 
 /**
- * @defgroup Evas_Object_Group_Basic Basic Object Manipulation
+ * @}
+ */
+
+/**
+ * @defgroup Evas_Object_Group Generic Object Functions
+   @ingroup Evas
  *
- * Almost every evas object created will have some generic function used to
- * manipulate it. That's because there are a number of basic actions to be done
- * to objects that are irrespective of the object's type, things like:
- * @li Showing/Hiding
- * @li Setting(and getting) geometry
- * @li Bring up or down a layer
- * @li Color management
- * @li Handling focus
- * @li Clipping
- * @li Reference counting
- *
- * All of this issues are handled through the functions here grouped. Examples
- * of these function can be seen in @ref Example_Evas_Object_Manipulation(which
- * deals with the most common ones) and in @ref Example_Evas_Stacking(which
- * deals with stacking functions).
+ * @brief   This group provides functions that manipulate generic Evas objects.
  *
- * @ingroup Evas_Object_Group
+ * @remarks All Evas displaying units are Evas objects. You can handle them all by
+ *          means of the handle ::Evas_Object. Besides Evas treats their
+ *          objects equally, they have @b types, which define their specific
+ *          behavior (and individual API).
+ *
+ * @remarks Evas comes with a set of built-in object types:
+ *          - rectangle,
+ *          - line,
+ *          - polygon,
+ *          - text,
+ *          - textblock, and
+ *          - image.
+ *
+ * @remarks These functions apply to @b any Evas object, whichever type that
+ *          may have.
+ *
+ * @remarks The built-in types which are most used are rectangles, text
+ *          and images. In fact, with these ones one can create 2D interfaces
+ *          of arbitrary complexity and EFL makes it easy.
  */
 
 /**
- * @addtogroup Evas_Object_Group_Basic
+ * @defgroup Evas_Object_Group_Basic Basic Object Manipulation
+ * @ingroup Evas_Object_Group
+ *
+ * @brief   This group provides functions for basic object manipulation.
+ *
+ * @remarks Almost every evas object created has some generic function used to
+ *          manipulate it. That is because there are a number of basic actions to be done
+ *          to objects that are irrespective of the object's type like:
+ *          @li Showing/Hiding
+ *          @li Setting(and getting) geometry
+ *          @li Bring up or down a layer
+ *          @li Color management
+ *          @li Handling focus
+ *          @li Clipping
+ *          @li Reference counting
+ *
  * @{
  */
 
 /**
- * Clip one object to another.
+ * @brief   Clips one object to another.
  *
- * @param obj The object to be clipped
- * @param clip The object to clip @p obj by
+ * @details This function clips the object @a obj to the area occupied by
+ *          the object @a clip. This means the object @a obj is only
+ *          visible within the area occupied by the clipping object (@a clip).
  *
- * This function will clip the object @p obj to the area occupied by
- * the object @p clip. This means the object @p obj will only be
- * visible within the area occupied by the clipping object (@p clip).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * The color of the object being clipped will be multiplied by the
- * color of the clipping one, so the resulting color for the former
- * will be <code>RESULT = (OBJ * CLIP) / (255 * 255)</code>, per color
- * element (red, green, blue and alpha).
+ * @remarks The color of the object being clipped is multiplied by the
+ *          color of the clipping one, so the resulting color for the former
+ *          is <code>RESULT = (OBJ * CLIP) / (255 * 255)</code>, per color
+ *          element (red, green, blue and alpha).
  *
- * Clipping is recursive, so clipping objects may be clipped by
- * others, and their color will in term be multiplied. You may @b not
- * set up circular clipping lists (i.e. object 1 clips object 2, which
- * clips object 1): the behavior of Evas is undefined in this case.
+ * @remarks Clipping is recursive, so clipping objects may be clipped by
+ *          others, and their color is in term multiplied. You may @b not
+ *          set up circular clipping lists (i.e. object 1 clips object 2, which
+ *          clips object 1): the behavior of Evas is undefined in this case.
  *
- * Objects which do not clip others are visible in the canvas as
- * normal; <b>those that clip one or more objects become invisible
- * themselves</b>, only affecting what they clip. If an object ceases
- * to have other objects being clipped by it, it will become visible
- * again.
+ * @remarks Objects which do not clip others are visible in the canvas as
+ *          normal; <b>those that clip one or more objects become invisible
+ *          themselves</b>, only affecting what they clip. If an object ceases
+ *          to have other objects being clipped by it, it becomes visible
+ *          again.
  *
- * The visibility of an object affects the objects that are clipped by
- * it, so if the object clipping others is not shown (as in
- * evas_object_show()), the objects clipped by it will not be shown
- * either.
+ * @remarks The visibility of an object affects the objects that are clipped by
+ *          it, so if the object clipping others is not shown (as in
+ *          evas_object_show()), the objects clipped by it is not shown
+ *          either.
  *
- * If @p obj was being clipped by another object when this function is
- * called, it gets implicitly removed from the old clipper's domain
- * and is made now to be clipped by its new clipper.
+ * @remarks If @a obj is being clipped by another object when this function is
+ *          called, it gets implicitly removed from the old clipper's domain
+ *          and is made now to be clipped by its new clipper.
  *
- * The following figure illustrates some clipping in Evas:
+ * @remarks The following figure illustrates some clipping in Evas:
  *
  * @image html clipping.png
  * @image rtf clipping.png
  * @image latex clipping.eps
  *
- * @note At the moment the <b>only objects that can validly be used to
- * clip other objects are rectangle objects</b>. All other object
- * types are invalid and the result of using them is undefined. The
- * clip object @p clip must be a valid object, but can also be @c
- * NULL, in which case the effect of this function is the same as
- * calling evas_object_clip_unset() on the @p obj object.
- *
- * Example:
- * @dontinclude evas-object-manipulation.c
- * @skip solid white clipper (note that it's the default color for a
- * @until evas_object_show(d.clipper);
+ * @remarks At the moment the <b>only objects that can validly be used to
+ *          clip other objects are rectangle objects</b>. All other object
+ *          types are invalid and the result of using them is undefined. The
+ *          clip object @a clip must be a valid object, but can also be @c
+ *          NULL, in which case the effect of this function is the same as
+ *          calling evas_object_clip_unset() on the @a obj object.
  *
- * See the full @ref Example_Evas_Object_Manipulation "example".
+ * @param[in]   obj   The object to be clipped
+ * @param[in]   clip  The object to clip @a obj by
  */
 EAPI void             evas_object_clip_set(Evas_Object *obj, Evas_Object *clip) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Get the object clipping @p obj (if any).
- *
- * @param obj The object to get the clipper from
+ * @brief   Gets the object clipping @a obj (if any).
  *
- * This function returns the object clipping @p obj. If @p obj is
- * not being clipped at all, @c NULL is returned. The object @p obj
- * must be a valid ::Evas_Object.
+ * @details This function returns the object clipping @a obj. If @a obj is
+ *          not being clipped at all, @c NULL is returned. The object @a obj
+ *          must be a valid ::Evas_Object.
  *
- * See also evas_object_clip_set(), evas_object_clip_unset() and
- * evas_object_clipees_get().
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Example:
- * @dontinclude evas-object-manipulation.c
- * @skip if (evas_object_clip_get(d.img) == d.clipper)
- * @until return
+ * @remarks See also evas_object_clip_set(), evas_object_clip_unset() and
+ *          evas_object_clipees_get().
  *
- * See the full @ref Example_Evas_Object_Manipulation "example".
+ * @param[in]   obj  The object to get the clipper from
+ * @return  The object clipping @a obj \n
+ *          If @a obj object is not being clipped, @c NULL is returned.
  */
 EAPI Evas_Object     *evas_object_clip_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Disable/cease clipping on a clipped @p obj object.
+ * @brief   Disables or ceases clipping on a clipped @a obj object.
  *
- * @param obj The object to cease clipping on
+ * @details This function disables clipping for the object @a obj, if it is
+ *          already clipped, i.e., its visibility and color get detached from
+ *          the previous clipper. If it is not already clipped, this has no effect. The object
+ *          @a obj must be a valid ::Evas_Object.
  *
- * This function disables clipping for the object @p obj, if it was
- * already clipped, i.e., its visibility and color get detached from
- * the previous clipper. If it wasn't, this has no effect. The object
- * @p obj must be a valid ::Evas_Object.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * See also evas_object_clip_set() (for an example),
- * evas_object_clipees_get() and evas_object_clip_get().
+ * @remarks See also evas_object_clip_set() (for an example),
+ *          evas_object_clipees_get() and evas_object_clip_get().
  *
+ * @param[in]   obj  The object to cease clipping on
  */
 EAPI void             evas_object_clip_unset(Evas_Object *obj);
 
 /**
- * Return a list of objects currently clipped by @p obj.
+ * @brief   Gets a list of objects currently clipped by @a obj.
  *
- * @param obj The object to get a list of clippees from
- * @return a list of objects being clipped by @p obj
+ * @details This returns the internal list handle that contains all objects
+ *          clipped by the object @a obj. If none are clipped by it, the call
+ *          returns @c NULL. This list is only valid until the clip list is
+ *          changed and should be fetched again with another call to
+ *          evas_object_clipees_get() if any objects being clipped by this
+ *          object are unclipped, clipped by a new object, deleted or get the
+ *          clipper deleted. These operations invalidate the list
+ *          returned, so it should not be used anymore after that point. Any
+ *          use of the list after this may have undefined results, possibly
+ *          leading to crashes. The object @a obj must be a valid
+ *          ::Evas_Object.
  *
- * This returns the internal list handle that contains all objects
- * clipped by the object @p obj. If none are clipped by it, the call
- * returns @c NULL. This list is only valid until the clip list is
- * changed and should be fetched again with another call to
- * evas_object_clipees_get() if any objects being clipped by this
- * object are unclipped, clipped by a new object, deleted or get the
- * clipper deleted. These operations will invalidate the list
- * returned, so it should not be used anymore after that point. Any
- * use of the list after this may have undefined results, possibly
- * leading to crashes. The object @p obj must be a valid
- * ::Evas_Object.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * See also evas_object_clip_set(), evas_object_clip_unset() and
- * evas_object_clip_get().
+ * @remarks See also evas_object_clip_set(), evas_object_clip_unset() and
+ *          evas_object_clip_get().
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas_Object *obj;
  * Evas_Object *clipper;
@@ -3124,154 +3615,149 @@ EAPI void             evas_object_clip_unset(Evas_Object *obj);
  *         evas_object_show(obj_tmp);
  *   }
  * @endcode
+ *
+ * @param[in]   obj  The object to get a list of clippees from
+ * @return  The list of objects being clipped by @a obj
  */
 EAPI const Eina_List *evas_object_clipees_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Sets or unsets a given object as the currently focused one on its
- * canvas.
+ * @brief   Sets or unsets a given object as the currently focused one on its canvas.
  *
- * @param obj The object to be focused or unfocused.
- * @param focus @c EINA_TRUE, to set it as focused or @c EINA_FALSE,
- * to take away the focus from it.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Changing focus only affects where (key) input events go. There can
- * be only one object focused at any time. If @p focus is @c EINA_TRUE,
- * @p obj will be set as the currently focused object and it will
- * receive all keyboard events that are not exclusive key grabs on
- * other objects.
+ * @remarks Changing focus only affects where (key) input events go. There can
+ *          be only one object focused at any time. If @a focus is #EINA_TRUE,
+ *          @a obj is set as the currently focused object and it
+ *          receives all keyboard events that are not exclusive key grabs on
+ *          other objects.
  *
- * Example:
- * @dontinclude evas-events.c
- * @skip evas_object_focus_set
- * @until evas_object_focus_set
- *
- * See the full example @ref Example_Evas_Events "here".
+ * @param[in]   obj    The object to be focused or unfocused
+ * @param[in]   focus  #EINA_TRUE to set it as focused, \n
+ *                 otherwise #EINA_FALSE to take away the focus from it
  *
  * @see evas_object_focus_get
- * @see evas_focus_get
  * @see evas_object_key_grab
  * @see evas_object_key_ungrab
  */
 EAPI void             evas_object_focus_set(Evas_Object *obj, Eina_Bool focus) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve whether an object has the focus.
+ * @brief   Checks whether an object has the focus.
  *
- * @param obj The object to retrieve focus information from.
- * @return @c EINA_TRUE if the object has the focus, @c EINA_FALSE otherwise.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * If the passed object is the currently focused one, @c EINA_TRUE is
- * returned. @c EINA_FALSE is returned, otherwise.
- *
- * Example:
- * @dontinclude evas-events.c
- * @skip And again
- * @until something is bad
+ * @remarks If the passed object is the currently focused one, #EINA_TRUE is
+ *          returned. #EINA_FALSE is returned, otherwise.
  *
- * See the full example @ref Example_Evas_Events "here".
+ * @param[in]   obj  The object to retrieve focus information from
+ * @return  #EINA_TRUE if the object has the focus, \n
+ *          otherwise #EINA_FALSE
  *
  * @see evas_object_focus_set
- * @see evas_focus_get
  * @see evas_object_key_grab
  * @see evas_object_key_ungrab
  */
 EAPI Eina_Bool        evas_object_focus_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Sets the layer of its canvas that the given object will be part of.
+ * @brief   Sets the layer of its canvas that the given object is part of.
  *
- * @param   obj The given Evas object.
- * @param   l   The number of the layer to place the object on.
- *          Must be between #EVAS_LAYER_MIN and #EVAS_LAYER_MAX.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * If you don't use this function, you'll be dealing with an @b unique
- * layer of objects, the default one. Additional layers are handy when
- * you don't want a set of objects to interfere with another set with
- * regard to @b stacking. Two layers are completely disjoint in that
- * matter.
+ * @remarks If you do not use this function, you are dealing with a @b unique
+ *          layer of objects, the default one. Additional layers are handy when
+ *          you do not want a set of objects to interfere with another set with
+ *          regard to @b stacking. Two layers are completely disjoint in that matter.
  *
- * This is a low-level function, which you'd be using when something
- * should be always on top, for example.
+ * @remarks This is a low-level function, which you would be using when something
+ *          should be always on top, for example.
  *
- * @warning Be careful, it doesn't make sense to change the layer of
- * smart objects' children. Smart objects have a layer of their own,
- * which should contain all their children objects.
+ * @remarks Be careful, it does not make sense to change the layer of the children of
+ *          smart objects. Smart objects have a layer of their own,
+ *          which should contain all their children objects.
+ *
+ * @param[in]   obj  The given Evas object
+ * @param[in]   l    The number of the layer to place the object on \n
+ *               This must be between #EVAS_LAYER_MIN and #EVAS_LAYER_MAX.
  *
  * @see evas_object_layer_get()
  */
 EAPI void             evas_object_layer_set(Evas_Object *obj, short l) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the layer of its canvas that the given object is part of.
+ * @brief   Gets the layer of its canvas that the given object is part of.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param   obj The given Evas object to query layer from
- * @return  Number of its layer
+ * @param[in]   obj  The given Evas object to query the layer from
+ * @return  The number of its layer
  *
  * @see evas_object_layer_set()
  */
 EAPI short            evas_object_layer_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Sets the name of the given Evas object to the given name.
+ * @brief   Sets the name of the given Evas object to the given name.
  *
- * @param   obj  The given object.
- * @param   name The given name.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * There might be occasions where one would like to name his/her
- * objects.
- *
- * Example:
- * @dontinclude evas-events.c
- * @skip d.bg = evas_object_rectangle_add(d.canvas);
- * @until evas_object_name_set(d.bg, "our dear rectangle");
+ * @remarks There might be occasions where you would like to name your objects.
  *
- * See the full @ref Example_Evas_Events "example".
+ * @param[in]   obj   The given object
+ * @param[in]   name  The given name
  */
 EAPI void             evas_object_name_set(Evas_Object *obj, const char *name) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the name of the given Evas object.
+ * @brief   Gets the name of the given Evas object.
  *
- * @param   obj The given object.
- * @return  The name of the object or @c NULL, if no name has been given
- *          to it.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Example:
- * @dontinclude evas-events.c
- * @skip fprintf(stdout, "An object got focused: %s\n",
- * @until evas_focus_get
- *
- * See the full @ref Example_Evas_Events "example".
+ * @param[in]   obj  The given object
+ * @return  The name of the object, \n
+ *          otherwise @c NULL if no name has been given to it
  */
 EAPI const char      *evas_object_name_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Increments object reference count to defer its deletion.
+ * @brief   Increments object reference count to defer its deletion.
+ * @since   1.1
  *
- * @param obj The given Evas object to reference
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This increments the reference count of an object, which if greater
- * than 0 will defer deletion by evas_object_del() until all
- * references are released back (counter back to 0). References cannot
- * go below 0 and unreferencing past that will result in the reference
- * count being limited to 0. References are limited to <c>2^32 - 1</c>
- * for an object. Referencing it more than this will result in it
- * being limited to this value.
- *
- * @see evas_object_unref()
- * @see evas_object_del()
+ * @remarks This increments the reference count of an object, which if greater
+ *          than @c 0 defers deletion by evas_object_del() until all
+ *          references are released back (counter back to @c 0). References cannot
+ *          go below @c 0 and unreferencing past that results in the reference
+ *          count being limited to @c 0. References are limited to <c>2^32 - 1</c>
+ *          for an object. Referencing it more than this results in it
+ *          being limited to this value.
  *
- * @note This is a <b>very simple</b> reference counting mechanism! For
- * instance, Evas is not ready to check for pending references on a
- * canvas deletion, or things like that. This is useful on scenarios
- * where, inside a code block, callbacks exist which would possibly
- * delete an object we are operating on afterwards. Then, one would
- * evas_object_ref() it on the beginning of the block and
- * evas_object_unref() it on the end. It would then be deleted at this
- * point, if it should be.
+ * @remarks This is a <b>very simple</b> reference counting mechanism. For
+ *          instance, Evas is not ready to check for pending references on a
+ *          canvas deletion, or things like that. This is useful on scenarios
+ *          where, inside a code block, callbacks exist which would possibly
+ *          delete an object that you are operating on afterwards. Then, you would
+ *          evas_object_ref() it on the beginning of the block and
+ *          evas_object_unref() it on the end. It would then be deleted at this
+ *          point, if it should be.
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  *  evas_object_ref(obj);
  *
@@ -3281,62 +3767,77 @@ EAPI const char      *evas_object_name_get(const Evas_Object *obj) EINA_WARN_UNU
  *  evas_object_unref(obj);
  * @endcode
  *
+ * @param[in]   obj  The given Evas object to reference
+ *
+ * @see evas_object_unref()
+ * @see evas_object_del()
  * @ingroup Evas_Object_Group_Basic
- * @since 1.1
  */
 EAPI void             evas_object_ref(Evas_Object *obj);
 
 /**
- * Decrements object reference count.
+ * @brief   Decrements object reference count.
  *
- * @param obj The given Evas object to unreference
+ * @details This decrements the reference count of an object. If the object has
+ *          had evas_object_del() called on it while references were more than
+ *          @c 0, it is deleted at the time this function is called and puts
+ *          the counter back to @c 0. See evas_object_ref() for more information.
+ * @since   1.1
  *
- * This decrements the reference count of an object. If the object has
- * had evas_object_del() called on it while references were more than
- * 0, it will be deleted at the time this function is called and puts
- * the counter back to 0. See evas_object_ref() for more information.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given Evas object to unreference
  *
  * @see evas_object_ref() (for an example)
  * @see evas_object_del()
  *
  * @ingroup Evas_Object_Group_Basic
- * @since 1.1
  */
 EAPI void             evas_object_unref(Evas_Object *obj);
 
 /**
- * Get the object reference count.
+ * @brief   Gets the object reference count.
  *
- * @param obj The given Evas object to query
+ * @details This gets the reference count for an object (normally @c 0 until it is
+ *          referenced). Values of @c 1 or greater mean that someone is holding a
+ *          reference to this object that needs to be unreffed before it can be
+ *          deleted.
+ * @since   1.2
  *
- * This gets the reference count for an object (normally 0 until it is
- * referenced). Values of 1 or greater mean that someone is holding a
- * reference to this object that needs to be unreffed before it can be
- * deleted.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given Evas object to query
+ * @return The object reference count
  *
  * @see evas_object_ref()
  * @see evas_object_unref()
  * @see evas_object_del()
  *
  * @ingroup Evas_Object_Group_Basic
- * @since 1.2
  */
 EAPI int              evas_object_ref_get(const Evas_Object *obj);
 
 /**
- * Marks the given Evas object for deletion (when Evas will free its
- * memory).
+ * @brief   Marks the given Evas object for deletion (when Evas frees its memory).
  *
- * @param obj The given Evas object.
+ * @details This call marks @a obj for deletion, which takes place
+ *          whenever it has no more references to it (see evas_object_ref() and
+ *          evas_object_unref()).
  *
- * This call will mark @p obj for deletion, which will take place
- * whenever it has no more references to it (see evas_object_ref() and
- * evas_object_unref()).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * At actual deletion time, which may or may not be just after this
- * call, ::EVAS_CALLBACK_DEL and ::EVAS_CALLBACK_FREE callbacks will
- * be called. If the object currently had the focus, its
- * ::EVAS_CALLBACK_FOCUS_OUT callback will also be called.
+ * @remarks At actual deletion time, which may or may not be just after this
+ *          call, ::EVAS_CALLBACK_DEL and ::EVAS_CALLBACK_FREE callbacks are
+ *          called. If the object currently had the focus, its
+ *          ::EVAS_CALLBACK_FOCUS_OUT callback is also called.
+ *
+ * @param[in]   obj  The given Evas object
  *
  * @see evas_object_ref()
  * @see evas_object_unref()
@@ -3346,55 +3847,48 @@ EAPI int              evas_object_ref_get(const Evas_Object *obj);
 EAPI void             evas_object_del(Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Move the given Evas object to the given location inside its
- * canvas' viewport.
- *
- * @param obj The given Evas object.
- * @param x   X position to move the object to, in canvas units.
- * @param y   Y position to move the object to, in canvas units.
+ * @brief   Moves the given Evas object to the given location inside its canvas' viewport.
  *
- * Besides being moved, the object's ::EVAS_CALLBACK_MOVE callback
- * will be called.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note Naturally, newly created objects are placed at the canvas'
- * origin: <code>0, 0</code>.
+ * @remarks Besides being moved, the object's ::EVAS_CALLBACK_MOVE callback is called.
  *
- * Example:
- * @dontinclude evas-object-manipulation.c
- * @skip evas_object_image_border_set(d.clipper_border, 3, 3, 3, 3);
- * @until evas_object_show
+ * @remarks Naturally, newly created objects are placed at the canvas' origin: <code>0, 0</code>.
  *
- * See the full @ref Example_Evas_Object_Manipulation "example".
+ * @param[in]   obj  The given Evas object
+ * @param[in]   x    The X position to move the object to, in canvas units
+ * @param[in]   y    The Y position to move the object to, in canvas units
  *
  * @ingroup Evas_Object_Group_Basic
  */
 EAPI void             evas_object_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
 
 /**
- * Changes the size of the given Evas object.
+ * @brief   Changes the size of the given Evas object.
  *
- * @param obj The given Evas object.
- * @param w   The new width of the Evas object.
- * @param h   The new height of the Evas object.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Besides being resized, the object's ::EVAS_CALLBACK_RESIZE callback
- * will be called.
+ * @remarks Besides being resized, the object's ::EVAS_CALLBACK_RESIZE callback
+ *          is called.
  *
- * @note Newly created objects have zeroed dimensions. Then, you most
- * probably want to use evas_object_resize() on them after they are
- * created.
+ * @remarks Newly created objects have zeroed dimensions. Then, you most
+ *          probably want to use evas_object_resize() on them after they are
+ *          created.
  *
- * @note Be aware that resizing an object changes its drawing area,
- * but that does imply the object is rescaled! For instance, images
- * are filled inside their drawing area using the specifications of
- * evas_object_image_fill_set(). Thus to scale the image to match
- * exactly your drawing area, you need to change the
- * evas_object_image_fill_set() as well.
+ * @remarks Be aware that resizing an object changes its drawing area,
+ *          but that does imply the object is rescaled. For instance, images
+ *          are filled inside their drawing area using the specifications of
+ *          evas_object_image_fill_set(). Thus to scale the image to match
+ *          exactly your drawing area, you need to change the
+ *          evas_object_image_fill_set() as well.
  *
- * @note This is more evident in images, but text, textblock, lines
- * and polygons will behave similarly. Check their specific APIs to
- * know how to achieve your desired behavior. Consider the following
- * example:
+ * @remarks This is more evident in images, but text, textblock, lines
+ *          and polygons behave similarly. Check their specific APIs to
+ *          know how to achieve your desired behavior. Consider the following example:
  *
  * @code
  * // rescale image to fill exactly its area without tiling:
@@ -3402,48 +3896,49 @@ EAPI void             evas_object_move(Evas_Object *obj, Evas_Coord x, Evas_Coor
  * evas_object_image_fill_set(img, 0, 0, w, h);
  * @endcode
  *
+ * @param[in]   obj  The given Evas object
+ * @param[in]   w    The new width of the Evas object
+ * @param[in]   h    The new height of the Evas object
  * @ingroup Evas_Object_Group_Basic
  */
 EAPI void             evas_object_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the position and (rectangular) size of the given Evas
- * object.
- *
- * @param obj The given Evas object.
- * @param x Pointer to an integer in which to store the X coordinate
- *          of the object.
- * @param y Pointer to an integer in which to store the Y coordinate
- *          of the object.
- * @param w Pointer to an integer in which to store the width of the
- *          object.
- * @param h Pointer to an integer in which to store the height of the
- *          object.
+ * @brief   Gets the position and (rectangular) size of the given Evas object.
  *
- * The position, naturally, will be relative to the top left corner of
- * the canvas' viewport.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note Use @c NULL pointers on the geometry components you're not
- * interested in: they'll be ignored by the function.
+ * @remarks The position is relative to the top left corner of
+ *          the canvas' viewport.
  *
- * Example:
- * @dontinclude evas-events.c
- * @skip int w, h, cw, ch;
- * @until return
+ * @remarks Use @c NULL pointers on the geometry components you are not
+ *          interested in: they are ignored by the function.
  *
- * See the full @ref Example_Evas_Events "example".
+ * @param[in]   obj  The given Evas object
+ * @param[out]   x    The pointer to an integer in which to store the X coordinate
+ *               of the object
+ * @param[out]   y    The pointer to an integer in which to store the Y coordinate
+ *               of the object
+ * @param[out]   w    The pointer to an integer in which to store the width of the object
+ * @param[out]   h    The pointer to an integer in which to store the height of the object
  *
  * @ingroup Evas_Object_Group_Basic
  */
 EAPI void             evas_object_geometry_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
 
 /**
- * Makes the given Evas object visible.
+ * @brief   Makes the given Evas object visible.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given Evas object.
+ * @remarks Besides becoming visible, the object's ::EVAS_CALLBACK_SHOW
+ *          callback are called.
  *
- * Besides becoming visible, the object's ::EVAS_CALLBACK_SHOW
- * callback will be called.
+ * @param[in]   obj  The given Evas object
  *
  * @see evas_object_hide() for more on object visibility.
  * @see evas_object_visible_get()
@@ -3453,50 +3948,50 @@ EAPI void             evas_object_geometry_get(const Evas_Object *obj, Evas_Coor
 EAPI void             evas_object_show(Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Makes the given Evas object invisible.
+ * @brief   Makes the given Evas object invisible.
  *
- * @param obj The given Evas object.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Hidden objects, besides not being shown at all in your canvas,
- * won't be checked for changes on the canvas rendering
- * process. Furthermore, they will not catch input events. Thus, they
- * are much ligher (in processing needs) than an object that is
- * invisible due to indirect causes, such as being clipped or out of
- * the canvas' viewport.
+ * @remarks Hidden objects, besides not being shown at all in your canvas,
+ *          are not checked for changes on the canvas rendering
+ *          process. Furthermore, they do not catch input events. Thus, they
+ *          are much lighter (in processing needs) than an object that is
+ *          invisible due to indirect causes, such as being clipped or out of
+ *          the canvas' viewport.
  *
- * Besides becoming hidden, @p obj object's ::EVAS_CALLBACK_SHOW
- * callback will be called.
+ * @remarks Besides becoming hidden, @a obj object's ::EVAS_CALLBACK_SHOW
+ *          callback is called.
  *
- * @note All objects are created in the hidden state! If you want them
- * shown, use evas_object_show() after their creation.
+ * @remarks All objects are created in the hidden state. If you want to
+ *          show them, use evas_object_show() after their creation.
+ *
+ * @param[in]   obj  The given Evas object
  *
  * @see evas_object_show()
  * @see evas_object_visible_get()
- *
- * Example:
- * @dontinclude evas-object-manipulation.c
- * @skip if (evas_object_visible_get(d.clipper))
- * @until return
- *
- * See the full @ref Example_Evas_Object_Manipulation "example".
- *
  * @ingroup Evas_Object_Group_Basic
  */
 EAPI void             evas_object_hide(Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves whether or not the given Evas object is visible.
+ * @brief   Checks whether the given Evas object is visible.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param   obj The given Evas object.
- * @return @c EINA_TRUE if the object is visible, @c EINA_FALSE
- * otherwise.
+ * @details This retrieves an object's visibility as the one enforced by
+ *          evas_object_show() and evas_object_hide().
  *
- * This retrieves an object's visibility as the one enforced by
- * evas_object_show() and evas_object_hide().
+ * @remarks The value returned is not, by any means, influenced by
+ *          clippers covering @a obj, it being out of its canvas' viewport or
+ *          stacked below other object.
  *
- * @note The value returned isn't, by any means, influenced by
- * clippers covering @p obj, it being out of its canvas' viewport or
- * stacked below other object.
+ * @param[in]   obj  The given Evas object
+ * @return  #EINA_TRUE if the object is visible, \n
+ *          otherwise #EINA_FALSE if the object is not visible
  *
  * @see evas_object_show()
  * @see evas_object_hide() (for an example)
@@ -3506,113 +4001,121 @@ EAPI void             evas_object_hide(Evas_Object *obj) EINA_ARG_NONNULL(1);
 EAPI Eina_Bool        evas_object_visible_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Sets the general/main color of the given Evas object to the given
- * one.
+ * @brief   Sets the general or main color of the given Evas object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks These color values are expected to be premultiplied by @a a.
  *
- * @param obj The given Evas object.
- * @param r   The red component of the given color.
- * @param g   The green component of the given color.
- * @param b   The blue component of the given color.
- * @param a   The alpha component of the given color.
+ * @param[in]   obj  The given Evas object
+ * @param[in]   r    The red component of the given color
+ * @param[in]   g    The green component of the given color
+ * @param[in]   b    The blue component of the given color
+ * @param[in]   a    The alpha component of the given color
  *
  * @see evas_object_color_get() (for an example)
- * @note These color values are expected to be premultiplied by @p a.
  *
  * @ingroup Evas_Object_Group_Basic
  */
 EAPI void             evas_object_color_set(Evas_Object *obj, int r, int g, int b, int a) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the general/main color of the given Evas object.
+ * @brief   Gets the general or main color of the given Evas object.
  *
- * @param obj The given Evas object to retrieve color from.
- * @param r Pointer to an integer in which to store the red component
- *          of the color.
- * @param g Pointer to an integer in which to store the green
- *          component of the color.
- * @param b Pointer to an integer in which to store the blue component
- *          of the color.
- * @param a Pointer to an integer in which to store the alpha
- *          component of the color.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Retrieves the “main” color's RGB component (and alpha channel)
- * values, <b>which range from 0 to 255</b>. For the alpha channel,
- * which defines the object's transparency level, 0 means totally
- * transparent, while 255 means opaque. These color values are
- * premultiplied by the alpha value.
+ * @remarks Gets the "main" color's RGB component (and alpha channel)
+ *          values, <b>which range from 0 to 255</b>. For the alpha channel,
+ *          which defines the object's transparency level, @c 0 means totally
+ *          transparent, while @c 255 means opaque. These color values are
+ *          premultiplied by the alpha value.
  *
- * Usually you’ll use this attribute for text and rectangle objects,
- * where the “main” color is their unique one. If set for objects
- * which themselves have colors, like the images one, those colors get
- * modulated by this one.
+ * @remarks Usually you use this attribute for text and rectangle objects,
+ *          where the "main" color is their unique one. If set for objects
+ *          which themselves have colors, like the images one, those colors get
+ *          modulated by this one.
  *
- * @note All newly created Evas rectangles get the default color
- * values of <code>255 255 255 255</code> (opaque white).
+ * @remarks All newly created Evas rectangles get the default color
+ *          values of <code>255 255 255 255</code> (opaque white).
  *
- * @note Use @c NULL pointers on the components you're not interested
- * in: they'll be ignored by the function.
+ * @remarks Use @c NULL pointers on the components you are not interested
+ *          in: they are ignored by the function.
  *
- * Example:
- * @dontinclude evas-object-manipulation.c
- * @skip int alpha, r, g, b;
- * @until return
- *
- * See the full @ref Example_Evas_Object_Manipulation "example".
+ * @param[in]   obj  The given Evas object to retrieve color from
+ * @param[out]   r    The pointer to an integer in which to store the red component 
+ *               of the color
+ * @param[out]   g    The pointer to an integer in which to store the green
+ *               component of the color
+ * @param[out]   b    The pointer to an integer in which to store the blue component
+ *               of the color
+ * @param[out]   a    The pointer to an integer in which to store the alpha
+ *               component of the color
  *
  * @ingroup Evas_Object_Group_Basic
  */
 EAPI void             evas_object_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the Evas canvas that the given object lives on.
+ * @brief   Gets the Evas canvas that the given object lives on.
  *
- * @param   obj The given Evas object.
- * @return  A pointer to the canvas where the object is on.
+ * @details This function is most useful at code contexts where you need to
+ *          operate on the canvas but have only the object pointer.
  *
- * This function is most useful at code contexts where you need to
- * operate on the canvas but have only the object pointer.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given Evas object
+ * @return  A pointer to the canvas where the object is on
  *
  * @ingroup Evas_Object_Group_Basic
  */
 EAPI Evas            *evas_object_evas_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the type of the given Evas object.
- *
- * @param obj The given object.
- * @return The type of the object.
+ * @brief   Gets the type of the given Evas object.
  *
- * For Evas' builtin types, the return strings will be one of:
- *   - <c>"rectangle"</c>,
- *   - <c>"line"</c>,
- *   - <c>"polygon"</c>,
- *   - <c>"text"</c>,
- *   - <c>"textblock"</c> and
- *   - <c>"image"</c>.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * For Evas smart objects (see @ref Evas_Smart_Group), the name of the
- * smart class itself is returned on this call. For the built-in smart
- * objects, these names are:
- *   - <c>"EvasObjectSmartClipped"</c>, for the clipped smart object
- *   - <c>"Evas_Object_Box"</c>, for the box object and
- *   - <c>"Evas_Object_Table"</c>, for the table object.
+ * @remarks For Evas' built-in types, the return strings are one of:
+ *          - <c>"rectangle"</c>,
+ *          - <c>"line"</c>,
+ *          - <c>"polygon"</c>,
+ *          - <c>"text"</c>,
+ *          - <c>"textblock"</c> and
+ *          - <c>"image"</c>.
  *
- * Example:
- * @dontinclude evas-object-manipulation.c
- * @skip d.img = evas_object_image_filled_add(d.canvas);
- * @until border on the
+ * @internal
+ * @remarks For Evas smart objects (see @ref Evas_Smart_Group), the name of the
+ *          smart class itself is returned on this call. For the built-in smart
+ *          objects, these names are:
+ *          - <c>"EvasObjectSmartClipped"</c>, for the clipped smart object
+ *          - <c>"Evas_Object_Box"</c>, for the box object and
+ *          - <c>"Evas_Object_Table"</c>, for the table object.
+ * @endinternal
  *
- * See the full @ref Example_Evas_Object_Manipulation "example".
+ * @param[in]   obj  The given object
+ * @return  The type of the object
  */
 EAPI const char      *evas_object_type_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Raise @p obj to the top of its layer.
+ * @brief   Raises @a obj to the top of its layer.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj the object to raise
+ * @remarks @a obj is, then, the highest one in the layer it belongs
+ *          to. Objects on other layers do not get touched.
  *
- * @p obj will, then, be the highest one in the layer it belongs
- * to. Object on other layers won't get touched.
+ * @param[in]   obj  The object to raise
  *
  * @see evas_object_stack_above()
  * @see evas_object_stack_below()
@@ -3621,12 +4124,16 @@ EAPI const char      *evas_object_type_get(const Evas_Object *obj) EINA_WARN_UNU
 EAPI void             evas_object_raise(Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Lower @p obj to the bottom of its layer.
+ * @brief   Lowers @a obj to the bottom of its layer.
  *
- * @param obj the object to lower
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @p obj will, then, be the lowest one in the layer it belongs
- * to. Objects on other layers won't get touched.
+ * @remarks @a obj is, then, the lowest one in the layer it belongs
+ *          to. Objects on other layers do not get touched.
+ *
+ * @param[in]   obj  The object to lower
  *
  * @see evas_object_stack_above()
  * @see evas_object_stack_below()
@@ -3635,26 +4142,30 @@ EAPI void             evas_object_raise(Evas_Object *obj) EINA_ARG_NONNULL(1);
 EAPI void             evas_object_lower(Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Stack @p obj immediately above @p above
+ * @brief   Stacks @a obj immediately above @a above.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj the object to stack
- * @param above the object above which to stack
+ * @remarks Objects, in a given canvas, are stacked in the order they get added
+ *          to it.  This means that, if they overlap, the highest ones
+ *          cover the lowest ones, in that order. This function is a way to
+ *          change the stacking order for the objects.
  *
- * Objects, in a given canvas, are stacked in the order they get added
- * to it.  This means that, if they overlap, the highest ones will
- * cover the lowest ones, in that order. This function is a way to
- * change the stacking order for the objects.
+ * @remarks This function is intended to be used with <b>objects belonging to
+ *          the same layer</b> in a given canvas, otherwise it fails (and
+ *          accomplish nothing).
  *
- * This function is intended to be used with <b>objects belonging to
- * the same layer</b> in a given canvas, otherwise it will fail (and
- * accomplish nothing).
+ * @remarks If you have smart objects on your canvas and @a obj is a member of
+ *          one of them, then @a above must also be a member of the same
+ *          smart object.
  *
- * If you have smart objects on your canvas and @p obj is a member of
- * one of them, then @p above must also be a member of the same
- * smart object.
+ * @remarks Similarly, if @a obj is not a member of a smart object, @a above
+ *          must not be either.
  *
- * Similarly, if @p obj is not a member of a smart object, @p above
- * must not be either.
+ * @param[in]   obj    The object to stack
+ * @param[in]   above  The object above which to stack
  *
  * @see evas_object_layer_get()
  * @see evas_object_layer_set()
@@ -3663,26 +4174,30 @@ EAPI void             evas_object_lower(Evas_Object *obj) EINA_ARG_NONNULL(1);
 EAPI void             evas_object_stack_above(Evas_Object *obj, Evas_Object *above) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Stack @p obj immediately below @p below
+ * @brief   Stacks @a obj immediately below @a below.
  *
- * @param obj the object to stack
- * @param below the object below which to stack
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Objects, in a given canvas, are stacked in the order they get added
- * to it.  This means that, if they overlap, the highest ones will
- * cover the lowest ones, in that order. This function is a way to
- * change the stacking order for the objects.
+ * @remarks Objects, in a given canvas, are stacked in the order they get added
+ *          to it. This means that, if they overlap, the highest ones
+ *          cover the lowest ones, in that order. This function is a way to
+ *          change the stacking order for the objects.
  *
- * This function is intended to be used with <b>objects belonging to
- * the same layer</b> in a given canvas, otherwise it will fail (and
- * accomplish nothing).
+ * @remarks This function is intended to be used with <b>objects belonging to
+ *          the same layer</b> in a given canvas, otherwise it fails (and
+ *          accomplish nothing).
  *
- * If you have smart objects on your canvas and @p obj is a member of
- * one of them, then @p below must also be a member of the same
- * smart object.
+ * @remarks If you have smart objects on your canvas and @a obj is a member of
+ *          one of them, then @a below must also be a member of the same
+ *          smart object.
  *
- * Similarly, if @p obj is not a member of a smart object, @p below
- * must not be either.
+ * @remarks Similarly, if @a obj is not a member of a smart object, @a below
+ *          must not be either.
+ *
+ * @param[in]   obj    The object to stack
+ * @param[in]   below  The object below which to stack
  *
  * @see evas_object_layer_get()
  * @see evas_object_layer_set()
@@ -3691,14 +4206,18 @@ EAPI void             evas_object_stack_above(Evas_Object *obj, Evas_Object *abo
 EAPI void             evas_object_stack_below(Evas_Object *obj, Evas_Object *below) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Get the Evas object stacked right above @p obj
+ * @brief   Gets the Evas object stacked right above @a obj.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj an #Evas_Object
- * @return the #Evas_Object directly above @p obj, if any, or @c NULL,
- * if none
+ * @remarks This function traverses layers in its search, if there are
+ *          objects on layers above the one @a obj is placed at.
  *
- * This function will traverse layers in its search, if there are
- * objects on layers above the one @p obj is placed at.
+ * @param[in]   obj  An #Evas_Object
+ * @return  The #Evas_Object directly above @a obj, if any, \n
+ *          otherwise @c NULL if none
  *
  * @see evas_object_layer_get()
  * @see evas_object_layer_set()
@@ -3708,14 +4227,18 @@ EAPI void             evas_object_stack_below(Evas_Object *obj, Evas_Object *bel
 EAPI Evas_Object     *evas_object_above_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Get the Evas object stacked right below @p obj
+ * @brief   Gets the Evas object stacked right below @a obj.
  *
- * @param obj an #Evas_Object
- * @return the #Evas_Object directly below @p obj, if any, or @c NULL,
- * if none
+ * @details This function traverses layers in its search, if there are
+ *          objects on layers below the one @a obj is placed at.
  *
- * This function will traverse layers in its search, if there are
- * objects on layers below the one @p obj is placed at.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  An #Evas_Object
+ * @return  The #Evas_Object directly below @a obj, if any, \n
+ *          otherwise @c NULL if none
  *
  * @see evas_object_layer_get()
  * @see evas_object_layer_set()
@@ -3729,257 +4252,247 @@ EAPI Evas_Object     *evas_object_below_get(const Evas_Object *obj) EINA_WARN_UN
 
 /**
  * @defgroup Evas_Object_Group_Events Object Events
+ * @ingroup Evas_Object_Group
  *
- * Objects generate events when they are moved, resized, when their
- * visibility change, when they are deleted and so on. These methods
- * allow one to be notified about and to handle such events.
+ * @brief   This group provides functions for object events.
  *
- * Objects also generate events on input (keyboard and mouse), if they
- * accept them (are visible, focused, etc).
+ * @remarks Objects generate events when they are moved, resized, when their
+ *          visibility change, when they are deleted and so on. These methods
+ *          allow you to be notified about and to handle such events.
  *
- * For each of those events, Evas provides a way for one to register
- * callback functions to be issued just after they happen.
+ * @remarks Objects also generate events on input (keyboard and mouse), if they
+ *          accept them (are visible, focused, and so on).
  *
- * The following figure illustrates some Evas (event) callbacks:
+ * @remarks For each of those events, Evas provides a way for one to register
+ *          callback functions to be issued just after they happen.
+ *
+ * @remarks The following figure illustrates some Evas (event) callbacks:
  *
  * @image html evas-callbacks.png
  * @image rtf evas-callbacks.png
  * @image latex evas-callbacks.eps
  *
- * These events have their values in the #Evas_Callback_Type
- * enumeration, which has also ones happening on the canvas level (see
- * @ref Evas_Canvas_Events ).
- *
- * Examples on this group of functions can be found @ref
- * Example_Evas_Stacking "here" and @ref Example_Evas_Events "here".
+ * @remarks These events have their values in the #Evas_Callback_Type
+ *          enumeration, which also has the happening on the canvas level (see
+ *          @ref Evas_Canvas_Events ).
  *
- * @ingroup Evas_Object_Group
- */
-
-/**
- * @addtogroup Evas_Object_Group_Events
  * @{
  */
 
 /**
- * Add (register) a callback function to a given Evas object event.
- *
- * @param obj Object to attach a callback to
- * @param type The type of event that will trigger the callback
- * @param func The function to be called when the event is triggered
- * @param data The data pointer to be passed to @p func
- *
- * This function adds a function callback to an object when the event
- * of type @p type occurs on object @p obj. The function is @p func.
- *
- * In the event of a memory allocation error during addition of the
- * callback to the object, evas_alloc_error() should be used to
- * determine the nature of the error, if any, and the program should
- * sensibly try and recover.
- *
- * A callback function must have the ::Evas_Object_Event_Cb prototype
- * definition. The first parameter (@p data) in this definition will
- * have the same value passed to evas_object_event_callback_add() as
- * the @p data parameter, at runtime. The second parameter @p e is the
- * canvas pointer on which the event occurred. The third parameter is
- * a pointer to the object on which event occurred. Finally, the
- * fourth parameter @p event_info is a pointer to a data structure
- * that may or may not be passed to the callback, depending on the
- * event type that triggered the callback. This is so because some
- * events don't carry extra context with them, but others do.
- *
- * The event type @p type to trigger the function may be one of
- * #EVAS_CALLBACK_MOUSE_IN, #EVAS_CALLBACK_MOUSE_OUT,
- * #EVAS_CALLBACK_MOUSE_DOWN, #EVAS_CALLBACK_MOUSE_UP,
- * #EVAS_CALLBACK_MOUSE_MOVE, #EVAS_CALLBACK_MOUSE_WHEEL,
- * #EVAS_CALLBACK_MULTI_DOWN, #EVAS_CALLBACK_MULTI_UP,
- * #EVAS_CALLBACK_MULTI_MOVE, #EVAS_CALLBACK_FREE,
- * #EVAS_CALLBACK_KEY_DOWN, #EVAS_CALLBACK_KEY_UP,
- * #EVAS_CALLBACK_FOCUS_IN, #EVAS_CALLBACK_FOCUS_OUT,
- * #EVAS_CALLBACK_SHOW, #EVAS_CALLBACK_HIDE, #EVAS_CALLBACK_MOVE,
- * #EVAS_CALLBACK_RESIZE, #EVAS_CALLBACK_RESTACK, #EVAS_CALLBACK_DEL,
- * #EVAS_CALLBACK_HOLD, #EVAS_CALLBACK_CHANGED_SIZE_HINTS,
- * #EVAS_CALLBACK_IMAGE_PRELOADED or #EVAS_CALLBACK_IMAGE_UNLOADED.
- *
- * This determines the kind of event that will trigger the callback.
- * What follows is a list explaining better the nature of each type of
- * event, along with their associated @p event_info pointers:
- *
- * - #EVAS_CALLBACK_MOUSE_IN: @p event_info is a pointer to an
- *   #Evas_Event_Mouse_In struct\n\n
- *   This event is triggered when the mouse pointer enters the area
- *   (not shaded by other objects) of the object @p obj. This may
- *   occur by the mouse pointer being moved by
- *   evas_event_feed_mouse_move() calls, or by the object being shown,
- *   raised, moved, resized, or other objects being moved out of the
- *   way, hidden or lowered, whatever may cause the mouse pointer to
- *   get on top of @p obj, having been on top of another object
- *   previously.
- *
- * - #EVAS_CALLBACK_MOUSE_OUT: @p event_info is a pointer to an
- *   #Evas_Event_Mouse_Out struct\n\n
- *   This event is triggered exactly like #EVAS_CALLBACK_MOUSE_IN is,
- *   but it occurs when the mouse pointer exits an object's area. Note
- *   that no mouse out events will be reported if the mouse pointer is
- *   implicitly grabbed to an object (mouse buttons are down, having
- *   been pressed while the pointer was over that object). In these
- *   cases, mouse out events will be reported once all buttons are
- *   released, if the mouse pointer has left the object's area. The
- *   indirect ways of taking off the mouse pointer from an object,
- *   like cited above, for #EVAS_CALLBACK_MOUSE_IN, also apply here,
- *   naturally.
- *
- * - #EVAS_CALLBACK_MOUSE_DOWN: @p event_info is a pointer to an
- *   #Evas_Event_Mouse_Down struct\n\n
- *   This event is triggered by a mouse button being pressed while the
- *   mouse pointer is over an object. If the pointer mode for Evas is
- *   #EVAS_OBJECT_POINTER_MODE_AUTOGRAB (default), this causes this
- *   object to <b>passively grab the mouse</b> until all mouse buttons
- *   have been released: all future mouse events will be reported to
- *   only this object until no buttons are down. That includes mouse
- *   move events, mouse in and mouse out events, and further button
- *   presses. When all buttons are released, event propagation will
- *   occur as normal (see #Evas_Object_Pointer_Mode).
- *
- * - #EVAS_CALLBACK_MOUSE_UP: @p event_info is a pointer to an
- *   #Evas_Event_Mouse_Up struct\n\n
- *   This event is triggered by a mouse button being released while
- *   the mouse pointer is over an object's area (or when passively
- *   grabbed to an object).
- *
- * - #EVAS_CALLBACK_MOUSE_MOVE: @p event_info is a pointer to an
- *   #Evas_Event_Mouse_Move struct\n\n
- *   This event is triggered by the mouse pointer being moved while
- *   over an object's area (or while passively grabbed to an object).
- *
- * - #EVAS_CALLBACK_MOUSE_WHEEL: @p event_info is a pointer to an
- *   #Evas_Event_Mouse_Wheel struct\n\n
- *   This event is triggered by the mouse wheel being rolled while the
- *   mouse pointer is over an object (or passively grabbed to an
- *   object).
- *
- * - #EVAS_CALLBACK_MULTI_DOWN: @p event_info is a pointer to an
- *   #Evas_Event_Multi_Down struct
- *
- * - #EVAS_CALLBACK_MULTI_UP: @p event_info is a pointer to an
- *   #Evas_Event_Multi_Up struct
- *
- * - #EVAS_CALLBACK_MULTI_MOVE: @p event_info is a pointer to an
- *   #Evas_Event_Multi_Move struct
- *
- * - #EVAS_CALLBACK_FREE: @p event_info is @c NULL \n\n
- *   This event is triggered just before Evas is about to free all
- *   memory used by an object and remove all references to it. This is
- *   useful for programs to use if they attached data to an object and
- *   want to free it when the object is deleted. The object is still
- *   valid when this callback is called, but after it returns, there
- *   is no guarantee on the object's validity.
- *
- * - #EVAS_CALLBACK_KEY_DOWN: @p event_info is a pointer to an
- *   #Evas_Event_Key_Down struct\n\n
- *   This callback is called when a key is pressed and the focus is on
- *   the object, or a key has been grabbed to a particular object
- *   which wants to intercept the key press regardless of what object
- *   has the focus.
- *
- * - #EVAS_CALLBACK_KEY_UP: @p event_info is a pointer to an
- *   #Evas_Event_Key_Up struct \n\n
- *   This callback is called when a key is released and the focus is
- *   on the object, or a key has been grabbed to a particular object
- *   which wants to intercept the key release regardless of what
- *   object has the focus.
- *
- * - #EVAS_CALLBACK_FOCUS_IN: @p event_info is @c NULL \n\n
- *   This event is called when an object gains the focus. When it is
- *   called the object has already gained the focus.
- *
- * - #EVAS_CALLBACK_FOCUS_OUT: @p event_info is @c NULL \n\n
- *   This event is triggered when an object loses the focus. When it
- *   is called the object has already lost the focus.
- *
- * - #EVAS_CALLBACK_SHOW: @p event_info is @c NULL \n\n
- *   This event is triggered by the object being shown by
- *   evas_object_show().
- *
- * - #EVAS_CALLBACK_HIDE: @p event_info is @c NULL \n\n
- *   This event is triggered by an object being hidden by
- *   evas_object_hide().
- *
- * - #EVAS_CALLBACK_MOVE: @p event_info is @c NULL \n\n
- *   This event is triggered by an object being
- *   moved. evas_object_move() can trigger this, as can any
- *   object-specific manipulations that would mean the object's origin
- *   could move.
- *
- * - #EVAS_CALLBACK_RESIZE: @p event_info is @c NULL \n\n
- *   This event is triggered by an object being resized. Resizes can
- *   be triggered by evas_object_resize() or by any object-specific
- *   calls that may cause the object to resize.
- *
- * - #EVAS_CALLBACK_RESTACK: @p event_info is @c NULL \n\n
- *   This event is triggered by an object being re-stacked. Stacking
- *   changes can be triggered by
- *   evas_object_stack_below()/evas_object_stack_above() and others.
- *
- * - #EVAS_CALLBACK_DEL: @p event_info is @c NULL.
- *
- * - #EVAS_CALLBACK_HOLD: @p event_info is a pointer to an
- *   #Evas_Event_Hold struct
- *
- * - #EVAS_CALLBACK_CHANGED_SIZE_HINTS: @p event_info is @c NULL.
- *
- * - #EVAS_CALLBACK_IMAGE_PRELOADED: @p event_info is @c NULL.
- *
- * - #EVAS_CALLBACK_IMAGE_UNLOADED: @p event_info is @c NULL.
- *
- * @note Be careful not to add the same callback multiple times, if
- * that's not what you want, because Evas won't check if a callback
- * existed before exactly as the one being registered (and thus, call
- * it more than once on the event, in this case). This would make
- * sense if you passed different functions and/or callback data, only.
- *
- * Example:
- * @dontinclude evas-events.c
- * @skip evas_object_event_callback_add(
- * @until }
- *
- * See the full example @ref Example_Evas_Events "here".
- *
+ * @brief   Adds or registers a callback function to a given Evas object event.
+ *
+ * @details This function adds a function callback to an object when the event
+ *          of type @a type occurs on object @a obj. The function is @a func.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks In the event of a memory allocation error during addition of the
+ *          callback to the object.
+ *
+ * @remarks A callback function must have the #Evas_Object_Event_Cb prototype
+ *          definition. The first parameter (@a data) in this definition
+ *          has the same value passed to evas_object_event_callback_add() as
+ *          the @a data parameter, at runtime. The second parameter @a e is the
+ *          canvas pointer on which the event occurred. The third parameter is
+ *          a pointer to the object on which event occurred. Finally, the
+ *          fourth parameter @a event_info is a pointer to a data structure
+ *          that may or may not be passed to the callback, depending on the
+ *          event type that triggered the callback. This is so because some
+ *          events do not carry extra context with them, but others do.
+ *
+ * @remarks The valid event type @a type to trigger the function are
+ *          #EVAS_CALLBACK_MOUSE_IN, #EVAS_CALLBACK_MOUSE_OUT,
+ *          #EVAS_CALLBACK_MOUSE_DOWN, #EVAS_CALLBACK_MOUSE_UP,
+ *          #EVAS_CALLBACK_MOUSE_MOVE, #EVAS_CALLBACK_MOUSE_WHEEL,
+ *          #EVAS_CALLBACK_MULTI_DOWN, #EVAS_CALLBACK_MULTI_UP,
+ *          #EVAS_CALLBACK_MULTI_MOVE, #EVAS_CALLBACK_FREE,
+ *          #EVAS_CALLBACK_KEY_DOWN, #EVAS_CALLBACK_KEY_UP,
+ *          #EVAS_CALLBACK_FOCUS_IN, #EVAS_CALLBACK_FOCUS_OUT,
+ *          #EVAS_CALLBACK_SHOW, #EVAS_CALLBACK_HIDE, #EVAS_CALLBACK_MOVE,
+ *          #EVAS_CALLBACK_RESIZE, #EVAS_CALLBACK_RESTACK, #EVAS_CALLBACK_DEL,
+ *          #EVAS_CALLBACK_HOLD, #EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+ *          #EVAS_CALLBACK_IMAGE_PRELOADED or #EVAS_CALLBACK_IMAGE_UNLOADED.
+ *
+ * @remarks This determines the kind of event that triggers the callback.
+ *          The event types are explained below along with their associated @a event_info pointers:
+ *
+ * @remarks - #EVAS_CALLBACK_MOUSE_IN: @a event_info is a pointer to an
+ *          #Evas_Event_Mouse_In struct\n\n
+ *          This event is triggered when the mouse pointer enters the area
+ *          (not shaded by other objects) of the object @a obj. This may
+ *          occur by the mouse pointer being moved or by the object being shown,
+ *          raised, moved, resized, or other objects being moved out of the
+ *          way, hidden or lowered, whatever may cause the mouse pointer to
+ *          get on top of @a obj, having been on top of another object
+ *          previously.
+ *
+ *          - #EVAS_CALLBACK_MOUSE_OUT: @a event_info is a pointer to an
+ *          #Evas_Event_Mouse_Out struct\n\n
+ *          This event is triggered exactly like #EVAS_CALLBACK_MOUSE_IN is,
+ *          but it occurs when the mouse pointer exits an object's area. Note
+ *          that no mouse out events are reported if the mouse pointer is
+ *          implicitly grabbed to an object (mouse buttons are down, having
+ *          been pressed while the pointer is over that object). In these
+ *          cases, mouse out events are reported once all buttons are
+ *          released, if the mouse pointer has left the object's area. The
+ *          indirect ways of taking off the mouse pointer from an object,
+ *          like cited above, for #EVAS_CALLBACK_MOUSE_IN, also apply here,
+ *          naturally.
+ *
+ *          - #EVAS_CALLBACK_MOUSE_DOWN: @a event_info is a pointer to an
+ *          #Evas_Event_Mouse_Down struct\n\n
+ *          This event is triggered by a mouse button being pressed while the
+ *          mouse pointer is over an object. If the pointer mode for Evas is
+ *          #EVAS_OBJECT_POINTER_MODE_AUTOGRAB (default), this causes this
+ *          object to <b>passively grab the mouse</b> until all mouse buttons
+ *          have been released: all future mouse events are reported to
+ *          only this object until no buttons are down. That includes mouse
+ *          move events, mouse in and mouse out events, and further button
+ *          presses. When all buttons are released, event propagation
+ *          occurs as normal (see #Evas_Object_Pointer_Mode).
+ *
+ *          - #EVAS_CALLBACK_MOUSE_UP: @a event_info is a pointer to an
+ *          #Evas_Event_Mouse_Up struct\n\n
+ *          This event is triggered by a mouse button being released while
+ *          the mouse pointer is over an object's area (or when passively
+ *          grabbed to an object).
+ *
+ *          - #EVAS_CALLBACK_MOUSE_MOVE: @a event_info is a pointer to an
+ *          #Evas_Event_Mouse_Move struct\n\n
+ *          This event is triggered by the mouse pointer being moved while
+ *          over an object's area (or while passively grabbed to an object).
+ *
+ *          - #EVAS_CALLBACK_MOUSE_WHEEL: @a event_info is a pointer to an
+ *          #Evas_Event_Mouse_Wheel struct\n\n
+ *          This event is triggered by the mouse wheel being rolled while the
+ *          mouse pointer is over an object (or passively grabbed to an object).
+ *
+ *          - #EVAS_CALLBACK_MULTI_DOWN: @a event_info is a pointer to an
+ *          #Evas_Event_Multi_Down struct
+ *
+ *          - #EVAS_CALLBACK_MULTI_UP: @a event_info is a pointer to an
+ *          #Evas_Event_Multi_Up struct
+ *
+ *          - #EVAS_CALLBACK_MULTI_MOVE: @a event_info is a pointer to an
+ *          #Evas_Event_Multi_Move struct
+ *
+ *          - #EVAS_CALLBACK_FREE: @a event_info is @c NULL \n\n
+ *          This event is triggered just before Evas is about to free all
+ *          memory used by an object and remove all references to it. This is
+ *          useful for programs to use if they attached data to an object and
+ *          want to free it when the object is deleted. The object is still
+ *          valid when this callback is called, but after it returns, there
+ *          is no guarantee on the object's validity.
+ *
+ *          - #EVAS_CALLBACK_KEY_DOWN: @a event_info is a pointer to an
+ *          #Evas_Event_Key_Down struct\n\n
+ *          This callback is called when a key is pressed and the focus is on
+ *          the object, or a key has been grabbed to a particular object
+ *          which wants to intercept the key press regardless of what object
+ *          has the focus.
+ *
+ *          - #EVAS_CALLBACK_KEY_UP: @a event_info is a pointer to an
+ *          #Evas_Event_Key_Up struct \n\n
+ *          This callback is called when a key is released and the focus is
+ *          on the object, or a key has been grabbed to a particular object
+ *          which wants to intercept the key release regardless of what
+ *          object has the focus.
+ *
+ *          - #EVAS_CALLBACK_FOCUS_IN: @a event_info is @c NULL \n\n
+ *          This event is called when an object gains the focus. When it is
+ *          called the object has already gained the focus.
+ *
+ *          - #EVAS_CALLBACK_FOCUS_OUT: @a event_info is @c NULL \n\n
+ *          This event is triggered when an object loses the focus. When it
+ *          is called the object has already lost the focus.
+ *
+ *          - #EVAS_CALLBACK_SHOW: @a event_info is @c NULL \n\n
+ *          This event is triggered by the object being shown by
+ *          evas_object_show().
+ *
+ *          - #EVAS_CALLBACK_HIDE: @a event_info is @c NULL \n\n
+ *          This event is triggered by an object being hidden by
+ *          evas_object_hide().
+ *
+ *          - #EVAS_CALLBACK_MOVE: @a event_info is @c NULL \n\n
+ *          This event is triggered by an object being
+ *          moved. evas_object_move() can trigger this, as can any
+ *          object-specific manipulations that would mean the object's origin
+ *          could move.
+ *
+ *          - #EVAS_CALLBACK_RESIZE: @a event_info is @c NULL \n\n
+ *          This event is triggered by an object being resized. Resizes can
+ *          be triggered by evas_object_resize() or by any object-specific
+ *          calls that may cause the object to resize.
+ *
+ *          - #EVAS_CALLBACK_RESTACK: @a event_info is @c NULL \n\n
+ *          This event is triggered by an object being re-stacked. Stacking
+ *          changes can be triggered by
+ *          evas_object_stack_below()/evas_object_stack_above() and others.
+ *
+ *          - #EVAS_CALLBACK_DEL: @a event_info is @c NULL.
+ *
+ *          - #EVAS_CALLBACK_HOLD: @a event_info is a pointer to an
+ *          #Evas_Event_Hold struct
+ *
+ *          - #EVAS_CALLBACK_CHANGED_SIZE_HINTS: @a event_info is @c NULL.
+ *
+ *          - #EVAS_CALLBACK_IMAGE_PRELOADED: @a event_info is @c NULL.
+ *
+ *          - #EVAS_CALLBACK_IMAGE_UNLOADED: @a event_info is @c NULL.
+ *
+ * @remarks Be careful not to add the same callback multiple times, if
+ *          that is not what you want, because Evas does not check if a callback
+ *          existed before exactly as the one being registered (and thus, call
+ *          it more than once on the event, in this case). This would make
+ *          sense if you passed different functions and/or callback data, only.
+ *
+ * @param[in]   obj   The object to attach a callback to
+ * @param[in]   type  The type of event that triggers the callback
+ * @param[in]   func  The function to be called when the event is triggered
+ * @param[in]   data  The data pointer to be passed to @a func
  */
 EAPI void      evas_object_event_callback_add(Evas_Object *obj, Evas_Callback_Type type, Evas_Object_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
 
 /**
- * Add (register) a callback function to a given Evas object event with a
- * non-default priority set. Except for the priority field, it's exactly the
- * same as @ref evas_object_event_callback_add
+ * @brief   Adds or registers a callback function to a given Evas object event with a
+ *          non-default priority set. Except for the priority field, it is exactly the
+ *          same as @ref evas_object_event_callback_add.
+ * @since   1.1
  *
- * @param obj Object to attach a callback to
- * @param type The type of event that will trigger the callback
- * @param priority The priority of the callback, lower values called first.
- * @param func The function to be called when the event is triggered
- * @param data The data pointer to be passed to @p func
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj       The object to attach a callback to
+ * @param[in]   type      The type of event that triggers the callback
+ * @param[in]   priority  The priority of the callback \n 
+ *                    Lower values are called first.
+ * @param[in]   func      The function to be called when the event is triggered
+ * @param[in]   data      The data pointer to be passed to @a func
  *
  * @see evas_object_event_callback_add
- * @since 1.1
  */
 EAPI void      evas_object_event_callback_priority_add(Evas_Object *obj, Evas_Callback_Type type, Evas_Callback_Priority priority, Evas_Object_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 4);
 
 /**
- * Delete a callback function from an object
+ * @brief   Deletes a callback function from an object.
  *
- * @param obj Object to remove a callback from
- * @param type The type of event that was triggering the callback
- * @param func The function that was to be called when the event was triggered
- * @return The data pointer that was to be passed to the callback
+ * @details This function removes the most recently added callback from the
+ *          object @a obj which is triggered by the event type @a type and is
+ *          calling the function @a func when triggered. If the removal is
+ *          successful it also returns the data pointer that is passed to
+ *          evas_object_event_callback_add() when the callback is added to the
+ *          object. If not successful @c NULL is returned.
  *
- * This function removes the most recently added callback from the
- * object @p obj which was triggered by the event type @p type and was
- * calling the function @p func when triggered. If the removal is
- * successful it will also return the data pointer that was passed to
- * evas_object_event_callback_add() when the callback was added to the
- * object. If not successful @c NULL will be returned.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas_Object *object;
  * void *my_data;
@@ -3987,33 +4500,33 @@ EAPI void      evas_object_event_callback_priority_add(Evas_Object *obj, Evas_Ca
  *
  * my_data = evas_object_event_callback_del(object, EVAS_CALLBACK_MOUSE_UP, up_callback);
  * @endcode
+ *
+ * @param[in]   obj   The object to remove a callback from
+ * @param[in]   type  The type of event triggering the callback
+ * @param[in]   func  The function to be called when the event is triggered
+ * @return  The data pointer to be passed to the callback
  */
 EAPI void     *evas_object_event_callback_del(Evas_Object *obj, Evas_Callback_Type type, Evas_Object_Event_Cb func) EINA_ARG_NONNULL(1, 3);
 
 /**
- * Delete (unregister) a callback function registered to a given
- * Evas object event.
+ * @brief   Deletes or unregisters a callback function registered to a given Evas object event.
  *
- * @param obj Object to remove a callback from
- * @param type The type of event that was triggering the callback
- * @param func The function that was to be called when the event was
- * triggered
- * @param data The data pointer that was to be passed to the callback
- * @return The data pointer that was to be passed to the callback
+ * @details This function removes the most recently added callback from the
+ *          object @a obj, which is triggered by the event type @a type and is
+ *          calling the function @a func with data @a data, when triggered. If
+ *          the removal is successful it also returns the data pointer that
+ *          is passed to evas_object_event_callback_add() (that is the
+ *          same as the parameter) when the callback is added to the
+ *          object. In case of errors, @c NULL is returned.
  *
- * This function removes the most recently added callback from the
- * object @p obj, which was triggered by the event type @p type and was
- * calling the function @p func with data @p data, when triggered. If
- * the removal is successful it will also return the data pointer that
- * was passed to evas_object_event_callback_add() (that will be the
- * same as the parameter) when the callback was added to the
- * object. In errors, @c NULL will be returned.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note For deletion of Evas object events callbacks filtering by
- * just type and function pointer, user
- * evas_object_event_callback_del().
+ * @remarks For deletion of Evas object events callbacks filtering by
+ *          just type and function pointer, use evas_object_event_callback_del().
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas_Object *object;
  * void *my_data;
@@ -4021,22 +4534,33 @@ EAPI void     *evas_object_event_callback_del(Evas_Object *obj, Evas_Callback_Ty
  *
  * my_data = evas_object_event_callback_del_full(object, EVAS_CALLBACK_MOUSE_UP, up_callback, data);
  * @endcode
+ *
+ * @param[in]   obj   The object to remove a callback from
+ * @param[in]   type  The type of event triggering the callback
+ * @param[in]   func  The function to be called when the event is triggered
+ * @param[in]   data  The data pointer to be passed to the callback
+ * @return  The data pointer to be passed to the callback
  */
 EAPI void     *evas_object_event_callback_del_full(Evas_Object *obj, Evas_Callback_Type type, Evas_Object_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
 
 /**
- * Set whether an Evas object is to pass (ignore) events.
+ * @brief   Sets whether an Evas object is to pass (ignore) events.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj the Evas object to operate on
- * @param pass whether @p obj is to pass events (@c EINA_TRUE) or not
- * (@c EINA_FALSE)
+ * @remarks If @a pass is #EINA_TRUE, it makes events on @a obj to be @b
+ *          ignored. They instead are triggered on the @b next lower object that
+ *          is not set to pass events. See evas_object_below_get().
  *
- * If @p pass is @c EINA_TRUE, it will make events on @p obj to be @b
- * ignored. They will be triggered on the @b next lower object (that
- * is not set to pass events), instead (see evas_object_below_get()).
+ * @remarks If @a pass is #EINA_FALSE, events are processed on that
+ *          object as normal.
  *
- * If @p pass is @c EINA_FALSE, events will be processed on that
- * object as normal.
+ *
+ * @param[in]   obj   The Evas object to operate on
+ * @param[in]   pass  Set #EINA_TRUE for @a obj to pass events, \n 
+ *                otherwise #EINA_FALSE not to pass events
  *
  * @see evas_object_pass_events_get() for an example
  * @see evas_object_repeat_events_set()
@@ -4046,18 +4570,15 @@ EAPI void     *evas_object_event_callback_del_full(Evas_Object *obj, Evas_Callba
 EAPI void      evas_object_pass_events_set(Evas_Object *obj, Eina_Bool pass) EINA_ARG_NONNULL(1);
 
 /**
- * Determine whether an object is set to pass (ignore) events.
- *
- * @param obj the Evas object to get information from.
- * @return pass whether @p obj is set to pass events (@c EINA_TRUE) or not
- * (@c EINA_FALSE)
+ * @brief   Checks whether an object is set to pass (ignore) events.
  *
- * Example:
- * @dontinclude evas-stacking.c
- * @skip if (strcmp(ev->keyname, "p") == 0)
- * @until }
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * See the full @ref Example_Evas_Stacking "example".
+ * @param[in]   obj  The Evas object to get information from
+ * @return  #EINA_TRUE if @a obj is set to pass events, \n
+ *          otherwise #EINA_FALSE if it is not set to pass events
  *
  * @see evas_object_pass_events_set()
  * @see evas_object_repeat_events_get()
@@ -4067,25 +4588,22 @@ EAPI void      evas_object_pass_events_set(Evas_Object *obj, Eina_Bool pass) EIN
 EAPI Eina_Bool evas_object_pass_events_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set whether an Evas object is to repeat events.
- *
- * @param obj the Evas object to operate on
- * @param repeat whether @p obj is to repeat events (@c EINA_TRUE) or not
- * (@c EINA_FALSE)
+ * @brief   Sets whether an Evas object is to repeat events.
  *
- * If @p repeat is @c EINA_TRUE, it will make events on @p obj to also
- * be repeated for the @b next lower object in the objects' stack (see
- * see evas_object_below_get()).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * If @p repeat is @c EINA_FALSE, events occurring on @p obj will be
- * processed only on it.
+ * @remarks If @a repeat is #EINA_TRUE, it makes events on @a obj to also
+ *          be repeated for the @b next lower object in the objects' stack. See
+ *          evas_object_below_get().
  *
- * Example:
- * @dontinclude evas-stacking.c
- * @skip if (strcmp(ev->keyname, "r") == 0)
- * @until }
+ * @remarks If @a repeat is #EINA_FALSE, events occurring on @a obj are
+ *          processed only on it.
  *
- * See the full @ref Example_Evas_Stacking "example".
+ * @param[in]   obj     The Evas object to operate on
+ * @param[in]   repeat  Set #EINA_TRUE for @a obj to repeat events, \n 
+ *                  otherwise set #EINA_FALSE
  *
  * @see evas_object_repeat_events_get()
  * @see evas_object_pass_events_set()
@@ -4095,11 +4613,15 @@ EAPI Eina_Bool evas_object_pass_events_get(const Evas_Object *obj) EINA_WARN_UNU
 EAPI void      evas_object_repeat_events_set(Evas_Object *obj, Eina_Bool repeat) EINA_ARG_NONNULL(1);
 
 /**
- * Determine whether an object is set to repeat events.
+ * @brief   Checks whether an object is set to repeat events.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj the given Evas object pointer
- * @return whether @p obj is set to repeat events (@c EINA_TRUE)
- * or not (@c EINA_FALSE)
+ * @param[in]   obj  The given Evas object pointer
+ * @return  #EINA_TRUE if @a obj is set to repeat events,
+ *          otherwise #EINA_FALSE if it is not set to repeat events
  *
  * @see evas_object_repeat_events_set() for an example
  * @see evas_object_pass_events_get()
@@ -4109,21 +4631,24 @@ EAPI void      evas_object_repeat_events_set(Evas_Object *obj, Eina_Bool repeat)
 EAPI Eina_Bool evas_object_repeat_events_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set whether events on a smart object's member should get propagated
- * up to its parent.
+ * @brief   Sets whether events on a smart object's member should get propagated
+ *          up to its parent.
  *
- * @param obj the smart object's child to operate on
- * @param prop whether to propagate events (@c EINA_TRUE) or not
- * (@c EINA_FALSE)
+ * @details This function has @b no effect if @a obj is not a member of a smart object.
  *
- * This function has @b no effect if @p obj is not a member of a smart
- * object.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * If @p prop is @c EINA_TRUE, events occurring on this object will be
- * propagated on to the smart object of which @p obj is a member.  If
- * @p prop is @c EINA_FALSE, events occurring on this object will @b
- * not be propagated on to the smart object of which @p obj is a
- * member.  The default value is @c EINA_TRUE.
+ * @remarks If @a prop is #EINA_TRUE, events occurring on this object is
+ *          propagated on to the smart object of which @a obj is a member.  If
+ *          @a prop is #EINA_FALSE, events occurring on this object is @b
+ *          not propagated on to the smart object of which @a obj is a
+ *          member. The default value is #EINA_TRUE.
+ *
+ * @param[in]   obj   The smart object's child to operate on
+ * @param[in]   prop  Set #EINA_TRUE to propagate events, \n 
+ *                otherwise #EINA_FALSE to not propagate events
  *
  * @see evas_object_propagate_events_get()
  * @see evas_object_repeat_events_set()
@@ -4133,11 +4658,15 @@ EAPI Eina_Bool evas_object_repeat_events_get(const Evas_Object *obj) EINA_WARN_U
 EAPI void      evas_object_propagate_events_set(Evas_Object *obj, Eina_Bool prop) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve whether an Evas object is set to propagate events.
+ * @brief   Checks whether an Evas object is set to propagate events.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj the given Evas object pointer
- * @return whether @p obj is set to propagate events (@c EINA_TRUE)
- * or not (@c EINA_FALSE)
+ * @param[in]   obj  The given Evas object pointer
+ * @return  #EINA_TRUE if @a obj is set to propagate events, \n
+ *          otherwise #EINA_FALSE it is not set to propagate events
  *
  * @see evas_object_propagate_events_set()
  * @see evas_object_repeat_events_get()
@@ -4147,40 +4676,48 @@ EAPI void      evas_object_propagate_events_set(Evas_Object *obj, Eina_Bool prop
 EAPI Eina_Bool evas_object_propagate_events_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set whether an Evas object is to freeze (discard) events.
+ * @brief   Sets whether an Evas object is to freeze (discard) events.
+ * @since   1.1
  *
- * @param obj the Evas object to operate on
- * @param freeze pass whether @p obj is to freeze events (@c EINA_TRUE) or not
- * (@c EINA_FALSE)
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * If @p freeze is @c EINA_TRUE, it will make events on @p obj to be @b
- * discarded. Unlike evas_object_pass_events_set(), events will not be
- * passed to @b next lower object. This API can be used for blocking
- * events while @p obj is on transiting.
+ * @remarks If @a freeze is #EINA_TRUE, it makes events on @a obj to be @b
+ *          discarded. Unlike evas_object_pass_events_set(), events are not
+ *          passed to @b next lower object. This API can be used for blocking
+ *          events while @a obj is on transiting.
  *
- * If @p freeze is @c EINA_FALSE, events will be processed on that
- * object as normal.
+ * @remarks If @a freeze is #EINA_FALSE, events are processed on that
+ *          object as normal.
+ *
+ * @param[in]   obj     The Evas object to operate on
+ * @param[in]   freeze  Set #EINA_TRUE for @a obj to freeze events, \n 
+ *                  otherwise #EINA_FALSE not to freeze events
  *
  * @see evas_object_freeze_events_get()
  * @see evas_object_pass_events_set()
  * @see evas_object_repeat_events_set()
  * @see evas_object_propagate_events_set()
- * @since 1.1
  */
 EAPI void      evas_object_freeze_events_set(Evas_Object *obj, Eina_Bool freeze) EINA_ARG_NONNULL(1);
 
 /**
- * Determine whether an object is set to freeze (discard) events.
+ * @brief   Checks whether an object is set to freeze (discard) events.
+ * @since   1.1
  *
- * @param obj the Evas object to get information from.
- * @return freeze whether @p obj is set to freeze events (@c EINA_TRUE) or
- * not (@c EINA_FALSE)
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The Evas object to get information from
+ * @return  #EINA_TRUE if @a obj is set to freeze events, \n 
+ *          otherwise #EINA_FALSE if it is not set to freeze events
  *
  * @see evas_object_freeze_events_set()
  * @see evas_object_pass_events_get()
  * @see evas_object_repeat_events_get()
  * @see evas_object_propagate_events_get()
- * @since 1.1
  */
 EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
@@ -4190,6 +4727,9 @@ EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_U
 
 /**
  * @defgroup Evas_Object_Group_Map UV Mapping (Rotation, Perspective, 3D...)
+ * @ingroup Evas_Object_Group
+ *
+ * @brief   This group provides functions for UV mapping.
  *
  * Evas allows different transformations to be applied to all kinds of
  * objects. These are applied by means of UV mapping.
@@ -4202,15 +4742,15 @@ EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_U
  * calculated, these can do shading effects on the object, producing
  * 3D effects.
  *
- * As usual, Evas provides both the raw and easy to use methods. The
+ * As usual, Evas provides both raw and easy to use methods. The
  * raw methods allow developers to create their maps somewhere else,
  * possibly loading them from some file format. The easy to use methods
  * calculate the points given some high-level parameters such as
  * rotation angle, ambient light, and so on.
  *
- * @note applying mapping will reduce performance, so use with
- *       care. The impact on performance depends on engine in
- *       use. Software is quite optimized, but not as fast as OpenGL.
+ * @remarks Applying mapping reduces performance, so use with
+ *          care. The impact on performance depends on the engine in
+ *          use. The software is quite optimized, but not as fast as OpenGL.
  *
  * @section sec-map-points Map points
  * @subsection subsec-rotation Rotation
@@ -4219,33 +4759,29 @@ EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_U
  * of these points contains a set of canvas coordinates @c x and @c y that
  * can be used to alter the geometry of the mapped object, and a @c z
  * coordinate that indicates the depth of that point. This last coordinate
- * does not normally affect the map, but it's used by several of the utility
+ * does not normally affect the map, but it is used by several of the utility
  * functions to calculate the right position of the point given other
  * parameters.
  *
  * The coordinates for each point are set with evas_map_point_coord_set().
- * The following image shows a map set to match the geometry of an existing
- * object.
+ * The following image shows a map set to match the geometry of an existing object.
  *
  * @image html map-set-map-points-1.png
  * @image rtf map-set-map-points-1.png
  * @image latex map-set-map-points-1.eps
  *
- * This is a common practice, so there are a few functions that help make it
- * easier.
+ * This is a common practice, so there are a few functions that help make it easier.
  *
  * evas_map_util_points_populate_from_geometry() sets the coordinates of each
- * point in the given map to match the rectangle defined by the function
- * parameters.
+ * point in the given map to match the rectangle defined by the function parameters.
  *
  * evas_map_util_points_populate_from_object() and
  * evas_map_util_points_populate_from_object_full() both take an object and
  * set the map points to match its geometry. The difference between the two
- * is that the first function sets the @c z value of all points to 0, while
+ * is that the first function sets the @c z value of all points to @c 0, while
  * the latter receives the value to set in said coordinate as a parameter.
  *
- * The following lines of code all produce the same result as in the image
- * above.
+ * The following lines of code all produce the same result as in the image above.
  * @code
  * evas_map_util_points_populate_from_geometry(m, 100, 100, 200, 200, 0);
  * // Assuming o is our original object
@@ -4270,8 +4806,7 @@ EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_U
  * @image rtf map-set-map-points-3.png
  * @image latex map-set-map-points-3.eps
  *
- * In all three cases above, setting the map to be used by the object is the
- * same.
+ * In all three cases above, setting the map to be used by the object is the same.
  * @code
  * evas_object_map_set(o, m);
  * evas_object_map_enable_set(o, EINA_TRUE);
@@ -4286,7 +4821,7 @@ EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_U
  * specific effect. For example, to rotate an object around its own center
  * you would need to take the rotation angle, the coordinates of each corner
  * of the object and do all the math to get the new set of coordinates that
- * need to tbe set in the map.
+ * need to be set in the map.
  *
  * Or you can use this code:
  * @code
@@ -4299,7 +4834,7 @@ EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_U
  * evas_map_free(m);
  * @endcode
  *
- * Which will rotate the object around its center point in a 45 degree angle
+ * which rotates the object around its center point in a 45 degree angle
  * in the clockwise direction, taking it from this
  *
  * @image html map-rotation-2d-1.png
@@ -4313,7 +4848,7 @@ EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_U
  * @image latex map-rotation-2d-2.eps
  *
  * Objects may be rotated around any other point just by setting the last two
- * paramaters of the evas_map_util_rotate() function to the right values. A
+ * parameters of the evas_map_util_rotate() function to the right values. A
  * circle of roughly the diameter of the object overlaid on each image shows
  * where the center of rotation is set for each example.
  *
@@ -4356,12 +4891,12 @@ EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_U
  * Maps can also be used to achieve the effect of 3-dimensionality. When doing
  * this, the @c z coordinate of each point counts, with higher values meaning
  * the point is further into the screen, and smaller values (negative, usually)
- * meaning the point is closwer towards the user.
+ * meaning the point is closer towards the user.
  *
  * Thinking in 3D also introduces the concept of back-face of an object. An
  * object is said to be facing the user when all its points are placed in a
- * clockwise fashion. The next image shows this, with each point showing the
- * with which is identified within the map.
+ * clockwise fashion. The next image shows this, with each point showing each
+ * corner of the object with which it is identified within the map.
  *
  * @image html map-point-order-face.png
  * @image rtf map-point-order-face.png
@@ -4375,15 +4910,15 @@ EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_U
  * @image latex map-point-order-back.eps
  *
  * This way we can say that we are looking at the back face of the object.
- * This will have stronger implications later when we talk about lighting.
+ * This has stronger implications later when we talk about lighting.
  *
- * To know if a map is facing towards the user or not it's enough to use
+ * To know if a map is facing towards the user or not it is enough to use
  * the evas_map_util_clockwise_get() function, but this is normally done
  * after all the other operations are applied on the map.
  *
  * @subsection subsec-3d-rot 3D rotation and perspective
  *
- * Much like evas_map_util_rotate(), there's the function
+ * Much like evas_map_util_rotate(), there is the function
  * evas_map_util_3d_rotate() that transforms the map to apply a 3D rotation
  * to an object. As in its 2D counterpart, the rotation can be applied around
  * any point in the canvas, this time with a @c z coordinate too. The rotation
@@ -4406,7 +4941,7 @@ EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_U
  * @image rtf map-3d-basic-2.png
  * @image latex map-3d-basic-2.eps
  *
- * which doesn't look very real. This can be helped by adding perspective
+ * which does not look very real. This can be helped by adding perspective
  * to the transformation, which can be simply done by calling
  * evas_map_util_3d_perspective() on the map after its position has been set.
  * The result in this case, making the vanishing point the center of each
@@ -4418,7 +4953,7 @@ EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_U
  *
  * @section sec-color Color and lighting
  *
- * Each point in a map can be set to a color, which will be multiplied with
+ * Each point in a map can be set to a color, which is multiplied with
  * the objects own color and linearly interpolated in between adjacent points.
  * This is done with evas_map_point_color_set() for each point of the map,
  * or evas_map_util_points_color_set() to set every point to the same color.
@@ -4430,7 +4965,7 @@ EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_U
  * of each point based on the distance to the light source, the angle with
  * which the object is facing the light and the ambient light. Here, the
  * orientation of each point as explained before, becomes more important.
- * If the map is defined counter-clockwise, the object will be facing away
+ * If the map is defined counter-clockwise, the object faces away
  * from the user and thus become obscured, since no light would be reflecting
  * from it.
  *
@@ -4451,7 +4986,7 @@ EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_U
  * @image latex map-uv-mapping-1.eps
  *
  * Images need some special handling when mapped. Evas can easily take care
- * of objects and do almost anything with them, but it's completely oblivious
+ * of objects and do almost anything with them, but it is completely oblivious
  * to the content of images, so each point in the map needs to be told to what
  * pixel in the source image it belongs. Failing to do may sometimes result
  * in the expected behavior, or it may look like a partial work.
@@ -4465,8 +5000,8 @@ EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_U
  * @image rtf map-uv-mapping-2.png
  * @image latex map-uv-mapping-2.eps
  *
- * Once Evas knows how to handle the source image within the map, it will
- * transform it as needed. This is done with evas_map_point_image_uv_set(),
+ * Once Evas knows how to handle the source image within the map, it
+ * transforms it as needed. This is done with evas_map_point_image_uv_set(),
  * which tells the map to which pixel in image it maps.
  *
  * To match our example images to the maps above all we need is the size of
@@ -4488,14 +5023,12 @@ EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_U
  * evas_object_map_enable_set(o2, EINA_TRUE);
  * @endcode
  *
- * To get
- *
  * @image html map-uv-mapping-3.png
  * @image rtf map-uv-mapping-3.png
  * @image latex map-uv-mapping-3.eps
  *
  * Maps can also be set to use part of an image only, or even map them inverted,
- * and combined with evas_object_image_source_set() it can be used to achieve
+ * and when combined with evas_object_image_source_set() it can be used to achieve
  * more interesting results.
  *
  * @code
@@ -4512,57 +5045,66 @@ EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj) EINA_WARN_U
  * @image rtf map-uv-mapping-4.png
  * @image latex map-uv-mapping-4.eps
  *
- * Examples:
- * @li @ref Example_Evas_Map_Overview
- *
- * @ingroup Evas_Object_Group
- *
  * @{
  */
 
 /**
- * Enable or disable the map that is set.
+ * @brief   Enables or disables the map that is set.
+ *
+ * @details This function enables or disables the use of map for the object @a obj.
+ *          When enabled, the object geometry is saved, and the new geometry
+ *          changes (position and size) to reflect the map geometry set.
  *
- * Enable or disable the use of map for the object @p obj.
- * On enable, the object geometry will be saved, and the new geometry will
- * change (position and size) to reflect the map geometry set.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * If the object doesn't have a map set (with evas_object_map_set()), the
- * initial geometry will be undefined. It is advised to always set a map
- * to the object first, and then call this function to enable its use.
+ * @remarks If the object does not have a map set (with evas_object_map_set()), the
+ *          initial geometry is undefined. It is advised to always set a map
+ *          to the object first, and then call this function to enable its use.
  *
- * @param obj object to enable the map on
- * @param enabled enabled state
+ * @param[in]   obj      The object to enable the map on
+ * @param[in]   enabled  Set #EINA_TRUE to enable the map, \n
+ *                   otherwise #EINA_FALSE to not enable the map
  */
 EAPI void            evas_object_map_enable_set(Evas_Object *obj, Eina_Bool enabled);
 
 /**
- * Get the map enabled state
+ * @brief   Checks whether the map is enabled.
  *
- * This returns the currently enabled state of the map on the object indicated.
- * The default map enable state is off. You can enable and disable it with
- * evas_object_map_enable_set().
+ * @details This function returns the currently enabled state of the map on the object indicated.
+ *          The default map enable state is off. You can enable and disable it with
+ *          evas_object_map_enable_set().
  *
- * @param obj object to get the map enabled state from
- * @return the map enabled state
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The object to get the map enabled state from
+ * @return  #EINA_TRUE of the map is enabled, \n
+ *          otherwise #EINA_FALSE of the map is not enabled
  */
 EAPI Eina_Bool       evas_object_map_enable_get(const Evas_Object *obj);
 
 /**
- * Set current object transformation map.
+ * @brief   Sets current object transformation map.
+ *
+ * @details This function sets the map on a given object. It is copied from the @a map pointer,
+ *          so there is no need to keep the @a map object if you do not need it anymore.
  *
- * This sets the map on a given object. It is copied from the @p map pointer,
- * so there is no need to keep the @p map object if you don't need it anymore.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * A map is a set of 4 points which have canvas x, y coordinates per point,
- * with an optional z point value as a hint for perspective correction, if it
- * is available. As well each point has u and v coordinates. These are like
- * "texture coordinates" in OpenGL in that they define a point in the source
- * image that is mapped to that map vertex/point. The u corresponds to the x
- * coordinate of this mapped point and v, the y coordinate. Note that these
- * coordinates describe a bounding region to sample. If you have a 200x100
- * source image and want to display it at 200x100 with proper pixel
- * precision, then do:
+ * @remarks A map is a set of 4 points which have canvas @c x, @c y coordinates per point,
+ *          with an optional @c z point value as a hint for perspective correction, if it
+ *          is available. As well each point has @c u and @c v coordinates. These are like
+ *          "texture coordinates" in OpenGL in that they define a point in the source
+ *          image that is mapped to that map vertex or point. The @c u corresponds to the @c x
+ *          coordinate of this mapped point and @c v, the @c y coordinate. Note that these
+ *          coordinates describe a bounding region to sample. If you have a 200x100
+ *          source image and want to display it at 200x100 with proper pixel
+ *          precision, then do the following:
  *
  * @code
  * Evas_Map *m = evas_map_new(4);
@@ -4578,54 +5120,62 @@ EAPI Eina_Bool       evas_object_map_enable_get(const Evas_Object *obj);
  * evas_map_free(m);
  * @endcode
  *
- * Note that the map points a uv coordinates match the image geometry. If
- * the @p map parameter is NULL, the stored map will be freed and geometry
- * prior to enabling/setting a map will be restored.
+ * @remarks Note that the map points a uv coordinates that match the image geometry. If
+ *          the @a map parameter is @c NULL, the stored map is freed and geometry
+ *          prior to enabling/setting a map is restored.
  *
- * @param obj object to change transformation map
- * @param map new map to use
+ * @param[in]   obj  The object to change transformation map
+ * @param[in]   map  The new map to use
  *
  * @see evas_map_new()
  */
 EAPI void            evas_object_map_set(Evas_Object *obj, const Evas_Map *map);
 
 /**
- * Get current object transformation map.
+ * @brief   Gets the current object transformation map.
  *
- * This returns the current internal map set on the indicated object. It is
- * intended for read-only access and is only valid as long as the object is
- * not deleted or the map on the object is not changed. If you wish to modify
- * the map and set it back do the following:
+ * @details This function returns the current internal map set on the indicated object. It is
+ *          intended for read-only access and is only valid as long as the object is
+ *          not deleted or the map on the object is not changed. If you wish to modify
+ *          the map and set it back do the following:
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
  * @code
  * const Evas_Map *m = evas_object_map_get(obj);
  * Evas_Map *m2 = evas_map_dup(m);
  * evas_map_util_rotate(m2, 30.0, 0, 0);
- * evas_object_map_set(obj);
+ * evas_object_map_set(obj, m2);
  * evas_map_free(m2);
  * @endcode
  *
- * @param obj object to query transformation map.
- * @return map reference to map in use. This is an internal data structure, so
- * do not modify it.
+ * @param[in]   obj  The object to query transformation map
+ * @return  The map reference to the map in use \n 
+ *          This is an internal data structure, so do not modify it.
  *
  * @see evas_object_map_set()
  */
 EAPI const Evas_Map *evas_object_map_get(const Evas_Object *obj);
 
 /**
- * Populate source and destination map points to match exactly object.
+ * @brief   Populates source and destination map points to exactly match the object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Usually one initialize map of an object to match it's original
- * position and size, then transform these with evas_map_util_*
- * functions, such as evas_map_util_rotate() or
- * evas_map_util_3d_rotate(). The original set is done by this
- * function, avoiding code duplication all around.
+ * @remarks You initialize the map of an object to match its original
+ *          position and size, then transform these with evas_map_util_*
+ *          functions, such as evas_map_util_rotate() or
+ *          evas_map_util_3d_rotate(). The original set is done by this
+ *          function, avoiding code duplication all around.
  *
- * @param m map to change all 4 points (must be of size 4).
- * @param obj object to use unmapped geometry to populate map coordinates.
- * @param z Point Z Coordinate hint (pre-perspective transform). This value
- *        will be used for all four points.
+ * @param[in]   m    The map to change all 4 points (must be of size 4)
+ * @param[in]   obj  The object to use unmapped geometry to populate map coordinates
+ * @param[in]   z    The point Z coordinate hint (pre-perspective transform) \n 
+ *               This value is used for all four points.
  *
  * @see evas_map_util_points_populate_from_object()
  * @see evas_map_point_coord_set()
@@ -4634,18 +5184,22 @@ EAPI const Evas_Map *evas_object_map_get(const Evas_Object *obj);
 EAPI void            evas_map_util_points_populate_from_object_full(Evas_Map *m, const Evas_Object *obj, Evas_Coord z);
 
 /**
- * Populate source and destination map points to match exactly object.
+ * @brief   Populates the source and destination map points to exactly match the object.
  *
- * Usually one initialize map of an object to match it's original
- * position and size, then transform these with evas_map_util_*
- * functions, such as evas_map_util_rotate() or
- * evas_map_util_3d_rotate(). The original set is done by this
- * function, avoiding code duplication all around.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Z Point coordinate is assumed as 0 (zero).
+ * @remarks You initialize map of an object to match its original
+ *          position and size, then transform these with evas_map_util_*
+ *          functions, such as evas_map_util_rotate() or
+ *          evas_map_util_3d_rotate(). The original set is done by this
+ *          function, avoiding code duplication all around.
  *
- * @param m map to change all 4 points (must be of size 4).
- * @param obj object to use unmapped geometry to populate map coordinates.
+ * @remarks The Z point coordinate is assumed as @c 0 (zero).
+ *
+ * @param[in]   m    The map to change all 4 points (must be of size 4)
+ * @param[in]   obj  The object to use unmapped geometry to populate map coordinates
  *
  * @see evas_map_util_points_populate_from_object_full()
  * @see evas_map_util_points_populate_from_geometry()
@@ -4655,21 +5209,25 @@ EAPI void            evas_map_util_points_populate_from_object_full(Evas_Map *m,
 EAPI void            evas_map_util_points_populate_from_object(Evas_Map *m, const Evas_Object *obj);
 
 /**
- * Populate source and destination map points to match given geometry.
+ * @brief   Populates the source and destination map points to match the given geometry.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Similar to evas_map_util_points_populate_from_object_full(), this
- * call takes raw values instead of querying object's unmapped
- * geometry. The given width will be used to calculate destination
- * points (evas_map_point_coord_set()) and set the image uv
- * (evas_map_point_image_uv_set()).
+ * @remarks Similar to evas_map_util_points_populate_from_object_full(), this
+ *          call takes raw values instead of querying object's unmapped
+ *          geometry. The given width is used to calculate destination
+ *          points (evas_map_point_coord_set()) and set the image uv
+ *          (evas_map_point_image_uv_set()).
  *
- * @param m map to change all 4 points (must be of size 4).
- * @param x Point X Coordinate
- * @param y Point Y Coordinate
- * @param w width to use to calculate second and third points.
- * @param h height to use to calculate third and fourth points.
- * @param z Point Z Coordinate hint (pre-perspective transform). This value
- *        will be used for all four points.
+ * @param[in]   m  The map to change all 4 points (must be of size 4)
+ * @param[in]   x  The X coordinate
+ * @param[in]   y  The Y coordinate
+ * @param[in]   w  The width to use to calculate second and third points
+ * @param[in]   h  The height to use to calculate third and fourth points
+ * @param[in]   z  The Z coordinate hint (pre-perspective transform) \n 
+ *             This value is used for all four points.
  *
  * @see evas_map_util_points_populate_from_object()
  * @see evas_map_point_coord_set()
@@ -4678,34 +5236,42 @@ EAPI void            evas_map_util_points_populate_from_object(Evas_Map *m, cons
 EAPI void            evas_map_util_points_populate_from_geometry(Evas_Map *m, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Evas_Coord z);
 
 /**
- * Set color of all points to given color.
+ * @brief   Sets the given color for all the points.
  *
- * This call is useful to reuse maps after they had 3d lightning or
- * any other colorization applied before.
+ * @details This function is useful to reuse maps after they had 3D lightning or
+ *          any other colorization applied before.
  *
- * @param m map to change the color of.
- * @param r red (0 - 255)
- * @param g green (0 - 255)
- * @param b blue (0 - 255)
- * @param a alpha (0 - 255)
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   m  The map to change the color of
+ * @param[in]   r  The red color (0 - 255)
+ * @param[in]   g  The green color (0 - 255)
+ * @param[in]   b  The blue color (0 - 255)
+ * @param[in]   a  The alpha color (0 - 255)
  *
  * @see evas_map_point_color_set()
  */
 EAPI void            evas_map_util_points_color_set(Evas_Map *m, int r, int g, int b, int a);
 
 /**
- * Change the map to apply the given rotation.
+ * @brief   Changes the map to apply the given rotation.
+ *
+ * @details This function rotates the indicated map's coordinates around the center coordinate
+ *          given by @a cx and @a cy as the rotation center. The points have their
+ *          X and Y coordinates rotated clockwise by @a degrees degrees (@c 360.0 is a
+ *          full rotation). Negative values for degrees rotate counter-clockwise
+ *          by that amount. All coordinates are canvas global coordinates.
  *
- * This rotates the indicated map's coordinates around the center coordinate
- * given by @p cx and @p cy as the rotation center. The points will have their
- * X and Y coordinates rotated clockwise by @p degrees degrees (360.0 is a
- * full rotation). Negative values for degrees will rotate counter-clockwise
- * by that amount. All coordinates are canvas global coordinates.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param m map to change.
- * @param degrees amount of degrees from 0.0 to 360.0 to rotate.
- * @param cx rotation's center horizontal position.
- * @param cy rotation's center vertical position.
+ * @param[in]   m        The map to change
+ * @param[in]   degrees  The amount of degrees from @c 0.0 to @c 360.0 to rotate
+ * @param[in]   cx       The rotation's center horizontal position
+ * @param[in]   cy       The rotation's center vertical position
  *
  * @see evas_map_point_coord_set()
  * @see evas_map_util_zoom()
@@ -4713,19 +5279,23 @@ EAPI void            evas_map_util_points_color_set(Evas_Map *m, int r, int g, i
 EAPI void            evas_map_util_rotate(Evas_Map *m, double degrees, Evas_Coord cx, Evas_Coord cy);
 
 /**
- * Change the map to apply the given zooming.
+ * @brief   Changes the map to apply the given zooming.
  *
- * Like evas_map_util_rotate(), this zooms the points of the map from a center
- * point. That center is defined by @p cx and @p cy. The @p zoomx and @p zoomy
- * parameters specify how much to zoom in the X and Y direction respectively.
- * A value of 1.0 means "don't zoom". 2.0 means "double the size". 0.5 is
- * "half the size" etc. All coordinates are canvas global coordinates.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param m map to change.
- * @param zoomx horizontal zoom to use.
- * @param zoomy vertical zoom to use.
- * @param cx zooming center horizontal position.
- * @param cy zooming center vertical position.
+ * @remarks Like evas_map_util_rotate(), this zooms the points of the map from a center
+ *          point. That center is defined by @a cx and @a cy. The @a zoomx and @a zoomy
+ *          parameters specify how much to zoom in the X and Y direction respectively.
+ *          A value of @c 1.0 means "don't zoom", @c 2.0 means "double the size", @c 0.5 is
+ *          "half the size", and so on. All coordinates are canvas global coordinates.
+ *
+ * @param[in]   m      The map to change
+ * @param[in]   zoomx  The horizontal zoom to use
+ * @param[in]   zoomy  The vertical zoom to use
+ * @param[in]   cx     The zooming center horizontal position
+ * @param[in]   cy     The zooming center vertical position
  *
  * @see evas_map_point_coord_set()
  * @see evas_map_util_rotate()
@@ -4733,127 +5303,177 @@ EAPI void            evas_map_util_rotate(Evas_Map *m, double degrees, Evas_Coor
 EAPI void            evas_map_util_zoom(Evas_Map *m, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy);
 
 /**
- * Rotate the map around 3 axes in 3D
+ * @brief   Rotates the map around 3 axes in 3D.
+ *
+ * @details This function rotates not just around the "Z" axis as in evas_map_util_rotate()
+ *          (which is a convenience call for those only wanting 2D). This rotates
+ *          around the X, Y and Z axes. The Z axis points "into" the screen with low
+ *          values at the screen and higher values further away. The X axis runs from
+ *          left to right on the screen and the Y axis from top to bottom. Like with
+ *          evas_map_util_rotate() you provide a center point to rotate around (in 3D).
  *
- * This will rotate not just around the "Z" axis as in evas_map_util_rotate()
- * (which is a convenience call for those only wanting 2D). This will rotate
- * around the X, Y and Z axes. The Z axis points "into" the screen with low
- * values at the screen and higher values further away. The X axis runs from
- * left to right on the screen and the Y axis from top to bottom. Like with
- * evas_map_util_rotate() you provide a center point to rotate around (in 3D).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param m map to change.
- * @param dx amount of degrees from 0.0 to 360.0 to rotate around X axis.
- * @param dy amount of degrees from 0.0 to 360.0 to rotate around Y axis.
- * @param dz amount of degrees from 0.0 to 360.0 to rotate around Z axis.
- * @param cx rotation's center horizontal position.
- * @param cy rotation's center vertical position.
- * @param cz rotation's center vertical position.
+ * @param[in]  m   The map to change
+ * @param[in]  dx  The amount of degrees from @c 0.0 to @c 360.0 to rotate around X axis
+ * @param[in]  dy  The amount of degrees from @c 0.0 to @c 360.0 to rotate around Y axis
+ * @param[in]  dz  The amount of degrees from @c 0.0 to @c 360.0 to rotate around Z axis
+ * @param[in]  cx  The rotation's center horizontal position
+ * @param[in]  cy  The rotation's center vertical position
+ * @param[in]  cz  The rotation's center vertical position
  */
 EAPI void            evas_map_util_3d_rotate(Evas_Map *m, double dx, double dy, double dz, Evas_Coord cx, Evas_Coord cy, Evas_Coord cz);
 
 /**
- * Perform lighting calculations on the given Map
+ * @brief   Rotates the map in 3D using a unit quaternion.
  *
- * This is used to apply lighting calculations (from a single light source)
- * to a given map. The R, G and B values of each vertex will be modified to
- * reflect the lighting based on the lixth point coordinates, the light
- * color and the ambient color, and at what angle the map is facing the
- * light source. A surface should have its points be declared in a
- * clockwise fashion if the face is "facing" towards you (as opposed to
- * away from you) as faces have a "logical" side for lighting.
+ * @details This function rotates in 3D using a unit quaternion. Like with
+ *          evas_map_util_3d_rotate() you provide a center point 
+ *          to rotate around (in 3D).
+ * @since   1.8
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks Rotations can be done using a unit quaternion. Thus, this
+ *          function expects a unit quaternion (i.e. qx² + qy² + qz² + qw² == 1).
+ *          If this is not the case the behavior is undefined.
+ *
+ * @param[in]   m   The map to change
+ * @param[in]   qx  The x component of the imaginary part of the quaternion
+ * @param[in]   qy  The y component of the imaginary part of the quaternion
+ * @param[in]   qz  The z component of the imaginary part of the quaternion
+ * @param[in]   qw  The w component of the real part of the quaternion
+ * @param[in]   cx  The rotation's center x
+ * @param[in]   cy  The rotation's center y
+ * @param[in]   cz  The rotation's center z
+ *
+ */
+EAPI void            evas_map_util_quat_rotate(Evas_Map *m, double qx, double qy, double qz, double qw, double cx, double cy, double cz);
+
+/**
+ * @brief   Performs lighting calculations on the given map.
+ *
+ * @details This function is used to apply lighting calculations (from a single light source)
+ *          to a given map. The R, G and B values of each vertex is modified to
+ *          reflect the lighting based on the lixth point coordinates, the light
+ *          color and the ambient color, and at what angle the map is facing the
+ *          light source. A surface should have its points declared in a
+ *          clockwise fashion if the face is "facing" towards you (as opposed to
+ *          away from you) as faces have a "logical" side for lighting.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
  * @image html map-light3.png
  * @image rtf map-light3.png
  * @image latex map-light3.eps
- * @note Grey object, no lighting used
+ * @remarks Grey object, no lighting used
  *
  * @image html map-light4.png
  * @image rtf map-light4.png
  * @image latex map-light4.eps
- * @note Lights out! Every color set to 0
+ * @remarks Lights out! Every color set to @c 0
  *
  * @image html map-light5.png
  * @image rtf map-light5.png
  * @image latex map-light5.eps
- * @note Ambient light to full black, red light coming from close at the
- * bottom-left vertex
+ * @remarks Ambient light to full black, red light coming from close at the
+ *          bottom-left vertex.
  *
  * @image html map-light6.png
  * @image rtf map-light6.png
  * @image latex map-light6.eps
- * @note Same light as before, but not the light is set to 0 and ambient light
- * is cyan
+ * @remarks Same light as before, but not the light is set to 0 and ambient light
+ *          is cyan.
  *
  * @image html map-light7.png
  * @image rtf map-light7.png
  * @image latex map-light7.eps
- * @note Both lights are on
+ * @remarks Both lights are on.
  *
  * @image html map-light8.png
  * @image rtf map-light8.png
  * @image latex map-light8.eps
- * @note Both lights again, but this time both are the same color.
- *
- * @param m map to change.
- * @param lx X coordinate in space of light point
- * @param ly Y coordinate in space of light point
- * @param lz Z coordinate in space of light point
- * @param lr light red value (0 - 255)
- * @param lg light green value (0 - 255)
- * @param lb light blue value (0 - 255)
- * @param ar ambient color red value (0 - 255)
- * @param ag ambient color green value (0 - 255)
- * @param ab ambient color blue value (0 - 255)
+ * @remarks Both lights again, but this time both are the same color.
+ *
+ * @param[in]   m   The map to change
+ * @param[in]   lx  The X coordinate in space of light point
+ * @param[in]   ly  The Y coordinate in space of light point
+ * @param[in]   lz  The Z coordinate in space of light point
+ * @param[in]   lr  The light red value (0 - 255)
+ * @param[in]   lg  The light green value (0 - 255)
+ * @param[in]   lb  The light blue value (0 - 255)
+ * @param[in]   ar  The ambient color red value (0 - 255)
+ * @param[in]   ag  The ambient color green value (0 - 255)
+ * @param[in]   ab  The ambient color blue value (0 - 255)
  */
 EAPI void            evas_map_util_3d_lighting(Evas_Map *m, Evas_Coord lx, Evas_Coord ly, Evas_Coord lz, int lr, int lg, int lb, int ar, int ag, int ab);
 
 /**
- * Apply a perspective transform to the map
+ * @brief   Applies a perspective transform to the map.
+ *
+ * @details This function applies a given perspective (3D) to the map coordinates. X, Y and Z
+ *          values are used. The px and py points specify the "infinite distance" point
+ *          in the 3D conversion (where all lines converge to, like when artists draw
+ *          3D by hand). The @a z0 value specifies the z value at which there is a 1:1
+ *          mapping between spatial coordinates and screen coordinates. Any points
+ *          on this z value do not have their X and Y values modified in the transform.
+ *          Those further away (Z value higher) shrink into the distance, and
+ *          those less than this value expand and become bigger. The @a foc value
+ *          determines the "focal length" of the camera. This is in reality the distance
+ *          between the camera lens plane itself (at or closer than this rendering
+ *          results are undefined) and the "z0" z value. This allows for some "depth"
+ *          control and @a foc must be greater than @c 0.
  *
- * This applies a given perspective (3D) to the map coordinates. X, Y and Z
- * values are used. The px and py points specify the "infinite distance" point
- * in the 3D conversion (where all lines converge to like when artists draw
- * 3D by hand). The @p z0 value specifies the z value at which there is a 1:1
- * mapping between spatial coordinates and screen coordinates. Any points
- * on this z value will not have their X and Y values modified in the transform.
- * Those further away (Z value higher) will shrink into the distance, and
- * those less than this value will expand and become bigger. The @p foc value
- * determines the "focal length" of the camera. This is in reality the distance
- * between the camera lens plane itself (at or closer than this rendering
- * results are undefined) and the "z0" z value. This allows for some "depth"
- * control and @p foc must be greater than 0.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param m map to change.
- * @param px The perspective distance X coordinate
- * @param py The perspective distance Y coordinate
- * @param z0 The "0" z plane value
- * @param foc The focal distance
+ * @param[in]   m    The map to change
+ * @param[in]   px   The perspective distance X coordinate
+ * @param[in]   py   The perspective distance Y coordinate
+ * @param[in]   z0   The "0" z plane value
+ * @param[in]   foc  The focal distance
  */
 EAPI void            evas_map_util_3d_perspective(Evas_Map *m, Evas_Coord px, Evas_Coord py, Evas_Coord z0, Evas_Coord foc);
 
 /**
- * Get the clockwise state of a map
+ * @brief   Gets the clockwise state of a map.
  *
- * This determines if the output points (X and Y. Z is not used) are
- * clockwise or anti-clockwise. This can be used for "back-face culling". This
- * is where you hide objects that "face away" from you. In this case objects
- * that are not clockwise.
+ * @details This function determines if the output points (X and Y. Z is not used) are
+ *          clockwise or counter-clockwise. This can be used for "back-face culling". This
+ *          is where you hide objects that "face away" from you, in this case, the objects
+ *          that are not clockwise.
  *
- * @param m map to query.
- * @return 1 if clockwise, 0 otherwise
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   m  The map to query
+ * @return  #EINA_TRUE if the output points are clockwise, 
+ *          otherwise #EINA_FALSE if the output points are not clockwise
  */
 EAPI Eina_Bool       evas_map_util_clockwise_get(Evas_Map *m);
 
 /**
- * Create map of transformation points to be later used with an Evas object.
+ * @brief   Creates a map of transformation points to be later used with an Evas object.
+ *
+ * @details This function creates a set of points (currently only 4 is supported and no other
+ *          number for @a count works). That is empty and ready to be modified
+ *          with evas_map calls.
  *
- * This creates a set of points (currently only 4 is supported. no other
- * number for @p count will work). That is empty and ready to be modified
- * with evas_map calls.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param count number of points in the map.
- * @return a newly allocated map or @c NULL on errors.
+ * @param[in]   count  The number of points in the map
+ * @return  The newly allocated map, \n
+ *          otherwise @c NULL on errors
  *
  * @see evas_map_free()
  * @see evas_map_dup()
@@ -4867,102 +5487,182 @@ EAPI Eina_Bool       evas_map_util_clockwise_get(Evas_Map *m);
 EAPI Evas_Map       *evas_map_new(int count);
 
 /**
- * Set the smoothing for map rendering
+ * @brief   Sets the smoothing for map rendering.
  *
- * This sets smoothing for map rendering. If the object is a type that has
- * its own smoothing settings, then both the smooth settings for this object
- * and the map must be turned off. By default smooth maps are enabled.
+ * @details This function sets smoothing for map rendering. If the object is a type that has
+ *          its own smoothing settings, then both the smooth settings for this object
+ *          and the map must be turned off. By default, smooth maps are enabled.
  *
- * @param m map to modify. Must not be NULL.
- * @param enabled enable or disable smooth map rendering
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   m        The map to modify \n 
+ *                   This must not be @c NULL.
+ * @param[in]   enabled  Set #EINA_TRUE to enable smooth map rendering, \n
+ *                   otherwise set #EINA_FALSE not to enable smooth map rendering
  */
 EAPI void            evas_map_smooth_set(Evas_Map *m, Eina_Bool enabled);
 
 /**
- * get the smoothing for map rendering
+ * Checks whether the smoothing for map rendering is enabled.
+ *
+ * @details  This gets smoothing for map rendering.
  *
- * This gets smoothing for map rendering.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param m map to get the smooth from. Must not be NULL.
+ * @param[in]    m  The map for which to get the smoothing status \n 
+ *              This must not be @c NULL.
+ * @return   #EINA_TRUE if smoothing for map rendering is enabled, \n
+ *           otherwise #EINA_FALSE if smoothing for map rendering is not enabled
  */
 EAPI Eina_Bool       evas_map_smooth_get(const Evas_Map *m);
 
 /**
- * Set the alpha flag for map rendering
+ * @brief   Sets the alpha flag for map rendering.
  *
- * This sets alpha flag for map rendering. If the object is a type that has
- * its own alpha settings, then this will take precedence. Only image objects
- * have this currently.
- * Setting this off stops alpha blending of the map area, and is
- * useful if you know the object and/or all sub-objects is 100% solid.
+ * @details This function sets alpha flag for map rendering. If the object is a type that has
+ *          its own alpha settings, then this takes precedence. Only image objects
+ *          have this currently. Setting this off stops alpha blending of the map area, and is
+ *          useful if you know the object and/or all sub-objects is 100% solid.
  *
- * @param m map to modify. Must not be NULL.
- * @param enabled enable or disable alpha map rendering
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   m        The map to modify \n 
+ *                   This must not be @c NULL.
+ * @param[in]   enabled  Set #EINA_TRUE to enable alpha map rendering, \n
+ *                   otheriwse set #EINA_FALSE to disable alpha map rendering
  */
 EAPI void            evas_map_alpha_set(Evas_Map *m, Eina_Bool enabled);
 
 /**
- * get the alpha flag for map rendering
+ * @brief   Gets the alpha flag for map rendering.
+ *
+ * @details This gets the alpha flag for map rendering.
  *
- * This gets the alpha flag for map rendering.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param m map to get the alpha from. Must not be NULL.
+ * @param[in]   m  The map to get the alpha from \n
+ *             This must not be @c NULL.
+ * @return The alpha flag
  */
 EAPI Eina_Bool       evas_map_alpha_get(const Evas_Map *m);
 
 /**
- * Copy a previously allocated map.
+ * @internal
  *
- * This makes a duplicate of the @p m object and returns it.
+ * @brief   Set the flag of the object move synchronization for map rendering.
  *
- * @param m map to copy. Must not be NULL.
- * @return newly allocated map with the same count and contents as @p m.
+ * @details This sets the flag of the object move synchronization for map rendering.
+ *          If the flag is set as enabled, the map will be moved as the object of the map
+ *          is moved. By default, the flag of the object move synchronization is not
+ *          enabled.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif.1
+ *
+ * @param[in]   m  map to modify. Must not be NULL. \n
+ * @param[in]   enabled  enable or disable the object move synchronization for map \n
+ *              rendering.
+ */
+EAPI void            evas_map_util_object_move_sync_set(Evas_Map *m, Eina_Bool enabled);
+
+/**
+ * @internal
+ *
+ * @brief   Get the flag of the object move synchronization for map rendering
+ *
+ * @details This gets the flag of the object move synchronization for map rendering.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif.1
+ *
+ * @param[in]   m  map to get the flag of the object move synchronization from. Must \n
+ *              not be NULL.
+ * @return EINA_FALSE if map is NULL EINA_TRUE otherwise.
+ */
+EAPI Eina_Bool       evas_map_util_object_move_sync_get(const Evas_Map *m);
+
+/**
+ * @brief   Copies a previously allocated map.
+ *
+ * @details This makes a duplicate of the @a m object and returns it.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   m  The map to copy \n 
+ *             This must not be @c NULL.
+ * @return  The newly allocated map with the same count and contents as @a m
  */
 EAPI Evas_Map       *evas_map_dup(const Evas_Map *m);
 
 /**
- * Free a previously allocated map.
+ * @brief   Frees a previously allocated map.
+ *
+ * @details This function frees a given map @a m and all memory associated with it. You must NOT
+ *          free a map returned by evas_object_map_get() as this is internal.
  *
- * This frees a givem map @p m and all memory associated with it. You must NOT
- * free a map returned by evas_object_map_get() as this is internal.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param m map to free.
+ * @param[in]   m  The map to free
  */
 EAPI void            evas_map_free(Evas_Map *m);
 
 /**
- * Get a maps size.
+ * @brief   Gets a maps size.
  *
- * Returns the number of points in a map.  Should be at least 4.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param m map to get size.
- * @return -1 on error, points otherwise.
+ * @remarks This function returns the number of points in a map. It should be at least be @c 4.
+ *
+ * @param[in]   m  The map to get the size
+ * @return  The number of points in a map, \n
+ *          otherwise @c -1 on error
  */
 EAPI int             evas_map_count_get(const Evas_Map *m) EINA_CONST;
 
 /**
- * Change the map point's coordinate.
+ * @brief   Changes the map point's coordinate.
+ *
+ * @details This function sets the fixed point's coordinate in the map. Note that points
+ *          describe the outline of a quadrangle and are ordered either clockwise
+ *          or counter-clockwise. It is suggested to keep your quadrangles concave and
+ *          non-complex, though these polygon modes may work, they may not render
+ *          a desired set of output. The quadrangle uses points @c 0 and @c 1 , @c 1 and @c 2,
+ *          @c 2 and @c 3, and @c 3 and @c 0 to describe the edges of the quadrangle.
  *
- * This sets the fixed point's coordinate in the map. Note that points
- * describe the outline of a quadrangle and are ordered either clockwise
- * or anti-clock-wise. It is suggested to keep your quadrangles concave and
- * non-complex, though these polygon modes may work, they may not render
- * a desired set of output. The quadrangle will use points 0 and 1 , 1 and 2,
- * 2 and 3, and 3 and 0 to describe the edges of the quadrangle.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * The X and Y and Z coordinates are in canvas units. Z is optional and may
- * or may not be honored in drawing. Z is a hint and does not affect the
- * X and Y rendered coordinates. It may be used for calculating fills with
- * perspective correct rendering.
+ * @remarks The X, Y, and Z coordinates are in canvas units. Z is optional and may
+ *          or may not be honored in drawing. Z is a hint and does not affect the
+ *          X and Y rendered coordinates. It may be used for calculating fills with
+ *          perspective correct rendering.
  *
- * Remember all coordinates are canvas global ones like with move and resize
- * in evas.
+ * @remarks Remember all coordinates are canvas global ones like with move and resize in evas.
  *
- * @param m map to change point. Must not be @c NULL.
- * @param idx index of point to change. Must be smaller than map size.
- * @param x Point X Coordinate
- * @param y Point Y Coordinate
- * @param z Point Z Coordinate hint (pre-perspective transform)
+ * @param[in]   m    The map to change point \n 
+ *               This must not be @c NULL.
+ * @param[in]   idx  The index of point to change \n 
+ *               This must be smaller than map size.
+ * @param[in]   x    The X coordinate
+ * @param[in]   y    The Y coordinate
+ * @param[in]   z    The Z coordinate hint (pre-perspective transform)
  *
  * @see evas_map_util_rotate()
  * @see evas_map_util_zoom()
@@ -4972,31 +5672,40 @@ EAPI int             evas_map_count_get(const Evas_Map *m) EINA_CONST;
 EAPI void            evas_map_point_coord_set(Evas_Map *m, int idx, Evas_Coord x, Evas_Coord y, Evas_Coord z);
 
 /**
- * Get the map point's coordinate.
+ * @brief   Gets the map point's coordinate.
  *
- * This returns the coordinates of the given point in the map.
+ * @details This function returns the coordinates of the given point in the map.
  *
- * @param m map to query point.
- * @param idx index of point to query. Must be smaller than map size.
- * @param x where to return the X coordinate.
- * @param y where to return the Y coordinate.
- * @param z where to return the Z coordinate.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   m    The map to query point
+ * @param[in]   idx  The index of point to query \n 
+ *               This must be smaller than the map size.
+ * @param[out]   x    The X coordinate
+ * @param[out]   y    The Y coordinate
+ * @param[out]   z    The Z coordinate
  */
 EAPI void            evas_map_point_coord_get(const Evas_Map *m, int idx, Evas_Coord *x, Evas_Coord *y, Evas_Coord *z);
 
 /**
- * Change the map point's U and V texture source point
+ * @brief   Changes the map point's U and V texture source point.
+ *
+ * @details This sets the U and V coordinates for the point. This determines which
+ *          coordinate in the source image is mapped to the given point, much like
+ *          OpenGL and textures. Note that these points do select the pixel, but
+ *          are double floating point values to allow for accuracy and sub-pixel selection.
  *
- * This sets the U and V coordinates for the point. This determines which
- * coordinate in the source image is mapped to the given point, much like
- * OpenGL and textures. Notes that these points do select the pixel, but
- * are double floating point values to allow for accuracy and sub-pixel
- * selection.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param m map to change the point of.
- * @param idx index of point to change. Must be smaller than map size.
- * @param u the X coordinate within the image/texture source
- * @param v the Y coordinate within the image/texture source
+ * @param[in]   m    The map to change the point of
+ * @param[in]   idx  The index of point to change \n 
+ *               This must be smaller than map size.
+ * @param[in]   u    The X coordinate within the image or texture source
+ * @param[in]   v    The Y coordinate within the image or texture source
  *
  * @see evas_map_point_coord_set()
  * @see evas_object_map_set()
@@ -5006,32 +5715,42 @@ EAPI void            evas_map_point_coord_get(const Evas_Map *m, int idx, Evas_C
 EAPI void            evas_map_point_image_uv_set(Evas_Map *m, int idx, double u, double v);
 
 /**
- * Get the map point's U and V texture source points
+ * @brief   Gets the map point's U and V texture source points.
  *
- * This returns the texture points set by evas_map_point_image_uv_set().
+ * @details This function returns the texture points set by evas_map_point_image_uv_set().
  *
- * @param m map to query point.
- * @param idx index of point to query. Must be smaller than map size.
- * @param u where to write the X coordinate within the image/texture source
- * @param v where to write the Y coordinate within the image/texture source
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   m    The map to query point
+ * @param[in]   idx  The index of point to query \n 
+ *               This must be smaller than map size.
+ * @param[out]   u    The X coordinate within the image or texture source
+ * @param[out]   v    The Y coordinate within the image or texture source
  */
 EAPI void            evas_map_point_image_uv_get(const Evas_Map *m, int idx, double *u, double *v);
 
 /**
- * Set the color of a vertex in the map
+ * @brief   Sets the color of a vertex in the map.
+ *
+ * @details This sets the color of the vertex in the map. Colors are linearly
+ *          interpolated between vertex points through the map. Color multiplies
+ *          the "texture" pixels (like GL_MODULATE in OpenGL). The default color of
+ *          a vertex in a map is white solid (255, 255, 255, 255) which means it
+ *          has no affect on modifying the texture pixels.
  *
- * This sets the color of the vertex in the map. Colors will be linearly
- * interpolated between vertex points through the map. Color will multiply
- * the "texture" pixels (like GL_MODULATE in OpenGL). The default color of
- * a vertex in a map is white solid (255, 255, 255, 255) which means it will
- * have no affect on modifying the texture pixels.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param m map to change the color of.
- * @param idx index of point to change. Must be smaller than map size.
- * @param r red (0 - 255)
- * @param g green (0 - 255)
- * @param b blue (0 - 255)
- * @param a alpha (0 - 255)
+ * @param[in]   m    The map to change the color of
+ * @param[in]   idx  The index of point to change \n 
+ *               This must be smaller than the map size.
+ * @param[in]   r    The red color (0 - 255)
+ * @param[in]   g    The green color (0 - 255)
+ * @param[in]   b    The blue color (0 - 255)
+ * @param[in]   a    The alpha color (0 - 255)
  *
  * @see evas_map_util_points_color_set()
  * @see evas_map_point_coord_set()
@@ -5040,28 +5759,37 @@ EAPI void            evas_map_point_image_uv_get(const Evas_Map *m, int idx, dou
 EAPI void            evas_map_point_color_set(Evas_Map *m, int idx, int r, int g, int b, int a);
 
 /**
- * Get the color set on a vertex in the map
+ * @brief   Gets the color set on a vertex in the map.
  *
- * This gets the color set by evas_map_point_color_set() on the given vertex
- * of the map.
+ * @details This function gets the color set by evas_map_point_color_set() on the given vertex
+ *          of the map.
  *
- * @param m map to get the color of the vertex from.
- * @param idx index of point get. Must be smaller than map size.
- * @param r pointer to red return
- * @param g pointer to green return
- * @param b pointer to blue return
- * @param a pointer to alpha return (0 - 255)
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   m    The map to get the color of the vertex from
+ * @param[in]   idx  The index of point get \n 
+ *               This must be smaller than the map size.
+ * @param[out]   r    The pointer to red color
+ * @param[out]   g    The pointer to green color
+ * @param[out]   b    The pointer to blue color
+ * @param[out]   a    The pointer to alpha color (0 - 255)
  *
  * @see evas_map_point_coord_set()
  * @see evas_object_map_set()
  */
 EAPI void            evas_map_point_color_get(const Evas_Map *m, int idx, int *r, int *g, int *b, int *a);
+
 /**
  * @}
  */
 
 /**
  * @defgroup Evas_Object_Group_Size_Hints Size Hints
+ * @ingroup Evas_Object_Group
+ *
+ * @brief  This group provides functions for size hints.
  *
  * Objects may carry hints, so that another object that acts as a
  * manager (see @ref Evas_Smart_Object_Group) may know how to properly
@@ -5070,165 +5798,194 @@ EAPI void            evas_map_point_color_get(const Evas_Map *m, int idx, int *r
  * information.
  *
  * For example, box objects use alignment hints to align its
- * lines/columns inside its container, padding hints to set the
- * padding between each individual child, etc.
+ * lines or columns inside its container, padding hints to set the
+ * padding between each individual child, and so on.
  *
- * Examples on their usage:
- * - @ref Example_Evas_Size_Hints "evas-hints.c"
- * - @ref Example_Evas_Aspect_Hints "evas-aspect-hints.c"
- *
- * @ingroup Evas_Object_Group
- */
-
-/**
- * @addtogroup Evas_Object_Group_Size_Hints
  * @{
  */
 
 /**
- * Retrieves the hints for an object's minimum size.
+ * @brief   Gets the hints for an object's minimum size.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given Evas object to query hints from.
- * @param w Pointer to an integer in which to store the minimum width.
- * @param h Pointer to an integer in which to store the minimum height.
+ * @remarks These are hints on the minimim sizes @a obj should have. This is
+ *          not a size enforcement in any way. It is just a hint that should be
+ *          used whenever appropriate.
  *
- * These are hints on the minimim sizes @p obj should have. This is
- * not a size enforcement in any way, it's just a hint that should be
- * used whenever appropriate.
+ * @remarks Use @c NULL pointers on the hint components that you are not
+ *          interested in: they are ignored by the function.
  *
- * @note Use @c NULL pointers on the hint components you're not
- * interested in: they'll be ignored by the function.
+ * @param[in]   obj  The given Evas object to query hints from
+ * @param[out]   w    The pointer to an integer in which to store the minimum width
+ * @param[out]   h    The pointer to an integer in which to store the minimum height
  *
  * @see evas_object_size_hint_min_set() for an example
  */
 EAPI void evas_object_size_hint_min_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the hints for an object's minimum size.
+ * @brief   Sets the hints for an object's minimum size.
  *
- * @param obj The given Evas object to query hints from.
- * @param w Integer to use as the minimum width hint.
- * @param h Integer to use as the minimum height hint.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This is not a size enforcement in any way, it's just a hint that
- * should be used whenever appropriate.
+ * @remarks This is not a size enforcement in any way. It is just a hint that
+ *          should be used whenever appropriate.
  *
- * Values @c 0 will be treated as unset hint components, when queried
- * by managers.
+ * @remarks Values like @c 0 are treated as unset hint components, when queried
+ *          by managers.
  *
- * Example:
- * @dontinclude evas-hints.c
- * @skip evas_object_size_hint_min_set
- * @until return
- *
- * In this example the minimum size hints change the behavior of an
- * Evas box when layouting its children. See the full @ref
- * Example_Evas_Size_Hints "example".
+ * @param[in]   obj  The given Evas object to query hints from
+ * @param[in]   w    The integer to use as the minimum width hint
+ * @param[in]   h    The integer to use as the minimum height hint
  *
  * @see evas_object_size_hint_min_get()
  */
 EAPI void evas_object_size_hint_min_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the hints for an object's maximum size.
+ * @brief   Gets the hints for an object's maximum size.
  *
- * @param obj The given Evas object to query hints from.
- * @param w Pointer to an integer in which to store the maximum width.
- * @param h Pointer to an integer in which to store the maximum height.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * These are hints on the maximum sizes @p obj should have. This is
- * not a size enforcement in any way, it's just a hint that should be
- * used whenever appropriate.
+ * @remarks These are hints on the maximum sizes @a obj should have. This is
+ *          not a size enforcement in any way. It is just a hint that should be
+ *          used whenever appropriate.
  *
- * @note Use @c NULL pointers on the hint components you're not
- * interested in: they'll be ignored by the function.
+ * @remarks Use @c NULL pointers on the hint components that you are not
+ *          interested in: they are ignored by the function.
  *
+ * @param[in]   obj  The given Evas object to query hints from
+ * @param[out]   w    The pointer to an integer in which to store the maximum width
+ * @param[out]   h    The pointer to an integer in which to store the maximum height
  * @see evas_object_size_hint_max_set()
  */
 EAPI void evas_object_size_hint_max_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the hints for an object's maximum size.
- *
- * @param obj The given Evas object to query hints from.
- * @param w Integer to use as the maximum width hint.
- * @param h Integer to use as the maximum height hint.
- *
- * This is not a size enforcement in any way, it's just a hint that
- * should be used whenever appropriate.
+ * @brief   Sets the hints for an object's maximum size.
  *
- * Values @c -1 will be treated as unset hint components, when queried
- * by managers.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Example:
- * @dontinclude evas-hints.c
- * @skip evas_object_size_hint_max_set
- * @until return
+ * @remarks This is not a size enforcement in any way. It is just a hint that
+ *          should be used whenever appropriate.
  *
- * In this example the maximum size hints change the behavior of an
- * Evas box when layouting its children. See the full @ref
- * Example_Evas_Size_Hints "example".
+ * @remarks Values like @c -1 are treated as unset hint components, when queried
+ *          by managers.
  *
+ * @param[in]   obj  The given Evas object to query hints from
+ * @param[in]   w    The integer to use as the maximum width hint
+ * @param[in]   h    The integer to use as the maximum height hint
  * @see evas_object_size_hint_max_get()
  */
 EAPI void evas_object_size_hint_max_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the hints for an object's optimum size.
+ * @brief   Gets the hints for an object's display mode.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks These are hints on the display mode @a obj. This is
+ *          not a size enforcement in any way. It is just a hint that can be
+ *          used whenever appropriate. This mode can be used with object's display 
+ *          mode like compress or expand.
+ *
+ * @param[in]   obj  The given Evas object to query hints from
+ * @return The display mode hints
+ *
+ * @see evas_object_size_hint_display_mode_set()
+ */
+EAPI Evas_Display_Mode evas_object_size_hint_display_mode_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief   Sets the hints for an object's display mode.
  *
- * @param obj The given Evas object to query hints from.
- * @param w Pointer to an integer in which to store the requested width.
- * @param h Pointer to an integer in which to store the requested height.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * These are hints on the optimum sizes @p obj should have. This is
- * not a size enforcement in any way, it's just a hint that should be
- * used whenever appropriate.
+ * @remarks This is not a size enforcement in any way. It is just a hint that
+ *          can be used whenever appropriate.
  *
- * @note Use @c NULL pointers on the hint components you're not
- * interested in: they'll be ignored by the function.
+ * @param[in]   obj       The given Evas object to query hints from
+ * @param[in]   dispmode  The display mode hint
+ *
+ * @see evas_object_size_hint_display_mode_get()
+ */
+EAPI void evas_object_size_hint_display_mode_set(Evas_Object *obj, Evas_Display_Mode dispmode) EINA_ARG_NONNULL(1);
+
+/**
+ * @internal
+ * @brief   Gets the hints for an object's optimum size.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks These are hints on the optimum sizes @a obj should have. This is
+ *          not a size enforcement in any way. It is just a hint that should be
+ *          used whenever appropriate.
+ *
+ * @remarks Use @c NULL pointers on the hint components that you are not
+ *          interested in: they are ignored by the function.
+ *
+ * @param[in]   obj  The given Evas object to query hints from
+ * @param[out]   w    The pointer to an integer in which to store the requested width
+ * @param[out]   h    The pointer to an integer in which to store the requested height
  *
  * @see evas_object_size_hint_request_set()
  */
 EAPI void evas_object_size_hint_request_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the hints for an object's optimum size.
+ * @internal
+ * @brief   Sets the hints for an object's optimum size.
  *
- * @param obj The given Evas object to query hints from.
- * @param w Integer to use as the preferred width hint.
- * @param h Integer to use as the preferred height hint.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This is not a size enforcement in any way, it's just a hint that
- * should be used whenever appropriate.
+ * @remarks This is not a size enforcement in any way. It is just a hint that
+ *          should be used whenever appropriate.
  *
- * Values @c 0 will be treated as unset hint components, when queried
- * by managers.
+ * @remarks Values like @c 0 are treated as unset hint components, when queried
+ *          by managers.
+ *
+ * @param[in]   obj  The given Evas object to query hints from
+ * @param[in]   w    The integer to use as the preferred width hint
+ * @param[in]   h    The integer to use as the preferred height hint
  *
  * @see evas_object_size_hint_request_get()
  */
 EAPI void evas_object_size_hint_request_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the hints for an object's aspect ratio.
+ * @brief   Gets the hints for an object's aspect ratio.
  *
- * @param obj The given Evas object to query hints from.
- * @param aspect Returns the policy/type of aspect ratio applied to @p obj.
- * @param w Pointer to an integer in which to store the aspect's width
- * ratio term.
- * @param h Pointer to an integer in which to store the aspect's
- * height ratio term.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * The different aspect ratio policies are documented in the
- * #Evas_Aspect_Control type. A container respecting these size hints
- * would @b resize its children accordingly to those policies.
+ * @remarks The different aspect ratio policies are documented in the
+ *          #Evas_Aspect_Control type. A container respecting these size hints
+ *          would @b resize its children accordingly to those policies.
  *
- * For any policy, if any of the given aspect ratio terms are @c 0,
- * the object's container should ignore the aspect and scale @p obj to
- * occupy the whole available area. If they are both positive
- * integers, that proportion will be respected, under each scaling
- * policy.
+ * @remarks For any policy, if any of the given aspect ratio terms are @c 0,
+ *          the object's container should ignore the aspect and scale @a obj to
+ *          occupy the whole available area. If they are both positive
+ *          integers, that proportion is respected, under each scaling policy.
  *
- * These images illustrate some of the #Evas_Aspect_Control policies:
+ * @remarks These images illustrate some of the #Evas_Aspect_Control policies:
  *
  * @image html any-policy.png
  * @image rtf any-policy.png
@@ -5246,104 +6003,106 @@ EAPI void evas_object_size_hint_request_set(Evas_Object *obj, Evas_Coord w, Evas
  * @image rtf aspect-control-horizontal.png
  * @image latex aspect-control-horizontal.eps
  *
- * This is not a size enforcement in any way, it's just a hint that
- * should be used whenever appropriate.
- *
- * @note Use @c NULL pointers on the hint components you're not
- * interested in: they'll be ignored by the function.
+ * @remarks This is not a size enforcement in any way. It is just a hint that
+ *          should be used whenever appropriate.
  *
- * Example:
- * @dontinclude evas-aspect-hints.c
- * @skip if (strcmp(ev->keyname, "c") == 0)
- * @until }
+ * @remarks Use @c NULL pointers on the hint components that you are not
+ *          interested in: they are ignored by the function.
  *
- * See the full @ref Example_Evas_Aspect_Hints "example".
+ * @param[in]   obj     The given Evas object to query hints from
+ * @param[out]   aspect  The policy or type of aspect ratio applied to @a obj that is returned
+ * @param[out]   w       The pointer to an integer in which to store the aspect's width
+ *                  ratio term
+ * @param[out]   h       The pointer to an integer in which to store the aspect's
+ *                  height ratio term
  *
  * @see evas_object_size_hint_aspect_set()
  */
 EAPI void evas_object_size_hint_aspect_get(const Evas_Object *obj, Evas_Aspect_Control *aspect, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the hints for an object's aspect ratio.
+ * @brief   Sets the hints for an object's aspect ratio.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given Evas object to query hints from.
- * @param aspect The policy/type of aspect ratio to apply to @p obj.
- * @param w Integer to use as aspect width ratio term.
- * @param h Integer to use as aspect height ratio term.
+ * @remarks This is not a size enforcement in any way. It is just a hint that should
+ *          be used whenever appropriate.
  *
- * This is not a size enforcement in any way, it's just a hint that should
- * be used whenever appropriate.
+ * @remarks If any of the given aspect ratio terms are @c 0,
+ *          the object's container ignores the aspect and scale @a obj to
+ *          occupy the whole available area, for any given policy.
  *
- * If any of the given aspect ratio terms are @c 0,
- * the object's container will ignore the aspect and scale @p obj to
- * occupy the whole available area, for any given policy.
+ * @param[in]   obj     The given Evas object to query hints from
+ * @param[in]   aspect  The policy or type of aspect ratio to apply to @a obj
+ * @param[in]   w       The integer to use as aspect width ratio term
+ * @param[in]   h       The integer to use as aspect height ratio term
  *
  * @see evas_object_size_hint_aspect_get() for more information.
  */
 EAPI void evas_object_size_hint_aspect_set(Evas_Object *obj, Evas_Aspect_Control aspect, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the hints for on object's alignment.
+ * @brief   Gets the hints for the object's alignment.
  *
- * @param obj The given Evas object to query hints from.
- * @param x Pointer to a double in which to store the horizontal
- * alignment hint.
- * @param y Pointer to a double in which to store the vertical
- * alignment hint.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This is not a size enforcement in any way, it's just a hint that
- * should be used whenever appropriate.
+ * @remarks This is not a size enforcement in any way. It is just a hint that
+ *          should be used whenever appropriate.
  *
- * @note Use @c NULL pointers on the hint components you're not
- * interested in: they'll be ignored by the function.
- * @note If @c obj is invalid, then the hint components will be set with 0.5
+ * @remarks Use @c NULL pointers on the hint components that you are not
+ *          interested in: they are ignored by the function.
+ * @remarks If @c obj is invalid, then the hint components are set with @c 0.5
+ *
+ * @param[in]   obj  The given Evas object to query hints from
+ * @param[out]   x    The pointer to a double in which to store the horizontal alignment hint
+ * @param[out]   y    The pointer to a double in which to store the vertical alignment hint
  *
  * @see evas_object_size_hint_align_set() for more information
  */
 EAPI void evas_object_size_hint_align_get(const Evas_Object *obj, double *x, double *y) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the hints for an object's alignment.
+ * @brief   Sets the hints for an object's alignment.
  *
- * @param obj The given Evas object to query hints from.
- * @param x Double, ranging from @c 0.0 to @c 1.0 or with the
- * special value #EVAS_HINT_FILL, to use as horizontal alignment hint.
- * @param y Double, ranging from @c 0.0 to @c 1.0 or with the
- * special value #EVAS_HINT_FILL, to use as vertical alignment hint.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * These are hints on how to align an object <b>inside the boundaries
- * of a container/manager</b>. Accepted values are in the @c 0.0 to @c
- * 1.0 range, with the special value #EVAS_HINT_FILL used to specify
- * "justify" or "fill" by some users. In this case, maximum size hints
- * should be enforced with higher priority, if they are set. Also, any
- * padding hint set on objects should add up to the alignment space on
- * the final scene composition.
+ * @remarks These are hints on how to align an object <b>inside the boundaries
+ *          of a container/manager</b>. Accepted values are in the @c 0.0 to @c
+ *          1.0 range, with the special value #EVAS_HINT_FILL used to specify
+ *          "justify" or "fill" by some users. In this case, maximum size hints
+ *          should be enforced with higher priority, if they are set. Also, any
+ *          padding hint set on objects should add up to the alignment space on
+ *          the final scene composition.
  *
- * See documentation of possible users: in Evas, they are the @ref
- * Evas_Object_Box "box" and @ref Evas_Object_Table "table" smart
- * objects.
+ * @remarks See documentation of possible users: in Evas, they are the @ref
+ *          Evas_Object_Box "box" and @ref Evas_Object_Table "table" smart objects.
  *
- * For the horizontal component, @c 0.0 means to the left, @c 1.0
- * means to the right. Analogously, for the vertical component, @c 0.0
- * to the top, @c 1.0 means to the bottom.
+ * @remarks For the horizontal component, @c 0.0 means to the left, @c 1.0
+ *          means to the right. Analogously, for the vertical component, @c 0.0
+ *          to the top, @c 1.0 means to the bottom.
  *
- * See the following figure:
+ * @remarks See the following figure:
  *
  * @image html alignment-hints.png
  * @image rtf alignment-hints.png
  * @image latex alignment-hints.eps
  *
- * This is not a size enforcement in any way, it's just a hint that
- * should be used whenever appropriate.
+ * @remarks This is not a size enforcement in any way. It is just a hint that
+ *          should be used whenever appropriate.
  *
- * Example:
- * @dontinclude evas-hints.c
- * @skip evas_object_size_hint_align_set
- * @until return
+ * @remarks The default alignment hint values are @c 0.5, for both axis.
  *
- * In this example the alignment hints change the behavior of an Evas
- * box when layouting its children. See the full @ref
- * Example_Evas_Size_Hints "example".
+ * @param[in]   obj  The given Evas object to query hints from
+ * @param[in]   x    The horizontal alignment hint as double value ranging from @c 0.0 to @c 1.0 or with the
+ *               special value #EVAS_HINT_FILL
+ * @param[in]   y    The vertical alignment hint as double value ranging from @c 0.0 to @c 1.0 or with the
+ *               special value #EVAS_HINT_FILL 
  *
  * @see evas_object_size_hint_align_get()
  * @see evas_object_size_hint_max_set()
@@ -5352,110 +6111,109 @@ EAPI void evas_object_size_hint_align_get(const Evas_Object *obj, double *x, dou
 EAPI void evas_object_size_hint_align_set(Evas_Object *obj, double x, double y) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the hints for an object's weight.
+ * @brief   Gets the hints for an object's weight.
  *
- * @param obj The given Evas object to query hints from.
- * @param x Pointer to a double in which to store the horizontal weight.
- * @param y Pointer to a double in which to store the vertical weight.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Accepted values are zero or positive values. Some users might use
- * this hint as a boolean, but some might consider it as a @b
- * proportion, see documentation of possible users, which in Evas are
- * the @ref Evas_Object_Box "box" and @ref Evas_Object_Table "table"
- * smart objects.
+ * @remarks Accepted values are @c 0 or positive values. Some users might use
+ *          this hint as a boolean, but some might consider it as a @b
+ *          proportion. See documentation of possible users, which in Evas are
+ *          the @ref Evas_Object_Box "box" and @ref Evas_Object_Table "table"
+ *          smart objects.
  *
- * This is not a size enforcement in any way, it's just a hint that
- * should be used whenever appropriate.
+ * @remarks This is not a size enforcement in any way. It is just a hint that
+ *          should be used whenever appropriate.
  *
- * @note Use @c NULL pointers on the hint components you're not
- * interested in: they'll be ignored by the function.
- * @note If @c obj is invalid, then the hint components will be set with 0.0
+ * @remarks Use @c NULL pointers on the hint components that you are not
+ *          interested in: they are ignored by the function.
+ * @remarks If @c obj is invalid, then the hint components are set with @c 0.0
+ *
+ * @param[in]   obj  The given Evas object to query hints from
+ * @param[out]   x    The pointer to a double in which to store the horizontal weight
+ * @param[out]   y    The pointer to a double in which to store the vertical weight
  *
  * @see evas_object_size_hint_weight_set() for an example
  */
 EAPI void evas_object_size_hint_weight_get(const Evas_Object *obj, double *x, double *y) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the hints for an object's weight.
+ * @brief   Sets the hints for an object's weight.
  *
- * @param obj The given Evas object to query hints from.
- * @param x Nonnegative double value to use as horizontal weight hint.
- * @param y Nonnegative double value to use as vertical weight hint.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This is not a size enforcement in any way, it's just a hint that
- * should be used whenever appropriate.
+ * @remarks This is not a size enforcement in any way. It is just a hint that
+ *          should be used whenever appropriate.
  *
- * This is a hint on how a container object should @b resize a given
- * child within its area. Containers may adhere to the simpler logic
- * of just expanding the child object's dimensions to fit its own (see
- * the #EVAS_HINT_EXPAND helper weight macro) or the complete one of
- * taking each child's weight hint as real @b weights to how much of
- * its size to allocate for them in each axis. A container is supposed
- * to, after @b normalizing the weights of its children (with weight
- * hints), distribute the space it has to layout them by those factors
- * -- most weighted children get larger in this process than the least
- * ones.
+ * @remarks This is a hint on how a container object should @b resize a given
+ *          child within its area. Containers may adhere to the simpler logic
+ *          of just expanding the child object's dimensions to fit its own (see
+ *          the #EVAS_HINT_EXPAND helper weight macro) or the complete one of
+ *          taking each child's weight hint as real @b weights to how much of
+ *          its size to allocate for them in each axis. A container is supposed
+ *          to, after @b normalizing the weights of its children (with weight
+ *          hints), distribute the space it has to layout them by those factors
+ *          -- most weighted children get larger in this process than the least ones.
  *
- * Example:
- * @dontinclude evas-hints.c
- * @skip evas_object_size_hint_weight_set
- * @until return
+ * @remarks Default weight hint values are @c 0.0, for both axis.
  *
- * In this example the weight hints change the behavior of an Evas box
- * when layouting its children. See the full @ref
- * Example_Evas_Size_Hints "example".
+ * @param[in]   obj  The given Evas object to query hints from
+ * @param[in]   x    The non-negative double value to use as horizontal weight hint
+ * @param[in]   y    The non-negative double value to use as vertical weight hint
  *
  * @see evas_object_size_hint_weight_get() for more information
  */
 EAPI void evas_object_size_hint_weight_set(Evas_Object *obj, double x, double y) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the hints for an object's padding space.
+ * @brief   Gets the hints for an object's padding space.
  *
- * @param obj The given Evas object to query hints from.
- * @param l Pointer to an integer in which to store left padding.
- * @param r Pointer to an integer in which to store right padding.
- * @param t Pointer to an integer in which to store top padding.
- * @param b Pointer to an integer in which to store bottom padding.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Padding is extra space an object takes on each of its delimiting
- * rectangle sides, in canvas units. This space will be rendered
- * transparent, naturally, as in the following figure:
+ * @remarks Padding is extra space that an object takes on each of its delimiting
+ *          rectangle sides, in canvas units. This space is rendered
+ *          transparent, naturally, as in the following figure:
  *
  * @image html padding-hints.png
  * @image rtf padding-hints.png
  * @image latex padding-hints.eps
  *
- * This is not a size enforcement in any way, it's just a hint that
- * should be used whenever appropriate.
+ * @remarks This is not a size enforcement in any way. It is just a hint that
+ *          should be used whenever appropriate.
  *
- * @note Use @c NULL pointers on the hint components you're not
- * interested in: they'll be ignored by the function.
+ * @remarks Use @c NULL pointers on the hint components that you are not
+ *          interested in: they are ignored by the function.
  *
- * Example:
- * @dontinclude evas-hints.c
- * @skip evas_object_size_hint_padding_set
- * @until return
- *
- * In this example the padding hints change the behavior of an Evas box
- * when layouting its children. See the full @ref
- * Example_Evas_Size_Hints "example".
+ * @param[in]   obj  The given Evas object to query hints from
+ * @param[out]   l    The pointer to an integer in which to store left padding
+ * @param[out]   r    The pointer to an integer in which to store right padding
+ * @param[out]   t    The pointer to an integer in which to store top padding
+ * @param[out]   b    The pointer to an integer in which to store bottom padding
  *
  * @see evas_object_size_hint_padding_set()
  */
 EAPI void evas_object_size_hint_padding_get(const Evas_Object *obj, Evas_Coord *l, Evas_Coord *r, Evas_Coord *t, Evas_Coord *b) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the hints for an object's padding space.
+ * @brief   Sets the hints for an object's padding space.
  *
- * @param obj The given Evas object to query hints from.
- * @param l Integer to specify left padding.
- * @param r Integer to specify right padding.
- * @param t Integer to specify top padding.
- * @param b Integer to specify bottom padding.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This is not a size enforcement in any way, it's just a hint that
- * should be used whenever appropriate.
+ * @remarks This is not a size enforcement in any way. It is just a hint that
+ *          should be used whenever appropriate.
+ *
+ * @param[in]   obj  The given Evas object to query hints from
+ * @param[in]   l    The integer to specify left padding
+ * @param[in]   r    The integer to specify right padding
+ * @param[in]   t    The integer to specify top padding
+ * @param[in]   b    The integer to specify bottom padding
  *
  * @see evas_object_size_hint_padding_get() for more information
  */
@@ -5467,49 +6225,44 @@ EAPI void evas_object_size_hint_padding_set(Evas_Object *obj, Evas_Coord l, Evas
 
 /**
  * @defgroup Evas_Object_Group_Extras Extra Object Manipulation
+ * @ingroup Evas_Object_Group
+ *
+ * @brief  This group provides functions for extra object manipulation.
  *
  * Miscellaneous functions that also apply to any object, but are less
  * used or not implemented by all objects.
  *
- * Examples on this group of functions can be found @ref
- * Example_Evas_Stacking "here" and @ref Example_Evas_Events "here".
- *
- * @ingroup Evas_Object_Group
- */
-
-/**
- * @addtogroup Evas_Object_Group_Extras
  * @{
  */
 
 /**
- * Set an attached data pointer to an object with a given string key.
+ * @brief   Sets an attached data pointer to an object with a given string key.
  *
- * @param obj The object to attach the data pointer to
- * @param key The string key for the data to access it
- * @param data The pointer to the data to be attached
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This attaches the pointer @p data to the object @p obj, given the
- * access string @p key. This pointer will stay "hooked" to the object
- * until a new pointer with the same string key is attached with
- * evas_object_data_set() or it is deleted with
- * evas_object_data_del(). On deletion of the object @p obj, the
- * pointers will not be accessible from the object anymore.
+ * @remarks This attaches the pointer @a data to the object @a obj, given the
+ *          access string @a key. This pointer stays "hooked" to the object
+ *          until a new pointer with the same string key is attached with
+ *          evas_object_data_set() or it is deleted with
+ *          evas_object_data_del(). On deletion of the object @a obj, the
+ *          pointers is not accessible from the object anymore.
  *
- * You can find the pointer attached under a string key using
- * evas_object_data_get(). It is the job of the calling application to
- * free any data pointed to by @p data when it is no longer required.
+ * @remarks You can find the pointer attached under a string key using
+ *          evas_object_data_get(). It is the job of the calling application to
+ *          free any data pointed to by @a data when it is no longer required.
  *
- * If @p data is @c NULL, the old value stored at @p key will be
- * removed but no new value will be stored. This is synonymous with
- * calling evas_object_data_del() with @p obj and @p key.
+ * @remarks If @a data is @c NULL, the old value stored at @a key is
+ *          removed but no new value is stored. This is synonymous with
+ *          calling evas_object_data_del() with @a obj and @a key.
  *
- * @note This function is very handy when you have data associated
- * specifically to an Evas object, being of use only when dealing with
- * it. Than you don't have the burden to a pointer to it elsewhere,
- * using this family of functions.
+ * @remarks This function is very handy when you have data associated
+ *          specifically to an Evas object, being of use only when dealing with
+ *          it. You do not have the burden to a pointer to it elsewhere,
+ *          using this family of functions.
  *
- * Example:
+ * @remarks The following is an example:
  *
  * @code
  * int *my_data;
@@ -5517,54 +6270,64 @@ EAPI void evas_object_size_hint_padding_set(Evas_Object *obj, Evas_Coord l, Evas
  *
  * my_data = malloc(500);
  * evas_object_data_set(obj, "name_of_data", my_data);
- * printf("The data that was attached was %p\n", evas_object_data_get(obj, "name_of_data"));
+ * printf("The data that is attached is %p\n", evas_object_data_get(obj, "name_of_data"));
  * @endcode
+ *
+ * @param[in]   obj   The object to attach the data pointer to
+ * @param[in]   key   The string key for the data to access it
+ * @param[in]   data  The pointer to the data to be attached
+ *
  */
 EAPI void                     evas_object_data_set(Evas_Object *obj, const char *key, const void *data) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Return an attached data pointer on an Evas object by its given
- * string key.
+ * @brief   Gets an attached data pointer on an Evas object by its given
+ *          string key.
  *
- * @param obj The object to which the data was attached
- * @param key The string key the data was stored under
- * @return The data pointer stored, or @c NULL if none was stored
+ * @details This function returns the data pointer attached to the object
+ *          @a obj, stored using the string key @a key. If the object is valid
+ *          and a data pointer is stored under the given key, that pointer
+ *          is returned. If this is not the case, @c NULL is
+ *          returned, signifying an invalid object or a non-existent key. It is
+ *          possible that a @c NULL pointer is stored given that key, but this
+ *          situation is not probable and thus can be considered an error as
+ *          well. @c NULL pointers are never stored as this is the return value
+ *          if an error occurs.
  *
- * This function will return the data pointer attached to the object
- * @p obj, stored using the string key @p key. If the object is valid
- * and a data pointer was stored under the given key, that pointer
- * will be returned. If this is not the case, @c NULL will be
- * returned, signifying an invalid object or a non-existent key. It is
- * possible that a @c NULL pointer was stored given that key, but this
- * situation is non-sensical and thus can be considered an error as
- * well. @c NULL pointers are never stored as this is the return value
- * if an error occurs.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Example:
+ * @remarks The following is an example:
  *
  * @code
  * int *my_data;
  * extern Evas_Object *obj;
  *
  * my_data = evas_object_data_get(obj, "name_of_my_data");
- * if (my_data) printf("Data stored was %p\n", my_data);
- * else printf("No data was stored on the object\n");
+ * if (my_data) printf("Data stored is %p\n", my_data);
+ * else printf("No data is stored on the object\n");
  * @endcode
+ *
+ * @param[in]   obj  The object to which the data is attached
+ * @param[in]   key  The string key the data is stored under
+ * @return  The data pointer stored, 
+ *          otherwise @c NULL if none are stored
  */
 EAPI void                    *evas_object_data_get(const Evas_Object *obj, const char *key) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
 
 /**
- * Delete an attached data pointer from an object.
+ * @brief   Deletes an attached data pointer from an object.
  *
- * @param obj The object to delete the data pointer from
- * @param key The string key the data was stored under
- * @return The original data pointer stored at @p key on @p obj
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This will remove the stored data pointer from @p obj stored under
- * @p key and return this same pointer, if actually there was data
- * there, or @c NULL, if nothing was stored under that key.
+ * @remarks This removes the stored data pointer from @a obj stored under
+ *          @a key and return this same pointer, if actually there is data
+ *          there, or @c NULL, if nothing is stored under that key.
  *
- * Example:
+ * @remarks The following is an example:
  *
  * @code
  * int *my_data;
@@ -5572,71 +6335,98 @@ EAPI void                    *evas_object_data_get(const Evas_Object *obj, const
  *
  * my_data = evas_object_data_del(obj, "name_of_my_data");
  * @endcode
+ *
+ * @param[in]   obj  The object to delete the data pointer from
+ * @param[in]   key  The string key the data is stored under
+ * @return  The original data pointer stored at @a key on @a obj
  */
 EAPI void                    *evas_object_data_del(Evas_Object *obj, const char *key) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Set pointer behavior.
+ * @brief   Sets the pointer behavior.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj
- * @param setting desired behavior.
+ * @remarks This function has direct effect on event callbacks related to mouse.
  *
- * This function has direct effect on event callbacks related to
- * mouse.
+ * @remarks If @a setting is @c EVAS_OBJECT_POINTER_MODE_AUTOGRAB, then when mouse
+ *          is down at this object, events are restricted to it as source,
+ *          mouse moves, for example, are emitted even if outside this
+ *          object area.
  *
- * If @p setting is EVAS_OBJECT_POINTER_MODE_AUTOGRAB, then when mouse
- * is down at this object, events will be restricted to it as source,
- * mouse moves, for example, will be emitted even if outside this
- * object area.
+ * @remarks If @a setting is @c EVAS_OBJECT_POINTER_MODE_NOGRAB, then events are
+ *          emitted just when inside this object area.
  *
- * If @p setting is EVAS_OBJECT_POINTER_MODE_NOGRAB, then events will
- * be emitted just when inside this object area.
+ * @remarks The default value is @c EVAS_OBJECT_POINTER_MODE_AUTOGRAB.
  *
- * The default value is EVAS_OBJECT_POINTER_MODE_AUTOGRAB.
+ * @param[in]   obj      The pointer for which behavior is set
+ * @param[in]   setting  The desired behavior
  *
  * @ingroup Evas_Object_Group_Extras
  */
 EAPI void                     evas_object_pointer_mode_set(Evas_Object *obj, Evas_Object_Pointer_Mode setting) EINA_ARG_NONNULL(1);
 
 /**
- * Determine how pointer will behave.
- * @param obj
- * @return pointer behavior.
+ * @brief   Gets how the pointer behaves.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The pointer
+ * @return  The pointer behavior
  * @ingroup Evas_Object_Group_Extras
  */
 EAPI Evas_Object_Pointer_Mode evas_object_pointer_mode_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Sets whether or not the given Evas object is to be drawn anti-aliased.
+ * @brief   Sets whether the given Evas object is to be drawn anti-aliased.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param   obj The given Evas object.
- * @param   antialias 1 if the object is to be anti_aliased, 0 otherwise.
+ * @param[in]   obj        The given Evas object
+ * @param[in]   antialias  Set #EINA_TRUE for the object to be anti-aliased, \n
+ *                     otherwise #EINA_FALSE for it not to be anti-aliased
  * @ingroup Evas_Object_Group_Extras
  */
 EAPI void                     evas_object_anti_alias_set(Evas_Object *obj, Eina_Bool antialias) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves whether or not the given Evas object is to be drawn anti_aliased.
- * @param   obj The given Evas object.
- * @return  @c 1 if the object is to be anti_aliased.  @c 0 otherwise.
+ * @brief   Checks whether the given Evas object is to be drawn anti-aliased.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given Evas object
+ * @return  #EINA_TRUE if the object is to be anti-aliased,
+ *          otherwise #EINA_FALSE if it is not to be anti-aliased
  * @ingroup Evas_Object_Group_Extras
  */
 EAPI Eina_Bool                evas_object_anti_alias_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Sets the scaling factor for an Evas object. Does not affect all
- * objects.
+ * @brief   Sets the scaling factor for an Evas object. \n
+ *          Does not affect all objects.
  *
- * @param obj The given Evas object.
- * @param scale The scaling factor. <c>1.0</c> means no scaling,
- *        default size.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This will multiply the object's dimension by the given factor, thus
- * altering its geometry (width and height). Useful when you want
- * scalable UI elements, possibly at run time.
+ * @remarks This multiplies the object's dimension by the given factor, thus
+ *          altering its geometry (width and height). This is useful when you want
+ *          scalable UI elements, possibly at run time.
  *
- * @note Only text and textblock objects have scaling change
- * handlers. Other objects won't change visually on this call.
+ * @remarks Only text and textblock objects have scaling change
+ *          handlers. Other objects do not change visually on this call.
+ *
+ * @param[in]   obj    The given Evas object
+ * @param[in]   scale  The scaling factor \n 
+ *                 <c>1.0</c> means no scaling, default size.
  *
  * @see evas_object_scale_get()
  *
@@ -5645,10 +6435,14 @@ EAPI Eina_Bool                evas_object_anti_alias_get(const Evas_Object *obj)
 EAPI void                     evas_object_scale_set(Evas_Object *obj, double scale) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the scaling factor for the given Evas object.
+ * @brief   Gets the scaling factor for the given Evas object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param   obj The given Evas object.
- * @return  The scaling factor.
+ * @param[in]   obj The given Evas object
+ * @return  The scaling factor
  *
  * @ingroup Evas_Object_Group_Extras
  *
@@ -5657,43 +6451,51 @@ EAPI void                     evas_object_scale_set(Evas_Object *obj, double sca
 EAPI double                   evas_object_scale_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Sets the render_op to be used for rendering the Evas object.
- * @param   obj The given Evas object.
- * @param   op one of the Evas_Render_Op values.
+ * @brief   Sets the render_op to be used for rendering the Evas object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given Evas object
+ * @param[in]   op   An Evas_Render_Op value
  * @ingroup Evas_Object_Group_Extras
  */
 EAPI void                     evas_object_render_op_set(Evas_Object *obj, Evas_Render_Op op) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the current value of the operation used for rendering the Evas object.
- * @param   obj The given Evas object.
- * @return  one of the enumerated values in Evas_Render_Op.
+ * @brief   Gets the current value of the operation used for rendering the Evas object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given Evas object
+ * @return  An enumerated value in Evas_Render_Op
  * @ingroup Evas_Object_Group_Extras
  */
 EAPI Evas_Render_Op           evas_object_render_op_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set whether to use precise (usually expensive) point collision
- * detection for a given Evas object.
+ * @brief   Sets whether to use precise (usually expensive) point collision
+ *          detection for a given Evas object.
  *
- * @param obj The given object.
- * @param precise Whether to use precise point collision detection or
- * not. The default value is false.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Use this function to make Evas treat objects' transparent areas as
- * @b not belonging to it with regard to mouse pointer events. By
- * default, all of the object's boundary rectangle will be taken in
- * account for them.
+ * @remarks Use this function to make Evas treat objects' transparent areas as
+ *          @b not belonging to it with regard to mouse pointer events. By
+ *          default, all of the object's boundary rectangle is taken into
+ *          account for them.
  *
- * @warning By using precise point collision detection you'll be
- * making Evas more resource intensive.
+ * @remarks By using precise point collision detection you are
+ *          making Evas more resource intensive.
  *
- * Example code follows.
- * @dontinclude evas-events.c
- * @skip if (strcmp(ev->keyname, "p") == 0)
- * @until }
- *
- * See the full example @ref Example_Evas_Events "here".
+ * @param[in]   obj      The given object
+ * @param[in]   precise  Set #EINA_TRUE to use precise point collision detection, \n 
+ *                   otherwise set #EINA_FALSE to not use it \n
+ *                   The default value is #EINA_FALSE.
  *
  * @see evas_object_precise_is_inside_get()
  * @ingroup Evas_Object_Group_Extras
@@ -5701,12 +6503,16 @@ EAPI Evas_Render_Op           evas_object_render_op_get(const Evas_Object *obj)
 EAPI void                     evas_object_precise_is_inside_set(Evas_Object *obj, Eina_Bool precise) EINA_ARG_NONNULL(1);
 
 /**
- * Determine whether an object is set to use precise point collision
- * detection.
+ * @brief   Checks whether an object is set to use precise point collision detection.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given object.
- * @return whether @p obj is set to use precise point collision
- * detection or not The default value is false.
+ * @param[in]   obj  The given object
+ * @return  #EINA_TRUE if @a obj is set to use precise point collision detection, \n 
+ *          otherwise #EINA_FALSE if it is not set to use \n 
+ *          The default value is #EINA_FALSE.
  *
  * @see evas_object_precise_is_inside_set() for an example
  *
@@ -5715,17 +6521,19 @@ EAPI void                     evas_object_precise_is_inside_set(Evas_Object *obj
 EAPI Eina_Bool                evas_object_precise_is_inside_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set a hint flag on the given Evas object that it's used as a "static
- * clipper".
+ * @brief   Sets a hint flag on the given Evas object that it is used as a "static clipper".
  *
- * @param obj The given object.
- * @param is_static_clip @c EINA_TRUE if it's to be used as a static
- * clipper, @c EINA_FALSE otherwise.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This is a hint to Evas that this object is used as a big static
- * clipper and shouldn't be moved with children and otherwise
- * considered specially. The default value for new objects is
- * @c EINA_FALSE.
+ * @remarks This is a hint to Evas that this object is used as a big static
+ *          clipper and should not be moved with children and otherwise
+ *          considered specially. The default value for new objects is #EINA_FALSE.
+ *
+ * @param[in]   obj             The given object
+ * @param[in]   is_static_clip  Set #EINA_TRUE if it is to be used as a static clipper, \n
+ *                          otherwise set #EINA_FALSE
  *
  * @see evas_object_static_clip_get()
  *
@@ -5734,11 +6542,15 @@ EAPI Eina_Bool                evas_object_precise_is_inside_get(const Evas_Objec
 EAPI void                     evas_object_static_clip_set(Evas_Object *obj, Eina_Bool is_static_clip) EINA_ARG_NONNULL(1);
 
 /**
- * Get the "static clipper" hint flag for a given Evas object.
+ * @brief   Gets the "static clipper" hint flag for a given Evas object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given object.
- * @return @c EINA_TRUE if it's set as a static clipper,
- * @c EINA_FALSE otherwise.
+ * @param[in]   obj  The given object
+ * @return  #EINA_TRUE if it is set as a static clipper, \n
+ *          otheriwse #EINA_FALSE
  *
  * @see evas_object_static_clip_set() for more details
  *
@@ -5751,234 +6563,253 @@ EAPI Eina_Bool                evas_object_static_clip_get(const Evas_Object *obj
  */
 
 /**
+ * @internal
  * @defgroup Evas_Object_Group_Find Finding Objects
+ * @ingroup Evas_Object_Group
  *
- * Functions that allows finding objects by their position, name or
- * other properties.
+ * @brief   This group provides functions for finding objects.
+ *          Functions that allows finding objects by their position, name or
+ *          other properties.
  *
- * @ingroup Evas_Object_Group
- */
-
-/**
- * @addtogroup Evas_Object_Group_Find
  * @{
  */
 
 /**
- * Retrieve the object that currently has focus.
+ * @brief   Gets the object that currently has focus.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The Evas canvas to query for focused object on.
- * @return The object that has focus or @c NULL if there is not one.
+ * @remarks Evas can have (at most) one of its objects focused at a time.
+ *          Focused objects are the ones having <b>key events</b> delivered
+ *          to, which the programmer can act upon by means of
+ *          evas_object_event_callback_add() usage.
  *
- * Evas can have (at most) one of its objects focused at a time.
- * Focused objects will be the ones having <b>key events</b> delivered
- * to, which the programmer can act upon by means of
- * evas_object_event_callback_add() usage.
+ * @remarks Mostly you would not be dealing directly with Evas focused
+ *          objects. Instead, you would be using a higher level library for
+ *          that (like a toolkit, as Elementary) to handle focus and who is
+ *          receiving input for them.
  *
- * @note Most users wouldn't be dealing directly with Evas' focused
- * objects. Instead, they would be using a higher level library for
- * that (like a toolkit, as Elementary) to handle focus and who's
- * receiving input for them.
+ * @remarks This call returns the object that currently has focus on the canvas
+ *          @a e or @c NULL, if none.
  *
- * This call returns the object that currently has focus on the canvas
- * @p e or @c NULL, if none.
+ * @param[in]   e  The Evas canvas to query for focused object
+ * @return  The object that has focus, \n 
+ *          otherwise @c NULL if there is no object that has focus
  *
  * @see evas_object_focus_set
  * @see evas_object_focus_get
  * @see evas_object_key_grab
  * @see evas_object_key_ungrab
- *
- * Example:
- * @dontinclude evas-events.c
- * @skip evas_event_callback_add(d.canvas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
- * @until evas_object_focus_set(d.bg, EINA_TRUE);
- * @dontinclude evas-events.c
- * @skip called when our rectangle gets focus
- * @until }
- *
- * In this example the @c event_info is exactly a pointer to that
- * focused rectangle. See the full @ref Example_Evas_Events "example".
- *
  * @ingroup Evas_Object_Group_Find
  */
 EAPI Evas_Object *evas_focus_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the object on the given evas with the given name.
- * @param   e    The given evas.
- * @param   name The given name.
- * @return  If successful, the Evas object with the given name.  Otherwise,
- *          @c NULL.
+ * @brief   Gets the object on the given evas with the given name.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This looks for the evas object given a name by evas_object_name_set(). If
- * the name is not unique canvas-wide, then which one of the many objects
- * with that name is returned is undefined, so only use this if you can ensure
- * the object name is unique.
+ * @remarks This looks for the evas object given a name by evas_object_name_set(). If
+ *          the name is not unique canvas-wide, then which one of the many objects
+ *          with that name is returned is undefined. So only use this if you can ensure
+ *          the object name is unique.
+ *
+ * @param[in]   e     The given evas
+ * @param[in]   name  The given name
+ * @return  The Evas object with the given name, \n  
+ *          otherwise @c NULL on failure
  *
  * @ingroup Evas_Object_Group_Find
  */
 EAPI Evas_Object *evas_object_name_find(const Evas *e, const char *name) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the object from children of the given object with the given name.
- * @param   obj  The parent (smart) object whose children to search.
- * @param   name The given name.
- * @param   recurse Set to the number of child levels to recurse (0 == don't recurse, 1 == only look at the children of @p obj or their immediate children, but no further etc.).
- * @return  If successful, the Evas object with the given name.  Otherwise,
- *          @c NULL.
+ * @brief   Gets the object from children of the given object with the given name.
  *
- * This looks for the evas object given a name by evas_object_name_set(), but
- * it ONLY looks at the children of the object *p obj, and will only recurse
- * into those children if @p recurse is greater than 0. If the name is not
- * unique within immediate children (or the whole child tree) then it is not
- * defined which child object will be returned. If @p recurse is set to -1 then
- * it will recurse without limit.
+ * @details This function looks for the evas object, which has its name set using evas_object_name_set(), but
+ *          it ONLY looks at the children of the object @a obj, and only recurse
+ *          into those children if @a recurse is greater than @c 0. If the name is not
+ *          unique within immediate children (or the whole child tree) then it is not
+ *          defined which child object is returned. If @a recurse is set to @c -1 then
+ *          it recurses without limit.
+ * @since   1.2
  *
- * @since 1.2
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj      The parent (smart) object whose children to search
+ * @param[in]   name     The given name
+ * @param[in]   recurse  Set to the number of child levels to recurse \n
+ *                   (0 == do not recurse, \n
+ *                   1 == only look at the children of @a obj or their immediate children and no further etc.).
+ * @return  The Evas object with the given name, \n 
+ *          otherwise @c NULL on failure
  *
  * @ingroup Evas_Object_Group_Find
  */
 EAPI Evas_Object *evas_object_name_child_find(const Evas_Object *obj, const char *name, int recurse) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve the Evas object stacked at the top of a given position in
- * a canvas
+ * @brief   Gets the Evas object stacked at the top of a given position in a canvas.
  *
- * @param   e A handle to the canvas.
- * @param   x The horizontal coordinate of the position
- * @param   y The vertical coordinate of the position
- * @param   include_pass_events_objects Boolean flag to include or not
- * objects which pass events in this calculation
- * @param   include_hidden_objects Boolean flag to include or not hidden
- * objects in this calculation
- * @return  The Evas object that is over all other objects at the given
- * position.
+ * @details This function traverses all the layers of the given canvas,
+ *          from top to bottom, querying for objects with areas covering the
+ *          given position. The user can remove from the query
+ *          objects which are hidden and/or which are set to pass events.
  *
- * This function will traverse all the layers of the given canvas,
- * from top to bottom, querying for objects with areas covering the
- * given position. The user can remove from from the query
- * objects which are hidden and/or which are set to pass events.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @warning This function will @b skip objects parented by smart
- * objects, acting only on the ones at the "top level", with regard to
- * object parenting.
+ * @remarks This function @b skips objects parented by smart
+ *          objects, acting only on the ones at the "top level", with regard to
+ *          object parenting.
+ *
+ * @param[in]   e                            A handle to the canvas
+ * @param[in]   x                            The horizontal coordinate of the position
+ * @param[in]   y                            The vertical coordinate of the position
+ * @param[in]   include_pass_events_objects  Set #EINA_TRUE to include objects which pass events in this calculation, \n
+ *                                       otherwise set #EINA_FALSE to not include the objects
+ * @param[in]   include_hidden_objects       Set #EINA_TRUE to include hidden objects in this calculation, \n
+ *                                       otherwise set #EINA_FALSE to not include hidden objects 
+ * @return  The Evas object that is over all other objects at the given position
  */
 EAPI Evas_Object *evas_object_top_at_xy_get(const Evas *e, Evas_Coord x, Evas_Coord y, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve the Evas object stacked at the top at the position of the
- * mouse cursor, over a given canvas
+ * @brief   Gets the Evas object stacked at the top at the position of the
+ *          mouse cursor, over a given canvas.
+ *
+ * @details This function traverses all the layers of the given canvas,
+ *          from top to bottom, querying for objects with areas covering the
+ *          mouse pointer's position, over @a e.
  *
- * @param   e A handle to the canvas.
- * @return  The Evas object that is over all other objects at the mouse
- * pointer's position
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function will traverse all the layers of the given canvas,
- * from top to bottom, querying for objects with areas covering the
- * mouse pointer's position, over @p e.
+ * @remarks This function @b skips objects parented by smart
+ *          objects, acting only on the ones at the "top level", with regard to
+ *          object parenting.
  *
- * @warning This function will @b skip objects parented by smart
- * objects, acting only on the ones at the "top level", with regard to
- * object parenting.
+ * @param[in]   e  A handle to the canvas
+ * @return  The Evas object that is over all other objects at the mouse pointer's position
  */
 EAPI Evas_Object *evas_object_top_at_pointer_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve the Evas object stacked at the top of a given rectangular
- * region in a canvas
- *
- * @param   e A handle to the canvas.
- * @param   x The top left corner's horizontal coordinate for the
- * rectangular region
- * @param   y The top left corner's vertical coordinate for the
- * rectangular region
- * @param   w The width of the rectangular region
- * @param   h The height of the rectangular region
- * @param   include_pass_events_objects Boolean flag to include or not
- * objects which pass events in this calculation
- * @param   include_hidden_objects Boolean flag to include or not hidden
- * objects in this calculation
- * @return  The Evas object that is over all other objects at the given
- * rectangular region.
- *
- * This function will traverse all the layers of the given canvas,
- * from top to bottom, querying for objects with areas overlapping
- * with the given rectangular region inside @p e. The user can remove
- * from the query objects which are hidden and/or which are set to
- * pass events.
- *
- * @warning This function will @b skip objects parented by smart
- * objects, acting only on the ones at the "top level", with regard to
- * object parenting.
+ * @brief   Gets the Evas object stacked at the top of a given rectangular
+ *          region in a canvas.
+ *
+ * @details This function traverses all the layers of the given canvas,
+ *          from top to bottom, querying for objects with areas overlapping
+ *          with the given rectangular region inside @a e. The user can remove
+ *          from the query objects which are hidden and/or which are set to
+ *          pass events.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks This function @b skips objects parented by smart
+ *          objects, acting only on the ones at the "top level", with regard to
+ *          object parenting.
+ *
+ * @param[in]   e                            A handle to the canvas
+ * @param[in]   x                            The top left corner's horizontal coordinate for the
+ *                                       rectangular region
+ * @param[in]   y                            The top left corner's vertical coordinate for the
+ *                                       rectangular region
+ * @param[in]   w                            The width of the rectangular region
+ * @param[in]   h                            The height of the rectangular region
+ * @param[in]   include_pass_events_objects  Set #EINA_TRUE to include objects which pass events in this calculation,  \n
+ *                                       otherwise #EINA_FALSE to not include the objects
+ * @param[in]   include_hidden_objects       Set #EINA_TRUE to include hidden objects in this calculation, \n
+ *                                       otherwise #EINA_FALSE to not include the hidden objects
+ * @return  The Evas object that is over all other objects at the given rectangular region
  */
 EAPI Evas_Object *evas_object_top_in_rectangle_get(const Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve a list of Evas objects lying over a given position in
- * a canvas
+ * @brief   Gets a list of Evas objects lying over a given position in a canvas.
  *
- * @param   e A handle to the canvas.
- * @param   x The horizontal coordinate of the position
- * @param   y The vertical coordinate of the position
- * @param   include_pass_events_objects Boolean flag to include or not
- * objects which pass events in this calculation
- * @param   include_hidden_objects Boolean flag to include or not hidden
- * objects in this calculation
- * @return  The list of Evas objects that are over the given position
- * in @p e
+ * @details This function traverses all the layers of the given canvas,
+ *          from top to bottom, querying for objects with areas covering the
+ *          given position. The user can remove from query
+ *          objects which are hidden and/or which are set to pass events.
  *
- * This function will traverse all the layers of the given canvas,
- * from top to bottom, querying for objects with areas covering the
- * given position. The user can remove from from the query
- * objects which are hidden and/or which are set to pass events.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @warning This function will @b skip objects parented by smart
- * objects, acting only on the ones at the "top level", with regard to
- * object parenting.
+ * @remarks This function @b skips objects parented by smart
+ *          objects, acting only on the ones at the "top level", with regard to
+ *          object parenting.
+ *
+ * @param[in]   e                            A handle to the canvas
+ * @param[in]   x                            The horizontal coordinate of the position
+ * @param[in]   y                            The vertical coordinate of the position
+ * @param[in]   include_pass_events_objects  Set #EINA_TRUE to include objects which pass events in this calculation, \n
+ *                                       otherwise set #EINA_FALSE to not include the objects
+ * @param[in]   include_hidden_objects       Set #EINA_TRUE to include hidden objects in this calculation, \n
+ *                                       otherwise set #EINA_FALSE to not include the hidden objects
+ * @return  The list of Evas objects that are over the given position in @a e
  */
 EAPI Eina_List   *evas_objects_at_xy_get(const Evas *e, Evas_Coord x, Evas_Coord y, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 EAPI Eina_List   *evas_objects_in_rectangle_get(const Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Get the lowest (stacked) Evas object on the canvas @p e.
+ * @brief   Gets the lowest (stacked) Evas object on the canvas @a e.
+ *
+ * @details This function takes all populated layers in the canvas into
+ *          account, getting the lowest object for the lowest layer, naturally.
  *
- * @param e a valid canvas pointer
- * @return a pointer to the lowest object on it, if any, or @c NULL,
- * otherwise
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function will take all populated layers in the canvas into
- * account, getting the lowest object for the lowest layer, naturally.
+ * @remarks This function @b skips objects parented by smart
+ *          objects, acting only on the ones at the "top level", with regard to
+ *          object parenting.
+ *
+ * @param[in]   e  A valid canvas pointer
+ * @return  A pointer to the lowest object on it, if any, \n
+ *          otherwise @c NULL if the pointer is not obtained
  *
  * @see evas_object_layer_get()
  * @see evas_object_layer_set()
  * @see evas_object_below_get()
  * @see evas_object_above_get()
- *
- * @warning This function will @b skip objects parented by smart
- * objects, acting only on the ones at the "top level", with regard to
- * object parenting.
  */
 EAPI Evas_Object *evas_object_bottom_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Get the highest (stacked) Evas object on the canvas @p e.
+ * @brief   Gets the highest (stacked) Evas object on the canvas @a e.
  *
- * @param e a valid canvas pointer
- * @return a pointer to the highest object on it, if any, or @c NULL,
- * otherwise
+ * @details This function takes all populated layers in the canvas into
+ *          account, getting the highest object for the highest layer, naturally.
  *
- * This function will take all populated layers in the canvas into
- * account, getting the highest object for the highest layer,
- * naturally.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks This function @b skips objects parented by smart
+ *          objects, acting only on the ones at the "top level", with regard to
+ *          object parenting.
+ *
+ * @param[in]   e  A valid canvas pointer
+ * @return  A pointer to the highest object on it, if any, \n
+ *          otherwise @c NULL if the pointer is not obtained 
  *
  * @see evas_object_layer_get()
  * @see evas_object_layer_set()
  * @see evas_object_below_get()
- * @see evas_object_above_get()
- *
- * @warning This function will @b skip objects parented by smart
- * objects, acting only on the ones at the "top level", with regard to
- * object parenting.
+ * @see evas_object_above_get() 
  */
 EAPI Evas_Object *evas_object_top_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
@@ -5987,7 +6818,11 @@ EAPI Evas_Object *evas_object_top_get(const Evas *e) EINA_WARN_UNUSED_RESULT EIN
  */
 
 /**
+ * @internal
  * @defgroup Evas_Object_Group_Interceptors Object Method Interceptors
+ * @ingroup Evas_Object_Group
+ *
+ * @brief  This group provides functions for method interceptors.
  *
  * Evas provides a way to intercept method calls. The interceptor
  * callback may opt to completely deny the call, or may check and
@@ -5995,11 +6830,6 @@ EAPI Evas_Object *evas_object_top_get(const Evas *e) EINA_WARN_UNUSED_RESULT EIN
  * intercepted call is done by calling the intercepted call again,
  * from inside the interceptor callback.
  *
- * @ingroup Evas_Object_Group
- */
-
-/**
- * @addtogroup Evas_Object_Group_Interceptors
  * @{
  */
 
@@ -6017,14 +6847,18 @@ typedef void (*Evas_Object_Intercept_Clip_Set_Cb)(void *data, Evas_Object *obj,
 typedef void (*Evas_Object_Intercept_Clip_Unset_Cb)(void *data, Evas_Object *obj);
 
 /**
- * Set the callback function that intercepts a show event of a object.
+ * @brief   Sets the callback function that intercepts a show event of an object.
  *
- * @param obj The given canvas object pointer.
- * @param func The given function to be the callback function.
- * @param data The data passed to the callback function.
+ * @details This function sets a callback function to intercepts a show event
+ *          of a canvas object.
  *
- * This function sets a callback function to intercepts a show event
- * of a canvas object.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj   The given canvas object pointer
+ * @param[in]   func  The given function to be the callback function
+ * @param[in]   data  The data passed to the callback function
  *
  * @see evas_object_intercept_show_callback_del().
  *
@@ -6032,14 +6866,17 @@ typedef void (*Evas_Object_Intercept_Clip_Unset_Cb)(void *data, Evas_Object *obj
 EAPI void  evas_object_intercept_show_callback_add(Evas_Object *obj, Evas_Object_Intercept_Show_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Unset the callback function that intercepts a show event of a
- * object.
+ * @brief   Unsets the callback function that intercepts a show event of a object.
+ *
+ * @details This function sets a callback function to intercept a show event
+ *          of a canvas object.
  *
- * @param obj The given canvas object pointer.
- * @param func The given callback function.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function sets a callback function to intercepts a show event
- * of a canvas object.
+ * @param[in]   obj   The given canvas object pointer
+ * @param[in]   func  The given callback function
  *
  * @see evas_object_intercept_show_callback_add().
  *
@@ -6047,14 +6884,18 @@ EAPI void  evas_object_intercept_show_callback_add(Evas_Object *obj, Evas_Object
 EAPI void *evas_object_intercept_show_callback_del(Evas_Object *obj, Evas_Object_Intercept_Show_Cb func) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Set the callback function that intercepts a hide event of a object.
+ * @brief   Sets the callback function that intercepts a hide event of a object.
  *
- * @param obj The given canvas object pointer.
- * @param func The given function to be the callback function.
- * @param data The data passed to the callback function.
+ * @details This function sets a callback function to intercepts a hide event
+ *          of a canvas object.
  *
- * This function sets a callback function to intercepts a hide event
- * of a canvas object.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj   The given canvas object pointer
+ * @param[in]   func  The given function to be the callback function
+ * @param[in]   data  The data passed to the callback function
  *
  * @see evas_object_intercept_hide_callback_del().
  *
@@ -6062,14 +6903,17 @@ EAPI void *evas_object_intercept_show_callback_del(Evas_Object *obj, Evas_Object
 EAPI void  evas_object_intercept_hide_callback_add(Evas_Object *obj, Evas_Object_Intercept_Hide_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Unset the callback function that intercepts a hide event of a
- * object.
+ * @brief   Unsets the callback function that intercepts a hide event of a object.
+ *
+ * @details This function sets a callback function to intercepts a hide event
+ *          of a canvas object.
  *
- * @param obj The given canvas object pointer.
- * @param func The given callback function.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function sets a callback function to intercepts a hide event
- * of a canvas object.
+ * @param[in]   obj   The given canvas object pointer
+ * @param[in]   func  The given callback function
  *
  * @see evas_object_intercept_hide_callback_add().
  *
@@ -6077,14 +6921,18 @@ EAPI void  evas_object_intercept_hide_callback_add(Evas_Object *obj, Evas_Object
 EAPI void *evas_object_intercept_hide_callback_del(Evas_Object *obj, Evas_Object_Intercept_Hide_Cb func) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Set the callback function that intercepts a move event of a object.
+ * @brief   Sets the callback function that intercepts a move event of a object.
  *
- * @param obj The given canvas object pointer.
- * @param func The given function to be the callback function.
- * @param data The data passed to the callback function.
+ * @details This function sets a callback function to intercepts a move event
+ *          of a canvas object.
  *
- * This function sets a callback function to intercepts a move event
- * of a canvas object.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj   The given canvas object pointer
+ * @param[in]   func  The given function to be the callback function
+ * @param[in]   data  The data passed to the callback function
  *
  * @see evas_object_intercept_move_callback_del().
  *
@@ -6092,14 +6940,17 @@ EAPI void *evas_object_intercept_hide_callback_del(Evas_Object *obj, Evas_Object
 EAPI void  evas_object_intercept_move_callback_add(Evas_Object *obj, Evas_Object_Intercept_Move_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Unset the callback function that intercepts a move event of a
- * object.
+ * @brief   Unsets the callback function that intercepts a move event of a object.
+ *
+ * @details This function sets a callback function to intercept a move event
+ *          of a canvas object.
  *
- * @param obj The given canvas object pointer.
- * @param func The given callback function.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function sets a callback function to intercepts a move event
- * of a canvas object.
+ * @param[in]   obj   The given canvas object pointer
+ * @param[in]   func  The given callback function
  *
  * @see evas_object_intercept_move_callback_add().
  *
@@ -6131,13 +6982,15 @@ EAPI void *evas_object_intercept_clip_unset_callback_del(Evas_Object *obj, Evas_
 
 /**
  * @defgroup Evas_Object_Specific Specific Object Functions
+ * @ingroup Evas_Object_Group
  *
- * Functions that work on specific objects.
+ * @brief This group provides functions that work on specific objects.
  *
  */
 
 /**
  * @defgroup Evas_Object_Rectangle Rectangle Object Functions
+ * @ingroup Evas_Object_Specific
  *
  * @brief Function to create evas rectangle objects.
  *
@@ -6155,7 +7008,7 @@ EAPI void *evas_object_intercept_clip_unset_callback_del(Evas_Object *obj, Evas_
  * @section Background
  *
  * One extremely common requirement of evas programs is to have a solid color
- * background, this can be accomplished with the following very simple code:
+ * background. This can be accomplished with the following very simple code:
  * @code
  * Evas_Object *bg = evas_object_rectangle_add(evas_canvas);
  * //Here we set the rectangles red, green, blue and opacity levels
@@ -6164,46 +7017,45 @@ EAPI void *evas_object_intercept_clip_unset_callback_del(Evas_Object *obj, Evas_
  * evas_object_show(bg);
  * @endcode
  *
- * This however will have issues if the @c evas_canvas is resized, however most
+ * This however has issues if the @c evas_canvas is resized. However most
  * windows are created using ecore evas and that has a solution to using the
  * rectangle as a background:
  * @code
- * Evas_Object *bg = evas_object_rectangle_add(ecore_evas_get(ee));
+ * Evas_Object *bg = evas_object_rectangle_add(evas_canvas);
  * //Here we set the rectangles red, green, blue and opacity levels
  * evas_object_color_set(bg, 255, 255, 255, 255); // opaque white background
  * evas_object_resize(bg, WIDTH, HEIGHT); // covers full canvas
  * evas_object_show(bg);
- * ecore_evas_object_associate(ee, bg, ECORE_EVAS_OBJECT_ASSOCIATE_BASE);
  * @endcode
- * So this gives us a white background to our window that will be resized
+ * So this gives us a white background to our window that is resized
  * together with it.
  *
  * @section Debugging
  *
  * Debugging is a major part of any programmers task and when debugging visual
  * issues with evas programs the rectangle is an extremely useful tool. The
- * rectangle's simplicity means that it's easier to pinpoint issues with it than
+ * rectangle's simplicity means that it is easier to pinpoint issues with it than
  * with more complex objects. Therefore a common technique to use when writing
  * an evas program and not getting the desired visual result is to replace the
  * misbehaving object for a solid color rectangle and seeing how it interacts
  * with the other elements, this often allows us to notice clipping, parenting
  * or positioning issues. Once the issues have been identified and corrected the
  * rectangle can be replaced for the original part and in all likelihood any
- * remaining issues will be specific to that object's type.
+ * remaining issues are specific to that object's type.
  *
  * @section clipping Clipping
  *
  * Clipping serves two main functions:
- * @li Limiting visibility(i.e. hiding portions of an object).
+ * @li Limiting visibility (i.e. hiding portions of an object).
  * @li Applying a layer of color to an object.
  *
  * @subsection hiding Limiting visibility
  *
  * It is often necessary to show only parts of an object, while it may be
  * possible to create an object that corresponds only to the part that must be
- * shown(and it isn't always possible) it's usually easier to use a a clipper. A
- * clipper is a rectangle that defines what's visible and what is not. The way
- * to do this is to create a solid white rectangle(which is the default, no need
+ * shown (and it is not always possible), it is usually easier to use a clipper. A
+ * clipper is a rectangle that defines what is visible and what is not. The way
+ * to do this is to create a solid white rectangle (which is the default, no need
  * to call evas_object_color_set()) and give it a position and size of what
  * should be visible. The following code exemplifies showing the center half of
  * @c my_evas_object:
@@ -6218,11 +7070,11 @@ EAPI void *evas_object_intercept_clip_unset_callback_del(Evas_Object *obj, Evas_
  * @subsection color Layer of color
  *
  * In the @ref clipping section we used a solid white clipper, which produced no
- * change in the color of the clipped object, it just hid what was outside the
- * clippers area. It is however sometimes desirable to change the of color an
+ * change in the color of the clipped object, it just hid what is outside the
+ * clippers area. It is however sometimes desirable to change the color of an
  * object, this can be accomplished using a clipper that has a non-white color.
  * Clippers with color work by multiplying the colors of clipped object. The
- * following code will show how to remove all the red from an object:
+ * following code shows how to remove all the red from an object:
  * @code
  * Evas_Object *clipper = evas_object_rectangle_add(evas);
  * evas_object_move(clipper, my_evas_object_x, my_evas_object_y);
@@ -6232,33 +7084,40 @@ EAPI void *evas_object_intercept_clip_unset_callback_del(Evas_Object *obj, Evas_
  * evas_object_show(clipper);
  * @endcode
  *
- * @warning We don't guarantee any proper results if you create a Rectangle
- * object without setting the evas engine.
- *
- * For an example that more fully exercise the use of an evas object rectangle
- * see @ref Example_Evas_Object_Manipulation.
+ * @remarks We do not guarantee any proper results if you create a Rectangle
+ *          object without setting the evas engine.
  *
- * @ingroup Evas_Object_Specific
+ * @{
  */
 
 /**
- * Adds a rectangle to the given evas.
- * @param   e The given evas.
- * @return  The new rectangle object.
+ * @brief   Adds a rectangle to the given evas.
  *
- * @ingroup Evas_Object_Rectangle
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e  The given evas
+ * @return  The new rectangle object
  */
 EAPI Evas_Object *evas_object_rectangle_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
+ * @}
+ */
+
+/**
  * @defgroup Evas_Object_Image Image Object Functions
+ * @ingroup Evas_Object_Specific
  *
- * Here are grouped together functions used to create and manipulate
- * image objects. They are available to whichever occasion one needs
+ * @brief  This group provides functions for image objects.
+ *
+ * The functions used to create and manipulate image objects
+ * are grouped together. They are available to whichever occasion one needs
  * complex imagery on a GUI that could not be achieved by the other
  * Evas' primitive object types, or to make image manipulations.
  *
- * Evas will support whichever image file types it was compiled with
+ * Evas supports whichever image file types it is compiled with
  * support to (its image loaders) -- check your software packager for
  * that information and see
  * evas_object_image_extension_can_load_get().
@@ -6273,13 +7132,13 @@ EAPI Evas_Object *evas_object_rectangle_add(Evas *e) EINA_WARN_UNUSED_RESULT EIN
  * evas_object_image_fill_set(img, 0, 0, w, h);
  * @endcode
  * The first function, naturally, is creating the image object. Then,
- * one must set an source file on it, so that it knows where to fetch
+ * one must set a source file on it, so that it knows where to fetch
  * image data from. Next, one must set <b>how to fill the image
- * object's area</b> with that given pixel data. One could use just a
+ * object's area</b> with the given pixel data. One could use just a
  * sub-region of the original image or even have it tiled repeatedly
  * on the image object. For the common case of having the whole source
  * image to be displayed on the image object, stretched to the
- * destination's size, there's also a function helper, to be used
+ * destination's size, there is also a function helper, to be used
  * instead of evas_object_image_fill_set():
  * @code
  * evas_object_image_filled_set(img, EINA_TRUE);
@@ -6288,17 +7147,17 @@ EAPI Evas_Object *evas_object_rectangle_add(Evas *e) EINA_WARN_UNUSED_RESULT EIN
  *
  * @section Evas_Object_Image_Scale Scale and resizing
  *
- * Resizing of image objects will scale their respective source images
+ * Resizing of image objects scales their respective source images
  * to their areas, if they are set to "fill" the object's area
- * (evas_object_image_filled_set()). If the user wants any control on
- * the aspect ratio of an image for different sizes, he/she has to
- * take care of that themselves. There are functions to make images to
- * get loaded scaled (up or down) in memory, already, if the user is
- * going to use them at pre-determined sizes and wants to save
+ * (evas_object_image_filled_set()). If you want any control on
+ * the aspect ratio of an image for different sizes, you have to
+ * take care of that yourself. There are functions to make images to
+ * get loaded scaled (up or down) in memory, already, if you are
+ * going to use them at pre-determined sizes and want to save
  * computations.
  *
- * Evas has even a scale cache, which will take care of caching scaled
- * versions of images with more often usage/hits. Finally, one can
+ * Evas has even a scale cache, which takes care of caching scaled
+ * versions of images with most usage/hits. Finally, you can
  * have images being rescaled @b smoothly by Evas (more
  * computationally expensive) or not.
  *
@@ -6310,8 +7169,8 @@ EAPI Evas_Object *evas_object_rectangle_add(Evas *e) EINA_WARN_UNUSED_RESULT EIN
  *
  * @subsection Evas_Object_Image_Load Load hints
  *
- * In image viewer applications, for example, the user will be looking
- * at a given image, at full size, and will desire that the navigation
+ * In image viewer applications, for example, the user is looking
+ * at a given image, at full size, and desires that the navigation
  * to the adjacent images on his/her album be fluid and fast. Thus,
  * while displaying a given image, the program can be on the
  * background loading the next and previous images already, so that
@@ -6330,16 +7189,15 @@ EAPI Evas_Object *evas_object_rectangle_add(Evas *e) EINA_WARN_UNUSED_RESULT EIN
  * evas_object_image_preload(next, EINA_TRUE);
  * @endcode
  *
- * If you're loading images which are too big, consider setting
- * previously it's loading size to something smaller, in case you
- * won't expose them in real size. It may speed up the loading
- * considerably:
+ * If you are loading images which are too big, consider setting
+ * its loading size to something smaller, in case you do not expose 
+ * them in real size. It may speed up the loading considerably:
  * @code
- * //to load a scaled down version of the image in memory, if that's
- * //the size you'll be displaying it anyway
+ * //To load a scaled down version of the image in memory, if that is
+ * //the size you are displaying anyway
  * evas_object_image_load_scale_down_set(img, zoom);
  *
- * //optional: if you know you'll be showing a sub-set of the image's
+ * //optional: if you know you are going to show a sub-set of the image's
  * //pixels, you can avoid loading the complementary data
  * evas_object_image_load_region_set(img, x, y, w, h);
  * @endcode
@@ -6348,18 +7206,18 @@ EAPI Evas_Object *evas_object_rectangle_add(Evas *e) EINA_WARN_UNUSED_RESULT EIN
  *
  * @subsection Evas_Object_Image_Animation Animation hints
  *
- * If you want to animate image objects on a UI (what you'd get by
+ * If you want to animate image objects on a UI (what you would get by
  * concomitant usage of other libraries, like Ecore and Edje), there
  * are also some tips on how to boost the performance of your
  * application. If the animation involves resizing of an image (thus,
- * re-scaling), you'd better turn off smooth scaling on it @b during
+ * re-scaling), you would better turn off smooth scaling on it @b during
  * the animation, turning it back on afterwards, for less
- * computations. Also, in this case you'd better flag the image object
+ * computations. Also, in this case you would better flag the image object
  * in question not to cache scaled versions of it:
  * @code
  * evas_object_image_scale_hint_set(wd->img, EVAS_IMAGE_SCALE_HINT_DYNAMIC);
  *
- * // resizing takes place in between
+ * // Resizing takes place in between
  *
  * evas_object_image_scale_hint_set(wd->img, EVAS_IMAGE_SCALE_HINT_STATIC);
  * @endcode
@@ -6371,30 +7229,32 @@ EAPI Evas_Object *evas_object_rectangle_add(Evas *e) EINA_WARN_UNUSED_RESULT EIN
  * @section Evas_Object_Image_Borders Borders
  *
  * Evas provides facilities for one to specify an image's region to be
- * treated specially -- as "borders". This will make those regions be
+ * treated specially -- as "borders". This makes those regions to be
  * treated specially on resizing scales, by keeping their aspect. This
  * makes setting frames around other objects on UIs easy.
  * See the following figures for a visual explanation:\n
+ *
+ * @image html image-borders.png
  * @htmlonly
- * <img src="image-borders.png" style="max-width: 100%;" />
  * <a href="image-borders.png">Full-size</a>
  * @endhtmlonly
  * @image rtf image-borders.png
- * @image latex image-borders.eps width=\textwidth
+ * @image latex image-borders.eps "image borders" width=\textwidth
+ *
+ * @image html border-effect.png
  * @htmlonly
- * <img src="border-effect.png" style="max-width: 100%;" />
  * <a href="border-effect.png">Full-size</a>
  * @endhtmlonly
  * @image rtf border-effect.png
- * @image latex border-effect.eps width=\textwidth
+ * @image latex border-effect.eps "border effect" width=\textwidth
  *
  * @section Evas_Object_Image_Manipulation Manipulating pixels
  *
  * Evas image objects can be used to manipulate raw pixels in many
- * ways.  The meaning of the data in the pixel arrays will depend on
+ * ways.  The meaning of the data in the pixel arrays depends on
  * the image's color space, be warned (see next section). You can set
  * your own data as an image's pixel data, fetch an image's pixel data
- * for saving/altering, convert images between different color spaces
+ * for saving or altering, convert images between different color spaces
  * and even advanced operations like setting a native surface as image
  * objects' data.
  *
@@ -6407,7 +7267,7 @@ EAPI Evas_Object *evas_object_rectangle_add(Evas *e) EINA_WARN_UNUSED_RESULT EIN
  * - #EVAS_COLORSPACE_ARGB8888:
  *   This pixel format is a linear block of pixels, starting at the
  *   top-left row by row until the bottom right of the image or pixel
- *   region. All pixels are 32-bit unsigned int's with the high-byte
+ *   region. All pixels are 32-bit unsigned int with the high-byte
  *   being alpha and the low byte being blue in the format ARGB. Alpha
  *   may or may not be used by evas depending on the alpha flag of the
  *   image, but if not used, should be set to 0xff anyway.
@@ -6418,7 +7278,7 @@ EAPI Evas_Object *evas_object_rectangle_add(Evas *e) EINA_WARN_UNUSED_RESULT EIN
  *   \n\n
  *   R = (r * a) / 255; G = (g * a) / 255; B = (b * a) / 255;
  *   \n\n
- *   So 50% transparent blue will be: 0x80000080. This will not be
+ *   So 50% transparent blue is: 0x80000080. This is not
  *   "dark" - just 50% transparent. Values are 0 == black, 255 ==
  *   solid or full red, green or blue.
  * .
@@ -6426,12 +7286,12 @@ EAPI Evas_Object *evas_object_rectangle_add(Evas *e) EINA_WARN_UNUSED_RESULT EIN
  *   This is a pointer-list indirected set of YUV (YCbCr) pixel
  *   data. This means that the data returned or set is not actual
  *   pixel data, but pointers TO lines of pixel data. The list of
- *   pointers will first be N rows of pointers to the Y plane -
+ *   pointers are first be N rows of pointers to the Y plane -
  *   pointing to the first pixel at the start of each row in the Y
  *   plane. N is the height of the image data in pixels. Each pixel in
  *   the Y, U and V planes is 1 byte exactly, packed. The next N / 2
- *   pointers will point to rows in the U plane, and the next N / 2
- *   pointers will point to the V plane rows. U and V planes are half
+ *   pointers points to rows in the U plane, and the next N / 2
+ *   pointers points to the V plane rows. U and V planes are half
  *   the horizontal and vertical resolution of the Y plane.
  *   \n\n
  *   Row order is top to bottom and row pixels are stored left to
@@ -6444,14 +7304,14 @@ EAPI Evas_Object *evas_object_rectangle_add(Evas *e) EINA_WARN_UNUSED_RESULT EIN
  *   standard television and mpeg streams. HDTV may use the itu709
  *   specification.
  *   \n\n
- *   Values are 0 to 255, indicating full or no signal in that plane
+ *   Values are @c 0 to @c 255, indicating full or no signal in that plane
  *   respectively.
  * .
  * - #EVAS_COLORSPACE_YCBCR422P709_PL:
  *   Not implemented yet.
  * .
  * - #EVAS_COLORSPACE_RGB565_A5P:
- *   In the process of being implemented in 1 engine only. This may
+ *   In the process of being implemented in one engine only. This may
  *   change.
  *   \n\n
  *   This is a pointer to image data for 16-bit half-word pixel data
@@ -6460,79 +7320,83 @@ EAPI Evas_Object *evas_object_rectangle_add(Evas *e) EINA_WARN_UNUSED_RESULT EIN
  *   blue, per pixel. This data is packed row by row from the top-left
  *   to the bottom right.
  *   \n\n
- *   If the image has an alpha channel enabled there will be an extra
+ *   If the image has an alpha channel enabled there is an extra
  *   alpha plane after the color pixel plane. If not, then this data
- *   will not exist and should not be accessed in any way. This plane
+ *   does not exist and should not be accessed in any way. This plane
  *   is a set of pixels with 1 byte per pixel defining the alpha
  *   values of all pixels in the image from the top-left to the bottom
  *   right of the image, row by row. Even though the values of the
- *   alpha pixels can be 0 to 255, only values 0 through to 32 are
- *   used, 32 being solid and 0 being transparent.
+ *   alpha pixels can be @c 0 to @c 255, only values @c 0 through to @c 32 are
+ *   used, @c 32 being solid and 0 being transparent.
  *   \n\n
- *   RGB values can be 0 to 31 for red and blue and 0 to 63 for green,
- *   with 0 being black and 31 or 63 being full red, green or blue
+ *   RGB values can be @c 0 to @c 31 for red and blue and @c 0 to @c 63 for green,
+ *   with @c 0 being black and @c 31 or @c 63 being full red, green or blue
  *   respectively. This colorspace is also pre-multiplied like
  *   EVAS_COLORSPACE_ARGB8888 so:
  *   \n\n
  *   R = (r * a) / 32; G = (g * a) / 32; B = (b * a) / 32;
  * .
  * - #EVAS_COLORSPACE_GRY8:
- *   The image is just a alpha mask (8 bit's per pixel). This is used
+ *   The image is just an alpha mask (8 bits per pixel). This is used
  *   for alpha masking.
  *
- * @warning We don't guarantee any proper results if you create a Image object
- * without setting the evas engine.
- *
- * Some examples on this group of functions can be found @ref
- * Example_Evas_Images "here".
+ * @remarks We do not guarantee any proper results if you create an Image object
+ *          without setting the evas engine.
  *
- * @ingroup Evas_Object_Specific
+ * @{
  */
 
 /**
- * @addtogroup Evas_Object_Image
- * @{
+ * @brief Callback of Evas Object Image Pixels
+ * @see evas_object_image_pixels_get_callback_set
  */
-
 typedef void (*Evas_Object_Image_Pixels_Get_Cb)(void *data, Evas_Object *o);
 
 /**
- * Creates a new image object on the given Evas @p e canvas.
+ * @brief   Creates a new image object on the given Evas @a e canvas.
  *
- * @param e The given canvas.
- * @return The created image object handle.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note If you intend to @b display an image somehow in a GUI,
- * besides binding it to a real image file/source (with
- * evas_object_image_file_set(), for example), you'll have to tell
- * this image object how to fill its space with the pixels it can get
- * from the source. See evas_object_image_filled_add(), for a helper
- * on the common case of scaling up an image source to the whole area
- * of the image object.
+ * @remarks If you intend to @b display an image somehow in a GUI,
+ *          besides binding it to a real image file or source (with
+ *          evas_object_image_file_set(), for example), you have to tell
+ *          this image object how to fill its space with the pixels it can get
+ *          from the source. See evas_object_image_filled_add(), for a helper
+ *          on the common case of scaling up an image source to the whole area
+ *          of the image object.
  *
- * @see evas_object_image_fill_set()
- *
- * Example:
+ * @remarks The following is an example:
  * @code
  * img = evas_object_image_add(canvas);
  * evas_object_image_file_set(img, "/path/to/img", NULL);
  * @endcode
+ *
+ * @param[in]   e  The given canvas
+ * @return  The created image object handle
+ *
+ * @see evas_object_image_fill_set()
  */
 EAPI Evas_Object                  *evas_object_image_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Creates a new image object that @b automatically scales its bound
- * image to the object's area, on both axis.
+ * @brief   Creates a new image object that @b automatically scales its bound
+ *          image to the object's area, on both axis.
  *
- * @param e The given canvas.
- * @return The created image object handle.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This is a helper function around evas_object_image_add() and
- * evas_object_image_filled_set(). It has the same effect of applying
- * those functions in sequence, which is a very common use case.
+ * @remarks This is a helper function around evas_object_image_add() and
+ *          evas_object_image_filled_set(). It has the same effect of applying
+ *          those functions in sequence, which is a very common use case.
  *
- * @note Whenever this object gets resized, the bound image will be
- * rescaled, too.
+ * @remarks Whenever this object gets resized, the bound image is
+ *          rescaled, too.
+ *
+ * @param[in]   e  The given canvas
+ * @return  The created image object handle
  *
  * @see evas_object_image_add()
  * @see evas_object_image_filled_set()
@@ -6541,44 +7405,49 @@ EAPI Evas_Object                  *evas_object_image_add(Evas *e) EINA_WARN_UNUS
 EAPI Evas_Object                  *evas_object_image_filled_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Sets the data for an image from memory to be loaded
+ * @brief   Sets the data for an image from memory to be loaded.
+ *
+ * @details This function is the same as evas_object_image_file_set() but the file to be loaded
+ *          may exist at an address in memory (the data for the file, not the filename
+ *          itself). The @a data at the address is copied and stored for future use, so
+ *          no @a data needs to be kept after this call is made. It is managed and
+ *          freed for you when no longer needed. The @a size is limited to 2 gigabytes
+ *          in size, and must be greater than @c 0. A @c NULL @a data pointer is also
+ *          invalid. Set the filename to @c NULL to reset to empty state and have the
+ *          image file data freed from memory using evas_object_image_file_set().
  *
- * This is the same as evas_object_image_file_set() but the file to be loaded
- * may exist at an address in memory (the data for the file, not the filename
- * itself). The @p data at the address is copied and stored for future use, so
- * no @p data needs to be kept after this call is made. It will be managed and
- * freed for you when no longer needed. The @p size is limited to 2 gigabytes
- * in size, and must be greater than 0. A @c NULL @p data pointer is also
- * invalid. Set the filename to @c NULL to reset to empty state and have the
- * image file data freed from memory using evas_object_image_file_set().
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * The @p format is optional (pass @c NULL if you don't need/use it). It is
- * used to help Evas guess better which loader to use for the data. It may
- * simply be the "extension" of the file as it would normally be on disk
- * such as "jpg" or "png" or "gif" etc.
+ * @remarks The @a format is optional (pass @c NULL if you do not need/use it). It is
+ *          used to help Evas guess better which loader to use for the data. It may
+ *          simply be the "extension" of the file as it would normally be on disk
+ *          such as "jpg", "png", and "gif".
  *
- * @param obj The given image object.
- * @param data The image file data address
- * @param size The size of the image file data in bytes
- * @param format The format of the file (optional), or @c NULL if not needed
- * @param key The image key in file, or @c NULL.
+ * @param[in]   obj     The given image object
+ * @param[in]   data    The image file data address
+ * @param[in]   size    The size of the image file data in bytes
+ * @param[in]   format  The format of the file (optional), \n
+ *                  otherwise set @c NULL
+ * @param[in]   key     The image key in file, \n 
+ *                  otherwise set @c NULL
  */
 EAPI void                          evas_object_image_memfile_set(Evas_Object *obj, void *data, int size, char *format, char *key) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Set the source file from where an image object must fetch the real
- * image data (it may be an Eet file, besides pure image ones).
+ * @brief   Sets the source file from where an image object must fetch the real
+ *          image data (it may be an Eet file, besides pure image ones).
  *
- * @param obj The given image object.
- * @param file The image file path.
- * @param key The image key in @p file (if its an Eet one), or @c
- * NULL, otherwise.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * If the file supports multiple data stored in it (as Eet files do),
- * you can specify the key to be used as the index of the image in
- * this file.
+ * @remarks If the file supports multiple data stored in it (as Eet files do),
+ *          you can specify the key to be used as the index of the image in
+ *          this file.
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * img = evas_object_image_add(canvas);
  * evas_object_image_file_set(img, "/path/to/img", NULL);
@@ -6595,63 +7464,76 @@ EAPI void                          evas_object_image_memfile_set(Evas_Object *ob
  *      evas_object_show(img);
  *   }
  * @endcode
+ *
+ * @param[in]   obj   The given image object
+ * @param[in]   file  The image file path
+ * @param[in]   key   The image key in @a file (if its an Eet one), \n
+ *                otherwise set @c NULL
  */
 EAPI void                          evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve the source file from where an image object is to fetch the
- * real image data (it may be an Eet file, besides pure image ones).
+ * @brief   Gets the source file from where an image object is to fetch the
+ *          real image data (it may be an Eet file, besides pure image ones).
  *
- * @param obj The given image object.
- * @param file Location to store the image file path.
- * @param key Location to store the image key (if @p file is an Eet
- * one).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * You must @b not modify the strings on the returned pointers.
+ * @remarks You must @b not modify the strings on the returned pointers.
  *
- * @note Use @c NULL pointers on the file components you're not
- * interested in: they'll be ignored by the function.
+ * @remarks Use @c NULL pointers on the file components that you are not
+ *          interested in: they are ignored by the function.
+ *
+ * @param[in]   obj   The given image object
+ * @param[out]   file  The location to store the image file path
+ * @param[out]   key   The location to store the image key (if @a file is an Eet one)
  */
 EAPI void                          evas_object_image_file_get(const Evas_Object *obj, const char **file, const char **key) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Set the dimensions for an image object's border, a region which @b
- * won't ever be scaled together with its center.
+ * @brief   Sets the dimensions for an image object's border, a region which @b
+ *          is not scaled together with its center ever.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given image object.
- * @param l The border's left width.
- * @param r The border's right width.
- * @param t The border's top width.
- * @param b The border's bottom width.
+ * @remarks When Evas is rendering, an image source may be scaled to fit the
+ *          size of its image object. This function sets an area from the
+ *          borders of the image inwards which is @b not to be scaled. This
+ *          function is useful for making frames and for widget theming, where,
+ *          for example, buttons may be of varying sizes, but their border size
+ *          must remain constant.
  *
- * When Evas is rendering, an image source may be scaled to fit the
- * size of its image object. This function sets an area from the
- * borders of the image inwards which is @b not to be scaled. This
- * function is useful for making frames and for widget theming, where,
- * for example, buttons may be of varying sizes, but their border size
- * must remain constant.
+ * @remarks The units used for @a l, @a r, @a t and @a b are canvas units.
  *
- * The units used for @p l, @p r, @p t and @p b are canvas units.
+ * @remarks The border region itself @b may be scaled by the
+ *          evas_object_image_border_scale_set() function.
  *
- * @note The border region itself @b may be scaled by the
- * evas_object_image_border_scale_set() function.
+ * @remarks By default, image objects have no borders set, i. e. @c l, @c
+ *          r, @c t and @c b start as @c 0.
  *
- * @note By default, image objects have no borders set, i. e. @c l, @c
- * r, @c t and @c b start as @c 0.
+ * @remarks See the following figures for visual explanation:\n
  *
- * See the following figures for visual explanation:\n
+ * @image html image-borders.png
  * @htmlonly
- * <img src="image-borders.png" style="max-width: 100%;" />
  * <a href="image-borders.png">Full-size</a>
  * @endhtmlonly
- * @image rtf image-borders.png
- * @image latex image-borders.eps width=\textwidth
+ * @image latex image-borders.eps "image borders" width=\textwidth
+ *
+ * @image html border-effect.png
  * @htmlonly
- * <img src="border-effect.png" style="max-width: 100%;" />
  * <a href="border-effect.png">Full-size</a>
  * @endhtmlonly
  * @image rtf border-effect.png
- * @image latex border-effect.eps width=\textwidth
+ * @image latex border-effect.eps "border effect" width=\textwidth
+ *
+ * @param[in]   obj  The given image object
+ * @param[in]   l    The border's left width
+ * @param[in]   r    The border's right width
+ * @param[in]   t    The border's top width
+ * @param[in]   b    The border's bottom width
  *
  * @see evas_object_image_border_get()
  * @see evas_object_image_border_center_fill_set()
@@ -6659,66 +7541,82 @@ EAPI void                          evas_object_image_file_get(const Evas_Object
 EAPI void                          evas_object_image_border_set(Evas_Object *obj, int l, int r, int t, int b) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve the dimensions for an image object's border, a region
- * which @b won't ever be scaled together with its center.
+ * @brief   Gets the dimensions for an image object's border, a region
+ *          which @b is not scaled together with its center ever.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given image object.
- * @param l Location to store the border's left width in.
- * @param r Location to store the border's right width in.
- * @param t Location to store the border's top width in.
- * @param b Location to store the border's bottom width in.
+ * @remarks Use @c NULL pointers on the border components that you are not
+ *          interested in: they are ignored by the function.
  *
- * @note Use @c NULL pointers on the border components you're not
- * interested in: they'll be ignored by the function.
+ * @param[in]   obj  The given image object
+ * @param[out]   l    The location to store the border's left width in
+ * @param[out]   r    The location to store the border's right width in
+ * @param[out]   t    The location to store the border's top width in
+ * @param[out]   b    The location to store the border's bottom width in
  *
- * See @ref evas_object_image_border_set() for more details.
+ * @see evas_object_image_border_set() for more details.
  */
 EAPI void                          evas_object_image_border_get(const Evas_Object *obj, int *l, int *r, int *t, int *b) EINA_ARG_NONNULL(1);
 
 /**
- * Sets @b how the center part of the given image object (not the
- * borders) should be drawn when Evas is rendering it.
+ * @brief   Sets @b how the center part of the given image object (not the
+ *          borders) should be drawn when Evas is rendering it.
  *
- * @param obj The given image object.
- * @param fill Fill mode of the center region of @p obj (a value in
- * #Evas_Border_Fill_Mode).
+ * @details This function sets how the center part of the image object's source
+ *          image is to be drawn, which must be one of the values in
+ *          #Evas_Border_Fill_Mode. By center we mean the complementary part of
+ *          that defined by evas_object_image_border_set(). This one is very
+ *          useful for making frames and decorations. You would most probably
+ *          also be using a filled image (as in evas_object_image_filled_set())
+ *          to use as a frame.
  *
- * This function sets how the center part of the image object's source
- * image is to be drawn, which must be one of the values in
- * #Evas_Border_Fill_Mode. By center we mean the complementary part of
- * that defined by evas_object_image_border_set(). This one is very
- * useful for making frames and decorations. You would most probably
- * also be using a filled image (as in evas_object_image_filled_set())
- * to use as a frame.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj   The given image object
+ * @param[in]   fill  The fill mode of the center region of @a obj (a value in
+ *                #Evas_Border_Fill_Mode)
  *
  * @see evas_object_image_border_center_fill_get()
  */
 EAPI void                          evas_object_image_border_center_fill_set(Evas_Object *obj, Evas_Border_Fill_Mode fill) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves @b how the center part of the given image object (not the
- * borders) is to be drawn when Evas is rendering it.
+ * @brief   Gets @b how the center part of the given image object (not the
+ *          borders) is to be drawn when Evas is rendering it.
  *
- * @param obj The given image object.
- * @return fill Fill mode of the center region of @p obj (a value in
- * #Evas_Border_Fill_Mode).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * See @ref evas_object_image_fill_set() for more details.
+ * @param[in]   obj   The given image object
+ * @return  fill  The fill mode of the center region of @a obj (a value in
+ *                #Evas_Border_Fill_Mode)
+ *
+ * @see evas_object_image_fill_set()
  */
 EAPI Evas_Border_Fill_Mode         evas_object_image_border_center_fill_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set whether the image object's fill property should track the
- * object's size.
+ * @brief   Sets whether the image object's fill property should track the 
+ *          object's size.
  *
- * @param obj The given image object.
- * @param setting @c EINA_TRUE, to make the fill property follow
- *        object size or @c EINA_FALSE, otherwise.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * If @p setting is @c EINA_TRUE, then every evas_object_resize() will
- * @b automatically trigger a call to evas_object_image_fill_set()
- * with the that new size (and @c 0, @c 0 as source image's origin),
- * so the bound image will fill the whole object's area.
+ * @remarks If @a setting is #EINA_TRUE, then every evas_object_resize()
+ *          @b automatically triggers a call to evas_object_image_fill_set()
+ *          with the that new size (and @c 0, @c 0 as source image's origin),
+ *          so the bound image fills the whole object's area.
+ *
+ * @param[in]   obj      The given image object
+ * @param[in]   setting  Set #EINA_TRUE to make the fill property follow object size, \n 
+ *                   otherwise set #EINA_FALSE
  *
  * @see evas_object_image_filled_add()
  * @see evas_object_image_fill_get()
@@ -6726,23 +7624,31 @@ EAPI Evas_Border_Fill_Mode         evas_object_image_border_center_fill_get(cons
 EAPI void                          evas_object_image_filled_set(Evas_Object *obj, Eina_Bool setting) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve whether the image object's fill property should track the
- * object's size.
+ * @brief   Checks whether the image object's fill property should track the
+ *          object's size.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given image object.
- * @return @c EINA_TRUE if it is tracking, @c EINA_FALSE, if not (and
- *         evas_object_fill_set() must be called manually).
+ * @param[in]   obj  The given image object
+ * @return  #EINA_TRUE if it is tracking, \n
+ *          otherwise #EINA_FALSE if it is not tracking (and
+ *          evas_object_fill_set() must be called manually)
  *
  * @see evas_object_image_filled_set() for more information
  */
 EAPI Eina_Bool                     evas_object_image_filled_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Sets the scaling factor (multiplier) for the borders of an image
- * object.
+ * @brief   Sets the scaling factor (multiplier) for the borders of an image object.
  *
- * @param obj The given image object.
- * @param scale The scale factor (default is @c 1.0 - i.e. no scaling)
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj    The given image object
+ * @param[in]   scale  The scale factor (default is @c 1.0 - i.e. no scaling)
  *
  * @see evas_object_image_border_set()
  * @see evas_object_image_border_scale_get()
@@ -6750,11 +7656,14 @@ EAPI Eina_Bool                     evas_object_image_filled_get(const Evas_Objec
 EAPI void                          evas_object_image_border_scale_set(Evas_Object *obj, double scale);
 
 /**
- * Retrieves the scaling factor (multiplier) for the borders of an
- * image object.
+ * @brief   Gets the scaling factor (multiplier) for the borders of an image object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given image object.
- * @return The scale factor set for its borders
+ * @param[in]   obj  The given image object
+ * @return  The scale factor set for its borders
  *
  * @see evas_object_image_border_set()
  * @see evas_object_image_border_scale_set()
@@ -6762,709 +7671,910 @@ EAPI void                          evas_object_image_border_scale_set(Evas_Objec
 EAPI double                        evas_object_image_border_scale_get(const Evas_Object *obj);
 
 /**
- * Set how to fill an image object's drawing rectangle given the
- * (real) image bound to it.
+ * @brief   Sets how to fill an image object's drawing rectangle given the
+ *          (real) image bound to it.
  *
- * @param obj The given image object to operate on.
- * @param x The x coordinate (from the top left corner of the bound
- *          image) to start drawing from.
- * @param y The y coordinate (from the top left corner of the bound
- *          image) to start drawing from.
- * @param w The width the bound image will be displayed at.
- * @param h The height the bound image will be displayed at.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Note that if @p w or @p h are smaller than the dimensions of
- * @p obj, the displayed image will be @b tiled around the object's
- * area. To have only one copy of the bound image drawn, @p x and @p y
- * must be 0 and @p w and @p h need to be the exact width and height
- * of the image object itself, respectively.
+ * @remarks Note that if @a w or @a h are smaller than the dimensions of
+ *          @a obj, the displayed image is @b tiled around the object's
+ *          area. To have only one copy of the bound image drawn, @a x and @a y
+ *          must be @c 0 and @a w and @a h need to be the exact width and height
+ *          of the image object itself, respectively.
  *
- * See the following image to better understand the effects of this
- * call. On this diagram, both image object and original image source
- * have @c a x @c a dimensions and the image itself is a circle, with
- * empty space around it:
+ * @remarks See the following image to better understand the effects of this
+ *          call. On this diagram, both image object and original image source
+ *          have @c a x @c a dimensions and the image itself is a circle, with
+ *          empty space around it:
  *
  * @image html image-fill.png
  * @image rtf image-fill.png
  * @image latex image-fill.eps
  *
- * @warning The default values for the fill parameters are @p x = 0,
- * @p y = 0, @p w = 0 and @p h = 0. Thus, if you're not using the
- * evas_object_image_filled_add() helper and want your image
- * displayed, you'll have to set valid values with this function on
- * your object.
+ * @remarks The default values for the fill parameters are @a x = 0,
+ *          @a y = 0, @a w = 0 and @a h = 0. Thus, if you are not using the
+ *          evas_object_image_filled_add() helper and want your image
+ *          displayed, you have to set valid values with this function on
+ *          your object.
  *
- * @note evas_object_image_filled_set() is a helper function which
- * will @b override the values set here automatically, for you, in a
- * given way.
+ * @remarks evas_object_image_filled_set() is a helper function which
+ *          @b overrides the values set here automatically, for you, in a
+ *          given way.
+ *
+ * @param[in]   obj  The given image object to operate on
+ * @param[in]   x    The x coordinate (from the top left corner of the bound
+ *               image) to start drawing from
+ * @param[in]   y    The y coordinate (from the top left corner of the bound
+ *               image) to start drawing from
+ * @param[in]   w    The width the bound image is displayed at
+ * @param[in]   h    The height the bound image is displayed at
  */
 EAPI void                          evas_object_image_fill_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve how an image object is to fill its drawing rectangle,
- * given the (real) image bound to it.
+ * @brief   Sets how an image object is to fill its drawing rectangle,
+ *          given the (real) image bound to it.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given image object.
- * @param x Location to store the x coordinate (from the top left
- *          corner of the bound image) to start drawing from.
- * @param y Location to store the y coordinate (from the top left
- *          corner of the bound image) to start drawing from.
- * @param w Location to store the width the bound image is to be
- *          displayed at.
- * @param h Location to store the height the bound image is to be
- *          displayed at.
+ * @remarks Use @c NULL pointers on the fill components that you are not
+ *          interested in: they are ignored by the function.
  *
- * @note Use @c NULL pointers on the fill components you're not
- * interested in: they'll be ignored by the function.
+ * @param[in]   obj  The given image object
+ * @param[out]   x    The location to store the x coordinate (from the top left
+ *               corner of the bound image) to start drawing from
+ * @param[out]   y    The location to store the y coordinate (from the top left
+ *               corner of the bound image) to start drawing from
+ * @param[out]   w    The location to store the width the bound image is to be
+ *               displayed at
+ * @param[out]   h    The location to store the height the bound image is to be
+ *               displayed at
  *
  * See @ref evas_object_image_fill_set() for more details.
  */
 EAPI void                          evas_object_image_fill_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the tiling mode for the given evas image object's fill.
- * @param   obj   The given evas image object.
- * @param   spread One of EVAS_TEXTURE_REFLECT, EVAS_TEXTURE_REPEAT,
- * EVAS_TEXTURE_RESTRICT, or EVAS_TEXTURE_PAD.
+ * @brief   Sets the tiling mode for the given evas image object's fill.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj     The given evas image object
+ * @param[in]   spread  One of EVAS_TEXTURE_REFLECT, EVAS_TEXTURE_REPEAT,
+ *                  EVAS_TEXTURE_RESTRICT, or EVAS_TEXTURE_PAD.
  */
 EAPI void                          evas_object_image_fill_spread_set(Evas_Object *obj, Evas_Fill_Spread spread) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the spread (tiling mode) for the given image object's
- * fill.
+ * @brief   Gets the spread (tiling mode) for the given image object's fill.
  *
- * @param   obj The given evas image object.
- * @return  The current spread mode of the image object.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given evas image object
+ * @return  The current spread mode of the image object
  */
 EAPI Evas_Fill_Spread              evas_object_image_fill_spread_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Sets the size of the given image object.
+ * @brief   Sets the size of the given image object.
+ *
+ * @details This function scales down or crops the image so that it is
+ *          treated as if it were at the given size. If the size given is
+ *          smaller than the image, it is cropped. If the size given is
+ *          larger, then the image is treated as if it were in the upper
+ *          left hand corner of a larger image that is otherwise transparent.
  *
- * @param obj The given image object.
- * @param w The new width of the image.
- * @param h The new height of the image.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function will scale down or crop the image so that it is
- * treated as if it were at the given size. If the size given is
- * smaller than the image, it will be cropped. If the size given is
- * larger, then the image will be treated as if it were in the upper
- * left hand corner of a larger image that is otherwise transparent.
+ * @param[in]   obj  The given image object
+ * @param[in]   w    The new width of the image
+ * @param[in]   h    The new height of the image
  */
 EAPI void                          evas_object_image_size_set(Evas_Object *obj, int w, int h) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the size of the given image object.
+ * @brief   Gets the size of the given image object.
  *
- * @param obj The given image object.
- * @param w Location to store the width of the image in, or @c NULL.
- * @param h Location to store the height of the image in, or @c NULL.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given image object
+ * @param[out]   w    The location to store the width of the image in, or @c NULL
+ * @param[out]   h    The location to store the height of the image in, or @c NULL
  *
  * See @ref evas_object_image_size_set() for more details.
  */
 EAPI void                          evas_object_image_size_get(const Evas_Object *obj, int *w, int *h) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the row stride of the given image object.
+ * @brief   Gets the row stride of the given image object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given image object.
- * @return The stride of the image (<b>in bytes</b>).
+ * @remarks The row stride is the number of bytes between the start of a row
+ *          and the start of the next row for image data.
  *
- * The row stride is the number of bytes between the start of a row
- * and the start of the next row for image data.
+ * @param[in]   obj  The given image object
+ * @return  The stride of the image (<b>in bytes</b>)
  */
 EAPI int                           evas_object_image_stride_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves a number representing any error that occurred during the
- * last loading of the given image object's source image.
+ * @brief   Gets a number representing any error that occurred during the
+ *          last loading of the given image object's source image.
  *
- * @param obj The given image object.
- * @return A value giving the last error that occurred. It should be
- *         one of the #Evas_Load_Error values. #EVAS_LOAD_ERROR_NONE
- *         is returned if there was no error.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given image object
+ * @return  A value giving the last error that occurred \n 
+ *          It should be a #Evas_Load_Error value. #EVAS_LOAD_ERROR_NONE
+ *          is returned if there is no error.
  */
 EAPI Evas_Load_Error               evas_object_image_load_error_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Sets the raw image data of the given image object.
+ * @brief   Sets the raw image data of the given image object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given image object.
- * @param data The raw data, or @c NULL.
+ * @remarks Note that the raw data must be of the same size (see
+ *          evas_object_image_size_set(), which has to be called @b before this
+ *          one) and colorspace (see evas_object_image_colorspace_set()) of the
+ *          image. If data is @c NULL, the current image data is
+ *          freed. Naturally, if one does not set an image object's data
+ *          manually, it still has one, allocated by Evas.
  *
- * Note that the raw data must be of the same size (see
- * evas_object_image_size_set(), which has to be called @b before this
- * one) and colorspace (see evas_object_image_colorspace_set()) of the
- * image. If data is @c NULL, the current image data will be
- * freed. Naturally, if one does not set an image object's data
- * manually, it will still have one, allocated by Evas.
+ * @param[in]   obj   The given image object
+ * @param[in]   data  The raw data, or @c NULL
  *
  * @see evas_object_image_data_get()
  */
 EAPI void                          evas_object_image_data_set(Evas_Object *obj, void *data) EINA_ARG_NONNULL(1);
 
 /**
- * Get a pointer to the raw image data of the given image object.
+ * @brief   Gets a pointer to the raw image data of the given image object.
  *
- * @param obj The given image object.
- * @param for_writing Whether the data being retrieved will be
- *        modified (@c EINA_TRUE) or not (@c EINA_FALSE).
- * @return The raw image data.
+ * @details This function returns a pointer to an image object's internal pixel
+ *          buffer, for reading only or read/write. If you request it for
+ *          writing, the image is marked as dirty so that it gets redrawn at
+ *          the next update.
  *
- * This function returns a pointer to an image object's internal pixel
- * buffer, for reading only or read/write. If you request it for
- * writing, the image will be marked dirty so that it gets redrawn at
- * the next update.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Each time you call this function on an image object, its data
- * buffer will have an internal reference counter
- * incremented. Decrement it back by using
- * evas_object_image_data_set(). This is specially important for the
- * directfb Evas engine.
+ * @remarks Each time you call this function on an image object, its data
+ *          buffer has an internal reference counter
+ *          incremented. Decrement it back by using
+ *          evas_object_image_data_set(). This is specially important for the
+ *          directfb Evas engine.
  *
- * This is best suited for when you want to modify an existing image,
- * without changing its dimensions.
+ * @remarks This is best suited for when you want to modify an existing image,
+ *          without changing its dimensions.
  *
- * @note The contents' format returned by it depend on the color
- * space of the given image object.
+ * @remarks The contents' format returned by it depend on the color
+ *          space of the given image object.
  *
- * @note You may want to use evas_object_image_data_update_add() to
- * inform data changes, if you did any.
+ * @remarks You may want to use evas_object_image_data_update_add() to
+ *          inform data changes, if you did any.
+ *
+ * @param[in]   obj          The given image object
+ * @param[in]   for_writing  Set #EINA_TRUE to set retrieved data as modifiable, \n
+ *                       otherwise #EINA_FALSE to not set it as modifiable
+ * @return     The raw image data
  *
  * @see evas_object_image_data_set()
  */
 EAPI void                         *evas_object_image_data_get(const Evas_Object *obj, Eina_Bool for_writing) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Converts the raw image data of the given image object to the
- * specified colorspace.
+ * @brief   Converts the raw image data of the given image object to the
+ *          specified colorspace.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Note that this function does not modify the raw image data.  If the
- * requested colorspace is the same as the image colorspace nothing is
- * done and @c NULL is returned. You should use
- * evas_object_image_colorspace_get() to check the current image
- * colorspace.
+ * @remarks Note that this function does not modify the raw image data. If the
+ *          requested colorspace is the same as the image colorspace nothing is
+ *          done and @c NULL is returned. You should use
+ *          evas_object_image_colorspace_get() to check the current image
+ *          colorspace.
  *
- * See @ref evas_object_image_colorspace_get.
  *
- * @param obj The given image object.
- * @param to_cspace The colorspace to which the image raw data will be converted.
- * @return data A newly allocated data in the format specified by to_cspace.
+ * @param[in]   obj        The given image object
+ * @param[in]   to_cspace  The colorspace to which the image raw data is converted
+ *
+ * @see @ref evas_object_image_colorspace_get
  */
 EAPI void                         *evas_object_image_data_convert(Evas_Object *obj, Evas_Colorspace to_cspace) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Replaces the raw image data of the given image object.
+ * @brief   Replaces the raw image data of the given image object.
  *
- * @param obj The given image object.
- * @param data The raw data to replace.
+ * @details This function lets the application replace an image object's
+ *          internal pixel buffer with an user-allocated one. For best results,
+ *          you should generally first call evas_object_image_size_set() with
+ *          the width and height for the new buffer.
  *
- * This function lets the application replace an image object's
- * internal pixel buffer with an user-allocated one. For best results,
- * you should generally first call evas_object_image_size_set() with
- * the width and height for the new buffer.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This call is best suited for when you will be using image data with
- * different dimensions than the existing image data, if any. If you
- * only need to modify the existing image in some fashion, then using
- * evas_object_image_data_get() is probably what you are after.
+ * @remarks This call is best suited for when you are using image data with
+ *          different dimensions than the existing image data, if any. If you
+ *          only need to modify the existing image in some fashion, then using
+ *          evas_object_image_data_get() is probably what you are after.
  *
- * Note that the caller is responsible for freeing the buffer when
- * finished with it, as user-set image data will not be automatically
- * freed when the image object is deleted.
+ * @remarks Note that the caller is responsible for freeing the buffer when
+ *          finished with it, as user-set image data is not automatically
+ *          freed when the image object is deleted.
  *
- * See @ref evas_object_image_data_get() for more details.
+ * @param[in]   obj   The given image object
+ * @param[in]   data  The raw data to replace
  *
+ * @see evas_object_image_data_get()
  */
 EAPI void                          evas_object_image_data_copy_set(Evas_Object *obj, void *data) EINA_ARG_NONNULL(1);
 
 /**
- * Mark a sub-region of the given image object to be redrawn.
+ * @brief   Marks a sub-region of the given image object to be redrawn.
  *
- * @param obj The given image object.
- * @param x X-offset of the region to be updated.
- * @param y Y-offset of the region to be updated.
- * @param w Width of the region to be updated.
- * @param h Height of the region to be updated.
+ * @details This function schedules a particular rectangular region of an image
+ *          object to be updated (redrawn) at the next rendering cycle.
  *
- * This function schedules a particular rectangular region of an image
- * object to be updated (redrawn) at the next rendering cycle.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given image object
+ * @param[in]   x    The X-offset of the region to be updated
+ * @param[in]   y    The Y-offset of the region to be updated
+ * @param[in]   w    The width of the region to be updated
+ * @param[in]   h    The height of the region to be updated
  */
 EAPI void                          evas_object_image_data_update_add(Evas_Object *obj, int x, int y, int w, int h) EINA_ARG_NONNULL(1);
 
 /**
- * Enable or disable alpha channel usage on the given image object.
+ * @brief   Enables or disables alpha channel usage on the given image object.
+ *
+ * @details This function sets a flag on an image object indicating whether or
+ *          not to use alpha channel data. A value of #EINA_TRUE makes it use
+ *          alpha channel data, and #EINA_FALSE makes it ignore that
+ *          data. Note that this has nothing to do with an object's color as
+ *          manipulated by evas_object_color_set().
  *
- * @param obj The given image object.
- * @param has_alpha Whether to use alpha channel (@c EINA_TRUE) data
- * or not (@c EINA_FALSE).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function sets a flag on an image object indicating whether or
- * not to use alpha channel data. A value of @c EINA_TRUE makes it use
- * alpha channel data, and @c EINA_FALSE makes it ignore that
- * data. Note that this has nothing to do with an object's color as
- * manipulated by evas_object_color_set().
+ * @param[in]   obj        The given image object
+ * @param[in]   has_alpha  Set #EINA_TRUE to use alpha channel () data, \n
+ *                     otherwise set #EINA_FALSE to not use it
  *
  * @see evas_object_image_alpha_get()
  */
 EAPI void                          evas_object_image_alpha_set(Evas_Object *obj, Eina_Bool has_alpha) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve whether alpha channel data is being used on the given
- * image object.
+ * @brief   Checks whether alpha channel data is being used on the given
+ *          image object.
  *
- * @param obj The given image object.
- * @return Whether the alpha channel data is being used (@c EINA_TRUE)
- * or not (@c EINA_FALSE).
+ * @details This function returns #EINA_TRUE if the image object's alpha
+ *          channel is being used, or #EINA_FALSE otherwise.
  *
- * This function returns @c EINA_TRUE if the image object's alpha
- * channel is being used, or @c EINA_FALSE otherwise.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks See @ref evas_object_image_alpha_set() for more details.
+ *
+ * @param[in]   obj  The given image object
+ * @return  #EINA_TRUE if the alpha channel data is being used, \n
+ *          otherwise #EINA_FALSE if the alpha channel data is not being used
  *
- * See @ref evas_object_image_alpha_set() for more details.
  */
 EAPI Eina_Bool                     evas_object_image_alpha_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Sets whether to use high-quality image scaling algorithm on the
- * given image object.
+ * @brief   Sets whether to use high-quality image scaling algorithm on the
+ *          given image object.
  *
- * @param obj The given image object.
- * @param smooth_scale Whether to use smooth scale or not.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * When enabled, a higher quality image scaling algorithm is used when
- * scaling images to sizes other than the source image's original
- * one. This gives better results but is more computationally
- * expensive.
+ * @remarks When enabled, a higher quality image scaling algorithm is used when
+ *          scaling images to sizes other than the source image's original
+ *          one. This gives better results but is more computationally expensive.
  *
- * @note Image objects get created originally with smooth scaling @b
- * on.
+ * @remarks Image objects get created originally with smooth scaling @b on.
+ *
+ * @param[in]   obj           The given image object
+ * @param[in]   smooth_scale  Set #EINA_TRUE to use smooth scale, \n 
+ *                        otherwise set #EINA_FALSE to not use it
  *
  * @see evas_object_image_smooth_scale_get()
  */
 EAPI void                          evas_object_image_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth_scale) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves whether the given image object is using high-quality
- * image scaling algorithm.
+ * @brief   Checks whether the given image object is using high-quality
+ *          image scaling algorithm.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given image object.
- * @return Whether smooth scale is being used.
+ * @param[in]   obj  The given image object
+ * @return  #EINA_TRUE if smooth scale is being used, \n
+ *          otherwise #EINA_FALSE if smooth scale is not being used
  *
- * See @ref evas_object_image_smooth_scale_set() for more details.
+ * @see evas_object_image_smooth_scale_set()
  */
 EAPI Eina_Bool                     evas_object_image_smooth_scale_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Preload an image object's image data in the background
+ * @brief   Preloads an image object's image data in the background.
  *
- * @param obj The given image object.
- * @param cancel @c EINA_FALSE will add it the preloading work queue,
- *               @c EINA_TRUE will remove it (if it was issued before).
+ * @details This function requests the preload of the data image in the
+ *          background. The work is queued before being processed (because
+ *          there might be other pending requests of this type).
  *
- * This function requests the preload of the data image in the
- * background. The work is queued before being processed (because
- * there might be other pending requests of this type).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Whenever the image data gets loaded, Evas will call
- * #EVAS_CALLBACK_IMAGE_PRELOADED registered callbacks on @p obj (what
- * may be immediately, if the data was already preloaded before).
+ * @remarks Whenever the image data gets loaded, Evas calls
+ *          #EVAS_CALLBACK_IMAGE_PRELOADED registered callbacks on @a obj (that
+ *          may be immediately, if the data is already preloaded before).
  *
- * Use @c EINA_TRUE for @p cancel on scenarios where you don't need
- * the image data preloaded anymore.
+ * @remarks Use #EINA_TRUE for @a cancel on scenarios where you do not need
+ *          the image data preloaded anymore.
  *
- * @note Any evas_object_show() call after evas_object_image_preload()
- * will make the latter to be @b cancelled, with the loading process
- * now taking place @b synchronously (and, thus, blocking the return
- * of the former until the image is loaded). It is highly advisable,
- * then, that the user preload an image with it being @b hidden, just
- * to be shown on the #EVAS_CALLBACK_IMAGE_PRELOADED event's callback.
+ * @remarks Any evas_object_show() call after evas_object_image_preload()
+ *          makes the latter to be @b cancelled, with the loading process
+ *          now taking place @b synchronously (and, thus, blocking the return
+ *          of the former until the image is loaded). It is highly advisable,
+ *          then, that the user preload an image with it being @b hidden, just
+ *          to be shown on the #EVAS_CALLBACK_IMAGE_PRELOADED event's callback.
+ *
+ * @param[in]   obj     The given image object
+ * @param[in]   cancel  Set #EINA_FALSE to add to the preloading work queue, \n
+ *                  otherwise set #EINA_TRUE to remove it (if it is issued before)
  */
 EAPI void                          evas_object_image_preload(Evas_Object *obj, Eina_Bool cancel) EINA_ARG_NONNULL(1);
 
 /**
- * Reload an image object's image data.
+ * @brief   Reloads an image object's image data.
+ *
+ * @details This function reloads the image data bound to image object @a obj.
  *
- * @param obj The given image object pointer.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function reloads the image data bound to image object @p obj.
+ * @param[in]   obj  The given image object pointer
  */
 EAPI void                          evas_object_image_reload(Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Save the given image object's contents to an (image) file.
+ * @brief   Saves the given image object's contents to an (image) file.
  *
- * @param obj The given image object.
- * @param file The filename to be used to save the image (extension
- *        obligatory).
- * @param key The image key in the file (if an Eet one), or @c NULL,
- *        otherwise.
- * @param flags String containing the flags to be used (@c NULL for
- *        none).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * The extension suffix on @p file will determine which <b>saver
- * module</b> Evas is to use when saving, thus the final file's
- * format. If the file supports multiple data stored in it (Eet ones),
- * you can specify the key to be used as the index of the image in it.
+ * @remarks The extension suffix on @a file determines which <b>saver
+ *          module</b> Evas is to use when saving, thus the final file's
+ *          format. If the file supports multiple data stored in it (Eet ones),
+ *          you can specify the key to be used as the index of the image in it.
  *
- * You can specify some flags when saving the image.  Currently
- * acceptable flags are @c quality and @c compress. Eg.: @c
- * "quality=100 compress=9"
+ * @remarks You can specify some flags when saving the image. Currently
+ *          acceptable flags are @c quality and @c compress. Eg.: @c
+ *          "quality=100 compress=9"
+ *
+ * @param[in]   obj    The given image object
+ * @param[in]   file   The filename to be used to save the image (extension obligatory)
+ * @param[in]   key    The image key in the file (if an Eet one), \n
+ *                 otherwise @c NULL
+ * @param[in]   flags  String containing the flags to be used (@c NULL for none)
+ * @return  #EINA_TRUE if the contents are saved successfully, \n
+ *          otherwise #EINA_FALSE if it fails
  */
 EAPI Eina_Bool                     evas_object_image_save(const Evas_Object *obj, const char *file, const char *key, const char *flags)  EINA_ARG_NONNULL(1, 2);
 
 /**
- * Import pixels from given source to a given canvas image object.
+ * @brief   Imports pixels from given source to a given canvas image object.
  *
- * @param obj The given canvas object.
- * @param pixels The pixel's source to be imported.
+ * @details This function imports pixels from a given source to a given canvas image.
  *
- * This function imports pixels from a given source to a given canvas image.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
+ * @param[in]   obj     The given canvas object
+ * @param[in]   pixels  The pixel's source to be imported
+ * @return #EINA_TRUE if success, otherwise #EINA_FALSE.
  */
 EAPI Eina_Bool                     evas_object_image_pixels_import(Evas_Object *obj, Evas_Pixel_Import_Source *pixels) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Set the callback function to get pixels from a canvas' image.
+ * @brief   Sets the callback function to get pixels from a canvas' image.
+ *
+ * @details This sets a function to be the callback function that gets
+ *          pixels from an image of the canvas.
  *
- * @param obj The given canvas pointer.
- * @param func The callback function.
- * @param data The data pointer to be passed to @a func.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This functions sets a function to be the callback function that get
- * pixes from a image of the canvas.
+ * @param[in]   obj   The given canvas pointer
+ * @param[in]   func  The callback function
+ * @param[in]   data  The data pointer to be passed to @a func
  *
  */
 EAPI void                          evas_object_image_pixels_get_callback_set(Evas_Object *obj, Evas_Object_Image_Pixels_Get_Cb func, void *data) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Mark whether the given image object is dirty and needs to request its pixels.
+ * @brief   Sets whether the given image object is dirty and needs to request its pixels.
  *
- * @param obj The given image object.
- * @param dirty Whether the image is dirty.
+ * @details This function only works properly if a callback for getting pixels has been set.
  *
- * This function will only properly work if a pixels get callback has been set.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @warning use this function if you really know what you are doing.
+ * @remarks Use this function if you really know what you are doing.
+ *
+ * @param[in]   obj    The given image object
+ * @param[in]   dirty  Set #EINA_TRUE to mark the image object as dirty, \n
+ *                 otherwise set #EINA_FALSE to mark the image object as not dirty
  *
  * @see evas_object_image_pixels_get_callback_set()
  */
 EAPI void                          evas_object_image_pixels_dirty_set(Evas_Object *obj, Eina_Bool dirty) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves whether the given image object is dirty (needs to be redrawn).
+ * @brief   Checks whether the given image object is dirty (needs to be redrawn).
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given image object.
- * @return Whether the image is dirty.
+ * @param[in]   obj  The given image object
+ * @return  #EINA_TRUE if the image is dirty, \n
+ *          otherwise #EINA_FALSE if the image is not dirty
  */
 EAPI Eina_Bool                     evas_object_image_pixels_dirty_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set the DPI resolution of an image object's source image.
+ * @brief   Sets the DPI resolution of an image object's source image.
  *
- * @param obj The given canvas pointer.
- * @param dpi The new DPI resolution.
+ * @details This function sets the DPI resolution of a given loaded canvas
+ *          image. This is useful for the SVG image loader.
  *
- * This function sets the DPI resolution of a given loaded canvas
- * image. Most useful for the SVG image loader.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given canvas pointer
+ * @param[in]   dpi  The new DPI resolution
  *
  * @see evas_object_image_load_dpi_get()
  */
 EAPI void                          evas_object_image_load_dpi_set(Evas_Object *obj, double dpi) EINA_ARG_NONNULL(1);
 
 /**
- * Get the DPI resolution of a loaded image object in the canvas.
+ * @brief   Gets the DPI resolution of a loaded image object in the canvas.
+ *
+ * @details This function returns the DPI resolution of the given canvas image.
  *
- * @param obj The given canvas pointer.
- * @return The DPI resolution of the given canvas image.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function returns the DPI resolution of the given canvas image.
+ * @param[in]   obj  The given canvas pointer
+ * @return  The DPI resolution of the given canvas image
  *
  * @see evas_object_image_load_dpi_set() for more details
  */
 EAPI double                        evas_object_image_load_dpi_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set the size of a given image object's source image, when loading
- * it.
+ * @brief   Sets the load size of a given image object's source image.
  *
- * @param obj The given canvas object.
- * @param w The new width of the image's load size.
- * @param h The new height of the image's load size.
+ * @details This function sets a new geometry size for the given canvas image.
+ *          The image will be loaded into memory as if it was the set size instead of
+ *          the original size.
  *
- * This function sets a new (loading) size for the given canvas
- * image.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks The size of a given image object's source image will be less than or
+ *          equal to the size of @p w and @p h.
+ *
+ * @param[in]   obj  The given canvas object
+ * @param[in]   w    The new width of the image's load size
+ * @param[in]   h    The new height of the image's load size
  *
  * @see evas_object_image_load_size_get()
  */
 EAPI void                          evas_object_image_load_size_set(Evas_Object *obj, int w, int h) EINA_ARG_NONNULL(1);
 
 /**
- * Get the size of a given image object's source image, when loading
- * it.
+ * @brief   Gets the load size of a given image object's source image.
+ *
+ * @details This function gets the geometry size set manually for the given canvas image.
  *
- * @param obj The given image object.
- * @param w Where to store the new width of the image's load size.
- * @param h Where to store the new height of the image's load size.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note Use @c NULL pointers on the size components you're not
- * interested in: they'll be ignored by the function.
+ * @remarks Use @c NULL pointers on the size components that you are not
+ *          interested in: they are ignored by the function.
+ *          @p w and @p h will be set with the image's loading size only if
+ *          the image's load size is set manually: if evas_object_image_load_size_set()
+ *          has not been called, @p w and @p h will be set with 0.
+ *
+ * @param[in]   obj  The given image object
+ * @param[out]   w    The new width of the image's load size that is returned
+ * @param[out]   h    The new height of the image's load size that is returned
  *
  * @see evas_object_image_load_size_set() for more details
  */
 EAPI void                          evas_object_image_load_size_get(const Evas_Object *obj, int *w, int *h) EINA_ARG_NONNULL(1);
 
 /**
- * Set the scale down factor of a given image object's source image,
- * when loading it.
+ * @brief   Sets the scale down factor of a given image object's source image,
+ *          when loading it.
+ *
+ * @details This function sets the scale down factor of a given canvas
+ *          image. This is useful for the SVG image loader.
  *
- * @param obj The given image object pointer.
- * @param scale_down The scale down factor.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function sets the scale down factor of a given canvas
- * image. Most useful for the SVG image loader.
+ * @param[in]   obj         The given image object pointer
+ * @param[in]   scale_down  The scale down factor
  *
  * @see evas_object_image_load_scale_down_get()
  */
 EAPI void                          evas_object_image_load_scale_down_set(Evas_Object *obj, int scale_down) EINA_ARG_NONNULL(1);
 
 /**
- * get the scale down factor of a given image object's source image,
- * when loading it.
+ * @brief  Gets the scale down factor of a given image object's source image,
+ *         when loading it.
  *
- * @param obj The given image object pointer.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  obj  The given image object pointer
+ * @return The scale down factor
  *
  * @see evas_object_image_load_scale_down_set() for more details
  */
 EAPI int                           evas_object_image_load_scale_down_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Inform a given image object to load a selective region of its
- * source image.
+ * @brief   Sets a selective region of the source image to load for the given image object.
+ *
+ * @details This function is useful when you are not showing all of an image's
+ *          area on its image object.
  *
- * @param obj The given image object pointer.
- * @param x X-offset of the region to be loaded.
- * @param y Y-offset of the region to be loaded.
- * @param w Width of the region to be loaded.
- * @param h Height of the region to be loaded.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function is useful when one is not showing all of an image's
- * area on its image object.
+ * @remarks The image loader for the image format in question has to
+ *          support selective region loading in order to this function to take effect.
  *
- * @note The image loader for the image format in question has to
- * support selective region loading in order to this function to take
- * effect.
+ * @param[in]   obj  The given image object pointer
+ * @param[in]   x    The X-offset of the region to be loaded
+ * @param[in]   y    The Y-offset of the region to be loaded
+ * @param[in]   w    The width of the region to be loaded
+ * @param[in]   h    The height of the region to be loaded
  *
  * @see evas_object_image_load_region_get()
  */
 EAPI void                          evas_object_image_load_region_set(Evas_Object *obj, int x, int y, int w, int h) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve the coordinates of a given image object's selective
- * (source image) load region.
+ * @brief   Gets the coordinates of a given image object's selective
+ *          (source image) load region.
  *
- * @param obj The given image object pointer.
- * @param x Where to store the X-offset of the region to be loaded.
- * @param y Where to store the Y-offset of the region to be loaded.
- * @param w Where to store the width of the region to be loaded.
- * @param h Where to store the height of the region to be loaded.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note Use @c NULL pointers on the coordinates you're not interested
- * in: they'll be ignored by the function.
+ * @remarks Use @c NULL pointers on the coordinates that you are not interested
+ *          in: they are ignored by the function.
+ *
+ * @param[in]   obj  The given image object pointer
+ * @param[out]   x    The X-offset of the region to be loaded
+ * @param[out]   y    The Y-offset of the region to be loaded
+ * @param[out]   w    The width of the region to be loaded
+ * @param[out]   h    The height of the region to be loaded
  *
  * @see evas_object_image_load_region_get()
  */
 EAPI void                          evas_object_image_load_region_get(const Evas_Object *obj, int *x, int *y, int *w, int *h) EINA_ARG_NONNULL(1);
 
 /**
- * Define if the orientation information in the image file should be honored.
+ * @brief   Sets whether the orientation information in the image file should be honored.
+ * @since   1.1
  *
- * @param obj The given image object pointer.
- * @param enable @c EINA_TRUE means that it should honor the orientation information
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj     The given image object pointer
+ * @param[in]   enable  Set #EINA_TRUE to honor the orientation information, \n
+ *                  otherwise #EINA_FALSE to not honor the orientation information
  */
 EAPI void                          evas_object_image_load_orientation_set(Evas_Object *obj, Eina_Bool enable) EINA_ARG_NONNULL(1);
 
 /**
- * Get if the orientation information in the image file should be honored.
+ * @brief  Checks whether the orientation information in the image file should be honored.
+ * @since  1.1
  *
- * @param obj The given image object pointer.
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  obj  The given image object pointer
+ * @return #EINA_TRUE if the orientation information is honored, \n
+ *         otherwise #EINA_FALSE if it is not honored
  */
 EAPI Eina_Bool                     evas_object_image_load_orientation_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Set the colorspace of a given image of the canvas.
+ * @brief   Sets the colorspace of a given image of the canvas.
+ *
+ * @details This function sets the colorspace of given canvas image.
  *
- * @param obj The given image object pointer.
- * @param cspace The new color space.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function sets the colorspace of given canvas image.
+ * @param[in]   obj     The given image object pointer
+ * @param[in]   cspace  The new color space
  *
  */
 EAPI void                          evas_object_image_colorspace_set(Evas_Object *obj, Evas_Colorspace cspace) EINA_ARG_NONNULL(1);
 
 /**
- * Get the colorspace of a given image of the canvas.
+ * @brief   Gets the colorspace of a given image of the canvas.
  *
- * @param obj The given image object pointer.
- * @return The colorspace of the image.
+ * @details This function returns the colorspace of given canvas image.
  *
- * This function returns the colorspace of given canvas image.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given image object pointer
+ * @return  The colorspace of the image
  *
  */
 EAPI Evas_Colorspace               evas_object_image_colorspace_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Get the support state of a given image
+ * @brief   Gets the support state of a given image.
  *
- * @param obj The given image object pointer
- * @return The region support state
- * @since 1.2
+ * @details This function returns the state of the region support of given image
+ * @since   1.2
  *
- * This function returns the state of the region support of given image
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given image object pointer
+ * @return  The region support state
  */
 EAPI Eina_Bool                     evas_object_image_region_support_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set the native surface of a given image of the canvas
+ * @brief   Sets the native surface of a given image of the canvas.
+ *
+ * @details This function sets a native surface of a given canvas image.
  *
- * @param obj The given canvas pointer.
- * @param surf The new native surface.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function sets a native surface of a given canvas image.
+ * @param[in]   obj   The given canvas pointer
+ * @param[in]   surf  The new native surface
  *
  */
 EAPI void                          evas_object_image_native_surface_set(Evas_Object *obj, Evas_Native_Surface *surf) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Get the native surface of a given image of the canvas
+ * @brief   Gets the native surface of a given image of the canvas.
  *
- * @param obj The given canvas pointer.
- * @return The native surface of the given canvas image.
+ * @details This function returns the native surface of a given canvas image.
  *
- * This function returns the native surface of a given canvas image.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given canvas pointer
+ * @return  The native surface of the given canvas image
  *
  */
 EAPI Evas_Native_Surface          *evas_object_image_native_surface_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set the video surface linked to a given image of the canvas
+ * @brief   Sets the video surface linked to a given image of the canvas.
  *
- * @param obj The given canvas pointer.
- * @param surf The new video surface.
- * @since 1.1
+ * @details This function links a video surface to a given canvas image.
+ * @since   1.1
  *
- * This function link a video surface to a given canvas image.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj   The given canvas pointer
+ * @param[in]   surf  The new video surface
  *
  */
 EAPI void                          evas_object_image_video_surface_set(Evas_Object *obj, Evas_Video_Surface *surf) EINA_ARG_NONNULL(1);
 
 /**
- * Get the video surface linekd to a given image of the canvas
+ * @brief   Gets the video surface linked to a given image of the canvas.
  *
- * @param obj The given canvas pointer.
- * @return The video surface of the given canvas image.
- * @since 1.1
+ * @details This function returns the video surface linked to a given canvas image.
+ * @since   1.1 
  *
- * This function returns the video surface linked to a given canvas image.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given canvas pointer
+ * @return  The video surface of the given canvas image
  *
  */
 EAPI const Evas_Video_Surface     *evas_object_image_video_surface_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set the scale hint of a given image of the canvas.
+ * @brief   Sets the scale hint of a given image of the canvas.
+ *
+ * @details This function sets the scale hint value of the given image object
+ *          in the canvas, which affects how Evas is to cache scaled
+ *          versions of its original source image.
  *
- * @param obj The given image object pointer.
- * @param hint The scale hint, a value in
- * #Evas_Image_Scale_Hint.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function sets the scale hint value of the given image object
- * in the canvas, which will affect how Evas is to cache scaled
- * versions of its original source image.
+ * @param[in]   obj   The given image object pointer
+ * @param[in]   hint  The scale hint \n
+ *                A #Evas_Image_Scale_Hint value.
  *
  * @see evas_object_image_scale_hint_get()
  */
 EAPI void                          evas_object_image_scale_hint_set(Evas_Object *obj, Evas_Image_Scale_Hint hint) EINA_ARG_NONNULL(1);
 
 /**
- * Get the scale hint of a given image of the canvas.
+ * @brief   Gets the scale hint of a given image of the canvas.
  *
- * @param obj The given image object pointer.
- * @return The scale hint value set on @p obj, a value in
- * #Evas_Image_Scale_Hint.
+ * @details This function returns the scale hint value of the given image
+ *          object of the canvas.
  *
- * This function returns the scale hint value of the given image
- * object of the canvas.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given image object pointer
+ * @return  The scale hint value set on @a obj \n 
+ *          A #Evas_Image_Scale_Hint value.
  *
  * @see evas_object_image_scale_hint_set() for more details.
  */
 EAPI Evas_Image_Scale_Hint         evas_object_image_scale_hint_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set the content hint setting of a given image object of the canvas.
+ * @brief   Sets the content hint setting of a given image object of the canvas.
+ *
+ * @details This function sets the content hint value of the given image of the
+ *          canvas. For example, if you are on the GL engine and your driver
+ *          implementation supports it, setting this hint to
+ *          #EVAS_IMAGE_CONTENT_HINT_DYNAMIC makes it need @b zero copies
+ *          at texture upload time, which is an "expensive" operation.
  *
- * @param obj The given canvas pointer.
- * @param hint The content hint value, one of the
- * #Evas_Image_Content_Hint ones.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function sets the content hint value of the given image of the
- * canvas. For example, if you're on the GL engine and your driver
- * implementation supports it, setting this hint to
- * #EVAS_IMAGE_CONTENT_HINT_DYNAMIC will make it need @b zero copies
- * at texture upload time, which is an "expensive" operation.
+ * @param[in]   obj   The given canvas pointer
+ * @param[in]   hint  The content hint value \n
+ *                Valid values are defined in #Evas_Image_Content_Hint.
  *
  * @see evas_object_image_content_hint_get()
  */
 EAPI void                          evas_object_image_content_hint_set(Evas_Object *obj, Evas_Image_Content_Hint hint) EINA_ARG_NONNULL(1);
 
 /**
- * Get the content hint setting of a given image object of the canvas.
+ * @brief   Gets the content hint setting of a given image object of the canvas.
  *
- * @param obj The given canvas pointer.
- * @return hint The content hint value set on it, one of the
- * #Evas_Image_Content_Hint ones (#EVAS_IMAGE_CONTENT_HINT_NONE means
- * an error).
+ * @details This function returns the content hint value of the given image of
+ *          the canvas.
  *
- * This function returns the content hint value of the given image of
- * the canvas.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given canvas pointer
+ * @return  The content hint value set on it \n 
+ *          Valid values are define in #Evas_Image_Content_Hint. \n
+ *          #EVAS_IMAGE_CONTENT_HINT_NONE means an error.
  *
  * @see evas_object_image_content_hint_set()
  */
 EAPI Evas_Image_Content_Hint       evas_object_image_content_hint_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Enable an image to be used as an alpha mask.
+ * @brief   Enables an image to be used as an alpha mask.
  *
- * This will set any flags, and discard any excess image data not used as an
- * alpha mask.
+ * @details This function sets flags, and discard any excess image data not used as an
+ *          alpha mask.
  *
- * Note there is little point in using a image as alpha mask unless it has an
- * alpha channel.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj Object to use as an alpha mask.
- * @param ismask Use image as alphamask, must be true.
+ * @remarks Note that there is little point in using a image as alpha mask unless it has an
+ *          alpha channel.
+ *
+ * @param[in]   obj     The object to use as an alpha mask
+ * @param[in]   ismask  Set #EINA_TRUE to use image as alphamask, 
+ *                  otherwise #EINA_FALSE to not use image as alphamask
  */
 EAPI void                          evas_object_image_alpha_mask_set(Evas_Object *obj, Eina_Bool ismask) EINA_ARG_NONNULL(1);
 
 /**
- * Set the source object on an image object to used as a @b proxy.
+ * @brief   Sets the source object on an image object to used as a @b proxy.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj Proxy (image) object.
- * @param src Source object to use for the proxy.
- * @return @c EINA_TRUE on success, @c EINA_FALSE on error.
+ * @remarks If an image object is set to behave as a @b proxy, it mirrors
+ *          the rendering contents of a given @b source object in its drawing
+ *          region, without affecting that source in any way. The source must
+ *          be another valid Evas object. Other effects may be applied to the
+ *          proxy, such as a map (see evas_object_map_set()) to create a
+ *          reflection of the original object (for example).
  *
- * If an image object is set to behave as a @b proxy, it will mirror
- * the rendering contents of a given @b source object in its drawing
- * region, without affecting that source in any way. The source must
- * be another valid Evas object. Other effects may be applied to the
- * proxy, such as a map (see evas_object_map_set()) to create a
- * reflection of the original object (for example).
+ * @remarks Any existing source object on @a obj is removed after this
+ *          call. Setting @a src to @c NULL clears the proxy object (not in
+ *          "proxy state" anymore).
  *
- * Any existing source object on @p obj will be removed after this
- * call. Setting @p src to @c NULL clears the proxy object (not in
- * "proxy state" anymore).
+ * @remarks You cannot set a proxy as another proxy's source.
  *
- * @warning You cannot set a proxy as another proxy's source.
+ * @param[in]   obj  The proxy (image) object
+ * @param[in]   src  The source object to use for the proxy
+ * @return  #EINA_TRUE if the source object is set successfully, \n
+ *          otherwise #EINA_FALSE on error
  *
  * @see evas_object_image_source_get()
  * @see evas_object_image_source_unset()
@@ -7472,64 +8582,167 @@ EAPI void                          evas_object_image_alpha_mask_set(Evas_Object
 EAPI Eina_Bool                     evas_object_image_source_set(Evas_Object *obj, Evas_Object *src) EINA_ARG_NONNULL(1);
 
 /**
- * Get the current source object of an image object.
+ * @brief   Gets the current source object of an image object.
  *
- * @param obj Image object
- * @return Source object (if any), or @c NULL, if not in "proxy mode"
- * (or on errors).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The Image object
+ * @return  The source object (if any), \n
+ *          otherwise @c NULL if not in "proxy mode" or on errors
  *
  * @see evas_object_image_source_set() for more details
  */
 EAPI Evas_Object                  *evas_object_image_source_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Clear the source object on a proxy image object.
+ * @brief   Clears the source object on a proxy image object.
+ *
+ * @details This function is equivalent to calling evas_object_image_source_set() with a
+ *          @c NULL source.
  *
- * @param obj Image object to clear source of.
- * @return @c EINA_TRUE on success, @c EINA_FALSE on error.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This is equivalent to calling evas_object_image_source_set() with a
- * @c NULL source.
+ * @param[in]   obj  The Image object to clear source of
+ * @return  #EINA_TRUE if the source object is cleared successfully, \n
+ *          otherwise #EINA_FALSE on error
  */
 EAPI Eina_Bool                     evas_object_image_source_unset(Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Check if a file extension may be supported by @ref Evas_Object_Image.
+ * @brief   Sets the source object to be visible.
+ * @since   1.8
  *
- * @param file The file to check
- * @return @c EINA_TRUE if we may be able to open it, @c EINA_FALSE if it's
- * unlikely.
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks If @a visible is set to #EINA_FALSE, the source object of the proxy (@a obj)
+ *          is invisible.
+ *
+ * @remarks This function works differently to evas_object_show() and evas_object_hide().
+ *          Once the source object is hidden by evas_object_hide() then the proxy object is 
+ *          hidden as well. Actually in this case both objects are excluded from the
+ *          Evas internal update circle.
+ *
+ * @remarks Using this method, you can toggle the visibility of a proxy's source
+ *          object keeping the proxy visibility untouched.
  *
- * If file is a Eina_Stringshare, use directly @ref evas_object_image_extension_can_load_fast_get.
+ * @param[in]   obj      The proxy (image) object
+ * @param[in]   visible  Set #EINA_TRUE to show the source object, \n
+ *                   otherwise set #EINA_FALSE to not show it
  *
- * This functions is threadsafe.
+ * @see evas_object_image_source_visible_get()
+ * @see evas_object_image_source_set()
+ * @see evas_object_show()
+ * @see evas_object_hide()
+ */
+EAPI void                          evas_object_image_source_visible_set(Evas_Object *obj, Eina_Bool visible) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief   Gets the state of the source object visibility.
+ * @since   1.8
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The proxy (image) object
+ * @return  #EINA_TRUE if source object is visible, \n
+ *          otherwise #EINA_FALSE
+ *
+ * @see evas_object_image_source_visible_set()
+ * @see evas_object_image_source_set()
+ * @see evas_object_show()
+ * @see evas_object_hide()
+ */
+EAPI Eina_Bool                     evas_object_image_source_visible_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief   Clips the proxy object with the source object's clipper.
+ * @since   1.8
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj          The proxy (image) object
+ * @param[in]   source_clip  Set #EINA_TRUE if @a obj must be clipped by the source clipper, \n
+ *                       otherwise set #EINA_FALSE
+ *
+ * @see evas_object_clip_set()
+ * @see evas_object_image_source_set()
+ */
+EAPI void evas_object_image_source_clip_set(Evas_Object *obj, Eina_Bool source_clip) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief   Checks whether an object is clipped by source object's clipper.
+ * @since   1.8
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The proxy (image) object
+ * @return  #EINA_TRUE if source clip is enabled,
+ *          otherwise #EINA_FALSE if source clip is not enabled
+ *
+ * @see evas_object_clip_set()
+ * @see evas_object_image_source_set()
+ * @see evas_object_image_source_clip_set()
+ */
+EAPI Eina_Bool evas_object_image_source_clip_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief   Checks whether a file extension is supported by @ref Evas_Object_Image.
+ * @since   1.1
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks If file is a Eina_Stringshare, use @ref evas_object_image_extension_can_load_fast_get directly.
+ *
+ * @remarks This function is threadsafe.
+ *
+ * @param[in]   file  The file to check
+ * @return  #EINA_TRUE if the file extension is supported, \n
+ *          otherwise #EINA_FALSE if it is not supported
  */
 EAPI Eina_Bool                     evas_object_image_extension_can_load_get(const char *file);
 
 /**
- * Check if a file extension may be supported by @ref Evas_Object_Image.
+ * @brief   Checks whether a file extension is supported by @ref Evas_Object_Image.
+ * @since   1.1
  *
- * @param file The file to check, it should be an Eina_Stringshare.
- * @return @c EINA_TRUE if we may be able to open it, @c EINA_FALSE if it's
- * unlikely.
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This functions is threadsafe.
+ * @remarks This function is threadsafe.
+ * @param[in]   file  The file to check \n
+ *                It should be Eina_Stringshare.
+ * @return  #EINA_TRUE if the file extension is supported, \n
+ *          otherwise #EINA_FALSE if it is not supported
  */
 EAPI Eina_Bool                     evas_object_image_extension_can_load_fast_get(const char *file);
 
 /**
- * Check if an image object can be animated (have multiple frames)
+ * @brief   Checks whether an image object can be animated (have multiple frames).
  *
- * @param obj Image object
- * @return whether obj support animation
+ * @details This function returns if the image file of an image object is capable of animation
+ *          such as an animated gif file might. This is only useful to be called once
+ *          the image object file has been set.
+ * @since   1.1
  *
- * This returns if the image file of an image object is capable of animation
- * such as an animated gif file might. This is only useful to be called once
- * the image object file has been set.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas_Object *obj;
  *
@@ -7562,23 +8775,31 @@ EAPI Eina_Bool                     evas_object_image_extension_can_load_fast_get
  *   }
  * @endcode
  *
+ * @param[in]   obj  The Image object
+ * @return  #EINA_TRUE if @a obj supports animation, \n
+ *          otherwise #EINA_FALSE if it does not support animation
+ *
  * @see evas_object_image_animated_get()
  * @see evas_object_image_animated_frame_count_get()
  * @see evas_object_image_animated_loop_type_get()
  * @see evas_object_image_animated_loop_count_get()
  * @see evas_object_image_animated_frame_duration_get()
  * @see evas_object_image_animated_frame_set()
- * @since 1.1
  */
 EAPI Eina_Bool                     evas_object_image_animated_get(const Evas_Object *obj);
 
 /**
- * Get the total number of frames of the image object.
+ * @brief   Gets the total number of frames of the image object.
+ *
+ * @details This returns the total number of frames the image object supports (if animated).
+ * @since   1.1
  *
- * @param obj Image object
- * @return The number of frames
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This returns total number of frames the image object supports (if animated)
+ * @param[in]   obj  The Image object
+ * @return  The number of frames
  *
  * @see evas_object_image_animated_get()
  * @see evas_object_image_animated_frame_count_get()
@@ -7586,24 +8807,27 @@ EAPI Eina_Bool                     evas_object_image_animated_get(const Evas_Obj
  * @see evas_object_image_animated_loop_count_get()
  * @see evas_object_image_animated_frame_duration_get()
  * @see evas_object_image_animated_frame_set()
- * @since 1.1
  */
 EAPI int                           evas_object_image_animated_frame_count_get(const Evas_Object *obj);
 
 /**
- * Get the kind of looping the image object does.
+ * @brief   Gets the kind of looping the image object does.
  *
- * @param obj Image object
- * @return Loop type of the image object
+ * @details This function returns the kind of looping the image object wants to do.
+ * @since   1.1
  *
- * This returns the kind of looping the image object wants to do.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * If it returns EVAS_IMAGE_ANIMATED_HINT_LOOP, you should display frames in a sequence like:
- * 1->2->3->1->2->3->1...
- * If it returns EVAS_IMAGE_ANIMATED_HINT_PINGPONG, it is better to
- * display frames in a sequence like: 1->2->3->2->1->2->3->1...
+ * @remarks If it returns @c EVAS_IMAGE_ANIMATED_HINT_LOOP, you should display frames in a sequence like:
+ *          1->2->3->1->2->3->1...
+ *          If it returns @c EVAS_IMAGE_ANIMATED_HINT_PINGPONG, it is better to
+ *          display frames in a sequence like: 1->2->3->2->1->2->3->1... 
+ *          The default type is EVAS_IMAGE_ANIMATED_HINT_LOOP.
  *
- * The default type is EVAS_IMAGE_ANIMATED_HINT_LOOP.
+ * @param[in]   obj  The Image object
+ * @return  The Loop type of the image object
  *
  * @see evas_object_image_animated_get()
  * @see evas_object_image_animated_frame_count_get()
@@ -7611,22 +8835,26 @@ EAPI int                           evas_object_image_animated_frame_count_get(co
  * @see evas_object_image_animated_loop_count_get()
  * @see evas_object_image_animated_frame_duration_get()
  * @see evas_object_image_animated_frame_set()
- * @since 1.1
  */
 EAPI Evas_Image_Animated_Loop_Hint evas_object_image_animated_loop_type_get(const Evas_Object *obj);
 
 /**
- * Get the number times the animation of the object loops.
+ * @brief   Gets the number of times the animation of the object loops.
  *
- * @param obj Image object
- * @return The number of loop of an animated image object
+ * @details This function returns loop count of image. The loop count is the number of times
+ *          the animation plays fully from first to last frame until the animation
+ *          should stop (at the final frame).
+ * @since   1.1
  *
- * This returns loop count of image. The loop count is the number of times
- * the animation will play fully from first to last frame until the animation
- * should stop (at the final frame).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * If 0 is returned, then looping should happen indefinitely (no limit to
- * the number of times it loops).
+ * @remarks If @c 0 is returned, then looping should happen indefinitely (no limit to
+ *          the number of times it loops).
+ *
+ * @param[in]   obj  The Image object
+ * @return  The number of loop of an animated image object
  *
  * @see evas_object_image_animated_get()
  * @see evas_object_image_animated_frame_count_get()
@@ -7634,23 +8862,28 @@ EAPI Evas_Image_Animated_Loop_Hint evas_object_image_animated_loop_type_get(cons
  * @see evas_object_image_animated_loop_count_get()
  * @see evas_object_image_animated_frame_duration_get()
  * @see evas_object_image_animated_frame_set()
- * @since 1.1
  */
 EAPI int                           evas_object_image_animated_loop_count_get(const Evas_Object *obj);
 
 /**
- * Get the duration of a sequence of frames.
+ * @brief   Gets the duration of a sequence of frames.
  *
- * @param obj Image object
- * @param start_frame The first frame
- * @param fram_num Number of frames in the sequence
+ * @details This function returns the total duration that the specified sequence of frames should
+ *          take in seconds.
+ * @since   1.1
  *
- * This returns total duration that the specified sequence of frames should
- * take in seconds.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * If you set start_frame to 1 and frame_num 0, you get frame 1's duration
- * If you set start_frame to 1 and frame_num 1, you get frame 1's duration +
- * frame2's duration
+ * @remarks If you set start_frame to 1 and frame_num 0, you get frame 1's duration.
+ *          If you set start_frame to 1 and frame_num 1, you get frame 1's duration +
+ *          frame2's duration.
+ *
+ * @param[in]   obj          The Image object
+ * @param[in]   start_frame  The first frame
+ * @param[in]   fram_num     The number of frames in the sequence
+ * @return The duraction of a sequence of frames.
  *
  * @see evas_object_image_animated_get()
  * @see evas_object_image_animated_frame_count_get()
@@ -7658,18 +8891,22 @@ EAPI int                           evas_object_image_animated_loop_count_get(con
  * @see evas_object_image_animated_loop_count_get()
  * @see evas_object_image_animated_frame_duration_get()
  * @see evas_object_image_animated_frame_set()
- * @since 1.1
  */
 EAPI double                        evas_object_image_animated_frame_duration_get(const Evas_Object *obj, int start_frame, int fram_num);
 
 /**
- * Set the frame to current frame of an image object
+ * @brief   Sets the frame to the current frame of an image object.
  *
- * @param obj The given image object.
- * @param frame_num The index of current frame
+ * @details This function sets the image object's current frame to frame_num 
+ *          with 1 being the first frame.
+ * @since   1.1
  *
- * This set image object's current frame to frame_num with 1 being the first
- * frame.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj        The given image object
+ * @param[in]   frame_num  The index of current frame
  *
  * @see evas_object_image_animated_get()
  * @see evas_object_image_animated_frame_count_get()
@@ -7677,39 +8914,33 @@ EAPI double                        evas_object_image_animated_frame_duration_get
  * @see evas_object_image_animated_loop_count_get()
  * @see evas_object_image_animated_frame_duration_get()
  * @see evas_object_image_animated_frame_set()
- * @since 1.1
  */
 EAPI void                          evas_object_image_animated_frame_set(Evas_Object *obj, int frame_num);
+
 /**
  * @}
  */
 
 /**
  * @defgroup Evas_Object_Text Text Object Functions
+ * @ingroup Evas_Object_Specific
  *
- * Functions that operate on single line, single style text objects.
+ * @brief  This group provides functions that operate on single line, single style text objects.
  *
  * For multiline and multiple style text, see @ref Evas_Object_Textblock.
  *
- * See some @ref Example_Evas_Text "examples" on this group of functions.
+ * @remarks We do not guarantee any proper results if you create a Text object
+ *          without setting the evas engine.
  *
- * @warning We don't guarantee any proper results if you create a Text object
- * without setting the evas engine.
- *
- * @ingroup Evas_Object_Specific
- */
-
-/**
- * @addtogroup Evas_Object_Text
  * @{
  */
 
-/* basic styles (4 bits allocated use 0->10 now, 5 left) */
+/* Definition for basic styles (4 bits allocated use 0->10 now, 5 left) */
 #define EVAS_TEXT_STYLE_MASK_BASIC 0xf
 
 /**
- * Text style type creation macro. Use style types on the 's'
- * arguments, being 'x' your style variable.
+ * @brief Definition for text style type creation macro. Use style types on the 's'
+ *        arguments, being 'x' your style variable.
  */
 #define EVAS_TEXT_STYLE_BASIC_SET(x, s) \
   do { x = ((x) & ~EVAS_TEXT_STYLE_MASK_BASIC) | (s); } while (0)
@@ -7717,46 +8948,60 @@ EAPI void                          evas_object_image_animated_frame_set(Evas_Obj
 #define EVAS_TEXT_STYLE_MASK_SHADOW_DIRECTION (0x7 << 4)
 
 /**
- * Text style type creation macro. This one will impose shadow
- * directions on the style type variable -- use the @c
- * EVAS_TEXT_STYLE_SHADOW_DIRECTION_* values on 's', incrementally.
+ * @brief Definition for text style type creation macro. This one imposes shadow
+ *        directions on the style type variable -- use the @c
+ *        EVAS_TEXT_STYLE_SHADOW_DIRECTION_* values on 's', incrementally.
  */
 #define EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET(x, s) \
   do { x = ((x) & ~EVAS_TEXT_STYLE_MASK_SHADOW_DIRECTION) | (s); } while (0)
 
+/**
+ * Types of styles to be applied on text objects.
+ * The @c EVAS_TEXT_STYLE_SHADOW_DIRECTION_* ones are to be ORed together with
+ * others imposing shadow, to change shadow's direction
+ */
 typedef enum _Evas_Text_Style_Type
 {
-   EVAS_TEXT_STYLE_PLAIN,      /**< plain, standard text */
-   EVAS_TEXT_STYLE_SHADOW,      /**< text with shadow underneath */
-   EVAS_TEXT_STYLE_OUTLINE,      /**< text with an outline */
-   EVAS_TEXT_STYLE_SOFT_OUTLINE,      /**< text with a soft outline */
-   EVAS_TEXT_STYLE_GLOW,      /**< text with a glow effect */
-   EVAS_TEXT_STYLE_OUTLINE_SHADOW,      /**< text with both outline and shadow effects */
-   EVAS_TEXT_STYLE_FAR_SHADOW,      /**< text with (far) shadow underneath */
-   EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW,      /**< text with outline and soft shadow effects combined */
-   EVAS_TEXT_STYLE_SOFT_SHADOW,      /**< text with (soft) shadow underneath */
-   EVAS_TEXT_STYLE_FAR_SOFT_SHADOW,      /**< text with (far soft) shadow underneath */
+   EVAS_TEXT_STYLE_PLAIN,      /**< Plain, standard text */
+   EVAS_TEXT_STYLE_SHADOW,      /**< Text with shadow underneath */
+   EVAS_TEXT_STYLE_OUTLINE,      /**< Text with an outline */
+   EVAS_TEXT_STYLE_SOFT_OUTLINE,      /**< Text with a soft outline */
+   EVAS_TEXT_STYLE_GLOW,      /**< Text with a glow effect */
+   EVAS_TEXT_STYLE_OUTLINE_SHADOW,      /**< Text with both outline and shadow effects */
+   EVAS_TEXT_STYLE_FAR_SHADOW,      /**< Text with (far) shadow underneath */
+   EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW,      /**< Text with outline and soft shadow effects combined */
+   EVAS_TEXT_STYLE_SOFT_SHADOW,      /**< Text with (soft) shadow underneath */
+   EVAS_TEXT_STYLE_FAR_SOFT_SHADOW,      /**< Text with (far soft) shadow underneath */
+   // TIZEN ONLY (20131106) : Font effect for tizen.
+   EVAS_TEXT_STYLE_TIZEN_GLOW_SHADOW,      /** Tizen::Graphics::Effect::EFFECT_FOR_TEXT_ON_HOME_SCREEN_ICON */
+   EVAS_TEXT_STYLE_TIZEN_SOFT_GLOW_SHADOW,      /** Tizen::Graphics::Effect::EFFECT_FOR_TEXT_ON_DYNAMIC_BOX_IMPORT_IMAGE */
+   EVAS_TEXT_STYLE_TIZEN_SHADOW,      /** Tizen::Graphics::Effect::EFFECT_FOR_TEXT_ON_DYNAMIC_BOX_IMAGE */
+   //////////////////////////////
 
    /* OR these to modify shadow direction (3 bits needed) */
-   EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_RIGHT = (0x0 << 4),      /**< shadow growing to bottom right */
-   EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM = (0x1 << 4),            /**< shadow growing to the bottom */
-   EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_LEFT = (0x2 << 4),       /**< shadow growing to bottom left */
-   EVAS_TEXT_STYLE_SHADOW_DIRECTION_LEFT = (0x3 << 4),              /**< shadow growing to the left */
-   EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_LEFT = (0x4 << 4),          /**< shadow growing to top left */
-   EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP = (0x5 << 4),               /**< shadow growing to the top */
-   EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_RIGHT = (0x6 << 4),         /**< shadow growing to top right */
-   EVAS_TEXT_STYLE_SHADOW_DIRECTION_RIGHT = (0x7 << 4)             /**< shadow growing to the right */
-} Evas_Text_Style_Type;      /**< Types of styles to be applied on text objects. The @c EVAS_TEXT_STYLE_SHADOW_DIRECTION_* ones are to be ORed together with others imposing shadow, to change shadow's direction */
+   EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_RIGHT = (0x0 << 4),      /**< Shadow growing to bottom right */
+   EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM = (0x1 << 4),            /**< Shadow growing to the bottom */
+   EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_LEFT = (0x2 << 4),       /**< Shadow growing to bottom left */
+   EVAS_TEXT_STYLE_SHADOW_DIRECTION_LEFT = (0x3 << 4),              /**< Shadow growing to the left */
+   EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_LEFT = (0x4 << 4),          /**< Shadow growing to top left */
+   EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP = (0x5 << 4),               /**< Shadow growing to the top */
+   EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_RIGHT = (0x6 << 4),         /**< Shadow growing to top right */
+   EVAS_TEXT_STYLE_SHADOW_DIRECTION_RIGHT = (0x7 << 4)             /**< Shadow growing to the right */
+} Evas_Text_Style_Type;
 
 /**
- * Creates a new text object on the provided canvas.
+ * @brief   Creates a new text object on the provided canvas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The canvas to create the text object on.
- * @return @c NULL on error, a pointer to a new text object on
- * success.
+ * @remarks Text objects are for simple, single line text elements. If you want
+ *          more elaborated text blocks, see @ref Evas_Object_Textblock.
  *
- * Text objects are for simple, single line text elements. If you want
- * more elaborated text blocks, see @ref Evas_Object_Textblock.
+ * @param[in]   e  The canvas to create the text object on
+ * @return  A pointer to a new text object on success, \n
+ *          otherwise @c NULL on error
  *
  * @see evas_object_text_font_source_set()
  * @see evas_object_text_font_set()
@@ -7765,42 +9010,53 @@ typedef enum _Evas_Text_Style_Type
 EAPI Evas_Object         *evas_object_text_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Set the font (source) file to be used on a given text object.
+ * @brief   Sets the font (source) file to be used on a given text object.
  *
- * @param obj The text object to set font for.
- * @param font The font file's path.
+ * @details This function allows the font file to be explicitly set for a given
+ *          text object, overriding system lookup, which first occurs in
+ *          the given file's contents.
  *
- * This function allows the font file to be explicitly set for a given
- * text object, overriding system lookup, which will first occur in
- * the given file's contents.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj   The text object to set font for
+ * @param[in]   font  The font file's path
  *
  * @see evas_object_text_font_get()
  */
 EAPI void                 evas_object_text_font_source_set(Evas_Object *obj, const char *font) EINA_ARG_NONNULL(1);
 
 /**
- * Get the font file's path which is being used on a given text
- * object.
+ * @brief   Gets the font file's path which is being used on a given text object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The text object to set font for.
- * @return The font file's path.
+ * @param[in]   obj  The text object to set the font for
+ * @return  The font file's path
  *
  * @see evas_object_text_font_get() for more details
  */
 EAPI const char          *evas_object_text_font_source_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set the font family and size on a given text object.
+ * @brief   Sets the font family and size on a given text object.
  *
- * @param obj The text object to set font for.
- * @param font The font (family) name.
- * @param size The font size, in points.
+ * @details This function allows the font name and size of a text object to be
+ *          set. The @a font string has to follow fontconfig's convention on
+ *          naming fonts, as it is the underlying library used to query system
+ *          fonts by Evas (see the @c fc-list command's output, on your system,
+ *          to get an idea).
  *
- * This function allows the font name and size of a text object to be
- * set. The @p font string has to follow fontconfig's convention on
- * naming fonts, as it's the underlying library used to query system
- * fonts by Evas (see the @c fc-list command's output, on your system,
- * to get an idea).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj   The text object to set font for
+ * @param[in]   font  The font (family) name
+ * @param[in]   size  The font size, in points
  *
  * @see evas_object_text_font_get()
  * @see evas_object_text_font_source_set()
@@ -7808,136 +9064,241 @@ EAPI const char          *evas_object_text_font_source_get(const Evas_Object *ob
 EAPI void                 evas_object_text_font_set(Evas_Object *obj, const char *font, Evas_Font_Size size) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve the font family and size in use on a given text object.
+ * @brief   Gets the font family and size in use on a given text object.
+ *
+ * @details This function allows the font name and size of a text object to be
+ *          queried. Be aware that the font name string is still owned by Evas
+ *          and should @b not have free() called on it by the caller of the
+ *          function.
  *
- * @param obj The evas text object to query for font information.
- * @param font A pointer to the location to store the font name in.
- * @param size A pointer to the location to store the font size in.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function allows the font name and size of a text object to be
- * queried. Be aware that the font name string is still owned by Evas
- * and should @b not have free() called on it by the caller of the
- * function.
+ * @param[in]   obj   The evas text object to query for font information
+ * @param[out]   font  A pointer to the location to store the font name in
+ * @param[out]   size  A pointer to the location to store the font size in
  *
  * @see evas_object_text_font_set()
  */
 EAPI void                 evas_object_text_font_get(const Evas_Object *obj, const char **font, Evas_Font_Size *size) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the text string to be displayed by the given text object.
+ * @brief  Sets the text string to be displayed by the given text object.
  *
- * @param obj The text object to set text string on.
- * @param text Text string to display on it.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  obj   The text object to set text string on
+ * @param[in]  text  The text string to display on it
  *
  * @see evas_object_text_text_get()
  */
 EAPI void                 evas_object_text_text_set(Evas_Object *obj, const char *text) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the text string currently being displayed by the given
- * text object.
+ * @brief   Gets the text string currently being displayed by the given text object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param  obj The given text object.
- * @return The text string currently being displayed on it.
+ * @remarks Do not free() the return value.
  *
- * @note Do not free() the return value.
+ * @param[in]   obj  The given text object
+ * @return  The text string currently being displayed on it
  *
  * @see evas_object_text_text_set()
  */
 EAPI const char          *evas_object_text_text_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * @brief Sets the BiDi delimiters used in the textblock.
+ * @brief   Sets the BiDi delimiters used in the textblock. 
+ * @since   1.1
  *
- * BiDi delimiters are use for in-paragraph separation of bidi segments. This
- * is useful for example in recipients fields of e-mail clients where bidi
- * oddities can occur when mixing RTL and LTR.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given text object.
- * @param delim A null terminated string of delimiters, e.g ",|".
- * @since 1.1
+ * @remarks BiDi delimiters are use for in-paragraph separation of bidi segments. This
+ *          is useful for example in recipients fields of e-mail clients where bidi
+ *          oddities can occur when mixing RTL and LTR.
+ *
+ * @param[in]   obj    The given text object
+ * @param[in]   delim  A null terminated string of delimiters, for example ",|"
  */
 EAPI void                 evas_object_text_bidi_delimiters_set(Evas_Object *obj, const char *delim);
 
 /**
- * @brief Gets the BiDi delimiters used in the textblock.
+ * @brief   Gets the BiDi delimiters used in the textblock.
+ * @since   1.1
  *
- * BiDi delimiters are use for in-paragraph separation of bidi segments. This
- * is useful for example in recipients fields of e-mail clients where bidi
- * oddities can occur when mixing RTL and LTR.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given text object.
- * @return A null terminated string of delimiters, e.g ",|". If empty, returns NULL.
- * @since 1.1
+ * @remarks BiDi delimiters are use for in-paragraph separation of bidi segments. This
+ *          is useful for example in recipients fields of e-mail clients where bidi
+ *          oddities can occur when mixing RTL and LTR.
+ *
+ * @param[in]   obj  The given text object
+ * @return  A null terminated string of delimiters, for example, ",|", \n 
+ *          otherwise @c NULL if empty
  */
 EAPI const char          *evas_object_text_bidi_delimiters_get(const Evas_Object *obj);
 
+/**
+ * @brief   Sets the ellipsis that should be used for the text object.
+ *
+ * @details This is a value between @c 0.0 and @c 1.0 indicating the position of the text
+ *          to be shown. @c 0.0 means the start is shown and the end trimmed, @c 1.0
+ *          means the beginning is trimmed and the end is shown, and any value
+ *          in between causes ellipsis to be added in both the end of the text and the
+ *          requested part to be shown.
+ * @since   1.8
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks @c -1.0 means ellipsis is turned off.
+ *
+ * @param[in]   obj       The given text object
+ * @param[in]   ellipsis  The ellipsis
+ */
+EAPI void                 evas_object_text_ellipsis_set(Evas_Object *obj, double ellipsis);
+
+/**
+ * @brief   Gets the ellipsis currently set on the text object.
+ * @since   1.8
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given text object
+ * @return  The ellipsis set on the text object
+ * @see evas_object_text_ellipsis_set()
+ */
+EAPI double               evas_object_text_ellipsis_get(const Evas_Object *obj);
+
+/**
+ * @internal
+ */
 EAPI Evas_Coord           evas_object_text_ascent_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+
+/**
+ * @internal
+ */
 EAPI Evas_Coord           evas_object_text_descent_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+
+/**
+ * @internal
+ */
 EAPI Evas_Coord           evas_object_text_max_ascent_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+
+/**
+ * @internal
+ */
 EAPI Evas_Coord           evas_object_text_max_descent_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+
+/**
+ * @internal
+ */
 EAPI Evas_Coord           evas_object_text_horiz_advance_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+
+/**
+ * @internal
+ */
 EAPI Evas_Coord           evas_object_text_vert_advance_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+
+/**
+ * @internal
+ */
 EAPI Evas_Coord           evas_object_text_inset_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve position and dimension information of a character within a text @c Evas_Object.
+ * @brief   Gets the position and dimension information of a character within a text @c Evas_Object.
  *
- * This function is used to obtain the X, Y, width and height of a the character
- * located at @p pos within the @c Evas_Object @p obj. @p obj must be a text object
- * as created with evas_object_text_add(). Any of the @c Evas_Coord parameters (@p cx,
- * @p cy, @p cw, @p ch) may be @c NULL in which case no value will be assigned to that
- * parameter.
+ * @details This function is used to obtain the X, Y, width and height of a the character
+ *          located at @a pos within the @c Evas_Object @a obj. @a obj must be a text object
+ *          as created with evas_object_text_add(). Any of the @c Evas_Coord parameters (@p cx,
+ *          @a cy, @a cw, @a ch) may be @c NULL in which case no value is assigned to that
+ *          parameter.
  *
- * @param obj  The text object to retrieve position information for.
- * @param pos  The character position to request co-ordinates for.
- * @param cx   A pointer to an @c Evas_Coord to store the X value in (can be NULL).
- * @param cy   A pointer to an @c Evas_Coord to store the Y value in (can be NULL).
- * @param cw   A pointer to an @c Evas_Coord to store the Width value in (can be NULL).
- * @param ch   A pointer to an @c Evas_Coord to store the Height value in (can be NULL).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @return @c EINA_FALSE on success, @c EINA_TRUE on error.
+ * @param[in]   obj  The text object to retrieve position information for
+ * @param[in]   pos  The character position to request co-ordinates for
+ * @param[out]   cx   A pointer to an @c Evas_Coord to store the X value in (can be @c NULL)
+ * @param[out]   cy   A pointer to an @c Evas_Coord to store the Y value in (can be @c NULL)
+ * @param[out]   cw   A pointer to an @c Evas_Coord to store the Width value in (can be @c NULL)
+ * @param[out]   ch   A pointer to an @c Evas_Coord to store the Height value in (can be @c NULL)
+ * @return  #EINA_FALSE if the information is obtained successfully, 
+ *          otherwise #EINA_TRUE on error
  */
 EAPI Eina_Bool            evas_object_text_char_pos_get(const Evas_Object *obj, int pos, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
+
+/**
+ * @internal
+ */
 EAPI int                  evas_object_text_char_coords_get(const Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
 
 /**
- * Returns the logical position of the last char in the text
- * up to the pos given. this is NOT the position of the last char
- * because of the possibility of RTL in the text.
+ * @brief   Gets the logical position of the last char in the text up to the given position. \n
+ *          This is NOT the position of the last char because of the possibility of RTL in the text.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj     The text object
+ * @param[in]   x       The X co-ordinate
+ * @param[in]   y       The Y co-ordinate
+ * @return  The logical The positoin of the last char in the text up to the given position
  */
 EAPI int                  evas_object_text_last_up_to_pos(const Evas_Object *obj, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the style on use on the given text object.
+ * @brief   Gets the style on use on the given text object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj the given text object to set style on.
- * @return the style type in use.
+ * @param[in]   obj  The given text object to set style on
+ * @return  The style type in use
  *
  * @see evas_object_text_style_set() for more details.
  */
 EAPI Evas_Text_Style_Type evas_object_text_style_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Sets the style to apply on the given text object.
+ * @brief   Sets the style to apply on the given text object.
  *
- * @param obj the given text object to set style on.
- * @param type a style type.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Text object styles are one of the values in
- * #Evas_Text_Style_Type. Some of those values are combinations of
- * more than one style, and some account for the direction of the
- * rendering of shadow effects.
+ * @remarks Valid text object styles are defined in #Evas_Text_Style_Type. 
+ *          Some of those values are combinations of more than one style, 
+ *          and some account for the direction of the rendering of shadow effects.
  *
- * @note One may use the helper macros #EVAS_TEXT_STYLE_BASIC_SET and
- * #EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET to assemble a style value.
+ * @remarks You can use the helper macros #EVAS_TEXT_STYLE_BASIC_SET and
+ *          #EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET to assemble a style value.
  *
- * The following figure illustrates the text styles:
+ * @remarks The following figure illustrates the text styles:
  *
  * @image html text-styles.png
  * @image rtf text-styles.png
  * @image latex text-styles.eps
  *
+ * @param[in]   obj   The given text object to set style on
+ * @param[in]   type  The style type
+ *
  * @see evas_object_text_style_get()
  * @see evas_object_text_shadow_color_set()
  * @see evas_object_text_outline_color_set()
@@ -7947,247 +9308,329 @@ EAPI Evas_Text_Style_Type evas_object_text_style_get(const Evas_Object *obj) EIN
 EAPI void                 evas_object_text_style_set(Evas_Object *obj, Evas_Text_Style_Type type) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the shadow color for the given text object.
+ * @brief   Sets the shadow color for the given text object.
  *
- * @param obj The given Evas text object.
- * @param r The red component of the given color.
- * @param g The green component of the given color.
- * @param b The blue component of the given color.
- * @param a The alpha component of the given color.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Shadow effects, which are fading colors decorating the text
- * underneath it, will just be shown if the object is set to one of
- * the following styles:
+ * @remarks Shadow effects, which are fading colors decorating the text
+ *          underneath it, are just shown if the object is set to one of
+ *          the following styles:
+ *          - #EVAS_TEXT_STYLE_SHADOW
+ *          - #EVAS_TEXT_STYLE_OUTLINE_SHADOW
+ *          - #EVAS_TEXT_STYLE_FAR_SHADOW
+ *          - #EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW
+ *          - #EVAS_TEXT_STYLE_SOFT_SHADOW
+ *          - #EVAS_TEXT_STYLE_FAR_SOFT_SHADOW
  *
- * - #EVAS_TEXT_STYLE_SHADOW
- * - #EVAS_TEXT_STYLE_OUTLINE_SHADOW
- * - #EVAS_TEXT_STYLE_FAR_SHADOW
- * - #EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW
- * - #EVAS_TEXT_STYLE_SOFT_SHADOW
- * - #EVAS_TEXT_STYLE_FAR_SOFT_SHADOW
+ * @remarks You can also change the direction where the shadow grows to, with
+ *          evas_object_text_style_set().
  *
- * One can also change the direction where the shadow grows to, with
- * evas_object_text_style_set().
+ * @param[in]   obj  The given Evas text object
+ * @param[in]   r    The red component of the given color
+ * @param[in]   g    The green component of the given color
+ * @param[in]   b    The blue component of the given color
+ * @param[in]   a    The alpha component of the given color
  *
  * @see evas_object_text_shadow_color_get()
  */
 EAPI void                 evas_object_text_shadow_color_set(Evas_Object *obj, int r, int g, int b, int a) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the shadow color for the given text object.
+ * @brief   Gets the shadow color for the given text object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given Evas text object.
- * @param r Pointer to variable to hold the red component of the given
- * color.
- * @param g Pointer to variable to hold the green component of the
- * given color.
- * @param b Pointer to variable to hold the blue component of the
- * given color.
- * @param a Pointer to variable to hold the alpha component of the
- * given color.
+ * @remarks Use @c NULL pointers on the color components that you are not
+ *          interested in: they are ignored by the function.
  *
- * @note Use @c NULL pointers on the color components you're not
- * interested in: they'll be ignored by the function.
+ * @param[in]   obj  The given Evas text object
+ * @param[out]   r    The pointer to variable to hold the red component of the given color
+ * @param[out]   g    The pointer to variable to hold the green component of the given color
+ * @param[out]   b    The pointer to variable to hold the blue component of the given color
+ * @param[out]   a    The pointer to variable to hold the alpha component of the given color
  *
  * @see evas_object_text_shadow_color_set() for more details.
  */
 EAPI void                 evas_object_text_shadow_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the glow color for the given text object.
+ * @brief   Sets the glow color for the given text object.
  *
- * @param obj The given Evas text object.
- * @param r The red component of the given color.
- * @param g The green component of the given color.
- * @param b The blue component of the given color.
- * @param a The alpha component of the given color.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Glow effects, which are glowing colors decorating the text's
- * surroundings, will just be shown if the object is set to the
- * #EVAS_TEXT_STYLE_GLOW style.
+ * @remarks Glow effects, which are glowing colors decorating the text's
+ *          surroundings, are shown if the object is set to the
+ *          #EVAS_TEXT_STYLE_GLOW style.
  *
- * @note Glow effects are placed from a short distance of the text
- * itself, but no touching it. For glowing effects right on the
- * borders of the glyphs, see 'glow 2' effects
- * (evas_object_text_glow2_color_set()).
+ * @remarks Glow effects are placed from a short distance of the text
+ *          itself, but no touching it. For glowing effects right on the
+ *          borders of the glyphs, see 'glow 2' effects
+ *          (evas_object_text_glow2_color_set()).
+ *
+ * @param[in]   obj  The given Evas text object
+ * @param[in]   r    The red component of the given color
+ * @param[in]   g    The green component of the given color
+ * @param[in]   b    The blue component of the given color
+ * @param[in]   a    The alpha component of the given color
  *
  * @see evas_object_text_glow_color_get()
  */
 EAPI void                 evas_object_text_glow_color_set(Evas_Object *obj, int r, int g, int b, int a) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the glow color for the given text object.
+ * @brief   Gets the glow color for the given text object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given Evas text object.
- * @param r Pointer to variable to hold the red component of the given
- * color.
- * @param g Pointer to variable to hold the green component of the
- * given color.
- * @param b Pointer to variable to hold the blue component of the
- * given color.
- * @param a Pointer to variable to hold the alpha component of the
- * given color.
+ * @remarks Use @c NULL pointers on the color components that you are not
+ *          interested in: they are ignored by the function.
  *
- * @note Use @c NULL pointers on the color components you're not
- * interested in: they'll be ignored by the function.
+ * @param[in]   obj  The given Evas text object.
+ * @param[out]   r    The pointer to variable to hold the red component of the given color
+ * @param[out]   g    The pointer to variable to hold the green component of the given color
+ * @param[out]   b    The pointer to variable to hold the blue component of the given color
+ * @param[out]   a    The pointer to variable to hold the alpha component of the given color
  *
  * @see evas_object_text_glow_color_set() for more details.
  */
 EAPI void                 evas_object_text_glow_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the 'glow 2' color for the given text object.
+ * @brief   Sets the 'glow 2' color for the given text object.
  *
- * @param obj The given Evas text object.
- * @param r The red component of the given color.
- * @param g The green component of the given color.
- * @param b The blue component of the given color.
- * @param a The alpha component of the given color.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * 'Glow 2' effects, which are glowing colors decorating the text's
- * (immediate) surroundings, will just be shown if the object is set
- * to the #EVAS_TEXT_STYLE_GLOW style. See also
- * evas_object_text_glow_color_set().
+ * @remarks 'Glow 2' effects, which are glowing colors decorating the text's
+ *          (immediate) surroundings, are shown if the object is set
+ *          to the #EVAS_TEXT_STYLE_GLOW style. See also
+ *          evas_object_text_glow_color_set().
+ *
+ * @param[in]   obj  The given Evas text object
+ * @param[in]   r    The red component of the given color
+ * @param[in]   g    The green component of the given color
+ * @param[in]   b    The blue component of the given color
+ * @param[in]   a    The alpha component of the given color
  *
  * @see evas_object_text_glow2_color_get()
  */
 EAPI void                 evas_object_text_glow2_color_set(Evas_Object *obj, int r, int g, int b, int a) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the 'glow 2' color for the given text object.
+ * @brief   Gets the 'glow 2' color for the given text object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given Evas text object.
- * @param r Pointer to variable to hold the red component of the given
- * color.
- * @param g Pointer to variable to hold the green component of the
- * given color.
- * @param b Pointer to variable to hold the blue component of the
- * given color.
- * @param a Pointer to variable to hold the alpha component of the
- * given color.
+ * @remarks Use @c NULL pointers on the color components that you are not
+ *          interested in: they are ignored by the function.
  *
- * @note Use @c NULL pointers on the color components you're not
- * interested in: they'll be ignored by the function.
+ * @param[in]   obj  The given Evas text object
+ * @param[out]   r    The pointer to variable to hold the red component of the given color
+ * @param[out]   g    The pointer to variable to hold the green component of the given color
+ * @param[out]   b    The pointer to variable to hold the blue component of the given color
+ * @param[out]   a    The pointer to variable to hold the alpha component of the given color
  *
  * @see evas_object_text_glow2_color_set() for more details.
  */
 EAPI void                 evas_object_text_glow2_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the outline color for the given text object.
+ * @brief   Sets the outline color for the given text object.
  *
- * @param obj The given Evas text object.
- * @param r The red component of the given color.
- * @param g The green component of the given color.
- * @param b The blue component of the given color.
- * @param a The alpha component of the given color.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Outline effects (colored lines around text glyphs) will just be
- * shown if the object is set to one of the following styles:
- * - #EVAS_TEXT_STYLE_OUTLINE
- * - #EVAS_TEXT_STYLE_SOFT_OUTLINE
- * - #EVAS_TEXT_STYLE_OUTLINE_SHADOW
- * - #EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW
+ * @remarks Outline effects (colored lines around text glyphs) are just
+ *          shown if the object is set to one of the following styles:
+ *          - #EVAS_TEXT_STYLE_OUTLINE
+ *          - #EVAS_TEXT_STYLE_SOFT_OUTLINE
+ *          - #EVAS_TEXT_STYLE_OUTLINE_SHADOW
+ *          - #EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW
+ *
+ * @param[in]   obj  The given Evas text object
+ * @param[in]   r    The red component of the given color
+ * @param[in]   g    The green component of the given color
+ * @param[in]   b    The blue component of the given color
+ * @param[in]   a    The alpha component of the given color
  *
  * @see evas_object_text_outline_color_get()
  */
 EAPI void                 evas_object_text_outline_color_set(Evas_Object *obj, int r, int g, int b, int a) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the outline color for the given text object.
+ * @brief   Gets the outline color for the given text object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given Evas text object.
- * @param r Pointer to variable to hold the red component of the given
- * color.
- * @param g Pointer to variable to hold the green component of the
- * given color.
- * @param b Pointer to variable to hold the blue component of the
- * given color.
- * @param a Pointer to variable to hold the alpha component of the
- * given color.
+ * @remarks Use @c NULL pointers on the color components that you are not
+ *          interested in: they are ignored by the function.
  *
- * @note Use @c NULL pointers on the color components you're not
- * interested in: they'll be ignored by the function.
+ * @param[in]   obj  The given Evas text object
+ * @param[out]   r    The pointer to the variable to hold the red component of the given color
+ * @param[out]   g    The pointer to the variable to hold the green component of the given color
+ * @param[out]   b    The pointer to the variable to hold the blue component of the given color
+ * @param[out]   a    The pointer to the variable to hold the alpha component of the given color
  *
  * @see evas_object_text_outline_color_set() for more details.
  */
 EAPI void                 evas_object_text_outline_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a) EINA_ARG_NONNULL(1);
 
 /**
- * Gets the text style pad of a text object.
+ * @brief  Gets the text style pad of a text object.
  *
- * @param obj The given text object.
- * @param l The left pad (or @c NULL).
- * @param r The right pad (or @c NULL).
- * @param t The top pad (or @c NULL).
- * @param b The bottom pad (or @c NULL).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  obj  The given text object
+ * @param[out]  l    The left pad (or @c NULL)
+ * @param[out]  r    The right pad (or @c NULL)
+ * @param[out]  t    The top pad (or @c NULL)
+ * @param[out]  b    The bottom pad (or @c NULL)
  *
  */
 EAPI void                 evas_object_text_style_pad_get(const Evas_Object *obj, int *l, int *r, int *t, int *b) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the direction of the text currently being displayed in the
- * text object.
- * @param  obj The given evas text object.
- * @return the direction of the text
+ * @brief   Gets the direction of the text currently being displayed in the text object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given evas text object
+ * @return  The direction of the text
  */
 EAPI Evas_BiDi_Direction  evas_object_text_direction_get(const Evas_Object *obj) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
 
 /**
+ * @brief      Sets an Evas filter program on this Text Object.
+ * @since      1.9. Backported for Tizen (1.7.99).
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks    If the program fails to compile (syntax error, invalid buffer name, etc...),
+ *             the standard text effects are applied instead (SHADOW, etc...).
+ *
+ * @remarks    EXPERIMENTAL FEATURE. This is an unstable API, please use this only for testing purposes.
+ *
+ * @param[in]  obj  The given evas text object
+ * @param[in]  arg  The program code, as defined by the "Evas filters script language".
+ *                  Pass @c NULL to remove the former program and
+ *                  switch back to the standard text effects.
+ *
+ * @internal
+ * @see @ref evasfiltersref "Evas filters reference"
+ * @endinternal
+ */
+EAPI void                 evas_object_text_filter_program_set(Evas_Object *obj, const char *arg);
+
+/**
+ * @brief      Binds an object to use as a mask or texture with Evas Filters. This
+ *             automatically creates a new RGBA buffer containing the source object's
+ *             pixels (as it is rendered).
+ * @since      1.9. Backported for Tizen (1.7.99).
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks    EXPERIMENTAL FEATURE. This is an unstable API, please use this only for testing purposes.
+ *
+ * @param[in]  obj  The given evas object
+ * @param[in]  name   The object name as used in the program code
+ * @param[in]  source The evas object to use through proxy rendering
+ *
+ * @see evas_obj_text_filter_program_set
+ * @internal
+ * @see @ref evasfiltersref "Evas filters reference"
+ * @endinternal
+ */
+EAPI void                 evas_object_text_filter_source_set(Evas_Object *obj, const char *name, Evas_Object *source);
+
+// TIZEN_ONLY(20150513): Add evas_object_text/textblock_ellipsis_status_get internal API.
+/**
+ * @internal
+ */
+EAPI Eina_Bool            evas_object_text_ellipsis_status_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+//
+
+
+/**
  * @}
  */
 
 /**
  * @defgroup Evas_Object_Textblock Textblock Object Functions
+ * @ingroup Evas_Object_Specific
+ *
+ * @brief  This group provides functions used to create and manipulate textblock objects. 
  *
- * Functions used to create and manipulate textblock objects. Unlike
- * @ref Evas_Object_Text, these handle complex text, doing multiple
+ * Unlike @ref Evas_Object_Text, these handle complex text, doing multiple
  * styles and multiline text based on HTML-like tags. Of these extra
- * features will be heavier on memory and processing cost.
+ * features are heavier on memory and processing cost.
  *
  * @section Evas_Object_Textblock_Tutorial Textblock Object Tutorial
  *
  * This part explains about the textblock object's API and proper usage.
- * The main user of the textblock object is the edje entry object in Edje, so
- * that's a good place to learn from, but I think this document is more than
- * enough, if it's not, please contact me and I'll update it.
+ * The main user of the textblock object is the edje entry object in Edje. So
+ * that is a good place to learn from, but this document is more than
+ * enough. If it is not, please contact the developer to update it.
  *
  * @subsection textblock_intro Introduction
- * The textblock objects is, as implied, an object that can show big chunks of
+ * The textblock object is, as implied, an object that can show big chunks of
  * text. Textblock supports many features including: Text formatting, automatic
  * and manual text alignment, embedding items (for example icons) and more.
- * Textblock has three important parts, the text paragraphs, the format nodes
+ * Textblock has three important parts: the text paragraphs, the format nodes,
  * and the cursors.
  *
  * You can use markup to format text, for example: "<font_size=50>Big!</font_size>".
  * You can also put more than one style directive in one tag:
  * "<font_size=50 color=#F00>Big and Red!</font_size>".
  * Please notice that we used "</font_size>" although the format also included
- * color, this is because the first format determines the matching closing tag's
+ * color. This is because the first format determines the matching closing tag's
  * name. You can also use anonymous tags, like: "<font_size=30>Big</>" which
- * just pop any type of format, but it's advised to use the named alternatives
+ * just pop any type of format, but it is advised to use the named alternatives
  * instead.
  *
  * @subsection textblock_cursors Textblock Object Cursors
- * A textblock Cursor is data type that represents
+ * A textblock cursor is the data type that represents
  * a position in a textblock. Each cursor contains information about the
- * paragraph it points to, the position in that paragraph and the object itself.
- * Cursors register to textblock objects upon creation, this means that once
- * you created a cursor, it belongs to a specific obj and you can't for example
+ * paragraph it points to, the position in that paragraph, and the object itself.
+ * Cursors register to textblock objects upon creation. This means that once
+ * you created a cursor, it belongs to a specific object and you cannot, for example,
  * copy a cursor "into" a cursor of a different object. Registered cursors
  * also have the added benefit of updating automatically upon textblock changes,
- * this means that if you have a cursor pointing to a specific character, it'll
- * still point to it even after you change the whole object completely (as long
- * as the char was not deleted), this is not possible without updating, because
+ * this means that if you have a cursor pointing to a specific character, it
+ * still points to it even after you change the whole object completely (as long
+ * as the char is not deleted). This is not possible without updating, because
  * as mentioned, each cursor holds a character position. There are many
- * functions that handle cursors, just check out the evas_textblock_cursor*
- * functions. For creation and deletion of cursors check out:
+ * functions that handle cursors. See the evas_textblock_cursor*
+ * functions. For creation and deletion of cursors, see:
  * @see evas_object_textblock_cursor_new()
  * @see evas_textblock_cursor_free()
- * @note Cursors are generally the correct way to handle text in the textblock object, and there are enough functions to do everything you need with them (no need to get big chunks of text and processing them yourself).
+ * @remarks Cursors are generally the correct way to handle text in the textblock object, 
+ *          and there are enough functions to do everything you need with them 
+ *          (no need to get big chunks of text and processing them yourself).
  *
  * @subsection textblock_paragraphs Textblock Object Paragraphs
- * The textblock object is made out of text splitted to paragraphs (delimited
+ * The textblock object is made out of text split to paragraphs (delimited
  * by the paragraph separation character). Each paragraph has many (or none)
  * format nodes associated with it which are responsible for the formatting
  * of that paragraph.
@@ -8195,54 +9638,53 @@ EAPI Evas_BiDi_Direction  evas_object_text_direction_get(const Evas_Object *obj)
  * @subsection textblock_format_nodes Textblock Object Format Nodes
  * As explained in @ref textblock_paragraphs each one of the format nodes
  * is associated with a paragraph.
- * There are two types of format nodes, visible and invisible:
- * Visible: formats that a cursor can point to, i.e formats that
- * occupy space, for example: newlines, tabs, items and etc. Some visible items
- * are made of two parts, in this case, only the opening tag is visible.
+ * There are two types of format nodes: visible and invisible.
+ * Visible: Formats that a cursor can point to, that is, the formats that
+ * occupy space. For example: newlines, tabs, items and so on. Some visible items
+ * are made of two parts. In this case, only the opening tag is visible.
  * A closing tag (i.e a \</tag\> tag) should NEVER be visible.
- * Invisible: formats that don't occupy space, for example: bold and underline.
+ * Invisible: Formats that do not occupy space. For example: bold and underline.
  * Being able to access format nodes is very important for some uses. For
  * example, edje uses the "<a>" format to create links in the text (and pop
  * popups above them when clicked). For the textblock object a is just a
  * formatting instruction (how to color the text), but edje utilizes the access
  * to the format nodes to make it do more.
- * For more information, take a look at all the evas_textblock_node_format_*
- * functions.
+ * For more information, see all the evas_textblock_node_format_* functions.
  * The translation of "<tag>" tags to actual format is done according to the
  * tags defined in the style, see @ref evas_textblock_style_set
  *
  * @subsection textblock_special_formats Special Formats
  * Textblock supports various format directives that can be used in markup. In
  * addition to the mentioned format directives, textblock allows creating
- * additional format directives using "tags" that can be set in the style see
+ * additional format directives using "tags" that can be set in the style. See
  * @ref evas_textblock_style_set .
  *
  * Textblock supports the following formats:
- * @li font - Font description in fontconfig like format, e.g: "Sans:style=Italic:lang=hi". or "Serif:style=Bold".
- * @li font_weight - Overrides the weight defined in "font". E.g: "font_weight=Bold" is the same as "font=:style=Bold". Supported weights: "normal", "thin", "ultralight", "light", "book", "medium", "semibold", "bold", "ultrabold", "black", and "extrablack".
- * @li font_style - Overrides the style defined in "font". E.g: "font_style=Italic" is the same as "font=:style=Italic". Supported styles: "normal", "oblique", and "italic".
+ * @li font - Font description in fontconfig like format. Example: "Sans:style=Italic:lang=hi". or "Serif:style=Bold".
+ * @li font_weight - Overrides the weight defined in "font". Example: "font_weight=Bold" is the same as "font=:style=Bold". Supported weights: "normal", "thin", "ultralight", "light", "book", "medium", "semibold", "bold", "ultrabold", "black", and "extrablack".
+ * @li font_style - Overrides the style defined in "font". Example: "font_style=Italic" is the same as "font=:style=Italic". Supported styles: "normal", "oblique", and "italic".
  * @li font_width - Overrides the width defined in "font". E.g: "font_width=Condensed" is the same as "font=:style=Condensed". Supported widths: "normal", "ultracondensed", "extracondensed", "condensed", "semicondensed", "semiexpanded", "expanded", "extraexpanded", and "ultraexpanded".
- * @li lang - Overrides the language defined in "font". E.g: "lang=he" is the same as "font=:lang=he".
+ * @li lang - Overrides the language defined in "font". Example: "lang=he" is the same as "font=:lang=he".
  * @li font_fallbacks - A comma delimited list of fonts to try if finding the main font fails.
  * @li font_size - The font size in points.
- * @li font_source - The source of the font, e.g an eet file.
+ * @li font_source - The source of the font. Example: An eet file.
  * @li color - Text color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
- * @li underline_color - color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
- * @li underline2_color - color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
- * @li outline_color - color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
- * @li shadow_color - color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
- * @li glow_color - color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
- * @li glow2_color - color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
- * @li backing_color - color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
- * @li strikethrough_color - color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
- * @li align - Either "auto" (meaning according to text direction), "left", "right", "center", "middle", a value between 0.0 and 1.0, or a value between 0% to 100%.
- * @li valign - Either "top", "bottom", "middle", "center", "baseline", "base", a value between 0.0 and 1.0, or a value between 0% to 100%.
+ * @li underline_color - Color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
+ * @li underline2_color - Color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
+ * @li outline_color - Color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
+ * @li shadow_color - Color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
+ * @li glow_color - Color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
+ * @li glow2_color - Color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
+ * @li strikethrough_color - Color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
+ * @li align - Either "auto" (meaning according to text direction), "left", "right", "center", "middle", a value between @c 0.0 and @c 1.0, or a value between 0% to 100%.
+ * @li valign - Either "top", "bottom", "middle", "center", "baseline", "base", a value between @c 0.0 and @c 1.0, or a value between 0% to 100%.
  * @li wrap - "word", "char", "mixed", or "none".
  * @li left_margin - Either "reset", or a pixel value indicating the margin.
  * @li right_margin - Either "reset", or a pixel value indicating the margin.
  * @li underline - "on", "off", "single", or "double".
  * @li strikethrough - "on" or "off"
- * @li backing - "on" or "off"
+ * @li backing_color - Background color in one of the following formats: "#RRGGBB", "#RRGGBBAA", "#RGB", and "#RGBA".
+ * @li backing - Enable or disable background color. Example: "on" or "off"
  * @li style - Either "off", "none", "plain", "shadow", "outline", "soft_outline", "outline_shadow", "outline_soft_shadow", "glow", "far_shadow", "soft_shadow", or "far_soft_shadow".
  * @li tabstops - Pixel value for tab width.
  * @li linesize - Force a line size in pixels.
@@ -8251,25 +9693,22 @@ EAPI Evas_BiDi_Direction  evas_object_text_direction_get(const Evas_Object *obj)
  * @li linerelgap - Either a floating point value or a percentage indicating the wanted size of the line relative to the calculated size.
  * @li item - Creates an empty space that should be filled by an upper layer. Use "size", "abssize", or "relsize". To define the items size, and an optional: vsize=full/ascent to define the item's position in the line.
  * @li linefill - Either a float value or percentage indicating how much to fill the line.
- * @li ellipsis - Value between 0.0-1.0 to indicate the type of ellipsis, or -1.0 to indicate ellipsis isn't wanted.
+ * @li ellipsis - Value between @c 0.0-@c 1.0 to indicate the type of ellipsis, or @c -1.0 to indicate that ellipsis is not wanted.
  * @li password - "on" or "off". This is used to specifically turn replacing chars with the replacement char (i.e password mode) on and off.
  *
- * @warning We don't guarantee any proper results if you create a Textblock
- * object
- * without setting the evas engine.
+ * @remarks There is no guarantee of any proper results if you create a Textblock
+ *          object without setting the evas engine.
  *
  * @todo put here some usage examples
  *
- * @ingroup Evas_Object_Specific
- *
  * @{
  */
 
-typedef struct _Evas_Textblock_Style              Evas_Textblock_Style;
-typedef struct _Evas_Textblock_Cursor             Evas_Textblock_Cursor;
+typedef struct _Evas_Textblock_Style              Evas_Textblock_Style;    /**< @brief handle for Evas Textblock Style */
+typedef struct _Evas_Textblock_Cursor             Evas_Textblock_Cursor;   /**< @brief handle for Evas Textblock Cursor */
 /**
  * @typedef Evas_Object_Textblock_Node_Format
- * A format node.
+ * @brief The structure type containing a format node.
  */
 typedef struct _Evas_Object_Textblock_Node_Format Evas_Object_Textblock_Node_Format;
 typedef struct _Evas_Textblock_Rectangle          Evas_Textblock_Rectangle;
@@ -8293,894 +9732,1398 @@ typedef enum _Evas_Textblock_Cursor_Type
 } Evas_Textblock_Cursor_Type;
 
 /**
- * Adds a textblock to the given evas.
- * @param   e The given evas.
- * @return  The new textblock object.
+ * @brief  Adds a textblock to the given evas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  e  The given evas
+ * @return The new textblock object
  */
 EAPI Evas_Object                             *evas_object_textblock_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Returns the unescaped version of escape.
- * @param escape the string to be escaped
- * @return the unescaped version of escape
+ * @brief   Gets the unescaped version of escape.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   escape  The string to be escaped
+ * @return  The unescaped version of escape
  */
 EAPI const char                              *evas_textblock_escape_string_get(const char *escape) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Returns the escaped version of the string.
- * @param string to escape
- * @param len_ret the len of the part of the string that was used.
- * @return the escaped string.
+ * @brief   Gets the escaped version of the string.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   string   The string to escape
+ * @param[out]   len_ret  The len of the part of the string that is used
+ * @return  The escaped string
  */
 EAPI const char                              *evas_textblock_string_escape_get(const char *string, int *len_ret) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Return the unescaped version of the string between start and end.
+ * @brief   Gets the unescaped version of the string between start and end.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param escape_start the start of the string.
- * @param escape_end the end of the string.
- * @return the unescaped version of the range
+ * @param[in]   escape_start  The start of the string
+ * @param[in]   escape_end    The end of the string
+ * @return  The unescaped version of the range
  */
 EAPI const char                              *evas_textblock_escape_string_range_get(const char *escape_start, const char *escape_end) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
 
 /**
- * Return the plain version of the markup.
+ * @brief   Gets the plain version of the markup.
  *
- * Works as if you set the markup to a textblock and then retrieve the plain
- * version of the text. i.e: <br> and <\n> will be replaced with \n, &...; with
- * the actual char and etc.
+ * @details This function works as if you set the markup to a textblock and then retrieve the plain
+ *          version of the text. That is: <br> and <\n> is replaced with \n, &...; with
+ *          the actual char and so on.
  *
- * @param obj The textblock object to work with. (if @c NULL, tries the
- * default).
- * @param text The markup text (if @c NULL, return @c NULL).
- * @return An allocated plain text version of the markup.
- * @since 1.2
+ * @since   1.2
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj   The textblock object to work with \n
+ *                If @c NULL, it tries the default.
+ * @param[in]   text  The markup text \n
+ *                If @c NULL, it returns @c NULL.
+ * @return  An allocated plain text version of the markup
  */
 EAPI char                                    *evas_textblock_text_markup_to_utf8(const Evas_Object *obj, const char *text) EINA_WARN_UNUSED_RESULT EINA_MALLOC;
 
 /**
- * Return the markup version of the plain text.
+ * @brief   Gets the markup version of the plain text.
  *
- * Replaces \\n -\> \<br/\> \\t -\> \<tab/\> and etc. Generally needed before you pass
- * plain text to be set in a textblock.
+ * @details This function replaces \\n -\> \<br/\> \\t -\> \<tab/\> and so on. 
+ *          This is generally needed before you pass plain text to be set in a textblock.
+ * @since   1.2
  *
- * @param obj the textblock object to work with (if @c NULL, it just does the
- * default behaviour, i.e with no extra object information).
- * @param text The markup text (if @c NULL, return @c NULL).
- * @return An allocated plain text version of the markup.
- * @since 1.2
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj   The textblock object to work with \n
+ *                If @c NULL, it just does the default behaviour, i.e with no extra object information.
+ * @param[in]   text  The markup text \n
+ *                If @c NULL, it returns @c NULL.
+ * @return  An allocated plain text version of the markup
  */
 EAPI char                                    *evas_textblock_text_utf8_to_markup(const Evas_Object *obj, const char *text) EINA_WARN_UNUSED_RESULT EINA_MALLOC;
 
 /**
- * Creates a new textblock style.
- * @return  The new textblock style.
+ * @brief   Creates a new textblock style.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @return  The new textblock style
  */
 EAPI Evas_Textblock_Style                    *evas_textblock_style_new(void) EINA_WARN_UNUSED_RESULT EINA_MALLOC;
 
 /**
- * Destroys a textblock style.
- * @param ts The textblock style to free.
+ * @brief   Destroys a textblock style.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   ts  The textblock style to free
  */
 EAPI void                                     evas_textblock_style_free(Evas_Textblock_Style *ts) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the style ts to the style passed as text by text.
- * Expected a string consisting of many (or none) tag='format' pairs.
+ * @brief   Sets the style @a ts to the style passed as text by text.
+ * @details This function expects a string consisting of many (or none) tag='format' pairs.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param ts  the style to set.
- * @param text the text to parse - NOT NULL.
- * @return Returns no value.
+ * @param[in]   ts    The style to set
+ * @param[in]   text  The text to parse \n
+ *                This should be NOT NULL.
  */
 EAPI void                                     evas_textblock_style_set(Evas_Textblock_Style *ts, const char *text) EINA_ARG_NONNULL(1);
 
 /**
- * Return the text of the style ts.
- * @param ts  the style to get it's text.
- * @return the text of the style or null on error.
+ * @brief   Gets the text of the style @a ts.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   ts  The style to get the text
+ * @return  The text of the style, \n
+ *          otherwise @c NULL on error
  */
 EAPI const char                              *evas_textblock_style_get(const Evas_Textblock_Style *ts) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set the objects style to ts.
- * @param obj the Evas object to set the style to.
- * @param ts  the style to set.
- * @return Returns no value.
- */
+ * @brief  Sets the object style to @a ts.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  obj  The Evas object to set the style to
+ * @param[in]  ts   The style to set
+  */
 EAPI void                                     evas_object_textblock_style_set(Evas_Object *obj, Evas_Textblock_Style *ts) EINA_ARG_NONNULL(1);
 
 /**
- * Return the style of an object.
- * @param obj  the object to get the style from.
- * @return the style of the object.
+ * @brief   Gets the style of an object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The object to get the style from
+ * @return  The style of the object
  */
 EAPI const Evas_Textblock_Style              *evas_object_textblock_style_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Push ts to the top of the user style stack.
+ * @brief   Pushes @a ts to the top of the user style stack.
  *
  * FIXME: API is solid but currently only supports 1 style in the stack.
  *
- * The user style overrides the corresponding elements of the regular style.
- * This is the proper way to do theme overrides in code.
- * @param obj the Evas object to set the style to.
- * @param ts  the style to set.
- * @return Returns no value.
+ * @since   1.2
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks The user style overrides the corresponding elements of the regular style.
+ *          This is the proper way to do theme overrides in code.
+ * @param[in]   obj  The Evas object to set the style to
+ * @param[in]   ts   The style to set
  * @see evas_object_textblock_style_set
- * @since 1.2
  */
 EAPI void                                     evas_object_textblock_style_user_push(Evas_Object *obj, Evas_Textblock_Style *ts) EINA_ARG_NONNULL(1);
 
 /**
- * Del the from the top of the user style stack.
+ * @brief   Deletes the style from the top of the user style stack.
+ * @since   1.2
  *
- * @param obj  the object to get the style from.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The object to get the style from
  * @see evas_object_textblock_style_get
- * @since 1.2
  */
 EAPI void                                     evas_object_textblock_style_user_pop(Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Get (don't remove) the style at the top of the user style stack.
+ * @brief   Gets (does not remove) the style at the top of the user style stack.
+ * @since   1.2
  *
- * @param obj  the object to get the style from.
- * @return the style of the object.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The object to get the style from
+ * @return  The style of the object
  * @see evas_object_textblock_style_get
- * @since 1.2
  */
 EAPI const Evas_Textblock_Style              *evas_object_textblock_style_user_peek(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * @brief Set the "replacement character" to use for the given textblock object.
+ * @brief   Sets the "replacement character" to use for the given textblock object.
  *
- * @param obj The given textblock object.
- * @param ch The charset name.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given textblock object
+ * @param[in]   ch   The charset name
  */
 EAPI void                                     evas_object_textblock_replace_char_set(Evas_Object *obj, const char *ch) EINA_ARG_NONNULL(1);
 
 /**
- * @brief Get the "replacement character" for given textblock object. Returns
- * @c NULL if no replacement character is in use.
+ * @brief   Gets the "replacement character" for given textblock object. 
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given textblock object
- * @return Replacement character or @c NULL.
+ * @param[in]   obj  The given textblock object
+ * @return  The replacement character, \n
+ *          otherwise @c NULL if no replacement character is in use
  */
 EAPI const char                              *evas_object_textblock_replace_char_get(Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * @brief Sets the vertical alignment of text within the textblock object
- * as a whole.
+ * @brief   Sets the vertical alignment of text within the textblock object as a whole.
+ * @since   1.1
  *
- * Normally alignment is 0.0 (top of object). Values given should be
- * between 0.0 and 1.0 (1.0 bottom of object, 0.5 being vertically centered
- * etc.).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given textblock object.
- * @param align A value between @c 0.0 and @c 1.0.
- * @since 1.1
+ * @remarks Normally alignment is @c 0.0 (top of object). Values given should be
+ *          between @c 0.0 and @c 1.0 , where @c 1.0 is bottom of object, @c 0.5 is 
+ *          vertically centered, and so on.
+ *
+ * @param[in]   obj    The given textblock object
+ * @param[in]   align  A value between @c 0.0 and @c 1.0
  */
 EAPI void                                     evas_object_textblock_valign_set(Evas_Object *obj, double align);
 
 /**
- * @brief Gets the vertical alignment of a textblock
+ * @brief   Gets the vertical alignment of a textblock.
+ * @since   1.1
  *
- * @param obj The given textblock object.
- * @return The alignment set for the object.
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The given textblock object
+ * @return  The alignment set for the object
  */
 EAPI double                                   evas_object_textblock_valign_get(const Evas_Object *obj);
 
 /**
- * @brief Sets the BiDi delimiters used in the textblock.
+ * @brief   Sets the BiDi delimiters used in the textblock.
+ * @since   1.1
  *
- * BiDi delimiters are use for in-paragraph separation of bidi segments. This
- * is useful for example in recipients fields of e-mail clients where bidi
- * oddities can occur when mixing RTL and LTR.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The given textblock object.
- * @param delim A null terminated string of delimiters, e.g ",|".
- * @since 1.1
+ * @remarks BiDi delimiters are uses for in-paragraph separation of bidi segments. This
+ *          is useful, for example, in recipients fields of e-mail clients where bidi
+ *          oddities can occur when mixing RTL and LTR.
+ *
+ * @param[in]   obj    The given textblock object
+ * @param[in]   delim  A null terminated string of delimiters, for example ",|"
  */
 EAPI void                                     evas_object_textblock_bidi_delimiters_set(Evas_Object *obj, const char *delim);
 
 /**
- * @brief Gets the BiDi delimiters used in the textblock.
+ * @brief   Gets the BiDi delimiters used in the textblock.
  *
- * BiDi delimiters are use for in-paragraph separation of bidi segments. This
- * is useful for example in recipients fields of e-mail clients where bidi
- * oddities can occur when mixing RTL and LTR.
+ * @since   1.1
  *
- * @param obj The given textblock object.
- * @return A null terminated string of delimiters, e.g ",|". If empty, returns
- * @c NULL.
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks BiDi delimiters are used for in-paragraph separation of bidi segments. This
+ *          is useful, for example, in recipients fields of e-mail clients where bidi
+ *          oddities can occur when mixing RTL and LTR.
+ * 
+ * @param[in]   obj  The given textblock object
+ * @return  A null terminated string of delimiters, for example ",|", \n 
+ *          otherwise @c NULL if it is empty
  */
 EAPI const char                              *evas_object_textblock_bidi_delimiters_get(const Evas_Object *obj);
 
 /**
- * @brief Sets newline mode. When true, newline character will behave
- * as a paragraph separator.
+ * @brief   Sets the newline mode. 
+ * @since   1.1
  *
- * @param obj The given textblock object.
- * @param mode @c EINA_TRUE for legacy mode, @c EINA_FALSE otherwise.
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks When @c true, newline character behaves as a paragraph separator.
+ *
+ * @param[in]   obj   The given textblock object
+ * @param[in]   mode  Set #EINA_TRUE for legacy mode, \n
+ *                otherwise set #EINA_FALSE
  */
 EAPI void                                     evas_object_textblock_legacy_newline_set(Evas_Object *obj, Eina_Bool mode) EINA_ARG_NONNULL(1);
 
 /**
- * @brief Gets newline mode. When true, newline character behaves
- * as a paragraph separator.
+ * @brief   Gets the newline mode. 
+ * @since   1.1
  *
- * @param obj The given textblock object.
- * @return @c EINA_TRUE if in legacy mode, @c EINA_FALSE otherwise.
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks When true, newline character behaves as a paragraph separator.
+ *
+ * @param[in]   obj  The given textblock object
+ * @return  #EINA_TRUE if it is in legacy mode, \n
+ *          otherwise #EINA_FALSE
+
  */
 EAPI Eina_Bool                                evas_object_textblock_legacy_newline_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Sets the tetxblock's text to the markup text.
+ * @brief   Sets the textblock's text to the markup text.
  *
- * @note assumes text does not include the unicode object replacement char (0xFFFC)
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj  the textblock object.
- * @param text the markup text to use.
- * @return Return no value.
+ * @remarks This assumes that the text does not include the unicode object replacement char (0xFFFC).
+ *
+ * @param[in]   obj   The textblock object
+ * @param[in]   text  The markup text to use
  */
 EAPI void                                     evas_object_textblock_text_markup_set(Evas_Object *obj, const char *text) EINA_ARG_NONNULL(1);
 
 /**
- * Prepends markup to the cursor cur.
+ * @brief   Prepends markup to the cursor @a cur.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note assumes text does not include the unicode object replacement char (0xFFFC)
+ * @remarks This assumes that the text does not include the unicode object replacement char (0xFFFC).
  *
- * @param cur  the cursor to prepend to.
- * @param text the markup text to prepend.
- * @return Return no value.
+ * @param[in]   cur   The cursor to prepend to
+ * @param[in]   text  The markup text to prepend
  */
 EAPI void                                     evas_object_textblock_text_markup_prepend(Evas_Textblock_Cursor *cur, const char *text) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Return the markup of the object.
+ * @brief   Gets the markup of the object.
  *
- * @param obj the Evas object.
- * @return the markup text of the object.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The Evas object
+ * @return  The markup text of the object
  */
 EAPI const char                              *evas_object_textblock_text_markup_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Return the object's main cursor.
+ * @brief   Gets the object's main cursor.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj the object.
- * @return The @p obj's main cursor.
+ * @param[in]   obj  The object
+ * @return  @a obj's main cursor
  */
 EAPI Evas_Textblock_Cursor                   *evas_object_textblock_cursor_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Create a new cursor, associate it to the obj and init it to point
- * to the start of the textblock. Association to the object means the cursor
- * will be updated when the object will change.
+ * @brief   Creates a new cursor, associates it to the obj and inits it to point
+ *          to the start of the textblock. 
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks Association to the object means the cursor is updated when the object changes.
  *
- * @note if you need speed and you know what you are doing, it's slightly faster to just allocate the cursor yourself and not associate it. (only people developing the actual object, and not users of the object).
+ * @remarks If you need speed and you know what you are doing, it is slightly faster to 
+ *          just allocate the cursor yourself and not associate it. 
  *
- * @param obj the object to associate to.
- * @return the new cursor.
+ * @param[in]   obj  The object to associate to
+ * @return  The new cursor
  */
 EAPI Evas_Textblock_Cursor                   *evas_object_textblock_cursor_new(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Free the cursor and unassociate it from the object.
- * @note do not use it to free unassociated cursors.
+ * @brief   Frees the cursor and unassociates it from the object.
  *
- * @param cur the cursor to free.
- * @return Returns no value.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks Do not use it to free the unassociated cursors.
+ *
+ * @param[in]   cur  The cursor to free
  */
 EAPI void                                     evas_textblock_cursor_free(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the cursor to the start of the first text node.
+ * @brief  Sets the cursor to the start of the first text node.
  *
- * @param cur the cursor to update.
- * @return Returns no value.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  cur  The cursor to update
  */
 EAPI void                                     evas_textblock_cursor_paragraph_first(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * sets the cursor to the end of the last text node.
+ * @brief  Sets the cursor to the end of the last text node.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the cursor to set.
- * @return Returns no value.
+ * @param[in]  cur  The cursor to set
  */
 EAPI void                                     evas_textblock_cursor_paragraph_last(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Advances to the start of the next text node
+ * @brief   Advances to the start of the next text node.
  *
- * @param cur the cursor to update
- * @return @c EINA_TRUE if it managed to advance a paragraph, @c EINA_FALSE
- * otherwise.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur  The cursor to update
+ * @return  #EINA_TRUE if the cursor advances a paragraph, \n
+ *          otherwise #EINA_FALSE
  */
 EAPI Eina_Bool                                evas_textblock_cursor_paragraph_next(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Advances to the end of the previous text node
+ * @brief   Goes to the end of the previous text node.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the cursor to update
- * @return @c EINA_TRUE if it managed to advance a paragraph, @c EINA_FALSE
- * otherwise.
+ * @param[in]   cur  The cursor to update
+ * @return  #EINA_TRUE if the cursor goes to the end of the previous paragraph, \n
+ *          otherwise #EINA_FALSE
  */
 EAPI Eina_Bool                                evas_textblock_cursor_paragraph_prev(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Returns the
+ * @brief   Gets the the list format node corresponding to @a anchor.
  *
- * @param obj The evas, must not be @c NULL.
- * @param anchor the anchor name to get
- * @return Returns the list format node corresponding to the anchor, may be null if there are none.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj     The evas object \n
+ *                  This must not be @c NULL.
+ * @param[in]   anchor  The anchor name to get
+ * @return  The list format node corresponding to the anchor, \n
+ *          otherwise @c NULL if there is no list format node
  */
 EAPI const Eina_List                         *evas_textblock_node_format_list_get(const Evas_Object *obj, const char *anchor) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Returns the first format node.
+ * @brief   Gets the first format node.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The evas, must not be @c NULL.
- * @return Returns the first format node, may be null if there are none.
+ * @param[in]   obj  The evas object \n
+ *               This must not be @c NULL.
+ * @return  The first format node, \n
+ *          otherwise @c NULL if there is no first format node
  */
 EAPI const Evas_Object_Textblock_Node_Format *evas_textblock_node_format_first_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Returns the last format node.
+ * @brief   Gets the last format node.
  *
- * @param obj The evas textblock, must not be NULL.
- * @return Returns the first format node, may be null if there are none.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The evas textblock \n 
+ *               This must not be @c NULL.
+ * @return  The last format node, \n
+ *          otherwise @c NULL if there is no last format node
  */
 EAPI const Evas_Object_Textblock_Node_Format *evas_textblock_node_format_last_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Returns the next format node (after n)
+ * @brief   Gets the next format node (after n).
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param n the current format node - not null.
- * @return Returns the next format node, may be null.
+ * @param[in]   n  The current format node \n
+ *             This must not be @c NULL.
+ * @return  The next format node, \n
+ *          otherwise @c NULL if there is no next format node
  */
 EAPI const Evas_Object_Textblock_Node_Format *evas_textblock_node_format_next_get(const Evas_Object_Textblock_Node_Format *n) EINA_ARG_NONNULL(1);
 
 /**
- * Returns the prev format node (after n)
+ * @brief   Gets the previous format node (after n).
  *
- * @param n the current format node - not null.
- * @return Returns the prev format node, may be null.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   n  The current format node \n 
+ *             This is must not be @c NULL.
+ * @return  The previous format node, \n
+ *          otherwise @c NULL if there is no previous format node
  */
 EAPI const Evas_Object_Textblock_Node_Format *evas_textblock_node_format_prev_get(const Evas_Object_Textblock_Node_Format *n) EINA_ARG_NONNULL(1);
 
 /**
- * Remove a format node and it's match. i.e, removes a \<tag\> \</tag\> pair.
- * Assumes the node is the first part of \<tag\> i.e, this won't work if
- * n is a closing tag.
+ * @brief   Removes a format node and its match. \n
+ *          That is it removes a \<tag\> \</tag\> pair.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj the Evas object of the textblock - not null.
- * @param n the current format node - not null.
+ * @remarks Assumes that the node is the first part of \<tag\>. 
+ *          This does not work if @a n is a closing tag.
+ *
+ * @param[in]   obj  The Evas object of the textblock \n 
+ *               This must not be @c NULL.
+ * @param[in]   n    The current format node \n
+ *               This must not be @c NULL.
  */
 EAPI void                                     evas_textblock_node_format_remove_pair(Evas_Object *obj, Evas_Object_Textblock_Node_Format *n) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Sets the cursor to point to the place where format points to.
+ * @brief   Sets the cursor to point to the place where format points to.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the cursor to update.
- * @param n the format node to update according.
- * @deprecated duplicate of evas_textblock_cursor_at_format_set
+ * @param[in]   cur  The cursor to update
+ * @param[in]   n    The format node to update according
+ * @deprecated  Duplicate of evas_textblock_cursor_at_format_set
  */
 EAPI void                                     evas_textblock_cursor_set_at_format(Evas_Textblock_Cursor *cur, const Evas_Object_Textblock_Node_Format *n) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Return the format node at the position pointed by cur.
+ * @brief   Gets the format node at the position pointed by @a cur.
  *
- * @param cur the position to look at.
- * @return the format node if found, @c NULL otherwise.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur  The position to look at
+ * @return  The format node, \n
+ *          otherwise @c NULL if it is not found
  * @see evas_textblock_cursor_format_is_visible_get()
  */
 EAPI const Evas_Object_Textblock_Node_Format *evas_textblock_cursor_format_get(const Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Get the text format representation of the format node.
+ * @brief   Gets the text format representation of the format node.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param fnode the format node.
- * @return the textual format of the format node.
+ * @param[in]   fnode  The format node
+ * @return  The textual format of the format node
  */
 EAPI const char                              *evas_textblock_node_format_text_get(const Evas_Object_Textblock_Node_Format *fnode) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set the cursor to point to the position of fmt.
+ * @brief   Sets the cursor to point to the position of @a fmt.
  *
- * @param cur the cursor to update
- * @param fmt the format to update according to.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur  The cursor to update
+ * @param[in]   fmt  The format to update according to
  */
 EAPI void                                     evas_textblock_cursor_at_format_set(Evas_Textblock_Cursor *cur, const Evas_Object_Textblock_Node_Format *fmt) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Check if the current cursor position is a visible format. This way is more
- * efficient than evas_textblock_cursor_format_get() to check for the existence
- * of a visible format.
+ * @brief   Checks whether the current cursor position is a visible format. 
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the cursor to look at.
- * @return @c EINA_TRUE if the cursor points to a visible format, @c EINA_FALSE
- * otherwise.
+ * @remarks This way is more efficient than evas_textblock_cursor_format_get() to check for the existence
+ *          of a visible format.
+ *
+ * @param[in]   cur  The cursor to look at
+ * @return  #EINA_TRUE if the cursor points to a visible format, \n
+ *          otherwise #EINA_FALSE if the cursor does not point to a visible format
  * @see evas_textblock_cursor_format_get()
  */
 EAPI Eina_Bool                                evas_textblock_cursor_format_is_visible_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Advances to the next format node
+ * @brief   Advances the cursor to the next format node.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the cursor to be updated.
- * @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
+ * @param[in]   cur  The cursor to be updated
+ * @return  #EINA_TRUE if the cursor is advanced successfully, \n 
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                                evas_textblock_cursor_format_next(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Advances to the previous format node.
+ * @brief   Advances the cursor to the previous format node.
  *
- * @param cur the cursor to update.
- * @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur  The cursor to update
+ * @return  #EINA_TRUE if the cursor is advanced successfully, \n 
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                                evas_textblock_cursor_format_prev(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Returns true if the cursor points to a format.
+ * @brief   Checks whether the cursor points to a format.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the cursor to check.
- * @return  @c EINA_TRUE if a cursor points to a format @c EINA_FALSE
- * otherwise.
+ * @param[in]   cur  The cursor to check
+ * @return  #EINA_TRUE if the cursor points to a format, \n 
+ *          otherwise #EINA_FALSE if the cursor does not point to a format
  */
 EAPI Eina_Bool                                evas_textblock_cursor_is_format(const Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Advances 1 char forward.
+ * @internal
+ * @brief   Advances the cursor 1 cluster forward.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur  The cursor to advance
+ * @return  #EINA_TRUE if the cursor is advanced successfully, \n
+ *          otherwise #EINA_FALSE on failure
+ */
+EAPI Eina_Bool                                evas_textblock_cursor_cluster_next(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+
+/**
+ * @internal
+ * @brief   Advances the cursor 1 cluster backward.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur  The cursor to advance
+ * @return  #EINA_TRUE if the cursor is advanced successfully, \n
+ *          otherwise #EINA_FALSE on failure
+ */
+EAPI Eina_Bool                                evas_textblock_cursor_cluster_prev(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief   Advances the cursor 1 char forward.
  *
- * @param cur the cursor to advance.
- * @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur  The cursor to advance
+ * @return  #EINA_TRUE if the cursor is advanced successfully, \n
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                                evas_textblock_cursor_char_next(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Advances 1 char backward.
+ * @brief   Advances the cursor 1 char backward.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the cursor to advance.
- * @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
+ * @param[in]   cur  The cursor to advance
+ * @return  #EINA_TRUE if the cursor is advanced successfully, \n
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                                evas_textblock_cursor_char_prev(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Moves the cursor to the start of the word under the cursor.
+ * @brief   Moves the cursor to the start of the word under the cursor.
+ * @since   1.2
  *
- * @param cur the cursor to move.
- * @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
- * @since 1.2
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur  The cursor to move
+ * @return  #EINA_TRUE if the cursor is moved successfully, \n
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                                evas_textblock_cursor_word_start(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Moves the cursor to the end of the word under the cursor.
+ * @brief   Moves the cursor to the end of the word under the cursor.
+ * @since   1.2
  *
- * @param cur the cursor to move.
- * @return @c EINA_TRUE on success @c EINA_FALSE otherwise.
- * @since 1.2
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur  The cursor to move
+ * @return  #EINA_TRUE if the cursor is moved successfully, \n
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                                evas_textblock_cursor_word_end(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Go to the first char in the node the cursor is pointing on.
+ * @brief  Moves the cursor to the first char in the node the cursor is pointing on.
  *
- * @param cur the cursor to update.
- * @return Returns no value.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  cur  The cursor to move
  */
 EAPI void                                     evas_textblock_cursor_paragraph_char_first(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Go to the last char in a text node.
+ * @brief  Moves the cursor to the last char in a text node.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the cursor to update.
- * @return Returns no value.
+ * @param[in]  cur  The cursor to move
  */
 EAPI void                                     evas_textblock_cursor_paragraph_char_last(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Go to the start of the current line
+ * @brief  Moves the cursor to the start of the current line.
  *
- * @param cur the cursor to update.
- * @return Returns no value.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  cur  The cursor to move
  */
 EAPI void                                     evas_textblock_cursor_line_char_first(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Go to the end of the current line.
+ * @brief  Moves the cursor to the end of the current line.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the cursor to update.
- * @return Returns no value.
+ * @param[in]  cur  The cursor to move
  */
 EAPI void                                     evas_textblock_cursor_line_char_last(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Return the current cursor pos.
+ * @brief   Gets the current cursor position.
  *
- * @param cur the cursor to take the position from.
- * @return the position or -1 on error
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur  The cursor
+ * @return  The cursor position, \n 
+ *          otherwise @c -1 on error
  */
 EAPI int                                      evas_textblock_cursor_pos_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set the cursor pos.
+ * @brief  Sets the cursor position.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the cursor to be set.
- * @param pos the pos to set.
+ * @param[in]  cur  The cursor to be set
+ * @param[in]  pos  The position to set
  */
 EAPI void                                     evas_textblock_cursor_pos_set(Evas_Textblock_Cursor *cur, int pos) EINA_ARG_NONNULL(1);
 
 /**
- * Go to the start of the line passed
+ * @brief   Moves the cursor to the start of the line passed.
  *
- * @param cur cursor to update.
- * @param line numer to set.
- * @return @c EINA_TRUE on success, @c EINA_FALSE on error.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur   The cursor
+ * @param[in]   line  The line number
+ * @return  #EINA_TRUE if the cursor is moved successfully, \n
+ *          otherwise #EINA_FALSE on error
  */
 EAPI Eina_Bool                                evas_textblock_cursor_line_set(Evas_Textblock_Cursor *cur, int line) EINA_ARG_NONNULL(1);
 
 /**
- * Compare two cursors.
+ * @brief   Compares two cursors.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur1 the first cursor.
- * @param cur2 the second cursor.
- * @return -1 if cur1 < cur2, 0 if cur1 == cur2 and 1 otherwise.
+ * @param[in]   cur1  The first cursor
+ * @param[in]   cur2  The second cursor
+ * @return  @c -1 if cur1 < cur2, @c 0 if cur1 == cur2, \n 
+ *          otherwise @c 1
  */
 EAPI int                                      evas_textblock_cursor_compare(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
 
 /**
- * Make cur_dest point to the same place as cur. Does not work if they don't
- * point to the same object.
+ * @brief   Makes @a cur_dest point to the same point as @a cur. 
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks This does not work if they do not point to the same object.
  *
- * @param cur the source cursor.
- * @param cur_dest destination cursor.
- * @return Returns no value.
+ * @param[in]   cur       The source cursor
+ * @param[in]   cur_dest  The destination cursor
  */
 EAPI void                                     evas_textblock_cursor_copy(const Evas_Textblock_Cursor *cur, Evas_Textblock_Cursor *cur_dest) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Adds text to the current cursor position and set the cursor to *before*
- * the start of the text just added.
+ * @brief   Adds text to the current cursor position and sets the cursor to *before*
+ *          the start of the text just added.
  *
- * @param cur the cursor to where to add text at.
- * @param text the text to add.
- * @return Returns the len of the text added.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur   The cursor to the position to add text at
+ * @param[in]   text  The text to add
+ * @return  The length of the text added
  * @see evas_textblock_cursor_text_prepend()
  */
 EAPI int                                      evas_textblock_cursor_text_append(Evas_Textblock_Cursor *cur, const char *text) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Adds text to the current cursor position and set the cursor to *after*
- * the start of the text just added.
+ * @brief   Adds text to the current cursor position and sets the cursor to *after*
+ *          the start of the text just added.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the cursor to where to add text at.
- * @param text the text to add.
- * @return Returns the len of the text added.
+ * @param[in]   cur   The cursor to the position to add text at
+ * @param[in]   text  The text to add
+ * @return  The length of the text added
  * @see evas_textblock_cursor_text_append()
  */
 EAPI int                                      evas_textblock_cursor_text_prepend(Evas_Textblock_Cursor *cur, const char *text) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Adds format to the current cursor position. If the format being added is a
- * visible format, add it *before* the cursor position, otherwise, add it after.
- * This behavior is because visible formats are like characters and invisible
- * should be stacked in a way that the last one is added last.
+ * @brief Adds format to the current cursor position.
+ * @details If the format being added is a visible format,
+            add it *before* the cursor position, otherwise, add it after.
+ *          This behavior is because visible formats are like characters and invisible
+ *          should be stacked in a way that the last one is added last.
  *
- * This function works with native formats, that means that style defined
- * tags like <br> won't work here. For those kind of things use markup prepend.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the cursor to where to add format at.
- * @param format the format to add.
+ * @remarks This function works with native formats, that means that style defined
+ *          tags like <br> won't work here. For those kind of things use markup prepend.
+ *
+ * @param[in] cur the cursor to where to add format at.
+ * @param[in] format the format to add.
  * @return Returns true if a visible format was added, false otherwise.
  * @see evas_textblock_cursor_format_prepend()
  */
-
-/**
- * Check if the current cursor position points to the terminating null of the
- * last paragraph. (shouldn't be allowed to point to the terminating null of
- * any previous paragraph anyway.
- *
- * @param cur the cursor to look at.
- * @return @c EINA_TRUE if the cursor points to the terminating null, @c EINA_FALSE otherwise.
- */
 EAPI Eina_Bool                                evas_textblock_cursor_format_append(Evas_Textblock_Cursor *cur, const char *format) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Adds format to the current cursor position. If the format being added is a
- * visible format, add it *before* the cursor position, otherwise, add it after.
- * This behavior is because visible formats are like characters and invisible
- * should be stacked in a way that the last one is added last.
- * If the format is visible the cursor is advanced after it.
+ * @brief   Adds the format to the current cursor position. 
+ * @details If the format being added is a visible format, 
+ *          add it *before* the cursor position, otherwise, add it after.
+ *          This behavior is because visible formats are like characters and invisible
+ *          should be stacked in a way that the last one is added last.
+ *          If the format is visible the cursor is advanced after it.
  *
- * This function works with native formats, that means that style defined
- * tags like <br> won't work here. For those kind of things use markup prepend.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the cursor to where to add format at.
- * @param format the format to add.
- * @return Returns true if a visible format was added, false otherwise.
+ * @remarks This function works with native formats, that means that style defined
+ *          tags like <br> does not work here. For those, use markup prepend.
+ *
+ * @param[in]   cur     The cursor to where to add format at
+ * @param[in]   format  The format to add
+ * @return  #EINA_TRUE if the visible format is added, \n
+ *          otherwise #EINA_FALSE if the visible format is not added
  * @see evas_textblock_cursor_format_prepend()
  */
 EAPI Eina_Bool                                evas_textblock_cursor_format_prepend(Evas_Textblock_Cursor *cur, const char *format) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Delete the character at the location of the cursor. If there's a format
- * pointing to this position, delete it as well.
+ * @brief   Deletes the character at the location of the cursor. 
+ * @details If there is a format pointing to this position, delete it as well.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the cursor pointing to the current location.
- * @return Returns no value.
+ * @param[in]   cur  The cursor pointing to the current location
  */
 EAPI void                                     evas_textblock_cursor_char_delete(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
 
 /**
- * Delete the range between cur1 and cur2.
+ * @brief   Deletes the range between @a cur1 and @a cur2.
  *
- * @param cur1 one side of the range.
- * @param cur2 the second side of the range
- * @return Returns no value.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur1  Starting point of the range
+ * @param[in]   cur2  Ending point of the range
  */
 EAPI void                                     evas_textblock_cursor_range_delete(Evas_Textblock_Cursor *cur1, Evas_Textblock_Cursor *cur2) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Return the text of the paragraph cur points to - returns the text in markup.
+ * @brief   Gets the text of the paragraph @a cur points to.
  *
- * @param cur the cursor pointing to the paragraph.
- * @return the text on success, @c NULL otherwise.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur  The cursor pointing to the paragraph
+ * @return  The text in markup, \n
+ *          otherwise @c NULL on error
  */
 EAPI const char                              *evas_textblock_cursor_paragraph_text_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Return the length of the paragraph, cheaper the eina_unicode_strlen()
+ * @brief   Gets the length of the paragraph. 
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the position of the paragraph.
- * @return the length of the paragraph on success, -1 otehrwise.
+ * @remarks This is cheaper that the eina_unicode_strlen().
+ *
+ * @param[in]   cur  The position of the paragraph
+ * @return  The length of the paragraph on success, \n
+ *          otherwise @c -1 on error
  */
 EAPI int                                      evas_textblock_cursor_paragraph_text_length_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Return the currently visible range.
+ * @brief   Gets the currently visible range.
+ * @since   1.1
  *
- * @param start the start of the range.
- * @param end the end of the range.
- * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   start  The start of the range
+ * @param[in]   end    The end of the range
+ * @return  #EINA_TRUE if the range is obtained successfully, \n
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                                evas_textblock_cursor_visible_range_get(Evas_Textblock_Cursor *start, Evas_Textblock_Cursor *end) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Return the format nodes in the range between cur1 and cur2.
+ * @brief   Gets the format nodes in the range between @a cur1 and @a cur2.
+ * @since   1.1
  *
- * @param cur1 one side of the range.
- * @param cur2 the other side of the range
- * @return the foramt nodes in the range. You have to free it.
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur1  The start of the range
+ * @param[in]   cur2  The end of the range
+ * @return  The format nodes in the range \n 
+ *          You have to free it.
  */
 EAPI Eina_List                               *evas_textblock_cursor_range_formats_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
 
 /**
- * Return the text in the range between cur1 and cur2
+ * @brief   Gets the text in the range between @a cur1 and @a cur2.
  *
- * @param cur1 one side of the range.
- * @param cur2 the other side of the range
- * @param format The form on which to return the text. Markup - in textblock markup. Plain - UTF8.
- * @return the text in the range
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur1    The start of the range
+ * @param[in]   cur2    The end of the range
+ * @param[in]   format  The format in which to return the text \n 
+ *                  Markup - in textblock markup. Plain - UTF8.
+ * @return  The text in the range
  * @see elm_entry_markup_to_utf8()
  */
 EAPI char                                    *evas_textblock_cursor_range_text_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2, Evas_Textblock_Text_Type format) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
 
 /**
- * Return the content of the cursor.
+ * @internal
+ * // TIZEN_ONLY(20131218)
+ * // Add evas_textblock_cursor_range_text_valid_markup_get API.
+ * @brief   Gets the text and markup tags in the range between @a cur1 and @a cur2.
+ *
+ * @param   cur1  The start of the range
+ * @param   cur2  The end of the range
+ * @return  The text in the range and the markup tags that affect the text
+ * @see elm_entry_markup_to_utf8()
+ */
+EAPI char                                    *evas_textblock_cursor_range_text_valid_markup_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
+/****************************************************/
+/************* TIZEN ONLY END   *********************/
+/****************************************************/
+
+/**
+ * @brief   Gets the content of the cursor.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Free the returned string pointer when done (if it is not NULL).
+ * @remarks Frees the returned string pointer when done if it is not @c NULL.
  *
- * @param cur the cursor
- * @return the text in the range, terminated by a nul byte (may be utf8).
+ * @param[in]   cur  The cursor
+ * @return  The text in the range, terminated by a null byte (may be utf8)
  */
 EAPI char                                    *evas_textblock_cursor_content_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Returns the geometry of the cursor. Depends on the type of cursor requested.
- * This should be used instead of char_geometry_get because there are weird
- * special cases with BiDi text.
- * in '_' cursor mode (i.e a line below the char) it's the same as char_geometry
- * get, except for the case of the last char of a line which depends on the
- * paragraph direction.
+ * @brief   Gets the geometry of two cursors ("split cursor"), if logical cursor is
+ *          between LTR/RTL text, also considering paragraph direction.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks The upper cursor is shown for the text of the same direction as paragraph,
+ *          lower cursor - for the opposite.
+ *
+ * @remarks The split cursor geometry is valid only  in '|' cursor mode.
+ *          In this case #EINA_TRUE is returned and @a cx2, @a cy2, @a cw2, @a ch2 are set,
+ *          otherwise it behaves like cursor_geometry_get.
+ *
+ * @param[in]   cur    The cursor
+ * @param[out]  cx     The x coordinate of the cursor (or upper cursor)
+ * @param[out]  cy     The y coordinate of the cursor (or upper cursor)
+ * @param[out]  cw     The width of the cursor (or upper cursor)
+ * @param[out]  ch     The height of the cursor (or upper cursor)
+ * @param[out]  cx2    The x coordinate of the lower cursor
+ * @param[out]  cy2    The y coordinate of the lower cursor
+ * @param[out]  cw2    The width of the lower cursor
+ * @param[out]  ch2    The height of the lower cursor
+ * @param[in]   ctype  The type of the cursor
+ * @return      #EINA_TRUE if split cursor,
+ *              otherwise #EINA_FALSE
+ */
+EAPI Eina_Bool evas_textblock_cursor_geometry_bidi_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_Coord *cx2, Evas_Coord *cy2, Evas_Coord *cw2, Evas_Coord *ch2, Evas_Textblock_Cursor_Type ctype);
+
+/**
+ * @brief   Gets the geometry of the cursor. 
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * in '|' cursor mode (i.e a line between two chars) it is very variable.
- * For example consider the following visual string:
- * "abcCBA" (ABC are rtl chars), a cursor pointing on A should actually draw
- * a '|' between the c and the C.
+ * @remarks It depends on the type of cursor requested.
+ *          This should be used instead of char_geometry_get because there are weird
+ *          special cases with BiDi text.
  *
- * @param cur the cursor.
- * @param cx the x of the cursor
- * @param cy the y of the cursor
- * @param cw the width of the cursor
- * @param ch the height of the cursor
- * @param dir the direction of the cursor, can be NULL.
- * @param ctype the type of the cursor.
- * @return line number of the char on success, -1 on error.
+ * @remarks In '_' cursor mode (i.e a line below the char) it is the same as char_geometry_get,
+ *          except for the case of the last char of a line which depends on the
+ *          paragraph direction.
+ *
+ * @remarks In '|' cursor mode (i.e a line between two chars) it is very variable.
+ *          For example, consider the following visual string:
+ *          "abcCBA" (ABC are rtl chars), a cursor pointing on A should actually draw
+ *          a '|' between the c and the C.
+ *
+ * @param[in]   cur    The cursor
+ * @param[out]   cx     The x coordinate of the cursor
+ * @param[out]   cy     The y coordinate of the cursor
+ * @param[out]   cw     The width of the cursor
+ * @param[out]   ch     The height of the cursor
+ * @param[in]   dir    The direction of the cursor \n 
+ *                 This can be @c NULL.
+ * @param[in]   ctype  The type of the cursor
+ * @return  The line number of the char on success, \n
+ *          otherwise @c -1 on error
  */
 EAPI int                                      evas_textblock_cursor_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_BiDi_Direction *dir, Evas_Textblock_Cursor_Type ctype) EINA_ARG_NONNULL(1);
 
 /**
- * Returns the geometry of the char at cur.
+ * @brief   Gets the geometry of the char at @a cur.
  *
- * @param cur the position of the char.
- * @param cx the x of the char.
- * @param cy the y of the char.
- * @param cw the w of the char.
- * @param ch the h of the char.
- * @return line number of the char on success, -1 on error.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur  The position of the char
+ * @param[out]   cx   The x coordinate of the char
+ * @param[out]   cy   The y coordinate of the char
+ * @param[out]   cw   The width of the char
+ * @param[out]   ch   The height of the char
+ * @return  The line number of the char, \n
+ *          otherwise @c -1 on error
  */
 EAPI int                                      evas_textblock_cursor_char_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
 
 /**
- * Returns the geometry of the pen at cur.
+ * @brief   Gets the geometry of the pen at @a cur.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the position of the char.
- * @param cpen_x the pen_x of the char.
- * @param cy the y of the char.
- * @param cadv the adv of the char.
- * @param ch the h of the char.
- * @return line number of the char on success, -1 on error.
+ * @param[in]   cur     The position of the char
+ * @param[out]   cpen_x  The pen_x of the char
+ * @param[out]   cy      The y of the char
+ * @param[out]   cadv    The adv of the char
+ * @param[out]   ch      The h of the char
+ * @return  The line number of the char, \n
+ *          otherwise @c -1 on error
  */
 EAPI int                                      evas_textblock_cursor_pen_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cpen_x, Evas_Coord *cy, Evas_Coord *cadv, Evas_Coord *ch) EINA_ARG_NONNULL(1);
 
 /**
- * Returns the geometry of the line at cur.
+ * @brief   Gets the geometry of the line at @a cur.
  *
- * @param cur the position of the line.
- * @param cx the x of the line.
- * @param cy the y of the line.
- * @param cw the width of the line.
- * @param ch the height of the line.
- * @return line number of the line on success, -1 on error.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur  The position of the line
+ * @param[out]   cx   The x coordinate of the line
+ * @param[out]   cy   The y coordinate of the line
+ * @param[out]   cw   The width of the line
+ * @param[out]   ch   The height of the line
+ * @return  The line number of the line, \n
+ *          otherwise @c -1 on error
  */
 EAPI int                                      evas_textblock_cursor_line_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
 
 /**
- * Set the position of the cursor according to the X and Y coordinates.
+ * @internal
+ * @brief   Sets the position of the cursor at a proper cluster according to the X and Y coordinates.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur  The cursor to set
+ * @param[in]   x    The x coordinate to set
+ * @param[in]   y    The y coordinate to set
+ * @return  #EINA_TRUE if the position of the cursor is set successfully, \n
+ *          otherwise #EINA_FALSE on failure
+ */
+EAPI Eina_Bool                                evas_textblock_cursor_cluster_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief   Sets the position of the cursor according to the X and Y coordinates.
  *
- * @param cur the cursor to set.
- * @param x coord to set by.
- * @param y coord to set by.
- * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur  The cursor to set
+ * @param[in]   x    The x coordinate to set
+ * @param[in]   y    The y coordinate to set
+ * @return  #EINA_TRUE if the position of the cursor is set successfully, \n 
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                                evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
 
 /**
- * Set the cursor position according to the y coord.
+ * @brief   Sets the cursor position according to the y coordinate.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the cur to be set.
- * @param y the coord to set by.
- * @return the line number found, -1 on error.
+ * @param[in]   cur  The cur to be set
+ * @param[in]   y    The y coordinate to set
+ * @return  The line number found, \n
+ *          otherwise @c -1 on error
  */
 EAPI int                                      evas_textblock_cursor_line_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord y) EINA_ARG_NONNULL(1);
 
 /**
- * Get the geometry of a range.
+ * @brief   Gets the geometry of a range.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   cur1  The start of the range
+ * @param[in]   cur2  The end of the range
+ * @return  A list of rectangles representing the geometry of the range
+ */
+EAPI Eina_List                               *evas_textblock_cursor_range_geometry_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
+
+/**
+ * @internal
+ *
+ * @brief   Get the simple geometry of a range.
+ * The simple geometry is the geomtry in which rectangles in middle
+ * lines of range are merged into one big rectangle.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
  * @param cur1 one side of the range.
  * @param cur2 other side of the range.
- * @return a list of Rectangles representing the geometry of the range.
+ * @return an iterator of rectangles representing the geometry of the range.
  */
-EAPI Eina_List                               *evas_textblock_cursor_range_geometry_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
+EAPI Eina_Iterator                               *evas_textblock_cursor_range_simple_geometry_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
+
+
 EAPI Eina_Bool                                evas_textblock_cursor_format_item_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
 
 /**
- * Checks if the cursor points to the end of the line.
+ * @brief   Checks whether the cursor points to the end of the line.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param cur the cursor to check.
- * @return @c EINA_TRUE if true, @c EINA_FALSE otherwise.
+ * @param[in]   cur  The cursor to check
+ * @return  #EINA_TRUE if the cursor points to the end of the line, \n
+ *          otherwise #EINA_FALSE
  */
 EAPI Eina_Bool                                evas_textblock_cursor_eol_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Get the geometry of a line number.
+ * @brief   Gets the geometry of a line number.
  *
- * @param obj the object.
- * @param line the line number.
- * @param cx x coord of the line.
- * @param cy y coord of the line.
- * @param cw w coord of the line.
- * @param ch h coord of the line.
- * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj   The object
+ * @param[in]   line  The line number
+ * @param[out]   cx    The x coordinate of the line
+ * @param[out]   cy    The y coordinate of the line
+ * @param[out]   cw    The w coordinate of the line
+ * @param[out]   ch    The h coordinate of the line
+ * @return  #EINA_TRUE if the geometry of the line is obtained successfully, 
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                                evas_object_textblock_line_number_geometry_get(const Evas_Object *obj, int line, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
 
 /**
- * Clear the textblock object.
- * @note Does *NOT* free the Evas object itself.
+ * @brief   Clears the textblock object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj the object to clear.
- * @return nothing.
+ * @remarks Does *NOT* free the Evas object itself.
+ *
+ * @param[in]   obj  The object to clear
  */
 EAPI void                                     evas_object_textblock_clear(Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Get the formatted width and height. This calculates the actual size after restricting
- * the textblock to the current size of the object.
- * The main difference between this and @ref evas_object_textblock_size_native_get
- * is that the "native" function does not wrapping into account
- * it just calculates the real width of the object if it was placed on an
- * infinite canvas, while this function gives the size after wrapping
- * according to the size restrictions of the object.
+ * @brief   Gets the formatted width and height. 
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * For example for a textblock containing the text: "You shall not pass!"
- * with no margins or padding and assuming a monospace font and a size of
- * 7x10 char widths (for simplicity) has a native size of 19x1
- * and a formatted size of 5x4.
+ * @remarks This calculates the actual size after restricting
+ *          the textblock to the current size of the object.
+ *          The main difference between this and @ref evas_object_textblock_size_native_get
+ *          is that the "native" function does not take wrapping into account.
+ *          It just calculates the real width of the object if it is placed on an
+ *          infinite canvas, while this function gives the size after wrapping
+ *          according to the size restrictions of the object.
  *
+ * @remarks For example, a textblock containing the text: "You shall not pass!"
+ *          with no margins or padding and assuming a monospace font and a size of
+ *          7x10 char widths (for simplicity) has a native size of 19x1
+ *          and a formatted size of 5x4.
  *
- * @param obj the Evas object.
- * @param w the width of the object.
- * @param h the height of the object
- * @return Returns no value.
+ *
+ * @param[in]   obj  The Evas object
+ * @param[out]   w    The width of the object
+ * @param[out]   h    The height of the object
  * @see evas_object_textblock_size_native_get
  */
 EAPI void                                     evas_object_textblock_size_formatted_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
 
 /**
- * Get the native width and height. This calculates the actual size without taking account
- * the current size of the object.
- * The main difference between this and @ref evas_object_textblock_size_formatted_get
- * is that the "native" function does not take wrapping into account
- * it just calculates the real width of the object if it was placed on an
- * infinite canvas, while the "formatted" function gives the size after
- * wrapping text according to the size restrictions of the object.
+ * @brief   Gets the native width and height. 
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * For example for a textblock containing the text: "You shall not pass!"
- * with no margins or padding and assuming a monospace font and a size of
- * 7x10 char widths (for simplicity) has a native size of 19x1
- * and a formatted size of 5x4.
+ * @remarks This calculates the actual size without taking into account
+ *          the current size of the object.
+ *          The main difference between this and @ref evas_object_textblock_size_formatted_get
+ *          is that the "native" function does not take wrapping into account.
+ *          It just calculates the real width of the object if it is placed on an
+ *          infinite canvas, while the "formatted" function gives the size after
+ *          wrapping text according to the size restrictions of the object.
  *
- * @param obj the Evas object of the textblock
- * @param w the width returned
- * @param h the height returned
- * @return Returns no value.
+ * @remarks For example, a textblock containing the text: "You shall not pass!"
+ *          with no margins or padding and assuming a monospace font and a size of
+ *          7x10 char widths (for simplicity) has a native size of 19x1
+ *          and a formatted size of 5x4.
+ *
+ * @param[in]   obj  The Evas object of the textblock
+ * @param[out]   w    The width returned
+ * @param[out]   h    The height returned
  */
 EAPI void                                     evas_object_textblock_size_native_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
+
+/**
+ * @internal
+ */
 EAPI void                                     evas_object_textblock_style_insets_get(const Evas_Object *obj, Evas_Coord *l, Evas_Coord *r, Evas_Coord *t, Evas_Coord *b) EINA_ARG_NONNULL(1);
 
+// TIZEN_ONLY(20150513): Add evas_object_text/textblock_ellipsis_status_get internal API.
+/**
+ * @internal
+ */
+EAPI Eina_Bool                                evas_object_textblock_ellipsis_status_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+//
+
 /**
  * @}
  */
 
 
 /**
+ * @internal
  * @defgroup Evas_Object_Textgrid Textgrid Object Functions
+ * @ingroup Evas_Object_Specific
  *
  * @todo put here some usage examples
  *
  * @since 1.7
  *
- * @ingroup Evas_Object_Specific
- *
  * @{
  */
 
 /**
  * @typedef Evas_Textgrid_Palette
  *
- * The palette to use for the forgraound and background colors.
+ * @brief Enumeration for the palette to use for the foreground and background colors.
  *
  * @since 1.7
  */
 typedef enum
 {
    EVAS_TEXTGRID_PALETTE_NONE,     /**< No palette is used */
-   EVAS_TEXTGRID_PALETTE_STANDARD, /**< standard palette (around 16 colors) */
-   EVAS_TEXTGRID_PALETTE_EXTENDED, /**< extended palette (at max 256 colors) */
-   EVAS_TEXTGRID_PALETTE_LAST      /**< ignore it */
+   EVAS_TEXTGRID_PALETTE_STANDARD, /**< Standard palette (around 16 colors) */
+   EVAS_TEXTGRID_PALETTE_EXTENDED, /**< Extended palette (at max 256 colors) */
+   EVAS_TEXTGRID_PALETTE_LAST      /**< Ignore this */
 } Evas_Textgrid_Palette;
 
 /**
  * @typedef Evas_Textgrid_Font_Style
  *
- * The style to give to each character of the grid.
+ * @brief Enumeration for the style to give to each character of the grid.
  *
  * @since 1.7
  */
@@ -9194,234 +11137,274 @@ typedef enum
 /**
  * @typedef Evas_Textgrid_Cell
  *
- * The values that describes each cell.
+ * @brief The structure type containing the values that describe each cell.
  *
  * @since 1.7
  */
 typedef struct _Evas_Textgrid_Cell Evas_Textgrid_Cell;
 
 /**
+ * @internal
  * @struct _Evas_Textgrid_Cell
  *
- * The values that describes each cell.
+ *  @brief The structure type containing the values that describe each cell.
  *
  * @since 1.7
  */
 struct _Evas_Textgrid_Cell
 {
-   Eina_Unicode   codepoint;         /**< the UNICODE value of the character */
-   unsigned char  fg;                /**< the index of the palette for the foreground color */
-   unsigned char  bg;                /**< the index of the palette for the background color */
-   unsigned short bold          : 1; /**< whether the character is bold */
-   unsigned short italic        : 1; /**< whether the character is oblique */
-   unsigned short underline     : 1; /**< whether the character is underlined */
-   unsigned short strikethrough : 1; /**< whether the character is strikethrough'ed */
-   unsigned short fg_extended   : 1; /**< whether the extended palette is used for the foreground color */
-   unsigned short bg_extended   : 1; /**< whether the extended palette is used for the background color */
-   unsigned short double_width  : 1; /**< if the codepoint is merged with the following cell to the right visually (cells must be in pairs with 2nd cell being a duplicate in all ways except codepoint is 0) */
+   Eina_Unicode   codepoint;         /**< The UNICODE value of the character */
+   unsigned char  fg;                /**< The index of the palette for the foreground color */
+   unsigned char  bg;                /**< The index of the palette for the background color */
+   unsigned short bold          : 1; /**< The character is bold */
+   unsigned short italic        : 1; /**< The character is oblique */
+   unsigned short underline     : 1; /**< The character is underlined */
+   unsigned short strikethrough : 1; /**< The character is struck through */
+   unsigned short fg_extended   : 1; /**< The extended palette is used for the foreground color */
+   unsigned short bg_extended   : 1; /**< The extended palette is used for the background color */
+   unsigned short double_width  : 1; /**< The codepoint is merged with the following cell to the right visually (cells must be in pairs with 2nd cell being a duplicate in all ways except codepoint is 0) */
 };
 
 /**
- * @brief Add a textgrid to the given Evas.
+ * @brief   Adds a textgrid to the given Evas.
  *
- * @param e The given evas.
- * @return The new textgrid object.
+ * @details This function adds a new textgrid object to the Evas @a e and returns the object.
+ * @since   1.7
  *
- * This function adds a new textgrid object to the Evas @p e and returns the object.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e  The given evas
+ * @return  The new textgrid object
  *
- * @since 1.7
  */
 EAPI Evas_Object *evas_object_textgrid_add(Evas *e);
 
 /**
- * @brief Set the size of the textgrid object.
+ * @brief   Sets the size of the textgrid object.
  *
- * @param obj The textgrid object.
- * @param w The number of columns (width in cells) of the grid.
- * @param h The number of rows (height in cells) of the grid.
+ * @details This function sets the number of lines @a h and the number
+ *          of columns @a w to the textgrid object @a obj. If
+ *          @a w or @a h are less or equal than @c 0, this
+ *          function does nothing.
  *
- * This function sets the number of lines @p h and the number
- * of columns @p w to the textgrid object @p obj. If
- * @p w or @p h are less or equal than 0, this
- * functiond does nothing.
+ * @since   1.7
  *
- * @since 1.7
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The textgrid object
+ * @param[in]   w    The number of columns (width in cells) of the grid
+ * @param[in]   h    The number of rows (height in cells) of the grid
  */
 EAPI void evas_object_textgrid_size_set(Evas_Object *obj, int w, int h);
 
 /**
- * @brief Get the size of the textgrid object.
+ * @brief   Gets the size of the textgrid object.
  *
- * @param obj The textgrid object.
- * @param w The number of columns of the grid.
- * @param h The number of rows of the grid.
+ * @details This function retrieves the number of lines in the buffer @a
+ *          h and the number of columns in the buffer @a w of
+ *          the textgrid object @a obj. @a w or @a h can be
+ *          @c NULL. On error, their value is @c 0.
  *
- * This function retrieves the number of lines in the buffer @p
- * h and the number of columns in the buffer @p w of
- * the textgrid object @p obj. @p w or @p h can be
- * @c NULL. On error, their value is 0.
+ * @since   1.7
  *
- * @since 1.7
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The textgrid object
+ * @param[out]   w    The number of columns of the grid
+ * @param[out]   h    The number of rows of the grid
  */
 EAPI void evas_object_textgrid_size_get(const Evas_Object *obj, int *w, int *h);
 
 /**
- * @brief Set the font (source) file to be used on a given textgrid object.
+ * @brief   Sets the font (source) file to be used on a given textgrid object.
+ *
+ * @details This function allows the font file @a font_source to be explicitly
+ *          set for the textgrid object @a obj, overriding system lookup, which
+ *          first occurs in the given file's contents. If @a font_source is
+ *          @c NULL or is an empty string, or the same @a font_source has already
+ *          been set, or on error, this function does nothing.
+ *
+ * @since   1.7
  *
- * @param obj The textgrid object to set font for.
- * @param font_source The font file's path.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function allows the font file @p font_source to be explicitly
- * set for the textgrid object @p obj, overriding system lookup, which
- * will first occur in the given file's contents. If @font_source is
- * @c NULL or is an empty string, or the same font_source has already
- * been set, or on error, this function does nothing.
+ * @param[in]   obj          The textgrid object to set font for
+ * @param[in]   font_source  The font file's path
  *
  * @see evas_object_textgrid_font_get()
  * @see evas_object_textgrid_font_set()
  * @see evas_object_textgrid_font_source_get()
- *
- * @since 1.7
  */
 EAPI void evas_object_textgrid_font_source_set(Evas_Object *obj, const char *font_source);
 
 /**
- * @brief Get the font file's path which is being used on a given textgrid object.
+ * @brief   Gets the font file's path which is being used on a given textgrid object.
+ *
+ * @details This function returns the font source path of the textgrid object
+ *          @a obj. If the font source path has not been set, or on error,
+ *          @c NULL is returned.
+ *
+ * @since   1.7
  *
- * @param obj The textgrid object to set font for.
- * @return The font file's path.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function returns the font source path of the textgrid object
- * @p obj. If the font source path has not been set, or on error,
- * @c NULL is returned.
+ * @param[in]   obj  The textgrid object to set font for
+ * @return  The font file's path
  *
  * @see evas_object_textgrid_font_get()
  * @see evas_object_textgrid_font_set()
  * @see evas_object_textgrid_font_source_set()
- *
- * @since 1.7
  */
 EAPI const char *evas_object_textgrid_font_source_get(const Evas_Object *obj);
 
 /**
- * @brief Set the font family and size on a given textgrid object.
+ * @brief   Sets the font family and size on a given textgrid object.
+ *
+ * @details This function allows the font name @a font_name and size
+ *          @a font_size of the textgrid object @a obj to be set. The @a font_name
+ *          string has to follow fontconfig's convention on naming fonts, as
+ *          it is the underlying library used to query system fonts by Evas (see
+ *          the @c fc-list command's output, on your system, to get an
+ *          idea). It also has to be a monospace font. If @a font_name is
+ *          @c NULL, or if it is an empty string, or if @a font_size is less or
+ *          equal than @c 0, or on error, this function does nothing.
+ *
+ * @since   1.7
  *
- * @param obj The textgrid object to set font for.
- * @param font_name The font (family) name.
- * @param font_size The font size, in points.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function allows the font name @p font_name and size
- * @p font_size of the textgrid object @p obj to be set. The @p font_name
- * string has to follow fontconfig's convention on naming fonts, as
- * it's the underlying library used to query system fonts by Evas (see
- * the @c fc-list command's output, on your system, to get an
- * idea). It also has to be a monospace font. If @p font_name is
- * @c NULL, or if it is an empty string, or if @p font_size is less or
- * equal than 0, or on error, this function does nothing.
+ * @param[in]   obj        The textgrid object to set font for
+ * @param[in]   font_name  The font (family) name
+ * @param[in]   font_size  The font size, in points
  *
  * @see evas_object_textgrid_font_get()
  * @see evas_object_textgrid_font_source_set()
  * @see evas_object_textgrid_font_source_get()
- *
- * @since 1.7
  */
 EAPI void evas_object_textgrid_font_set(Evas_Object *obj, const char *font_name, Evas_Font_Size font_size);
 
 /**
- * @brief Retrieve the font family and size in use on a given textgrid object.
+ * @brief   Gets the font family and size in use on a given textgrid object.
+ *
+ * @details This function allows the font name and size of a textgrid object
+ *          @a obj to be queried and stored respectively in the buffers
+ *          @a font_name and @a font_size. Be aware that the font name string is
+ *          still owned by Evas and should @b not have free() called on it by
+ *          the caller of the function. On error, the font name is the empty
+ *          string and the font size is @c 0. @a font_name and @a font_source can
+ *          be @c NULL.
+ *
+ * @since   1.7
  *
- * @param obj The textgrid object to query for font information.
- * @param font_name A pointer to the location to store the font name in.
- * @param font_size A pointer to the location to store the font size in.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function allows the font name and size of a textgrid object
- * @p obj to be queried and stored respectively in the buffers
- * @p font_name and @p font_size. Be aware that the font name string is
- * still owned by Evas and should @b not have free() called on it by
- * the caller of the function. On error, the font name is the empty
- * string and the font size is 0. @p font_name and @p font_source can
- * be @c NULL.
+ * @param[in]   obj        The textgrid object to query for font information
+ * @param[out]   font_name  A pointer to the location to store the font name in
+ * @param[out]   font_size  A pointer to the location to store the font size in
  *
  * @see evas_object_textgrid_font_set()
  * @see evas_object_textgrid_font_source_set()
  * @see evas_object_textgrid_font_source_get()
- *
- * @since 1.7
  */
 EAPI void evas_object_textgrid_font_get(const Evas_Object *obj, const char **font_name, Evas_Font_Size *font_size);
 
 /**
- * @brief Retrieve the size of a cell of the given textgrid object in pixels.
+ * @brief   Gets the size of a cell of the given textgrid object in pixels.
+ *
+ * @details This functions retrieves the width and height, in pixels, of a cell
+ *          of the textgrid object @a obj and store them respectively in the
+ *          buffers @a width and @a height. Their value depends on the
+ *          monospace font used for the textgrid object, as well as the
+ *          style. @a width and @a height can be @c NULL. On error, they are
+ *          set to @c 0.
+ *
+ * @since   1.7
  *
- * @param obj The textgrid object to query for font information.
- * @param width A pointer to the location to store the width in pixels of a cell.
- * @param height A pointer to the location to store the height in
- * pixels of a cell.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This functions retrieves the width and height, in pixels, of a cell
- * of the textgrid object @p obj and store them respectively in the
- * buffers @p width and @p height. Their value depends on the
- * monospace font used for the textgrid object, as well as the
- * style. @p width and @p height can be @c NULL. On error, they are
- * set to 0.
+ * @param[in]   obj    The textgrid object to query for font information
+ * @param[out]  w      A pointer to the location to store the width in pixels of a cell
+ * @param[out]  h      A pointer to the location to store the height in pixels of a cell
  *
  * @see evas_object_textgrid_font_set()
  * @see evas_object_textgrid_supported_font_styles_set()
- *
- * @since 1.7
  */
 EAPI void evas_object_textgrid_cell_size_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);
 
 /**
- * @brief The set color to the given palette at the given index of the given textgrid object.
+ * @brief   Sets the color to the given palette at the given index of the given textgrid object.
  *
- * @param obj The textgrid object to query for font information.
- * @param pal The type of the palette to set the color.
- * @param idx The index of the paletter to wich the color is stored.
- * @param r The red component of the color.
- * @param g The green component of the color.
- * @param b The blue component of the color.
- * @param a The alpha component of the color.
+ * @details This function sets the color for the palette of type @a pal at the
+ *          index @a idx of the textgrid object @a obj. The ARGB components are
+ *          given by @a r, @a g, @a b and @a a. This color can be used when
+ *          setting the #Evas_Textgrid_Cell structure. The components must set
+ *          a pre-multiplied color. If pal is #EVAS_TEXTGRID_PALETTE_NONE or
+ *          #EVAS_TEXTGRID_PALETTE_LAST, or if @a idx is not between @c 0 and @c 255,
+ *          or on error, this function does nothing. The color components are
+ *          clamped between @c 0 and @c 255. If @a idx is greater than the latest set
+ *          color, the colors between this last index and @a idx - 1 are set to
+ *          black (0, 0, 0, 0).
  *
- * This function sets the color for the palette of type @p pal at the
- * index @p idx of the textgrid object @p obj. The ARGB components are
- * given by @p r, @p g, @p b and @p a. This color can be used when
- * setting the #Evas_Textgrid_Cell structure. The components must set
- * a pre-multiplied color. If pal is #EVAS_TEXTGRID_PALETTE_NONE or
- * #EVAS_TEXTGRID_PALETTE_LAST, or if @p idx is not between 0 and 255,
- * or on error, this function does nothing. The color components are
- * clamped between 0 and 255. If @p idx is greater than the latest set
- * color, the colors between this last index and @p idx - 1 are set to
- * black (0, 0, 0, 0).
+ * @since   1.7
  *
- * @see evas_object_textgrid_palette_get()
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @since 1.7
+ * @param[in]   obj  The textgrid object to query for font information
+ * @param[in]   pal  The type of the palette to set the color
+ * @param[in]   idx  The index of the paletter to which the color is stored
+ * @param[in]   r    The red component of the color
+ * @param[in]   g    The green component of the color
+ * @param[in]   b    The blue component of the color
+ * @param[in]   a    The alpha component of the color
+ *
+ * @see evas_object_textgrid_palette_get()
  */
 EAPI void evas_object_textgrid_palette_set(Evas_Object *obj, Evas_Textgrid_Palette pal, int idx, int r, int g, int b, int a);
 
 /**
- * @brief The retrieve color to the given palette at the given index of the given textgrid object.
+ * @brief   Gets the color to the given palette at the given index of the given textgrid object.
  *
- * @param obj The textgrid object to query for font information.
- * @param pal The type of the palette to set the color.
- * @param idx The index of the paletter to wich the color is stored.
- * @param r A pointer to the red component of the color.
- * @param g A pointer to the green component of the color.
- * @param b A pointer to the blue component of the color.
- * @param a A pointer to the alpha component of the color.
+ * @details This function retrieves the color for the palette of type @a pal at the
+ *          index @a idx of the textgrid object @a obj. The ARGB components are
+ *          stored in the buffers @a r, @a g, @a b and @a a. If @a idx is not
+ *          between @c 0 and the index of the latest set color, or if @a pal is
+ *          #EVAS_TEXTGRID_PALETTE_NONE or #EVAS_TEXTGRID_PALETTE_LAST, the
+ *          values of the components are @c 0. @a r, @a g, @a b and @a a can be
+ *          @c NULL.
  *
- * This function retrieves the color for the palette of type @p pal at the
- * index @p idx of the textgrid object @p obj. The ARGB components are
- * stored in the buffers @p r, @p g, @p b and @p a. If @p idx is not
- * between 0 and the index of the latest set color, or if @p pal is
- * #EVAS_TEXTGRID_PALETTE_NONE or #EVAS_TEXTGRID_PALETTE_LAST, the
- * values of the components are 0. @p r, @p g, @pb and @p a can be
- * @c NULL.
+ * @since   1.7
  *
- * @see evas_object_textgrid_palette_set()
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @since 1.7
+ * @param[in]   obj  The textgrid object to query for font information
+ * @param[in]   pal  The type of the palette to set the color
+ * @param[in]   idx  The index of the paletter to which the color is stored
+ * @param[out]   r    A pointer to the red component of the color
+ * @param[out]   g    A pointer to the green component of the color
+ * @param[out]   b    A pointer to the blue component of the color
+ * @param[out]   a    A pointer to the alpha component of the color
+ *
+ * @see evas_object_textgrid_palette_set()
  */
 EAPI void evas_object_textgrid_palette_get(const Evas_Object *obj, Evas_Textgrid_Palette pal, int idx, int *r, int *g, int *b, int *a);
 
@@ -9429,56 +11412,64 @@ EAPI void evas_object_textgrid_supported_font_styles_set(Evas_Object *obj, Evas_
 EAPI Evas_Textgrid_Font_Style evas_object_textgrid_supported_font_styles_get(const Evas_Object *obj);
 
 /**
- * @brief Set the string at the given row of the given textgrid object.
+ * @brief   Sets the string at the given row of the given textgrid object.
+ *
+ * @details This function returns cells to the textgrid taken by
+ *          evas_object_textgrid_cellrow_get(). The row pointer @a row should be the
+ *          same row pointer returned by evas_object_textgrid_cellrow_get() for the
+ *          same row @a y.
  *
- * @param obj The textgrid object to query for font information.
- * @param y The row index of the grid.
- * @param The string as a sequence of #Evas_Textgrid_Cell.
+ * @since   1.7
  *
- * This function returns cells to the textgrid taken by
- * evas_object_textgrid_cellrow_get(). The row pointer @p row should be the
- * same row pointer returned by evas_object_textgrid_cellrow_get() for the
- * same row @p y.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The textgrid object to query for font information
+ * @param[in]   y    The row index of the grid
+ * @param[in]   row  The string as a sequence of #Evas_Textgrid_Cell
  *
  * @see evas_object_textgrid_cellrow_get()
  * @see evas_object_textgrid_size_set()
  * @see evas_object_textgrid_update_add()
- *
- * @since 1.7
  */
 EAPI void evas_object_textgrid_cellrow_set(Evas_Object *obj, int y, const Evas_Textgrid_Cell *row);
 
 /**
- * @brief Get the string at the given row of the given textgrid object.
+ * @brief   Gets the string at the given row of the given textgrid object.
+ *
+ * @details This function returns a pointer to the first cell of the line @a y
+ *          of the textgrid object @a obj. If @a y is not between @c 0 and the
+ *          number of lines of the grid - 1, or on error, this function return @c NULL.
  *
- * @param obj The textgrid object to query for font information.
- * @param y The row index of the grid.
- * @return A pointer to the first cell of the given row.
+ * @since   1.7
  *
- * This function returns a pointer to the first cell of the line @p y
- * of the textgrid object @p obj. If @p y is not between 0 and the
- * number of lines of the grid - 1, or on error, this function return @c NULL.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj  The textgrid object to query for font information
+ * @param[in]   y    The row index of the grid
+ * @return  A pointer to the first cell of the given row
  *
  * @see evas_object_textgrid_cellrow_set()
  * @see evas_object_textgrid_size_set()
  * @see evas_object_textgrid_update_add()
- *
- * @since 1.7
  */
 EAPI Evas_Textgrid_Cell *evas_object_textgrid_cellrow_get(const Evas_Object *obj, int y);
 
 /**
- * @brief Indicate for evas that part of a textgrid region (cells) has been updated.
+ * @brief   Indicates to evas that part of a textgrid region (cells) has been updated.
+ *
+ * @since   1.7
  *
- * @param obj The textgrid object.
- * @param x The rect region of cells top-left x (column)
- * @param y The rect region of cells top-left y (row)
- * @param w The rect region size in number of cells (columns)
- * @param h The rect region size in number of cells (rows)
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function declares to evas that a region of cells was updated by
- * code and needs refreshing. An application should modify cells like this
- * as an example:
+ * @remarks This function declares to evas that a region of cells is updated by
+ *          code and needs refreshing. An application should modify cells like this
+ *          as an example:
  * 
  * @code
  * Evas_Textgrid_Cell *cells;
@@ -9490,11 +11481,15 @@ EAPI Evas_Textgrid_Cell *evas_object_textgrid_cellrow_get(const Evas_Object *obj
  * evas_object_textgrid_update_add(obj, 0, row, width, 1);
  * @endcode
  *
+ * @param[in]   obj  The textgrid object
+ * @param[in]   x    The rect region of cells top-left x (column)
+ * @param[in]   y    The rect region of cells top-left y (row)
+ * @param[in]   w    The rect region size in number of cells (columns)
+ * @param[in]   h    The rect region size in number of cells (rows)
+ *
  * @see evas_object_textgrid_cellrow_set()
  * @see evas_object_textgrid_cellrow_get()
  * @see evas_object_textgrid_size_set()
- *
- * @since 1.7
  */
 EAPI void evas_object_textgrid_update_add(Evas_Object *obj, int x, int y, int w, int h);
 
@@ -9504,118 +11499,155 @@ EAPI void evas_object_textgrid_update_add(Evas_Object *obj, int x, int y, int w,
 
 /**
  * @defgroup Evas_Line_Group Line Object Functions
+ * @ingroup Evas_Object_Specific
  *
- * Functions used to deal with evas line objects.
- *
- * @warning We don't guarantee any proper results if you create a Line object
- * without setting the evas engine.
+ * @brief This group provides functions to deal with evas line objects.
  *
- * @ingroup Evas_Object_Specific
+ * @remarks We do not guarantee any proper results if you create a Line object
+ *          without setting the evas engine.
  *
  * @{
  */
 
 /**
- * Adds a new evas line object to the given evas.
- * @param   e The given evas.
- * @return  The new evas line object.
+ * @brief   Adds a new evas line object to the given evas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e  The given evas
+ * @return  The new evas line object
  */
 EAPI Evas_Object *evas_object_line_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Sets the coordinates of the end points of the given evas line object.
- * @param   obj The given evas line object.
- * @param   x1  The X coordinate of the first point.
- * @param   y1  The Y coordinate of the first point.
- * @param   x2  The X coordinate of the second point.
- * @param   y2  The Y coordinate of the second point.
+ * @brief  Sets the coordinates of the end points of the given evas line object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  obj  The given evas line object
+ * @param[in]  x1   The X coordinate of the first point
+ * @param[in]  y1   The Y coordinate of the first point
+ * @param[in]  x2   The X coordinate of the second point
+ * @param[in]  y2   The Y coordinate of the second point
  */
 EAPI void         evas_object_line_xy_set(Evas_Object *obj, Evas_Coord x1, Evas_Coord y1, Evas_Coord x2, Evas_Coord y2);
 
 /**
- * Retrieves the coordinates of the end points of the given evas line object.
- * @param obj The given line object.
- * @param x1  Pointer to an integer in which to store the X coordinate of the
- *            first end point.
- * @param y1  Pointer to an integer in which to store the Y coordinate of the
- *            first end point.
- * @param x2  Pointer to an integer in which to store the X coordinate of the
- *            second end point.
- * @param y2  Pointer to an integer in which to store the Y coordinate of the
- *            second end point.
+ * @brief  Gets the coordinates of the end points of the given evas line object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  obj  The given line object
+ * @param[out]  x1   The pointer to an integer in which to store the X coordinate of the
+ *              first end point
+ * @param[out]  y1   The pointer to an integer in which to store the Y coordinate of the
+ *              first end point
+ * @param[out]  x2   The pointer to an integer in which to store the X coordinate of the
+ *              second end point
+ * @param[out]  y2   The pointer to an integer in which to store the Y coordinate of the
+ *              second end point
  */
 EAPI void         evas_object_line_xy_get(const Evas_Object *obj, Evas_Coord *x1, Evas_Coord *y1, Evas_Coord *x2, Evas_Coord *y2);
+
 /**
  * @}
  */
 
 /**
  * @defgroup Evas_Object_Polygon Polygon Object Functions
+ * @ingroup Evas_Object_Specific
  *
- * Functions that operate on evas polygon objects.
+ * @brief This group provides functions that operate on evas polygon objects.
  *
  * Hint: as evas does not provide ellipse, smooth paths or circle, one
  * can calculate points and convert these to a polygon.
  *
- * @warning We don't guarantee any proper results if you create a Polygon
- * object without setting the evas engine.
- *
- * @ingroup Evas_Object_Specific
+ * @remarks We do not guarantee any proper results if you create a Polygon
+ *          object without setting the evas engine.
  *
  * @{
  */
 
 /**
- * Adds a new evas polygon object to the given evas.
- * @param   e The given evas.
- * @return  A new evas polygon object.
+ * @brief   Adds a new evas polygon object to the given evas.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e  The given evas
+ * @return  A new evas polygon object
  */
 EAPI Evas_Object *evas_object_polygon_add(Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Adds the given point to the given evas polygon object.
- * @param obj The given evas polygon object.
- * @param x   The X coordinate of the given point.
- * @param y   The Y coordinate of the given point.
+ * @brief  Adds the given point to the given evas polygon object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  obj  The given evas polygon object
+ * @param[in]  x    The X coordinate of the given point
+ * @param[in]  y    The Y coordinate of the given point
  * @ingroup Evas_Polygon_Group
  */
 EAPI void         evas_object_polygon_point_add(Evas_Object *obj, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1);
 
 /**
- * Removes all of the points from the given evas polygon object.
- * @param   obj The given polygon object.
+ * @brief  Removes all of the points from the given evas polygon object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  obj  The given polygon object
  */
 EAPI void         evas_object_polygon_points_clear(Evas_Object *obj) EINA_ARG_NONNULL(1);
 /**
  * @}
  */
 
-/* @since 1.2 */
+/**
+ * @internal
+ * @since 1.2
+ *
+ * Need description
+ * @ingroup Evas_Object_Group
+ */
 EAPI void         evas_object_is_frame_object_set(Evas_Object *obj, Eina_Bool is_frame);
 
-/* @since 1.2 */
+/**
+ * @internal
+ * @since 1.2
+ *
+ * Need description
+ * @ingroup Evas_Object_Group
+ */
 EAPI Eina_Bool    evas_object_is_frame_object_get(Evas_Object *obj);
 
 /**
+ * @internal
  * @defgroup Evas_Smart_Group Smart Functions
+   @ingroup Evas
  *
- * Functions that deal with #Evas_Smart structs, creating definition
- * (classes) of objects that will have customized behavior for methods
+ * This group provides functions that deal with #Evas_Smart structs, creating definition
+ * (classes) of objects that have customized behavior for methods
  * like evas_object_move(), evas_object_resize(),
  * evas_object_clip_set() and others.
  *
- * These objects will accept the generic methods defined in @ref
+ * These objects accept the generic methods defined in @ref
  * Evas_Object_Group and the extensions defined in @ref
  * Evas_Smart_Object_Group. There are a couple of existent smart
  * objects in Evas itself (see @ref Evas_Object_Box, @ref
  * Evas_Object_Table and @ref Evas_Smart_Object_Clipped).
  *
- * See also some @ref Example_Evas_Smart_Objects "examples" of this
- * group of functions.
- */
-
-/**
- * @addtogroup Evas_Smart_Group
  * @{
  */
 
@@ -9625,89 +11657,84 @@ EAPI Eina_Bool    evas_object_is_frame_object_get(Evas_Object *obj);
  * The version you have to put into the version field in the
  * #Evas_Smart_Class struct. Used to safeguard from binaries with old
  * smart object intefaces running with newer ones.
- *
- * @ingroup Evas_Smart_Group
  */
 #define EVAS_SMART_CLASS_VERSION 4
+
 /**
+ * @internal
  * @struct _Evas_Smart_Class
  *
- * A smart object's @b base class definition
- *
- * @ingroup Evas_Smart_Group
+ * @brief The structure type containing a smart object's @b base class definition.
  */
 struct _Evas_Smart_Class
 {
-   const char                      *name; /**< the name string of the class */
+   const char                      *name; /**< The name string of the class */
    int                              version;
-   void                             (*add)(Evas_Object *o); /**< code to be run when adding object to a canvas */
-   void                             (*del)(Evas_Object *o); /**< code to be run when removing object from a canvas */
-   void                             (*move)(Evas_Object *o, Evas_Coord x, Evas_Coord y); /**< code to be run when moving object on a canvas. @a x and @a y will be new coordinates one applied to the object. use evas_object_geometry_get() if you need the old values, during this call. after that, the old values will be lost. */
-   void                             (*resize)(Evas_Object *o, Evas_Coord w, Evas_Coord h); /**< code to be run when resizing object on a canvas. @a w and @a h will be new dimensions one applied to the object. use evas_object_geometry_get() if you need the old values, during this call. after that, the old values will be lost. */
-   void                             (*show)(Evas_Object *o); /**< code to be run when showing object on a canvas */
-   void                             (*hide)(Evas_Object *o); /**< code to be run when hiding object on a canvas */
-   void                             (*color_set)(Evas_Object *o, int r, int g, int b, int a); /**< code to be run when setting color of object on a canvas. @a r, @a g, @a b and @a y will be new color components one applied to the object. use evas_object_color_get() if you need the old values, during this call. after that, the old values will be lost. */
-   void                             (*clip_set)(Evas_Object *o, Evas_Object *clip); /**< code to be run when setting clipper of object on a canvas. @a clip will be new clipper one applied to the object. use evas_object_clip_get() if you need the old one, during this call. after that, the old (object pointer) value will be lost. */
-   void                             (*clip_unset)(Evas_Object *o); /**< code to be run when unsetting clipper of object on a canvas. if you need the pointer to a previous set clipper, during this call, use evas_object_clip_get(). after that, the old (object pointer) value will be lost. */
-   void                             (*calculate)(Evas_Object *o); /**< code to be run when object has rendering updates on a canvas */
-   void                             (*member_add)(Evas_Object *o, Evas_Object *child); /**< code to be run when a child member is added to object */
-   void                             (*member_del)(Evas_Object *o, Evas_Object *child); /**< code to be run when a child member is removed from object */
-
-   const Evas_Smart_Class          *parent; /**< this class inherits from this parent */
-   const Evas_Smart_Cb_Description *callbacks; /**< callbacks at this level, @c NULL terminated */
-   const Evas_Smart_Interface     **interfaces; /**< #Evas_Smart_Interface pointers array, @c NULL terminated. These will be the interfaces supported at this level for an object (parents may have others) @since 1.7 */
+   void                             (*add)(Evas_Object *o); /**< Code to be run when adding object to a canvas */
+   void                             (*del)(Evas_Object *o); /**< Code to be run when removing object from a canvas */
+   void                             (*move)(Evas_Object *o, Evas_Coord x, Evas_Coord y); /**< Code to be run when moving object on a canvas. @a x and @a y are new coordinates you apply to the object. Use evas_object_geometry_get() if you need the old values, during this call. After that, the old values are lost */
+   void                             (*resize)(Evas_Object *o, Evas_Coord w, Evas_Coord h); /**< Code to be run when resizing object on a canvas. @a w and @a h are new dimensions you apply to the object. Use evas_object_geometry_get() if you need the old values, during this call. After that, the old values are lost */
+   void                             (*show)(Evas_Object *o); /**< Code to be run when showing object on a canvas */
+   void                             (*hide)(Evas_Object *o); /**< Code to be run when hiding object on a canvas */
+   void                             (*color_set)(Evas_Object *o, int r, int g, int b, int a); /**< Code to be run when setting color of object on a canvas. @a r, @a g, @a b and @a y are new color components one applied to the object. Use evas_object_color_get() if you need the old values, during this call. After that, the old values are lost */
+   void                             (*clip_set)(Evas_Object *o, Evas_Object *clip); /**< Code to be run when setting clipper of object on a canvas. @a clip is a new clipper you apply to the object. Use evas_object_clip_get() if you need the old one, during this call. After that, the old (object pointer) value is lost */
+   void                             (*clip_unset)(Evas_Object *o); /**< Code to be run when unsetting clipper of object on a canvas. If you need the pointer to a previous set clipper, during this call, use evas_object_clip_get(). After that, the old (object pointer) value is lost */
+   void                             (*calculate)(Evas_Object *o); /**< Code to be run when object has rendering updates on a canvas */
+   void                             (*member_add)(Evas_Object *o, Evas_Object *child); /**< Code to be run when a child member is added to object */
+   void                             (*member_del)(Evas_Object *o, Evas_Object *child); /**< Code to be run when a child member is removed from object */
+
+   const Evas_Smart_Class          *parent; /**< This class inherits from this parent */
+   const Evas_Smart_Cb_Description *callbacks; /**< Callbacks at this level, @c NULL terminated */
+   const Evas_Smart_Interface     **interfaces; /**< #Evas_Smart_Interface pointers array, @c NULL terminated. These are the interfaces supported at this level for an object (parents may have others) @since 1.7 */
    const void                      *data;
 };
 
 /**
+ * @internal
  * @struct _Evas_Smart_Interface
  *
- * A smart object's @b base interface definition
+ * @brief   The structure type containing a smart object's @b base interface definition
+ * @since   1.7
  *
- * Every Evas interface must have a name field, pointing to a global,
- * constant string variable. This string pointer will be the only way
- * of retrieving back a given interface from a smart object. Two
- * function pointers must be defined, too, which will be called at
- * object creation and deletion times.
+ * @remarks Every Evas interface must have a name field, pointing to a global,
+ *          constant string variable. This string pointer is the only way
+ *          of retrieving back a given interface from a smart object. Two
+ *          function pointers must be defined, too, which is called at
+ *          object creation and deletion times.
  *
- * See also some @ref Example_Evas_Smart_Interfaces "examples" on
- * smart interfaces.
- *
- * @since 1.7
  *
  * @ingroup Evas_Smart_Group
  */
 struct _Evas_Smart_Interface
 {
    const char *name; /**< Name of the given interface */
-   unsigned    private_size; /**< Size, in bytes, of the interface's private dada blob. This will be allocated and freed automatically for you. Get it with evas_object_smart_interface_data_get(). */
-   Eina_Bool   (*add)(Evas_Object *obj); /**< Function to be called at object creation time. This will take place @b before the object's smart @c add() function. */
-   void        (*del)(Evas_Object *obj); /**< Function to be called at object deletion time. This will take place @b after the object's smart @c del() function. */
+   unsigned    private_size; /**< Size, in bytes, of the interface's private data blob. This is allocated and freed automatically for you. Get it with evas_object_smart_interface_data_get() */
+   Eina_Bool   (*add)(Evas_Object *obj); /**< Function to be called at object creation time. This takes place @b before the object's smart @c add() function */
+   void        (*del)(Evas_Object *obj); /**< Function to be called at object deletion time. This takes place @b after the object's smart @c del() function */
 };
 
 /**
+ * @internal
  * @struct _Evas_Smart_Cb_Description
  *
- * Describes a callback issued by a smart object
- * (evas_object_smart_callback_call()), as defined in its smart object
- * class. This is particularly useful to explain to end users and
- * their code (i.e., introspection) what the parameter @c event_info
- * will point to.
- *
- * @ingroup Evas_Smart_Group
+ * @brief The structure type that describes a callback issued by a smart object
+ *        (evas_object_smart_callback_call()), as defined in its smart object
+ *        class. This is particularly useful to explain to end users and
+ *        their code (i.e., introspection) what the parameter @a event_info
+ *        points to.
  */
 struct _Evas_Smart_Cb_Description
 {
    const char *name; /**< callback name ("changed", for example) */
 
    /**
-    * @brief Hint on the type of @c event_info parameter's contents on
-    * a #Evas_Smart_Cb callback.
+    * @brief Hint on the type of @a event_info parameter's contents on
+    *        a #Evas_Smart_Cb callback.
     *
-    * The type string uses the pattern similar to
-    * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-signatures,
-    * but extended to optionally include variable names within
-    * brackets preceding types. Example:
+    * @remarks The type string uses the pattern similar to
+    *          http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-signatures,
+    *          but extended to optionally include variable names within
+    *          brackets preceding types. Example:
     *
     * @li Structure with two integers:
     *     @c "(ii)"
@@ -9721,148 +11748,141 @@ struct _Evas_Smart_Cb_Description
     * @li Array called 'x' of struct with two integers:
     *     @c "[x]a(ii)"
     *
-    * @note This type string is used as a hint and is @b not validated
-    *       or enforced in any way. Implementors should make the best
-    *       use of it to help bindings, documentation and other users
-    *       of introspection features.
+    * @remarks This type string is used as a hint and is @b not validated
+    *          or enforced in any way. Implementors should make the best
+    *          use of it to help bindings, documentation and other users
+    *          of introspection features.
     */
    const char *type;
 };
 
 /**
  * @def EVAS_SMART_CLASS_INIT_NULL
- * Initializer to zero a whole Evas_Smart_Class structure.
+ * @brief Definition for initializing to zero a whole Evas_Smart_Class structure.
  *
  * @see EVAS_SMART_CLASS_INIT_VERSION
  * @see EVAS_SMART_CLASS_INIT_NAME_VERSION
  * @see EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT
  * @see EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT_CALLBACKS
- * @ingroup Evas_Smart_Group
  */
 #define EVAS_SMART_CLASS_INIT_NULL    {NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
 
 /**
  * @def EVAS_SMART_CLASS_INIT_VERSION
- * Initializer to zero a whole Evas_Smart_Class structure and set version.
+ * @brief Definition for initializing to zero a whole Evas_Smart_Class structure and set version.
  *
- * Similar to EVAS_SMART_CLASS_INIT_NULL, but will set version field to
- * latest EVAS_SMART_CLASS_VERSION.
+ * @remarks Similar to EVAS_SMART_CLASS_INIT_NULL, but sets version field to
+ *          latest EVAS_SMART_CLASS_VERSION.
  *
  * @see EVAS_SMART_CLASS_INIT_NULL
  * @see EVAS_SMART_CLASS_INIT_NAME_VERSION
  * @see EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT
  * @see EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT_CALLBACKS
- * @ingroup Evas_Smart_Group
  */
 #define EVAS_SMART_CLASS_INIT_VERSION {NULL, EVAS_SMART_CLASS_VERSION, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
 
 /**
  * @def EVAS_SMART_CLASS_INIT_NAME_VERSION
- * Initializer to zero a whole Evas_Smart_Class structure and set name
- * and version.
+ * @brief   Definition for initializing to zero a whole Evas_Smart_Class structure and set name
+ *          and version.
  *
- * Similar to EVAS_SMART_CLASS_INIT_NULL, but will set version field to
- * latest EVAS_SMART_CLASS_VERSION and name to the specified value.
+ * @remarks Similar to EVAS_SMART_CLASS_INIT_NULL, but sets version field to
+ *          latest EVAS_SMART_CLASS_VERSION and name to the specified value.
  *
- * It will keep a reference to name field as a "const char *", that is,
- * name must be available while the structure is used (hint: static or global!)
- * and will not be modified.
+ * @remarks It keeps a reference to name field as a "const char *", that is,
+ *          name must be available while the structure is used (hint: static or global!)
+ *          and is not modified.
  *
  * @see EVAS_SMART_CLASS_INIT_NULL
  * @see EVAS_SMART_CLASS_INIT_VERSION
  * @see EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT
  * @see EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT_CALLBACKS
- * @ingroup Evas_Smart_Group
  */
 #define EVAS_SMART_CLASS_INIT_NAME_VERSION(name)                                     {name, EVAS_SMART_CLASS_VERSION, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
 
 /**
  * @def EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT
- * Initializer to zero a whole Evas_Smart_Class structure and set name,
- * version and parent class.
+ * @brief   Definition for initializing to zero a whole Evas_Smart_Class structure and set name,
+ *          version and parent class.
  *
- * Similar to EVAS_SMART_CLASS_INIT_NULL, but will set version field to
- * latest EVAS_SMART_CLASS_VERSION, name to the specified value and
- * parent class.
+ * @remarks Similar to EVAS_SMART_CLASS_INIT_NULL, but sets version field to
+ *          latest EVAS_SMART_CLASS_VERSION, name to the specified value and
+ *          parent class.
  *
- * It will keep a reference to name field as a "const char *", that is,
- * name must be available while the structure is used (hint: static or global!)
- * and will not be modified. Similarly, parent reference will be kept.
+ * @remarks It keeps a reference to name field as a "const char *", that is,
+ *          name must be available while the structure is used (hint: static or global!)
+ *          and is not modified. Similarly, parent reference is kept.
  *
  * @see EVAS_SMART_CLASS_INIT_NULL
  * @see EVAS_SMART_CLASS_INIT_VERSION
  * @see EVAS_SMART_CLASS_INIT_NAME_VERSION
  * @see EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT_CALLBACKS
- * @ingroup Evas_Smart_Group
  */
 #define EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT(name, parent)                      {name, EVAS_SMART_CLASS_VERSION, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, parent, NULL, NULL}
 
 /**
  * @def EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT_CALLBACKS
- * Initializer to zero a whole Evas_Smart_Class structure and set name,
- * version, parent class and callbacks definition.
+ * @brief   Definition for initializing to zero a whole Evas_Smart_Class structure and set name,
+ *          version, parent class and callbacks definition.
  *
- * Similar to EVAS_SMART_CLASS_INIT_NULL, but will set version field to
- * latest EVAS_SMART_CLASS_VERSION, name to the specified value, parent
- * class and callbacks at this level.
+ * @remarks Similar to EVAS_SMART_CLASS_INIT_NULL, but sets version field to
+ *          latest EVAS_SMART_CLASS_VERSION, name to the specified value, parent
+ *          class and callbacks at this level.
  *
- * It will keep a reference to name field as a "const char *", that is,
- * name must be available while the structure is used (hint: static or global!)
- * and will not be modified. Similarly, parent and callbacks reference
- * will be kept.
+ * @remarks It keeps a reference to name field as a "const char *", that is,
+ *          name must be available while the structure is used (hint: static or global!)
+ *          and is not modified. Similarly, parent and callbacks reference
+ *          is kept.
  *
  * @see EVAS_SMART_CLASS_INIT_NULL
  * @see EVAS_SMART_CLASS_INIT_VERSION
  * @see EVAS_SMART_CLASS_INIT_NAME_VERSION
  * @see EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT
- * @ingroup Evas_Smart_Group
  */
 #define EVAS_SMART_CLASS_INIT_NAME_VERSION_PARENT_CALLBACKS(name, parent, callbacks) {name, EVAS_SMART_CLASS_VERSION, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, parent, callbacks, NULL}
 
 /**
  * @def EVAS_SMART_SUBCLASS_NEW
  *
- * Convenience macro to subclass a given Evas smart class.
- *
- * @param smart_name The name used for the smart class. e.g:
- * @c "Evas_Object_Box".
- * @param prefix Prefix used for all variables and functions defined
- * and referenced by this macro.
- * @param api_type Type of the structure used as API for the smart
- * class. Either #Evas_Smart_Class or something derived from it.
- * @param parent_type Type of the parent class API.
- * @param parent_func Function that gets the parent class. e.g:
- * evas_object_box_smart_class_get().
- * @param cb_desc Array of callback descriptions for this smart class.
- *
- * This macro saves some typing when writing a smart class derived
- * from another one. In order to work, the user @b must provide some
- * functions adhering to the following guidelines:
- *  - @<prefix@>_smart_set_user(): the @b internal @c _smart_set
- *    function (defined by this macro) will call this one, provided by
- *    the user, after inheriting everything from the parent, which
- *    should <b>take care of setting the right member functions for
- *    the class</b>, both overrides and extensions, if any.
- *  - If this new class should be subclassable as well, a @b public
- *    @c _smart_set() function is desirable to fill in the class used as
- *    parent by the children. It's up to the user to provide this
- *    interface, which will most likely call @<prefix@>_smart_set() to
- *    get the job done.
- *
- * After the macro's usage, the following will be defined for use:
- *  - @<prefix@>_parent_sc: A pointer to the @b parent smart
- *    class. When calling parent functions from overloaded ones, use
- *    this global variable.
- *  - @<prefix@>_smart_class_new(): this function returns the
- *    #Evas_Smart needed to create smart objects with this class,
- *    which should be passed to evas_object_smart_add().
- *
- * @warning @p smart_name has to be a pointer to a globally available
- * string! The smart class created here will just have a pointer set
- * to that, and all object instances will depend on it for smart class
- * name lookup.
- *
- * @ingroup Evas_Smart_Group
+ * @brief Convenience macro to subclass a given Evas smart class.
+ *
+ * @details This macro saves some typing when writing a smart class derived
+ *          from another one. In order to work, the user @b must provide some
+ *          functions adhering to the following guidelines:
+ *          - @<prefix@>_smart_set_user(): The @b internal @c _smart_set
+ *            function (defined by this macro) calls this one, provided by
+ *            the user, after inheriting everything from the parent, which
+ *            should <b>take care of setting the right member functions for
+ *            the class</b>, both overrides and extensions, if any.
+ *          - If this new class should be subclassable as well, a @b public
+ *            @c _smart_set() function is desirable to fill in the class used as
+ *            parent by the children. It is up to the user to provide this
+ *            interface, which most likely calls @<prefix@>_smart_set() to
+ *            get the job done.
+ *
+ *          After the macro's usage, the following are defined for use:
+ *          - @<prefix@>_parent_sc: A pointer to the @b parent smart
+ *            class. When calling parent functions from overloaded ones, use
+ *            this global variable.
+ *          - @<prefix@>_smart_class_new(): This function returns the
+ *            #Evas_Smart needed to create smart objects with this class,
+ *            which should be passed to evas_object_smart_add().
+ *
+ * @remarks @a smart_name has to be a pointer to a globally available
+ *          string. The smart class created here just has a pointer set
+ *          to that, and all object instances depend on it for smart class
+ *          name lookup.
+ *
+ * @param   smart_name   The name used for the smart class \n 
+ *                       For example, @c "Evas_Object_Box".
+ * @param   prefix       Prefix used for all variables and functions defined
+ *                       and referenced by this macro
+ * @param   api_type     Type of the structure used as API for the smart class \n
+ *                       Either #Evas_Smart_Class or something derived from it.
+ * @param   parent_type  Type of the parent class API
+ * @param   parent_func  Function that gets the parent class \n 
+ *                       For example, evas_object_box_smart_class_get().
+ * @param   cb_desc      Array of callback descriptions for this smart class
  */
 #define EVAS_SMART_SUBCLASS_NEW(smart_name, prefix, api_type, parent_type, parent_func, cb_desc) \
   static const parent_type * prefix##_parent_sc = NULL;                                          \
@@ -9897,55 +11917,51 @@ struct _Evas_Smart_Cb_Description
 /**
  * @def EVAS_SMART_SUBCLASS_IFACE_NEW
  *
- * @since 1.7
- *
- * Convenience macro to subclass a given Evas smart class. This is the
- * same as #EVAS_SMART_SUBCLASS_NEW, but now <b>declaring smart
- * interfaces</b> besides the smart callbacks.
- *
- * @param smart_name The name used for the smart class. e.g:
- *                   @c "Evas_Object_Box".
- * @param prefix Prefix used for all variables and functions defined
- *               and referenced by this macro.
- * @param api_type Type of the structure used as API for the smart
- *                 class. Either #Evas_Smart_Class or something
- *                 derived from it.
- * @param parent_type Type of the parent class API.
- * @param parent_func Function that gets the parent class. e.g:
- *                    evas_object_box_smart_class_get().
- * @param cb_desc Array of smart callback descriptions for this smart
- *                class.
- * @param ifaces Array of Evas smart interafaces for this smart
- *               class.
- *
- * This macro saves some typing when writing a smart class derived
- * from another one. In order to work, the user @b must provide some
- * functions adhering to the following guidelines:
- *  - @<prefix@>_smart_set_user(): the @b internal @c _smart_set
- *    function (defined by this macro) will call this one, provided by
- *    the user, after inheriting everything from the parent, which
- *    should <b>take care of setting the right member functions for
- *    the class</b>, both overrides and extensions, if any.
- *  - If this new class should be subclassable as well, a @b public
- *    @c _smart_set() function is desirable to fill in the class used as
- *    parent by the children. It's up to the user to provide this
- *    interface, which will most likely call @<prefix@>_smart_set() to
- *    get the job done.
- *
- * After the macro's usage, the following will be defined for use:
- *  - @<prefix@>_parent_sc: A pointer to the @b parent smart
- *    class. When calling parent functions from overloaded ones, use
- *    this global variable.
- *  - @<prefix@>_smart_class_new(): this function returns the
- *    #Evas_Smart needed to create smart objects with this class,
- *    which should be passed to evas_object_smart_add().
- *
- * @warning @p smart_name has to be a pointer to a globally available
- * string! The smart class created here will just have a pointer set
- * to that, and all object instances will depend on it for smart class
- * name lookup.
- *
- * @ingroup Evas_Smart_Group
+ * @brief   Convenience macro to subclass a given Evas smart class. This is the
+ *          same as #EVAS_SMART_SUBCLASS_NEW, but <b>declares smart
+ *          interfaces</b> besides the smart callbacks.
+ *
+ * @details This macro saves some typing when writing a smart class derived
+ *          from another one. In order to work, the user @b must provide some
+ *          functions adhering to the following guidelines:
+ *          - @<prefix@>_smart_set_user(): The @b internal @c _smart_set
+ *            function (defined by this macro) calls this one, provided by
+ *            the user, after inheriting everything from the parent, which
+ *            should <b>take care of setting the right member functions for
+ *            the class</b>, both overrides and extensions, if any.
+ *          - If this new class should be subclassable as well, a @b public
+ *            @c _smart_set() function is desirable to fill in the class used as
+ *            parent by the children. It is up to the user to provide this
+ *            interface, which most likely calls @<prefix@>_smart_set() to
+ *            get the job done.
+ *
+ *          After the macro's usage, the following is defined for use:
+ *          - @<prefix@>_parent_sc: A pointer to the @b parent smart
+ *            class. When calling parent functions from overloaded ones, use
+ *            this global variable.
+ *          - @<prefix@>_smart_class_new(): This function returns the
+ *            #Evas_Smart needed to create smart objects with this class,
+ *            which should be passed to evas_object_smart_add().
+ *
+ * @since   1.7
+ *
+ * @remarks @a smart_name has to be a pointer to a globally available
+ *          string. The smart class created here just has a pointer set
+ *          to that, and all object instances depend on it for smart class
+ *          name lookup.
+ *
+ * @param   smart_name   The name used for the smart class \n 
+ *                       For example, @c "Evas_Object_Box".
+ * @param   prefix       Prefix used for all variables and functions defined
+ *                       and referenced by this macro
+ * @param   api_type     Type of the structure used as API for the smart class
+ *                       Either #Evas_Smart_Class or something
+ *                       derived from it.
+ * @param   parent_type  Type of the parent class API
+ * @param   parent_func  Function that gets the parent class \n 
+ *                       For example, evas_object_box_smart_class_get().
+ * @param   cb_desc      Array of smart callback descriptions for this smart class
+ * @param   ifaces       Array of Evas smart interfaces for this smart class
  */
 #define EVAS_SMART_SUBCLASS_IFACE_NEW(smart_name,          \
                                       prefix,              \
@@ -9987,21 +12003,19 @@ struct _Evas_Smart_Cb_Description
 /**
  * @def EVAS_SMART_DATA_ALLOC
  *
- * Convenience macro to allocate smart data only if needed.
- *
- * When writing a subclassable smart object, the @c .add() function
- * will need to check if the smart private data was already allocated
- * by some child object or not. This macro makes it easier to do it.
+ * @brief Convenience macro to allocate smart data only if needed.
  *
- * @note This is an idiom used when one calls the parent's @c .add()
- * after the specialized code. Naturally, the parent's base smart data
- * has to be contemplated as the specialized one's first member, for
- * things to work.
+ * @remarks When writing a subclassable smart object, the @c .add() function
+ *          needs to check if the smart private data is already allocated
+ *          by some child object or not. This macro makes it easier to do it.
  *
- * @param o Evas object passed to the @c .add() function
- * @param priv_type The type of the data to allocate
+ * @remarks This is an idiom used when one calls the parent's @c .add()
+ *          after the specialized code. Naturally, the parent's base smart data
+ *          has to be contemplated as the specialized one's first member, for
+ *          things to work.
  *
- * @ingroup Evas_Smart_Group
+ * @param   o          The Evas object passed to the @c .add() function
+ * @param   priv_type  The type of the data to allocate
  */
 #define EVAS_SMART_DATA_ALLOC(o, priv_type)              \
   priv_type * priv;                                      \
@@ -10013,160 +12027,194 @@ struct _Evas_Smart_Cb_Description
     }
 
 /**
- * Free an #Evas_Smart struct
+ * @brief   Frees an #Evas_Smart struct.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param s the #Evas_Smart struct to free
+ * @remarks If this smart handle is created using evas_smart_class_new(),
+ *          the associated #Evas_Smart_Class is not freed.
  *
- * @warning If this smart handle was created using
- * evas_smart_class_new(), the associated #Evas_Smart_Class will not
- * be freed.
+ * @remarks If you are using the #EVAS_SMART_SUBCLASS_NEW schema to create your
+ *          smart object, note that an #Evas_Smart handle is shared amongst all
+ *          instances of the given smart class, through a static variable.
+ *          Evas internally counts references on #Evas_Smart handles and free them
+ *          when they are not referenced any more. Thus, this function is mostly of no use
+ *          for Evas users.
  *
- * @note If you're using the #EVAS_SMART_SUBCLASS_NEW schema to create your
- * smart object, note that an #Evas_Smart handle will be shared amongst all
- * instances of the given smart class, through a static variable.
- * Evas will internally count references on #Evas_Smart handles and free them
- * when they are not referenced anymore. Thus, this function is of no use
- * for Evas users, most probably.
+ * @param[in]   s  The #Evas_Smart struct to free
  */
 EAPI void                              evas_smart_free(Evas_Smart *s) EINA_ARG_NONNULL(1);
 
 /**
- * Creates a new #Evas_Smart from a given #Evas_Smart_Class struct
+ * @brief   Creates a new #Evas_Smart from a given #Evas_Smart_Class struct.
  *
- * @param sc the smart class definition
- * @return a new #Evas_Smart pointer
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * #Evas_Smart handles are necessary to create new @b instances of
- * smart objects belonging to the class described by @p sc. That
- * handle will contain, besides the smart class interface definition,
- * all its smart callbacks infrastructure set, too.
+ * @remarks #Evas_Smart handles are necessary to create new @b instances of
+ *          smart objects belonging to the class described by @a sc. That
+ *          handle contains, besides the smart class interface definition,
+ *          all its smart callbacks infrastructure set, too.
  *
- * @note If you are willing to subclass a given smart class to
- * construct yours, consider using the #EVAS_SMART_SUBCLASS_NEW macro,
- * which will make use of this function automatically for you.
+ * @remarks If you are willing to subclass a given smart class to
+ *          construct yours, consider using the #EVAS_SMART_SUBCLASS_NEW macro,
+ *          which makes use of this function automatically for you.
+ *
+ * @param[in]   sc  The smart class definition
+ * @return  A new #Evas_Smart pointer
  */
 EAPI Evas_Smart                       *evas_smart_class_new(const Evas_Smart_Class *sc) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Get the #Evas_Smart_Class handle of an #Evas_Smart struct
+ * @brief   Gets the #Evas_Smart_Class handle of an #Evas_Smart struct.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param s a valid #Evas_Smart pointer
- * @return the #Evas_Smart_Class in it
+ * @param[in]   s  A valid #Evas_Smart pointer
+ * @return  The #Evas_Smart_Class
  */
 EAPI const Evas_Smart_Class           *evas_smart_class_get(const Evas_Smart *s) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * @brief Get the data pointer set on an #Evas_Smart struct
+ * @brief   Gets the data pointer set on an #Evas_Smart struct.
  *
- * @param s a valid #Evas_Smart handle
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This data pointer is set as the data field in the #Evas_Smart_Class
- * passed in to evas_smart_class_new().
+ * @remarks This data pointer is set as the data field in the #Evas_Smart_Class
+ *          passed in to evas_smart_class_new().
+ *
+ * @param[in]   s  A valid #Evas_Smart handle
  */
 EAPI void                             *evas_smart_data_get(const Evas_Smart *s) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Get the smart callbacks known by this #Evas_Smart handle's smart
- * class hierarchy.
+ * @brief   Gets the smart callbacks known by this #Evas_Smart handle's smart
+ *          class hierarchy.
+ *
+ * @details This function is likely different from
+ *          evas_object_smart_callbacks_descriptions_get() as it contains
+ *          the callbacks of @b all this class hierarchy sorted, while the
+ *          direct smart class member refers only to that specific class and
+ *          should not include the parent's.
  *
- * @param s A valid #Evas_Smart handle.
- * @param[out] count Returns the number of elements in the returned
- * array.
- * @return The array with callback descriptions known by this smart
- *         class, with its size returned in @a count parameter. It
- *         should not be modified in any way. If no callbacks are
- *         known, @c NULL is returned. The array is sorted by event
- *         names and elements refer to the original values given to
- *         evas_smart_class_new()'s Evas_Smart_Class::callbacks
- *         (pointer to them).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This is likely different from
- * evas_object_smart_callbacks_descriptions_get() as it will contain
- * the callbacks of @b all this class hierarchy sorted, while the
- * direct smart class member refers only to that specific class and
- * should not include parent's.
+ * @remarks If no callbacks are known, this function returns @c NULL.
  *
- * If no callbacks are known, this function returns @c NULL.
+ * @remarks The array elements and thus their contents are @b references to
+ *          original values given to evas_smart_class_new() as
+ *          Evas_Smart_Class::callbacks.
  *
- * The array elements and thus their contents will be @b references to
- * original values given to evas_smart_class_new() as
- * Evas_Smart_Class::callbacks.
+ * @remarks The array is sorted by Evas_Smart_Cb_Description::name. The last
+ *          array element is a @c NULL pointer and is not accounted for in @a
+ *          count. Loop iterations can check any of these size indicators.
  *
- * The array is sorted by Evas_Smart_Cb_Description::name. The last
- * array element is a @c NULL pointer and is not accounted for in @a
- * count. Loop iterations can check any of these size indicators.
+ * @remarks Objects may provide per-instance callbacks. Use
+ *          evas_object_smart_callbacks_descriptions_get() to get those
+ *          as well.
+ *
+ * @param[in]       s      A valid #Evas_Smart handle.
+ * @param[out]  count  The number of elements in the returned array
+ * @return      The array with callback descriptions known by this smart
+ *              class, with its size returned in @a count parameter \n 
+ *              It should not be modified in any way. If no callbacks are
+ *              known, @c NULL is returned. The array is sorted by event
+ *              names and elements refer to the original values given to
+ *              evas_smart_class_new()'s Evas_Smart_Class::callbacks
+ *              (pointer to them).
  *
- * @note objects may provide per-instance callbacks, use
- *       evas_object_smart_callbacks_descriptions_get() to get those
- *       as well.
  * @see evas_object_smart_callbacks_descriptions_get()
  */
 EAPI const Evas_Smart_Cb_Description **evas_smart_callbacks_descriptions_get(const Evas_Smart *s, unsigned int *count) EINA_ARG_NONNULL(1, 1);
 
 /**
- * Find a callback description for the callback named @a name.
+ * @brief   Finds a callback description for the callback named @a name.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param s The #Evas_Smart where to search for class registered smart
- * event callbacks.
- * @param name Name of the desired callback, which must @b not be @c
- *        NULL. The search has a special case for @a name being the
- *        same pointer as registered with #Evas_Smart_Cb_Description.
- *        One can use it to avoid excessive use of strcmp().
- * @return A reference to the description if found, or @c NULL, otherwise
+ * @param[in]   s     The #Evas_Smart where to search for class registered smart
+ *                event callbacks
+ * @param[in]   name  The name of the desired callback, which must @b not be @c
+ *                NULL. The search has a special case for @a name being the
+ *                same pointer as registered with #Evas_Smart_Cb_Description.
+ *                You can use it to avoid excessive use of strcmp().
+ * @return  A reference to the description if found, \n
+ *          otherwise @c NULL if no description is found
  *
  * @see evas_smart_callbacks_descriptions_get()
  */
 EAPI const Evas_Smart_Cb_Description  *evas_smart_callback_description_find(const Evas_Smart *s, const char *name) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Sets one class to inherit from the other.
+ * brief    Sets one class to inherit from the other.
  *
- * Copy all function pointers, set @c parent to @a parent_sc and copy
- * everything after sizeof(Evas_Smart_Class) present in @a parent_sc,
- * using @a parent_sc_size as reference.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *          everything after sizeof(Evas_Smart_Class) present in @a parent_sc,
+ *          using @a parent_sc_size as reference.
  *
- * This is recommended instead of a single memcpy() since it will take
- * care to not modify @a sc name, version, callbacks and possible
- * other members.
+ * @remarks This is recommended instead of a single memcpy() since it takes
+ *          care to not modify @a sc name, version, callbacks and possible
+ *          other members.
  *
- * @param sc child class.
- * @param parent_sc parent class, will provide attributes.
- * @param parent_sc_size size of parent_sc structure, child should be at least
- *        this size. Everything after @c Evas_Smart_Class size is copied
- *        using regular memcpy().
+ * @param[in]   sc              The child class
+ * @param[in]   parent_sc       The parent class, provides attributes
+ * @param[in]   parent_sc_size  The size of parent_sc structure \n
+ *                          The child should be at least this size. \n
+ *                          Everything after @c Evas_Smart_Class size is copied
+ *                          using regular memcpy().
  */
 EAPI Eina_Bool                         evas_smart_class_inherit_full(Evas_Smart_Class *sc, const Evas_Smart_Class *parent_sc, unsigned int parent_sc_size) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Get the number of users of the smart instance
+ * @brief   Gets the number of users of the smart instance.
  *
- * @param s The Evas_Smart to get the usage count of
- * @return The number of uses of the smart instance
+ * @details This function tells you how many more uses of the smart instance are in
+ *          existence. This should be used before freeing or clearing any of the
+ *          Evas_Smart_Class that is used to create the smart instance. The smart
+ *          instance refers to data in the Evas_Smart_Class used to create it and
+ *          thus you cannot remove the original data until all users of it are gone.
+ *          When the usage count goes to @c 0, you can evas_smart_free() the smart
+ *          instance @a s and remove from memory any of the Evas_Smart_Class that
+ *          is used to create the smart instance, if you desire. Removing it from
+ *          memory without doing this causes problems (crashes, undefined
+ *          behavior, and so on). So either never remove the original
+ *          Evas_Smart_Class data from memory (have it be a constant structure and
+ *          data), or use this API call and be very careful.
  *
- * This function tells you how many more uses of the smart instance are in
- * existence. This should be used before freeing/clearing any of the
- * Evas_Smart_Class that was used to create the smart instance. The smart
- * instance will refer to data in the Evas_Smart_Class used to create it and
- * thus you cannot remove the original data until all users of it are gone.
- * When the usage count goes to 0, you can evas_smart_free() the smart
- * instance @p s and remove from memory any of the Evas_Smart_Class that
- * was used to create the smart instance, if you desire. Removing it from
- * memory without doing this will cause problems (crashes, undefined
- * behavior etc. etc.), so either never remove the original
- * Evas_Smart_Class data from memory (have it be a constant structure and
- * data), or use this API call and be very careful.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   s  The Evas_Smart to get the usage count of
+ * @return  The number of uses of the smart instance
  */
 EAPI int                               evas_smart_usage_get(const Evas_Smart *s);
 
 /**
  * @def evas_smart_class_inherit
- * Easy to use version of evas_smart_class_inherit_full().
+ * @brief   Easy to use version of evas_smart_class_inherit_full().
  *
- * This version will use sizeof(parent_sc), copying everything.
+ * @remarks This version uses sizeof(parent_sc), copying everything.
  *
- * @param sc child class, will have methods copied from @a parent_sc
- * @param parent_sc parent class, will provide contents to be copied.
- * @return 1 on success, 0 on failure.
+ * @param   sc         The child class \n 
+ *                     It has methods copied from @a parent_sc.
+ * @param   parent_sc  The parent class \n 
+ *                     It provides contents to be copied.
+ * @return  @c 1 if everything is copied successfully, \n
+ *          otherwise @c 0 on failure
  * @ingroup Evas_Smart_Group
  */
 #define evas_smart_class_inherit(sc, parent_sc) evas_smart_class_inherit_full(sc, (Evas_Smart_Class *)parent_sc, sizeof(*parent_sc))
@@ -10177,19 +12225,20 @@ EAPI int                               evas_smart_usage_get(const Evas_Smart *s)
 
 /**
  * @defgroup Evas_Smart_Object_Group Smart Object Functions
+   @ingroup Evas_Object_Group
  *
- * Functions dealing with Evas smart objects (instances).
+ * @brief This group provides functions dealing with Evas smart objects (instances).
  *
  * Smart objects are groupings of primitive Evas objects that behave
  * as a cohesive group. For instance, a file manager icon may be a
- * smart object composed of an image object, a text label and two
+ * smart object composed of an image object, a text label, and two
  * rectangles that appear behind the image and text when the icon is
  * selected. As a smart object, the normal Evas object API could be
  * used on the icon object.
  *
  * Besides that, generally smart objects implement a <b>specific
  * API</b>, so that users interact with its own custom features. The
- * API takes form of explicit exported functions one may call and
+ * API takes the form of explicit exported functions one may call and
  * <b>smart callbacks</b>.
  *
  * @section Evas_Smart_Object_Group_Callbacks Smart events and callbacks
@@ -10198,73 +12247,79 @@ EAPI int                               evas_smart_usage_get(const Evas_Smart *s)
  * inside of them to be reported back to their users via callback
  * functions (smart callbacks). This way, you can extend Evas' own
  * object events. They are defined by an <b>event string</b>, which
- * identifies them uniquely. There's also a function prototype
- * definition for the callback functions: #Evas_Smart_Cb.
+ * identifies them uniquely. There is also a function prototype
+ * definition for the callback functions: Evas_Smart_Cb.
  *
  * When defining an #Evas_Smart_Class, smart object implementors are
  * strongly encouraged to properly set the Evas_Smart_Class::callbacks
  * callbacks description array, so that the users of the smart object
  * can have introspection on its events API <b>at run time</b>.
  *
- * See some @ref Example_Evas_Smart_Objects "examples" of this group
- * of functions.
- *
+ * @internal
  * @see @ref Evas_Smart_Group for class definitions.
- */
-
-/**
- * @addtogroup Evas_Smart_Object_Group
+ * @endinternal
+ *
  * @{
  */
 
 /**
- * Instantiates a new smart object described by @p s.
+ * @brief   Instantiates a new smart object described by @a s.
  *
- * @param e the canvas on which to add the object
- * @param s the #Evas_Smart describing the smart object
- * @return a new #Evas_Object handle
+ * @details This is the function that you should use when defining the public
+ *          function @b adding an instance of the new smart object to a given
+ *          canvas.
+ *          @internal
+ *          It takes care of setting all of its internals to work
+ *          as they should, if the user set things properly, like
+ *          #EVAS_SMART_SUBCLASS_NEW, for example.
+ *          @endinternal
  *
- * This is the function one should use when defining the public
- * function @b adding an instance of the new smart object to a given
- * canvas. It will take care of setting all of its internals to work
- * as they should, if the user set things properly, as seem on the
- * #EVAS_SMART_SUBCLASS_NEW, for example.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @ingroup Evas_Smart_Object_Group
+ * @param[in]   e  The canvas on which to add the object
+ * @param[in]   s  The #Evas_Smart describing the smart object
+ * @return  A new #Evas_Object handle
  */
 EAPI Evas_Object *evas_object_smart_add(Evas *e, Evas_Smart *s) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2) EINA_MALLOC;
 
 /**
- * Set an Evas object as a member of a given smart object.
+ * @brief   Sets an Evas object as a member of a given smart object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj The member object
- * @param smart_obj The smart object
+ * @remarks Members are automatically stacked and layered together with the
+ *          smart object. The various stacking functions operate on
+ *          members relative to the other members instead of the entire canvas,
+ *          since they now live on an exclusive layer (see
+ *          evas_object_stack_above(), for more details).
  *
- * Members will automatically be stacked and layered together with the
- * smart object. The various stacking functions will operate on
- * members relative to the other members instead of the entire canvas,
- * since they now live on an exclusive layer (see
- * evas_object_stack_above(), for more details).
+ * @remarks Any @a smart_obj object's specific implementation of the @c
+ *          member_add() smart function takes place too, naturally.
  *
- * Any @p smart_obj object's specific implementation of the @c
- * member_add() smart function will take place too, naturally.
+ * @param[in]   obj        The member object
+ * @param[in]   smart_obj  The smart object
  *
  * @see evas_object_smart_member_del()
  * @see evas_object_smart_members_get()
- *
- * @ingroup Evas_Smart_Object_Group
  */
 EAPI void         evas_object_smart_member_add(Evas_Object *obj, Evas_Object *smart_obj) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Removes a member object from a given smart object.
+ * @brief   Removes a member object from a given smart object.
  *
- * @param obj the member object
- * @ingroup Evas_Smart_Object_Group
+ * @details This function removes a member object from a smart object, if it is added
+ *          to any. The object is still on the canvas, but no longer
+ *          associated with whichever smart object it is associated with.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This removes a member object from a smart object, if it was added
- * to any. The object will still be on the canvas, but no longer
- * associated with whichever smart object it was associated with.
+ * @param[in]   obj  The member object
  *
  * @see evas_object_smart_member_add() for more details
  * @see evas_object_smart_members_get()
@@ -10272,16 +12327,19 @@ EAPI void         evas_object_smart_member_add(Evas_Object *obj, Evas_Object *sm
 EAPI void         evas_object_smart_member_del(Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieves the list of the member objects of a given Evas smart
- * object
+ * @brief   Gets the list of the member objects of a given Evas smart object.
+ * @since   1.7
  *
- * @param obj the smart object to get members from
- * @return Returns the list of the member objects of @p obj.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * The returned list should be freed with @c eina_list_free() when you
- * no longer need it.
+ * @remarks The returned list should be freed with @c eina_list_free() when you
+ *          no longer need it.
  *
- * @since 1.7 This function will return @c NULL when a non-smart object is passed.
+ * @param[in]   obj  The smart object to get members from
+ * @return  The list of the member objects of @a obj, \n
+ *          otherwise @c NULL when a non-smart object is passed
  *
  * @see evas_object_smart_member_add()
  * @see evas_object_smart_member_del()
@@ -10289,52 +12347,61 @@ EAPI void         evas_object_smart_member_del(Evas_Object *obj) EINA_ARG_NONNUL
 EAPI Eina_List   *evas_object_smart_members_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Gets the parent smart object of a given Evas object, if it has one.
+ * @brief   Gets the parent smart object of a given Evas object, if it has one.
  *
- * @param obj the Evas object you want to get the parent smart object
- * from
- * @return Returns the parent smart object of @a obj or @c NULL, if @a
- * obj is not a smart member of any
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @ingroup Evas_Smart_Object_Group
+ * @param[in]   obj  The Evas object to get the parent smart object from
+ * @return  The parent smart object of @a obj \n
+ *          otherwise @c NULL if @a obj is not a smart member of any Evas object
  */
 EAPI Evas_Object *evas_object_smart_parent_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Checks whether a given smart object or any of its smart object
- * parents is of a given smart class.
+ * @brief   Checks whether a given smart object or any of its smart object
+ *          parents is of a given smart class.
  *
- * @param obj An Evas smart object to check the type of
- * @param type The @b name (type) of the smart class to check for
- * @return @c EINA_TRUE, if @a obj or any of its parents is of type @a
- * type, @c EINA_FALSE otherwise
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * If @p obj is not a smart object, this call will fail
- * immediately. Otherwise, make sure evas_smart_class_inherit() or its
- * sibling functions were used correctly when creating the smart
- * object's class, so it has a valid @b parent smart class pointer
- * set.
+ * @remarks If @a obj is not a smart object, this call fails
+ *          immediately. Otherwise, make sure evas_smart_class_inherit() or its
+ *          sibling functions were used correctly when creating the smart
+ *          object's class, so it has a valid @b parent smart class pointer set.
  *
- * The checks use smart classes names and <b>string
- * comparison</b>. There is a version of this same check using
- * <b>pointer comparison</b>, since a smart class' name is a single
- * string in Evas.
+ * @remarks The checks use smart classes names and <b>string
+ *          comparison</b>. There is a version of this same check using
+ *          <b>pointer comparison</b>, since a smart class' name is a single
+ *          string in Evas.
  *
- * @see evas_object_smart_type_check_ptr()
- * @see #EVAS_SMART_SUBCLASS_NEW
+ * @param[in]   obj   An Evas smart object to check the type of
+ * @param[in]   type  The @b name (type) of the smart class to check for
+ * @return  #EINA_TRUE if @a obj or any of its parents is of type @a type, \n
+ *          otherwise #EINA_FALSE
  *
- * @ingroup Evas_Smart_Object_Group
+ * @internal
+ * @see #EVAS_SMART_SUBCLASS_NEW
+ * @endinternal
  */
 EAPI Eina_Bool    evas_object_smart_type_check(const Evas_Object *obj, const char *type) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
 
 /**
- * Checks whether a given smart object or any of its smart object
- * parents is of a given smart class, <b>using pointer comparison</b>.
+ * @internal
+ * @brief   Checks whether a given smart object or any of its smart object
+ *          parents is of a given smart class, <b>using pointer comparison</b>.
  *
- * @param obj An Evas smart object to check the type of
- * @param type The type (name string) to check for. Must be the name
- * @return @c EINA_TRUE, if @a obj or any of its parents is of type @a
- * type, @c EINA_FALSE otherwise
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj   An Evas smart object to check the type of
+ * @param[in]   type  The type (name string) to check for \n
+ *                Must be the name.
+ * @return  #EINA_TRUE if @a obj or any of its parents is of type @a type, \n
+ *          otherwise #EINA_FALSE
  *
  * @see evas_object_smart_type_check() for more details
  *
@@ -10343,417 +12410,465 @@ EAPI Eina_Bool    evas_object_smart_type_check(const Evas_Object *obj, const cha
 EAPI Eina_Bool    evas_object_smart_type_check_ptr(const Evas_Object *obj, const char *type) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
 
 /**
- * Get the #Evas_Smart from which @p obj smart object was created.
+ * @internal
+ * @brief   Gets the #Evas_Smart from which @a obj smart object is created.
  *
- * @param obj a smart object
- * @return the #Evas_Smart handle or @c NULL, on errors
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @ingroup Evas_Smart_Object_Group
+ * @param[in]   obj  A smart object
+ * @return  The #Evas_Smart handle, \n 
+ *          otherwise @c NULL on errors
  */
 EAPI Evas_Smart  *evas_object_smart_smart_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve user data stored on a given smart object.
+ * @brief   Gets the user data stored on a given smart object.
  *
- * @param obj The smart object's handle
- * @return A pointer to data stored using
- *         evas_object_smart_data_set(), or @c NULL, if none has been
- *         set.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @see evas_object_smart_data_set()
+ * @param[in]   obj  The smart object's handle
+ * @return  A pointer to data stored using evas_object_smart_data_set(), \n
+ *          otherwise @c NULL if none has been set
  *
- * @ingroup Evas_Smart_Object_Group
+ * @see evas_object_smart_data_set()
  */
 EAPI void        *evas_object_smart_data_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Store a pointer to user data for a given smart object.
+ * @brief   Sets a pointer to the user data for a given smart object.
  *
- * @param obj The smart object's handle
- * @param data A pointer to user data
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This data is stored @b independently of the one set by
- * evas_object_data_set(), naturally.
+ * @remarks This data is stored @b independently of the one set by
+ *          evas_object_data_set(), naturally.
  *
- * @see evas_object_smart_data_get()
+ * @param[in]   obj   The smart object's handle
+ * @param[in]   data  A pointer to user data
  *
- * @ingroup Evas_Smart_Object_Group
+ * @see evas_object_smart_data_get()
  */
 EAPI void         evas_object_smart_data_set(Evas_Object *obj, void *data) EINA_ARG_NONNULL(1);
 
 /**
- * Add (register) a callback function to the smart event specified by
- * @p event on the smart object @p obj.
+ * @brief   Adds or registers a callback function to the smart event specified by
+ *          @a event on the smart object @a obj.
  *
- * @param obj a smart object
- * @param event the event's name string
- * @param func the callback function
- * @param data user data to be passed to the callback function
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Smart callbacks look very similar to Evas callbacks, but are
- * implemented as smart object's custom ones.
+ * @remarks Smart callbacks look very similar to Evas callbacks, but are
+ *          implemented as smart object's custom ones.
  *
- * This function adds a function callback to an smart object when the
- * event named @p event occurs in it. The function is @p func.
+ * @remarks This function adds a function callback to an smart object when the
+ *          event named @a event occurs in it. The function is @a func.
  *
- * In the event of a memory allocation error during addition of the
- * callback to the object, evas_alloc_error() should be used to
- * determine the nature of the error, if any, and the program should
- * sensibly try and recover.
+ * @remarks In the event of a memory allocation error during addition of the
+ *          callback to the object.
  *
- * A smart callback function must have the ::Evas_Smart_Cb prototype
- * definition. The first parameter (@p data) in this definition will
- * have the same value passed to evas_object_smart_callback_add() as
- * the @p data parameter, at runtime. The second parameter @p obj is a
- * handle to the object on which the event occurred. The third
- * parameter, @p event_info, is a pointer to data which is totally
- * dependent on the smart object's implementation and semantic for the
- * given event.
+ * @remarks A smart callback function must have the ::Evas_Smart_Cb prototype
+ *          definition. The first parameter (@a data) in this definition
+ *          has the same value passed to evas_object_smart_callback_add() as
+ *          the @a data parameter, at runtime. The second parameter @a obj is a
+ *          handle to the object on which the event occurred. The third
+ *          parameter, @a event_info, is a pointer to data which is totally
+ *          dependent on the smart object's implementation and semantic for the
+ *          given event.
  *
- * There is an infrastructure for introspection on smart objects'
- * events (see evas_smart_callbacks_descriptions_get()), but no
- * internal smart objects on Evas implement them yet.
+ * @remarks There is an infrastructure for introspection on smart objects'
+ *          events, but no internal smart objects on Evas implement them yet.
+ *
+ * @remarks The event's name strings are implemented by each smart object.
+ *          Please refer the documentation of a smart object which you are
+ *          insterested in.
+ *
+ * @param[in]   obj    A smart object
+ * @param[in]   event  The event's name string
+ * @param[in]   func   The callback function
+ * @param[in]   data   The user data to be passed to the callback function
  *
  * @see @ref Evas_Smart_Object_Group_Callbacks for more details.
  *
  * @see evas_object_smart_callback_del()
- * @ingroup Evas_Smart_Object_Group
  */
 EAPI void         evas_object_smart_callback_add(Evas_Object *obj, const char *event, Evas_Smart_Cb func, const void *data) EINA_ARG_NONNULL(1, 2, 3);
 
 /**
- * Add (register) a callback function to the smart event specified by
- * @p event on the smart object @p obj. Except for the priority field,
- * it's exactly the same as @ref evas_object_smart_callback_add
+ * @internal
+ * @brief   Adds or registers a callback function to the smart event specified by
+ *          @a event on the smart object @a obj.
+ *
+ * @details Except for the priority field, it is exactly the same as @ref evas_object_smart_callback_add.
+ * @since   1.1
  *
- * @param obj a smart object
- * @param event the event's name string
- * @param priority The priority of the callback, lower values called first.
- * @param func the callback function
- * @param data user data to be passed to the callback function
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   obj       A smart object
+ * @param[in]   event     The event's name string
+ * @param[in]   priority  The priority of the callback \n
+ *                    Lower values are called first.
+ * @param[in]   func      The callback function
+ * @param[in]   data      The user data to be passed to the callback function
  *
  * @see evas_object_smart_callback_add
- * @since 1.1
- * @ingroup Evas_Smart_Object_Group
  */
 EAPI void         evas_object_smart_callback_priority_add(Evas_Object *obj, const char *event, Evas_Callback_Priority priority, Evas_Smart_Cb func, const void *data);
 
 /**
- * Delete (unregister) a callback function from the smart event
- * specified by @p event on the smart object @p obj.
+ * @brief   Deletes or unregisters a callback function from the smart event
+ *          specified by @a event on the smart object @a obj.
  *
- * @param obj a smart object
- * @param event the event's name string
- * @param func the callback function
- * @return the data pointer
+ * @details This function removes <b>the first</b> added smart callback on the
+ *          object @a obj matching the event name @a event and the registered
+ *          function pointer @a func. If the removal is successful it also
+ *          returns the data pointer that is passed to
+ *          evas_object_smart_callback_add() (that is the same as the
+ *          parameter) when the callback(s) is(are) added to the canvas.
  *
- * This function removes <b>the first</b> added smart callback on the
- * object @p obj matching the event name @p event and the registered
- * function pointer @p func. If the removal is successful it will also
- * return the data pointer that was passed to
- * evas_object_smart_callback_add() (that will be the same as the
- * parameter) when the callback(s) was(were) added to the canvas. If
- * not successful @c NULL will be returned.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @see evas_object_smart_callback_add() for more details.
+ * @param[in]   obj    A smart object
+ * @param[in]   event  The event's name string
+ * @param[in]   func   The callback function
+ * @return  The data pointer, \n
+ *          otherwise @c NULL if it is not successful
  *
- * @ingroup Evas_Smart_Object_Group
+ * @see evas_object_smart_callback_add() for more details.
  */
 EAPI void        *evas_object_smart_callback_del(Evas_Object *obj, const char *event, Evas_Smart_Cb func) EINA_ARG_NONNULL(1, 2, 3);
 
 /**
- * Delete (unregister) a callback function from the smart event
- * specified by @p event on the smart object @p obj.
+ * @brief   Deletes or unregisters a callback function from the smart event
+ *          specified by @a event on the smart object @a obj.
  *
- * @param obj a smart object
- * @param event the event's name string
- * @param func the callback function
- * @param data the data pointer that was passed to the callback
- * @return the data pointer
+ * @details This function removes <b>the first</b> added smart callback on the
+ *          object @a obj matching the event name @a event, the registered
+ *          function pointer @a func and the callback data pointer @a data. If
+ *          the removal is successful, it also returns the data pointer that
+ *          is passed to evas_object_smart_callback_add() (that is the same
+ *          as the parameter) when the callback(s) is(are) added to the canvas.
+ *          If not successful @c NULL is returned. A common use would be to
+ *          remove an exact match of a callback
+ * @since   1.2
  *
- * This function removes <b>the first</b> added smart callback on the
- * object @p obj matching the event name @p event, the registered
- * function pointer @p func and the callback data pointer @p data. If
- * the removal is successful it will also return the data pointer that
- * was passed to evas_object_smart_callback_add() (that will be the same
- * as the parameter) when the callback(s) was(were) added to the canvas.
- * If not successful @c NULL will be returned. A common use would be to
- * remove an exact match of a callback
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @see evas_object_smart_callback_add() for more details.
- * @since 1.2
- * @ingroup Evas_Smart_Object_Group
+ * @remarks To delete all smart event callbacks which match @a type and @a func,
+ *          use evas_object_smart_callback_del().
+ *
+ * @param[in]   obj    A smart object
+ * @param[in]   event  The event's name string
+ * @param[in]   func   The callback function
+ * @param[in]   data   The data pointer that is passed to the callback
+ * @return  The data pointer
  *
- * @note To delete all smart event callbacks which match @p type and @p func,
- * use evas_object_smart_callback_del().
+ * @see evas_object_smart_callback_add() for more details.
  */
 EAPI void        *evas_object_smart_callback_del_full(Evas_Object *obj, const char *event, Evas_Smart_Cb func, const void *data) EINA_ARG_NONNULL(1, 2, 3);
 
 /**
- * Call a given smart callback on the smart object @p obj.
+ * @brief   Calls a given smart callback on the smart object @a obj.
  *
- * @param obj the smart object
- * @param event the event's name string
- * @param event_info pointer to an event specific struct or information to
- * pass to the callback functions registered on this smart event
+ * @details This function should be called @b internally, from the smart object's own
+ *          code, when some specific event has occurred and the implementor
+ *          wants to listen to the object's events API (see @ref
+ *          Evas_Smart_Object_Group_Callbacks). The documentation for the smart
+ *          object should include a list of possible events and what type of @a
+ *          event_info to expect for each of them. Also, when defining an
+ *          #Evas_Smart_Class, smart object implementors are strongly
+ *          encouraged to properly set the Evas_Smart_Class::callbacks
+ *          callbacks description array, so that the users of the smart object
+ *          can have introspection on its events API <b>at run time</b>.
  *
- * This should be called @b internally, from the smart object's own
- * code, when some specific event has occurred and the implementor
- * wants is to pertain to the object's events API (see @ref
- * Evas_Smart_Object_Group_Callbacks). The documentation for the smart
- * object should include a list of possible events and what type of @p
- * event_info to expect for each of them. Also, when defining an
- * #Evas_Smart_Class, smart object implementors are strongly
- * encouraged to properly set the Evas_Smart_Class::callbacks
- * callbacks description array, so that the users of the smart object
- * can have introspection on its events API <b>at run time</b>.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @ingroup Evas_Smart_Object_Group
+ * @param[in]   obj         The smart object
+ * @param[in]   event       The event's name string
+ * @param[in]   event_info  The pointer to an event specific struct or information to
+ *                      pass to the callback functions registered on this smart event
  */
 EAPI void         evas_object_smart_callback_call(Evas_Object *obj, const char *event, void *event_info) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Set an smart object @b instance's smart callbacks descriptions.
+ * @brief   Sets an smart object @b instance's smart callbacks descriptions.
  *
- * @param obj A smart object
- * @param descriptions @c NULL terminated array with
- * #Evas_Smart_Cb_Description descriptions. Array elements won't be
- * modified at run time, but references to them and their contents
- * will be made, so this array should be kept alive during the whole
- * object's lifetime.
- * @return @c EINA_TRUE on success, @c EINA_FALSE on failure.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * These descriptions are hints to be used by introspection and are
- * not enforced in any way.
+ * @remarks These descriptions are hints to be used by introspection and are
+ *          not enforced in any way.
  *
- * It will not be checked if instance callbacks descriptions have the
- * same name as respective possibly registered in the smart object
- * @b class. Both are kept in different arrays and users of
- * evas_object_smart_callbacks_descriptions_get() should handle this
- * case as they wish.
+ * @remarks It is not checked if instance callbacks descriptions have the
+ *          same name as respective possibly registered in the smart object
+ *          @b class. Both are kept in different arrays and users of
+ *          evas_object_smart_callbacks_descriptions_get() should handle this
+ *          case as they wish.
  *
- * @note Becase @p descriptions must be @c NULL terminated, and
- *        because a @c NULL name makes little sense, too,
- *        Evas_Smart_Cb_Description::name must @b not be @c NULL.
+ * @remarks Because @a descriptions must be @c NULL terminated, and
+ *          because a @c NULL name makes little sense, too,
+ *          Evas_Smart_Cb_Description::name must @b not be @c NULL.
  *
- * @note While instance callbacks descriptions are possible, they are
- *       @b not recommended. Use @b class callbacks descriptions
- *       instead as they make you smart object user's life simpler and
- *       will use less memory, as descriptions and arrays will be
- *       shared among all instances.
+ * @remarks While instance callbacks descriptions are possible, they are
+ *          @b not recommended. Use @b class callbacks descriptions
+ *          instead as they make it easier for you to use smart objects
+ *          and use less memory, as descriptions and arrays are
+ *          shared among all instances.
  *
- * @ingroup Evas_Smart_Object_Group
+ * @param[in]   obj           A smart object
+ * @param[in]   descriptions  @c NULL terminated array with #Evas_Smart_Cb_Description descriptions \n 
+ *                        Array elements are not modified at run time, but references to 
+ *                        them and their contents are made, so this array should be kept 
+ *                        alive during the whole object's lifetime.
+ * @return  #EINA_TRUE if the descriptions are set successfully, 
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool    evas_object_smart_callbacks_descriptions_set(Evas_Object *obj, const Evas_Smart_Cb_Description *descriptions) EINA_ARG_NONNULL(1);
 
 /**
- * Retrieve an smart object's know smart callback descriptions (both
- * instance and class ones).
+ * @brief   Gets a smart object's smart callback descriptions (both
+ *          instance and class ones).
  *
- * @param obj The smart object to get callback descriptions from.
- * @param class_descriptions Where to store class callbacks
- *        descriptions array, if any is known. If no descriptions are
- *        known, @c NULL is returned
- * @param class_count Returns how many class callbacks descriptions
- *        are known.
- * @param instance_descriptions Where to store instance callbacks
- *        descriptions array, if any is known. If no descriptions are
- *        known, @c NULL is returned.
- * @param instance_count Returns how many instance callbacks
- *        descriptions are known.
+ * @details This function searches for registered callback descriptions for both
+ *          instance and class of the given smart object. These arrays are
+ *          sorted by Evas_Smart_Cb_Description::name and also @c NULL
+ *          terminated, so both @a class_count and @a instance_count can be
+ *          ignored, if the caller wishes so. The terminator @c NULL is not
+ *          counted in these values.
  *
- * This call searches for registered callback descriptions for both
- * instance and class of the given smart object. These arrays will be
- * sorted by Evas_Smart_Cb_Description::name and also @c NULL
- * terminated, so both @a class_count and @a instance_count can be
- * ignored, if the caller wishes so. The terminator @c NULL is not
- * counted in these values.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note If just class descriptions are of interest, try
- *       evas_smart_callbacks_descriptions_get() instead.
+ * @remarks If just class descriptions are of interest.
  *
- * @note Use @c NULL pointers on the descriptions/counters you're not
- * interested in: they'll be ignored by the function.
+ * @remarks Use @c NULL pointers on the descriptions or counters that you are not
+ *          interested in: they are ignored by the function.
  *
- * @see evas_smart_callbacks_descriptions_get()
+ * @param[in]   obj                    The smart object to get callback descriptions from
+ * @param[in]   class_descriptions     The class callbacks descriptions array, if any, that is returned \n 
+ *                                 If no descriptions are known, @c NULL is returned.
+ * @param[in]   class_count            The number of class callbacks descriptions, that is returned
+ * @param[in]   instance_descriptions  The instance callbacks descriptions array, if any, that is returned \n
+ *                                 If no descriptions are known, @c NULL is returned.
+ * @param[in]   instance_count         The number of instance callbacks descriptions, that is returned
  *
- * @ingroup Evas_Smart_Object_Group
  */
 EAPI void         evas_object_smart_callbacks_descriptions_get(const Evas_Object *obj, const Evas_Smart_Cb_Description ***class_descriptions, unsigned int *class_count, const Evas_Smart_Cb_Description ***instance_descriptions, unsigned int *instance_count) EINA_ARG_NONNULL(1);
 
 /**
- * Find callback description for callback called @a name.
+ * @internal
+ * @brief   Finds the callback description for callback called @a name.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj the smart object.
- * @param name name of desired callback, must @b not be @c NULL.  The
- *        search have a special case for @a name being the same
- *        pointer as registered with Evas_Smart_Cb_Description, one
- *        can use it to avoid excessive use of strcmp().
- * @param class_description pointer to return class description or
- *        @c NULL if not found. If parameter is @c NULL, no search will
- *        be done on class descriptions.
- * @param instance_description pointer to return instance description
- *        or @c NULL if not found. If parameter is @c NULL, no search
- *        will be done on instance descriptions.
- * @return reference to description if found, @c NULL if not found.
+ * @param[in]   obj                   The smart object
+ * @param[in]   name                  The name of desired callback, \n
+ *                                This must @b not be @c NULL. The search has a special case 
+ *                                for @a name being the same pointer as registered with 
+ *                                Evas_Smart_Cb_Description; you can use it to avoid excessive 
+ *                                use of strcmp().
+ * @param[in]   class_description     The pointer to return class description or @c NULL, if not found \n 
+ *                                If parameter is @c NULL, no search is done on class descriptions.
+ * @param[in]   instance_description  The pointer to return instance description or @c NULL if not found \n 
+ *                                If parameter is @c NULL, no search is done on instance descriptions.
+ * @return  The reference to description if found, \n
+ *          otherwise @c NULL if not found
  */
 EAPI void         evas_object_smart_callback_description_find(const Evas_Object *obj, const char *name, const Evas_Smart_Cb_Description **class_description, const Evas_Smart_Cb_Description **instance_description) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Retrieve an Evas smart object's interface, by name string pointer.
+ * @internal
+ * @brief   Gets an Evas smart object's interface, by name string pointer.
+ * @since   1.7
  *
- * @param obj An Evas smart object.
- * @param name Name string of the desired interface, which must be the
- *             same pointer used at the interface's declarion, when
- *             creating the smart object @a obj.
- *
- * @since 1.7
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @return The interface's handle pointer, if found, @c NULL
- * otherwise.
+ * @param[in]   obj   An Evas smart object.
+ * @param[in]   name  The name string of the desired interface \n 
+ *                This must be the same pointer used at the interface's declaration, 
+ *                when creating the smart object @a obj.
+ * @return  The interface's handle pointer, \n 
+ *          otherwise @c NULL if not found
  */
-const void       *evas_object_smart_interface_get(const Evas_Object *obj, const char *name);
+EAPI const void       *evas_object_smart_interface_get(const Evas_Object *obj, const char *name);
 
 /**
- * Retrieve an Evas smart object interface's <b>private data</b>.
+ * @internal
+ * @brief   Gets an Evas smart object interface's <b>private data</b>.
+ * @since   1.7
  *
- * @param obj An Evas smart object.
- * @param iface The given object's interface handle.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @since 1.7
- *
- * @return The object interface's private data blob pointer, if found,
- * @c NULL otherwise.
+ * @param[in]   obj    An Evas smart object
+ * @param[in]   iface  The given object's interface handle
+ * @return  The object interface's private data blob pointer, \n
+ *          otherwise @c NULL if not found
  */
-void             *evas_object_smart_interface_data_get(const Evas_Object *obj, const Evas_Smart_Interface *iface);
+EAPI void             *evas_object_smart_interface_data_get(const Evas_Object *obj, const Evas_Smart_Interface *iface);
 
 /**
- * Mark smart object as changed, dirty.
+ * @brief   Marks smart object as changed, dirty.
  *
- * @param obj The given Evas smart object
+ * @details This function flags the given object as needing recalculation,
+ *          forcefully. As an effect, on the next rendering cycle its @b
+ *          calculate() (see #Evas_Smart_Class) smart function is called.
  *
- * This will flag the given object as needing recalculation,
- * forcefully. As an effect, on the next rendering cycle it's @b
- * calculate() (see #Evas_Smart_Class) smart function will be called.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @see evas_object_smart_need_recalculate_set().
- * @see evas_object_smart_calculate().
- *
- * @ingroup Evas_Smart_Object_Group
+ * @param[in]   obj  The given Evas smart object
  */
 EAPI void         evas_object_smart_changed(Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Set or unset the flag signalling that a given smart object needs to
- * get recalculated.
+ * @internal
+ * @brief   Sets or unsets the flag signalling that a given smart object needs to
+ *          get recalculated.
  *
- * @param obj the smart object
- * @param value whether one wants to set (@c EINA_TRUE) or to unset
- * (@c EINA_FALSE) the flag.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * If this flag is set, then the @c calculate() smart function of @p
- * obj will be called, if one is provided, during rendering phase of
- * Evas (see evas_render()), after which this flag will be
- * automatically unset.
+ * @remarks If this flag is set, then the @c calculate() smart function of @a
+ *          obj is called, if one is provided, during rendering phase of
+ *          Evas (see evas_render()), after which this flag is
+ *          automatically unset.
  *
- * If that smart function is not provided for the given object, this
- * flag will be left unchanged.
+ * @remarks If that smart function is not provided for the given object, this
+ *          flag is left unchanged.
  *
- * @note just setting this flag will not make the canvas' whole scene
- *       dirty, by itself, and evas_render() will have no effect. To
- *       force that, use evas_object_smart_changed(), that will also
- *       automatically call this function automatically, with
- *       @c EINA_TRUE as parameter.
+ * @remarks Just setting this flag does not make the canvas' whole scene
+ *          dirty, by itself, and evas_render() has no effect. To
+ *          force that, use evas_object_smart_changed(), that also
+ *          automatically calls this function, with
+ *          #EINA_TRUE as parameter.
+ *
+ * @param[in]   obj    The smart object
+ * @param[in]   value  Set #EINA_TRUE to recalculate the smart object, \n
+ *                 otherwise set #EINA_FALSE to not recalculate the smart object
  *
  * @see evas_object_smart_need_recalculate_get()
  * @see evas_object_smart_calculate()
  * @see evas_smart_objects_calculate()
- *
- * @ingroup Evas_Smart_Object_Group
  */
 EAPI void         evas_object_smart_need_recalculate_set(Evas_Object *obj, Eina_Bool value) EINA_ARG_NONNULL(1);
 
 /**
- * Get the value of the flag signalling that a given smart object needs to
- * get recalculated.
+ * @internal
+ * @brief   Gets the value of the flag signalling that a given smart object needs to
+ *          get recalculated.
  *
- * @param obj the smart object
- * @return if flag is set or not.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note this flag will be unset during the rendering phase, when the
- *       @c calculate() smart function is called, if one is provided.
- *       If it's not provided, then the flag will be left unchanged
- *       after the rendering phase.
+ * @remarks This flag is unset during the rendering phase, when the
+ *          @c calculate() smart function is called, if one is provided.
+ *          If it is not provided, then the flag is left unchanged
+ *          after the rendering phase.
  *
- * @see evas_object_smart_need_recalculate_set(), for more details
+ * @param[in]   obj  The smart object
+ * @return  #EINA_TRUE if flag is set to recalculate, \n
+ *          otherwise #EINA_FALSE if flag is not set to recalculate
  *
- * @ingroup Evas_Smart_Object_Group
+ * @see evas_object_smart_need_recalculate_set()
  */
 EAPI Eina_Bool    evas_object_smart_need_recalculate_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Call the @b calculate() smart function immediately on a given smart
- * object.
+ * @internal
+ * @brief   Calls the @b calculate() smart function immediately on a given smart object.
  *
- * @param obj the smart object's handle
+ * @details This function forces immediate calculations (see #Evas_Smart_Class)
+ *          needed for rendering of this object and, besides, unset the
+ *          flag on it telling it needs recalculation for the next rendering phase.
  *
- * This will force immediate calculations (see #Evas_Smart_Class)
- * needed for renderization of this object and, besides, unset the
- * flag on it telling it needs recalculation for the next rendering
- * phase.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @see evas_object_smart_need_recalculate_set()
+ * @param[in]   obj  The smart object's handle
  *
- * @ingroup Evas_Smart_Object_Group
+ * @see evas_object_smart_need_recalculate_set()
  */
 EAPI void         evas_object_smart_calculate(Evas_Object *obj) EINA_ARG_NONNULL(1);
 
 /**
- * Call user-provided @c calculate() smart functions and unset the
- * flag signalling that the object needs to get recalculated to @b all
- * smart objects in the canvas.
+ * @brief  Calls user-provided @c calculate() smart functions and unset the
+ *         flag signalling that the object needs to get recalculated to @b all
+ *         smart objects in the canvas.
  *
- * @param e The canvas to calculate all smart objects in
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @see evas_object_smart_need_recalculate_set()
- *
- * @ingroup Evas_Smart_Object_Group
+ * @param[in]  e  The canvas to calculate all smart objects in
  */
 EAPI void         evas_smart_objects_calculate(Evas *e);
 
 /**
- * This gets the internal counter that counts the number of smart calculations
+ * @brief   Gets the internal counter that counts the number of smart calculations.
+ * @since   1.1
  *
- * @param e The canvas to get the calculate counter from
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Whenever evas performs smart object calculations on the whole canvas
- * it increments a counter by 1. This is the smart object calculate counter
- * that this function returns the value of. It starts at the value of 0 and
- * will increase (and eventually wrap around to negative values and so on) by
- * 1 every time objects are calculated. You can use this counter to ensure
- * you don't re-do calculations withint the same calculation generation/run
- * if the calculations maybe cause self-feeding effects.
+ * @remarks Whenever evas performs smart object calculations on the whole canvas
+ *          it increments a counter by @c 1. This is the smart object calculate counter
+ *          that this function returns the value of. It starts at the value of @c 0 and
+ *          increases (and eventually wrap around to negative values and so on) by
+ *          @c 1 every time objects are calculated. You can use this counter to ensure
+ *          that you do not re-do calculations within the same calculation generation or run
+ *          if the calculations maybe cause self-feeding effects.
  *
- * @ingroup Evas_Smart_Object_Group
- * @since 1.1
+ * @param[in]   e  The canvas to get the calculate counter from
+ * @return The number of smart calculations
  */
 EAPI int          evas_smart_objects_calculate_count_get(const Evas *e);
 
 /**
- * Moves all children objects of a given smart object relative to a
- * given offset.
+ * @internal
+ * @brief   Moves all children objects of a given smart object relative to a
+ *          given offset.
+ *
+ * @details This function makes each of @a obj object's children to move, from where
+ *          they before, with those delta values (offsets) on both directions.
  *
- * @param obj the smart object.
- * @param dx horizontal offset (delta).
- * @param dy vertical offset (delta).
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This will make each of @p obj object's children to move, from where
- * they before, with those delta values (offsets) on both directions.
+ * @remarks This is most useful on custom smart @c move() functions.
  *
- * @note This is most useful on custom smart @c move() functions.
+ * @remarks Clipped smart objects already make use of this function on
+ *          their @c move() smart function definition.
  *
- * @note Clipped smart objects already make use of this function on
- * their @c move() smart function definition.
+ * @param[in]   obj  The smart object
+ * @param[in]   dx   The horizontal offset (delta)
+ * @param[in]   dy   The vertical offset (delta)
  */
 EAPI void         evas_object_smart_move_children_relative(Evas_Object *obj, Evas_Coord dx, Evas_Coord dy) EINA_ARG_NONNULL(1);
 
@@ -10762,33 +12877,29 @@ EAPI void         evas_object_smart_move_children_relative(Evas_Object *obj, Eva
  */
 
 /**
+ * @internal
  * @defgroup Evas_Smart_Object_Clipped Clipped Smart Object
+ * @ingroup Evas_Smart_Object_Group
+ *
+ * @brief  This group provides functions for clipped smart objects.
  *
  * Clipped smart object is a base to construct other smart objects
  * based on the concept of having an internal clipper that is applied
- * to all children objects. This clipper will control the visibility,
+ * to all children objects. This clipper controls the visibility,
  * clipping and color of sibling objects (remember that the clipping
  * is recursive, and clipper color modulates the color of its
- * clippees). By default, this base will also move children relatively
+ * clippees). By default, this base also moves children relatively
  * to the parent, and delete them when parent is deleted. In other
  * words, it is the base for simple object grouping.
  *
- * See some @ref Example_Evas_Smart_Objects "examples" of this group
- * of functions.
- *
  * @see evas_object_smart_clipped_smart_set()
  *
- * @ingroup Evas_Smart_Object_Group
- */
-
-/**
- * @addtogroup Evas_Smart_Object_Clipped
  * @{
  */
 
 /**
- * Every subclass should provide this at the beginning of their own
- * data set with evas_object_smart_data_set().
+ * @brief The strcuture type that every subclass should provide this at the beginning of their own
+ *        data set with evas_object_smart_data_set().
  */
 typedef struct _Evas_Object_Smart_Clipped_Data Evas_Object_Smart_Clipped_Data;
 struct _Evas_Object_Smart_Clipped_Data
@@ -10798,30 +12909,38 @@ struct _Evas_Object_Smart_Clipped_Data
 };
 
 /**
- * Get the clipper object for the given clipped smart object.
+ * @brief   Gets the clipper object for the given clipped smart object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param obj the clipped smart object to retrieve associated clipper
- * from.
- * @return the clipper object.
+ * @remarks Use this function if you want to change any of this clipper's
+ *          properties, like colors.
  *
- * Use this function if you want to change any of this clipper's
- * properties, like colors.
+ * @param[in]   obj  The clipped smart object to retrieve associated clipper from
+ * @return  The clipper object
  *
  * @see evas_object_smart_clipped_smart_add()
  */
 EAPI Evas_Object            *evas_object_smart_clipped_clipper_get(Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set a given smart class' callbacks so it implements the <b>clipped smart
- * object"</b>'s interface.
+ * @internal
+ * @brief   Sets a given smart class' callbacks so it implements the <b>clipped smart
+ *          object</b>'s interface.
  *
- * @param sc The smart class handle to operate on
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This call will assign all the required methods of the @p sc
- * #Evas_Smart_Class instance to the implementations set for clipped
- * smart objects. If one wants to "subclass" it, call this function
- * and then override desired values. If one wants to call any original
- * method, save it somewhere. Example:
+ * @remarks This call assigns all the required methods of the @a sc
+ *          #Evas_Smart_Class instance to the implementations set for clipped
+ *          smart objects. If one wants to "subclass" it, call this function
+ *          and then override desired values. If one wants to call any original
+ *          method, save it somewhere. 
+ *
+ * @remarks The following is an example:
  *
  * @code
  * static Evas_Smart_Class parent_sc = EVAS_SMART_CLASS_INIT_NULL;
@@ -10846,31 +12965,36 @@ EAPI Evas_Object            *evas_object_smart_clipped_clipper_get(Evas_Object *
  * }
  * @endcode
  *
- * Default behavior for each of #Evas_Smart_Class functions on a
- * clipped smart object are:
- * - @c add: creates a hidden clipper with "infinite" size, to clip
- *    any incoming members;
- * - @c del: delete all children objects;
- * - @c move: move all objects relative relatively;
- * - @c resize: <b>not defined</b>;
- * - @c show: if there are children objects, show clipper;
- * - @c hide: hides clipper;
- * - @c color_set: set the color of clipper;
- * - @c clip_set: set clipper of clipper;
- * - @c clip_unset: unset the clipper of clipper;
- *
- * @note There are other means of assigning parent smart classes to
- * child ones, like the #EVAS_SMART_SUBCLASS_NEW macro or the
- * evas_smart_class_inherit_full() function.
+ * @remarks The default behavior for each of #Evas_Smart_Class functions on a
+ *          clipped smart object are:
+ *          - @c add: creates a hidden clipper with "infinite" size, to clip any incoming members;
+ *          - @c del: delete all children objects;
+ *          - @c move: move all objects relative relatively;
+ *          - @c resize: <b>not defined</b>;
+ *          - @c show: if there are children objects, show clipper;
+ *          - @c hide: hides clipper;
+ *          - @c color_set: set the color of clipper;
+ *          - @c clip_set: set clipper of clipper;
+ *          - @c clip_unset: unset the clipper of clipper;
+ *
+ * @remarks There are other means of assigning parent smart classes to
+ *          child ones, like the #EVAS_SMART_SUBCLASS_NEW macro or the
+ *          evas_smart_class_inherit_full() function.
+ *
+ * @param[in]   sc  The smart class handle to operate on
  */
 EAPI void                    evas_object_smart_clipped_smart_set(Evas_Smart_Class *sc) EINA_ARG_NONNULL(1);
 
 /**
- * Get a pointer to the <b>clipped smart object's</b> class, to use
- * for proper inheritance
+ * @internal
+ * @brief  Gets a pointer to the <b>clipped smart object's</b> class, to use
+ *         for proper inheritance.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @see #Evas_Smart_Object_Clipped for more information on this smart
- * class
+ * @see #Evas_Smart_Object_Clipped for more information on this smart class.
  */
 EAPI const Evas_Smart_Class *evas_object_smart_clipped_class_get(void) EINA_CONST;
 
@@ -10880,6 +13004,9 @@ EAPI const Evas_Smart_Class *evas_object_smart_clipped_class_get(void) EINA_CONS
 
 /**
  * @defgroup Evas_Object_Box Box Smart Object
+ * @ingroup Evas_Smart_Object_Group
+ *
+ * @brief  This group provides functions for bos smart objects.
  *
  * A box is a convenience smart object that packs children inside it
  * in @b sequence, using a layouting function specified by the
@@ -10887,97 +13014,75 @@ EAPI const Evas_Smart_Class *evas_object_smart_clipped_class_get(void) EINA_CONS
  * in Evas</b>, all of them using children size hints to define their
  * size and alignment inside their cell space.
  *
- * Examples on this smart object's usage:
- * - @ref Example_Evas_Box
- * - @ref Example_Evas_Size_Hints
- *
  * @see @ref Evas_Object_Group_Size_Hints
  *
- * @ingroup Evas_Smart_Object_Group
- */
-
-/**
- * @addtogroup Evas_Object_Box
  * @{
  */
 
 /**
  * @typedef Evas_Object_Box_Api
  *
- * Smart class extension, providing extra box object requirements.
- *
- * @ingroup Evas_Object_Box
+ * @brief  The structure type containing the smart class extension, providing extra box object requirements.
  */
 typedef struct _Evas_Object_Box_Api Evas_Object_Box_Api;
 
 /**
  * @typedef Evas_Object_Box_Data
  *
- * Smart object instance data, providing box object requirements.
- *
- * @ingroup Evas_Object_Box
+ * @brief  The structure type containing the smart object instance data, providing box object requirements.
  */
 typedef struct _Evas_Object_Box_Data Evas_Object_Box_Data;
 
 /**
  * @typedef Evas_Object_Box_Option
  *
- * The base structure for a box option. Box options are a way of
- * extending box items properties, which will be taken into account
- * for layouting decisions. The box layouting functions provided by
- * Evas will only rely on objects' canonical size hints to layout
- * them, so the basic box option has @b no (custom) property set.
- *
- * Users creating their own layouts, but not depending on extra child
- * items' properties, would be fine just using
- * evas_object_box_layout_set(). But if one desires a layout depending
- * on extra child properties, he/she has to @b subclass the box smart
- * object. Thus, by using evas_object_box_smart_class_get() and
- * evas_object_box_smart_set(), the @c option_new() and @c
- * option_free() smart class functions should be properly
- * redefined/extended.
- *
- * Object properties are bound to an integer identifier and must have
- * a name string. Their values are open to any data. See the API on
- * option properties for more details.
- *
- * @ingroup Evas_Object_Box
+ * @brief The structure type containing the base structure for a box option.
+ *        Box options are a way of extending box items properties, which are taken into account
+ *        for layouting decisions. The box layouting functions provided by
+ *        Evas only relies on objects' canonical size hints to layout
+ *        them, so the basic box option has @b no (custom) property set.
+ *
+ *        Users creating their own layouts, but not depending on extra child
+ *        items' properties, would be fine just using
+ *        evas_object_box_layout_set(). But if one desires a layout depending
+ *        on extra child properties, he or she has to @b subclass the box smart
+ *        object. Thus, by using evas_object_box_smart_class_get() and
+ *        evas_object_box_smart_set(), the @c option_new() and @c
+ *        option_free() smart class functions should be properly
+ *        redefined or extended.
+ *
+ *        Object properties are bound to an integer identifier and must have
+ *        a name string. Their values are open to any data. See the API on
+ *        option properties for more details.
  */
 typedef struct _Evas_Object_Box_Option Evas_Object_Box_Option;
 
 /**
  * @typedef Evas_Object_Box_Layout
  *
- * Function signature for an Evas box object layouting routine. By
- * @a o it will be passed the box object in question, by @a priv it will
- * be passed the box's internal data and, by @a user_data, it will be
- * passed any custom data one could have set to a given box layouting
- * function, with evas_object_box_layout_set().
- *
- * @ingroup Evas_Object_Box
+ * @brief Called for the function signature for an Evas box object layouting routine. 
+ *        @a o is the box object in question, @a priv is the box's internal data
+ *        and, @a user_data is any custom data you could have set to
+ *        a given box layouting function, with evas_object_box_layout_set().
  */
 typedef void (*Evas_Object_Box_Layout)(Evas_Object *o, Evas_Object_Box_Data *priv, void *user_data);
 
 /**
  * @def EVAS_OBJECT_BOX_API_VERSION
  *
- * Current version for Evas box object smart class, a value which goes
- * to _Evas_Object_Box_Api::version.
- *
- * @ingroup Evas_Object_Box
+ * @brief Definition of the current version for Evas box object smart class, a value which goes
+ *        to _Evas_Object_Box_Api::version.
  */
 #define EVAS_OBJECT_BOX_API_VERSION 1
 
 /**
  * @struct _Evas_Object_Box_Api
  *
- * This structure should be used by any smart class inheriting from
- * the box's one, to provide custom box behavior which could not be
- * achieved only by providing a layout function, with
- * evas_object_box_layout_set().
+ * @brief The structure type that should be used by any smart class inheriting from
+ *        the box's one, to provide custom box behavior which could not be
+ *        achieved only by providing a layout function, with evas_object_box_layout_set().
  *
  * @extends Evas_Smart_Class
- * @ingroup Evas_Object_Box
  */
 struct _Evas_Object_Box_Api
 {
@@ -11001,11 +13106,11 @@ struct _Evas_Object_Box_Api
 /**
  * @def EVAS_OBJECT_BOX_API_INIT
  *
- * Initializer for a whole #Evas_Object_Box_Api structure, with
- * @c NULL values on its specific fields.
+ * @brief Definition for initializing for a whole #Evas_Object_Box_Api structure, with
+ *        @c NULL values on its specific fields.
  *
- * @param smart_class_init initializer to use for the "base" field
- * (#Evas_Smart_Class).
+ * @param smart_class_init  The initializer to use for the "base" field 
+ *                          (#Evas_Smart_Class)
  *
  * @see EVAS_SMART_CLASS_INIT_NULL
  * @see EVAS_SMART_CLASS_INIT_VERSION
@@ -11013,70 +13118,65 @@ struct _Evas_Object_Box_Api
  * @see EVAS_OBJECT_BOX_API_INIT_NULL
  * @see EVAS_OBJECT_BOX_API_INIT_VERSION
  * @see EVAS_OBJECT_BOX_API_INIT_NAME_VERSION
- * @ingroup Evas_Object_Box
  */
 #define EVAS_OBJECT_BOX_API_INIT(smart_class_init) {smart_class_init, EVAS_OBJECT_BOX_API_VERSION, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
 
 /**
  * @def EVAS_OBJECT_BOX_API_INIT_NULL
  *
- * Initializer to zero out a whole #Evas_Object_Box_Api structure.
+ * @brief  Definition for initializing to zero out a whole #Evas_Object_Box_Api structure.
  *
  * @see EVAS_OBJECT_BOX_API_INIT_VERSION
  * @see EVAS_OBJECT_BOX_API_INIT_NAME_VERSION
  * @see EVAS_OBJECT_BOX_API_INIT
- * @ingroup Evas_Object_Box
  */
 #define EVAS_OBJECT_BOX_API_INIT_NULL    EVAS_OBJECT_BOX_API_INIT(EVAS_SMART_CLASS_INIT_NULL)
 
 /**
  * @def EVAS_OBJECT_BOX_API_INIT_VERSION
  *
- * Initializer to zero out a whole #Evas_Object_Box_Api structure and
- * set a specific version on it.
+ * @brief   Definition for initializing to zero out a whole #Evas_Object_Box_Api structure and
+ *          set a specific version on it.
  *
- * This is similar to #EVAS_OBJECT_BOX_API_INIT_NULL, but it will set
- * the version field of #Evas_Smart_Class (base field) to the latest
- * #EVAS_SMART_CLASS_VERSION.
+ * @remarks This is similar to #EVAS_OBJECT_BOX_API_INIT_NULL, but it sets
+ *          the version field of #Evas_Smart_Class (base field) to the latest
+ *          EVAS_SMART_CLASS_VERSION.
  *
  * @see EVAS_OBJECT_BOX_API_INIT_NULL
  * @see EVAS_OBJECT_BOX_API_INIT_NAME_VERSION
  * @see EVAS_OBJECT_BOX_API_INIT
- * @ingroup Evas_Object_Box
  */
 #define EVAS_OBJECT_BOX_API_INIT_VERSION EVAS_OBJECT_BOX_API_INIT(EVAS_SMART_CLASS_INIT_VERSION)
 
 /**
  * @def EVAS_OBJECT_BOX_API_INIT_NAME_VERSION
  *
- * Initializer to zero out a whole #Evas_Object_Box_Api structure and
- * set its name and version.
+ * @brief   Definition for initializing to zero out a whole #Evas_Object_Box_Api structure and
+ *          set its name and version.
  *
- * This is similar to #EVAS_OBJECT_BOX_API_INIT_NULL, but it will also
- * set the version field of #Evas_Smart_Class (base field) to the
- * latest #EVAS_SMART_CLASS_VERSION and name it to the specific value.
+ * @remarks This is similar to #EVAS_OBJECT_BOX_API_INIT_NULL, but it also
+ *          sets the version field of #Evas_Smart_Class (base field) to the
+ *          latest EVAS_SMART_CLASS_VERSION and name it to the specific value.
  *
- * It will keep a reference to the name field as a <c>"const char *"</c>,
- * i.e., the name must be available while the structure is
- * used (hint: static or global variable!) and must not be modified.
+ * @remarks It keeps a reference to the name field as a <c>"const char *"</c>,
+ *          i.e., the name must be available while the structure is
+ *          used (hint: static or global variable) and must not be modified.
  *
  * @see EVAS_OBJECT_BOX_API_INIT_NULL
  * @see EVAS_OBJECT_BOX_API_INIT_VERSION
  * @see EVAS_OBJECT_BOX_API_INIT
- * @ingroup Evas_Object_Box
  */
 #define EVAS_OBJECT_BOX_API_INIT_NAME_VERSION(name) EVAS_OBJECT_BOX_API_INIT(EVAS_SMART_CLASS_INIT_NAME_VERSION(name))
 
 /**
  * @struct _Evas_Object_Box_Data
  *
- * This structure augments clipped smart object's instance data,
- * providing extra members required by generic box implementation. If
- * a subclass inherits from #Evas_Object_Box_Api, then it may augment
- * #Evas_Object_Box_Data to fit its own needs.
+ * @brief The structure type that augments clipped smart object's instance data,
+ *        providing extra members required by generic box implementation. If
+ *        a subclass inherits from #Evas_Object_Box_Api, then it may augment
+ *        #Evas_Object_Box_Data to fit its own needs.
  *
  * @extends Evas_Object_Smart_Clipped_Data
- * @ingroup Evas_Object_Box
  */
 struct _Evas_Object_Box_Data
 {
@@ -11101,97 +13201,113 @@ struct _Evas_Object_Box_Data
    Eina_Bool                      children_changed : 1;
 };
 
+/**
+ * @brief Evas_Object_Box_Option struct fields
+ */
 struct _Evas_Object_Box_Option
 {
    Evas_Object *obj;    /**< Pointer to the box child object, itself */
    Eina_Bool    max_reached : 1;
    Eina_Bool    min_reached : 1;
    Evas_Coord   alloc_size;
-};    /**< #Evas_Object_Box_Option struct fields */
+};
 
 /**
- * Set the default box @a api struct (Evas_Object_Box_Api)
- * with the default values. May be used to extend that API.
+ * @brief   Sets the default box @a api struct (Evas_Object_Box_Api)
+ *          with the default values. This may be used to extend that API.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param api The box API struct to set back, most probably with
- * overridden fields (on class extensions scenarios)
+ * @param   api  The box API struct to set back, most probably with
+ *               overridden fields (on class extensions scenarios)
  */
 EAPI void                       evas_object_box_smart_set(Evas_Object_Box_Api *api) EINA_ARG_NONNULL(1);
 
 /**
- * Get the Evas box smart class, for inheritance purposes.
+ * @brief   Gets the Evas box smart class, for inheritance purposes.
  *
- * @return the (canonical) Evas box smart class.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * The returned value is @b not to be modified, just use it as your
- * parent class.
+ * @remarks The returned value is @b not to be modified, just use it as your
+ *          parent class.
+ * @return  The (canonical) Evas box smart class
  */
 EAPI const Evas_Object_Box_Api *evas_object_box_smart_class_get(void) EINA_CONST;
 
 /**
- * Set a new layouting function to a given box object
+ * @brief   Sets a new layouting function to a given box object.
  *
- * @param o The box object to operate on.
- * @param cb The new layout function to set on @p o.
- * @param data Data pointer to be passed to @p cb.
- * @param free_data Function to free @p data, if need be.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * A box layout function affects how a box object displays child
- * elements within its area. The list of pre-defined box layouts
- * available in Evas is:
- * - evas_object_box_layout_horizontal()
- * - evas_object_box_layout_vertical()
- * - evas_object_box_layout_homogeneous_horizontal()
- * - evas_object_box_layout_homogeneous_vertical()
- * - evas_object_box_layout_homogeneous_max_size_horizontal()
- * - evas_object_box_layout_homogeneous_max_size_vertical()
- * - evas_object_box_layout_flow_horizontal()
- * - evas_object_box_layout_flow_vertical()
- * - evas_object_box_layout_stack()
+ * @remarks A box layout function affects how a box object displays child
+ *          elements within its area. The list of pre-defined box layouts
+ *          available in Evas is:
+ *          - evas_object_box_layout_horizontal()
+ *          - evas_object_box_layout_vertical()
+ *          - evas_object_box_layout_homogeneous_horizontal()
+ *          - evas_object_box_layout_homogeneous_vertical()
+ *          - evas_object_box_layout_homogeneous_max_size_horizontal()
+ *          - evas_object_box_layout_homogeneous_max_size_vertical()
+ *          - evas_object_box_layout_flow_horizontal()
+ *          - evas_object_box_layout_flow_vertical()
+ *          - evas_object_box_layout_stack()
+ *          See each of their documentation texts for details on them.
  *
- * Refer to each of their documentation texts for details on them.
+ * @remarks A box layouting function is triggered by the @c
+ *          'calculate' smart callback of the box's smart class.
  *
- * @note A box layouting function will be triggered by the @c
- * 'calculate' smart callback of the box's smart class.
+ * @param[in]   o          The box object to operate on
+ * @param[in]   cb         The new layout function to set on @a o
+ * @param[in]   data       The data pointer to be passed to @a cb
+ * @param[in]   free_data  The function to free @a data, if need be
  */
 EAPI void                       evas_object_box_layout_set(Evas_Object *o, Evas_Object_Box_Layout cb, const void *data, void (*free_data)(void *data)) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Add a new box object on the provided canvas.
+ * @brief   Adds a new box object on the provided canvas.
  *
- * @param evas The canvas to create the box object on.
- * @return @c NULL on error, a pointer to a new box object on
- * success.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * After instantiation, if a box object hasn't its layout function
- * set, via evas_object_box_layout_set(), it will have it by default
- * set to evas_object_box_layout_horizontal(). The remaining
- * properties of the box must be set/retrieved via
- * <c>evas_object_box_{h,v}_{align,padding}_{get,set)()</c>.
+ * @remarks After instantiation, if a box object has not its layout function
+ *          set, via evas_object_box_layout_set(), it has it by default
+ *          set to evas_object_box_layout_horizontal(). The remaining
+ *          properties of the box must be set/retrieved via
+ *          <c>evas_object_box_{h,v}_{align,padding}_{get,set)()</c>.
+ *
+ * @param[in]   evas  The canvas to create the box object on
+ * @return  A pointer to a new box object, \n
+ *          otherwise @c NULL on error
  */
 EAPI Evas_Object               *evas_object_box_add(Evas *evas) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Add a new box as a @b child of a given smart object.
+ * @brief   Adds a new box as a @b child of a given smart object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param parent The parent smart object to put the new box in.
- * @return @c NULL on error, a pointer to a new box object on
- * success.
+ * @remarks This function is a helper function that has the same effect of putting a new
+ *          box object into @a parent by use of evas_object_smart_member_add().
  *
- * This is a helper function that has the same effect of putting a new
- * box object into @p parent by use of evas_object_smart_member_add().
+ * @param[in]   parent  The parent smart object to put the new box in
+ * @return  A pointer to a new box object, \n
+ *          otherwise @c NULL on error
  *
  * @see evas_object_box_add()
  */
 EAPI Evas_Object               *evas_object_box_add_to(Evas_Object *parent) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Layout function which sets the box @a o to a (basic) horizontal box
- *
- * @param o The box object in question
- * @param priv The smart data of the @p o
- * @param data The data pointer passed on
- * evas_object_box_layout_set(), if any
+ * @brief  Layout function which sets the box @a o to a (basic) horizontal box.
  *
  * In this layout, the box object's overall behavior is controlled by
  * its padding/alignment properties, which are set by the
@@ -11200,91 +13316,110 @@ EAPI Evas_Object               *evas_object_box_add_to(Evas_Object *parent) EINA
  * <c>evas_object_size_hint_{align,padding,weight}_set()</c> functions
  * -- also control the way this function works.
  *
- * \par Box's properties:
+ * @par Box's properties:
  * @c align_h controls the horizontal alignment of the child objects
  * relative to the containing box. When set to @c 0.0, children are
  * aligned to the left. A value of @c 1.0 makes them aligned to the
  * right border. Values in between align them proportionally. Note
  * that if the size required by the children, which is given by their
  * widths and the @c padding_h property of the box, is bigger than the
- * their container's width, the children will be displayed out of the
+ * their container's width, the children are displayed out of the
  * box's bounds. A negative value of @c align_h makes the box to
  * @b justify its children. The padding between them, in this case, is
  * corrected so that the leftmost one touches the left border and the
  * rightmost one touches the right border (even if they must
  * overlap). The @c align_v and @c padding_v properties of the box
- * @b don't contribute to its behaviour when this layout is chosen.
+ * @b do not contribute to its behaviour when this layout is chosen.
  *
- * \par Child element's properties:
+ * @par Child element's properties:
  * @c align_x does @b not influence the box's behavior. @c padding_l
  * and @c padding_r sum up to the container's horizontal padding
  * between elements. The child's @c padding_t, @c padding_b and
- * @c align_y properties apply for padding/alignment relative to the
+ * @c align_y properties apply for padding or alignment relative to the
  * overall height of the box. Finally, there is the @c weight_x
  * property, which, if set to a non-zero value, tells the container
- * that the child width is @b not pre-defined. If the container can't
+ * that the child width is @b not pre-defined. If the container can not
  * accommodate all its children, it sets the widths of the ones
  * <b>with weights</b> to sizes as small as they can all fit into
  * it. If the size required by the children is less than the
  * available, the box increases its childrens' (which have weights)
  * widths as to fit the remaining space. The @c weight_x property,
  * besides telling the element is resizable, gives a @b weight for the
- * resizing process.  The parent box will try to distribute (or take
- * off) widths accordingly to the @b normalized list of weigths: most
- * weighted children remain/get larger in this process than the least
+ * resizing process.  The parent box tries to distribute (or take
+ * off) widths accordingly to the @b normalized list of weights: most
+ * weighted children remain or get larger in this process than the least
  * ones. @c weight_y does not influence the layout.
  *
- * If one desires that, besides having weights, child elements must be
+ * If you desire that, besides having weights, child elements must be
  * resized bounded to a minimum or maximum size, those size hints must
  * be set, by the <c>evas_object_size_hint_{min,max}_set()</c>
  * functions.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  o     The box object in question
+ * @param[in]  priv  The smart data of the @a o
+ * @param[in]  data  The data pointer passed on evas_object_box_layout_set(), if any
  */
 EAPI void                       evas_object_box_layout_horizontal(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Layout function which sets the box @a o to a (basic) vertical box
+ * @brief   Sets the box @a o to a (basic) vertical box.
+ *
+ * @details This Layout function behaves analogously to
+ *          evas_object_box_layout_horizontal(). The description of its
+ *          behaviour can be derived from that function's documentation.
+ *
+ * @param[in]  o     The box object in question
+ * @param[in]  priv  The smart data of the @a o
+ * @param[in]  data  The data pointer passed on evas_object_box_layout_set(), if any
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function behaves analogously to
- * evas_object_box_layout_horizontal(). The description of its
- * behaviour can be derived from that function's documentation.
  */
 EAPI void                       evas_object_box_layout_vertical(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Layout function which sets the box @a o to a @b homogeneous
- * vertical box
+ * @brief   Sets the box @a o to a @b homogeneous vertical box.
+ *
+ * @details This Layout function behaves analogously to
+ *          evas_object_box_layout_homogeneous_horizontal(). The description
+ *          of its behaviour can be derived from that function's documentation.
+ *
+ * @param[in]  o     The box object in question
+ * @param[in]  priv  The smart data of the @a o
+ * @param[in]  data  The data pointer passed on evas_object_box_layout_set(), if any
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function behaves analogously to
- * evas_object_box_layout_homogeneous_horizontal().  The description
- * of its behaviour can be derived from that function's documentation.
  */
 EAPI void                       evas_object_box_layout_homogeneous_vertical(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Layout function which sets the box @a o to a @b homogeneous
- * horizontal box
- *
- * @param o The box object in question
- * @param priv The smart data of the @p o
- * @param data The data pointer passed on
- * evas_object_box_layout_set(), if any
+ * @brief  Sets the box @a o to a @b homogeneous horizontal box.
  *
  * In a homogeneous horizontal box, its width is divided @b equally
  * between the contained objects. The box's overall behavior is
- * controlled by its padding/alignment properties, which are set by
+ * controlled by its padding or alignment properties, which are set by
  * the <c>evas_object_box_{h,v}_{align,padding}_set()</c> family of
  * functions.  The size hints the elements in the box -- set by the
  * <c>evas_object_size_hint_{align,padding,weight}_set()</c> functions
  * -- also control the way this function works.
  *
- * \par Box's properties:
+ * @par Box's properties:
  * @c align_h has no influence on the box for this layout.
  * @c padding_h tells the box to draw empty spaces of that size, in
- * pixels, between the (equal) child objects's cells. The @c align_v
- * and @c padding_v properties of the box don't contribute to its
+ * pixels, between the (equal) child objects' cells. The @c align_v
+ * and @c padding_v properties of the box do not contribute to its
  * behaviour when this layout is chosen.
  *
- * \par Child element's properties:
+ * @par Child element's properties:
  * @c padding_l and @c padding_r sum up to the required width of the
  * child element. The @c align_x property tells the relative position
  * of this overall child width in its allocated cell (@c 0.0 to
@@ -11293,35 +13428,37 @@ EAPI void                       evas_object_box_layout_homogeneous_vertical(Evas
  * width of its cell (respecting the minimum and maximum size hints on
  * the child's width and accounting for its horizontal padding
  * hints). The child's @c padding_t, @c padding_b and @c align_y
- * properties apply for padding/alignment relative to the overall
+ * properties apply for padding or alignment relative to the overall
  * height of the box. A value of @c -1.0 to @c align_y makes the box
  * try to resize this child element to the exact height of its parent
  * (respecting the maximum size hint on the child's height).
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  o     The box object in question
+ * @param[in]  priv  The smart data of the @a o
+ * @param[in]  data  The data pointer passed on evas_object_box_layout_set(), if any
  */
 EAPI void                       evas_object_box_layout_homogeneous_horizontal(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Layout function which sets the box @a o to a <b>maximum size,
- * homogeneous</b> horizontal box
- *
- * @param o The box object in question
- * @param priv The smart data of the @p o
- * @param data The data pointer passed on
- * evas_object_box_layout_set(), if any
+ * @brief  Sets the box @a o to a <b>maximum size, homogeneous</b> horizontal box
  *
  * In a maximum size, homogeneous horizontal box, besides having cells
- * of <b>equal size</b> reserved for the child objects, this size will
- * be defined by the size of the @b largest child in the box (in
+ * of <b>equal size</b> reserved for the child objects, this size is
+ * defined by the size of the @b largest child in the box (in
  * width). The box's overall behavior is controlled by its properties,
  * which are set by the
  * <c>evas_object_box_{h,v}_{align,padding}_set()</c> family of
- * functions.  The size hints of the elements in the box -- set by the
+ * functions. The size hints of the elements in the box -- set by the
  * <c>evas_object_size_hint_{align,padding,weight}_set()</c> functions
  * -- also control the way this function works.
  *
- * \par Box's properties:
+ * @par Box's properties:
  * @c padding_h tells the box to draw empty spaces of that size, in
- * pixels, between the child objects's cells. @c align_h controls the
+ * pixels, between the child objects' cells. @c align_h controls the
  * horizontal alignment of the child objects, relative to the
  * containing box. When set to @c 0.0, children are aligned to the
  * left. A value of @c 1.0 lets them aligned to the right
@@ -11330,10 +13467,10 @@ EAPI void                       evas_object_box_layout_homogeneous_horizontal(Ev
  * cells. The padding between them, in this case, is corrected so that
  * the leftmost one touches the left border and the rightmost one
  * touches the right border (even if they must overlap). The
- * @c align_v and @c padding_v properties of the box don't contribute to
+ * @c align_v and @c padding_v properties of the box do not contribute to
  * its behaviour when this layout is chosen.
  *
- * \par Child element's properties:
+ * @par Child element's properties:
  * @c padding_l and @c padding_r sum up to the required width of the
  * child element. The @c align_x property tells the relative position
  * of this overall child width in its allocated cell (@c 0.0 to
@@ -11346,41 +13483,50 @@ EAPI void                       evas_object_box_layout_homogeneous_horizontal(Ev
  * height of the box. A value of @c -1.0 to @c align_y makes the box
  * try to resize this child element to the exact height of its parent
  * (respecting the max hint on the child's height).
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  o     The box object in question
+ * @param[in]  priv  The smart data of the @a o
+ * @param[in]  data  The data pointer passed on evas_object_box_layout_set(), if any
  */
 EAPI void                       evas_object_box_layout_homogeneous_max_size_horizontal(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Layout function which sets the box @a o to a <b>maximum size,
- * homogeneous</b> vertical box
+ * @brief   Sets the box @a o to a <b>maximum size, homogeneous</b> vertical box.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function behaves analogously to
- * evas_object_box_layout_homogeneous_max_size_horizontal(). The
- * description of its behaviour can be derived from that function's
- * documentation.
+ * @remarks This function behaves analogously to 
+ *          evas_object_box_layout_homogeneous_max_size_horizontal(). The
+ *          description of its behaviour can be derived from that function's
+ *          documentation.
+ *
+ * @param[in]  o     The box object in question
+ * @param[in]  priv  The smart data of the @a o
+ * @param[in]  data  The data pointer passed on evas_object_box_layout_set(), if any
  */
 EAPI void                       evas_object_box_layout_homogeneous_max_size_vertical(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Layout function which sets the box @a o to a @b flow horizontal
- * box.
- *
- * @param o The box object in question
- * @param priv The smart data of the @p o
- * @param data The data pointer passed on
- * evas_object_box_layout_set(), if any
+ * @brief  Sets the box @a o to a @b flow horizontal box.
  *
  * In a flow horizontal box, the box's child elements are placed in
  * @b rows (think of text as an analogy). A row has as much elements as
  * can fit into the box's width. The box's overall behavior is
  * controlled by its properties, which are set by the
  * <c>evas_object_box_{h,v}_{align,padding}_set()</c> family of
- * functions.  The size hints of the elements in the box -- set by the
+ * functions. The size hints of the elements in the box -- set by the
  * <c>evas_object_size_hint_{align,padding,weight}_set()</c> functions
  * -- also control the way this function works.
  *
- * \par Box's properties:
+ * @par Box's properties:
  * @c padding_h tells the box to draw empty spaces of that size, in
- * pixels, between the child objects's cells. @c align_h dictates the
+ * pixels, between the child objects' cells. @c align_h dictates the
  * horizontal alignment of the rows (@c 0.0 to left align them, @c 1.0
  * to right align). A value of @c -1.0 to @c align_h lets the rows
  * @b justified horizontally. @c align_v controls the vertical alignment
@@ -11391,7 +13537,7 @@ EAPI void                       evas_object_box_layout_homogeneous_max_size_vert
  * the bottom border (even if they must overlap). @c padding_v has no
  * influence on the layout.
  *
- * \par Child element's properties:
+ * @par Child element's properties:
  * @c padding_l and @c padding_r sum up to the required width of the
  * child element. The @c align_x property has no influence on the
  * layout. The child's @c padding_t and @c padding_b sum up to the
@@ -11399,35 +13545,47 @@ EAPI void                       evas_object_box_layout_homogeneous_max_size_vert
  * row justifying) of setting space between rows. Note, however, that
  * @c align_y dictates positioning relative to the <b>largest
  * height</b> required by a child object in the actual row.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  o     The box object in question
+ * @param[in]  priv  The smart data of the @a o
+ * @param[in]  data  The data pointer passed on evas_object_box_layout_set(), if any
  */
 EAPI void                       evas_object_box_layout_flow_horizontal(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Layout function which sets the box @a o to a @b flow vertical box.
+ * @brief   Sets the box @a o to a @b flow vertical box.
+ *
+ * @details This function behaves analogously to
+ *          evas_object_box_layout_flow_horizontal(). The description of its
+ *          behaviour can be derived from that function's documentation.
+ *
+ * @param[in]  o     The box object in question
+ * @param[in]  priv  The smart data of the @a o
+ * @param[in]  data  The data pointer passed on evas_object_box_layout_set(), if any
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function behaves analogously to
- * evas_object_box_layout_flow_horizontal(). The description of its
- * behaviour can be derived from that function's documentation.
  */
 EAPI void                       evas_object_box_layout_flow_vertical(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Layout function which sets the box @a o to a @b stacking box
+ * @brief  Sets the box @a o to a @b stacking box.
  *
- * @param o The box object in question
- * @param priv The smart data of the @p o
- * @param data The data pointer passed on
- * evas_object_box_layout_set(), if any
+ * In a stacking box, all children are given the same size -- the
+ * box's own size -- and they are stacked one above the other, so
+ * that the first object in @a o's internal list of child elements
+ * are the bottommost in the stack.
  *
- * In a stacking box, all children will be given the same size -- the
- * box's own size -- and they will be stacked one above the other, so
- * that the first object in @p o's internal list of child elements
- * will be the bottommost in the stack.
- *
- * \par Box's properties:
+ * @par Box's properties:
  * No box properties are used.
  *
- * \par Child element's properties:
+ * @par Child element's properties:
  * @c padding_l and @c padding_r sum up to the required width of the
  * child element. The @c align_x property tells the relative position
  * of this overall child width in its allocated cell (@c 0.0 to
@@ -11436,400 +13594,495 @@ EAPI void                       evas_object_box_layout_flow_vertical(Evas_Object
  * width of its cell (respecting the min and max hints on the child's
  * width and accounting for its horizontal padding properties). The
  * same applies to the vertical axis.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  o     The box object in question
+ * @param[in]  priv  The smart data of the @a o
+ * @param[in]  data  The data pointer passed on evas_object_box_layout_set(), if any
  */
 EAPI void                       evas_object_box_layout_stack(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Set the alignment of the whole bounding box of contents, for a
- * given box object.
+ * @brief   Sets the alignment of the whole bounding box of contents, for a
+ *          given box object.
+ *
+ * @details This influences how a box object is to align its bounding box
+ *          of contents within its own area. The values @b must be in the range
+ *          @c 0.0 - @c 1.0, or undefined behavior is expected. For horizontal
+ *          alignment, @c 0.0 means to the left, with @c 1.0 meaning to the
+ *          right. For vertical alignment, @c 0.0 means to the top, with @c 1.0
+ *          meaning to the bottom.
  *
- * @param o The given box object to set alignment from
- * @param horizontal The horizontal alignment, in pixels
- * @param vertical the vertical alignment, in pixels
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This will influence how a box object is to align its bounding box
- * of contents within its own area. The values @b must be in the range
- * @c 0.0 - @c 1.0, or undefined behavior is expected. For horizontal
- * alignment, @c 0.0 means to the left, with @c 1.0 meaning to the
- * right. For vertical alignment, @c 0.0 means to the top, with @c 1.0
- * meaning to the bottom.
+ * @remarks The default values for both alignments is @c 0.5.
  *
- * @note The default values for both alignments is @c 0.5.
+ * @param[in]   o           The given box object to set alignment from
+ * @param[in]   horizontal  The horizontal alignment, in pixels
+ * @param[in]   vertical    The vertical alignment, in pixels
  *
  * @see evas_object_box_align_get()
  */
 EAPI void                       evas_object_box_align_set(Evas_Object *o, double horizontal, double vertical) EINA_ARG_NONNULL(1);
 
 /**
- * Get the alignment of the whole bounding box of contents, for a
- * given box object.
+ * @brief   Gets the alignment of the whole bounding box of contents, for a
+ *          given box object.
  *
- * @param o The given box object to get alignment from
- * @param horizontal Pointer to a variable where to store the
- * horizontal alignment
- * @param vertical Pointer to a variable where to store the vertical
- * alignment
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   o           The given box object to get alignment from
+ * @param[out]   horizontal  The pointer to a variable where to store the
+ *                      horizontal alignment
+ * @param[out]   vertical    The pointer to a variable where to store the vertical alignment
  *
  * @see evas_object_box_align_set() for more information
  */
 EAPI void                       evas_object_box_align_get(const Evas_Object *o, double *horizontal, double *vertical) EINA_ARG_NONNULL(1);
 
 /**
- * Set the (space) padding between cells set for a given box object.
+ * @brief   Sets the (space) padding between cells set for a given box object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param o The given box object to set padding from
- * @param horizontal The horizontal padding, in pixels
- * @param vertical the vertical padding, in pixels
+ * @remarks The default values for both padding components is @c 0.
  *
- * @note The default values for both padding components is @c 0.
+ * @param[in]   o           The given box object to set padding from
+ * @param[in]   horizontal  The horizontal padding, in pixels
+ * @param[in]   vertical    The vertical padding, in pixels
  *
  * @see evas_object_box_padding_get()
  */
 EAPI void                       evas_object_box_padding_set(Evas_Object *o, Evas_Coord horizontal, Evas_Coord vertical) EINA_ARG_NONNULL(1);
 
 /**
- * Get the (space) padding between cells set for a given box object.
+ * @brief   Gets the (space) padding between cells set for a given box object.
  *
- * @param o The given box object to get padding from
- * @param horizontal Pointer to a variable where to store the
- * horizontal padding
- * @param vertical Pointer to a variable where to store the vertical
- * padding
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   o           The given box object to get padding from
+ * @param[out]   horizontal  The pointer to a variable where to store the
+ *                      horizontal padding
+ * @param[out]   vertical    The pointer to a variable where to store the vertical padding
  *
  * @see evas_object_box_padding_set()
  */
 EAPI void                       evas_object_box_padding_get(const Evas_Object *o, Evas_Coord *horizontal, Evas_Coord *vertical) EINA_ARG_NONNULL(1);
 
 /**
- * Append a new @a child object to the given box object @a o.
+ * @brief   Appends a new @a child object to the given box object @a o.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param o The given box object
- * @param child A child Evas object to be made a member of @p o
- * @return A box option bound to the recently added box item or @c
- * NULL, on errors
+ * @remarks On success, the @c "child,added" smart event takes place.
  *
- * On success, the @c "child,added" smart event will take place.
+ * @remarks The actual placing of the item relative to the area of @a o
+ *          depends on the layout set to it. For example, on horizontal layouts
+ *          an item in the end of the box's list of children appear on its right.
  *
- * @note The actual placing of the item relative to @p o's area will
- * depend on the layout set to it. For example, on horizontal layouts
- * an item in the end of the box's list of children will appear on its
- * right.
+ * @remarks This call triggers the box's _Evas_Object_Box_Api::append
+ *          smart function.
  *
- * @note This call will trigger the box's _Evas_Object_Box_Api::append
- * smart function.
+ * @param[in]   o      The given box object
+ * @param[in]   child  A child Evas object to be made a member of @a o
+ * @return  A box option bound to the recently added box item, \n
+ *          otherwise @c NULL on errors
  */
 EAPI Evas_Object_Box_Option    *evas_object_box_append(Evas_Object *o, Evas_Object *child) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Prepend a new @a child object to the given box object @a o.
+ * @brief   Prepends a new @a child object to the given box object @a o.
  *
- * @param o The given box object
- * @param child A child Evas object to be made a member of @p o
- * @return A box option bound to the recently added box item or @c
- * NULL, on errors
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * On success, the @c "child,added" smart event will take place.
+ * @remarks On success, the @c "child,added" smart event takes place.
  *
- * @note The actual placing of the item relative to @p o's area will
- * depend on the layout set to it. For example, on horizontal layouts
- * an item in the beginning of the box's list of children will appear
- * on its left.
+ * @remarks The actual placing of the item relative to the area of @a o
+ *          depends on the layout set to it. For example, on horizontal layouts
+ *          an item in the beginning of the box's list of children appear
+ *          on its left.
  *
- * @note This call will trigger the box's
- * _Evas_Object_Box_Api::prepend smart function.
+ * @remarks This call triggers the box's
+ *          _Evas_Object_Box_Api::prepend smart function.
+ *
+ * @param[in]   o      The given box object
+ * @param[in]   child  A child Evas object to be made a member of @a o
+ * @return  A box option bound to the recently added box item, \n 
+ *          otherwise @c NULL on errors
  */
 EAPI Evas_Object_Box_Option    *evas_object_box_prepend(Evas_Object *o, Evas_Object *child) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Insert a new @a child object <b>before another existing one</b>, in
- * a given box object @a o.
+ * @brief  Inserts a new @a child object <b>before another existing one</b>, in
+ *         a given box object @a o.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param o The given box object
- * @param child A child Evas object to be made a member of @p o
- * @param reference The child object to place this new one before
- * @return A box option bound to the recently added box item or @c
- * NULL, on errors
+ * @remarks On success, the @c "child,added" smart event takes place.
  *
- * On success, the @c "child,added" smart event will take place.
+ * @remarks This function fails if @a reference is not a member of @a o.
  *
- * @note This function will fail if @p reference is not a member of @p
- * o.
+ * @remarks The actual placing of the item relative to the area of @a o
+ *          depends on the layout set to it.
  *
- * @note The actual placing of the item relative to @p o's area will
- * depend on the layout set to it.
+ * @remarks This call triggers the box's
+ *          _Evas_Object_Box_Api::insert_before smart function.
  *
- * @note This call will trigger the box's
- * _Evas_Object_Box_Api::insert_before smart function.
+ * @param[in]   o          The given box object
+ * @param[in]   child      A child Evas object to be made a member of @a o
+ * @param[in]   reference  The child object to place this new one before
+ * @return  A box option bound to the recently added box item, \n 
+ *          otherwise @c NULL on errors
  */
 EAPI Evas_Object_Box_Option    *evas_object_box_insert_before(Evas_Object *o, Evas_Object *child, const Evas_Object *reference) EINA_ARG_NONNULL(1, 2, 3);
 
 /**
- * Insert a new @a child object <b>after another existing one</b>, in
- * a given box object @a o.
+ * @brief   Inserts a new @a child object <b>after another existing one</b>, in
+ *          a given box object @a o.
  *
- * @param o The given box object
- * @param child A child Evas object to be made a member of @p o
- * @param reference The child object to place this new one after
- * @return A box option bound to the recently added box item or @c
- * NULL, on errors
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * On success, the @c "child,added" smart event will take place.
+ * @remarks On success, the @c "child,added" smart event takes place.
  *
- * @note This function will fail if @p reference is not a member of @p
- * o.
+ * @remarks This function fails if @a reference is not a member of @a o.
  *
- * @note The actual placing of the item relative to @p o's area will
- * depend on the layout set to it.
+ * @remarks The actual placing of the item relative to the area of @a o
+ *          depends on the layout set to it.
  *
- * @note This call will trigger the box's
- * _Evas_Object_Box_Api::insert_after smart function.
+ * @remarks This call triggers the box's
+ *          _Evas_Object_Box_Api::insert_after smart function.
+ *
+ * @param[in]   o          The given box object
+ * @param[in]   child      A child Evas object to be made a member of @a o
+ * @param[in]   reference  The child object to place this new one after
+ * @return  A box option bound to the recently added box item, \n 
+ *          otherwise @c NULL on errors
  */
 EAPI Evas_Object_Box_Option    *evas_object_box_insert_after(Evas_Object *o, Evas_Object *child, const Evas_Object *reference) EINA_ARG_NONNULL(1, 2, 3);
 
 /**
- * Insert a new @a child object <b>at a given position</b>, in a given
- * box object @a o.
+ * @brief   Inserts a new @a child object <b>at a given position</b>, in a given
+ *          box object @a o.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param o The given box object
- * @param child A child Evas object to be made a member of @p o
- * @param pos The numeric position (starting from @c 0) to place the
- * new child object at
- * @return A box option bound to the recently added box item or @c
- * NULL, on errors
+ * @remarks On success, the @c "child,added" smart event takes place.
  *
- * On success, the @c "child,added" smart event will take place.
+ * @remarks This function fails if the given position is invalid,
+ *          given the internal list of elements of @a o.
  *
- * @note This function will fail if the given position is invalid,
- * given @p o's internal list of elements.
+ * @remarks The actual placing of the item relative to the area of @a o
+ *          depends on the layout set to it.
  *
- * @note The actual placing of the item relative to @p o's area will
- * depend on the layout set to it.
+ * @remarks This call triggers the box's
+ *          _Evas_Object_Box_Api::insert_at smart function.
  *
- * @note This call will trigger the box's
- * _Evas_Object_Box_Api::insert_at smart function.
+ * @param[in]   o      The given box object
+ * @param[in]   child  A child Evas object to be made a member of @a o
+ * @param[in]   pos    The numeric position (starting from @c 0) to place the
+ *                 new child object at
+ * @return  A box option bound to the recently added box item, \n 
+ *          otherwise @c NULL on errors
  */
 EAPI Evas_Object_Box_Option    *evas_object_box_insert_at(Evas_Object *o, Evas_Object *child, unsigned int pos) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Remove a given object from a box object, unparenting it again.
+ * @brief   Removes a given object from a box object, unparenting it again.
  *
- * @param o The box object to remove a child object from
- * @param child The handle to the child object to be removed
- * @return @c EINA_TRUE, on success, @c EINA_FALSE otherwise
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * On removal, you'll get an unparented object again, just as it was
- * before you inserted it in the box. The
- * _Evas_Object_Box_Api::option_free box smart callback will be called
- * automatically for you and, also, the @c "child,removed" smart event
- * will take place.
+ * @remarks On removal, you get an unparented object again, just as it is
+ *          before you inserted it in the box. The
+ *          _Evas_Object_Box_Api::option_free box smart callback is called
+ *          automatically for you and, also, the @c "child,removed" smart event
+ *          takes place.
  *
- * @note This call will trigger the box's _Evas_Object_Box_Api::remove
- * smart function.
+ * @remarks This call triggers the box's _Evas_Object_Box_Api::remove
+ *          smart function.
+ *
+ * @param[in]   o      The box object to remove a child object from
+ * @param[in]   child  The handle to the child object to be removed
+ * @return  #EINA_TRUE if the object is removed from the box object successfully, \n 
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                  evas_object_box_remove(Evas_Object *o, Evas_Object *child) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Remove an object, <b>bound to a given position</b> in a box object,
- * unparenting it again.
+ * @brief   Removes an object, <b>bound to a given position</b> in a box object,
+ *          unparenting it again.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param o The box object to remove a child object from
- * @param pos The numeric position (starting from @c 0) of the child
- * object to be removed
- * @return @c EINA_TRUE, on success, @c EINA_FALSE otherwise
+ * @remarks On removal, you get an unparented object again, just as it is
+ *          before you inserted it in the box. The @c option_free() box smart
+ *          callback is called automatically for you and, also, the
+ *          @c "child,removed" smart event takes place.
  *
- * On removal, you'll get an unparented object again, just as it was
- * before you inserted it in the box. The @c option_free() box smart
- * callback will be called automatically for you and, also, the
- * @c "child,removed" smart event will take place.
+ * @remarks This function fails if the given position is invalid,
+ *          given the internal list of elements of @a o.
  *
- * @note This function will fail if the given position is invalid,
- * given @p o's internal list of elements.
+ * @remarks This call triggers the box's
+ *          _Evas_Object_Box_Api::remove_at smart function.
  *
- * @note This call will trigger the box's
- * _Evas_Object_Box_Api::remove_at smart function.
+ * @param[in]   o    The box object to remove a child object from
+ * @param[in]   pos  The numeric position (starting from @c 0) of the child
+ *               object to be removed
+ * @return  #EINA_TRUE if the object is removed successfully, 
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                  evas_object_box_remove_at(Evas_Object *o, unsigned int pos) EINA_ARG_NONNULL(1);
 
 /**
- * Remove @b all child objects from a box object, unparenting them
- * again.
+ * @brief   Removes @b all child objects from a box object, unparenting them again.
  *
- * @param o The box object to remove a child object from
- * @param clear if true, it will delete just removed children.
- * @return @c EINA_TRUE, on success, @c EINA_FALSE otherwise
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This has the same effect of calling evas_object_box_remove() on
- * each of @p o's child objects, in sequence. If, and only if, all
- * those calls succeed, so does this one.
+ * @remarks This has the same effect of calling evas_object_box_remove() on
+ *          each of @a o's child objects, in sequence. If, and only if, all
+ *          those calls succeed, so does this one.
+ *
+ * @param[in]   o      The box object to remove a child object from
+ * @param[in]   clear  Set #EINA_TRUE to delete the just removed children, \n
+ *                 otherwise set #EINA_FALSE to not delete the children
+ * @return  #EINA_TRUE if the child objects are removed successfully, \n
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                  evas_object_box_remove_all(Evas_Object *o, Eina_Bool clear) EINA_ARG_NONNULL(1);
 
 /**
- * Get an iterator to walk the list of children of a given box object.
+ * @brief   Gets an iterator to walk the list of children of a given box object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param o The box to retrieve an items iterator from
- * @return An iterator on @p o's child objects, on success, or @c NULL,
- * on errors
+ * @remarks Do @b not remove or delete objects while walking the list.
  *
- * @note Do @b not remove or delete objects while walking the list.
+ * @param[in]   o  The box to retrieve an items iterator from
+ * @return  An iterator on @a o's child objects, \n
+ *          otherwise @c NULL on errors
  */
 EAPI Eina_Iterator             *evas_object_box_iterator_new(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Get an accessor (a structure providing random items access) to the
- * list of children of a given box object.
+ * @brief   Gets an accessor (a structure providing random items access) to the
+ *          list of children of a given box object.
  *
- * @param o The box to retrieve an items iterator from
- * @return An accessor on @p o's child objects, on success, or @c NULL,
- * on errors
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note Do not remove or delete objects while walking the list.
+ * @remarks Do not remove or delete objects while walking the list.
+ *
+ * @param[in]   o  The box to retrieve an items iterator from
+ * @return  An accessor on @a o's child objects, \n 
+ *          otherwise @c NULL on errors
  */
 EAPI Eina_Accessor             *evas_object_box_accessor_new(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Get the list of children objects in a given box object.
+ * @brief   Gets the list of children objects in a given box object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param o The box to retrieve an items list from
- * @return A list of @p o's child objects, on success, or @c NULL,
- * on errors (or if it has no child objects)
+ * @remarks The returned list should be freed with @c eina_list_free() when you
+ *          no longer need it.
  *
- * The returned list should be freed with @c eina_list_free() when you
- * no longer need it.
+ * @remarks This is a duplicate of the list kept by the box internally.
+ *          It is up to the user to destroy it when it no longer needs it.
+ *          It is possible to remove objects from the box when walking
+ *          this list, but these removals are not reflected on it.
  *
- * @note This is a duplicate of the list kept by the box internally.
- *       It's up to the user to destroy it when it no longer needs it.
- *       It's possible to remove objects from the box when walking
- *       this list, but these removals won't be reflected on it.
+ * @param[in]   o  The box to retrieve an items list from
+ * @return  A list of @a o's child objects, \n 
+ *          otherwise @c NULL on errors or if it has no child objects
  */
 EAPI Eina_List                 *evas_object_box_children_get(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Get the name of the property of the child elements of the box @a o
- * which have @a id as identifier
+ * @brief   Gets the name of the property of the child elements of the box @a o
+ *          which have @a id as identifier.
  *
- * @param o The box to search child options from
- * @param property The numerical identifier of the option being searched,
- * for its name
- * @return The name of the given property or @c NULL, on errors.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note This call won't do anything for a canonical Evas box. Only
- * users which have @b subclassed it, setting custom box items options
- * (see #Evas_Object_Box_Option) on it, would benefit from this
- * function. They'd have to implement it and set it to be the
- * _Evas_Object_Box_Api::property_name_get smart class function of the
- * box, which is originally set to @c NULL.
+ * @remarks This call does not do anything for a canonical Evas box. Only
+ *          users which have @b subclassed it, setting custom box items options
+ *          (see #Evas_Object_Box_Option) on it, would benefit from this
+ *          function. They would have to implement it and set it to be the
+ *          _Evas_Object_Box_Api::property_name_get smart class function of the
+ *          box, which is originally set to @c NULL.
+ *
+ * @param[in]   o         The box to search child options from
+ * @param[in]   property  The numerical identifier of the option being searched,
+ *                    for its name
+ * @return  The name of the given property, \n
+ *          otherwise @c NULL on errors
  */
 EAPI const char                *evas_object_box_option_property_name_get(const Evas_Object *o, int property) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Get the numerical identifier of the property of the child elements
- * of the box @a o which have @a name as name string
+ * @brief   Gets the numerical identifier of the property of the child elements
+ *          of the box @a o which have @a name as name string.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param o The box to search child options from
- * @param name The name string of the option being searched, for
- * its ID
- * @return The numerical ID of the given property or @c -1, on
- * errors.
+ * @remarks This call does not do anything for a canonical Evas box. Only
+ *          users which have @b subclassed it, setting custom box items options
+ *          (see #Evas_Object_Box_Option) on it, would benefit from this
+ *          function. They would have to implement it and set it to be the
+ *          _Evas_Object_Box_Api::property_id_get smart class function of the
+ *          box, which is originally set to @c NULL.
  *
- * @note This call won't do anything for a canonical Evas box. Only
- * users which have @b subclassed it, setting custom box items options
- * (see #Evas_Object_Box_Option) on it, would benefit from this
- * function. They'd have to implement it and set it to be the
- * _Evas_Object_Box_Api::property_id_get smart class function of the
- * box, which is originally set to @c NULL.
+ * @param[in]   o     The box to search child options from
+ * @param[in]   name  The name string of the option being searched, for its ID
+ * @return  The numerical ID of the given property, \n 
+ *          otherwise @c -1 on errors
  */
 EAPI int                        evas_object_box_option_property_id_get(const Evas_Object *o, const char *name) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
 
 /**
- * Set a property value (by its given numerical identifier), on a
- * given box child element
+ * @brief   Sets a property value (by its given numerical identifier), on a
+ *          given box child element
  *
- * @param o The box parenting the child element
- * @param opt The box option structure bound to the child box element
- * to set a property on
- * @param property The numerical ID of the given property
- * @param ... (List of) actual value(s) to be set for this
- * property. It (they) @b must be of the same type the user has
- * defined for it (them).
- * @return @c EINA_TRUE on success, @c EINA_FALSE on failure.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note This call won't do anything for a canonical Evas box. Only
- * users which have @b subclassed it, setting custom box items options
- * (see #Evas_Object_Box_Option) on it, would benefit from this
- * function. They'd have to implement it and set it to be the
- * _Evas_Object_Box_Api::property_set smart class function of the box,
- * which is originally set to @c NULL.
+ * @remarks This call does not do anything for a canonical Evas box. Only
+ *          users which have @b subclassed it, setting custom box items options
+ *          (see #Evas_Object_Box_Option) on it, would benefit from this
+ *          function. They would have to implement it and set it to be the
+ *          _Evas_Object_Box_Api::property_set smart class function of the box,
+ *          which is originally set to @c NULL.
  *
- * @note This function will internally create a variable argument
- * list, with the values passed after @p property, and call
- * evas_object_box_option_property_vset() with this list and the same
- * previous arguments.
+ * @remarks This function internally creates a variable argument
+ *          list, with the values passed after @a property, and call
+ *          evas_object_box_option_property_vset() with this list and the same
+ *          previous arguments.
+ *
+ * @param[in]   o         The box parenting the child element
+ * @param[in]   opt       The box option structure bound to the child box element
+ *                    to set a property on
+ * @param[in]   property  The numerical ID of the given property
+ * @param[in]   ...       (List of) actual value(s) to be set for this property \n
+ *                    It (they) @b must be of the same type the user has
+ *                    defined for it (them).
+ * @return  #EINA_TRUE if the property value is set successfully, 
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                  evas_object_box_option_property_set(Evas_Object *o, Evas_Object_Box_Option *opt, int property, ...) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Set a property value (by its given numerical identifier), on a
- * given box child element -- by a variable argument list
+ * @brief   Sets a property value (by its given numerical identifier), on a
+ *          given box child element -- by a variable argument list
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param o The box parenting the child element
- * @param opt The box option structure bound to the child box element
- * to set a property on
- * @param property The numerical ID of the given property
- * @param args The variable argument list implementing the value to
- * be set for this property. It @b must be of the same type the user has
- * defined for it.
- * @return @c EINA_TRUE on success, @c EINA_FALSE on failure.
+ * @remarks This is a variable argument list variant of the
+ *          evas_object_box_option_property_set(). See its documentation for
+ *          more details.
  *
- * This is a variable argument list variant of the
- * evas_object_box_option_property_set(). See its documentation for
- * more details.
+ * @param[in]   o         The box parenting the child element
+ * @param[in]   opt       The box option structure bound to the child box element
+ *                    to set a property on
+ * @param[in]   property  The numerical ID of the given property
+ * @param[in]   args      The variable argument list implementing the value to
+ *                    be set for this property. It @b must be of the same type the user has
+ *                    defined for it.
+ * @return  #EINA_TRUE if teh property value is set successfully, \n
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                  evas_object_box_option_property_vset(Evas_Object *o, Evas_Object_Box_Option *opt, int property, va_list args) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Get a property's value (by its given numerical identifier), on a
- * given box child element
+ * @brief   Gets a property's value (by its given numerical identifier), on a
+ *          given box child element.
  *
- * @param o The box parenting the child element
- * @param opt The box option structure bound to the child box element
- * to get a property from
- * @param property The numerical ID of the given property
- * @param ... (List of) pointer(s) where to store the value(s) set for
- * this property. It (they) @b must point to variable(s) of the same
- * type the user has defined for it (them).
- * @return @c EINA_TRUE on success, @c EINA_FALSE on failure.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note This call won't do anything for a canonical Evas box. Only
- * users which have @b subclassed it, getting custom box items options
- * (see #Evas_Object_Box_Option) on it, would benefit from this
- * function. They'd have to implement it and get it to be the
- * _Evas_Object_Box_Api::property_get smart class function of the
- * box, which is originally get to @c NULL.
+ * @remarks This call does not do anything for a canonical Evas box. Only
+ *          users which have @b subclassed it, getting custom box items options
+ *          (see #Evas_Object_Box_Option) on it, would benefit from this
+ *          function. They would have to implement it and get it to be the
+ *          _Evas_Object_Box_Api::property_get smart class function of the
+ *          box, which is originally get to @c NULL.
  *
- * @note This function will internally create a variable argument
- * list, with the values passed after @p property, and call
- * evas_object_box_option_property_vget() with this list and the same
- * previous arguments.
+ * @remarks This function internally creates a variable argument
+ *          list, with the values passed after @a property, and call
+ *          evas_object_box_option_property_vget() with this list and the same
+ *          previous arguments.
+ *
+ * @param[in]   o         The box parenting the child element
+ * @param[in]   opt       The box option structure bound to the child box element
+ *                    to get a property from
+ * @param[in]   property  The numerical ID of the given property
+ * @param[in]   ...       (List of) pointer(s) where to store the value(s) set for this property, \n
+ *                    It (they) @b must point to variable(s) of the same type the user 
+ *                    has defined for it (them).
+ * @return  #EINA_TRUE if the property values are obtained successfully, \n
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                  evas_object_box_option_property_get(const Evas_Object *o, Evas_Object_Box_Option *opt, int property, ...) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Get a property's value (by its given numerical identifier), on a
- * given box child element -- by a variable argument list
+ * @brief   Gets a property's value (by its given numerical identifier), on a
+ *          given box child element -- by a variable argument list
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param o The box parenting the child element
- * @param opt The box option structure bound to the child box element
- * to get a property from
- * @param property The numerical ID of the given property
- * @param args The variable argument list with pointers to where to
- * store the values of this property. They @b must point to variables
- * of the same type the user has defined for them.
- * @return @c EINA_TRUE on success, @c EINA_FALSE on failure.
+ * @remarks This is a variable argument list variant of the
+ *          evas_object_box_option_property_get(). See its documentation for
+ *          more details.
  *
- * This is a variable argument list variant of the
- * evas_object_box_option_property_get(). See its documentation for
- * more details.
+ * @param[in]   o         The box parenting the child element
+ * @param[in]   opt       The box option structure bound to the child box element
+ *                    to get a property from
+ * @param[in]   property  The numerical ID of the given property
+ * @param[in]   args      The variable argument list with pointers to where to
+ *                    store the values of this property \n 
+ *                    They @b must point to variables 
+ *                    of the same type the user has defined for them.
+ * @return  #EINA_TRUE if the property values are obtained successfully, \n
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                  evas_object_box_option_property_vget(const Evas_Object *o, Evas_Object_Box_Option *opt, int property, va_list args) EINA_ARG_NONNULL(1, 2);
 
@@ -11839,368 +14092,581 @@ EAPI Eina_Bool                  evas_object_box_option_property_vget(const Evas_
 
 /**
  * @defgroup Evas_Object_Table Table Smart Object.
+ * @ingroup Evas_Smart_Object_Group
  *
- * Convenience smart object that packs children using a tabular
- * layout using children size hints to define their size and
- * alignment inside their cell space.
+ * @brief   This group provides functions for table smart objects.
  *
- * @ref tutorial_table shows how to use this Evas_Object.
+ * @remarks Convenience smart object that packs children using a tabular
+ *          layout using children size hints to define their size and
+ *          alignment inside their cell space.
  *
  * @see @ref Evas_Object_Group_Size_Hints
  *
- * @ingroup Evas_Smart_Object_Group
- *
  * @{
  */
 
 /**
- * @brief Create a new table.
+ * @brief   Creates a new table.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param evas Canvas in which table will be added.
+ * @param[in]   evas  The canvas in which table are added
+ * @return  The new table object
  */
 EAPI Evas_Object                       *evas_object_table_add(Evas *evas) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * @brief Create a table that is child of a given element @a parent.
+ * @brief   Creates a table that is child of a given element @a parent.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   parent  The parent element
+ * @return  The new table object
  *
  * @see evas_object_table_add()
  */
 EAPI Evas_Object                       *evas_object_table_add_to(Evas_Object *parent) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * @brief Set how this table should layout children.
+ * @brief Sets how this table should layout children.
  *
  * @todo consider aspect hint and respect it.
  *
  * @par EVAS_OBJECT_TABLE_HOMOGENEOUS_NONE
- * If table does not use homogeneous mode then columns and rows will
- * be calculated based on hints of individual cells. This operation
+ * If table does not use homogeneous mode then columns and rows
+ * are calculated based on hints of individual cells. This operation
  * mode is more flexible, but more complex and heavy to calculate as
  * well. @b Weight properties are handled as a boolean expand. Negative
- * alignment will be considered as 0.5. This is the default.
+ * alignment is considered as @c 0.5. This is the default.
  *
  * @todo @c EVAS_OBJECT_TABLE_HOMOGENEOUS_NONE should balance weight.
  *
  * @par EVAS_OBJECT_TABLE_HOMOGENEOUS_TABLE
- * When homogeneous is relative to table the own table size is divided
+ * When homogeneous is relative to table, the own table size is divided
  * equally among children, filling the whole table area. That is, if
- * table has @c WIDTH and @c COLUMNS, each cell will get <tt>WIDTH /
+ * table has @c WIDTH and @c COLUMNS, each cell gets <tt>WIDTH /
  * COLUMNS</tt> pixels. If children have minimum size that is larger
- * than this amount (including padding), then it will overflow and be
+ * than this amount (including padding), then it overflows and is
  * aligned respecting the alignment hint, possible overlapping sibling
  * cells. @b Weight hint is used as a boolean, if greater than zero it
- * will make the child expand in that axis, taking as much space as
- * possible (bounded to maximum size hint). Negative alignment will be
- * considered as 0.5.
+ * makes the child expand in that axis, taking as much space as
+ * possible (bounded to maximum size hint). Negative alignment is
+ * considered as @c 0.5.
  *
  * @par EVAS_OBJECT_TABLE_HOMOGENEOUS_ITEM
- * When homogeneous is relative to item it means the greatest minimum
- * cell size will be used. That is, if no element is set to expand,
- * the table will have its contents to a minimum size, the bounding
- * box of all these children will be aligned relatively to the table
+ * When homogeneous is relative to item, it means the greatest minimum
+ * cell size is used. That is, if no element is set to expand,
+ * the table has its contents to a minimum size, the bounding
+ * box of all these children is aligned relatively to the table
  * object using evas_object_table_align_get(). If the table area is
- * too small to hold this minimum bounding box, then the objects will
- * keep their size and the bounding box will overflow the box area,
+ * too small to hold this minimum bounding box, then the objects
+ * keep their size and the bounding box overflows the box area,
  * still respecting the alignment. @b Weight hint is used as a
- * boolean, if greater than zero it will make that cell expand in that
+ * boolean, if greater than zero it makes that cell expand in that
  * axis, toggling the <b>expand mode</b>, which makes the table behave
  * much like @b EVAS_OBJECT_TABLE_HOMOGENEOUS_TABLE, except that the
- * bounding box will overflow and items will not overlap siblings. If
- * no minimum size is provided at all then the table will fallback to
+ * bounding box overflows and items do not overlap siblings. If
+ * no minimum size is provided at all then the table fallsback to
  * expand mode as well.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  o            The table object 
+ * @param[in]  homogeneous  The homogeneous mode
  */
 EAPI void                               evas_object_table_homogeneous_set(Evas_Object *o, Evas_Object_Table_Homogeneous_Mode homogeneous) EINA_ARG_NONNULL(1);
 
 /**
- * Get the current layout homogeneous mode.
+ * @brief  Gets the current layout homogeneous mode.
  *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  o  The table object 
+ * @return The homogeneous mode
+
  * @see evas_object_table_homogeneous_set()
  */
 EAPI Evas_Object_Table_Homogeneous_Mode evas_object_table_homogeneous_get(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Set padding between cells.
+ * @brief  Sets padding between cells.
+ *
+ *  @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  o           The table object 
+ * @param[in]  horizontal  The horizontal padding to set
+ * @param[in]  vertical    The vertical padding to set
+ *
  */
 EAPI void                               evas_object_table_padding_set(Evas_Object *o, Evas_Coord horizontal, Evas_Coord vertical) EINA_ARG_NONNULL(1);
 
 /**
- * Get padding between cells.
+ * @brief  Gets padding between cells.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  o           The table object 
+ * @param[out]  horizontal  The horizontal padding that is obtained
+ * @param[out]  vertical    The vertical padding that is obtained
  */
 EAPI void                               evas_object_table_padding_get(const Evas_Object *o, Evas_Coord *horizontal, Evas_Coord *vertical) EINA_ARG_NONNULL(1);
 
 /**
- * Set the alignment of the whole bounding box of contents.
+ * @brief  Sets the alignment of the whole bounding box of contents.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  o           The table object 
+ * @param[in]  horizontal  The horizontal alignment to set
+ * @param[in]  vertical    The vertical alignment to set
  */
 EAPI void                               evas_object_table_align_set(Evas_Object *o, double horizontal, double vertical) EINA_ARG_NONNULL(1);
 
 /**
- * Get alignment of the whole bounding box of contents.
+ * @brief  Gets the alignment of the whole bounding box of contents.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  o           The table object 
+ * @param[out]  horizontal  The horizontal alignment that is obtained
+ * @param[out]  vertical    The vertical alignment that is obtained
  */
 EAPI void                               evas_object_table_align_get(const Evas_Object *o, double *horizontal, double *vertical) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the mirrored mode of the table. In mirrored mode the table items go
- * from right to left instead of left to right. That is, 1,1 is top right, not
- * top left.
+ * @brief   Sets the mirrored mode of the table. 
+ * @since   1.1
  *
- * @param o The table object.
- * @param mirrored the mirrored mode to set
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * remarks  In mirrored mode the table items go from right to left instead of left to right. 
+ *          That is, 1,1 is top right, not top left.
+ *
+ * @param[in]   o         The table object
+ * @param[in]   mirrored  The mirrored mode to set
  */
 EAPI void                               evas_object_table_mirrored_set(Evas_Object *o, Eina_Bool mirrored) EINA_ARG_NONNULL(1);
 
 /**
- * Gets the mirrored mode of the table.
+ * @brief   Gets the mirrored mode of the table.
+ * @since   1.1
  *
- * @param o The table object.
- * @return @c EINA_TRUE if it's a mirrored table, @c EINA_FALSE otherwise.
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   o  The table object
+ * @return  #EINA_TRUE if it is a mirrored table, \n
+ *          otherwise #EINA_FALSE if it is not a mirrored table
  * @see evas_object_table_mirrored_set()
  */
 EAPI Eina_Bool                          evas_object_table_mirrored_get(const Evas_Object *o) EINA_ARG_NONNULL(1);
 
 /**
- * Get packing location of a child of table
+ * @brief   Gets packing location of a child of table.
+ * @since   1.1
  *
- * @param o The given table object.
- * @param child The child object to add.
- * @param col pointer to store relative-horizontal position to place child.
- * @param row pointer to store relative-vertical position to place child.
- * @param colspan pointer to store how many relative-horizontal position to use for this child.
- * @param rowspan pointer to store how many relative-vertical position to use for this child.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @return 1 on success, 0 on failure.
- * @since 1.1
+ * @param[in]   o        The given table object
+ * @param[in]   child    The child object to add
+ * @param[out]   col      The pointer to store relative-horizontal position to place child
+ * @param[out]   row      The pointer to store relative-vertical position to place child
+ * @param[out]   colspan  The pointer to store how many relative-horizontal position to use for this child
+ * @param[out]   rowspan  The pointer to store how many relative-vertical position to use for this child
+ *
+ * @return  #EINA_TRUE if the packing location is obtained successfully, \n
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                          evas_object_table_pack_get(const Evas_Object *o, Evas_Object *child, unsigned short *col, unsigned short *row, unsigned short *colspan, unsigned short *rowspan);
 
 /**
- * Add a new child to a table object or set its current packing.
+ * @brief   Adds a new child to a table object or set its current packing.
  *
- * @param o The given table object.
- * @param child The child object to add.
- * @param col relative-horizontal position to place child.
- * @param row relative-vertical position to place child.
- * @param colspan how many relative-horizontal position to use for this child.
- * @param rowspan how many relative-vertical position to use for this child.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @return 1 on success, 0 on failure.
+ * @param[in]   o        The given table object
+ * @param[in]   child    The child object to add
+ * @param[in]   col      The relative-horizontal position to place the child
+ * @param[in]   row      The relative-vertical position to place the child
+ * @param[in]   colspan  The number of relative-horizontal position to use for this child
+ * @param[in]   rowspan  The number of relative-vertical position to use for this child
+ * @return  #EINA_TRUE if the new child is added successfully, \n
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                          evas_object_table_pack(Evas_Object *o, Evas_Object *child, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Remove child from table.
+ * @brief   Removes child from table.
  *
- * @note removing a child will immediately call a walk over children in order
- *       to recalculate numbers of columns and rows. If you plan to remove
- *       all children, use evas_object_table_clear() instead.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @return 1 on success, 0 on failure.
+ * @remarks Removing a child immediately calls a walk over children in order
+ *          to recalculate the numbers of columns and rows. If you plan to remove
+ *          all children, use evas_object_table_clear() instead.
+ *
+ * @param[in]   o      The given table object
+ * @param[in]   child    The child object to remove
+ * @return  #EINA_TRUE if the child is removed successfully, \n
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool                          evas_object_table_unpack(Evas_Object *o, Evas_Object *child) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Faster way to remove all child objects from a table object.
+ * @brief   Removes all child objects from a table object.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param o The given table object.
- * @param clear if true, it will delete just removed children.
+ * @remarks This is a faster way to remove the child objects.
+ *
+ * @param[in]   o      The given table object
+ * @param[in]   clear  Set #EINA_TRUE to delete the just removed children, \n
+ *                 otherwise set #EINA_FALSE to not delete the removed children
  */
 EAPI void                               evas_object_table_clear(Evas_Object *o, Eina_Bool clear) EINA_ARG_NONNULL(1);
 
 /**
- * Get the number of columns and rows this table takes.
+ * @brief   Gets the number of columns and rows this table takes.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note columns and rows are virtual entities, one can specify a table
- *       with a single object that takes 4 columns and 5 rows. The only
- *       difference for a single cell table is that paddings will be
- *       accounted proportionally.
+ * @remarks The columns and rows are virtual entities, one can specify a table
+ *          with a single object that takes 4 columns and 5 rows. The only
+ *          difference for a single cell table is that paddings are
+ *          accounted proportionally.
+ *
+ * @param[in]   o     The table object 
+ * @param[out]   cols  The number of columns
+ * @param[out]   rows  The number of rows
  */
 EAPI void                               evas_object_table_col_row_size_get(const Evas_Object *o, int *cols, int *rows) EINA_ARG_NONNULL(1);
 
 /**
- * Get an iterator to walk the list of children for the table.
+ * @brief    Gets an iterator to walk through the list of children for the table.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note Do not remove or delete objects while walking the list.
+ * @remarks  Do not remove or delete objects while walking the list.
+ *
+ * @param[in]    o  The table object 
+ * @return   An iterator to walk through the children of the object, \n
+ *           otherwise @c NULL in case of errors
  */
 EAPI Eina_Iterator                     *evas_object_table_iterator_new(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Get an accessor to get random access to the list of children for the table.
+ * @brief    Gets an accessor to get random access to the list of children for the table.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note Do not remove or delete objects while walking the list.
+ * @remarks  Do not remove or delete objects while walking the list.
+ *
+ * @param[in]    o  The table object 
+ * @return   An accessor on @a o's child objects, \n
+ *           otherwise @c NULL in case of errors
  */
 EAPI Eina_Accessor                     *evas_object_table_accessor_new(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Get the list of children for the table.
+ * @brief   Gets the list of children for the table.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note This is a duplicate of the list kept by the table internally.
- *       It's up to the user to destroy it when it no longer needs it.
- *       It's possible to remove objects from the table when walking this
- *       list, but these removals won't be reflected on it.
+ * @remarks This is a duplicate of the list kept by the table internally.
+ *          It is up to the user to destroy it when it no longer needs it.
+ *          It is possible to remove objects from the table when walking this
+ *          list, but these removals are not reflected on it.
+ *
+ * @param[in]   o  The table object 
+ * @return  The list of the children, \n
+ *          otherwise @c NULL in case of errors
  */
 EAPI Eina_List                         *evas_object_table_children_get(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Get the child of the table at the given coordinates
+ * @brief    Gets the child of the table at the given coordinates.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @note This does not take into account col/row spanning
+ * @remarks  This does not take into account col or row spanning.
+ *
+ * @param[in]    o    The table object 
+ * @param[in]    col  The number of columns
+ * @param[in]    row  The number of rows
+ * @return   A child of the table object 
  */
 EAPI Evas_Object                       *evas_object_table_child_get(const Evas_Object *o, unsigned short col, unsigned short row) EINA_ARG_NONNULL(1);
+
 /**
  * @}
  */
 
 /**
  * @defgroup Evas_Object_Grid Grid Smart Object.
+ * @ingroup Evas_Smart_Object_Group
  *
- * Convenience smart object that packs children under a regular grid
- * layout, using their virtual grid location and size to determine
- * children's positions inside the grid object's area.
+ * @brief   This group provides functions for grid smart objects.
+ * @since   1.1
+ *
+ * @remarks Convenience smart object that packs children under a regular grid
+ *          layout, using their virtual grid location and size to determine
+ *          children's positions inside the grid object's area.
  *
- * @ingroup Evas_Smart_Object_Group
- * @since 1.1
- */
-
-/**
- * @addtogroup Evas_Object_Grid
  * @{
  */
 
 /**
- * Create a new grid.
+ * @brief    Creates a new grid.
  *
- * It's set to a virtual size of 1x1 by default and add children with
- * evas_object_grid_pack().
- * @since 1.1
+ * @since    1.1
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks  It is set to a virtual size of 1x1 by default and add children with
+ *           evas_object_grid_pack().
+ *
+ * @param[in]    evas  The given evas
+ * @return   The new grid object
  */
 EAPI Evas_Object   *evas_object_grid_add(Evas *evas) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Create a grid that is child of a given element @a parent.
+ * @brief   Creates a grid that is child of a given element @a parent.
+ * @since   1.1
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in] parent The parent element
+ * @return  The new grid object
  *
  * @see evas_object_grid_add()
- * @since 1.1
  */
 EAPI Evas_Object   *evas_object_grid_add_to(Evas_Object *parent) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Set the virtual resolution for the grid
+ * @brief   Sets the virtual resolution for the grid.
+ * @since   1.1
  *
- * @param o The grid object to modify
- * @param w The virtual horizontal size (resolution) in integer units
- * @param h The virtual vertical size (resolution) in integer units
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   o  The grid object to modify
+ * @param[in]   w  The virtual horizontal size (resolution) in integer units
+ * @param[in]   h  The virtual vertical size (resolution) in integer units
  */
 EAPI void           evas_object_grid_size_set(Evas_Object *o, int w, int h) EINA_ARG_NONNULL(1);
 
 /**
- * Get the current virtual resolution
+ * @brief   Gets the current virtual resolution.
+ * @since   1.1
  *
- * @param o The grid object to query
- * @param w A pointer to an integer to store the virtual width
- * @param h A pointer to an integer to store the virtual height
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   o  The grid object to query
+ * @param[out]   w  A pointer to an integer to store the virtual width
+ * @param[out]   h  A pointer to an integer to store the virtual height
  * @see evas_object_grid_size_set()
- * @since 1.1
  */
 EAPI void           evas_object_grid_size_get(const Evas_Object *o, int *w, int *h) EINA_ARG_NONNULL(1);
 
 /**
- * Sets the mirrored mode of the grid. In mirrored mode the grid items go
- * from right to left instead of left to right. That is, 0,0 is top right, not
- * to left.
+ * @brief   Sets the mirrored mode of the grid. 
+ * @since   1.1
  *
- * @param o The grid object.
- * @param mirrored the mirrored mode to set
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks In mirrored mode the grid items go from right to left 
+ *          instead of left to right. That is, 0,0 is top right, not to left.
+ *
+ * @param[in]   o         The grid object
+ * @param[in]   mirrored  The mirrored mode to set
  */
 EAPI void           evas_object_grid_mirrored_set(Evas_Object *o, Eina_Bool mirrored) EINA_ARG_NONNULL(1);
 
 /**
- * Gets the mirrored mode of the grid.
+ * @brief   Gets the mirrored mode of the grid.
+ * @since   1.1
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   o  The grid object
+ * @return  #EINA_TRUE if it is a mirrored grid, \n
+ *          otherwise #EINA_FALSE if it is not a mirrored grid 
  *
- * @param o The grid object.
- * @return @c EINA_TRUE if it's a mirrored grid, @c EINA_FALSE otherwise.
  * @see evas_object_grid_mirrored_set()
- * @since 1.1
  */
 EAPI Eina_Bool      evas_object_grid_mirrored_get(const Evas_Object *o) EINA_ARG_NONNULL(1);
 
 /**
- * Add a new child to a grid object.
+ * @brief   Adds a new child to a grid object.
+ * @since   1.1
  *
- * @param o The given grid object.
- * @param child The child object to add.
- * @param x The virtual x coordinate of the child
- * @param y The virtual y coordinate of the child
- * @param w The virtual width of the child
- * @param h The virtual height of the child
- * @return 1 on success, 0 on failure.
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   o      The given grid object
+ * @param[in]   child  The child object to add
+ * @param[in]   x      The virtual x coordinate of the child
+ * @param[in]   y      The virtual y coordinate of the child
+ * @param[in]   w      The virtual width of the child
+ * @param[in]   h      The virtual height of the child
+ * @return  #EINA_TRUE if the child is added successfully, \n
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool      evas_object_grid_pack(Evas_Object *o, Evas_Object *child, int x, int y, int w, int h) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Remove child from grid.
+ * @brief   Removes child from grid.
+ * @since   1.1
  *
- * @note removing a child will immediately call a walk over children in order
- *       to recalculate numbers of columns and rows. If you plan to remove
- *       all children, use evas_object_grid_clear() instead.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @return 1 on success, 0 on failure.
- * @since 1.1
+ * @remarks Removing a child immediately calls a walk over children in order
+ *          to recalculate numbers of columns and rows. If you plan to remove
+ *          all children, use evas_object_grid_clear() instead.
+ *
+ * @param[in]   o      The given grid object
+ * @param[in]   child  The child object to remove
+ * @return  #EINA_TRUE if the child is removed successfully, \n
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool      evas_object_grid_unpack(Evas_Object *o, Evas_Object *child) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Faster way to remove all child objects from a grid object.
+ * @brief   Removes all child objects from a grid object.
+ * @since   1.1
  *
- * @param o The given grid object.
- * @param clear if true, it will delete just removed children.
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks This is a faster way to remove all child objects.
+ *
+ * @param[in]   o       The given grid object
+ * @param[in]   clear   Set #EINA_TRUE to delete the just removed children, \n
+ *                  otherwise set #EINA_FALSE to not delete them
  */
 EAPI void           evas_object_grid_clear(Evas_Object *o, Eina_Bool clear) EINA_ARG_NONNULL(1);
 
 /**
- * Get the pack options for a grid child
+ * @brief   Gets the pack options for a grid child.
+ * @since   1.1
  *
- * Get the pack x, y, width and height in virtual coordinates set by
- * evas_object_grid_pack()
- * @param o The grid object
- * @param child The grid child to query for coordinates
- * @param x The pointer to where the x coordinate will be returned
- * @param y The pointer to where the y coordinate will be returned
- * @param w The pointer to where the width will be returned
- * @param h The pointer to where the height will be returned
- * @return 1 on success, 0 on failure.
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks Gets the pack x, y, width and height in virtual coordinates set by
+ *          evas_object_grid_pack().
+ *
+ * @param[in]   o      The grid object
+ * @param[in]   child  The grid child to query for coordinates
+ * @param[out]   x      The pointer to where the x coordinate to be returned
+ * @param[out]   y      The pointer to where the y coordinate to be returned
+ * @param[out]   w      The pointer to where the width to be returned
+ * @param[out]   h      The pointer to where the height to be returned
+ * @return  #EINA_TRUE if the pack options are obtained successfully,
+ *          otherwise #EINA_FALSE on failure
  */
 EAPI Eina_Bool      evas_object_grid_pack_get(const Evas_Object *o, Evas_Object *child, int *x, int *y, int *w, int *h);
 
 /**
- * Get an iterator to walk the list of children for the grid.
+ * @brief    Gets an iterator to walk the list of children for the grid.
+ * @since    1.1
  *
- * @note Do not remove or delete objects while walking the list.
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks  Do not remove or delete objects while walking the list.
+ * 
+ * @param[in]    o  The grid object 
+ * @return   An iterator to walk through the children of the object, \n
+ *           otherwise @c NULL in case of errors
  */
 EAPI Eina_Iterator *evas_object_grid_iterator_new(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Get an accessor to get random access to the list of children for the grid.
+ * @brief   Gets an accessor to get random access to the list of children for the grid.
+ * @since   1.1
  *
- * @note Do not remove or delete objects while walking the list.
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks Do not remove or delete objects while walking the list.
+ *
+ * @param[in]   o  The grid object 
+ * @return  An accessor to get random access to the list of children for the grid, \n
+ *           otherwise @c NULL in case of errors 
  */
 EAPI Eina_Accessor *evas_object_grid_accessor_new(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
 /**
- * Get the list of children for the grid.
+ * @brief   Gets the list of children for the grid.
+ * @since   1.1
  *
- * @note This is a duplicate of the list kept by the grid internally.
- *       It's up to the user to destroy it when it no longer needs it.
- *       It's possible to remove objects from the grid when walking this
- *       list, but these removals won't be reflected on it.
- * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks This is a duplicate of the list kept by the grid internally.
+ *          It is up to the user to destroy it when it no longer needs it.
+ *          It is possible to remove objects from the grid when walking this
+ *          list, but these removals are not reflected on it.
+ *
+ * @param[in]    o  The grid object 
+ * @return   The list of children for the grid
  */
 EAPI Eina_List     *evas_object_grid_children_get(const Evas_Object *o) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
 
@@ -12209,14 +14675,20 @@ EAPI Eina_List     *evas_object_grid_children_get(const Evas_Object *o) EINA_WAR
  */
 
 /**
+ * @internal
  * @defgroup Evas_Cserve Shared Image Cache Server
+ * @ingroup Evas
+ *
+ * @brief  This group provides functions for shared image cache server
  *
  * Evas has an (optional) module which provides client-server
  * infrastructure to <b>share bitmaps across multiple processes</b>,
  * saving data and processing power.
  *
- * Be warned that it @b doesn't work when <b>threaded image
+ * Be warned that it @b does not work when <b>threaded image
  * preloading</b> is enabled for Evas, though.
+ *
+ * @{
  */
 typedef struct _Evas_Cserve_Stats       Evas_Cserve_Stats;
 typedef struct _Evas_Cserve_Image_Cache Evas_Cserve_Image_Cache;
@@ -12224,22 +14696,20 @@ typedef struct _Evas_Cserve_Image       Evas_Cserve_Image;
 typedef struct _Evas_Cserve_Config      Evas_Cserve_Config;
 
 /**
- * Statistics about the server that shares cached bitmaps.
- * @ingroup Evas_Cserve
+ * @brief   The structure type containing the statistics about the server that shares cached bitmaps.
  */
 struct _Evas_Cserve_Stats
 {
-   int    saved_memory;      /**< current amount of saved memory, in bytes */
-   int    wasted_memory;      /**< current amount of wasted memory, in bytes */
-   int    saved_memory_peak;      /**< peak amount of saved memory, in bytes */
-   int    wasted_memory_peak;      /**< peak amount of wasted memory, in bytes */
-   double saved_time_image_header_load;      /**< time, in seconds, saved in header loads by sharing cached loads instead */
-   double saved_time_image_data_load;      /**< time, in seconds, saved in data loads by sharing cached loads instead */
+   int    saved_memory;      /**< The current amount of saved memory, in bytes */
+   int    wasted_memory;      /**< The current amount of wasted memory, in bytes */
+   int    saved_memory_peak;      /**< The peak amount of saved memory, in bytes */
+   int    wasted_memory_peak;      /**< The peak amount of wasted memory, in bytes */
+   double saved_time_image_header_load;      /**< The time, in seconds, saved in header loads by sharing cached loads instead */
+   double saved_time_image_data_load;      /**< The time, in seconds, saved in data loads by sharing cached loads instead */
 };
 
 /**
- * A handle of a cache of images shared by a server.
- * @ingroup Evas_Cserve
+ * @brief   The structure type containing a handle of a cache of images shared by a server.
  */
 struct _Evas_Cserve_Image_Cache
 {
@@ -12252,8 +14722,7 @@ struct _Evas_Cserve_Image_Cache
 };
 
 /**
- * A handle to an image shared by a server.
- * @ingroup Evas_Cserve
+ * @brief   The structure type containing a handle to an image shared by a server.
  */
 struct _Evas_Cserve_Image
 {
@@ -12275,8 +14744,7 @@ struct _Evas_Cserve_Image
 };
 
 /**
- * Configuration that controls the server that shares cached bitmaps.
- * @ingroup Evas_Cserve
+ * @brief   The structure type containing the configuration that controls the server that shares cached bitmaps.
  */
 struct _Evas_Cserve_Config
 {
@@ -12286,114 +14754,141 @@ struct _Evas_Cserve_Config
 };
 
 /**
- * Retrieves if the system wants to share bitmaps using the server.
- * @return @c EINA_TRUE if it wants, @c EINA_FALSE otherwise.
- * @ingroup Evas_Cserve
+ * @brief   Checks whether the system shares bitmaps using the server.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @return  #EINA_TRUE if the system shares bitmaps using the server, \n
+ *          otherwise #EINA_FALSE if the system does not share bitmaps
  */
 EAPI Eina_Bool   evas_cserve_want_get(void) EINA_WARN_UNUSED_RESULT;
 
 /**
- * Retrieves if the system is connected to the server used to share
- * bitmaps.
+ * @brief   Checks whether the system is connected to the server used to share bitmaps.
  *
- * @return @c EINA_TRUE if it's connected, @c EINA_FALSE otherwise.
- * @ingroup Evas_Cserve
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @return  #EINA_TRUE if the system is connected to the server, \n
+ *          otherwise #EINA_FALSE if it is not connected
  */
 EAPI Eina_Bool   evas_cserve_connected_get(void) EINA_WARN_UNUSED_RESULT;
 
 /**
- * Retrieves statistics from a running bitmap sharing server.
- * @param stats pointer to structure to fill with statistics about the
- *        bitmap cache server.
+ * @brief   Gets the statistics from a running bitmap sharing server.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @return @c EINA_TRUE if @p stats were filled with data,
- *         @c EINA_FALSE otherwise (when @p stats is untouched)
- * @ingroup Evas_Cserve
+ * @param[in]   stats  The pointer to the structure to fill the statistics about the
+ *                 bitmap cache server
+ * @return  #EINA_TRUE if @a stats is filled with data, \n
+ *          otherwise #EINA_FALSE when @a stats is untouched
  */
 EAPI Eina_Bool   evas_cserve_stats_get(Evas_Cserve_Stats *stats) EINA_WARN_UNUSED_RESULT;
 
 /**
- * Completely discard/clean a given images cache, thus re-setting it.
+ * @brief  Completely discards or cleans a given images cache, thus re-setting it.
  *
- * @param cache A handle to the given images cache.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  cache  A handle to the given images cache
  */
 EAPI void        evas_cserve_image_cache_contents_clean(Evas_Cserve_Image_Cache *cache);
 
 /**
- * Retrieves the current configuration of the Evas image caching
- * server.
+ * @brief   Gets the current configuration of the Evas image caching server.
  *
- * @param config where to store current image caching server's
- * configuration.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @return @c EINA_TRUE if @p config was filled with data,
- *         @c EINA_FALSE otherwise (when @p config is untouched)
+ * @remarks  The fields of @a config are altered to reflect the current
+ *           configuration's values.
  *
- * The fields of @p config will be altered to reflect the current
- * configuration's values.
+ * @param[in]    config  The current image caching server's configuration
  *
- * @see evas_cserve_config_set()
+ * @return   #EINA_TRUE if @a config is filled with data, \n
+ *           otherwise #EINA_FALSE when @a config is untouched
  *
- * @ingroup Evas_Cserve
+ * @see evas_cserve_config_set()
  */
 EAPI Eina_Bool   evas_cserve_config_get(Evas_Cserve_Config *config) EINA_WARN_UNUSED_RESULT;
 
 /**
- * Changes the configurations of the Evas image caching server.
+ * @brief   Sets the configurations of the Evas image caching server.
  *
- * @param config A bitmap cache configuration handle with fields set
- * to desired configuration values.
- * @return @c EINA_TRUE if @p config was successfully applied,
- *         @c EINA_FALSE otherwise.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @see evas_cserve_config_get()
+ * @param[in]   config  A bitmap cache configuration handle with fields set
+ *                  to desired configuration values
+ * @return  #EINA_TRUE if @a config is applied successfully,
+ *          otherwise #EINA_FALSE
  *
- * @ingroup Evas_Cserve
+ * @see evas_cserve_config_get()
  */
 EAPI Eina_Bool   evas_cserve_config_set(const Evas_Cserve_Config *config) EINA_WARN_UNUSED_RESULT;
 
 /**
- * Force the system to disconnect from the bitmap caching server.
+ * @brief  Forces the system to disconnect from the bitmap caching server.
  *
- * @ingroup Evas_Cserve
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  */
 EAPI void        evas_cserve_disconnect(void);
 
 /**
+ * @}
+ */
+
+/**
  * @defgroup Evas_Utils General Utilities
+ * @ingroup Evas
+ * @brief   This group provides general utilities functions.
+ * @remarks Some functions that are handy but are not specific to canvas or objects.
  *
- * Some functions that are handy but are not specific of canvas or
- * objects.
+ * @{
  */
 
 /**
- * Converts the given Evas image load error code into a string
- * describing it in english.
+ * @brief   Converts the given Evas image load error code into a string
+ *          describing it in English.
  *
- * @param error the error code, a value in ::Evas_Load_Error.
- * @return Always returns a valid string. If the given @p error is not
- *         supported, <code>"Unknown error"</code> is returned.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Mostly evas_object_image_file_set() would be the function setting
- * that error value afterwards, but also evas_object_image_load(),
- * evas_object_image_save(), evas_object_image_data_get(),
- * evas_object_image_data_convert(), evas_object_image_pixels_import()
- * and evas_object_image_is_inside(). This function is meant to be
- * used in conjunction with evas_object_image_load_error_get(), as in:
+ * @remarks Mostly evas_object_image_file_set() would be the function setting
+ *          that error value afterwards, but also evas_object_image_load(),
+ *          evas_object_image_save(), evas_object_image_data_get(),
+ *          evas_object_image_data_convert(), evas_object_image_pixels_import()
+ *          and evas_object_image_is_inside(). This function is meant to be
+ *          used in conjunction with evas_object_image_load_error_get(), as in:
  *
- * Example code:
- * @dontinclude evas-images.c
+ * @remarks The following is an example code:
  * @skip img1 =
  * @until ecore_main_loop_begin(
  *
- * Here, being @c valid_path the path to a valid image and @c
- * bogus_path a path to a file which does not exist, the two outputs
- * of evas_load_error_str() would be (if no other errors occur):
- * <code>"No error on load"</code> and <code>"File (or file path) does
- * not exist"</code>, respectively. See the full @ref
- * Example_Evas_Images "example".
+ * @remarks Here, @c valid_path is the path to a valid image and @c
+ *          bogus_path is a path to a file which does not exist. The two outputs
+ *          of evas_load_error_str() would be (if no other errors occur):
+ *          <code>"No error on load"</code> and <code>"File (or file path) does
+ *          not exist"</code>, respectively.
  *
- * @ingroup Evas_Utils
+ *
+ * @param[in]   error  The error code \n
+ *                 A value in #Evas_Load_Error.
+ * @return  A valid string \n
+ *          If the given @a error is not supported, <code>"Unknown error"</code> is returned.
  */
 EAPI const char *evas_load_error_str(Evas_Load_Error error);
 
@@ -12402,215 +14897,276 @@ EAPI const char *evas_load_error_str(Evas_Load_Error error);
 /* rgb color space has r,g,b in the range 0 to 255 */
 
 /**
- * Convert a given color from HSV to RGB format.
+ * @brief   Converts a given color from HSV to RGB format.
  *
- * @param h The Hue component of the color.
- * @param s The Saturation component of the color.
- * @param v The Value component of the color.
- * @param r The Red component of the color.
- * @param g The Green component of the color.
- * @param b The Blue component of the color.
+ * @details This function converts a given color in HSV color format to RGB
+ *          color format.
  *
- * This function converts a given color in HSV color format to RGB
- * color format.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @ingroup Evas_Utils
+ * @param[in]   h  The Hue component of the color
+ * @param[in]   s  The Saturation component of the color
+ * @param[in]   v  The Value component of the color
+ * @param[out]   r  The Red component of the color
+ * @param[out]   g  The Green component of the color
+ * @param[out]   b  The Blue component of the color
  **/
 EAPI void evas_color_hsv_to_rgb(float h, float s, float v, int *r, int *g, int *b);
 
 /**
- * Convert a given color from RGB to HSV format.
+ * @brief   Converts a given color from RGB to HSV format.
  *
- * @param r The Red component of the color.
- * @param g The Green component of the color.
- * @param b The Blue component of the color.
- * @param h The Hue component of the color.
- * @param s The Saturation component of the color.
- * @param v The Value component of the color.
+ * @details This function converts a given color in RGB color format to HSV
+ *          color format.
  *
- * This function converts a given color in RGB color format to HSV
- * color format.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @ingroup Evas_Utils
+ * @param[in]   r  The Red component of the color
+ * @param[in]   g  The Green component of the color
+ * @param[in]   b  The Blue component of the color
+ * @param[out]   h  The Hue component of the color
+ * @param[out]   s  The Saturation component of the color
+ * @param[out]   v  The Value component of the color
  **/
 EAPI void evas_color_rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v);
 
 /* argb color space has a,r,g,b in the range 0 to 255 */
 
 /**
- * Pre-multiplies a rgb triplet by an alpha factor.
- *
- * @param a The alpha factor.
- * @param r The Red component of the color.
- * @param g The Green component of the color.
- * @param b The Blue component of the color.
+ * @brief   Pre-multiplies a rgb triplet by an alpha factor.
+ * @details This function pre-multiplies a given rgb triplet by an alpha
+ *          factor. Alpha factor is used to define transparency.
  *
- * This function pre-multiplies a given rgb triplet by an alpha
- * factor. Alpha factor is used to define transparency.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @ingroup Evas_Utils
+ * @param[in]   a  The alpha factor
+ * @param[out]   r  The Red component of the color
+ * @param[out]   g  The Green component of the color
+ * @param[out]   b  The Blue component of the color
  **/
 EAPI void evas_color_argb_premul(int a, int *r, int *g, int *b);
 
 /**
- * Undo pre-multiplication of a rgb triplet by an alpha factor.
+ * @brief   Undoes pre-multiplication of a rgb triplet by an alpha factor.
  *
- * @param a The alpha factor.
- * @param r The Red component of the color.
- * @param g The Green component of the color.
- * @param b The Blue component of the color.
+ * @details This function undoes pre-multiplication a given rbg triplet by an
+ *          alpha factor. Alpha factor is used to define transparency.
  *
- * This function undoes pre-multiplication a given rbg triplet by an
- * alpha factor. Alpha factor is used to define transparency.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @see evas_color_argb_premul().
+ * @param[in]   a  The alpha factor
+ * @param[out]   r  The Red component of the color
+ * @param[out]   g  The Green component of the color
+ * @param[out]   b  The Blue component of the color
  *
- * @ingroup Evas_Utils
+ * @see evas_color_argb_premul().
  **/
 EAPI void evas_color_argb_unpremul(int a, int *r, int *g, int *b);
 
 /**
- * Pre-multiplies data by an alpha factor.
+ * @brief   Pre-multiplies data by an alpha factor.
+ * @details This function pre-multiplies a given data by an alpha
+ *          factor. Alpha factor is used to define transparency.
  *
- * @param data The data value.
- * @param len  The length value.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * This function pre-multiplies a given data by an alpha
- * factor. Alpha factor is used to define transparency.
- *
- * @ingroup Evas_Utils
+ * @param[in]   data  The data value
+ * @param[in]   len   The length value
  **/
 EAPI void evas_data_argb_premul(unsigned int *data, unsigned int len);
 
 /**
- * Undo pre-multiplication data by an alpha factor.
+ * @brief   Undoes pre-multiplication data by an alpha factor.
  *
- * @param data The data value.
- * @param len  The length value.
+ * @details This function undoes the pre-multiplication of a given data by an alpha
+ *          factor. Alpha factor is used to define transparency.
  *
- * This function undoes pre-multiplication of a given data by an alpha
- * factor. Alpha factor is used to define transparency.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @ingroup Evas_Utils
+ * @param[in]   data  The data value
+ * @param[in]   len   The length value
  **/
 EAPI void evas_data_argb_unpremul(unsigned int *data, unsigned int len);
 
-/* string and font handling */
+/**
+ * @internal
+ * @remarks Tizen only feature
+ * @remarks TIZEN_ONLY(20140822): Added evas_bidi_direction_hint_set, get APIs and applied to textblock, text.
+ * @brief   Set BiDi direction hint to the given evas canvas.
+ *
+ * @details Evas has a BiDi direction hint value which affect to textblock, text object.
+ *          If a text that has only neutral BiDi direction is set to textblock or text,
+ *          the BiDi direction hint will be used to decide alignment of paragraphs.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]  e     The pointer to the Evas canvas
+ * @param[in]  dir   The BiDi direction hint
+ **/
+EAPI void evas_bidi_direction_hint_set(Evas *e, Evas_BiDi_Direction dir);
 
 /**
- * Gets the next character in the string
+ * @internal
+ * @remarks Tizen only feature
+ * @remarks TIZEN_ONLY(20140822): Added evas_bidi_direction_hint_set, get APIs and applied to textblock, text.
+ * @brief   Get BiDi direction hint of the given evas canvas.
+ *
+ * @details Evas has a BiDi direction hint value which affect to textblock, text object.
+ *          If a text that has only neutral BiDi direction is set to textblock or text,
+ *          the BiDi direction hint will be used to decide alignment of paragraphs.
  *
- * Given the UTF-8 string in @p str, and starting byte position in @p pos,
- * this function will place in @p decoded the decoded code point at @p pos
- * and return the byte index for the next character in the string.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * The only boundary check done is that @p pos must be >= 0. Other than that,
- * no checks are performed, so passing an index value that's not within the
- * length of the string will result in undefined behavior.
+ * @param[in]  e     The pointer to the Evas canvas
+ * @return     BiDi direction hint
  *
- * @param str The UTF-8 string
- * @param pos The byte index where to start
- * @param decoded Address where to store the decoded code point. Optional.
+ * @see evas_bidi_direction_hint_set().
+ **/
+EAPI Evas_BiDi_Direction evas_bidi_direction_hint_get(Evas *e);
+
+
+/* string and font handling */
+
+/**
+ * @brief   Gets the next character in the string.
  *
- * @return The byte index of the next character
+ * @remarks Given the UTF-8 string in @a str, and starting byte position in @a pos,
+ *          this function places in @a decoded the decoded code point at @a pos
+ *          and return the byte index for the next character in the string.
+ *          The only boundary check done is that @a pos must be >= 0. Other than that,
+ *          no checks are performed, so passing an index value that is not within the
+ *          length of the string results in undefined behavior.
  *
- * @ingroup Evas_Utils
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   str      The UTF-8 string
+ * @param[in]   pos      The byte index where to start
+ * @param[out]   decoded  The address to store the decoded code point \n
+ *                   This is optional.
+ * @return  The byte index of the next character
  */
 EAPI int  evas_string_char_next_get(const char *str, int pos, int *decoded) EINA_ARG_NONNULL(1);
 
 /**
- * Gets the previous character in the string
- *
- * Given the UTF-8 string in @p str, and starting byte position in @p pos,
- * this function will place in @p decoded the decoded code point at @p pos
- * and return the byte index for the previous character in the string.
+ * @brief   Gets the previous character in the string
  *
- * The only boundary check done is that @p pos must be >= 1. Other than that,
- * no checks are performed, so passing an index value that's not within the
- * length of the string will result in undefined behavior.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param str The UTF-8 string
- * @param pos The byte index where to start
- * @param decoded Address where to store the decoded code point. Optional.
+ * @remarks Given the UTF-8 string in @a str, and starting byte position in @a pos,
+ *          this function places in @a decoded the decoded code point at @a pos
+ *          and return the byte index for the previous character in the string.
  *
- * @return The byte index of the previous character
+ * @remarks The only boundary check done is that @a pos must be >= 1. Other than that,
+ *          no checks are performed, so passing an index value that is not within the
+ *          length of the string results in undefined behavior.
  *
- * @ingroup Evas_Utils
+ * @param[in]   str      The UTF-8 string
+ * @param[in]   pos      The byte index where to start
+ * @param[out]   decoded  The address where to store the decoded code point \n 
+ *                   This is optional.
+ * @return  The byte index of the previous character
  */
 EAPI int  evas_string_char_prev_get(const char *str, int pos, int *decoded) EINA_ARG_NONNULL(1);
 
 /**
- * Get the length in characters of the string.
- * @param  str The string to get the length of.
- * @return The length in characters (not bytes)
- * @ingroup Evas_Utils
+ * @brief   Gets the length in characters of the string.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   str  The string to get the length of
+ * @return  The length in characters (not bytes)
  */
 EAPI int  evas_string_char_len_get(const char *str) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
+ * @}
+ */
+
+/**
  * @defgroup Evas_Keys Key Input Functions
+ * @ingroup Evas_Canvas
  *
- * Functions which feed key events to the canvas.
+ * @brief  This group provides functions which feed key events to the canvas.
  *
- * As explained in @ref intro_not_evas, Evas is @b not aware of input
+ * Evas is @b not aware of input
  * systems at all. Then, the user, if using it crudely (evas_new()),
- * will have to feed it with input events, so that it can react
+ * has to feed it with input events, so that it can react
  * somehow. If, however, the user creates a canvas by means of the
- * Ecore_Evas wrapper, it will automatically bind the chosen display
+ * Ecore_Evas wrapper, it automatically binds the chosen display
  * engine's input events to the canvas, for you.
  *
  * This group presents the functions dealing with the feeding of key
  * events to the canvas. On most of them, one has to reference a given
  * key by a name (<code>keyname</code> argument). Those are
  * <b>platform dependent</b> symbolic names for the keys. Sometimes
- * you'll get the right <code>keyname</code> by simply using an ASCII
- * value of the key name, but it won't be like that always.
+ * you get the right <code>keyname</code> by simply using an ASCII
+ * value of the key name, but it is not like that always.
  *
  * Typical platforms are Linux frame buffer (Ecore_FB) and X server
  * (Ecore_X) when using Evas with Ecore and Ecore_Evas. Please refer
  * to your display engine's documentation when using evas through an
  * Ecore helper wrapper when you need the <code>keyname</code>s.
  *
- * Example:
- * @dontinclude evas-events.c
- * @skip mods = evas_key_modifier_get(evas);
- * @until {
- *
- * All the other @c evas_key functions behave on the same manner. See
- * the full @ref Example_Evas_Events "example".
- *
- * @ingroup Evas_Canvas
- */
-
-/**
- * @addtogroup Evas_Keys
  * @{
  */
 
 /**
- * Returns a handle to the list of modifier keys registered in the
- * canvas @p e. This is required to check for which modifiers are set
- * at a given time with the evas_key_modifier_is_set() function.
+ * @brief   Gets a handle to the list of modifier keys registered in the canvas @a e. 
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks This is required to check for which modifiers are set
+ *          at a given time with the evas_key_modifier_is_set() function.
  *
- * @param e The pointer to the Evas canvas
+ * @param[in]   e  The pointer to the Evas canvas
+ * @return  An Evas_Modifier handle to query Evas' keys subsystem with evas_key_modifier_is_set(), \n
+ *          otherwise @c NULL on error
  *
  * @see evas_key_modifier_add
  * @see evas_key_modifier_del
  * @see evas_key_modifier_on
  * @see evas_key_modifier_off
  * @see evas_key_modifier_is_set
- *
- * @return An ::Evas_Modifier handle to query Evas' keys subsystem
- *     with evas_key_modifier_is_set(), or @c NULL on error.
  */
 EAPI const Evas_Modifier *evas_key_modifier_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Returns a handle to the list of lock keys registered in the canvas
- * @p e. This is required to check for which locks are set at a given
- * time with the evas_key_lock_is_set() function.
+ * @brief   Gets a handle to the list of lock keys registered in the canvas @a e. 
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The pointer to the Evas canvas
+ * @remarks This is required to check for which locks are set at a given
+ *          time with the evas_key_lock_is_set() function.
+ *
+ * @param[in]   e  The pointer to the Evas canvas
+ * @return  An Evas_Lock handle to query Evas' keys subsystem with evas_key_lock_is_set(), \n
+ *          otherwise @c NULL on error
  *
  * @see evas_key_lock_add
  * @see evas_key_lock_del
@@ -12618,22 +15174,23 @@ EAPI const Evas_Modifier *evas_key_modifier_get(const Evas *e) EINA_WARN_UNUSED_
  * @see evas_key_lock_off
  * @see evas_key_lock_is_set
  *
- * @return An ::Evas_Lock handle to query Evas' keys subsystem with
- *     evas_key_lock_is_set(), or @c NULL on error.
  */
 EAPI const Evas_Lock     *evas_key_lock_get(const Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Checks the state of a given modifier key, at the time of the
- * call. If the modifier is set, such as shift being pressed, this
- * function returns @c Eina_True.
+ * @brief   Checks whether a given modifier key is set at the time of the call.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param m The current modifiers set, as returned by
- *        evas_key_modifier_get().
- * @param keyname The name of the modifier key to check status for.
+ * @remarks If the modifier is set, such as shift being pressed, this
+ *          function returns @c Eina_True.
  *
- * @return @c Eina_True if the modifier key named @p keyname is on, @c
- *         Eina_False otherwise.
+ * @param[in]   m        The current modifiers set, as returned by evas_key_modifier_get()
+ * @param[in]   keyname  The name of the modifier key to check status for
+ * @return  #EINA_TRUE if the modifier key named @a keyname is on, \n
+ *          otherwise #EINA_FALSE if the modifier key is not on 
  *
  * @see evas_key_modifier_add
  * @see evas_key_modifier_del
@@ -12644,15 +15201,18 @@ EAPI const Evas_Lock     *evas_key_lock_get(const Evas *e) EINA_WARN_UNUSED_RESU
 EAPI Eina_Bool            evas_key_modifier_is_set(const Evas_Modifier *m, const char *keyname) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
 
 /**
- * Checks the state of a given lock key, at the time of the call. If
- * the lock is set, such as caps lock, this function returns @c
- * Eina_True.
+ * @brief   Checks whether the given lock key is set at the time of the call. 
  *
- * @param l The current locks set, as returned by evas_key_lock_get().
- * @param keyname The name of the lock key to check status for.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @return @c Eina_True if the @p keyname lock key is set, @c
- *        Eina_False otherwise.
+ * @remarks If the lock is set, such as caps lock, this function returns @c Eina_True.
+ *
+ * @param[in]   l        The current locks set, as returned by evas_key_lock_get()
+ * @param[in]   keyname  The name of the lock key to check status for
+ * @return  #EINA_TRUE if the @a keyname lock key is set, \n
+ *          otherwise @c Eina_False if the lock key is not set
  *
  * @see evas_key_lock_get
  * @see evas_key_lock_add
@@ -12663,22 +15223,26 @@ EAPI Eina_Bool            evas_key_modifier_is_set(const Evas_Modifier *m, const
 EAPI Eina_Bool            evas_key_lock_is_set(const Evas_Lock *l, const char *keyname) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
 
 /**
- * Adds the @p keyname key to the current list of modifier keys.
+ * @brief   Adds the @a keyname key to the current list of modifier keys.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The pointer to the Evas canvas
- * @param keyname The name of the modifier key to add to the list of
- *        Evas modifiers.
+ * @remarks Modifiers are keys like shift, alt and ctrl, that is, keys which are
+ *          meant to be pressed together with others, altering the behavior of
+ *          the secondly pressed keys somehow. Evas allows these keys to be
+ *          user defined.
  *
- * Modifiers are keys like shift, alt and ctrl, i.e., keys which are
- * meant to be pressed together with others, altering the behavior of
- * the secondly pressed keys somehow. Evas is so that these keys can
- * be user defined.
+ * @remarks This call allows custom modifiers to be added to the Evas system at
+ *          run time. It is then possible to set and unset modifier keys
+ *          programmatically for other parts of the program to check and act
+ *          on. Programmers using Evas would check for modifier keys on key
+ *          event callbacks using evas_key_modifier_is_set().
  *
- * This call allows custom modifiers to be added to the Evas system at
- * run time. It is then possible to set and unset modifier keys
- * programmatically for other parts of the program to check and act
- * on. Programmers using Evas would check for modifier keys on key
- * event callbacks using evas_key_modifier_is_set().
+ * @param[in]   e        The pointer to the Evas canvas
+ * @param[in]   keyname  The name of the modifier key to add to the list of
+ *                   Evas modifiers
  *
  * @see evas_key_modifier_del
  * @see evas_key_modifier_get
@@ -12686,19 +15250,19 @@ EAPI Eina_Bool            evas_key_lock_is_set(const Evas_Lock *l, const char *k
  * @see evas_key_modifier_off
  * @see evas_key_modifier_is_set
  *
- * @note If the programmer instantiates the canvas by means of the
- *       ecore_evas_new() family of helper functions, Ecore will take
- *       care of registering on it all standard modifiers: "Shift",
- *       "Control", "Alt", "Meta", "Hyper", "Super".
  */
 EAPI void                 evas_key_modifier_add(Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Removes the @p keyname key from the current list of modifier keys
- * on canvas @p e.
+ * @brief   Removes the @a keyname key from the current list of modifier keys
+ *          on canvas @a e.
  *
- * @param e The pointer to the Evas canvas
- * @param keyname The name of the key to remove from the modifiers list.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @param[in]   e        The pointer to the Evas canvas
+ * @param[in]   keyname  The name of the key to remove from the modifiers list
  *
  * @see evas_key_modifier_add
  * @see evas_key_modifier_get
@@ -12709,42 +15273,45 @@ EAPI void                 evas_key_modifier_add(Evas *e, const char *keyname) EI
 EAPI void                 evas_key_modifier_del(Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Adds the @p keyname key to the current list of lock keys.
+ * @brief   Adds the @a keyname key to the current list of lock keys.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The pointer to the Evas canvas
- * @param keyname The name of the key to add to the locks list.
+ * @remarks Locks are keys like caps lock, num lock or scroll lock, that is, keys
+ *          which are meant to be pressed once -- toggling a binary state which
+ *          is bound to it -- and thus altering the behavior of all
+ *          subsequently pressed keys somehow, depending on its state. Evas is
+ *          so that these keys can be defined by the user.
  *
- * Locks are keys like caps lock, num lock or scroll lock, i.e., keys
- * which are meant to be pressed once -- toggling a binary state which
- * is bound to it -- and thus altering the behavior of all
- * subsequently pressed keys somehow, depending on its state. Evas is
- * so that these keys can be defined by the user.
+ * @remarks This allows custom locks to be added to the evas system at run
+ *          time. It is then possible to set and unset lock keys
+ *          programmatically for other parts of the program to check and act
+ *          on. Programmers using Evas would check for lock keys on key event
+ *          callbacks using evas_key_lock_is_set().
  *
- * This allows custom locks to be added to the evas system at run
- * time. It is then possible to set and unset lock keys
- * programmatically for other parts of the program to check and act
- * on. Programmers using Evas would check for lock keys on key event
- * callbacks using evas_key_lock_is_set().
+ * @param[in]   e        The pointer to the Evas canvas
+ * @param[in]   keyname  The name of the key to add to the locks list
  *
  * @see evas_key_lock_get
  * @see evas_key_lock_del
  * @see evas_key_lock_on
  * @see evas_key_lock_off
  * @see evas_key_lock_is_set
- *
- * @note If the programmer instantiates the canvas by means of the
- *       ecore_evas_new() family of helper functions, Ecore will take
- *       care of registering on it all standard lock keys: "Caps_Lock",
- *       "Num_Lock", "Scroll_Lock".
  */
 EAPI void                 evas_key_lock_add(Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Removes the @p keyname key from the current list of lock keys on
- * canvas @p e.
+ * @brief   Removes the @a keyname key from the current list of lock keys on
+ *          canvas @a e.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The pointer to the Evas canvas
- * @param keyname The name of the key to remove from the locks list.
+ * @param[in]   e        The pointer to the Evas canvas
+ * @param[in]   keyname  The name of the key to remove from the locks list
  *
  * @see evas_key_lock_get
  * @see evas_key_lock_add
@@ -12754,14 +15321,17 @@ EAPI void                 evas_key_lock_add(Evas *e, const char *keyname) EINA_A
 EAPI void                 evas_key_lock_del(Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Enables or turns on programmatically the modifier key with name @p
- * keyname.
+ * @brief   Enables or turns on programmatically the modifier key with name @a keyname.
  *
- * @param e The pointer to the Evas canvas
- * @param keyname The name of the modifier to enable.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * The effect will be as if the key was pressed for the whole time
- * between this call and a matching evas_key_modifier_off().
+ * @remarks The effect is as if the key is pressed for the whole time
+ *          between this call and a matching evas_key_modifier_off().
+ *
+ * @param[in]   e        The pointer to the Evas canvas
+ * @param[in]   keyname  The name of the modifier to enable
  *
  * @see evas_key_modifier_add
  * @see evas_key_modifier_get
@@ -12771,11 +15341,14 @@ EAPI void                 evas_key_lock_del(Evas *e, const char *keyname) EINA_A
 EAPI void                 evas_key_modifier_on(Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Disables or turns off programmatically the modifier key with name
- * @p keyname.
+ * @brief   Disables or turns off programmatically the modifier key with name @a keyname.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The pointer to the Evas canvas
- * @param keyname The name of the modifier to disable.
+ * @param[in]   e        The pointer to the Evas canvas
+ * @param[in]   keyname  The name of the modifier to disable
  *
  * @see evas_key_modifier_add
  * @see evas_key_modifier_get
@@ -12785,14 +15358,17 @@ EAPI void                 evas_key_modifier_on(Evas *e, const char *keyname) EIN
 EAPI void                 evas_key_modifier_off(Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Enables or turns on programmatically the lock key with name @p
- * keyname.
+ * @brief   Enables or turns on programmatically the lock key with name @a keyname.
  *
- * @param e The pointer to the Evas canvas
- * @param keyname The name of the lock to enable.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * The effect will be as if the key was put on its active state after
- * this call.
+ * @remarks The effect is as if the key is put on its active state after
+ *          this call.
+ *
+ * @param[in]   e        The pointer to the Evas canvas
+ * @param[in]   keyname  The name of the lock to enable
  *
  * @see evas_key_lock_get
  * @see evas_key_lock_add
@@ -12802,14 +15378,17 @@ EAPI void                 evas_key_modifier_off(Evas *e, const char *keyname) EI
 EAPI void                 evas_key_lock_on(Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Disables or turns off programmatically the lock key with name @p
- * keyname.
+ * @brief   Disables or turns off programmatically the lock key with name @a keyname.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @param e The pointer to the Evas canvas
- * @param keyname The name of the lock to disable.
+ * @remarks The effect is as if the key is put on its inactive state
+ *          after this call.
  *
- * The effect will be as if the key was put on its inactive state
- * after this call.
+ * @param[in]   e        The pointer to the Evas canvas
+ * @param[in]   keyname  The name of the lock to disable
  *
  * @see evas_key_lock_get
  * @see evas_key_lock_add
@@ -12819,19 +15398,23 @@ EAPI void                 evas_key_lock_on(Evas *e, const char *keyname) EINA_AR
 EAPI void                 evas_key_lock_off(Evas *e, const char *keyname) EINA_ARG_NONNULL(1, 2);
 
 /**
- * Creates a bit mask from the @p keyname @b modifier key. Values
- * returned from different calls to it may be ORed together,
- * naturally.
+ * @brief   Creates a bit mask from the @a keyname @b modifier key. 
  *
- * @param e The canvas whom to query the bit mask from.
- * @param keyname The name of the modifier key to create the mask for.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @returns the bit mask or 0 if the @p keyname key wasn't registered as a
- *          modifier for canvas @p e.
+ * @remarks Values returned from different calls to it may be ORed together,
+ *          naturally.
  *
- * This function is meant to be using in conjunction with
- * evas_object_key_grab()/evas_object_key_ungrab(). Go check their
- * documentation for more information.
+ * @remarks This function is meant to be used in conjunction with
+ *          evas_object_key_grab()/evas_object_key_ungrab(). See their
+ *          documentation for more information.
+ *
+ * @param[in]   e        The canvas to query the bit mask from
+ * @param[in]   keyname  The name of the modifier key to create the mask for
+ * @returns The bit mask or @c 0 if the @a keyname key is not registered as a
+ *          modifier for canvas @a e
  *
  * @see evas_key_modifier_add
  * @see evas_key_modifier_get
@@ -12844,79 +15427,73 @@ EAPI void                 evas_key_lock_off(Evas *e, const char *keyname) EINA_A
 EAPI Evas_Modifier_Mask   evas_key_modifier_mask_get(const Evas *e, const char *keyname) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
 
 /**
- * Requests @p keyname key events be directed to @p obj.
- *
- * @param obj the object to direct @p keyname events to.
- * @param keyname the key to request events for.
- * @param modifiers a mask of modifiers that must be present to
- * trigger the event.
- * @param not_modifiers a mask of modifiers that must @b not be present
- * to trigger the event.
- * @param exclusive request that the @p obj is the only object
- * receiving the @p keyname events.
- * @return @c EINA_TRUE, if the call succeeded, @c EINA_FALSE otherwise.
+ * @brief   Requests @a keyname key events be directed to @a obj.
  *
- * Key grabs allow one or more objects to receive key events for
- * specific key strokes even if other objects have focus. Whenever a
- * key is grabbed, only the objects grabbing it will get the events
- * for the given keys.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * @p keyname is a platform dependent symbolic name for the key
- * pressed (see @ref Evas_Keys for more information).
+ * @remarks Key grabs allow one or more objects to receive key events for
+ *          specific key strokes even if other objects have focus. Whenever a
+ *          key is grabbed, only the objects grabbing it gets the events
+ *          for the given keys.
  *
- * @p modifiers and @p not_modifiers are bit masks of all the
- * modifiers that must and mustn't, respectively, be pressed along
- * with @p keyname key in order to trigger this new key
- * grab. Modifiers can be things such as Shift and Ctrl as well as
- * user defined types via evas_key_modifier_add(). Retrieve them with
- * evas_key_modifier_mask_get() or use @c 0 for empty masks.
+ * @remarks @a keyname is a platform dependent symbolic name for the key
+ *          pressed (see @ref Evas_Keys for more information).
  *
- * @p exclusive will make the given object the only one permitted to
- * grab the given key. If given @c EINA_TRUE, subsequent calls on this
- * function with different @p obj arguments will fail, unless the key
- * is ungrabbed again.
+ * @remarks @a modifiers and @a not_modifiers are bit masks of all the
+ *          modifiers that must and must not, respectively, be pressed along
+ *          with @a keyname key in order to trigger this new key
+ *          grab. Modifiers can be things such as Shift and Ctrl as well as
+ *          user defined types via evas_key_modifier_add(). Retrieve them with
+ *          evas_key_modifier_mask_get() or use @c 0 for empty masks.
  *
- * Example code follows.
- * @dontinclude evas-events.c
- * @skip if (d.focus)
- * @until else
+ * @remarks @a exclusive makes the given object the only one permitted to
+ *          grab the given key. If given #EINA_TRUE, subsequent calls on this
+ *          function with different @a obj arguments it fails, unless the key
+ *          is ungrabbed again.
  *
- * See the full example @ref Example_Evas_Events "here".
+ * @remarks Providing impossible modifier sets creates undefined behavior.
  *
- * @warning Providing impossible modifier sets creates undefined behavior
+ * @param[in]   obj            The object to direct @a keyname events to
+ * @param[in]   keyname        The key to request events for
+ * @param[in]   modifiers      A mask of modifiers that must be present to
+ *                         trigger the event
+ * @param[in]   not_modifiers  A mask of modifiers that must @b not be present
+ *                         to trigger the event
+ * @param[in]   exclusive      Set #EINA_TRUE to request that the @a obj is the only object
+ *                         receiving the @a keyname events, \n
+ *                         otherwise set #EINA_FALSE
+ * @return  #EINA_TRUE if the call succeeded, \n
+ *          otherwise #EINA_FALSE on failure
  *
  * @see evas_object_key_ungrab
  * @see evas_object_focus_set
  * @see evas_object_focus_get
- * @see evas_focus_get
  * @see evas_key_modifier_add
  */
 EAPI Eina_Bool            evas_object_key_grab(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers, Eina_Bool exclusive) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2);
 
 /**
- * Removes the grab on @p keyname key events by @p obj.
+ * @brief   Removes the grab on @a keyname key events by @a obj.
  *
- * @param obj the object that has an existing key grab.
- * @param keyname the key the grab is set for.
- * @param modifiers a mask of modifiers that must be present to
- * trigger the event.
- * @param not_modifiers a mask of modifiers that must not not be
- * present to trigger the event.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Removes a key grab on @p obj if @p keyname, @p modifiers, and @p
- * not_modifiers match.
+ * @remarks Removes a key grab on @a obj if @a keyname, @a modifiers, 
+ *          and @a not_modifiers match.
  *
- * Example code follows.
- * @dontinclude evas-events.c
- * @skip got here by key grabs
- * @until }
- *
- * See the full example @ref Example_Evas_Events "here".
+ * @param[in]   obj            The object that has an existing key grab
+ * @param[in]   keyname        The key the grab is set for
+ * @param[in]   modifiers      A mask of modifiers that must be present to
+ *                         trigger the event
+ * @param[in]   not_modifiers  A mask of modifiers that must not be
+ *                         present to trigger the event
  *
  * @see evas_object_key_grab
  * @see evas_object_focus_set
  * @see evas_object_focus_get
- * @see evas_focus_get
  */
 EAPI void                 evas_object_key_ungrab(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers) EINA_ARG_NONNULL(1, 2);
 
@@ -12925,33 +15502,30 @@ EAPI void                 evas_object_key_ungrab(Evas_Object *obj, const char *k
  */
 
 /**
+ * @internal
  * @defgroup Evas_Touch_Point_List Touch Point List Functions
+ * @ingroup Evas_Canvas
  *
- * Functions to get information of touched points in the Evas.
+ * @brief   This group provides functions to get information of touched points in the Evas.
  *
- * Evas maintains list of touched points on the canvas. Each point has
- * its co-ordinates, id and state. You can get the number of touched
- * points and information of each point using evas_touch_point_list
- * functions.
+ * @remarks Evas maintains list of touched points on the canvas. Each point has
+ *          its co-ordinates, ID and state. You can get the number of touched
+ *          points and information of each point using evas_touch_point_list functions.
  *
- * @ingroup Evas_Canvas
- */
-
-/**
- * @addtogroup Evas_Touch_Point_List
  * @{
  */
 
 /**
- * Get the number of touched point in the evas.
+ * @brief   Gets the number of touched point in the evas.
  *
- * @param e The pointer to the Evas canvas.
- * @return The number of touched point on the evas.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * New touched point is added to the list whenever touching the evas
- * and point is removed whenever removing touched point from the evas.
+ * @remarks New touched point is added to the list whenever touching the evas
+ *          and point is removed whenever removing touched point from the evas.
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas *evas;
  * int count;
@@ -12960,6 +15534,9 @@ EAPI void                 evas_object_key_ungrab(Evas_Object *obj, const char *k
  * printf("The count of touch points: %i\n", count);
  * @endcode
  *
+ * @param[in]   e  The pointer to the Evas canvas
+ * @return  The number of touched point on the evas
+ *
  * @see evas_touch_point_list_nth_xy_get()
  * @see evas_touch_point_list_nth_id_get()
  * @see evas_touch_point_list_nth_state_get()
@@ -12967,17 +15544,16 @@ EAPI void                 evas_object_key_ungrab(Evas_Object *obj, const char *k
 EAPI unsigned int           evas_touch_point_list_count(Evas *e) EINA_ARG_NONNULL(1);
 
 /**
- * This function returns the nth touch point's co-ordinates.
+ * @brief   Gets the nth touch point's co-ordinates.
  *
- * @param e The pointer to the Evas canvas.
- * @param n The number of the touched point (0 being the first).
- * @param x The pointer to a Evas_Coord to be filled in.
- * @param y The pointer to a Evas_Coord to be filled in.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * Touch point's co-ordinates is updated whenever moving that point
- * on the canvas.
+ * @remarks Touch point's co-ordinates is updated whenever moving that point
+ *          on the canvas.
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas *evas;
  * Evas_Coord x, y;
@@ -12989,6 +15565,11 @@ EAPI unsigned int           evas_touch_point_list_count(Evas *e) EINA_ARG_NONNUL
  *   }
  * @endcode
  *
+ * @param[in]   e  The pointer to the Evas canvas
+ * @param[in]   n  The number of the touched point (0 being the first)
+ * @param[out]   x  The pointer to a Evas_Coord to be filled in
+ * @param[out]   y  The pointer to a Evas_Coord to be filled in
+ *
  * @see evas_touch_point_list_count()
  * @see evas_touch_point_list_nth_id_get()
  * @see evas_touch_point_list_nth_state_get()
@@ -12996,17 +15577,17 @@ EAPI unsigned int           evas_touch_point_list_count(Evas *e) EINA_ARG_NONNUL
 EAPI void                   evas_touch_point_list_nth_xy_get(Evas *e, unsigned int n, Evas_Coord *x, Evas_Coord *y) EINA_ARG_NONNULL(1);
 
 /**
- * This function returns the @p id of nth touch point.
+ * @brief   Gets the @a id of nth touch point.
  *
- * @param e The pointer to the Evas canvas.
- * @param n The number of the touched point (0 being the first).
- * @return id of nth touch point, if the call succeeded, -1 otherwise.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * The point which comes from Mouse Event has @p id 0 and The point
- * which comes from Multi Event has @p id that is same as Multi
- * Event's device id.
+ * @remarks The point which comes from Mouse Event has @a id 0 and The point
+ *          which comes from Multi Event has @a id that is same as Multi
+ *          Event's device ID.
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas *evas;
  * int id;
@@ -13018,6 +15599,11 @@ EAPI void                   evas_touch_point_list_nth_xy_get(Evas *e, unsigned i
  *   }
  * @endcode
  *
+ * @param[in]   e  The pointer to the Evas canvas
+ * @param[in]   n  The number of the touched point (@c 0 being the first)
+ * @return  The ID of nth touch point, \n 
+ *          otherwise @c -1
+ *
  * @see evas_touch_point_list_count()
  * @see evas_touch_point_list_nth_xy_get()
  * @see evas_touch_point_list_nth_state_get()
@@ -13025,19 +15611,18 @@ EAPI void                   evas_touch_point_list_nth_xy_get(Evas *e, unsigned i
 EAPI int                    evas_touch_point_list_nth_id_get(Evas *e, unsigned int n) EINA_ARG_NONNULL(1);
 
 /**
- * This function returns the @p state of nth touch point.
+ * @brief   Gets the @a state of nth touch point.
  *
- * @param e The pointer to the Evas canvas.
- * @param n The number of the touched point (0 being the first).
- * @return @p state of nth touch point, if the call succeeded,
- *         EVAS_TOUCH_POINT_CANCEL otherwise.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  *
- * The point's @p state is EVAS_TOUCH_POINT_DOWN when pressed,
- * EVAS_TOUCH_POINT_STILL when the point is not moved after pressed,
- * EVAS_TOUCH_POINT_MOVE when moved at least once after pressed and
- * EVAS_TOUCH_POINT_UP when released.
+ * @remarks The point's @a state is EVAS_TOUCH_POINT_DOWN when pressed,
+ *          EVAS_TOUCH_POINT_STILL when the point is not moved after pressed,
+ *          EVAS_TOUCH_POINT_MOVE when moved at least once after pressed and
+ *          EVAS_TOUCH_POINT_UP when released.
  *
- * Example:
+ * @remarks The following is an example:
  * @code
  * extern Evas *evas;
  * Evas_Touch_Point_State state;
@@ -13049,6 +15634,11 @@ EAPI int                    evas_touch_point_list_nth_id_get(Evas *e, unsigned i
  *   }
  * @endcode
  *
+ * @param[in]   e  The pointer to the Evas canvas
+ * @param[in]   n  The number of the touched point (@c 0 being the first)
+ * @return  @a state of nth touch point, \n
+ *          otherwise EVAS_TOUCH_POINT_CANCEL
+ *
  * @see evas_touch_point_list_count()
  * @see evas_touch_point_list_nth_xy_get()
  * @see evas_touch_point_list_nth_id_get()
old mode 100644 (file)
new mode 100755 (executable)
index 220214e..c0ffcea
@@ -10,12 +10,35 @@ extern "C" {
 
 /**
  * @defgroup Evas_GL Rendering GL on Evas
+ * @ingroup Evas_Canvas
+ *
+ * @brief This group discusses the functions that are used to do OpenGL rendering on Evas. Evas allows you
+ *        to use OpenGL to render to specially set up image objects (which act as
+ *        render target surfaces).
+ *        By default, Evas GL will use an OpenGL-ES 2.0 context and API set.
+ *
+ *
+ * <h2> Evas GL vs. Elementary GLView </h2>
  *
- * Functions that are used to do OpenGL rendering on Evas. Evas allows you
- * to use OpenGL to render to specially set up image objects (which act as
- * render target surfaces).
+ * While it is possible to Evas and Ecore_Evas to create an OpenGL application,
+ * using these low-level APIs can be troublesome for most users. Before
+ * diving in Evas GL, please refer to the page @ref elm_opengl_page.
+ *
+ * Elementary @ref GLView provides a set of helper functions in:
+ * @li @ref Elementary_GL_Helpers "Elementary_GL_Helpers.h"
+ *
+ * Similarly, two sets of helper functions are provided by Evas GL in the
+ * following header files:
+ * @li @ref Evas_GL_GLES1_Helpers "Evas_GL_GLES1_Helpers.h"
+ * @li @ref Evas_GL_GLES2_Helpers "Evas_GL_GLES2_Helpers.h"
+ *
+ * @{
+ */
+
+/*
+ * <h2> Evas GL usage example </h2>
  *
- * Below is an illlustrative example of how to use OpenGL to render to an
+ * Below is an illustrative example of how to use OpenGL to render to an
  * object in Evas.
  *
  * @code
@@ -39,10 +62,10 @@ typedef struct _GLData
    Eina_Bool        initialized : 1;
 } GLData;
 
-// callbacks we want to handle deletion on the object and updates/draws
+// Callbacks we need to handle deletion on the object and updates/draws
 static void      on_del       (void *data, Evas *e, Evas_Object *obj, void *event_info);
 static void      on_pixels    (void *data, Evas_Object *obj);
-// demo - animator just to keep ticking over saying to draw the image
+// Demo - animator just to keep ticking over asking to draw the image
 static Eina_Bool on_animate   (void *data);
 // gl stuff
 static int       init_shaders (GLData *gld);
@@ -51,23 +74,23 @@ static GLuint    load_shader  (GLData *gld, GLenum type, const char *shader_src)
 int
 main(int argc, char **argv)
 {
-   // a size by default
+   // A size by default
    int w = 256, h = 256;
-   // some variables we will use
+   // Some variables we will use
    Ecore_Evas  *ee;
    Evas *canvas;
    Evas_Object *r1;
    Evas_Native_Surface ns;
    GLData *gld = NULL;
 
-   // regular low-leve EFL (ecore+ecore-evas) init. elm is simpler
+   // Regular low-level EFL (ecore+ecore-evas) init. elm is simpler
    ecore_init();
    ecore_evas_init();
    ee = ecore_evas_gl_x11_new(NULL, 0, 0, 0, 512, 512);
    ecore_evas_title_set(ee, "Ecore_Evas Template");
    canvas = ecore_evas_get(ee);
 
-   // alloc a data struct to hold our relevant gl info in
+   // Alloc a data struct to hold our relevant gl info in it
    if (!(gld = calloc(1, sizeof(GLData)))) return 0;
 
    //-//-//-// THIS IS WHERE GL INIT STUFF HAPPENS (ALA EGL)
@@ -83,26 +106,26 @@ main(int argc, char **argv)
    //gld->cfg->stencil_bits = EVAS_GL_STENCIL_NONE;
    //gld->cfg->options_bits = EVAS_GL_OPTIONS_NONE;
 
-   // create a surface and context
+   // Create a surface and context
    gld->sfc = evas_gl_surface_create(gld->evasgl, gld->cfg, w, h);
    gld->ctx = evas_gl_context_create(gld->evasgl, NULL);
    //-//
    //-//-//-// END GL INIT BLOB
 
-   // set up the image object. a filled one by default
+   // Set up the image object. A filled one by default
    r1 = evas_object_image_filled_add(canvas);
-   // attach important data we need to the object using key names. this just
-   // avoids some global variables and means we can do nice cleanup. you can
+   // Attach important data we need to the object using key names. This just
+   // avoids some global variables which means we can do a good cleanup. You can
    // avoid this if you are lazy
    evas_object_data_set(r1, "..gld", gld);
-   // when the object is deleted - call the on_del callback. like the above,
+   // When the object is deleted - call the on_del callback. Like the above,
    // this is just being clean
    evas_object_event_callback_add(r1, EVAS_CALLBACK_DEL, on_del, NULL);
-   // set up an actual pixel size fot the buffer data. it may be different
-   // to the output size. any windowing system has something like this, just
+   // Set up an actual pixel size for the buffer data. It may be different
+   // from the output size. Any windowing system has something like this, only
    // evas has 2 sizes, a pixel size and the output object size
    evas_object_image_size_set(r1, w, h);
-   // set up the native surface info to use the context and surface created
+   // Set up the native surface info to use the context and surface created
    // above
 
    //-//-//-// THIS IS WHERE GL INIT STUFF HAPPENS (ALA EGL)
@@ -113,32 +136,32 @@ main(int argc, char **argv)
    //-//
    //-//-//-// END GL INIT BLOB
 
-   // move the image object somewhere, resize it and show it. any windowing
+   // Move the image object somewhere, resize it, and show it. Any windowing
    // system would need this kind of thing - place a child "window"
    evas_object_move(r1, 128, 128);
    evas_object_resize(r1, w, h);
    evas_object_show(r1);
 
-   // animating - just a demo. as long as you trigger an update on the image
-   // object via evas_object_image_pixels_dirty_set(). any display system,
-   // mainloop siztem etc. will have something of this kind unless it's making
-   // you spin infinitely yourself and invent your own animation mechanism
+   // Animating - just a demo. As long as you trigger an update on the image
+   // object via evas_object_image_pixels_dirty_set(), any display system,
+   // mainloop system etc., will have something of this kind unless it's making
+   // you spin infinitely by yourself and invent your own animation mechanism
    //
-   // NOTE: if you delete r1, this animator will keep running trying to access
+   // NOTE: If you delete r1, this animator will keep running and trying to access
    // r1 so you'd better delete this animator with ecore_animator_del() or
-   // structure how you do animation differently. you can also attach it like
-   // evasgl, sfc, etc. etc. if this animator is specific to this object
-   // only and delete it in the del handler for the obj.
+   // structure how you do animation differently. You can also attach it like
+   // evasgl, sfc, etc., if this animator is specific to this object
+   // then delete it in the del handler for the obj.
    ecore_animator_add(on_animate, r1);
 
-   // finally show the window for the world to see. windowing system generic
+   // Finally show the window for the world to see. Windowing system generic
    ecore_evas_show(ee);
 
-   // begin the mainloop and tick over the animator, handle events etc.
-   // also windowing system generic
+   // Begin the mainloop and tick over the animator, handle events, etc.
+   // Also windowing system generic
    ecore_main_loop_begin();
 
-   // standard EFL shutdown stuff - generic for most systems, EFL or not
+   // Standard EFL shutdown stuff - generic for most systems, EFL or not
    ecore_evas_shutdown();
    ecore_shutdown();
    return 0;
@@ -147,11 +170,11 @@ main(int argc, char **argv)
 static void
 on_del(void *data, Evas *e, Evas_Object *obj, void *event_info)
 {
-   // on delete of our object clean up some things that don't get auto
-   // celeted for us as they are not intrinsically bound to the image
+   // On delete of our object clean up some things that don't get auto
+   // deleted for us as they are not intrinsically bound to the image
    // object as such (you could use the same context and surface across
-   // multiple image objects and re-use the evasgl handle too multiple times.
-   // here we bind them to 1 object only though by doing this.
+   // multiple image objects and re-use the evasgl handle multiple times.
+   // Here we bind them to only 1 object though by doing this.
    GLData *gld = evas_object_data_get(obj, "..gld");
    if (!gld) return;
    Evas_GL_API *gl = gld->glapi;
@@ -174,7 +197,7 @@ on_del(void *data, Evas *e, Evas_Object *obj, void *event_info)
 static void
 on_pixels(void *data, Evas_Object *obj)
 {
-   // get some variable we need from the object data keys
+   // Get some variable we need from the object data keys
    GLData *gld = evas_object_data_get(obj, "..gld");
    if (!gld) return;
    Evas_GL_API *gl = gld->glapi;
@@ -186,9 +209,9 @@ on_pixels(void *data, Evas_Object *obj)
      };
    int w, h;
 
-   // get the image size in case it changed with evas_object_image_size_set()
+   // Get the image size, in case it changed, with evas_object_image_size_set()
    evas_object_image_size_get(obj, &w, &h);
-   // set up the context and surface as the current one
+   // Set up the context and surface as the current one
    evas_gl_make_current(gld->evasgl, gld->sfc, gld->ctx);
 
    if (!gld->initialized)
@@ -197,8 +220,8 @@ on_pixels(void *data, Evas_Object *obj)
         gld->initialized = EINA_TRUE;
      }
 
-   // GL Viewport stuff. you can avoid doing this if viewport is all the
-   // same as last frame if you want
+   // GL Viewport stuff. You can avoid doing this if viewport is all the
+   // same as the last frame, if you want
    gl->glViewport(0, 0, w, h);
 
    // Clear the buffer
@@ -222,11 +245,11 @@ on_pixels(void *data, Evas_Object *obj)
 static Eina_Bool
 on_animate(void *data)
 {
-   // just a demo - animate here whenever an animation tick happens and then
-   // mark the image as "dirty" meaning it needs an update next time evas
-   // renders. it will call the pixel get callback then.
+   // Just a demo - Animate here whenever an animation tick happens and then
+   // mark the image as "dirty" meaning it needs an update the next time evas
+   // renders. It will then call the pixel get callback.
    evas_object_image_pixels_dirty_set(data, EINA_TRUE);
-   return EINA_TRUE; // keep looping
+   return EINA_TRUE; // Keep looping
 }
 
 static GLuint
@@ -324,128 +347,167 @@ init_shaders(GLData *gld)
    return 1;
 }
  * @endcode
- *
- * @ingroup Evas_Canvas
- */
-
-/**
- * @addtogroup Evas_GL
- * @{
  */
 
 /**
   * @typedef Evas_GL
   *
-  * Evas GL Object for rendering gl in Evas.
-  */ 
+  * @brief The structure type of the Evas GL object used to render GL in Evas.
+  */
 typedef struct _Evas_GL               Evas_GL;
 
 /**
   * @typedef Evas_GL_Surface
   *
-  * Evas GL Surface object, a GL rendering target in Evas GL.
-  */ 
+  * @brief The structure type of the Evas GL Surface object, a GL rendering target in Evas GL.
+  */
 typedef struct _Evas_GL_Surface       Evas_GL_Surface;
 
 /**
   * @typedef Evas_GL_Context
   *
-  * Evas GL Context object, a GL rendering context in Evas GL.
-  */ 
+  * @brief The structure type of the Evas GL Context object, a GL rendering context in Evas GL.
+  */
 typedef struct _Evas_GL_Context       Evas_GL_Context;
 
 /**
   * @typedef Evas_GL_Config
   *
-  * Evas GL Surface configuration object for surface creation.
-  */ 
+  * @brief The structure type of the Evas GL Surface configuration object for surface creation.
+  */
 typedef struct _Evas_GL_Config        Evas_GL_Config;
 
 /**
   * @typedef Evas_GL_API
   *
-  * Evas GL API object that contains the GL APIs to be used in Evas GL.
-  */ 
+  * @brief The structure type of the Evas GL API object that contains the GL APIs to be used in Evas GL.
+  */
 typedef struct _Evas_GL_API           Evas_GL_API;
 
 /**
   * @typedef Evas_GL_Func
   *
-  * Evas GL Function Object used as a function pointer.
-  */ 
+  * @brief Represents a function pointer, that can be used for Evas GL extensions.
+  */
 typedef void                         *Evas_GL_Func;
 
 /**
   * @typedef EvasGLImage
   *
-  * Evas GL Image Object used in Evas GL Image extension.
-  */ 
+  * @brief Represents an Evas GL Image object used with Evas GL Image extensions.
+  */
 typedef void                         *EvasGLImage;
 
 /**
- * Surface Color Format
+ * @brief Enumeration that defines the available surface color formats.
  */
 typedef enum _Evas_GL_Color_Format
 {
-    EVAS_GL_RGB_888   = 0,
-    EVAS_GL_RGBA_8888 = 1
+    EVAS_GL_RGB_888   = 0, /**< Opaque RGB surface */
+    EVAS_GL_RGBA_8888 = 1, /**< RGBA surface with alpha */
+    EVAS_GL_NO_FBO    = 2  /**< Special value for creating PBuffer surfaces without any attached buffer. @see evas_gl_pbuffer_surface_create. @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */
 } Evas_GL_Color_Format;
 
 /**
- * Surface Depth Format
+ * @brief Enumeration that defines the Surface Depth Format.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  */
 typedef enum _Evas_GL_Depth_Bits
 {
     EVAS_GL_DEPTH_NONE   = 0,
-    EVAS_GL_DEPTH_BIT_8  = 1,
-    EVAS_GL_DEPTH_BIT_16 = 2,
-    EVAS_GL_DEPTH_BIT_24 = 3,
-    EVAS_GL_DEPTH_BIT_32 = 4
+    EVAS_GL_DEPTH_BIT_8  = 1,   /**< 8 bits precision surface depth */
+    EVAS_GL_DEPTH_BIT_16 = 2,   /**< 16 bits precision surface depth */
+    EVAS_GL_DEPTH_BIT_24 = 3,   /**< 24 bits precision surface depth */
+    EVAS_GL_DEPTH_BIT_32 = 4    /**< 32 bits precision surface depth */
 } Evas_GL_Depth_Bits;
 
 /**
- * Surface Stencil Format
+ * @brief Enumeration that defines the Surface Stencil Format.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  */
 typedef enum _Evas_GL_Stencil_Bits
 {
     EVAS_GL_STENCIL_NONE   = 0,
-    EVAS_GL_STENCIL_BIT_1  = 1,
-    EVAS_GL_STENCIL_BIT_2  = 2,
-    EVAS_GL_STENCIL_BIT_4  = 3,
-    EVAS_GL_STENCIL_BIT_8  = 4,
-    EVAS_GL_STENCIL_BIT_16 = 5
+    EVAS_GL_STENCIL_BIT_1  = 1,   /**< 1 bit precision for stencil buffer */
+    EVAS_GL_STENCIL_BIT_2  = 2,   /**< 2 bits precision for stencil buffer */
+    EVAS_GL_STENCIL_BIT_4  = 3,   /**< 4 bits precision for stencil buffer */
+    EVAS_GL_STENCIL_BIT_8  = 4,   /**< 8 bits precision for stencil buffer */
+    EVAS_GL_STENCIL_BIT_16 = 5    /**< 16 bits precision for stencil buffer */
 } Evas_GL_Stencil_Bits;
 
 /**
- * Configuration Options.
+ * @brief Enumeration that defines the Configuration Options.
  *
  * @since 1.1
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  */
 typedef enum _Evas_GL_Options_Bits
 {
    EVAS_GL_OPTIONS_NONE    = 0,     /**< No extra options */
-   EVAS_GL_OPTIONS_DIRECT  = (1<<0) /**< Optional hint to allow rendering directly to evas' window when possible */
+   EVAS_GL_OPTIONS_DIRECT  = (1<<0),/**< Optional hint to allow rendering directly to the Evas window if possible */
+   EVAS_GL_OPTIONS_CLIENT_SIDE_ROTATION = (1<<1) /**< Force direct rendering even if the canvas is rotated.
+                                                  *   In that case, it is the application's role to rotate the contents of
+                                                  *   the Evas_GL view. @see evas_gl_rotation_get */
 } Evas_GL_Options_Bits;
 
 /**
- * Configuration Option for Multisample Anti-aliased (MSAA) rendering surface.
- * Only works in supported device.
+ * @brief Enumeration that defines the configuration options for a Multisample Anti-Aliased (MSAA) rendering surface.
  *
  * @since 1.2
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @remarks This only works on devices that support the required extensions.
  */
 typedef enum _Evas_GL_Multisample_Bits
 {
    EVAS_GL_MULTISAMPLE_NONE = 0, /**< No multisample rendering */
-   EVAS_GL_MULTISAMPLE_LOW  = 1, /**< MSAA with mininum number of samples */
-   EVAS_GL_MULTISAMPLE_MED  = 2, /**< MSAA with half the number of max samples */
+   EVAS_GL_MULTISAMPLE_LOW  = 1, /**< MSAA with minimum number of samples */
+   EVAS_GL_MULTISAMPLE_MED  = 2, /**< MSAA with half the maximum number of samples */
    EVAS_GL_MULTISAMPLE_HIGH = 3  /**< MSAA with maximum allowed samples */
 } Evas_GL_Multisample_Bits;
 
 /**
-  * @struct _Evas_GL_Config
-  *
-  * Evas GL Surface configuration
-  */
+ * @brief Enumeration that defines the available OpenGL ES version numbers.
+ *        They can be used to create OpenGL-ES 1.1 contexts.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @see evas_gl_context_version_create
+ *
+ * @remarks This will only work with EGL/GLES (but not with desktop OpenGL).
+ */
+typedef enum _Evas_GL_Context_Version
+{
+   EVAS_GL_GLES_1_X = 1, /**< OpenGL-ES 1.x */
+   EVAS_GL_GLES_2_X = 2, /**< OpenGL-ES 2.x is the default */
+   EVAS_GL_GLES_3_X = 3  /**< @internal OpenGL-ES 3.x, not implemented yet */
+} Evas_GL_Context_Version;
+
+/**
+ * @struct _Evas_GL_Config
+ *
+ * @brief A structure used to specify the configuration of an @ref Evas_GL_Surface.
+ *
+ * This structure should be allocated with @ref evas_gl_config_new() and released
+ * with @ref evas_gl_config_free().
+ *
+ * @see evas_gl_surface_create
+ * @see evas_gl_pbuffer_surface_create
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ */
 struct _Evas_GL_Config
 {
    Evas_GL_Color_Format       color_format;     /**< Surface Color Format */
@@ -453,132 +515,457 @@ struct _Evas_GL_Config
    Evas_GL_Stencil_Bits       stencil_bits;     /**< Surface Stencil Bits */
    Evas_GL_Options_Bits       options_bits;     /**< Extra Surface Options */
    Evas_GL_Multisample_Bits   multisample_bits; /**< Optional Surface MSAA Bits */
+   Evas_GL_Context_Version    gles_version;     /**< @internal Special flag for OpenGL-ES 1.1 indirect rendering surfaces */
 };
 
+/** @brief Constant to use when calling @ref evas_gl_string_query to retrieve the available Evas_GL extensions. */
 #define EVAS_GL_EXTENSIONS       1
 
 
 /**
- * Creates a new Evas_GL object and returns a handle for gl rendering on efl.
+ * @brief Creates a new Evas_GL object and returns a handle for GL rendering with the EFL.
+ *
+ * @param[in] e The given Evas canvas to use
  *
- * @param e The given evas canvas OpenGL is to be used on.
- * @return The created evas_gl object, or NULl on fasilure.
+ * @return The created Evas_GL object, or @c NULL in case of failure
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  */
 EAPI Evas_GL                 *evas_gl_new                (Evas *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Frees the created Evas_GL object.
+ * @brief Frees an Evas_GL object.
+ *
+ * @param[in] evas_gl   The given Evas_GL object to destroy
  *
- * @param evas_gl The given Evas_GL object.
+ * @see evas_gl_new
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  */
 EAPI void                     evas_gl_free               (Evas_GL *evas_gl) EINA_ARG_NONNULL(1);
 
 /**
- * Allocates a new config object for the user to fill out.
+ * @brief Allocates a new config object for the user to fill out.
+ *
+ * @remarks As long as Evas creates a config object for the user, it takes care
+ *          of the backward compatibility issue.
  *
- * As long as the Evas creates a config object for the user, it takes care
- * of the backward compatibility issue.
+ * @see evas_gl_config_free
+ *
+ * @return A new config object
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  */
 EAPI Evas_GL_Config          *evas_gl_config_new         (void);
 
 /**
- * Frees a config object created from evas_gl_config_new.
+ * @brief Frees a config object created from evas_gl_config_new.
+ *
+ * @param[in] cfg  The configuration structure to free, it can not be accessed afterwards.
+ *
+ * @remarks As long as Evas creates a config object for the user, it takes care
+ *          of the backward compatibility issue.
  *
- * As long as the Evas creates a config object for the user, it takes care
- * of the backward compatibility issue.
+ * @see evas_gl_config_new
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  */
 EAPI void                     evas_gl_config_free        (Evas_GL_Config *cfg) EINA_ARG_NONNULL(1);
 
 /**
- * Creates and returns new Evas_GL_Surface object for GL Rendering.
+ * @brief Creates and returns a new @ref Evas_GL_Surface object for GL Rendering.
+ *
+ * @param[in] evas_gl The given Evas_GL object
+ * @param[in] cfg     The pixel format and configuration of the rendering surface
+ * @param[in] w       The width of the surface
+ * @param[in] h       The height of the surface
+ *
+ * @return The created GL surface object,
+ *         otherwise @c NULL on failure
+ *
+ * @see evas_gl_surface_destroy
  *
- * @param evas_gl The given Evas_GL object.
- * @param cfg The pixel format and configuration of the rendering surface.
- * @param w The width of the surface.
- * @param h The height of the surface.
- * @return The created GL surface object, or NULL on failure.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  */
 EAPI Evas_GL_Surface         *evas_gl_surface_create     (Evas_GL *evas_gl, Evas_GL_Config *cfg, int w, int h) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1,2);
 
 /**
- * Destroys the created Evas GL Surface.
+ * @brief Create a pixel buffer surface
+ *
+ * @param[in] evas_gl     The given Evas_GL object
+ * @param[in] cfg         Pixel format and configuration of the pixel buffer surface
+ * @param[in] w           Requested width of the buffer
+ * @param[in] h           Requested height of the buffer
+ * @param[in] attrib_list An optional list of attribute-value pairs terminated by attribute 0, can be @c NULL. Currently, no attributes are supported.
+ *
+ * @return The created GL surface object,
+ *         otherwise @c NULL on failure
+ *
+ * The surface must be released with @ref evas_gl_surface_destroy.
+ *
+ * If the color format in @a cfg is @ref EVAS_GL_RGB_888 or @ref EVAS_GL_RGBA_8888,
+ * then Evas will automatically generate a framebuffer attached to this PBuffer.
+ * Its properties can be queried using @ref evas_gl_native_surface_get.
+ * If you want to attach an FBO yourself, or create a PBuffer surface only,
+ * please use the color format @ref EVAS_GL_NO_FBO.
+ *
+ * Creating a 1x1 PBuffer surface can be useful in order to call
+ * @ref evas_gl_make_current() from another thread.
+ *
+ * @note The attribute list can be terminated by EVAS_GL_NONE or 0.
+ *       As of now, no special attributes are supported yet. Also, only EGL
+ *       is supported at the moment of writing.
+ *
+ * @see evas_gl_surface_destroy
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ */
+EAPI Evas_GL_Surface         *evas_gl_pbuffer_surface_create(Evas_GL *evas_gl, Evas_GL_Config *cfg, int w, int h, const int *attrib_list) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1,2);
+
+/**
+ * @brief Destroys an Evas GL Surface.
+ *
+ * @param[in] evas_gl   The given Evas_GL object
+ * @param[in] surf      The given GL surface object
  *
- * @param evas_gl The given Evas_GL object.
- * @param surf The given GL surface object.
+ * @note This function can also destroy pbuffer surfaces.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  */
 EAPI void                     evas_gl_surface_destroy    (Evas_GL *evas_gl, Evas_GL_Surface *surf) EINA_ARG_NONNULL(1,2);
 
 /**
- * Creates and returns a new Evas GL context object
+ * @brief Creates and returns a new Evas GL context object (OpenGL-ES 2.0).
+ *
+ * @param[in] evas_gl    The given Evas_GL object
+ * @param[in] share_ctx  An Evas_GL context to share with the new context
+ *
+ * The API in use will be an OpenGL-ES 2.0 API (ie. with framebuffers and shaders).
+ * Consider calling @ref evas_gl_context_version_create if you need an OpenGL-ES 1.1
+ * context instead.
+ *
+ * @return The created context,
+ *         otherwise @c NULL on failure
  *
- * @param evas_gl The given Evas_GL object.
- * @return The created context, or NULL on failure.
+ * @see evas_gl_context_version_create
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  */
 EAPI Evas_GL_Context         *evas_gl_context_create     (Evas_GL *evas_gl, Evas_GL_Context *share_ctx) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
 /**
- * Destroys the given Evas GL context object
+ * @brief Creates and returns a new Evas GL context object for OpenGL-ES 1.1 or 2.0.
+ *
+ * @param[in] evas_gl    The given Evas_GL object
+ * @param[in] share_ctx  A context to share (can be NULL)
+ * @param[in] version    Major OpenGL-ES version number
+ *
+ * @return The created context,
+ *         otherwise @c NULL on failure
+ *
+ * This function can be used to create OpenGL-ES 1.1 contexts, but OpenGL-ES 3.x
+ * is not supported yet.
+ *
+ * The GL API bound to the created context must be queried using
+ * @ref evas_gl_context_api_get (instead of @ref evas_gl_api_get).
+ *
+ * @note GLES 3.x is not supported yet.
+ *
+ * @see Evas_GL_Context_Version
+ * @see evas_gl_context_api_get
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ */
+EAPI Evas_GL_Context         *evas_gl_context_version_create(Evas_GL *evas_gl, Evas_GL_Context *share_ctx, Evas_GL_Context_Version version) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Destroys the given Evas GL context object.
+ *
+ * @param[in] evas_gl The given Evas_GL object
+ * @param[in] ctx     The given Evas GL context
  *
- * @param evas_gl The given Evas_GL object.
- * @param ctx The given Evas GL context.
+ * @see evas_gl_context_create
+ * @see evas_gl_context_version_create
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  */
 EAPI void                     evas_gl_context_destroy    (Evas_GL *evas_gl, Evas_GL_Context *ctx) EINA_ARG_NONNULL(1,2);
 
 /**
- * Sets the given context as a current context for the given surface
+ * @brief Sets the given context as the current context for the given surface.
+ *
+ * @param[in] evas_gl The given Evas_GL object
+ * @param[in] surf The given Evas GL surface
+ * @param[in] ctx The given Evas GL context
+ * @return @c EINA_TRUE if successful,
+ *         otherwise @c EINA_FALSE if not
  *
- * @param evas_gl The given Evas_GL object.
- * @param surf The given Evas GL surface.
- * @param ctx The given Evas GL context.
- * @return @c EINA_TRUE if successful, @c EINA_FALSE if not.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  */
 EAPI Eina_Bool                evas_gl_make_current       (Evas_GL *evas_gl, Evas_GL_Surface *surf, Evas_GL_Context *ctx) EINA_ARG_NONNULL(1,2);
 
 /**
- * Returns a pointer to a static, zero-terminated string describing some aspect of evas_gl.
+ * @brief Returns a pointer to a static, null-terminated string describing some aspect of Evas GL.
  *
- * @param evas_gl The given Evas_GL object.
- * @param name Specifies a symbolic constant, one of EVAS_GL_EXTENSIONS...
+ * @param[in] evas_gl The given Evas_GL object
+ * @param[in] name    A symbolic constant, only @ref EVAS_GL_EXTENSIONS is supported for now
+ * @return A string describing some aspect of Evas GL
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  */
 EAPI const char              *evas_gl_string_query       (Evas_GL *evas_gl, int name) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE;
 
 /**
- * Returns a GL or the Glue Layer's extension function.
+ * @brief Returns a extension function from the Evas_GL glue layer.
+ *
+ * @param[in] evas_gl  The given Evas_GL object
+ * @param[in] name     The name of the function to return
  *
- * @param evas_gl The given Evas_GL object.
- * @param name The name of the function to return.
+ * The available extension functions may depend on the backend engine Evas GL is
+ * running on.
+ *
+ * @note Evas_GL extensions are not EGL or OpenGL extensions, but Evas_GL-specific
+ *       features.
+ *
+ * @return A function pointer to the Evas_GL extension.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  */
 EAPI Evas_GL_Func             evas_gl_proc_address_get   (Evas_GL *evas_gl, const char *name) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1,2) EINA_PURE;
 
 /**
- * Fills in the Native Surface information from the given Evas GL surface.
+ * @brief Fills in the Native Surface information from a given Evas GL surface.
+ *
+ * @param[in]  evas_gl The given Evas_GL object
+ * @param[in]  surf    The given Evas GL surface to retrieve the Native Surface information from
+ * @param[out] ns      The native surface structure that the function fills in
+ * @return @c EINA_TRUE if successful,
+ *         otherwise @c EINA_FALSE if not
  *
- * @param evas_gl The given Evas_GL object.
- * @param surf The given Evas GL surface to retrieve the Native Surface info from.
- * @param ns The native surface structure that the function fills in.
- * @return @c EINA_TRUE if successful, @c EINA_FALSE if not.
+ * @details This function can be called to later set this native surface as
+ *          source of an Evas Object Image. Please refer to
+ *          @ref evas_object_image_native_surface_set.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
  */
 EAPI Eina_Bool                evas_gl_native_surface_get (Evas_GL *evas_gl, Evas_GL_Surface *surf, Evas_Native_Surface *ns) EINA_ARG_NONNULL(1,2,3);
 
 /**
- * Get the API for rendering using OpenGL
+ * @brief Gets the API for rendering using OpenGL.
+ *
+ * @details This returns a structure that contains all the OpenGL functions you can
+ *          use to render in Evas. These functions consist of all the standard
+ *          OpenGL-ES2.0 functions and any additional ones that Evas has decided to provide.
+ *          This means that if you have your code ported to OpenGL-ES2.0,
+ *          it is going to be easy to render to Evas.
+ *
+ * @param[in] evas_gl The given Evas_GL object
+ *
+ * @return The API to use
  *
- * @param evas_gl The given Eva_GL object.
- * @return The API to use.
+ * @note This function will always return an OpenGL-ES 2.0 API, please use
+ *       @ref evas_gl_context_api_get instead to get an OpenGL-ES 1.1 set of APIs.
  *
- * This returns a structure that contains all the OpenGL functions you can
- * use to render in Evas. These functions consist of all the standard
- * OpenGL-ES2.0 functions and any extra ones Evas has decided to provide in
- * addition. This means that if you have your code ported to OpenGL-ES2.0,
- * it will be easy to render to Evas.
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @see Evas_GL_API
+ * @see evas_gl_context_api_get
  *
  */
 EAPI Evas_GL_API             *evas_gl_api_get            (Evas_GL *evas_gl) EINA_ARG_NONNULL(1);
 
-#if !defined(__gl_h_) && !defined(__gl2_h_)
-# define __gl_h_
+/**
+ * @brief Gets the API for rendering using OpenGL with non standard contexts.
+ *
+ * This function is similar to @ref evas_gl_api_get but takes an extra Evas GL
+ * context argument as it is used to get the real API used by special contexts,
+ * that have been instanciated with @ref evas_gl_context_version_create().
+ *
+ * This function can be used to get the GL API for a OpenGL-ES 1.1 context. When
+ * using OpenGL-ES 1.1, applications should always use @ref evas_gl_context_api_get
+ * and never call @ref evas_gl_api_get (this will always return a OpenGL-ES 2+ API).
+ *
+ * @param[in] evas_gl The given Evas_GL object
+ * @param[in] ctx     Specifies which context to use, based on this, Evas GL
+ *                    will return a 1.1- or a 2.0-compatible OpenGL-ES API.
+ *
+ * @return The API to use. Only the available function pointers will be set
+ *         in the structure. All the non compatible functions or unsupported
+ *         extension function pointers will be set to NULL.
+ *
+ * @see Evas_GL_API
+ * @see evas_gl_api_get
+ * @see evas_gl_context_version_create
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ */
+EAPI Evas_GL_API             *evas_gl_context_api_get    (Evas_GL *evas_gl, Evas_GL_Context *ctx) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Get the current rotation of the view, in degrees.
+ *
+ * This function should be called in order to properly handle the current
+ * rotation of the view. It will always return 0 unless the option
+ * @ref EVAS_GL_OPTIONS_CLIENT_SIDE_ROTATION has been set.
+ *
+ * Indeed, in case of direct rendering to the back buffer, the client
+ * application is responsible for properly rotating its view. This can generally
+ * be done by applying a rotation to a view matrix.
+ *
+ * @param[in] evas_gl    The current Evas_GL object
+ *
+ * @note The returned value may not be the same as the window rotation, for
+ * example if indirect rendering is used as a fallback, or if the GPU supports
+ * transparent rotation of the buffer during swap.
+ *
+ * @return 0, 90, 180 or 270 depending on the Evas canvas' orientation.
+ *
+ * @see EVAS_GL_OPTIONS_CLIENT_SIDE_ROTATION
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ */
+EAPI int                      evas_gl_rotation_get       (Evas_GL *evas_gl) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+
+/**
+ * @brief Query a surface for its properties
+ *
+ * @param[in]  evas_gl    The current Evas_GL object
+ * @param[in]  surface    An Evas_GL_Surface surface to query
+ * @param[in]  attribute  Specifies the attribute to query.
+ * @param[out] value      Returns the requested value (usually an int)
+ *
+ * The currently accepted attributes are the following:
+ * @li @ref EVAS_GL_WIDTH,
+ * @li @ref EVAS_GL_HEIGHT,
+ * @li @ref EVAS_GL_TEXTURE_FORMAT,
+ * @li @ref EVAS_GL_TEXTURE_TARGET
+ *
+ * @return EINA_TRUE in case of success, EINA_FALSE in case of error.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ */
+EAPI Eina_Bool                evas_gl_surface_query      (Evas_GL *evas_gl, Evas_GL_Surface *surface, int attribute, void *value) EINA_ARG_NONNULL(1,2);
+
+/**
+ * @brief Returns the last error of any evas_gl function called in the current thread.
+ *        Initially, the error is set to @ref EVAS_GL_SUCCESS. A call to @ref evas_gl_error_get
+ *        resets the error to @ref EVAS_GL_SUCCESS.
+ *
+ * @param[in] evas_gl The given Evas_GL object
+ *
+ * @return @ref EVAS_GL_SUCCESS in case of no error, or any other @c EVAS_GL error code.
+ *
+ * Since Evas GL is a glue layer for GL imitating EGL, the error codes returned
+ * have a similar meaning as those defined in EGL, so please refer to the EGL
+ * documentation for more information about the various error codes.
+ *
+ * @note Evas GL does not specify exactly which error codes will be returned in
+ *       which circumstances. This is because different backends may behave
+ *       differently and Evas GL will try to give the most meaningful error code
+ *       based on the backend's error. Evas GL only tries to provide some
+ *       information, so an application can not expect the exact same error
+ *       codes as EGL would return.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ */
+EAPI int                      evas_gl_error_get          (Evas_GL *evas_gl) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Returns the Evas GL context object in use or set by @ref evas_gl_make_current.
+ *
+ * @param[in] evas_gl The given Evas_GL object
+ *
+ * @return The current context for the calling thread, or @c NULL in case of
+ *         failure and when there is no current context in this thread.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ */
+EAPI Evas_GL_Context         *evas_gl_current_context_get (Evas_GL *evas_gl) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Returns the Evas GL surface object in use or set by @ref evas_gl_make_current
+ *
+ * @param evas_gl The given Evas_GL object
+ *
+ * @return The current surface for the calling thread, or @c NULL in case of
+ *         failure and when there is no current surface in this thread.
+ *
+ * This can be used to get a handle to the current surface, so as to switch
+ * between contexts back and forth. Note that the OpenGL driver may stall when
+ * doing so.
+ *
+ * @see evas_gl_make_current
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ */
+EAPI Evas_GL_Surface         *evas_gl_current_surface_get (Evas_GL *evas_gl) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
+
+
+
+/*-------------------------------------------------------------------------
+ * Data types, definitions and values for use with Evas GL.
+ *
+ * The following definitions have been imported from the official GLES/GLES2
+ * header files. Please do not include the official GL headers along with
+ * Evas_GL.h as these will conflict.
+ *-----------------------------------------------------------------------*/
+
+#ifndef KHRONOS_SUPPORT_INT64
+typedef unsigned long long khronos_uint64_t;
+typedef signed long long   khronos_int64_t;
+#endif
+
+// Due to build conflicts on various platforms, we can't use GL[u]int64 directly
+typedef khronos_int64_t    EvasGLint64;
+typedef khronos_uint64_t   EvasGLuint64;
+
+#if !defined(__gl2_h_)
 # define __gl2_h_
 
+#define GL_ES_VERSION_2_0 1
+
 /*
  * This document is licensed under the SGI Free Software B License Version
  * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
@@ -589,6 +976,7 @@ EAPI Evas_GL_API             *evas_gl_api_get            (Evas_GL *evas_gl) EINA
  *-----------------------------------------------------------------------*/
 
 typedef void             GLvoid;
+typedef char             GLchar;
 typedef unsigned int     GLenum;
 typedef unsigned char    GLboolean;
 typedef unsigned int     GLbitfield;
@@ -607,8 +995,6 @@ typedef signed int       GLfixed;      // Changed khronos_int32_t
 typedef signed long int  GLintptr;     // Changed khronos_intptr_t
 typedef signed long int  GLsizeiptr;   // Changed khronos_ssize_t
 
-//#if (!defined(__gl2_h_) && !defined(__gl_h_))
-
 /* OpenGL ES core versions */
 //#define GL_ES_VERSION_2_0                 1
 
@@ -1044,256 +1430,2223 @@ typedef signed long int  GLsizeiptr;   // Changed khronos_ssize_t
 # endif
 #endif
 
+#ifndef __gl2ext_h_
+#define __gl2ext_h_ 1
+
+#ifndef GL_KHR_blend_equation_advanced
+#define GL_KHR_blend_equation_advanced 1
+#define GL_BLEND_ADVANCED_COHERENT_KHR    0x9285
+#define GL_MULTIPLY_KHR                   0x9294
+#define GL_SCREEN_KHR                     0x9295
+#define GL_OVERLAY_KHR                    0x9296
+#define GL_DARKEN_KHR                     0x9297
+#define GL_LIGHTEN_KHR                    0x9298
+#define GL_COLORDODGE_KHR                 0x9299
+#define GL_COLORBURN_KHR                  0x929A
+#define GL_HARDLIGHT_KHR                  0x929B
+#define GL_SOFTLIGHT_KHR                  0x929C
+#define GL_DIFFERENCE_KHR                 0x929E
+#define GL_EXCLUSION_KHR                  0x92A0
+#define GL_HSL_HUE_KHR                    0x92AD
+#define GL_HSL_SATURATION_KHR             0x92AE
+#define GL_HSL_COLOR_KHR                  0x92AF
+#define GL_HSL_LUMINOSITY_KHR             0x92B0
+#endif /* GL_KHR_blend_equation_advanced */
+
+#ifndef GL_KHR_debug
+#define GL_KHR_debug 1
+#define GL_SAMPLER                        0x82E6
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR   0x8242
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243
+#define GL_DEBUG_CALLBACK_FUNCTION_KHR    0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM_KHR  0x8245
+#define GL_DEBUG_SOURCE_API_KHR           0x8246
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247
+#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR   0x8249
+#define GL_DEBUG_SOURCE_APPLICATION_KHR   0x824A
+#define GL_DEBUG_SOURCE_OTHER_KHR         0x824B
+#define GL_DEBUG_TYPE_ERROR_KHR           0x824C
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E
+#define GL_DEBUG_TYPE_PORTABILITY_KHR     0x824F
+#define GL_DEBUG_TYPE_PERFORMANCE_KHR     0x8250
+#define GL_DEBUG_TYPE_OTHER_KHR           0x8251
+#define GL_DEBUG_TYPE_MARKER_KHR          0x8268
+#define GL_DEBUG_TYPE_PUSH_GROUP_KHR      0x8269
+#define GL_DEBUG_TYPE_POP_GROUP_KHR       0x826A
+#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B
+#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C
+#define GL_DEBUG_GROUP_STACK_DEPTH_KHR    0x826D
+#define GL_BUFFER_KHR                     0x82E0
+#define GL_SHADER_KHR                     0x82E1
+#define GL_PROGRAM_KHR                    0x82E2
+#define GL_VERTEX_ARRAY_KHR               0x8074
+#define GL_QUERY_KHR                      0x82E3
+#define GL_SAMPLER_KHR                    0x82E6
+#define GL_MAX_LABEL_LENGTH_KHR           0x82E8
+#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR   0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR  0x9144
+#define GL_DEBUG_LOGGED_MESSAGES_KHR      0x9145
+#define GL_DEBUG_SEVERITY_HIGH_KHR        0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM_KHR      0x9147
+#define GL_DEBUG_SEVERITY_LOW_KHR         0x9148
+#define GL_DEBUG_OUTPUT_KHR               0x92E0
+#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR     0x00000002
+#define GL_STACK_OVERFLOW_KHR             0x0503
+#define GL_STACK_UNDERFLOW_KHR            0x0504
+#endif /* GL_KHR_debug */
+
+#ifndef GL_KHR_texture_compression_astc_hdr
+#define GL_KHR_texture_compression_astc_hdr 1
+#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR   0x93B0
+#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR   0x93B1
+#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR   0x93B2
+#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR   0x93B3
+#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR   0x93B4
+#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR   0x93B5
+#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR   0x93B6
+#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR   0x93B7
+#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR  0x93B8
+#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR  0x93B9
+#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR  0x93BA
+#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
+#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
+#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
+#endif /* GL_KHR_texture_compression_astc_hdr */
+
+#ifndef GL_KHR_texture_compression_astc_ldr
+#define GL_KHR_texture_compression_astc_ldr 1
+#endif /* GL_KHR_texture_compression_astc_ldr */
+
+#ifndef GL_OES_EGL_image
+#define GL_OES_EGL_image 1
+#endif /* GL_OES_EGL_image */
+
+#ifndef GL_OES_EGL_image_external
+#define GL_OES_EGL_image_external 1
+#define GL_TEXTURE_EXTERNAL_OES           0x8D65
+#define GL_TEXTURE_BINDING_EXTERNAL_OES   0x8D67
+#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68
+#define GL_SAMPLER_EXTERNAL_OES           0x8D66
+#endif /* GL_OES_EGL_image_external */
+
+#ifndef GL_OES_compressed_ETC1_RGB8_texture
+#define GL_OES_compressed_ETC1_RGB8_texture 1
+#define GL_ETC1_RGB8_OES                  0x8D64
+#endif /* GL_OES_compressed_ETC1_RGB8_texture */
+
+#ifndef GL_OES_compressed_paletted_texture
+#define GL_OES_compressed_paletted_texture 1
+#define GL_PALETTE4_RGB8_OES              0x8B90
+#define GL_PALETTE4_RGBA8_OES             0x8B91
+#define GL_PALETTE4_R5_G6_B5_OES          0x8B92
+#define GL_PALETTE4_RGBA4_OES             0x8B93
+#define GL_PALETTE4_RGB5_A1_OES           0x8B94
+#define GL_PALETTE8_RGB8_OES              0x8B95
+#define GL_PALETTE8_RGBA8_OES             0x8B96
+#define GL_PALETTE8_R5_G6_B5_OES          0x8B97
+#define GL_PALETTE8_RGBA4_OES             0x8B98
+#define GL_PALETTE8_RGB5_A1_OES           0x8B99
+#endif /* GL_OES_compressed_paletted_texture */
+
+#ifndef GL_OES_depth24
+#define GL_OES_depth24 1
+#define GL_DEPTH_COMPONENT24_OES          0x81A6
+#endif /* GL_OES_depth24 */
+
+#ifndef GL_OES_depth32
+#define GL_OES_depth32 1
+#define GL_DEPTH_COMPONENT32_OES          0x81A7
+#endif /* GL_OES_depth32 */
+
+#ifndef GL_OES_depth_texture
+#define GL_OES_depth_texture 1
+#endif /* GL_OES_depth_texture */
+
+#ifndef GL_OES_depth_texture_cube_map
+#define GL_OES_depth_texture_cube_map 1
+#endif /* GL_OES_depth_texture */
+
+#ifndef GL_OES_element_index_uint
+#define GL_OES_element_index_uint 1
+#endif /* GL_OES_element_index_uint */
+
+#ifndef GL_OES_fbo_render_mipmap
+#define GL_OES_fbo_render_mipmap 1
+#endif /* GL_OES_fbo_render_mipmap */
+
+#ifndef GL_OES_fragment_precision_high
+#define GL_OES_fragment_precision_high 1
+#endif /* GL_OES_fragment_precision_high */
+
+#ifndef GL_OES_get_program_binary
+#define GL_OES_get_program_binary 1
+#define GL_PROGRAM_BINARY_LENGTH_OES      0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS_OES     0x87FF
+#endif /* GL_OES_get_program_binary */
+
+#ifndef GL_OES_mapbuffer
+#define GL_OES_mapbuffer 1
+#define GL_WRITE_ONLY_OES                 0x88B9
+#define GL_BUFFER_ACCESS_OES              0x88BB
+#define GL_BUFFER_MAPPED_OES              0x88BC
+#define GL_BUFFER_MAP_POINTER_OES         0x88BD
+#endif /* GL_OES_mapbuffer */
+
+#ifndef GL_OES_packed_depth_stencil
+#define GL_OES_packed_depth_stencil 1
+#define GL_DEPTH_STENCIL_OES              0x84F9
+#define GL_UNSIGNED_INT_24_8_OES          0x84FA
+#define GL_DEPTH24_STENCIL8_OES           0x88F0
+#endif /* GL_OES_packed_depth_stencil */
+
+#ifndef GL_OES_required_internalformat
+#define GL_OES_required_internalformat 1
+#define GL_ALPHA8_OES                     0x803C
+#define GL_DEPTH_COMPONENT16_OES          0x81A5
+#define GL_LUMINANCE4_ALPHA4_OES          0x8043
+#define GL_LUMINANCE8_ALPHA8_OES          0x8045
+#define GL_LUMINANCE8_OES                 0x8040
+#define GL_RGBA4_OES                      0x8056
+#define GL_RGB5_A1_OES                    0x8057
+#define GL_RGB565_OES                     0x8D62
+#define GL_RGB8_OES                       0x8051
+#define GL_RGBA8_OES                      0x8058
+#define GL_RGB10_EXT                      0x8052
+#define GL_RGB10_A2_EXT                   0x8059
+#endif /* GL_OES_required_internalformat */
+
+#ifndef GL_OES_rgb8_rgba8
+#define GL_OES_rgb8_rgba8 1
+#endif /* GL_OES_rgb8_rgba8 */
+
+#ifndef GL_OES_sample_shading
+#define GL_OES_sample_shading 1
+#define GL_SAMPLE_SHADING_OES             0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE_OES   0x8C37
+#endif /* GL_OES_sample_shading */
+
+#ifndef GL_OES_sample_variables
+#define GL_OES_sample_variables 1
+#endif /* GL_OES_sample_variables */
+
+#ifndef GL_OES_shader_image_atomic
+#define GL_OES_shader_image_atomic 1
+#endif /* GL_OES_shader_image_atomic */
+
+#ifndef GL_OES_shader_multisample_interpolation
+#define GL_OES_shader_multisample_interpolation 1
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5C
+#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES 0x8E5D
+#endif /* GL_OES_shader_multisample_interpolation */
+
+#ifndef GL_OES_standard_derivatives
+#define GL_OES_standard_derivatives 1
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B
+#endif /* GL_OES_standard_derivatives */
+
+#ifndef GL_OES_stencil1
+#define GL_OES_stencil1 1
+#define GL_STENCIL_INDEX1_OES             0x8D46
+#endif /* GL_OES_stencil1 */
+
+#ifndef GL_OES_stencil4
+#define GL_OES_stencil4 1
+#define GL_STENCIL_INDEX4_OES             0x8D47
+#endif /* GL_OES_stencil4 */
+
+#ifndef GL_OES_surfaceless_context
+#define GL_OES_surfaceless_context 1
+#define GL_FRAMEBUFFER_UNDEFINED_OES      0x8219
+#endif /* GL_OES_surfaceless_context */
+
+#ifndef GL_OES_texture_3D
+#define GL_OES_texture_3D 1
+#define GL_TEXTURE_WRAP_R_OES             0x8072
+#define GL_TEXTURE_3D_OES                 0x806F
+#define GL_TEXTURE_BINDING_3D_OES         0x806A
+#define GL_MAX_3D_TEXTURE_SIZE_OES        0x8073
+#define GL_SAMPLER_3D_OES                 0x8B5F
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4
+#endif /* GL_OES_texture_3D */
+
+#ifndef GL_OES_texture_compression_astc
+#define GL_OES_texture_compression_astc 1
+#define GL_COMPRESSED_RGBA_ASTC_3x3x3_OES 0x93C0
+#define GL_COMPRESSED_RGBA_ASTC_4x3x3_OES 0x93C1
+#define GL_COMPRESSED_RGBA_ASTC_4x4x3_OES 0x93C2
+#define GL_COMPRESSED_RGBA_ASTC_4x4x4_OES 0x93C3
+#define GL_COMPRESSED_RGBA_ASTC_5x4x4_OES 0x93C4
+#define GL_COMPRESSED_RGBA_ASTC_5x5x4_OES 0x93C5
+#define GL_COMPRESSED_RGBA_ASTC_5x5x5_OES 0x93C6
+#define GL_COMPRESSED_RGBA_ASTC_6x5x5_OES 0x93C7
+#define GL_COMPRESSED_RGBA_ASTC_6x6x5_OES 0x93C8
+#define GL_COMPRESSED_RGBA_ASTC_6x6x6_OES 0x93C9
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES 0x93E0
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES 0x93E1
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES 0x93E2
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES 0x93E3
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES 0x93E4
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES 0x93E5
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES 0x93E6
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES 0x93E7
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES 0x93E8
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 0x93E9
+#endif /* GL_OES_texture_compression_astc */
+
+#ifndef GL_OES_texture_float
+#define GL_OES_texture_float 1
+#endif /* GL_OES_texture_float */
+
+#ifndef GL_OES_texture_float_linear
+#define GL_OES_texture_float_linear 1
+#endif /* GL_OES_texture_float_linear */
+
+#ifndef GL_OES_texture_half_float
+#define GL_OES_texture_half_float 1
+#define GL_HALF_FLOAT_OES                 0x8D61
+#endif /* GL_OES_texture_half_float */
+
+#ifndef GL_OES_texture_half_float_linear
+#define GL_OES_texture_half_float_linear 1
+#endif /* GL_OES_texture_half_float_linear */
+
+#ifndef GL_OES_texture_npot
+#define GL_OES_texture_npot 1
+#endif /* GL_OES_texture_npot */
+
+#ifndef GL_OES_texture_stencil8
+#define GL_OES_texture_stencil8 1
+#define GL_STENCIL_INDEX_OES              0x1901
+#define GL_STENCIL_INDEX8_OES             0x8D48
+#endif /* GL_OES_texture_stencil8 */
+
+#ifndef GL_OES_texture_storage_multisample_2d_array
+#define GL_OES_texture_storage_multisample_2d_array 1
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES 0x9102
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES 0x9105
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910B
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910C
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910D
+#endif /* GL_OES_texture_storage_multisample_2d_array */
+
+#ifndef GL_OES_vertex_array_object
+#define GL_OES_vertex_array_object 1
+#define GL_VERTEX_ARRAY_BINDING_OES       0x85B5
+#endif /* GL_OES_vertex_array_object */
+
+#ifndef GL_OES_vertex_half_float
+#define GL_OES_vertex_half_float 1
+#endif /* GL_OES_vertex_half_float */
+
+#ifndef GL_OES_vertex_type_10_10_10_2
+#define GL_OES_vertex_type_10_10_10_2 1
+#define GL_UNSIGNED_INT_10_10_10_2_OES    0x8DF6
+#define GL_INT_10_10_10_2_OES             0x8DF7
+#endif /* GL_OES_vertex_type_10_10_10_2 */
+
+#ifndef GL_AMD_compressed_3DC_texture
+#define GL_AMD_compressed_3DC_texture 1
+#define GL_3DC_X_AMD                      0x87F9
+#define GL_3DC_XY_AMD                     0x87FA
+#endif /* GL_AMD_compressed_3DC_texture */
+
+#ifndef GL_AMD_compressed_ATC_texture
+#define GL_AMD_compressed_ATC_texture 1
+#define GL_ATC_RGB_AMD                    0x8C92
+#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD    0x8C93
+#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE
+#endif /* GL_AMD_compressed_ATC_texture */
+
+#ifndef GL_AMD_performance_monitor
+#define GL_AMD_performance_monitor 1
+#define GL_COUNTER_TYPE_AMD               0x8BC0
+#define GL_COUNTER_RANGE_AMD              0x8BC1
+#define GL_UNSIGNED_INT64_AMD             0x8BC2
+#define GL_PERCENTAGE_AMD                 0x8BC3
+#define GL_PERFMON_RESULT_AVAILABLE_AMD   0x8BC4
+#define GL_PERFMON_RESULT_SIZE_AMD        0x8BC5
+#define GL_PERFMON_RESULT_AMD             0x8BC6
+#endif /* GL_AMD_performance_monitor */
+
+#ifndef GL_AMD_program_binary_Z400
+#define GL_AMD_program_binary_Z400 1
+#define GL_Z400_BINARY_AMD                0x8740
+#endif /* GL_AMD_program_binary_Z400 */
+
+#ifndef GL_ANGLE_depth_texture
+#define GL_ANGLE_depth_texture 1
+#endif /* GL_ANGLE_depth_texture */
+
+#ifndef GL_ANGLE_framebuffer_blit
+#define GL_ANGLE_framebuffer_blit 1
+#define GL_READ_FRAMEBUFFER_ANGLE         0x8CA8
+#define GL_DRAW_FRAMEBUFFER_ANGLE         0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA
+#endif /* GL_ANGLE_framebuffer_blit */
+
+#ifndef GL_ANGLE_framebuffer_multisample
+#define GL_ANGLE_framebuffer_multisample 1
+#define GL_RENDERBUFFER_SAMPLES_ANGLE     0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56
+#define GL_MAX_SAMPLES_ANGLE              0x8D57
+#endif /* GL_ANGLE_framebuffer_multisample */
+
+#ifndef GL_ANGLE_instanced_arrays
+#define GL_ANGLE_instanced_arrays 1
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE
+#endif /* GL_ANGLE_instanced_arrays */
+
+#ifndef GL_ANGLE_pack_reverse_row_order
+#define GL_ANGLE_pack_reverse_row_order 1
+#define GL_PACK_REVERSE_ROW_ORDER_ANGLE   0x93A4
+#endif /* GL_ANGLE_pack_reverse_row_order */
+
+#ifndef GL_ANGLE_program_binary
+#define GL_ANGLE_program_binary 1
+#define GL_PROGRAM_BINARY_ANGLE           0x93A6
+#endif /* GL_ANGLE_program_binary */
+
+#ifndef GL_ANGLE_texture_compression_dxt3
+#define GL_ANGLE_texture_compression_dxt3 1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2
+#endif /* GL_ANGLE_texture_compression_dxt3 */
+
+#ifndef GL_ANGLE_texture_compression_dxt5
+#define GL_ANGLE_texture_compression_dxt5 1
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3
+#endif /* GL_ANGLE_texture_compression_dxt5 */
+
+#ifndef GL_ANGLE_texture_usage
+#define GL_ANGLE_texture_usage 1
+#define GL_TEXTURE_USAGE_ANGLE            0x93A2
+#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE   0x93A3
+#endif /* GL_ANGLE_texture_usage */
+
+#ifndef GL_ANGLE_translated_shader_source
+#define GL_ANGLE_translated_shader_source 1
+#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0
+#endif /* GL_ANGLE_translated_shader_source */
+
+#ifndef GL_APPLE_copy_texture_levels
+#define GL_APPLE_copy_texture_levels 1
+#endif /* GL_APPLE_copy_texture_levels */
+
+#ifndef GL_APPLE_framebuffer_multisample
+#define GL_APPLE_framebuffer_multisample 1
+#define GL_RENDERBUFFER_SAMPLES_APPLE     0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56
+#define GL_MAX_SAMPLES_APPLE              0x8D57
+#define GL_READ_FRAMEBUFFER_APPLE         0x8CA8
+#define GL_DRAW_FRAMEBUFFER_APPLE         0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA
+#endif /* GL_APPLE_framebuffer_multisample */
+
+#ifndef GL_APPLE_rgb_422
+#define GL_APPLE_rgb_422 1
+#define GL_RGB_422_APPLE                  0x8A1F
+#define GL_UNSIGNED_SHORT_8_8_APPLE       0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_APPLE   0x85BB
+#define GL_RGB_RAW_422_APPLE              0x8A51
+#endif /* GL_APPLE_rgb_422 */
+
+#ifndef GL_APPLE_sync
+#define GL_APPLE_sync 1
+#define GL_SYNC_OBJECT_APPLE              0x8A53
+#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE  0x9111
+#define GL_OBJECT_TYPE_APPLE              0x9112
+#define GL_SYNC_CONDITION_APPLE           0x9113
+#define GL_SYNC_STATUS_APPLE              0x9114
+#define GL_SYNC_FLAGS_APPLE               0x9115
+#define GL_SYNC_FENCE_APPLE               0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117
+#define GL_UNSIGNALED_APPLE               0x9118
+#define GL_SIGNALED_APPLE                 0x9119
+#define GL_ALREADY_SIGNALED_APPLE         0x911A
+#define GL_TIMEOUT_EXPIRED_APPLE          0x911B
+#define GL_CONDITION_SATISFIED_APPLE      0x911C
+#define GL_WAIT_FAILED_APPLE              0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE  0x00000001
+#define GL_TIMEOUT_IGNORED_APPLE          0xFFFFFFFFFFFFFFFFull
+#endif /* GL_APPLE_sync */
+
+#ifndef GL_APPLE_texture_format_BGRA8888
+#define GL_APPLE_texture_format_BGRA8888 1
+#define GL_BGRA_EXT                       0x80E1
+#define GL_BGRA8_EXT                      0x93A1
+#endif /* GL_APPLE_texture_format_BGRA8888 */
+
+#ifndef GL_APPLE_texture_max_level
+#define GL_APPLE_texture_max_level 1
+#define GL_TEXTURE_MAX_LEVEL_APPLE        0x813D
+#endif /* GL_APPLE_texture_max_level */
+
+#ifndef GL_ARM_mali_program_binary
+#define GL_ARM_mali_program_binary 1
+#define GL_MALI_PROGRAM_BINARY_ARM        0x8F61
+#endif /* GL_ARM_mali_program_binary */
+
+#ifndef GL_ARM_mali_shader_binary
+#define GL_ARM_mali_shader_binary 1
+#define GL_MALI_SHADER_BINARY_ARM         0x8F60
+#endif /* GL_ARM_mali_shader_binary */
+
+#ifndef GL_ARM_rgba8
+#define GL_ARM_rgba8 1
+#endif /* GL_ARM_rgba8 */
+
+#ifndef GL_ARM_shader_framebuffer_fetch
+#define GL_ARM_shader_framebuffer_fetch 1
+#define GL_FETCH_PER_SAMPLE_ARM           0x8F65
+#define GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM 0x8F66
+#endif /* GL_ARM_shader_framebuffer_fetch */
+
+#ifndef GL_ARM_shader_framebuffer_fetch_depth_stencil
+#define GL_ARM_shader_framebuffer_fetch_depth_stencil 1
+#endif /* GL_ARM_shader_framebuffer_fetch_depth_stencil */
+
+#ifndef GL_DMP_shader_binary
+#define GL_DMP_shader_binary 1
+#define GL_SHADER_BINARY_DMP              0x9250
+#endif /* GL_DMP_shader_binary */
+
+#ifndef GL_EXT_blend_minmax
+#define GL_EXT_blend_minmax 1
+#define GL_MIN_EXT                        0x8007
+#define GL_MAX_EXT                        0x8008
+#endif /* GL_EXT_blend_minmax */
+
+//indeed,this requires gles3.0. But some drivers support this in gles2.0
+#ifndef GL_EXT_color_buffer_float
+#define GL_EXT_color_buffer_float 1
+#endif /* GL_EXT_color_buffer_float */
+
+#ifndef GL_EXT_color_buffer_half_float
+#define GL_EXT_color_buffer_half_float 1
+#define GL_RGBA16F_EXT                    0x881A
+#define GL_RGB16F_EXT                     0x881B
+#define GL_RG16F_EXT                      0x822F
+#define GL_R16F_EXT                       0x822D
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211
+#define GL_UNSIGNED_NORMALIZED_EXT        0x8C17
+#endif /* GL_EXT_color_buffer_half_float */
+
+#ifndef GL_EXT_debug_label
+#define GL_EXT_debug_label 1
+#define GL_PROGRAM_PIPELINE_OBJECT_EXT    0x8A4F
+#define GL_PROGRAM_OBJECT_EXT             0x8B40
+#define GL_SHADER_OBJECT_EXT              0x8B48
+#define GL_BUFFER_OBJECT_EXT              0x9151
+#define GL_QUERY_OBJECT_EXT               0x9153
+#define GL_VERTEX_ARRAY_OBJECT_EXT        0x9154
+#define GL_TRANSFORM_FEEDBACK             0x8E22
+#endif /* GL_EXT_debug_label */
+
+#ifndef GL_EXT_debug_marker
+#define GL_EXT_debug_marker 1
+#endif /* GL_EXT_debug_marker */
+
+#ifndef GL_EXT_discard_framebuffer
+#define GL_EXT_discard_framebuffer 1
+#define GL_COLOR_EXT                      0x1800
+#define GL_DEPTH_EXT                      0x1801
+#define GL_STENCIL_EXT                    0x1802
+#endif /* GL_EXT_discard_framebuffer */
+
+#ifndef GL_EXT_disjoint_timer_query
+#define GL_EXT_disjoint_timer_query 1
+#define GL_QUERY_COUNTER_BITS_EXT         0x8864
+#define GL_CURRENT_QUERY_EXT              0x8865
+#define GL_QUERY_RESULT_EXT               0x8866
+#define GL_QUERY_RESULT_AVAILABLE_EXT     0x8867
+#define GL_TIME_ELAPSED_EXT               0x88BF
+#define GL_TIMESTAMP_EXT                  0x8E28
+#define GL_GPU_DISJOINT_EXT               0x8FBB
+#endif /* GL_EXT_disjoint_timer_query */
+
+#ifndef GL_EXT_draw_buffers
+#define GL_EXT_draw_buffers 1
+#define GL_MAX_COLOR_ATTACHMENTS_EXT      0x8CDF
+#define GL_MAX_DRAW_BUFFERS_EXT           0x8824
+#define GL_DRAW_BUFFER0_EXT               0x8825
+#define GL_DRAW_BUFFER1_EXT               0x8826
+#define GL_DRAW_BUFFER2_EXT               0x8827
+#define GL_DRAW_BUFFER3_EXT               0x8828
+#define GL_DRAW_BUFFER4_EXT               0x8829
+#define GL_DRAW_BUFFER5_EXT               0x882A
+#define GL_DRAW_BUFFER6_EXT               0x882B
+#define GL_DRAW_BUFFER7_EXT               0x882C
+#define GL_DRAW_BUFFER8_EXT               0x882D
+#define GL_DRAW_BUFFER9_EXT               0x882E
+#define GL_DRAW_BUFFER10_EXT              0x882F
+#define GL_DRAW_BUFFER11_EXT              0x8830
+#define GL_DRAW_BUFFER12_EXT              0x8831
+#define GL_DRAW_BUFFER13_EXT              0x8832
+#define GL_DRAW_BUFFER14_EXT              0x8833
+#define GL_DRAW_BUFFER15_EXT              0x8834
+#define GL_COLOR_ATTACHMENT0_EXT          0x8CE0
+#define GL_COLOR_ATTACHMENT1_EXT          0x8CE1
+#define GL_COLOR_ATTACHMENT2_EXT          0x8CE2
+#define GL_COLOR_ATTACHMENT3_EXT          0x8CE3
+#define GL_COLOR_ATTACHMENT4_EXT          0x8CE4
+#define GL_COLOR_ATTACHMENT5_EXT          0x8CE5
+#define GL_COLOR_ATTACHMENT6_EXT          0x8CE6
+#define GL_COLOR_ATTACHMENT7_EXT          0x8CE7
+#define GL_COLOR_ATTACHMENT8_EXT          0x8CE8
+#define GL_COLOR_ATTACHMENT9_EXT          0x8CE9
+#define GL_COLOR_ATTACHMENT10_EXT         0x8CEA
+#define GL_COLOR_ATTACHMENT11_EXT         0x8CEB
+#define GL_COLOR_ATTACHMENT12_EXT         0x8CEC
+#define GL_COLOR_ATTACHMENT13_EXT         0x8CED
+#define GL_COLOR_ATTACHMENT14_EXT         0x8CEE
+#define GL_COLOR_ATTACHMENT15_EXT         0x8CEF
+#endif /* GL_EXT_draw_buffers */
+
+#ifndef GL_EXT_draw_instanced
+#define GL_EXT_draw_instanced 1
+#endif /* GL_EXT_draw_instanced */
+
+#ifndef GL_EXT_instanced_arrays
+#define GL_EXT_instanced_arrays 1
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 0x88FE
+#endif /* GL_EXT_instanced_arrays */
+
+#ifndef GL_EXT_map_buffer_range
+#define GL_EXT_map_buffer_range 1
+#define GL_MAP_READ_BIT_EXT               0x0001
+#define GL_MAP_WRITE_BIT_EXT              0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT_EXT   0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT  0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT     0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT_EXT     0x0020
+#endif /* GL_EXT_map_buffer_range */
+
+#ifndef GL_EXT_multi_draw_arrays
+#define GL_EXT_multi_draw_arrays 1
+#endif /* GL_EXT_multi_draw_arrays */
+
+#ifndef GL_EXT_multisampled_render_to_texture
+#define GL_EXT_multisampled_render_to_texture 1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C
+#define GL_RENDERBUFFER_SAMPLES_EXT       0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define GL_MAX_SAMPLES_EXT                0x8D57
+#endif /* GL_EXT_multisampled_render_to_texture */
+
+#ifndef GL_EXT_multiview_draw_buffers
+#define GL_EXT_multiview_draw_buffers 1
+#define GL_COLOR_ATTACHMENT_EXT           0x90F0
+#define GL_MULTIVIEW_EXT                  0x90F1
+#define GL_DRAW_BUFFER_EXT                0x0C01
+#define GL_READ_BUFFER_EXT                0x0C02
+#define GL_MAX_MULTIVIEW_BUFFERS_EXT      0x90F2
+#endif /* GL_EXT_multiview_draw_buffers */
+
+#ifndef GL_EXT_occlusion_query_boolean
+#define GL_EXT_occlusion_query_boolean 1
+#define GL_ANY_SAMPLES_PASSED_EXT         0x8C2F
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A
+#endif /* GL_EXT_occlusion_query_boolean */
+
+#ifndef GL_EXT_pvrtc_sRGB
+#define GL_EXT_pvrtc_sRGB 1
+#define GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54
+#define GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55
+#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56
+#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57
+#endif /* GL_EXT_pvrtc_sRGB */
+
+#ifndef GL_EXT_read_format_bgra
+#define GL_EXT_read_format_bgra 1
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366
+#endif /* GL_EXT_read_format_bgra */
+
+#ifndef GL_EXT_robustness
+#define GL_EXT_robustness 1
+#define GL_GUILTY_CONTEXT_RESET_EXT       0x8253
+#define GL_INNOCENT_CONTEXT_RESET_EXT     0x8254
+#define GL_UNKNOWN_CONTEXT_RESET_EXT      0x8255
+#define GL_CONTEXT_ROBUST_ACCESS_EXT      0x90F3
+#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256
+#define GL_LOSE_CONTEXT_ON_RESET_EXT      0x8252
+#define GL_NO_RESET_NOTIFICATION_EXT      0x8261
+#endif /* GL_EXT_robustness */
+
+#ifndef GL_EXT_sRGB
+#define GL_EXT_sRGB 1
+#define GL_SRGB_EXT                       0x8C40
+#define GL_SRGB_ALPHA_EXT                 0x8C42
+#define GL_SRGB8_ALPHA8_EXT               0x8C43
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210
+#endif /* GL_EXT_sRGB */
+
+#ifndef GL_EXT_sRGB_write_control
+#define GL_EXT_sRGB_write_control 1
+#define GL_FRAMEBUFFER_SRGB_EXT           0x8DB9
+#endif /* GL_EXT_sRGB_write_control */
+
+#ifndef GL_EXT_separate_shader_objects
+#define GL_EXT_separate_shader_objects 1
+#define GL_ACTIVE_PROGRAM_EXT             0x8259
+#define GL_VERTEX_SHADER_BIT_EXT          0x00000001
+#define GL_FRAGMENT_SHADER_BIT_EXT        0x00000002
+#define GL_ALL_SHADER_BITS_EXT            0xFFFFFFFF
+#define GL_PROGRAM_SEPARABLE_EXT          0x8258
+#define GL_PROGRAM_PIPELINE_BINDING_EXT   0x825A
+#endif /* GL_EXT_separate_shader_objects */
+
+#ifndef GL_EXT_shader_framebuffer_fetch
+#define GL_EXT_shader_framebuffer_fetch 1
+#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52
+#endif /* GL_EXT_shader_framebuffer_fetch */
+
+#ifndef GL_EXT_shader_integer_mix
+#define GL_EXT_shader_integer_mix 1
+#endif /* GL_EXT_shader_integer_mix */
+
+#ifndef GL_EXT_shader_pixel_local_storage
+#define GL_EXT_shader_pixel_local_storage 1
+#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63
+#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT 0x8F67
+#define GL_SHADER_PIXEL_LOCAL_STORAGE_EXT 0x8F64
+#endif /* GL_EXT_shader_pixel_local_storage */
+
+#ifndef GL_EXT_shader_texture_lod
+#define GL_EXT_shader_texture_lod 1
+#endif /* GL_EXT_shader_texture_lod */
+
+#ifndef GL_EXT_shadow_samplers
+#define GL_EXT_shadow_samplers 1
+#define GL_TEXTURE_COMPARE_MODE_EXT       0x884C
+#define GL_TEXTURE_COMPARE_FUNC_EXT       0x884D
+#define GL_COMPARE_REF_TO_TEXTURE_EXT     0x884E
+#define GL_SAMPLER_2D_SHADOW_EXT          0x8B62
+#endif /* GL_EXT_shadow_samplers */
+
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_EXT_texture_compression_dxt1 1
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT   0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT  0x83F1
+#endif /* GL_EXT_texture_compression_dxt1 */
+
+#ifndef GL_EXT_texture_compression_s3tc
+#define GL_EXT_texture_compression_s3tc 1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT  0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT  0x83F3
+#endif /* GL_EXT_texture_compression_s3tc */
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_EXT_texture_filter_anisotropic 1
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT     0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+#endif /* GL_EXT_texture_filter_anisotropic */
+
+#ifndef GL_EXT_texture_format_BGRA8888
+#define GL_EXT_texture_format_BGRA8888 1
+#endif /* GL_EXT_texture_format_BGRA8888 */
+
+#ifndef GL_EXT_texture_rg
+#define GL_EXT_texture_rg 1
+#define GL_RED_EXT                        0x1903
+#define GL_RG_EXT                         0x8227
+#define GL_R8_EXT                         0x8229
+#define GL_RG8_EXT                        0x822B
+#endif /* GL_EXT_texture_rg */
+
+#ifndef GL_EXT_texture_sRGB_decode
+#define GL_EXT_texture_sRGB_decode 1
+#define GL_TEXTURE_SRGB_DECODE_EXT        0x8A48
+#define GL_DECODE_EXT                     0x8A49
+#define GL_SKIP_DECODE_EXT                0x8A4A
+#endif /* GL_EXT_texture_sRGB_decode */
+
+#ifndef GL_EXT_texture_storage
+#define GL_EXT_texture_storage 1
+#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT   0x912F
+#define GL_ALPHA8_EXT                     0x803C
+#define GL_LUMINANCE8_EXT                 0x8040
+#define GL_LUMINANCE8_ALPHA8_EXT          0x8045
+#define GL_RGBA32F_EXT                    0x8814
+#define GL_RGB32F_EXT                     0x8815
+#define GL_ALPHA32F_EXT                   0x8816
+#define GL_LUMINANCE32F_EXT               0x8818
+#define GL_LUMINANCE_ALPHA32F_EXT         0x8819
+#define GL_ALPHA16F_EXT                   0x881C
+#define GL_LUMINANCE16F_EXT               0x881E
+#define GL_LUMINANCE_ALPHA16F_EXT         0x881F
+#define GL_R32F_EXT                       0x822E
+#define GL_RG32F_EXT                      0x8230
+#endif /* GL_EXT_texture_storage */
+
+#ifndef GL_EXT_texture_type_2_10_10_10_REV
+#define GL_EXT_texture_type_2_10_10_10_REV 1
+#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368
+#endif /* GL_EXT_texture_type_2_10_10_10_REV */
+
+#ifndef GL_EXT_unpack_subimage
+#define GL_EXT_unpack_subimage 1
+#define GL_UNPACK_ROW_LENGTH_EXT          0x0CF2
+#define GL_UNPACK_SKIP_ROWS_EXT           0x0CF3
+#define GL_UNPACK_SKIP_PIXELS_EXT         0x0CF4
+#endif /* GL_EXT_unpack_subimage */
+
+#ifndef GL_FJ_shader_binary_GCCSO
+#define GL_FJ_shader_binary_GCCSO 1
+#define GL_GCCSO_SHADER_BINARY_FJ         0x9260
+#endif /* GL_FJ_shader_binary_GCCSO */
+
+#ifndef GL_IMG_multisampled_render_to_texture
+#define GL_IMG_multisampled_render_to_texture 1
+#define GL_RENDERBUFFER_SAMPLES_IMG       0x9133
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134
+#define GL_MAX_SAMPLES_IMG                0x9135
+#define GL_TEXTURE_SAMPLES_IMG            0x9136
+#endif /* GL_IMG_multisampled_render_to_texture */
+
+#ifndef GL_IMG_program_binary
+#define GL_IMG_program_binary 1
+#define GL_SGX_PROGRAM_BINARY_IMG         0x9130
+#endif /* GL_IMG_program_binary */
+
+#ifndef GL_IMG_read_format
+#define GL_IMG_read_format 1
+#define GL_BGRA_IMG                       0x80E1
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365
+#endif /* GL_IMG_read_format */
+
+#ifndef GL_IMG_shader_binary
+#define GL_IMG_shader_binary 1
+#define GL_SGX_BINARY_IMG                 0x8C0A
+#endif /* GL_IMG_shader_binary */
+
+#ifndef GL_IMG_texture_compression_pvrtc
+#define GL_IMG_texture_compression_pvrtc 1
+#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
+#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01
+#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
+#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03
+#endif /* GL_IMG_texture_compression_pvrtc */
+
+#ifndef GL_IMG_texture_compression_pvrtc2
+#define GL_IMG_texture_compression_pvrtc2 1
+#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137
+#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138
+#endif /* GL_IMG_texture_compression_pvrtc2 */
+
+#ifndef GL_INTEL_performance_query
+#define GL_INTEL_performance_query 1
+#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000
+#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x00000001
+#define GL_PERFQUERY_WAIT_INTEL           0x83FB
+#define GL_PERFQUERY_FLUSH_INTEL          0x83FA
+#define GL_PERFQUERY_DONOT_FLUSH_INTEL    0x83F9
+#define GL_PERFQUERY_COUNTER_EVENT_INTEL  0x94F0
+#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1
+#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2
+#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3
+#define GL_PERFQUERY_COUNTER_RAW_INTEL    0x94F4
+#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5
+#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8
+#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9
+#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA
+#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB
+#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC
+#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD
+#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE
+#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF
+#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500
+#endif /* GL_INTEL_performance_query */
+
+#ifndef GL_NV_blend_equation_advanced
+#define GL_NV_blend_equation_advanced 1
+#define GL_BLEND_OVERLAP_NV               0x9281
+#define GL_BLEND_PREMULTIPLIED_SRC_NV     0x9280
+#define GL_BLUE_NV                        0x1905
+#define GL_COLORBURN_NV                   0x929A
+#define GL_COLORDODGE_NV                  0x9299
+#define GL_CONJOINT_NV                    0x9284
+#define GL_CONTRAST_NV                    0x92A1
+#define GL_DARKEN_NV                      0x9297
+#define GL_DIFFERENCE_NV                  0x929E
+#define GL_DISJOINT_NV                    0x9283
+#define GL_DST_ATOP_NV                    0x928F
+#define GL_DST_IN_NV                      0x928B
+#define GL_DST_NV                         0x9287
+#define GL_DST_OUT_NV                     0x928D
+#define GL_DST_OVER_NV                    0x9289
+#define GL_EXCLUSION_NV                   0x92A0
+#define GL_GREEN_NV                       0x1904
+#define GL_HARDLIGHT_NV                   0x929B
+#define GL_HARDMIX_NV                     0x92A9
+#define GL_HSL_COLOR_NV                   0x92AF
+#define GL_HSL_HUE_NV                     0x92AD
+#define GL_HSL_LUMINOSITY_NV              0x92B0
+#define GL_HSL_SATURATION_NV              0x92AE
+#define GL_INVERT_OVG_NV                  0x92B4
+#define GL_INVERT_RGB_NV                  0x92A3
+#define GL_LIGHTEN_NV                     0x9298
+#define GL_LINEARBURN_NV                  0x92A5
+#define GL_LINEARDODGE_NV                 0x92A4
+#define GL_LINEARLIGHT_NV                 0x92A7
+#define GL_MINUS_CLAMPED_NV               0x92B3
+#define GL_MINUS_NV                       0x929F
+#define GL_MULTIPLY_NV                    0x9294
+#define GL_OVERLAY_NV                     0x9296
+#define GL_PINLIGHT_NV                    0x92A8
+#define GL_PLUS_CLAMPED_ALPHA_NV          0x92B2
+#define GL_PLUS_CLAMPED_NV                0x92B1
+#define GL_PLUS_DARKER_NV                 0x9292
+#define GL_PLUS_NV                        0x9291
+#define GL_RED_NV                         0x1903
+#define GL_SCREEN_NV                      0x9295
+#define GL_SOFTLIGHT_NV                   0x929C
+#define GL_SRC_ATOP_NV                    0x928E
+#define GL_SRC_IN_NV                      0x928A
+#define GL_SRC_NV                         0x9286
+#define GL_SRC_OUT_NV                     0x928C
+#define GL_SRC_OVER_NV                    0x9288
+#define GL_UNCORRELATED_NV                0x9282
+#define GL_VIVIDLIGHT_NV                  0x92A6
+#define GL_XOR_NV                         0x1506
+#endif /* GL_NV_blend_equation_advanced */
+
+#ifndef GL_NV_blend_equation_advanced_coherent
+#define GL_NV_blend_equation_advanced_coherent 1
+#define GL_BLEND_ADVANCED_COHERENT_NV     0x9285
+#endif /* GL_NV_blend_equation_advanced_coherent */
+
+#ifndef GL_NV_copy_buffer
+#define GL_NV_copy_buffer 1
+#define GL_COPY_READ_BUFFER_NV            0x8F36
+#define GL_COPY_WRITE_BUFFER_NV           0x8F37
+#endif /* GL_NV_copy_buffer */
+
+#ifndef GL_NV_coverage_sample
+#define GL_NV_coverage_sample 1
+#define GL_COVERAGE_COMPONENT_NV          0x8ED0
+#define GL_COVERAGE_COMPONENT4_NV         0x8ED1
+#define GL_COVERAGE_ATTACHMENT_NV         0x8ED2
+#define GL_COVERAGE_BUFFERS_NV            0x8ED3
+#define GL_COVERAGE_SAMPLES_NV            0x8ED4
+#define GL_COVERAGE_ALL_FRAGMENTS_NV      0x8ED5
+#define GL_COVERAGE_EDGE_FRAGMENTS_NV     0x8ED6
+#define GL_COVERAGE_AUTOMATIC_NV          0x8ED7
+#define GL_COVERAGE_BUFFER_BIT_NV         0x00008000
+#endif /* GL_NV_coverage_sample */
+
+#ifndef GL_NV_depth_nonlinear
+#define GL_NV_depth_nonlinear 1
+#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C
+#endif /* GL_NV_depth_nonlinear */
+
+#ifndef GL_NV_draw_buffers
+#define GL_NV_draw_buffers 1
+#define GL_MAX_DRAW_BUFFERS_NV            0x8824
+#define GL_DRAW_BUFFER0_NV                0x8825
+#define GL_DRAW_BUFFER1_NV                0x8826
+#define GL_DRAW_BUFFER2_NV                0x8827
+#define GL_DRAW_BUFFER3_NV                0x8828
+#define GL_DRAW_BUFFER4_NV                0x8829
+#define GL_DRAW_BUFFER5_NV                0x882A
+#define GL_DRAW_BUFFER6_NV                0x882B
+#define GL_DRAW_BUFFER7_NV                0x882C
+#define GL_DRAW_BUFFER8_NV                0x882D
+#define GL_DRAW_BUFFER9_NV                0x882E
+#define GL_DRAW_BUFFER10_NV               0x882F
+#define GL_DRAW_BUFFER11_NV               0x8830
+#define GL_DRAW_BUFFER12_NV               0x8831
+#define GL_DRAW_BUFFER13_NV               0x8832
+#define GL_DRAW_BUFFER14_NV               0x8833
+#define GL_DRAW_BUFFER15_NV               0x8834
+#define GL_COLOR_ATTACHMENT0_NV           0x8CE0
+#define GL_COLOR_ATTACHMENT1_NV           0x8CE1
+#define GL_COLOR_ATTACHMENT2_NV           0x8CE2
+#define GL_COLOR_ATTACHMENT3_NV           0x8CE3
+#define GL_COLOR_ATTACHMENT4_NV           0x8CE4
+#define GL_COLOR_ATTACHMENT5_NV           0x8CE5
+#define GL_COLOR_ATTACHMENT6_NV           0x8CE6
+#define GL_COLOR_ATTACHMENT7_NV           0x8CE7
+#define GL_COLOR_ATTACHMENT8_NV           0x8CE8
+#define GL_COLOR_ATTACHMENT9_NV           0x8CE9
+#define GL_COLOR_ATTACHMENT10_NV          0x8CEA
+#define GL_COLOR_ATTACHMENT11_NV          0x8CEB
+#define GL_COLOR_ATTACHMENT12_NV          0x8CEC
+#define GL_COLOR_ATTACHMENT13_NV          0x8CED
+#define GL_COLOR_ATTACHMENT14_NV          0x8CEE
+#define GL_COLOR_ATTACHMENT15_NV          0x8CEF
+#endif /* GL_NV_draw_buffers */
+
+#ifndef GL_NV_draw_instanced
+#define GL_NV_draw_instanced 1
+#endif /* GL_NV_draw_instanced */
+
+#ifndef GL_NV_explicit_attrib_location
+#define GL_NV_explicit_attrib_location 1
+#endif /* GL_NV_explicit_attrib_location */
+
+#ifndef GL_NV_fbo_color_attachments
+#define GL_NV_fbo_color_attachments 1
+#define GL_MAX_COLOR_ATTACHMENTS_NV       0x8CDF
+#endif /* GL_NV_fbo_color_attachments */
+
+#ifndef GL_NV_fence
+#define GL_NV_fence 1
+#define GL_ALL_COMPLETED_NV               0x84F2
+#define GL_FENCE_STATUS_NV                0x84F3
+#define GL_FENCE_CONDITION_NV             0x84F4
+#endif /* GL_NV_fence */
+
+#ifndef GL_NV_framebuffer_blit
+#define GL_NV_framebuffer_blit 1
+#define GL_READ_FRAMEBUFFER_NV            0x8CA8
+#define GL_DRAW_FRAMEBUFFER_NV            0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_NV    0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_NV    0x8CAA
+#endif /* GL_NV_framebuffer_blit */
+
+#ifndef GL_NV_framebuffer_multisample
+#define GL_NV_framebuffer_multisample 1
+#define GL_RENDERBUFFER_SAMPLES_NV        0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56
+#define GL_MAX_SAMPLES_NV                 0x8D57
+#endif /* GL_NV_framebuffer_multisample */
+
+#ifndef GL_NV_generate_mipmap_sRGB
+#define GL_NV_generate_mipmap_sRGB 1
+#endif /* GL_NV_generate_mipmap_sRGB */
+
+#ifndef GL_NV_instanced_arrays
+#define GL_NV_instanced_arrays 1
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE
+#endif /* GL_NV_instanced_arrays */
+
+#ifndef GL_NV_non_square_matrices
+#define GL_NV_non_square_matrices 1
+#define GL_FLOAT_MAT2x3_NV                0x8B65
+#define GL_FLOAT_MAT2x4_NV                0x8B66
+#define GL_FLOAT_MAT3x2_NV                0x8B67
+#define GL_FLOAT_MAT3x4_NV                0x8B68
+#define GL_FLOAT_MAT4x2_NV                0x8B69
+#define GL_FLOAT_MAT4x3_NV                0x8B6A
+#endif /* GL_NV_non_square_matrices */
+
+#ifndef GL_NV_read_buffer
+#define GL_NV_read_buffer 1
+#define GL_READ_BUFFER_NV                 0x0C02
+#endif /* GL_NV_read_buffer */
+
+#ifndef GL_NV_read_buffer_front
+#define GL_NV_read_buffer_front 1
+#endif /* GL_NV_read_buffer_front */
+
+#ifndef GL_NV_read_depth
+#define GL_NV_read_depth 1
+#endif /* GL_NV_read_depth */
+
+#ifndef GL_NV_read_depth_stencil
+#define GL_NV_read_depth_stencil 1
+#endif /* GL_NV_read_depth_stencil */
+
+#ifndef GL_NV_read_stencil
+#define GL_NV_read_stencil 1
+#endif /* GL_NV_read_stencil */
+
+#ifndef GL_NV_sRGB_formats
+#define GL_NV_sRGB_formats 1
+#define GL_SLUMINANCE_NV                  0x8C46
+#define GL_SLUMINANCE_ALPHA_NV            0x8C44
+#define GL_SRGB8_NV                       0x8C41
+#define GL_SLUMINANCE8_NV                 0x8C47
+#define GL_SLUMINANCE8_ALPHA8_NV          0x8C45
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV   0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F
+#define GL_ETC1_SRGB8_NV                  0x88EE
+#endif /* GL_NV_sRGB_formats */
+
+#ifndef GL_NV_shadow_samplers_array
+#define GL_NV_shadow_samplers_array 1
+#define GL_SAMPLER_2D_ARRAY_SHADOW_NV     0x8DC4
+#endif /* GL_NV_shadow_samplers_array */
+
+#ifndef GL_NV_shadow_samplers_cube
+#define GL_NV_shadow_samplers_cube 1
+#define GL_SAMPLER_CUBE_SHADOW_NV         0x8DC5
+#endif /* GL_NV_shadow_samplers_cube */
+
+#ifndef GL_NV_texture_border_clamp
+#define GL_NV_texture_border_clamp 1
+#define GL_TEXTURE_BORDER_COLOR_NV        0x1004
+#define GL_CLAMP_TO_BORDER_NV             0x812D
+#endif /* GL_NV_texture_border_clamp */
+
+#ifndef GL_NV_texture_compression_s3tc_update
+#define GL_NV_texture_compression_s3tc_update 1
+#endif /* GL_NV_texture_compression_s3tc_update */
+
+#ifndef GL_NV_texture_npot_2D_mipmap
+#define GL_NV_texture_npot_2D_mipmap 1
+#endif /* GL_NV_texture_npot_2D_mipmap */
+
+#ifndef GL_QCOM_alpha_test
+#define GL_QCOM_alpha_test 1
+#define GL_ALPHA_TEST_QCOM                0x0BC0
+#define GL_ALPHA_TEST_FUNC_QCOM           0x0BC1
+#define GL_ALPHA_TEST_REF_QCOM            0x0BC2
+#endif /* GL_QCOM_alpha_test */
+
+#ifndef GL_QCOM_driver_control
+#define GL_QCOM_driver_control 1
+#endif /* GL_QCOM_driver_control */
+
+#ifndef GL_QCOM_extended_get
+#define GL_QCOM_extended_get 1
+#define GL_TEXTURE_WIDTH_QCOM             0x8BD2
+#define GL_TEXTURE_HEIGHT_QCOM            0x8BD3
+#define GL_TEXTURE_DEPTH_QCOM             0x8BD4
+#define GL_TEXTURE_INTERNAL_FORMAT_QCOM   0x8BD5
+#define GL_TEXTURE_FORMAT_QCOM            0x8BD6
+#define GL_TEXTURE_TYPE_QCOM              0x8BD7
+#define GL_TEXTURE_IMAGE_VALID_QCOM       0x8BD8
+#define GL_TEXTURE_NUM_LEVELS_QCOM        0x8BD9
+#define GL_TEXTURE_TARGET_QCOM            0x8BDA
+#define GL_TEXTURE_OBJECT_VALID_QCOM      0x8BDB
+#define GL_STATE_RESTORE                  0x8BDC
+#endif /* GL_QCOM_extended_get */
+
+#ifndef GL_QCOM_extended_get2
+#define GL_QCOM_extended_get2 1
+#endif /* GL_QCOM_extended_get2 */
+
+#ifndef GL_QCOM_perfmon_global_mode
+#define GL_QCOM_perfmon_global_mode 1
+#define GL_PERFMON_GLOBAL_MODE_QCOM       0x8FA0
+#endif /* GL_QCOM_perfmon_global_mode */
+
+#ifndef GL_QCOM_tiled_rendering
+#define GL_QCOM_tiled_rendering 1
+#define GL_COLOR_BUFFER_BIT0_QCOM         0x00000001
+#define GL_COLOR_BUFFER_BIT1_QCOM         0x00000002
+#define GL_COLOR_BUFFER_BIT2_QCOM         0x00000004
+#define GL_COLOR_BUFFER_BIT3_QCOM         0x00000008
+#define GL_COLOR_BUFFER_BIT4_QCOM         0x00000010
+#define GL_COLOR_BUFFER_BIT5_QCOM         0x00000020
+#define GL_COLOR_BUFFER_BIT6_QCOM         0x00000040
+#define GL_COLOR_BUFFER_BIT7_QCOM         0x00000080
+#define GL_DEPTH_BUFFER_BIT0_QCOM         0x00000100
+#define GL_DEPTH_BUFFER_BIT1_QCOM         0x00000200
+#define GL_DEPTH_BUFFER_BIT2_QCOM         0x00000400
+#define GL_DEPTH_BUFFER_BIT3_QCOM         0x00000800
+#define GL_DEPTH_BUFFER_BIT4_QCOM         0x00001000
+#define GL_DEPTH_BUFFER_BIT5_QCOM         0x00002000
+#define GL_DEPTH_BUFFER_BIT6_QCOM         0x00004000
+#define GL_DEPTH_BUFFER_BIT7_QCOM         0x00008000
+#define GL_STENCIL_BUFFER_BIT0_QCOM       0x00010000
+#define GL_STENCIL_BUFFER_BIT1_QCOM       0x00020000
+#define GL_STENCIL_BUFFER_BIT2_QCOM       0x00040000
+#define GL_STENCIL_BUFFER_BIT3_QCOM       0x00080000
+#define GL_STENCIL_BUFFER_BIT4_QCOM       0x00100000
+#define GL_STENCIL_BUFFER_BIT5_QCOM       0x00200000
+#define GL_STENCIL_BUFFER_BIT6_QCOM       0x00400000
+#define GL_STENCIL_BUFFER_BIT7_QCOM       0x00800000
+#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM   0x01000000
+#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM   0x02000000
+#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM   0x04000000
+#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM   0x08000000
+#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM   0x10000000
+#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM   0x20000000
+#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM   0x40000000
+#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM   0x80000000
+#endif /* GL_QCOM_tiled_rendering */
+
+#ifndef GL_QCOM_writeonly_rendering
+#define GL_QCOM_writeonly_rendering 1
+#define GL_WRITEONLY_RENDERING_QCOM       0x8823
+#endif /* GL_QCOM_writeonly_rendering */
+
+#ifndef GL_VIV_shader_binary
+#define GL_VIV_shader_binary 1
+#define GL_SHADER_BINARY_VIV              0x8FC4
+#endif /* GL_VIV_shader_binary */
 
-#if !defined(__glext_h_) && !defined(__gl2ext_h_)
-# define __glext_h_
-# define __gl2ext_h_
-
-//---------------------------//
-// GLES extension defines
-
-/* GL_OES_compressed_ETC1_RGB8_texture */
-#define GL_ETC1_RGB8_OES                                        0x8D64
-
-/* GL_OES_compressed_paletted_texture */
-#define GL_PALETTE4_RGB8_OES                                    0x8B90
-#define GL_PALETTE4_RGBA8_OES                                   0x8B91
-#define GL_PALETTE4_R5_G6_B5_OES                                0x8B92
-#define GL_PALETTE4_RGBA4_OES                                   0x8B93
-#define GL_PALETTE4_RGB5_A1_OES                                 0x8B94
-#define GL_PALETTE8_RGB8_OES                                    0x8B95
-#define GL_PALETTE8_RGBA8_OES                                   0x8B96
-#define GL_PALETTE8_R5_G6_B5_OES                                0x8B97
-#define GL_PALETTE8_RGBA4_OES                                   0x8B98
-#define GL_PALETTE8_RGB5_A1_OES                                 0x8B99
-
-/* GL_OES_depth24 */
-#define GL_DEPTH_COMPONENT24_OES                                0x81A6
-
-/* GL_OES_depth32 */
-#define GL_DEPTH_COMPONENT32_OES                                0x81A7
-
-/* GL_OES_get_program_binary */
-#define GL_PROGRAM_BINARY_LENGTH_OES                            0x8741
-#define GL_NUM_PROGRAM_BINARY_FORMATS_OES                       0x87FE
-#define GL_PROGRAM_BINARY_FORMATS_OES                           0x87FF
-
-/* GL_OES_mapbuffer */
-#define GL_WRITE_ONLY_OES                                       0x88B9
-#define GL_BUFFER_ACCESS_OES                                    0x88BB
-#define GL_BUFFER_MAPPED_OES                                    0x88BC
-#define GL_BUFFER_MAP_POINTER_OES                               0x88BD
-
-/* GL_OES_packed_depth_stencil */
-#define GL_DEPTH_STENCIL_OES                                    0x84F9
-#define GL_UNSIGNED_INT_24_8_OES                                0x84FA
-#define GL_DEPTH24_STENCIL8_OES                                 0x88F0
-
-/* GL_OES_rgb8_rgba8 */
-#define GL_RGB8_OES                                             0x8051
-#define GL_RGBA8_OES                                            0x8058
-
-/* GL_OES_standard_derivatives */
-#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES                  0x8B8B
-
-/* GL_OES_stencil1 */
-#define GL_STENCIL_INDEX1_OES                                   0x8D46
-
-/* GL_OES_stencil4 */
-#define GL_STENCIL_INDEX4_OES                                   0x8D47
-
-/* GL_OES_texture_3D */
-#define GL_TEXTURE_WRAP_R_OES                                   0x8072
-#define GL_TEXTURE_3D_OES                                       0x806F
-#define GL_TEXTURE_BINDING_3D_OES                               0x806A
-#define GL_MAX_3D_TEXTURE_SIZE_OES                              0x8073
-#define GL_SAMPLER_3D_OES                                       0x8B5F
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES        0x8CD4
+#else
+# ifndef EVAS_GL_NO_GL_H_CHECK
+#  error "You may only include either Evas_GL.h OR use your native GLES2 headers. If you use Evas to do GL, then you cannot use the native GLES2 headers."
+# endif
+#endif
 
-/* GL_OES_texture_float */
-/* No new tokens introduced by this extension. */
 
-/* GL_OES_texture_float_linear */
-/* No new tokens introduced by this extension. */
+/* OpenGLES 1.0 */
 
-/* GL_OES_texture_half_float */
-#define GL_HALF_FLOAT_OES                                       0x8D61
+#ifndef __gl_h_
+# define __gl_h_ 1
 
-/* GL_OES_texture_half_float_linear */
-/* No new tokens introduced by this extension. */
+/* Note: This should redefine a lot of the macros already defined above,
+ * but the compiler shouldn't raise any warning since the definitions are
+ * exactly the same.
+ */
 
-/* GL_OES_texture_npot */
-/* No new tokens introduced by this extension. */
+/* OpenGL ES core versions */
+#define GL_VERSION_ES_CM_1_0          1
+#define GL_VERSION_ES_CL_1_0          1
+#define GL_VERSION_ES_CM_1_1          1
+#define GL_VERSION_ES_CL_1_1          1
 
-/* GL_OES_vertex_half_float */
-/* GL_HALF_FLOAT_OES defined in GL_OES_texture_half_float already. */
+/* ClearBufferMask */
+#define GL_DEPTH_BUFFER_BIT               0x00000100
+#define GL_STENCIL_BUFFER_BIT             0x00000400
+#define GL_COLOR_BUFFER_BIT               0x00004000
 
-/* GL_OES_vertex_type_10_10_10_2 */
-#define GL_UNSIGNED_INT_10_10_10_2_OES                          0x8DF6
-#define GL_INT_10_10_10_2_OES                                   0x8DF7
+/* Boolean */
+#define GL_FALSE                          0
+#define GL_TRUE                           1
 
-/*------------------------------------------------------------------------*
- * AMD extension tokens
- *------------------------------------------------------------------------*/
+/* BeginMode */
+#define GL_POINTS                         0x0000
+#define GL_LINES                          0x0001
+#define GL_LINE_LOOP                      0x0002
+#define GL_LINE_STRIP                     0x0003
+#define GL_TRIANGLES                      0x0004
+#define GL_TRIANGLE_STRIP                 0x0005
+#define GL_TRIANGLE_FAN                   0x0006
 
-/* GL_AMD_compressed_3DC_texture */
-#define GL_3DC_X_AMD                                            0x87F9
-#define GL_3DC_XY_AMD                                           0x87FA
+/* AlphaFunction */
+#define GL_NEVER                          0x0200
+#define GL_LESS                           0x0201
+#define GL_EQUAL                          0x0202
+#define GL_LEQUAL                         0x0203
+#define GL_GREATER                        0x0204
+#define GL_NOTEQUAL                       0x0205
+#define GL_GEQUAL                         0x0206
+#define GL_ALWAYS                         0x0207
 
-/* GL_AMD_compressed_ATC_texture */
-#define GL_ATC_RGB_AMD                                          0x8C92
-#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD                          0x8C93
-#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD                      0x87EE
+/* BlendingFactorDest */
+#define GL_ZERO                           0
+#define GL_ONE                            1
+#define GL_SRC_COLOR                      0x0300
+#define GL_ONE_MINUS_SRC_COLOR            0x0301
+#define GL_SRC_ALPHA                      0x0302
+#define GL_ONE_MINUS_SRC_ALPHA            0x0303
+#define GL_DST_ALPHA                      0x0304
+#define GL_ONE_MINUS_DST_ALPHA            0x0305
 
-/* GL_AMD_performance_monitor */
-#define GL_COUNTER_TYPE_AMD                                     0x8BC0
-#define GL_COUNTER_RANGE_AMD                                    0x8BC1
-#define GL_UNSIGNED_INT64_AMD                                   0x8BC2
-#define GL_PERCENTAGE_AMD                                       0x8BC3
-#define GL_PERFMON_RESULT_AVAILABLE_AMD                         0x8BC4
-#define GL_PERFMON_RESULT_SIZE_AMD                              0x8BC5
-#define GL_PERFMON_RESULT_AMD                                   0x8BC6
+/* BlendingFactorSrc */
+/*      GL_ZERO */
+/*      GL_ONE */
+#define GL_DST_COLOR                      0x0306
+#define GL_ONE_MINUS_DST_COLOR            0x0307
+#define GL_SRC_ALPHA_SATURATE             0x0308
+/*      GL_SRC_ALPHA */
+/*      GL_ONE_MINUS_SRC_ALPHA */
+/*      GL_DST_ALPHA */
+/*      GL_ONE_MINUS_DST_ALPHA */
 
-/* GL_AMD_program_binary_Z400 */
-#define GL_Z400_BINARY_AMD                                      0x8740
+/* ClipPlaneName */
+#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
 
-/*------------------------------------------------------------------------*
- * EXT extension tokens
- *------------------------------------------------------------------------*/
+/* ColorMaterialFace */
+/*      GL_FRONT_AND_BACK */
 
-/* GL_EXT_blend_minmax */
-#define GL_MIN_EXT                                              0x8007
-#define GL_MAX_EXT                                              0x8008
+/* ColorMaterialParameter */
+/*      GL_AMBIENT_AND_DIFFUSE */
 
-/* GL_EXT_discard_framebuffer */
-#define GL_COLOR_EXT                                            0x1800
-#define GL_DEPTH_EXT                                            0x1801
-#define GL_STENCIL_EXT                                          0x1802
+/* ColorPointerType */
+/*      GL_UNSIGNED_BYTE */
+/*      GL_FLOAT */
+/*      GL_FIXED */
 
-/* GL_EXT_multi_draw_arrays */
-/* No new tokens introduced by this extension. */
+/* CullFaceMode */
+#define GL_FRONT                          0x0404
+#define GL_BACK                           0x0405
+#define GL_FRONT_AND_BACK                 0x0408
 
-/* GL_EXT_read_format_bgra */
-#define GL_BGRA_EXT                                             0x80E1
-#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT                       0x8365
-#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT                       0x8366
+/* DepthFunction */
+/*      GL_NEVER */
+/*      GL_LESS */
+/*      GL_EQUAL */
+/*      GL_LEQUAL */
+/*      GL_GREATER */
+/*      GL_NOTEQUAL */
+/*      GL_GEQUAL */
+/*      GL_ALWAYS */
 
-/* GL_EXT_texture_filter_anisotropic */
-#define GL_TEXTURE_MAX_ANISOTROPY_EXT                           0x84FE
-#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT                       0x84FF
+/* EnableCap */
+#define GL_FOG                            0x0B60
+#define GL_LIGHTING                       0x0B50
+#define GL_TEXTURE_2D                     0x0DE1
+#define GL_CULL_FACE                      0x0B44
+#define GL_ALPHA_TEST                     0x0BC0
+#define GL_BLEND                          0x0BE2
+#define GL_COLOR_LOGIC_OP                 0x0BF2
+#define GL_DITHER                         0x0BD0
+#define GL_STENCIL_TEST                   0x0B90
+#define GL_DEPTH_TEST                     0x0B71
+/*      GL_LIGHT0 */
+/*      GL_LIGHT1 */
+/*      GL_LIGHT2 */
+/*      GL_LIGHT3 */
+/*      GL_LIGHT4 */
+/*      GL_LIGHT5 */
+/*      GL_LIGHT6 */
+/*      GL_LIGHT7 */
+#define GL_POINT_SMOOTH                   0x0B10
+#define GL_LINE_SMOOTH                    0x0B20
+#define GL_SCISSOR_TEST                   0x0C11
+#define GL_COLOR_MATERIAL                 0x0B57
+#define GL_NORMALIZE                      0x0BA1
+#define GL_RESCALE_NORMAL                 0x803A
+#define GL_POLYGON_OFFSET_FILL            0x8037
+#define GL_VERTEX_ARRAY                   0x8074
+#define GL_NORMAL_ARRAY                   0x8075
+#define GL_COLOR_ARRAY                    0x8076
+#define GL_TEXTURE_COORD_ARRAY            0x8078
+#define GL_MULTISAMPLE                    0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE       0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE            0x809F
+#define GL_SAMPLE_COVERAGE                0x80A0
 
-/* GL_EXT_texture_format_BGRA8888 */
-#define GL_BGRA_EXT                                             0x80E1
+/* ErrorCode */
+#define GL_NO_ERROR                       0
+#define GL_INVALID_ENUM                   0x0500
+#define GL_INVALID_VALUE                  0x0501
+#define GL_INVALID_OPERATION              0x0502
+#define GL_STACK_OVERFLOW                 0x0503
+#define GL_STACK_UNDERFLOW                0x0504
+#define GL_OUT_OF_MEMORY                  0x0505
 
-/* GL_EXT_texture_type_2_10_10_10_REV */
-#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT                      0x8368
+/* FogMode */
+/*      GL_LINEAR */
+#define GL_EXP                            0x0800
+#define GL_EXP2                           0x0801
 
-/*------------------------------------------------------------------------*
- * IMG extension tokens
- *------------------------------------------------------------------------*/
+/* FogParameter */
+#define GL_FOG_DENSITY                    0x0B62
+#define GL_FOG_START                      0x0B63
+#define GL_FOG_END                        0x0B64
+#define GL_FOG_MODE                       0x0B65
+#define GL_FOG_COLOR                      0x0B66
 
-/* GL_IMG_program_binary */
-#define GL_SGX_PROGRAM_BINARY_IMG                               0x9130
+/* FrontFaceDirection */
+#define GL_CW                             0x0900
+#define GL_CCW                            0x0901
 
-/* GL_IMG_read_format */
-#define GL_BGRA_IMG                                             0x80E1
-#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG                       0x8365
+/* GetPName */
+#define GL_CURRENT_COLOR                  0x0B00
+#define GL_CURRENT_NORMAL                 0x0B02
+#define GL_CURRENT_TEXTURE_COORDS         0x0B03
+#define GL_POINT_SIZE                     0x0B11
+#define GL_POINT_SIZE_MIN                 0x8126
+#define GL_POINT_SIZE_MAX                 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE      0x8128
+#define GL_POINT_DISTANCE_ATTENUATION     0x8129
+#define GL_SMOOTH_POINT_SIZE_RANGE        0x0B12
+#define GL_LINE_WIDTH                     0x0B21
+#define GL_SMOOTH_LINE_WIDTH_RANGE        0x0B22
+#define GL_ALIASED_POINT_SIZE_RANGE       0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE       0x846E
+#define GL_CULL_FACE_MODE                 0x0B45
+#define GL_FRONT_FACE                     0x0B46
+#define GL_SHADE_MODEL                    0x0B54
+#define GL_DEPTH_RANGE                    0x0B70
+#define GL_DEPTH_WRITEMASK                0x0B72
+#define GL_DEPTH_CLEAR_VALUE              0x0B73
+#define GL_DEPTH_FUNC                     0x0B74
+#define GL_STENCIL_CLEAR_VALUE            0x0B91
+#define GL_STENCIL_FUNC                   0x0B92
+#define GL_STENCIL_VALUE_MASK             0x0B93
+#define GL_STENCIL_FAIL                   0x0B94
+#define GL_STENCIL_PASS_DEPTH_FAIL        0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS        0x0B96
+#define GL_STENCIL_REF                    0x0B97
+#define GL_STENCIL_WRITEMASK              0x0B98
+#define GL_MATRIX_MODE                    0x0BA0
+#define GL_VIEWPORT                       0x0BA2
+#define GL_MODELVIEW_STACK_DEPTH          0x0BA3
+#define GL_PROJECTION_STACK_DEPTH         0x0BA4
+#define GL_TEXTURE_STACK_DEPTH            0x0BA5
+#define GL_MODELVIEW_MATRIX               0x0BA6
+#define GL_PROJECTION_MATRIX              0x0BA7
+#define GL_TEXTURE_MATRIX                 0x0BA8
+#define GL_ALPHA_TEST_FUNC                0x0BC1
+#define GL_ALPHA_TEST_REF                 0x0BC2
+#define GL_BLEND_DST                      0x0BE0
+#define GL_BLEND_SRC                      0x0BE1
+#define GL_LOGIC_OP_MODE                  0x0BF0
+#define GL_SCISSOR_BOX                    0x0C10
+#define GL_SCISSOR_TEST                   0x0C11
+#define GL_COLOR_CLEAR_VALUE              0x0C22
+#define GL_COLOR_WRITEMASK                0x0C23
+#define GL_UNPACK_ALIGNMENT               0x0CF5
+#define GL_PACK_ALIGNMENT                 0x0D05
+#define GL_MAX_LIGHTS                     0x0D31
+#define GL_MAX_CLIP_PLANES                0x0D32
+#define GL_MAX_TEXTURE_SIZE               0x0D33
+#define GL_MAX_MODELVIEW_STACK_DEPTH      0x0D36
+#define GL_MAX_PROJECTION_STACK_DEPTH     0x0D38
+#define GL_MAX_TEXTURE_STACK_DEPTH        0x0D39
+#define GL_MAX_VIEWPORT_DIMS              0x0D3A
+#define GL_MAX_TEXTURE_UNITS              0x84E2
+#define GL_SUBPIXEL_BITS                  0x0D50
+#define GL_RED_BITS                       0x0D52
+#define GL_GREEN_BITS                     0x0D53
+#define GL_BLUE_BITS                      0x0D54
+#define GL_ALPHA_BITS                     0x0D55
+#define GL_DEPTH_BITS                     0x0D56
+#define GL_STENCIL_BITS                   0x0D57
+#define GL_POLYGON_OFFSET_UNITS           0x2A00
+#define GL_POLYGON_OFFSET_FILL            0x8037
+#define GL_POLYGON_OFFSET_FACTOR          0x8038
+#define GL_TEXTURE_BINDING_2D             0x8069
+#define GL_VERTEX_ARRAY_SIZE              0x807A
+#define GL_VERTEX_ARRAY_TYPE              0x807B
+#define GL_VERTEX_ARRAY_STRIDE            0x807C
+#define GL_NORMAL_ARRAY_TYPE              0x807E
+#define GL_NORMAL_ARRAY_STRIDE            0x807F
+#define GL_COLOR_ARRAY_SIZE               0x8081
+#define GL_COLOR_ARRAY_TYPE               0x8082
+#define GL_COLOR_ARRAY_STRIDE             0x8083
+#define GL_TEXTURE_COORD_ARRAY_SIZE       0x8088
+#define GL_TEXTURE_COORD_ARRAY_TYPE       0x8089
+#define GL_TEXTURE_COORD_ARRAY_STRIDE     0x808A
+#define GL_VERTEX_ARRAY_POINTER           0x808E
+#define GL_NORMAL_ARRAY_POINTER           0x808F
+#define GL_COLOR_ARRAY_POINTER            0x8090
+#define GL_TEXTURE_COORD_ARRAY_POINTER    0x8092
+#define GL_SAMPLE_BUFFERS                 0x80A8
+#define GL_SAMPLES                        0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE          0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT         0x80AB
+
+/* GetTextureParameter */
+/*      GL_TEXTURE_MAG_FILTER */
+/*      GL_TEXTURE_MIN_FILTER */
+/*      GL_TEXTURE_WRAP_S */
+/*      GL_TEXTURE_WRAP_T */
+
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS     0x86A3
+
+/* HintMode */
+#define GL_DONT_CARE                      0x1100
+#define GL_FASTEST                        0x1101
+#define GL_NICEST                         0x1102
+
+/* HintTarget */
+#define GL_PERSPECTIVE_CORRECTION_HINT    0x0C50
+#define GL_POINT_SMOOTH_HINT              0x0C51
+#define GL_LINE_SMOOTH_HINT               0x0C52
+#define GL_FOG_HINT                       0x0C54
+#define GL_GENERATE_MIPMAP_HINT           0x8192
+
+/* LightModelParameter */
+#define GL_LIGHT_MODEL_AMBIENT            0x0B53
+#define GL_LIGHT_MODEL_TWO_SIDE           0x0B52
+
+/* LightParameter */
+#define GL_AMBIENT                        0x1200
+#define GL_DIFFUSE                        0x1201
+#define GL_SPECULAR                       0x1202
+#define GL_POSITION                       0x1203
+#define GL_SPOT_DIRECTION                 0x1204
+#define GL_SPOT_EXPONENT                  0x1205
+#define GL_SPOT_CUTOFF                    0x1206
+#define GL_CONSTANT_ATTENUATION           0x1207
+#define GL_LINEAR_ATTENUATION             0x1208
+#define GL_QUADRATIC_ATTENUATION          0x1209
+
+/* DataType */
+#define GL_BYTE                           0x1400
+#define GL_UNSIGNED_BYTE                  0x1401
+#define GL_SHORT                          0x1402
+#define GL_UNSIGNED_SHORT                 0x1403
+#define GL_FLOAT                          0x1406
+#define GL_FIXED                          0x140C
+
+/* LogicOp */
+#define GL_CLEAR                          0x1500
+#define GL_AND                            0x1501
+#define GL_AND_REVERSE                    0x1502
+#define GL_COPY                           0x1503
+#define GL_AND_INVERTED                   0x1504
+#define GL_NOOP                           0x1505
+#define GL_XOR                            0x1506
+#define GL_OR                             0x1507
+#define GL_NOR                            0x1508
+#define GL_EQUIV                          0x1509
+#define GL_INVERT                         0x150A
+#define GL_OR_REVERSE                     0x150B
+#define GL_COPY_INVERTED                  0x150C
+#define GL_OR_INVERTED                    0x150D
+#define GL_NAND                           0x150E
+#define GL_SET                            0x150F
+
+/* MaterialFace */
+/*      GL_FRONT_AND_BACK */
+
+/* MaterialParameter */
+#define GL_EMISSION                       0x1600
+#define GL_SHININESS                      0x1601
+#define GL_AMBIENT_AND_DIFFUSE            0x1602
+/*      GL_AMBIENT */
+/*      GL_DIFFUSE */
+/*      GL_SPECULAR */
+
+/* MatrixMode */
+#define GL_MODELVIEW                      0x1700
+#define GL_PROJECTION                     0x1701
+#define GL_TEXTURE                        0x1702
+
+/* NormalPointerType */
+/*      GL_BYTE */
+/*      GL_SHORT */
+/*      GL_FLOAT */
+/*      GL_FIXED */
+
+/* PixelFormat */
+#define GL_ALPHA                          0x1906
+#define GL_RGB                            0x1907
+#define GL_RGBA                           0x1908
+#define GL_LUMINANCE                      0x1909
+#define GL_LUMINANCE_ALPHA                0x190A
+
+/* PixelStoreParameter */
+#define GL_UNPACK_ALIGNMENT               0x0CF5
+#define GL_PACK_ALIGNMENT                 0x0D05
+
+/* PixelType */
+/*      GL_UNSIGNED_BYTE */
+#define GL_UNSIGNED_SHORT_4_4_4_4         0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1         0x8034
+#define GL_UNSIGNED_SHORT_5_6_5           0x8363
+
+/* ShadingModel */
+#define GL_FLAT                           0x1D00
+#define GL_SMOOTH                         0x1D01
+
+/* StencilFunction */
+/*      GL_NEVER */
+/*      GL_LESS */
+/*      GL_EQUAL */
+/*      GL_LEQUAL */
+/*      GL_GREATER */
+/*      GL_NOTEQUAL */
+/*      GL_GEQUAL */
+/*      GL_ALWAYS */
+
+/* StencilOp */
+/*      GL_ZERO */
+#define GL_KEEP                           0x1E00
+#define GL_REPLACE                        0x1E01
+#define GL_INCR                           0x1E02
+#define GL_DECR                           0x1E03
+/*      GL_INVERT */
 
-/* GL_IMG_shader_binary */
-#define GL_SGX_BINARY_IMG                                       0x8C0A
+/* StringName */
+#define GL_VENDOR                         0x1F00
+#define GL_RENDERER                       0x1F01
+#define GL_VERSION                        0x1F02
+#define GL_EXTENSIONS                     0x1F03
+
+/* TexCoordPointerType */
+/*      GL_SHORT */
+/*      GL_FLOAT */
+/*      GL_FIXED */
+/*      GL_BYTE */
 
-/* GL_IMG_texture_compression_pvrtc */
-#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG                      0x8C00
-#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG                      0x8C01
-#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG                     0x8C02
-#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG                     0x8C03
+/* TextureEnvMode */
+#define GL_MODULATE                       0x2100
+#define GL_DECAL                          0x2101
+/*      GL_BLEND */
+#define GL_ADD                            0x0104
+/*      GL_REPLACE */
 
-/* GL_IMG_multisampled_render_to_texture */
-#define GL_RENDERBUFFER_SAMPLES_IMG                             0x9133
-#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG               0x9134
-#define GL_MAX_SAMPLES_IMG                                      0x9135
-#define GL_TEXTURE_SAMPLES_IMG                                  0x9136
+/* TextureEnvParameter */
+#define GL_TEXTURE_ENV_MODE               0x2200
+#define GL_TEXTURE_ENV_COLOR              0x2201
+
+/* TextureEnvTarget */
+#define GL_TEXTURE_ENV                    0x2300
+
+/* TextureMagFilter */
+#define GL_NEAREST                        0x2600
+#define GL_LINEAR                         0x2601
+
+/* TextureMinFilter */
+/*      GL_NEAREST */
+/*      GL_LINEAR */
+#define GL_NEAREST_MIPMAP_NEAREST         0x2700
+#define GL_LINEAR_MIPMAP_NEAREST          0x2701
+#define GL_NEAREST_MIPMAP_LINEAR          0x2702
+#define GL_LINEAR_MIPMAP_LINEAR           0x2703
+
+/* TextureParameterName */
+#define GL_TEXTURE_MAG_FILTER             0x2800
+#define GL_TEXTURE_MIN_FILTER             0x2801
+#define GL_TEXTURE_WRAP_S                 0x2802
+#define GL_TEXTURE_WRAP_T                 0x2803
+#define GL_GENERATE_MIPMAP                0x8191
+
+/* TextureTarget */
+/*      GL_TEXTURE_2D */
+
+/* TextureUnit */
+#define GL_TEXTURE0                       0x84C0
+#define GL_TEXTURE1                       0x84C1
+#define GL_TEXTURE2                       0x84C2
+#define GL_TEXTURE3                       0x84C3
+#define GL_TEXTURE4                       0x84C4
+#define GL_TEXTURE5                       0x84C5
+#define GL_TEXTURE6                       0x84C6
+#define GL_TEXTURE7                       0x84C7
+#define GL_TEXTURE8                       0x84C8
+#define GL_TEXTURE9                       0x84C9
+#define GL_TEXTURE10                      0x84CA
+#define GL_TEXTURE11                      0x84CB
+#define GL_TEXTURE12                      0x84CC
+#define GL_TEXTURE13                      0x84CD
+#define GL_TEXTURE14                      0x84CE
+#define GL_TEXTURE15                      0x84CF
+#define GL_TEXTURE16                      0x84D0
+#define GL_TEXTURE17                      0x84D1
+#define GL_TEXTURE18                      0x84D2
+#define GL_TEXTURE19                      0x84D3
+#define GL_TEXTURE20                      0x84D4
+#define GL_TEXTURE21                      0x84D5
+#define GL_TEXTURE22                      0x84D6
+#define GL_TEXTURE23                      0x84D7
+#define GL_TEXTURE24                      0x84D8
+#define GL_TEXTURE25                      0x84D9
+#define GL_TEXTURE26                      0x84DA
+#define GL_TEXTURE27                      0x84DB
+#define GL_TEXTURE28                      0x84DC
+#define GL_TEXTURE29                      0x84DD
+#define GL_TEXTURE30                      0x84DE
+#define GL_TEXTURE31                      0x84DF
+#define GL_ACTIVE_TEXTURE                 0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE          0x84E1
+
+/* TextureWrapMode */
+#define GL_REPEAT                         0x2901
+#define GL_CLAMP_TO_EDGE                  0x812F
+
+/* VertexPointerType */
+/*      GL_SHORT */
+/*      GL_FLOAT */
+/*      GL_FIXED */
+/*      GL_BYTE */
+
+/* LightName */
+#define GL_LIGHT0                         0x4000
+#define GL_LIGHT1                         0x4001
+#define GL_LIGHT2                         0x4002
+#define GL_LIGHT3                         0x4003
+#define GL_LIGHT4                         0x4004
+#define GL_LIGHT5                         0x4005
+#define GL_LIGHT6                         0x4006
+#define GL_LIGHT7                         0x4007
+
+/* Buffer Objects */
+#define GL_ARRAY_BUFFER                   0x8892
+#define GL_ELEMENT_ARRAY_BUFFER           0x8893
+
+#define GL_ARRAY_BUFFER_BINDING               0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING       0x8895
+#define GL_VERTEX_ARRAY_BUFFER_BINDING        0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING        0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING         0x8898
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
+
+#define GL_STATIC_DRAW                    0x88E4
+#define GL_DYNAMIC_DRAW                   0x88E8
+
+#define GL_BUFFER_SIZE                    0x8764
+#define GL_BUFFER_USAGE                   0x8765
+
+/* Texture combine + dot3 */
+#define GL_SUBTRACT                       0x84E7
+#define GL_COMBINE                        0x8570
+#define GL_COMBINE_RGB                    0x8571
+#define GL_COMBINE_ALPHA                  0x8572
+#define GL_RGB_SCALE                      0x8573
+#define GL_ADD_SIGNED                     0x8574
+#define GL_INTERPOLATE                    0x8575
+#define GL_CONSTANT                       0x8576
+#define GL_PRIMARY_COLOR                  0x8577
+#define GL_PREVIOUS                       0x8578
+#define GL_OPERAND0_RGB                   0x8590
+#define GL_OPERAND1_RGB                   0x8591
+#define GL_OPERAND2_RGB                   0x8592
+#define GL_OPERAND0_ALPHA                 0x8598
+#define GL_OPERAND1_ALPHA                 0x8599
+#define GL_OPERAND2_ALPHA                 0x859A
+
+#define GL_ALPHA_SCALE                    0x0D1C
+
+#define GL_SRC0_RGB                       0x8580
+#define GL_SRC1_RGB                       0x8581
+#define GL_SRC2_RGB                       0x8582
+#define GL_SRC0_ALPHA                     0x8588
+#define GL_SRC1_ALPHA                     0x8589
+#define GL_SRC2_ALPHA                     0x858A
+
+#define GL_DOT3_RGB                       0x86AE
+#define GL_DOT3_RGBA                      0x86AF
 
 /*------------------------------------------------------------------------*
- * NV extension tokens
+ * required OES extension tokens
  *------------------------------------------------------------------------*/
 
-/* GL_NV_fence */
-#define GL_ALL_COMPLETED_NV                                     0x84F2
-#define GL_FENCE_STATUS_NV                                      0x84F3
-#define GL_FENCE_CONDITION_NV                                   0x84F4
+/* OES_read_format */
+#ifndef GL_OES_read_format
+#define GL_OES_read_format 1
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES                   0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES                 0x8B9B
+#endif
+
+/* OES_point_size_array */
+#ifndef GL_OES_point_size_array
+#define GL_OES_point_size_array 1
+#define GL_POINT_SIZE_ARRAY_OES                                 0x8B9C
+#define GL_POINT_SIZE_ARRAY_TYPE_OES                            0x898A
+#define GL_POINT_SIZE_ARRAY_STRIDE_OES                          0x898B
+#define GL_POINT_SIZE_ARRAY_POINTER_OES                         0x898C
+#define GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES                  0x8B9F
+#endif
+
+/* GL_OES_point_sprite */
+#ifndef GL_OES_point_sprite
+#define GL_OES_point_sprite 1
+#define GL_POINT_SPRITE_OES                                     0x8861
+#define GL_COORD_REPLACE_OES                                    0x8862
+#endif
+
+#else
+# ifndef EVAS_GL_NO_GL_H_CHECK
+#  error "You may only include either Evas_GL.h OR use your native GLES headers. If you use Evas to do GL, then you cannot use the native GLES headers."
+# endif
+#endif
+
+
+#ifndef __glext_h_
+#define __glext_h_ 1
+
+/*------------------------------------------------------------------------*
+ * OES extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_OES_blend_equation_separate */
+#ifndef GL_OES_blend_equation_separate
+/* BLEND_EQUATION_RGB_OES same as BLEND_EQUATION_OES */
+#define GL_BLEND_EQUATION_RGB_OES                               0x8009
+#define GL_BLEND_EQUATION_ALPHA_OES                             0x883D
+#endif
+
+/* GL_OES_blend_func_separate */
+#ifndef GL_OES_blend_func_separate
+#define GL_BLEND_DST_RGB_OES                                    0x80C8
+#define GL_BLEND_SRC_RGB_OES                                    0x80C9
+#define GL_BLEND_DST_ALPHA_OES                                  0x80CA
+#define GL_BLEND_SRC_ALPHA_OES                                  0x80CB
+#endif
+
+/* GL_OES_blend_subtract */
+#ifndef GL_OES_blend_subtract
+#define GL_BLEND_EQUATION_OES                                   0x8009
+#define GL_FUNC_ADD_OES                                         0x8006
+#define GL_FUNC_SUBTRACT_OES                                    0x800A
+#define GL_FUNC_REVERSE_SUBTRACT_OES                            0x800B
+#endif
+
+/* GL_OES_draw_texture */
+#ifndef GL_OES_draw_texture
+#define GL_TEXTURE_CROP_RECT_OES                                0x8B9D
+#endif
+
+/* GL_OES_EGL_image */
+#ifndef GL_OES_EGL_image
+#endif
+
+/* GL_OES_fixed_point */
+#ifndef GL_OES_fixed_point
+#define GL_FIXED_OES                                            0x140C
+#endif
+
+/* GL_OES_framebuffer_object */
+#ifndef GL_OES_framebuffer_object
+#define GL_NONE_OES                                             0
+#define GL_FRAMEBUFFER_OES                                      0x8D40
+#define GL_RENDERBUFFER_OES                                     0x8D41
+#define GL_RGBA4_OES                                            0x8056
+#define GL_RGB5_A1_OES                                          0x8057
+#define GL_RGB565_OES                                           0x8D62
+#define GL_DEPTH_COMPONENT16_OES                                0x81A5
+#define GL_RENDERBUFFER_WIDTH_OES                               0x8D42
+#define GL_RENDERBUFFER_HEIGHT_OES                              0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT_OES                     0x8D44
+#define GL_RENDERBUFFER_RED_SIZE_OES                            0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE_OES                          0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE_OES                           0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE_OES                          0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE_OES                          0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE_OES                        0x8D55
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES               0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES               0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES             0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES     0x8CD3
+#define GL_COLOR_ATTACHMENT0_OES                                0x8CE0
+#define GL_DEPTH_ATTACHMENT_OES                                 0x8D00
+#define GL_STENCIL_ATTACHMENT_OES                               0x8D20
+#define GL_FRAMEBUFFER_COMPLETE_OES                             0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES                0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES        0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES                0x8CD9
+#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES                   0x8CDA
+#define GL_FRAMEBUFFER_UNSUPPORTED_OES                          0x8CDD
+#define GL_FRAMEBUFFER_BINDING_OES                              0x8CA6
+#define GL_RENDERBUFFER_BINDING_OES                             0x8CA7
+#define GL_MAX_RENDERBUFFER_SIZE_OES                            0x84E8
+#define GL_INVALID_FRAMEBUFFER_OPERATION_OES                    0x0506
+#endif
+
+/* GL_OES_matrix_get */
+#ifndef GL_OES_matrix_get
+#define GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES               0x898D
+#define GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES              0x898E
+#define GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES                 0x898F
+#endif
+
+/* GL_OES_matrix_palette */
+#ifndef GL_OES_matrix_palette
+#define GL_MAX_VERTEX_UNITS_OES                                 0x86A4
+#define GL_MAX_PALETTE_MATRICES_OES                             0x8842
+#define GL_MATRIX_PALETTE_OES                                   0x8840
+#define GL_MATRIX_INDEX_ARRAY_OES                               0x8844
+#define GL_WEIGHT_ARRAY_OES                                     0x86AD
+#define GL_CURRENT_PALETTE_MATRIX_OES                           0x8843
+#define GL_MATRIX_INDEX_ARRAY_SIZE_OES                          0x8846
+#define GL_MATRIX_INDEX_ARRAY_TYPE_OES                          0x8847
+#define GL_MATRIX_INDEX_ARRAY_STRIDE_OES                        0x8848
+#define GL_MATRIX_INDEX_ARRAY_POINTER_OES                       0x8849
+#define GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES                0x8B9E
+#define GL_WEIGHT_ARRAY_SIZE_OES                                0x86AB
+#define GL_WEIGHT_ARRAY_TYPE_OES                                0x86A9
+#define GL_WEIGHT_ARRAY_STRIDE_OES                              0x86AA
+#define GL_WEIGHT_ARRAY_POINTER_OES                             0x86AC
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING_OES                      0x889E
+#endif
+
+/* GL_OES_stencil8 */
+#ifndef GL_OES_stencil8
+#define GL_STENCIL_INDEX8_OES                                   0x8D48
+#endif
+
+/* GL_OES_stencil_wrap */
+#ifndef GL_OES_stencil_wrap
+#define GL_INCR_WRAP_OES                                        0x8507
+#define GL_DECR_WRAP_OES                                        0x8508
+#endif
+
+/* GL_OES_texture_cube_map */
+#ifndef GL_OES_texture_cube_map
+#define GL_NORMAL_MAP_OES                                       0x8511
+#define GL_REFLECTION_MAP_OES                                   0x8512
+#define GL_TEXTURE_CUBE_MAP_OES                                 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_OES                         0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES                      0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES                      0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES                      0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES                      0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES                      0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES                      0x851A
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES                        0x851C
+#define GL_TEXTURE_GEN_MODE_OES                                 0x2500
+#define GL_TEXTURE_GEN_STR_OES                                  0x8D60
+#endif
+
+/* GL_OES_texture_mirrored_repeat */
+#ifndef GL_OES_texture_mirrored_repeat
+#define GL_MIRRORED_REPEAT_OES                                  0x8370
+#endif
+
+/*------------------------------------------------------------------------*
+ * EXT extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_EXT_texture_lod_bias */
+#ifndef GL_EXT_texture_lod_bias
+#define GL_MAX_TEXTURE_LOD_BIAS_EXT                             0x84FD
+#define GL_TEXTURE_FILTER_CONTROL_EXT                           0x8500
+#define GL_TEXTURE_LOD_BIAS_EXT                                 0x8501
+#endif
+
+/*------------------------------------------------------------------------*
+ * IMG extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_IMG_texture_env_enhanced_fixed_function */
+#ifndef GL_IMG_texture_env_enhanced_fixed_function
+#define GL_MODULATE_COLOR_IMG                                   0x8C04
+#define GL_RECIP_ADD_SIGNED_ALPHA_IMG                           0x8C05
+#define GL_TEXTURE_ALPHA_MODULATE_IMG                           0x8C06
+#define GL_FACTOR_ALPHA_MODULATE_IMG                            0x8C07
+#define GL_FRAGMENT_ALPHA_MODULATE_IMG                          0x8C08
+#define GL_ADD_BLEND_IMG                                        0x8C09
+#define GL_DOT3_RGBA_IMG                                        0x86AF
+#endif
+
+/* GL_IMG_user_clip_plane */
+#ifndef GL_IMG_user_clip_plane
+#define GL_CLIP_PLANE0_IMG                                      0x3000
+#define GL_CLIP_PLANE1_IMG                                      0x3001
+#define GL_CLIP_PLANE2_IMG                                      0x3002
+#define GL_CLIP_PLANE3_IMG                                      0x3003
+#define GL_CLIP_PLANE4_IMG                                      0x3004
+#define GL_CLIP_PLANE5_IMG                                      0x3005
+#define GL_MAX_CLIP_PLANES_IMG                                  0x0D32
+#endif
 
 /*------------------------------------------------------------------------*
  * QCOM extension tokens
  *------------------------------------------------------------------------*/
 
-/* GL_QCOM_driver_control */
-/* No new tokens introduced by this extension. */
+/* GL_QCOM_binning_control */
+#ifndef GL_QCOM_binning_control
+#define GL_QCOM_binning_control 1
+#define GL_BINNING_CONTROL_HINT_QCOM      0x8FB0
+#define GL_CPU_OPTIMIZED_QCOM             0x8FB1
+#define GL_GPU_OPTIMIZED_QCOM             0x8FB2
+#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3
+#endif
+
+/*------------------------------------------------------------------------*
+ * OES extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_OES_blend_equation_separate */
+#ifndef GL_OES_blend_equation_separate
+#define GL_OES_blend_equation_separate 1
+#endif
 
-/* GL_QCOM_extended_get */
-#define GL_TEXTURE_WIDTH_QCOM                                   0x8BD2
-#define GL_TEXTURE_HEIGHT_QCOM                                  0x8BD3
-#define GL_TEXTURE_DEPTH_QCOM                                   0x8BD4
-#define GL_TEXTURE_INTERNAL_FORMAT_QCOM                         0x8BD5
-#define GL_TEXTURE_FORMAT_QCOM                                  0x8BD6
-#define GL_TEXTURE_TYPE_QCOM                                    0x8BD7
-#define GL_TEXTURE_IMAGE_VALID_QCOM                             0x8BD8
-#define GL_TEXTURE_NUM_LEVELS_QCOM                              0x8BD9
-#define GL_TEXTURE_TARGET_QCOM                                  0x8BDA
-#define GL_TEXTURE_OBJECT_VALID_QCOM                            0x8BDB
-#define GL_STATE_RESTORE                                        0x8BDC
+/* GL_OES_blend_func_separate */
+#ifndef GL_OES_blend_func_separate
+#define GL_OES_blend_func_separate 1
+#endif
 
-/* GL_QCOM_extended_get2 */
-/* No new tokens introduced by this extension. */
+/* GL_OES_blend_subtract */
+#ifndef GL_OES_blend_subtract
+#define GL_OES_blend_subtract 1
+#endif
 
-/* GL_QCOM_perfmon_global_mode */
-#define GL_PERFMON_GLOBAL_MODE_QCOM                             0x8FA0
+/* GL_OES_byte_coordinates */
+#ifndef GL_OES_byte_coordinates
+#define GL_OES_byte_coordinates 1
+#endif
 
-/* GL_QCOM_writeonly_rendering */
-#define GL_WRITEONLY_RENDERING_QCOM                             0x8823
+/* GL_OES_draw_texture */
+#ifndef GL_OES_draw_texture
+#define GL_OES_draw_texture 1
+#endif
+
+/* GL_OES_extended_matrix_palette */
+#ifndef GL_OES_extended_matrix_palette
+#define GL_OES_extended_matrix_palette 1
+#endif
+
+/* GL_OES_fixed_point */
+#ifndef GL_OES_fixed_point
+#define GL_OES_fixed_point 1
+#endif
+
+/* GL_OES_framebuffer_object */
+#ifndef GL_OES_framebuffer_object
+#define GL_OES_framebuffer_object 1
+#endif
+
+/* GL_OES_matrix_get */
+#ifndef GL_OES_matrix_get
+#define GL_OES_matrix_get 1
+#endif
+
+/* GL_OES_matrix_palette */
+#ifndef GL_OES_matrix_palette
+#define GL_OES_matrix_palette 1
+#endif
+
+/* GL_OES_query_matrix */
+#ifndef GL_OES_query_matrix
+#define GL_OES_query_matrix 1
+#endif
+
+/* GL_OES_single_precision */
+#ifndef GL_OES_single_precision
+#define GL_OES_single_precision 1
+#endif
+
+/* GL_OES_stencil8 */
+#ifndef GL_OES_stencil8
+#define GL_OES_stencil8 1
+#endif
+
+/* GL_OES_stencil_wrap */
+#ifndef GL_OES_stencil_wrap
+#define GL_OES_stencil_wrap 1
+#endif
+
+/* GL_OES_texture_cube_map */
+#ifndef GL_OES_texture_cube_map
+#define GL_OES_texture_cube_map 1
+#endif
+
+/* GL_OES_texture_env_crossbar */
+#ifndef GL_OES_texture_env_crossbar
+#define GL_OES_texture_env_crossbar 1
+#endif
+
+/* GL_OES_texture_mirrored_repeat */
+#ifndef GL_OES_texture_mirrored_repeat
+#define GL_OES_texture_mirrored_repeat 1
+#endif
 
 /*------------------------------------------------------------------------*
- * End of extension tokens, start of corresponding extension functions
+ * APPLE extension functions
  *------------------------------------------------------------------------*/
 
-/* EvasGL_KHR_image */
-#define EVAS_GL_NATIVE_PIXMAP                                   0x30B0  /* evasglCreateImage target */
+/* GL_APPLE_texture_2D_limited_npot */
+#ifndef GL_APPLE_texture_2D_limited_npot
+#define GL_APPLE_texture_2D_limited_npot 1
+#endif
 
-/* EvasGL_KHR_vg_parent_image */
-#define EVAS_VG_PARENT_IMAGE                                    0x30BA  /* evasglCreateImage target */
+/*------------------------------------------------------------------------*
+ * EXT extension functions
+ *------------------------------------------------------------------------*/
 
-/* EvasGL_KHR_gl_texture_2D_image */
-#define EVAS_GL_TEXTURE_2D                                      0x30B1  /* evasglCreateImage target */
-#define EVAS_GL_TEXTURE_LEVEL                                   0x30BC  /* evasglCreateImage attribute */
+/* GL_EXT_texture_lod_bias */
+#ifndef GL_EXT_texture_lod_bias
+#define GL_EXT_texture_lod_bias 1
+#endif
 
-/* EvasGL_KHR_gl_texture_cubemap_image */
-#define EVAS_GL_TEXTURE_CUBE_MAP_POSITIVE_X                     0x30B3  /* evasglCreateImage target */
-#define EVAS_GL_TEXTURE_CUBE_MAP_NEGATIVE_X                     0x30B4  /* evasglCreateImage target */
-#define EVAS_GL_TEXTURE_CUBE_MAP_POSITIVE_Y                     0x30B5  /* evasglCreateImage target */
-#define EVAS_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y                     0x30B6  /* evasglCreateImage target */
-#define EVAS_GL_TEXTURE_CUBE_MAP_POSITIVE_Z                     0x30B7  /* evasglCreateImage target */
-#define EVAS_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z                     0x30B8  /* evasglCreateImage target */
+/*------------------------------------------------------------------------*
+ * IMG extension functions
+ *------------------------------------------------------------------------*/
 
-/* EvasGL_KHR_gl_texture_3D_image */
-#define EVAS_GL_TEXTURE_3D                                      0x30B2  /* evasglCreateImage target */
-#define EVAS_GL_TEXTURE_ZOFFSET                                 0x30BD  /* evasglCreateImage attribute */
+/* GL_IMG_texture_env_enhanced_fixed_function */
+#ifndef GL_IMG_texture_env_enhanced_fixed_function
+#define GL_IMG_texture_env_enhanced_fixed_function 1
+#endif
 
-/* EvasGL_KHR_gl_renderbuffer_image */
-#define EVAS_GL_RENDERBUFFER                                    0x30B9  /* evasglCreateImage target */
+/* GL_IMG_user_clip_plane */
+#ifndef GL_IMG_user_clip_plane
+#define GL_IMG_user_clip_plane 1
+#endif
 
 #else
 # ifndef EVAS_GL_NO_GL_H_CHECK
-#  error "You may only include either Evas_GL.h OR use your native OpenGL's headers. If you use Evas to do GL, then you cannot use the native gl headers."
+#  error "You may only include either Evas_GL.h OR use your native GLES headers. If you use Evas to do GL, then you cannot use the native GLES headers."
 # endif
 #endif
 
-#define EVAS_GL_API_VERSION 1
+
+/* Some definitions from GLES 3.0.
+ * Note: Evas_GL does NOT support GLES 3.
+ */
+
+/* Evas can use RGB8_ETC2 and RGBA8_ETC2_EAC internally, depending on the driver */
+#define GL_COMPRESSED_RGB8_ETC2           0x9274
+#define GL_COMPRESSED_RGBA8_ETC2_EAC      0x9278
+
+
+// These types are required since we can't include GLES/gl.h or gl2.h
+typedef signed int         GLclampx;   // Changed khronos_int32_t
+typedef struct __GLsync*   GLsync;
+
+
+
+/*
+ * EGL-related definitions
+ *
+ * Note the names have been changed from EGL to EvasGL so as to be
+ * platform independent. Except for the error codes, the following
+ * EVAS_GL_x definitions have the same values as their EGL_x counterparts.
+ * Please note that the error codes have been reset to start from 0 (success).
+ */
+
+/* EGL/EvasGL Types */
+typedef void *EvasGLSync;
+typedef unsigned long long EvasGLTime;
+
+/* @brief Attribute list terminator
+ * 0 is also accepted as an attribute terminator.
+ * Evas_GL will ensure that the attribute list is always properly terminated
+ * (eg. using EGL_NONE for EGL backends) and the values are supported by the
+ * backends.
+ */
+#define EVAS_GL_NONE                            0x3038
+
+/* EGL_KHR_image_base */
+#define EVAS_GL_image_base 1
+#define EVAS_GL_IMAGE_PRESERVED                 0x30D2  /**< @brief An attribute for @ref evasglCreateImage or @ref evasglCreateImageForContext, the default is @c EINA_FALSE. Please refer to @c EGL_IMAGE_PRESERVED_KHR. */
+
+/* EGL_KHR_image */
+#define EVAS_GL_image 1
+#define EVAS_GL_NATIVE_PIXMAP                   0x30B0  /**< @internal A target for @ref evasglCreateImage or @ref evasglCreateImageForContext. Since it is X11-specific, it should not be used by Tizen applications. */
+
+/* EGL_KHR_vg_parent_image */
+#define EVAS_VG_PARENT_IMAGE                    0x30BA  /**< @brief A target for @ref evasglCreateImage or @ref evasglCreateImageForContext */
+
+/* EGL_KHR_gl_texture_2D_image */
+#define EVAS_GL_TEXTURE_2D                      0x30B1  /**< @brief An attribute for @ref evasglCreateImage or @ref evasglCreateImageForContext */
+#define EVAS_GL_TEXTURE_LEVEL                   0x30BC  /**< @brief An attribute for @ref evasglCreateImage or @ref evasglCreateImageForContext */
+
+/* EGL_KHR_gl_texture_cubemap_image */
+#define EVAS_GL_TEXTURE_CUBE_MAP_POSITIVE_X     0x30B3  /**< @brief A target for @ref evasglCreateImage or @ref evasglCreateImageForContext */
+#define EVAS_GL_TEXTURE_CUBE_MAP_NEGATIVE_X     0x30B4  /**< @brief A target for @ref evasglCreateImage or @ref evasglCreateImageForContext */
+#define EVAS_GL_TEXTURE_CUBE_MAP_POSITIVE_Y     0x30B5  /**< @brief A target for @ref evasglCreateImage or @ref evasglCreateImageForContext */
+#define EVAS_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y     0x30B6  /**< @brief A target for @ref evasglCreateImage or @ref evasglCreateImageForContext */
+#define EVAS_GL_TEXTURE_CUBE_MAP_POSITIVE_Z     0x30B7  /**< @brief A target for @ref evasglCreateImage or @ref evasglCreateImageForContext */
+#define EVAS_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z     0x30B8  /**< @brief A target for @ref evasglCreateImage or @ref evasglCreateImageForContext */
+
+/* EGL_KHR_gl_texture_3D_image */
+#define EVAS_GL_TEXTURE_3D                      0x30B2  /**< @brief A target for @ref evasglCreateImage or @ref evasglCreateImageForContext */
+#define EVAS_GL_TEXTURE_ZOFFSET                 0x30BD  /**< @brief An attribute for @ref evasglCreateImage or @ref evasglCreateImageForContext */
+
+/* EGL_KHR_gl_renderbuffer_image */
+#define EVAS_GL_RENDERBUFFER                    0x30B9  /**< @brief A target for @ref evasglCreateImage or @ref evasglCreateImageForContext */
+
+/* Out-of-band attribute value */
+#define EVAS_GL_DONT_CARE                      (-1)
+
+/* EGL_TIZEN_image_native_surface */
+#define EVAS_GL_TIZEN_image_native_surface 1
+#define EVAS_GL_NATIVE_SURFACE_TIZEN            0x32A1  /**< @brief A target for @ref evasglCreateImage or @ref evasglCreateImageForContext. This is a Tizen specific feature. */
+
+/**
+ * @name Evas GL error codes
+ *
+ * These are the possible return values of @ref evas_gl_error_get.
+ * The values are the same as EGL error codes - @c EGL_SUCCESS.
+ *
+ * Some of the values may be set directly by Evas GL when an obvious error was
+ * detected (eg. @c NULL pointers or invalid dimensions), otherwise Evas GL will
+ * call the backend's GetError() function and translate to a valid @c EVAS_GL_
+ * error code.
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ *
+ * @{
+ */
+#define EVAS_GL_SUCCESS                         0x0000  /**< @brief The last evas_gl_ operation succeeded. A call to @c evas_gl_error_get() will reset the error. */
+#define EVAS_GL_NOT_INITIALIZED                 0x0001  /**< @brief Evas GL was not initialized or a @c NULL pointer was passed */
+#define EVAS_GL_BAD_ACCESS                      0x0002  /**< @brief Bad access; for more information, please refer to its EGL counterpart */
+#define EVAS_GL_BAD_ALLOC                       0x0003  /**< @brief Bad allocation; for more information, please refer to its EGL counterpart */
+#define EVAS_GL_BAD_ATTRIBUTE                   0x0004  /**< @brief Bad attribute; for more information, please refer to its EGL counterpart */
+#define EVAS_GL_BAD_CONFIG                      0x0005  /**< @brief Bad configuration; for more information, please refer to its EGL counterpart */
+#define EVAS_GL_BAD_CONTEXT                     0x0006  /**< @brief Bad context; for more information, please refer to its EGL counterpart */
+#define EVAS_GL_BAD_CURRENT_SURFACE             0x0007  /**< @brief Bad current surface; for more information, please refer to its EGL counterpart */
+#define EVAS_GL_BAD_DISPLAY                     0x0008  /**< @brief Bad display; for more information, please refer to its EGL counterpart */
+#define EVAS_GL_BAD_MATCH                       0x0009  /**< @brief Bad match; for more information, please refer to its EGL counterpart */
+#define EVAS_GL_BAD_NATIVE_PIXMAP               0x000A  /**< @internal Bad native pixmap; for more information, please refer to its EGL counterpart */
+#define EVAS_GL_BAD_NATIVE_WINDOW               0x000B  /**< @brief Bad native window; for more information, please refer to its EGL counterpart */
+#define EVAS_GL_BAD_PARAMETER                   0x000C  /**< @brief Bad parameter; for more information, please refer to its EGL counterpart */
+#define EVAS_GL_BAD_SURFACE                     0x000D  /**< @brief Bad surface; for more information, please refer to its EGL counterpart */
+/* EGL 1.1 - IMG_power_management */
+#define EVAS_GL_CONTEXT_LOST                    0x000E  /**< @brief Context lost; for more information, please refer to its EGL counterpart */
+
+/** @} */
+
+/* EGL_KHR_fence_sync - EVAS_GL_fence_sync */
+#define EVAS_GL_fence_sync 1
+/* EGL_KHR_reusable_sync - EVAS_GL_reusable_sync */
+#define EVAS_GL_reusable_sync 1
+/* EGL_KHR_wait_sync - EVAS_GL_wait_sync */
+#define EVAS_GL_KHR_wait_sync 1
+
+/**
+ * @name Constants used to define and wait for Sync objects.
+ * @{
+ */
+#define EVAS_GL_SYNC_PRIOR_COMMANDS_COMPLETE    0x30F0 /**< @brief A value for @ref evasglGetSyncAttrib with @ref EVAS_GL_SYNC_CONDITION  */
+#define EVAS_GL_SYNC_STATUS                     0x30F1 /**< @brief A attribute for @ref evasglGetSyncAttrib */
+#define EVAS_GL_SIGNALED                        0x30F2 /**< @brief A value for @ref evasglGetSyncAttrib with @ref EVAS_GL_SYNC_STATUS  */
+#define EVAS_GL_UNSIGNALED                      0x30F3 /**< @brief A value for @ref evasglGetSyncAttrib with @ref EVAS_GL_SYNC_STATUS  */
+#define EVAS_GL_TIMEOUT_EXPIRED                 0x30F5 /**< @brief A returned by @ref evasglClientWaitSync */
+#define EVAS_GL_CONDITION_SATISFIED             0x30F6 /**< @brief A returned by @ref evasglClientWaitSync */
+#define EVAS_GL_SYNC_TYPE                       0x30F7 /**< @brief A attribute for @ref evasglGetSyncAttrib */
+#define EVAS_GL_SYNC_CONDITION                  0x30F8 /**< @brief A attribute for @ref evasglGetSyncAttrib */
+#define EVAS_GL_SYNC_FENCE                      0x30F9 /**< @brief A type for @ref evasglCreateSync */
+#define EVAS_GL_SYNC_REUSABLE                   0x30FA /**< @brief A type for @ref evasglCreateSync */
+
+#define EVAS_GL_SYNC_FLUSH_COMMANDS_BIT         0x0001 /**< @brief A flag for @ref evasglClientWaitSync */
+#define EVAS_GL_FOREVER                         0xFFFFFFFFFFFFFFFFull  /**< @brief Disable wait timeout */
+#define EVAS_GL_NO_SYNC                         ((EvasGLSync) NULL)    /**< @brief Empty sync object, see @ref evasglCreateSync */
+/** @} */
+
+/**
+ * @name Surface attributes
+ * The attributes can be queried using @ref evas_gl_surface_query
+ * @{
+ */
+#define EVAS_GL_HEIGHT                          0x3056 /**< @brief Attribute for @ref evas_gl_surface_query, returns the surface width in pixels (@c value should be an @c int) */
+#define EVAS_GL_WIDTH                           0x3057 /**< @brief Attribute for @ref evas_gl_surface_query, returns the surface width in pixels (@c value should be an @c int) */
+#define EVAS_GL_TEXTURE_FORMAT                  0x3080 /**< @brief Attribute for @ref evas_gl_surface_query, returns an @ref Evas_GL_Color_Format */
+#define EVAS_GL_TEXTURE_TARGET                  0x3081 /**< @brief Attribute for @ref evas_gl_surface_query, returns @ref EVAS_GL_TEXTURE_2D (if format is @c EVAS_GL_RGB_888 or @c EVAS_GL_RGBA_8888) or 0 (meaning @c NO_TEXTURE, from @c EVAS_GL_NO_FBO) (@c value should be an @c int) */
+/** @} */
+
+
+/* Version 1: OpenGLES 2.0 + extensions only
+ * Version 2: OpenGLES 1.0 + extensions
+ */
+#define EVAS_GL_API_VERSION 2
+
+/**
+ * @brief The Evas GL API
+ * This structure contains function pointers to the available GL functions.
+ * Some of these functions may be wrapped internally by Evas GL.
+ */
 struct _Evas_GL_API
 {
+   /**
+    * The current version number is @c EVAS_GL_API_VERSION (2).
+    * This should not be confused with the OpenGL-ES context version.
+    */
    int            version;
 
-   /* version 1: */
-   /*------- GLES 2.0 -------*/
+   /**
+    * @anchor gles2
+    * @name OpenGL-ES 2.0.
+    *
+    * Evas_GL_API version 1.
+    *
+    * The following functions are supported in all OpenGL-ES 2.0 contexts.
+    * @{
+    */
    void         (*glActiveTexture) (GLenum texture);
    void         (*glAttachShader) (GLuint program, GLuint shader);
    void         (*glBindAttribLocation) (GLuint program, GLuint index, const char* name);
@@ -1436,16 +3789,29 @@ struct _Evas_GL_API
    void         (*glVertexAttrib4fv) (GLuint indx, const GLfloat* values);
    void         (*glVertexAttribPointer) (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
    void         (*glViewport) (GLint x, GLint y, GLsizei width, GLsizei height);
-
-   /*------- GLES 2.0 Extensions -------*/
+   /** @} */
+
+   /**
+    * @name OpenGL-ES 2.0 extensions.
+    *
+    *  Evas_GL_API version 1
+    *
+    * The following functions may be supported in OpenGL-ES 2.0 contexts,
+    * depending on which extensions Evas has decided to support.
+    *
+    * @{
+    */
+
+   /* GL_OES_EGL_image */
    // Notice these two names have been changed to fit Evas GL and not EGL!
-   /* GL_OES_EvasGL_image */
+   /** @brief Requires the @c GL_OES_EGL_image extension, similar to @c glEGLImageTargetTexture2DOES. */
    void         (*glEvasGLImageTargetTexture2DOES) (GLenum target, EvasGLImage image);
+   /** @brief Requires the @c GL_OES_EGL_image extension, similar to @c glEGLImageTargetRenderbufferStorageOES. */
    void         (*glEvasGLImageTargetRenderbufferStorageOES) (GLenum target, EvasGLImage image);
 
    /* GL_OES_get_program_binary */
    void        (*glGetProgramBinaryOES) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
-   void        (*glProgramBinaryOES) (GLuint program, GLenum binaryFormat, const void *binary, GLint length);   
+   void        (*glProgramBinaryOES) (GLuint program, GLenum binaryFormat, const void *binary, GLint length);
    /* GL_OES_mapbuffer */
    void*       (*glMapBufferOES) (GLenum target, GLenum access);
    GLboolean   (*glUnmapBufferOES) (GLenum target);
@@ -1503,20 +3869,387 @@ struct _Evas_GL_API
    void        (*glExtGetTexSubImageQCOM) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void* texels);
    void        (*glExtGetBufferPointervQCOM) (GLenum target, void** params);
 
-
    /* GL_QCOM_extended_get2 */
    void        (*glExtGetShadersQCOM) (GLuint* shaders, GLint maxShaders, GLint* numShaders);
    void        (*glExtGetProgramsQCOM) (GLuint* programs, GLint maxPrograms, GLint* numPrograms);
    GLboolean   (*glExtIsProgramBinaryQCOM) (GLuint program);
    void        (*glExtGetProgramBinarySourceQCOM) (GLuint program, GLenum shadertype, char* source, GLint* length);
-
-   //------- EGL Related Extensions -------//
-   /* EvasGL_KHR_image */
-   EvasGLImage  (*evasglCreateImage) (int target, void* buffer, int* attrib_list);
+   /** @} */
+
+   /**
+    * @name EGL-related extensions
+    *
+    * Evas_GL_API version 1.
+    *
+    * @{
+    */
+
+   /* EGL_KHR_image - #ifdef EVAS_GL_image */
+   /**
+    * @anchor evasglCreateImage
+    * @brief Create an EvasGLImage for the current context.
+    *
+    * Common targets are:
+    * @li @c EVAS_GL_TEXTURE_2D:<br/>
+    * In case of @c EVAS_GL_TEXTURE_2D on EGL, the currently bound EGLContext
+    * will be used to create the image. The buffer argument must be a texture
+    * ID cast down to a void* pointer.<br/>
+    * Requires the @c EVAS_GL_image extension.
+    *
+    * @li @c EVAS_GL_NATIVE_SURFACE_TIZEN (Tizen platform only):<br/>
+    * Requires the @c EVAS_GL_TIZEN_image_native_surface extension.
+    *
+    * @note Please consider using @ref evasglCreateImageForContext instead.
+    */
+   EvasGLImage  (*evasglCreateImage) (int target, void* buffer, const int* attrib_list) EINA_WARN_UNUSED_RESULT;
+
+   /**
+    * @anchor evasglDestroyImage
+    * @brief Destroys an EvasGLImage.
+    * Destroy an image created by either @ref evasglCreateImage or @ref evasglCreateImageForContext.
+    *
+    * Requires the @c EVAS_GL_image extension.
+    */
    void         (*evasglDestroyImage) (EvasGLImage image);
 
+   /* Evas_GL_API version 2: */
+
+   /**
+    * @anchor evasglCreateImageForContext
+    * @brief Create an EvasGLImage for a given context.
+    *
+    * @param[in]  evas_gl     The current Evas GL object,
+    * @param[in]  ctx         A context to create this image for,
+    * @param[in]  target      One of @c EVAS_GL_TEXTURE_2D and @c EVAS_GL_NATIVE_SURFACE_TIZEN,
+    * @param[in]  buffer      A pointer to a buffer, see below,
+    * @param[in]  attrib_list An array of key-value pairs terminated by 0 (see @ref EVAS_GL_IMAGE_PRESERVED)
+    *
+    * Common targets are:
+    * @li @c EVAS_GL_TEXTURE_2D:<br/>
+    * In case of @c EVAS_GL_TEXTURE_2D, the buffer argument must be a texture
+    * ID cast down to a void* pointer.<br/>
+    * Requires the @c EVAS_GL_image extension.
+    *
+    * @code
+EvasGLImage *img = glapi->evasglCreateImageForContext
+  (evasgl, ctx, EVAS_GL_TEXTURE_2D, (void*)(intptr_t)texture_id, NULL);
+    * @endcode
+    *
+    * @li @c EVAS_GL_NATIVE_SURFACE_TIZEN (Tizen platform only):<br/>
+    * Requires the @c EVAS_GL_TIZEN_image_native_surface extension.
+    *
+    * @if MOBILE @since_tizen 2.3
+    * @elseif WEARABLE @since_tizen 2.3.1
+    * @endif
+    */
+   EvasGLImage  (*evasglCreateImageForContext) (Evas_GL *evas_gl, Evas_GL_Context *ctx, int target, void* buffer, const int* attrib_list) EINA_WARN_UNUSED_RESULT;
+
+   /* This defines shows that Evas_GL_API supports GLES1 APIs */
+#define EVAS_GL_GLES1 1
+   /**
+    * @name OpenGL-ES 1.1
+    *
+    * Evas_GL_API version 2.
+    *
+    * The following functions are some of the standard OpenGL-ES 1.0 functions,
+    * that are not also present in the @ref gles2 "OpenGL-ES 2.0 APIs".
+    * @{
+    */
+   /* Available only in Common profile */
+   void         (*glAlphaFunc) (GLenum func, GLclampf ref);
+   void         (*glClipPlanef) (GLenum plane, const GLfloat *equation);
+   void         (*glColor4f) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+   void         (*glFogf) (GLenum pname, GLfloat param);
+   void         (*glFogfv) (GLenum pname, const GLfloat *params);
+   void         (*glFrustumf) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+   void         (*glGetClipPlanef) (GLenum pname, GLfloat eqn[4]);
+   void         (*glGetLightfv) (GLenum light, GLenum pname, GLfloat *params);
+   void         (*glGetMaterialfv) (GLenum face, GLenum pname, GLfloat *params);
+   void         (*glGetTexEnvfv) (GLenum env, GLenum pname, GLfloat *params);
+   void         (*glLightModelf) (GLenum pname, GLfloat param);
+   void         (*glLightModelfv) (GLenum pname, const GLfloat *params);
+   void         (*glLightf) (GLenum light, GLenum pname, GLfloat param);
+   void         (*glLightfv) (GLenum light, GLenum pname, const GLfloat *params);
+   void         (*glLoadMatrixf) (const GLfloat *m);
+   void         (*glMaterialf) (GLenum face, GLenum pname, GLfloat param);
+   void         (*glMaterialfv) (GLenum face, GLenum pname, const GLfloat *params);
+   void         (*glMultMatrixf) (const GLfloat *m);
+   void         (*glMultiTexCoord4f) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+   void         (*glNormal3f) (GLfloat nx, GLfloat ny, GLfloat nz);
+   void         (*glOrthof) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+   void         (*glPointParameterf) (GLenum pname, GLfloat param);
+   void         (*glPointParameterfv) (GLenum pname, const GLfloat *params);
+   void         (*glPointSize) (GLfloat size);
+   void         (*glPointSizePointerOES) (GLenum type, GLsizei stride, const GLvoid * pointer);
+   void         (*glRotatef) (GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+   void         (*glScalef) (GLfloat x, GLfloat y, GLfloat z);
+   void         (*glTexEnvf) (GLenum target, GLenum pname, GLfloat param);
+   void         (*glTexEnvfv) (GLenum target, GLenum pname, const GLfloat *params);
+   void         (*glTranslatef) (GLfloat x, GLfloat y, GLfloat z);
+
+   /* Available in both Common and Common-Lite profiles */
+   void         (*glAlphaFuncx) (GLenum func, GLclampx ref);
+   void         (*glClearColorx) (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
+   void         (*glClearDepthx) (GLclampx depth);
+   void         (*glClientActiveTexture) (GLenum texture);
+   void         (*glClipPlanex) (GLenum plane, const GLfixed *equation);
+   void         (*glColor4ub) (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+   void         (*glColor4x) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+   void         (*glColorPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+   void         (*glDepthRangex) (GLclampx zNear, GLclampx zFar);
+   void         (*glDisableClientState) (GLenum array);
+   void         (*glEnableClientState) (GLenum array);
+   void         (*glFogx) (GLenum pname, GLfixed param);
+   void         (*glFogxv) (GLenum pname, const GLfixed *params);
+   void         (*glFrustumx) (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+   void         (*glGetClipPlanex) (GLenum pname, GLfixed eqn[4]);
+   void         (*glGetFixedv) (GLenum pname, GLfixed *params);
+   void         (*glGetLightxv) (GLenum light, GLenum pname, GLfixed *params);
+   void         (*glGetMaterialxv) (GLenum face, GLenum pname, GLfixed *params);
+   void         (*glGetPointerv) (GLenum pname, GLvoid **params);
+   void         (*glGetTexEnviv) (GLenum env, GLenum pname, GLint *params);
+   void         (*glGetTexEnvxv) (GLenum env, GLenum pname, GLfixed *params);
+   void         (*glGetTexParameterxv) (GLenum target, GLenum pname, GLfixed *params);
+   void         (*glLightModelx) (GLenum pname, GLfixed param);
+   void         (*glLightModelxv) (GLenum pname, const GLfixed *params);
+   void         (*glLightx) (GLenum light, GLenum pname, GLfixed param);
+   void         (*glLightxv) (GLenum light, GLenum pname, const GLfixed *params);
+   void         (*glLineWidthx) (GLfixed width);
+   void         (*glLoadIdentity) (void);
+   void         (*glLoadMatrixx) (const GLfixed *m);
+   void         (*glLogicOp) (GLenum opcode);
+   void         (*glMaterialx) (GLenum face, GLenum pname, GLfixed param);
+   void         (*glMaterialxv) (GLenum face, GLenum pname, const GLfixed *params);
+   void         (*glMatrixMode) (GLenum mode);
+   void         (*glMultMatrixx) (const GLfixed *m);
+   void         (*glMultiTexCoord4x) (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+   void         (*glNormal3x) (GLfixed nx, GLfixed ny, GLfixed nz);
+   void         (*glNormalPointer) (GLenum type, GLsizei stride, const GLvoid *pointer);
+   void         (*glOrthox) (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+   void         (*glPointParameterx) (GLenum pname, GLfixed param);
+   void         (*glPointParameterxv) (GLenum pname, const GLfixed *params);
+   void         (*glPointSizex) (GLfixed size);
+   void         (*glPolygonOffsetx) (GLfixed factor, GLfixed units);
+   void         (*glPopMatrix) (void);
+   void         (*glPushMatrix) (void);
+   void         (*glRotatex) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+   void         (*glSampleCoveragex) (GLclampx value, GLboolean invert);
+   void         (*glScalex) (GLfixed x, GLfixed y, GLfixed z);
+   void         (*glShadeModel) (GLenum mode);
+   void         (*glTexCoordPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+   void         (*glTexEnvi) (GLenum target, GLenum pname, GLint param);
+   void         (*glTexEnvx) (GLenum target, GLenum pname, GLfixed param);
+   void         (*glTexEnviv) (GLenum target, GLenum pname, const GLint *params);
+   void         (*glTexEnvxv) (GLenum target, GLenum pname, const GLfixed *params);
+   void         (*glTexParameterx) (GLenum target, GLenum pname, GLfixed param);
+   void         (*glTexParameterxv) (GLenum target, GLenum pname, const GLfixed *params);
+   void         (*glTranslatex) (GLfixed x, GLfixed y, GLfixed z);
+   void         (*glVertexPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+   /** @} */
+
+   /**
+    * @name OpenGL-ES 1.1 extensions
+    *
+    * Evas_GL_API version 2.
+    *
+    * OpenGL-ES 1.1 specifies a set of extensions on top of OpenGL-ES 1.0.
+    * When available, Evas GL will expose these extensions with the following
+    * function pointers.
+    * @{
+    */
+   /* GL_OES_blend_equation_separate */
+   void         (*glBlendEquationSeparateOES) (GLenum modeRGB, GLenum modeAlpha);
+
+   /* GL_OES_blend_func_separate */
+   void         (*glBlendFuncSeparateOES) (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+
+   /* GL_OES_blend_subtract */
+   void         (*glBlendEquationOES) (GLenum mode);
+
+   /* GL_OES_draw_texture */
+   void         (*glDrawTexsOES) (GLshort x, GLshort y, GLshort z, GLshort width, GLshort height);
+   void         (*glDrawTexiOES) (GLint x, GLint y, GLint z, GLint width, GLint height);
+   void         (*glDrawTexxOES) (GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height);
+   void         (*glDrawTexsvOES) (const GLshort *coords);
+   void         (*glDrawTexivOES) (const GLint *coords);
+   void         (*glDrawTexxvOES) (const GLfixed *coords);
+   void         (*glDrawTexfOES) (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
+   void         (*glDrawTexfvOES) (const GLfloat *coords);
+
+   /* GL_OES_fixed_point */
+   void         (*glAlphaFuncxOES) (GLenum func, GLclampx ref);
+   void         (*glClearColorxOES) (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
+   void         (*glClearDepthxOES) (GLclampx depth);
+   void         (*glClipPlanexOES) (GLenum plane, const GLfixed *equation);
+   void         (*glColor4xOES) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+   void         (*glDepthRangexOES) (GLclampx zNear, GLclampx zFar);
+   void         (*glFogxOES) (GLenum pname, GLfixed param);
+   void         (*glFogxvOES) (GLenum pname, const GLfixed *params);
+   void         (*glFrustumxOES) (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+   void         (*glGetClipPlanexOES) (GLenum pname, GLfixed eqn[4]);
+   void         (*glGetFixedvOES) (GLenum pname, GLfixed *params);
+   void         (*glGetLightxvOES) (GLenum light, GLenum pname, GLfixed *params);
+   void         (*glGetMaterialxvOES) (GLenum face, GLenum pname, GLfixed *params);
+   void         (*glGetTexEnvxvOES) (GLenum env, GLenum pname, GLfixed *params);
+   void         (*glGetTexParameterxvOES) (GLenum target, GLenum pname, GLfixed *params);
+   void         (*glLightModelxOES) (GLenum pname, GLfixed param);
+   void         (*glLightModelxvOES) (GLenum pname, const GLfixed *params);
+   void         (*glLightxOES) (GLenum light, GLenum pname, GLfixed param);
+   void         (*glLightxvOES) (GLenum light, GLenum pname, const GLfixed *params);
+   void         (*glLineWidthxOES) (GLfixed width);
+   void         (*glLoadMatrixxOES) (const GLfixed *m);
+   void         (*glMaterialxOES) (GLenum face, GLenum pname, GLfixed param);
+   void         (*glMaterialxvOES) (GLenum face, GLenum pname, const GLfixed *params);
+   void         (*glMultMatrixxOES) (const GLfixed *m);
+   void         (*glMultiTexCoord4xOES) (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+   void         (*glNormal3xOES) (GLfixed nx, GLfixed ny, GLfixed nz);
+   void         (*glOrthoxOES) (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+   void         (*glPointParameterxOES) (GLenum pname, GLfixed param);
+   void         (*glPointParameterxvOES) (GLenum pname, const GLfixed *params);
+   void         (*glPointSizexOES) (GLfixed size);
+   void         (*glPolygonOffsetxOES) (GLfixed factor, GLfixed units);
+   void         (*glRotatexOES) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+   void         (*glSampleCoveragexOES) (GLclampx value, GLboolean invert);
+   void         (*glScalexOES) (GLfixed x, GLfixed y, GLfixed z);
+   void         (*glTexEnvxOES) (GLenum target, GLenum pname, GLfixed param);
+   void         (*glTexEnvxvOES) (GLenum target, GLenum pname, const GLfixed *params);
+   void         (*glTexParameterxOES) (GLenum target, GLenum pname, GLfixed param);
+   void         (*glTexParameterxvOES) (GLenum target, GLenum pname, const GLfixed *params);
+   void         (*glTranslatexOES) (GLfixed x, GLfixed y, GLfixed z);
+
+   /* GL_OES_framebuffer_object */
+   GLboolean    (*glIsRenderbufferOES) (GLuint renderbuffer);
+   void         (*glBindRenderbufferOES) (GLenum target, GLuint renderbuffer);
+   void         (*glDeleteRenderbuffersOES) (GLsizei n, const GLuint* renderbuffers);
+   void         (*glGenRenderbuffersOES) (GLsizei n, GLuint* renderbuffers);
+   void         (*glRenderbufferStorageOES) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+   void         (*glGetRenderbufferParameterivOES) (GLenum target, GLenum pname, GLint* params);
+   GLboolean    (*glIsFramebufferOES) (GLuint framebuffer);
+   void         (*glBindFramebufferOES) (GLenum target, GLuint framebuffer);
+   void         (*glDeleteFramebuffersOES) (GLsizei n, const GLuint* framebuffers);
+   void         (*glGenFramebuffersOES) (GLsizei n, GLuint* framebuffers);
+   GLenum       (*glCheckFramebufferStatusOES) (GLenum target);
+   void         (*glFramebufferRenderbufferOES) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+   void         (*glFramebufferTexture2DOES) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+   void         (*glGetFramebufferAttachmentParameterivOES) (GLenum target, GLenum attachment, GLenum pname, GLint* params);
+   void         (*glGenerateMipmapOES) (GLenum target);
+
+   /* GL_OES_matrix_palette */
+   void         (*glCurrentPaletteMatrixOES) (GLuint matrixpaletteindex);
+   void         (*glLoadPaletteFromModelViewMatrixOES) (void);
+   void         (*glMatrixIndexPointerOES) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+   void         (*glWeightPointerOES) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+
+   /* GL_OES_query_matrix */
+   GLbitfield   (*glQueryMatrixxOES) (GLfixed mantissa[16], GLint exponent[16]);
+
+   /* GL_OES_single_precision */
+   void         (*glDepthRangefOES) (GLclampf zNear, GLclampf zFar);
+   void         (*glFrustumfOES) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+   void         (*glOrthofOES) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+   void         (*glClipPlanefOES) (GLenum plane, const GLfloat *equation);
+   void         (*glGetClipPlanefOES) (GLenum pname, GLfloat eqn[4]);
+   void         (*glClearDepthfOES) (GLclampf depth);
+
+   /* GL_OES_texture_cube_map */
+   void         (*glTexGenfOES) (GLenum coord, GLenum pname, GLfloat param);
+   void         (*glTexGenfvOES) (GLenum coord, GLenum pname, const GLfloat *params);
+   void         (*glTexGeniOES) (GLenum coord, GLenum pname, GLint param);
+   void         (*glTexGenivOES) (GLenum coord, GLenum pname, const GLint *params);
+   void         (*glTexGenxOES) (GLenum coord, GLenum pname, GLfixed param);
+   void         (*glTexGenxvOES) (GLenum coord, GLenum pname, const GLfixed *params);
+   void         (*glGetTexGenfvOES) (GLenum coord, GLenum pname, GLfloat *params);
+   void         (*glGetTexGenivOES) (GLenum coord, GLenum pname, GLint *params);
+   void         (*glGetTexGenxvOES) (GLenum coord, GLenum pname, GLfixed *params);
+
+   /* GL_OES_vertex_array_object */
+   void         (*glBindVertexArrayOES) (GLuint array);
+   void         (*glDeleteVertexArraysOES) (GLsizei n, const GLuint *arrays);
+   void         (*glGenVertexArraysOES) (GLsizei n, GLuint *arrays);
+   GLboolean    (*glIsVertexArrayOES) (GLuint array);
+
+   /* GL_APPLE_copy_texture_levels */
+   void         (*glCopyTextureLevelsAPPLE) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount);
+   void         (*glRenderbufferStorageMultisampleAPPLE) (GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+   void         (*glResolveMultisampleFramebufferAPPLE) (void);
+   GLsync       (*glFenceSyncAPPLE) (GLenum condition, GLbitfield flags);
+   GLboolean    (*glIsSyncAPPLE) (GLsync sync);
+   void         (*glDeleteSyncAPPLE) (GLsync sync);
+   GLenum       (*glClientWaitSyncAPPLE) (GLsync sync, GLbitfield flags, EvasGLuint64 timeout);
+   void         (*glWaitSyncAPPLE) (GLsync sync, GLbitfield flags, EvasGLuint64 timeout);
+   void         (*glGetInteger64vAPPLE) (GLenum pname, EvasGLint64 *params);
+   void         (*glGetSyncivAPPLE) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+
+   /* GL_EXT_map_buffer_range */
+   void*        (*glMapBufferRangeEXT) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+   void         (*glFlushMappedBufferRangeEXT) (GLenum target, GLintptr offset, GLsizeiptr length);
+
+   /* GL_EXT_multisampled_render_to_texture */
+   void         (*glRenderbufferStorageMultisampleEXT) (GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+   void         (*glFramebufferTexture2DMultisampleEXT) (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei);
+
+   /* GL_EXT_robustness */
+   GLenum       (*glGetGraphicsResetStatusEXT) (void);
+   void         (*glReadnPixelsEXT) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+   void         (*glGetnUniformfvEXT) (GLuint program, GLint location, GLsizei bufSize, float *params);
+   void         (*glGetnUniformivEXT) (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+
+   /* GL_EXT_texture_storage */
+   void         (*glTexStorage1DEXT) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+   void         (*glTexStorage2DEXT) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+   void         (*glTexStorage3DEXT) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+   void         (*glTextureStorage1DEXT) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+   void         (*glTextureStorage2DEXT) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+   void         (*glTextureStorage3DEXT) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+
+   /* GL_IMG_user_clip_plane */
+   void         (*glClipPlanefIMG) (GLenum, const GLfloat *);
+   void         (*glClipPlanexIMG) (GLenum, const GLfixed *);
+
+   /* GL_IMG_multisampled_render_to_texture */
+   void         (*glRenderbufferStorageMultisampleIMG) (GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+   void         (*glFramebufferTexture2DMultisampleIMG) (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei);
+
+   /* GL_QCOM_tiled_rendering */
+   void         (*glStartTilingQCOM) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+   void         (*glEndTilingQCOM) (GLbitfield preserveMask);
+
+
+   /*------- EvasGL / EGL-related functions -------*/
+   /**
+    * @name Evas GL Sync object functions
+    * @if MOBILE @since_tizen 2.3
+    * @elseif WEARABLE @since_tizen 2.3.1
+    * @endif
+    * @{ */
+   /**
+    * @anchor evasglCreateSync
+    * @brief Requires the extension @c EGL_KHR_fence_sync, similar to eglCreateSyncKHR.
+    */
+   EvasGLSync   (*evasglCreateSync) (Evas_GL *evas_gl, unsigned int type, const int *attrib_list);
+   /** @anchor evasglDestroySync
+    * @brief Requires the extension @c EGL_KHR_fence_sync, similar to eglDestroySyncKHR.
+    */
+   Eina_Bool    (*evasglDestroySync) (Evas_GL *evas_gl, EvasGLSync sync);
+   /** @anchor evasglClientWaitSync
+    * @brief Requires the extension @c EGL_KHR_fence_sync, similar to eglClientWaitSyncKHR.
+    */
+   int          (*evasglClientWaitSync) (Evas_GL *evas_gl, EvasGLSync sync, int flags, EvasGLTime timeout);
+   /** @anchor evasglSignalSync
+    * @brief Requires the extension @c EGL_KHR_reusable_sync, similar to eglSignalSyncKHR.
+    */
+   Eina_Bool    (*evasglSignalSync) (Evas_GL *evas_gl, EvasGLSync sync, unsigned mode);
+   /** @anchor evasglGetSyncAttrib
+    * @brief Requires the extension @c EGL_KHR_fence_sync, similar to eglGetSyncAttribKHR.
+    */
+   Eina_Bool    (*evasglGetSyncAttrib) (Evas_GL *evas_gl, EvasGLSync sync, int attribute, int *value);
+   /** @anchor evasglWaitSync
+    * @brief Requires the extension @c EGL_KHR_wait_sync, similar to eglWaitSyncKHR.
+    */
+   int          (*evasglWaitSync) (Evas_GL *evas_gl, EvasGLSync sync, int flags);
+   /** @} */
+
    /* future calls will be added down here for expansion */
-   /* version 2: */
 };
 
 
diff --git a/src/lib/Evas_GL_GLES1_Helpers.h b/src/lib/Evas_GL_GLES1_Helpers.h
new file mode 100644 (file)
index 0000000..5bdc73a
--- /dev/null
@@ -0,0 +1,508 @@
+/**
+ * @file Evas_GL_GLES1_Helpers.h
+ * @defgroup Evas_GL_GLES1_Helpers Evas GL GLES1 helpers
+ * @ingroup Evas_GL
+ */
+
+/**
+ * @brief Provides a set of helper functions and macros to use GLES 1.1 with
+ * @ref Evas_GL "Evas GL".
+ *
+ * This file redefines all the OpenGL-ES 1.1 functions as follow:
+ * @code
+#define glFunction  __evas_gl_glapi->glFunction
+ * @endcode
+ *
+ * Extension functions can then be checked for existence simply by writing:
+ * @code
+if (glExtensionFunction)
+  {
+     ...
+     glExtensionFunction(...);
+     ...
+  }
+ * @endcode
+ *
+ * When using Elementary @ref GLView, please include the header file
+ * @ref Elementary_GL_Helpers "Elementary_GL_Helpers.h" instead.
+ *
+ * This header file should be included when using @ref Evas_GL "Evas GL"
+ * directly at a low level and with an OpenGL-ES 1.1 context only.
+ *
+ * @note When this file is included, all @c glFunctions are now macros, which
+ *       means that the @ref Evas_GL_API struct can't be used anyore.
+ *
+ * @see @ref elm_opengl_page
+ */
+#ifndef _EVAS_GL_GLES1_HELPERS_H
+#define _EVAS_GL_GLES1_HELPERS_H
+
+#include <Evas_GL.h>
+
+
+// local convenience macros
+
+/**
+ * @addtogroup Evas_GL_GLES1_Helpers
+ * @{
+ */
+
+/**
+ * @brief Macro to place at the beginning of any function using GLES 1.1 APIs
+ *
+ * Normally, it is necessary to call each function using its pointer as in:
+ * @code
+glapi->glFunction();
+ * @endcode
+ *
+ * When using this macro, developers can then call all @c glFunctions without
+ * changing their code:
+ * @code
+EVAS_GL_GLES1_USE(evasgl, context); // Add this at the beginning
+glFunction(); // All calls 'look' normal
+ * @endcode
+ *
+ * @note Please use @ref ELEMENTARY_GLVIEW_USE() instead, when possible.
+ * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ */
+#define EVAS_GL_GLES1_USE(evasgl, context) \
+   Evas_GL_API *__evas_gl_glapi = evas_gl_context_api_get(evasgl, context);
+
+/**
+ * @brief Macro to place at the beginning of any function using GLES 1.1 APIs
+ *
+ * This is similar to @ref EVAS_GL_GLES1_USE except that it will return from
+ * the function if the GL API can not be used.
+ *
+ * @note Please use @ref ELEMENTARY_GLVIEW_USE() instead, when possible.
+ * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ */
+#define EVAS_GL_GLES1_USE_OR_RETURN(evasgl, context, retval) \
+   Evas_GL_API *__evas_gl_glapi = evas_gl_context_api_get(evasgl, context); \
+   if (!__evas_gl_glapi) return retval;
+
+// End of the convenience functions
+
+// Global convenience macros
+
+/**
+ * @brief Convenience macro to use the GL helpers in simple applications: declare
+ *
+ * @c EVAS_GL_GLOBAL_GLES1_DECLARE should be used in a global header for the
+ * application. For example, in a platform-specific compatibility header file.
+ *
+ * To be used with OpenGL-ES 1.1 contexts.
+ *
+ * Example of a global header file @c main.h:
+ * @code
+#include <Evas_GL_GLES1_Helpers.h>
+// other includes...
+
+EVAS_GL_GLOBAL_GLES1_DECLARE()
+
+// ...
+ * @endcode
+ *
+ * @note Please use @ref ELEMENTARY_GLVIEW_USE() instead, when possible.
+ *
+ * @see @ref ELEMENTARY_GLVIEW_GLOBAL_DECLARE
+ * @see @ref EVAS_GL_GLOBAL_GLES1_DEFINE
+ * @see @ref EVAS_GL_GLOBAL_GLES1_USE
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ */
+#define EVAS_GL_GLOBAL_GLES1_DECLARE() \
+   extern Evas_GL_API *__evas_gl_glapi;
+
+/**
+ * @brief Convenience macro to use the GL helpers in simple applications: define
+ *
+ * To be used with OpenGL-ES 1.1 contexts.
+ *
+ * Example of a file @c glview.c:
+ *
+ * @code
+#include "main.h"
+EVAS_GL_GLOBAL_GLES1_DEFINE()
+
+// ...
+
+static inline void
+evgl_init(...)
+{
+   // ...
+   evasgl = evas_gl_new(canvas);
+   // ...
+   ctx = evas_gl_context_version_create(evasgl, NULL, EVAS_GL_GLES_1_X);
+   EVAS_GL_GLOBAL_GLES1_USE(evasgl, ctx);
+   // ...
+}
+
+// ...
+ * @endcode
+ *
+ * @see @ref ELEMENTARY_GLVIEW_GLOBAL_DEFINE
+ * @see @ref EVAS_GL_GLOBAL_GLES1_DECLARE
+ * @see @ref EVAS_GL_GLOBAL_GLES1_USE
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ */
+#define EVAS_GL_GLOBAL_GLES1_DEFINE() \
+   Evas_GL_API *__evas_gl_glapi = NULL;
+
+/**
+ * @brief Convenience macro to use the GL helpers in simple applications: use
+ *
+ * This macro will set the global variable holding the GL API so that it's
+ * available to the application.
+ *
+ * It should be used right after setting up the GL context object.
+ *
+ * @see @ref ELEMENTARY_GLVIEW_GLOBAL_USE
+ * @see @ref EVAS_GL_GLOBAL_GLES1_DECLARE
+ * @see @ref EVAS_GL_GLOBAL_GLES1_DEFINE
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ */
+#define EVAS_GL_GLOBAL_GLES1_USE(evgl, ctx) \
+   do { __evas_gl_glapi = evas_gl_context_api_get(evgl, ctx); } while (0)
+
+
+// End of the convenience functions (global)
+/** @} */
+
+#define glAlphaFunc                                __evas_gl_glapi->glAlphaFunc
+#define glClearColor                               __evas_gl_glapi->glClearColor
+#define glClearDepthf                              __evas_gl_glapi->glClearDepthf
+#define glClipPlanef                               __evas_gl_glapi->glClipPlanef
+#define glColor4f                                  __evas_gl_glapi->glColor4f
+#define glDepthRangef                              __evas_gl_glapi->glDepthRangef
+#define glFogf                                     __evas_gl_glapi->glFogf
+#define glFogfv                                    __evas_gl_glapi->glFogfv
+#define glFrustumf                                 __evas_gl_glapi->glFrustumf
+#define glGetClipPlanef                            __evas_gl_glapi->glGetClipPlanef
+#define glGetFloatv                                __evas_gl_glapi->glGetFloatv
+#define glGetLightfv                               __evas_gl_glapi->glGetLightfv
+#define glGetMaterialfv                            __evas_gl_glapi->glGetMaterialfv
+#define glGetTexEnvfv                              __evas_gl_glapi->glGetTexEnvfv
+#define glGetTexParameterfv                        __evas_gl_glapi->glGetTexParameterfv
+#define glLightModelf                              __evas_gl_glapi->glLightModelf
+#define glLightModelfv                             __evas_gl_glapi->glLightModelfv
+#define glLightf                                   __evas_gl_glapi->glLightf
+#define glLightfv                                  __evas_gl_glapi->glLightfv
+#define glLineWidth                                __evas_gl_glapi->glLineWidth
+#define glLoadMatrixf                              __evas_gl_glapi->glLoadMatrixf
+#define glMaterialf                                __evas_gl_glapi->glMaterialf
+#define glMaterialfv                               __evas_gl_glapi->glMaterialfv
+#define glMultMatrixf                              __evas_gl_glapi->glMultMatrixf
+#define glMultiTexCoord4f                          __evas_gl_glapi->glMultiTexCoord4f
+#define glNormal3f                                 __evas_gl_glapi->glNormal3f
+#define glOrthof                                   __evas_gl_glapi->glOrthof
+#define glPointParameterf                          __evas_gl_glapi->glPointParameterf
+#define glPointParameterfv                         __evas_gl_glapi->glPointParameterfv
+#define glPointSize                                __evas_gl_glapi->glPointSize
+#define glPolygonOffset                            __evas_gl_glapi->glPolygonOffset
+#define glRotatef                                  __evas_gl_glapi->glRotatef
+#define glScalef                                   __evas_gl_glapi->glScalef
+#define glTexEnvf                                  __evas_gl_glapi->glTexEnvf
+#define glTexEnvfv                                 __evas_gl_glapi->glTexEnvfv
+#define glTexParameterf                            __evas_gl_glapi->glTexParameterf
+#define glTexParameterfv                           __evas_gl_glapi->glTexParameterfv
+#define glTranslatef                               __evas_gl_glapi->glTranslatef
+#define glActiveTexture                            __evas_gl_glapi->glActiveTexture
+#define glAlphaFuncx                               __evas_gl_glapi->glAlphaFuncx
+#define glBindBuffer                               __evas_gl_glapi->glBindBuffer
+#define glBindTexture                              __evas_gl_glapi->glBindTexture
+#define glBlendFunc                                __evas_gl_glapi->glBlendFunc
+#define glBufferData                               __evas_gl_glapi->glBufferData
+#define glBufferSubData                            __evas_gl_glapi->glBufferSubData
+#define glClear                                    __evas_gl_glapi->glClear
+#define glClearColorx                              __evas_gl_glapi->glClearColorx
+#define glClearDepthx                              __evas_gl_glapi->glClearDepthx
+#define glClearStencil                             __evas_gl_glapi->glClearStencil
+#define glClientActiveTexture                      __evas_gl_glapi->glClientActiveTexture
+#define glClipPlanex                               __evas_gl_glapi->glClipPlanex
+#define glColor4ub                                 __evas_gl_glapi->glColor4ub
+#define glColor4x                                  __evas_gl_glapi->glColor4x
+#define glColorMask                                __evas_gl_glapi->glColorMask
+#define glColorPointer                             __evas_gl_glapi->glColorPointer
+#define glCompressedTexImage2D                     __evas_gl_glapi->glCompressedTexImage2D
+#define glCompressedTexSubImage2D                  __evas_gl_glapi->glCompressedTexSubImage2D
+#define glCopyTexImage2D                           __evas_gl_glapi->glCopyTexImage2D
+#define glCopyTexSubImage2D                        __evas_gl_glapi->glCopyTexSubImage2D
+#define glCullFace                                 __evas_gl_glapi->glCullFace
+#define glDeleteBuffers                            __evas_gl_glapi->glDeleteBuffers
+#define glDeleteTextures                           __evas_gl_glapi->glDeleteTextures
+#define glDepthFunc                                __evas_gl_glapi->glDepthFunc
+#define glDepthMask                                __evas_gl_glapi->glDepthMask
+#define glDepthRangex                              __evas_gl_glapi->glDepthRangex
+#define glDisable                                  __evas_gl_glapi->glDisable
+#define glDisableClientState                       __evas_gl_glapi->glDisableClientState
+#define glDrawArrays                               __evas_gl_glapi->glDrawArrays
+#define glDrawElements                             __evas_gl_glapi->glDrawElements
+#define glEnable                                   __evas_gl_glapi->glEnable
+#define glEnableClientState                        __evas_gl_glapi->glEnableClientState
+#define glFinish                                   __evas_gl_glapi->glFinish
+#define glFlush                                    __evas_gl_glapi->glFlush
+#define glFogx                                     __evas_gl_glapi->glFogx
+#define glFogxv                                    __evas_gl_glapi->glFogxv
+#define glFrontFace                                __evas_gl_glapi->glFrontFace
+#define glFrustumx                                 __evas_gl_glapi->glFrustumx
+#define glGetBooleanv                              __evas_gl_glapi->glGetBooleanv
+#define glGetBufferParameteriv                     __evas_gl_glapi->glGetBufferParameteriv
+#define glGetClipPlanex                            __evas_gl_glapi->glGetClipPlanex
+#define glGenBuffers                               __evas_gl_glapi->glGenBuffers
+#define glGenTextures                              __evas_gl_glapi->glGenTextures
+#define glGetError                                 __evas_gl_glapi->glGetError
+#define glGetFixedv                                __evas_gl_glapi->glGetFixedv
+#define glGetIntegerv                              __evas_gl_glapi->glGetIntegerv
+#define glGetLightxv                               __evas_gl_glapi->glGetLightxv
+#define glGetMaterialxv                            __evas_gl_glapi->glGetMaterialxv
+#define glGetPointerv                              __evas_gl_glapi->glGetPointerv
+#define glGetString                                __evas_gl_glapi->glGetString
+#define glGetTexEnviv                              __evas_gl_glapi->glGetTexEnviv
+#define glGetTexEnvxv                              __evas_gl_glapi->glGetTexEnvxv
+#define glGetTexParameteriv                        __evas_gl_glapi->glGetTexParameteriv
+#define glGetTexParameterxv                        __evas_gl_glapi->glGetTexParameterxv
+#define glHint                                     __evas_gl_glapi->glHint
+#define glIsBuffer                                 __evas_gl_glapi->glIsBuffer
+#define glIsEnabled                                __evas_gl_glapi->glIsEnabled
+#define glIsTexture                                __evas_gl_glapi->glIsTexture
+#define glLightModelx                              __evas_gl_glapi->glLightModelx
+#define glLightModelxv                             __evas_gl_glapi->glLightModelxv
+#define glLightx                                   __evas_gl_glapi->glLightx
+#define glLightxv                                  __evas_gl_glapi->glLightxv
+#define glLineWidthx                               __evas_gl_glapi->glLineWidthx
+#define glLoadIdentity                             __evas_gl_glapi->glLoadIdentity
+#define glLoadMatrixx                              __evas_gl_glapi->glLoadMatrixx
+#define glLogicOp                                  __evas_gl_glapi->glLogicOp
+#define glMaterialx                                __evas_gl_glapi->glMaterialx
+#define glMaterialxv                               __evas_gl_glapi->glMaterialxv
+#define glMatrixMode                               __evas_gl_glapi->glMatrixMode
+#define glMultMatrixx                              __evas_gl_glapi->glMultMatrixx
+#define glMultiTexCoord4x                          __evas_gl_glapi->glMultiTexCoord4x
+#define glNormal3x                                 __evas_gl_glapi->glNormal3x
+#define glNormalPointer                            __evas_gl_glapi->glNormalPointer
+#define glOrthox                                   __evas_gl_glapi->glOrthox
+#define glPixelStorei                              __evas_gl_glapi->glPixelStorei
+#define glPointParameterx                          __evas_gl_glapi->glPointParameterx
+#define glPointParameterxv                         __evas_gl_glapi->glPointParameterxv
+#define glPointSizex                               __evas_gl_glapi->glPointSizex
+#define glPolygonOffsetx                           __evas_gl_glapi->glPolygonOffsetx
+#define glPopMatrix                                __evas_gl_glapi->glPopMatrix
+#define glPushMatrix                               __evas_gl_glapi->glPushMatrix
+#define glReadPixels                               __evas_gl_glapi->glReadPixels
+#define glRotatex                                  __evas_gl_glapi->glRotatex
+#define glSampleCoverage                           __evas_gl_glapi->glSampleCoverage
+#define glSampleCoveragex                          __evas_gl_glapi->glSampleCoveragex
+#define glScalex                                   __evas_gl_glapi->glScalex
+#define glScissor                                  __evas_gl_glapi->glScissor
+#define glShadeModel                               __evas_gl_glapi->glShadeModel
+#define glStencilFunc                              __evas_gl_glapi->glStencilFunc
+#define glStencilMask                              __evas_gl_glapi->glStencilMask
+#define glStencilOp                                __evas_gl_glapi->glStencilOp
+#define glTexCoordPointer                          __evas_gl_glapi->glTexCoordPointer
+#define glTexEnvi                                  __evas_gl_glapi->glTexEnvi
+#define glTexEnvx                                  __evas_gl_glapi->glTexEnvx
+#define glTexEnviv                                 __evas_gl_glapi->glTexEnviv
+#define glTexEnvxv                                 __evas_gl_glapi->glTexEnvxv
+#define glTexImage2D                               __evas_gl_glapi->glTexImage2D
+#define glTexParameteri                            __evas_gl_glapi->glTexParameteri
+#define glTexParameterx                            __evas_gl_glapi->glTexParameterx
+#define glTexParameteriv                           __evas_gl_glapi->glTexParameteriv
+#define glTexParameterxv                           __evas_gl_glapi->glTexParameterxv
+#define glTexSubImage2D                            __evas_gl_glapi->glTexSubImage2D
+#define glTranslatex                               __evas_gl_glapi->glTranslatex
+#define glVertexPointer                            __evas_gl_glapi->glVertexPointer
+#define glViewport                                 __evas_gl_glapi->glViewport
+
+// GLES 1.0 extensions
+#define glPointSizePointerOES                      __evas_gl_glapi->glPointSizePointerOES
+
+// GLES 1.1 extensions
+#define glBlendEquationSeparateOES                 __evas_gl_glapi->glBlendEquationSeparateOES
+#define glBlendFuncSeparateOES                     __evas_gl_glapi->glBlendFuncSeparateOES
+#define glBlendEquationOES                         __evas_gl_glapi->glBlendEquationOES
+#define glDrawTexsOES                              __evas_gl_glapi->glDrawTexsOES
+#define glDrawTexiOES                              __evas_gl_glapi->glDrawTexiOES
+#define glDrawTexxOES                              __evas_gl_glapi->glDrawTexxOES
+#define glDrawTexsvOES                             __evas_gl_glapi->glDrawTexsvOES
+#define glDrawTexivOES                             __evas_gl_glapi->glDrawTexivOES
+#define glDrawTexxvOES                             __evas_gl_glapi->glDrawTexxvOES
+#define glDrawTexfOES                              __evas_gl_glapi->glDrawTexfOES
+#define glDrawTexfvOES                             __evas_gl_glapi->glDrawTexfvOES
+#define glEGLImageTargetTexture2DOES               __evas_gl_glapi->glEGLImageTargetTexture2DOES
+#define glEGLImageTargetRenderbufferStorageOES     __evas_gl_glapi->glEGLImageTargetRenderbufferStorageOES
+#define glAlphaFuncxOES                            __evas_gl_glapi->glAlphaFuncxOES
+#define glClearColorxOES                           __evas_gl_glapi->glClearColorxOES
+#define glClearDepthxOES                           __evas_gl_glapi->glClearDepthxOES
+#define glClipPlanexOES                            __evas_gl_glapi->glClipPlanexOES
+#define glColor4xOES                               __evas_gl_glapi->glColor4xOES
+#define glDepthRangexOES                           __evas_gl_glapi->glDepthRangexOES
+#define glFogxOES                                  __evas_gl_glapi->glFogxOES
+#define glFogxvOES                                 __evas_gl_glapi->glFogxvOES
+#define glFrustumxOES                              __evas_gl_glapi->glFrustumxOES
+#define glGetClipPlanexOES                         __evas_gl_glapi->glGetClipPlanexOES
+#define glGetFixedvOES                             __evas_gl_glapi->glGetFixedvOES
+#define glGetLightxvOES                            __evas_gl_glapi->glGetLightxvOES
+#define glGetMaterialxvOES                         __evas_gl_glapi->glGetMaterialxvOES
+#define glGetTexEnvxvOES                           __evas_gl_glapi->glGetTexEnvxvOES
+#define glGetTexParameterxvOES                     __evas_gl_glapi->glGetTexParameterxvOES
+#define glLightModelxOES                           __evas_gl_glapi->glLightModelxOES
+#define glLightModelxvOES                          __evas_gl_glapi->glLightModelxvOES
+#define glLightxOES                                __evas_gl_glapi->glLightxOES
+#define glLightxvOES                               __evas_gl_glapi->glLightxvOES
+#define glLineWidthxOES                            __evas_gl_glapi->glLineWidthxOES
+#define glLoadMatrixxOES                           __evas_gl_glapi->glLoadMatrixxOES
+#define glMaterialxOES                             __evas_gl_glapi->glMaterialxOES
+#define glMaterialxvOES                            __evas_gl_glapi->glMaterialxvOES
+#define glMultMatrixxOES                           __evas_gl_glapi->glMultMatrixxOES
+#define glMultiTexCoord4xOES                       __evas_gl_glapi->glMultiTexCoord4xOES
+#define glNormal3xOES                              __evas_gl_glapi->glNormal3xOES
+#define glOrthoxOES                                __evas_gl_glapi->glOrthoxOES
+#define glPointParameterxOES                       __evas_gl_glapi->glPointParameterxOES
+#define glPointParameterxvOES                      __evas_gl_glapi->glPointParameterxvOES
+#define glPointSizexOES                            __evas_gl_glapi->glPointSizexOES
+#define glPolygonOffsetxOES                        __evas_gl_glapi->glPolygonOffsetxOES
+#define glRotatexOES                               __evas_gl_glapi->glRotatexOES
+#define glSampleCoveragexOES                       __evas_gl_glapi->glSampleCoveragexOES
+#define glScalexOES                                __evas_gl_glapi->glScalexOES
+#define glTexEnvxOES                               __evas_gl_glapi->glTexEnvxOES
+#define glTexEnvxvOES                              __evas_gl_glapi->glTexEnvxvOES
+#define glTexParameterxOES                         __evas_gl_glapi->glTexParameterxOES
+#define glTexParameterxvOES                        __evas_gl_glapi->glTexParameterxvOES
+#define glTranslatexOES                            __evas_gl_glapi->glTranslatexOES
+#define glIsRenderbufferOES                        __evas_gl_glapi->glIsRenderbufferOES
+#define glBindRenderbufferOES                      __evas_gl_glapi->glBindRenderbufferOES
+#define glDeleteRenderbuffersOES                   __evas_gl_glapi->glDeleteRenderbuffersOES
+#define glGenRenderbuffersOES                      __evas_gl_glapi->glGenRenderbuffersOES
+#define glRenderbufferStorageOES                   __evas_gl_glapi->glRenderbufferStorageOES
+#define glGetRenderbufferParameterivOES            __evas_gl_glapi->glGetRenderbufferParameterivOES
+#define glIsFramebufferOES                         __evas_gl_glapi->glIsFramebufferOES
+#define glBindFramebufferOES                       __evas_gl_glapi->glBindFramebufferOES
+#define glDeleteFramebuffersOES                    __evas_gl_glapi->glDeleteFramebuffersOES
+#define glGenFramebuffersOES                       __evas_gl_glapi->glGenFramebuffersOES
+#define glCheckFramebufferStatusOES                __evas_gl_glapi->glCheckFramebufferStatusOES
+#define glFramebufferRenderbufferOES               __evas_gl_glapi->glFramebufferRenderbufferOES
+#define glFramebufferTexture2DOES                  __evas_gl_glapi->glFramebufferTexture2DOES
+#define glGetFramebufferAttachmentParameterivOES   __evas_gl_glapi->glGetFramebufferAttachmentParameterivOES
+#define glGenerateMipmapOES                        __evas_gl_glapi->glGenerateMipmapOES
+#define glMapBufferOES                             __evas_gl_glapi->glMapBufferOES
+#define glUnmapBufferOES                           __evas_gl_glapi->glUnmapBufferOES
+#define glGetBufferPointervOES                     __evas_gl_glapi->glGetBufferPointervOES
+#define glCurrentPaletteMatrixOES                  __evas_gl_glapi->glCurrentPaletteMatrixOES
+#define glLoadPaletteFromModelViewMatrixOES        __evas_gl_glapi->glLoadPaletteFromModelViewMatrixOES
+#define glMatrixIndexPointerOES                    __evas_gl_glapi->glMatrixIndexPointerOES
+#define glWeightPointerOES                         __evas_gl_glapi->glWeightPointerOES
+#define glQueryMatrixxOES                          __evas_gl_glapi->glQueryMatrixxOES
+#define glDepthRangefOES                           __evas_gl_glapi->glDepthRangefOES
+#define glFrustumfOES                              __evas_gl_glapi->glFrustumfOES
+#define glOrthofOES                                __evas_gl_glapi->glOrthofOES
+#define glClipPlanefOES                            __evas_gl_glapi->glClipPlanefOES
+#define glGetClipPlanefOES                         __evas_gl_glapi->glGetClipPlanefOES
+#define glClearDepthfOES                           __evas_gl_glapi->glClearDepthfOES
+#define glTexGenfOES                               __evas_gl_glapi->glTexGenfOES
+#define glTexGenfvOES                              __evas_gl_glapi->glTexGenfvOES
+#define glTexGeniOES                               __evas_gl_glapi->glTexGeniOES
+#define glTexGenivOES                              __evas_gl_glapi->glTexGenivOES
+#define glTexGenxOES                               __evas_gl_glapi->glTexGenxOES
+#define glTexGenxvOES                              __evas_gl_glapi->glTexGenxvOES
+#define glGetTexGenfvOES                           __evas_gl_glapi->glGetTexGenfvOES
+#define glGetTexGenivOES                           __evas_gl_glapi->glGetTexGenivOES
+#define glGetTexGenxvOES                           __evas_gl_glapi->glGetTexGenxvOES
+#define glBindVertexArrayOES                       __evas_gl_glapi->glBindVertexArrayOES
+#define glDeleteVertexArraysOES                    __evas_gl_glapi->glDeleteVertexArraysOES
+#define glGenVertexArraysOES                       __evas_gl_glapi->glGenVertexArraysOES
+#define glIsVertexArrayOES                         __evas_gl_glapi->glIsVertexArrayOES
+#define glCopyTextureLevelsAPPLE                   __evas_gl_glapi->glCopyTextureLevelsAPPLE
+#define glRenderbufferStorageMultisampleAPPLE      __evas_gl_glapi->glRenderbufferStorageMultisampleAPPLE
+#define glResolveMultisampleFramebufferAPPLE       __evas_gl_glapi->glResolveMultisampleFramebufferAPPLE
+#define glFenceSyncAPPLE                           __evas_gl_glapi->glFenceSyncAPPLE
+#define glIsSyncAPPLE                              __evas_gl_glapi->glIsSyncAPPLE
+#define glDeleteSyncAPPLE                          __evas_gl_glapi->glDeleteSyncAPPLE
+#define glClientWaitSyncAPPLE                      __evas_gl_glapi->glClientWaitSyncAPPLE
+#define glWaitSyncAPPLE                            __evas_gl_glapi->glWaitSyncAPPLE
+#define glGetInteger64vAPPLE                       __evas_gl_glapi->glGetInteger64vAPPLE
+#define glGetSyncivAPPLE                           __evas_gl_glapi->glGetSyncivAPPLE
+#define glDiscardFramebufferEXT                    __evas_gl_glapi->glDiscardFramebufferEXT
+#define glMapBufferRangeEXT                        __evas_gl_glapi->glMapBufferRangeEXT
+#define glFlushMappedBufferRangeEXT                __evas_gl_glapi->glFlushMappedBufferRangeEXT
+#define glRenderbufferStorageMultisampleEXT        __evas_gl_glapi->glRenderbufferStorageMultisampleEXT
+#define glFramebufferTexture2DMultisampleEXT       __evas_gl_glapi->glFramebufferTexture2DMultisampleEXT
+#define glMultiDrawArraysEXT                       __evas_gl_glapi->glMultiDrawArraysEXT
+#define glMultiDrawElementsEXT                     __evas_gl_glapi->glMultiDrawElementsEXT
+#define glGetGraphicsResetStatusEXT                __evas_gl_glapi->glGetGraphicsResetStatusEXT
+#define glReadnPixelsEXT                           __evas_gl_glapi->glReadnPixelsEXT
+#define glGetnUniformfvEXT                         __evas_gl_glapi->glGetnUniformfvEXT
+#define glGetnUniformivEXT                         __evas_gl_glapi->glGetnUniformivEXT
+#define glTexStorage1DEXT                          __evas_gl_glapi->glTexStorage1DEXT
+#define glTexStorage2DEXT                          __evas_gl_glapi->glTexStorage2DEXT
+#define glTexStorage3DEXT                          __evas_gl_glapi->glTexStorage3DEXT
+#define glTextureStorage1DEXT                      __evas_gl_glapi->glTextureStorage1DEXT
+#define glTextureStorage2DEXT                      __evas_gl_glapi->glTextureStorage2DEXT
+#define glTextureStorage3DEXT                      __evas_gl_glapi->glTextureStorage3DEXT
+#define glClipPlanefIMG                            __evas_gl_glapi->glClipPlanefIMG
+#define glClipPlanexIMG                            __evas_gl_glapi->glClipPlanexIMG
+#define glRenderbufferStorageMultisampleIMG        __evas_gl_glapi->glRenderbufferStorageMultisampleIMG
+#define glFramebufferTexture2DMultisampleIMG       __evas_gl_glapi->glFramebufferTexture2DMultisampleIMG
+#define glDeleteFencesNV                           __evas_gl_glapi->glDeleteFencesNV
+#define glGenFencesNV                              __evas_gl_glapi->glGenFencesNV
+#define glIsFenceNV                                __evas_gl_glapi->glIsFenceNV
+#define glTestFenceNV                              __evas_gl_glapi->glTestFenceNV
+#define glGetFenceivNV                             __evas_gl_glapi->glGetFenceivNV
+#define glFinishFenceNV                            __evas_gl_glapi->glFinishFenceNV
+#define glSetFenceNV                               __evas_gl_glapi->glSetFenceNV
+#define glGetDriverControlsQCOM                    __evas_gl_glapi->glGetDriverControlsQCOM
+#define glGetDriverControlStringQCOM               __evas_gl_glapi->glGetDriverControlStringQCOM
+#define glEnableDriverControlQCOM                  __evas_gl_glapi->glEnableDriverControlQCOM
+#define glDisableDriverControlQCOM                 __evas_gl_glapi->glDisableDriverControlQCOM
+#define glExtGetTexturesQCOM                       __evas_gl_glapi->glExtGetTexturesQCOM
+#define glExtGetBuffersQCOM                        __evas_gl_glapi->glExtGetBuffersQCOM
+#define glExtGetRenderbuffersQCOM                  __evas_gl_glapi->glExtGetRenderbuffersQCOM
+#define glExtGetFramebuffersQCOM                   __evas_gl_glapi->glExtGetFramebuffersQCOM
+#define glExtGetTexLevelParameterivQCOM            __evas_gl_glapi->glExtGetTexLevelParameterivQCOM
+#define glExtTexObjectStateOverrideiQCOM           __evas_gl_glapi->glExtTexObjectStateOverrideiQCOM
+#define glExtGetTexSubImageQCOM                    __evas_gl_glapi->glExtGetTexSubImageQCOM
+#define glExtGetBufferPointervQCOM                 __evas_gl_glapi->glExtGetBufferPointervQCOM
+#define glExtGetShadersQCOM                        __evas_gl_glapi->glExtGetShadersQCOM
+#define glExtGetProgramsQCOM                       __evas_gl_glapi->glExtGetProgramsQCOM
+#define glExtIsProgramBinaryQCOM                   __evas_gl_glapi->glExtIsProgramBinaryQCOM
+#define glExtGetProgramBinarySourceQCOM            __evas_gl_glapi->glExtGetProgramBinarySourceQCOM
+#define glStartTilingQCOM                          __evas_gl_glapi->glStartTilingQCOM
+#define glEndTilingQCOM                            __evas_gl_glapi->glEndTilingQCOM
+
+// glEvasGL functions
+#define glEvasGLImageTargetTexture2DOES            __evas_gl_glapi->glEvasGLImageTargetTexture2DOES
+#define glEvasGLImageTargetRenderbufferStorageOES  __evas_gl_glapi->glEvasGLImageTargetRenderbufferStorageOES
+
+// Evas GL glue layer
+#define evasglCreateImage                          __evas_gl_glapi->evasglCreateImage
+#define evasglCreateImageForContext                __evas_gl_glapi->evasglCreateImageForContext
+#define evasglDestroyImage                         __evas_gl_glapi->evasglDestroyImage
+#define evasglCreateSync                           __evas_gl_glapi->evasglCreateSync
+#define evasglDestroySync                          __evas_gl_glapi->evasglDestroySync
+#define evasglClientWaitSync                       __evas_gl_glapi->evasglClientWaitSync
+#define evasglSignalSync                           __evas_gl_glapi->evasglSignalSync
+#define evasglGetSyncAttrib                        __evas_gl_glapi->evasglGetSyncAttrib
+#define evasglWaitSync                             __evas_gl_glapi->evasglWaitSync
+
+/**
+ * @ingroup Evas_GL_GLES1_Helpers
+ * @brief Macro to check that the GL APIs are properly set (GLES 1.1)
+ * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ */
+#define EVAS_GL_GLES1_API_CHECK() \
+   ((__evas_gl_glapi != NULL) && (__evas_gl_glapi->version == EVAS_GL_API_VERSION) && (glAlphaFunc))
+
+/**
+ * @}
+ */
+
+#endif
+
diff --git a/src/lib/Evas_GL_GLES2_Helpers.h b/src/lib/Evas_GL_GLES2_Helpers.h
new file mode 100644 (file)
index 0000000..bb65433
--- /dev/null
@@ -0,0 +1,433 @@
+/**
+ * @file Evas_GL_GLES2_Helpers.h
+ * @defgroup Evas_GL_GLES2_Helpers Evas GL GLES2 helpers
+ * @ingroup Evas_GL
+ */
+
+/**
+ * @brief Provides a set of helper functions and macros to use GLES 2.0 with
+ * @ref Evas_GL "Evas GL".
+ *
+ * This file redefines all the OpenGL-ES 2.0 functions as follow:
+ * @code
+#define glFunction  __evas_gl_glapi->glFunction
+ * @endcode
+ *
+ * Extension functions can then be checked for existence simply by writing:
+ * @code
+if (glExtensionFunction)
+  {
+     ...
+     glExtensionFunction(...);
+     ...
+  }
+ * @endcode
+ *
+ * When using Elementary @ref GLView, please include the header file
+ * @ref Elementary_GL_Helpers "Elementary_GL_Helpers.h" instead.
+ *
+ * This header file should be included when using @ref Evas_GL "Evas GL"
+ * directly at a low level and with an OpenGL-ES 2.0 context only.
+ *
+ * @note When this file is included, all @c glFunctions are now macros, which
+ *       means that the @ref Evas_GL_API struct can't be used anyore.
+ *
+ * @see @ref elm_opengl_page
+ */
+#ifndef _EVAS_GL_GLES2_HELPERS_H
+#define _EVAS_GL_GLES2_HELPERS_H
+
+#include <Evas_GL.h>
+
+
+// local convenience macros
+
+/**
+ * @addtogroup Evas_GL_GLES2_Helpers
+ * @{
+ */
+
+/**
+ * @brief Macro to place at the beginning of any function using GLES 2.0 APIs
+ *
+ * Normally, it is necessary to call each function using its pointer as in:
+ * @code
+glapi->glFunction();
+ * @endcode
+ *
+ * When using this macro, developers can then call all @c glFunctions without
+ * changing their code:
+ * @code
+EVAS_GL_GLES2_USE(evasgl, context); // Add this at the beginning
+glFunction(); // All calls 'look' normal
+ * @endcode
+ *
+ * @note Please use @ref ELEMENTARY_GLVIEW_USE() instead, when possible.
+ * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ */
+#define EVAS_GL_GLES2_USE(evasgl, context) \
+   Evas_GL_API *__evas_gl_glapi = evas_gl_context_api_get(evasgl, context);
+
+/**
+ * @brief Macro to place at the beginning of any function using GLES 2.0 APIs
+ *
+ * This is similar to @ref EVAS_GL_GLES2_USE except that it will return from
+ * the function if the GL API can not be used.
+ *
+ * @note Please use @ref ELEMENTARY_GLVIEW_USE() instead, when possible.
+ * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ */
+#define EVAS_GL_GLES2_USE_OR_RETURN(evasgl, context, retval) \
+   Evas_GL_API *__evas_gl_glapi = evas_gl_context_api_get(evasgl, context); \
+   if (!__evas_gl_glapi) return retval;
+
+// End of the convenience functions
+
+// Global convenience macros
+
+/**
+ * @brief Convenience macro to use the GL helpers in simple applications: declare
+ *
+ * @c EVAS_GL_GLOBAL_GLES2_DECLARE should be used in a global header for the
+ * application. For example, in a platform-specific compatibility header file.
+ *
+ * To be used with OpenGL-ES 2.0 contexts.
+ *
+ * Example of a global header file @c main.h:
+ * @code
+#include <Evas_GL_GLES2_Helpers.h>
+// other includes...
+
+EVAS_GL_GLOBAL_GLES2_DECLARE()
+
+// ...
+ * @endcode
+ *
+ * @note Please use @ref ELEMENTARY_GLVIEW_USE() instead, when possible.
+ *
+ * @see @ref ELEMENTARY_GLVIEW_GLOBAL_DECLARE
+ * @see @ref EVAS_GL_GLOBAL_GLES2_DEFINE
+ * @see @ref EVAS_GL_GLOBAL_GLES2_USE
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ */
+#define EVAS_GL_GLOBAL_GLES2_DECLARE() \
+   extern Evas_GL_API *__evas_gl_glapi;
+
+/**
+ * @brief Convenience macro to use the GL helpers in simple applications: define
+ *
+ * To be used with OpenGL-ES 2.0 contexts.
+ *
+ * Example of a file @c glview.c:
+ *
+ * @code
+#include "main.h"
+EVAS_GL_GLOBAL_GLES2_DEFINE()
+
+// ...
+
+static inline void
+evgl_init(...)
+{
+   // ...
+   evasgl = evas_gl_new(canvas);
+   // ...
+   ctx = evas_gl_context_version_create(evasgl, NULL, EVAS_GL_GLES_2_X);
+   EVAS_GL_GLOBAL_GLES2_USE(evasgl, ctx);
+   // ...
+}
+
+// ...
+ * @endcode
+ *
+ * @see @ref ELEMENTARY_GLVIEW_GLOBAL_DEFINE
+ * @see @ref EVAS_GL_GLOBAL_GLES2_DECLARE
+ * @see @ref EVAS_GL_GLOBAL_GLES2_USE
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ */
+#define EVAS_GL_GLOBAL_GLES2_DEFINE() \
+   Evas_GL_API *__evas_gl_glapi = NULL;
+
+/**
+ * @brief Convenience macro to use the GL helpers in simple applications: use
+ *
+ * This macro will set the global variable holding the GL API so that it's
+ * available to the application.
+ *
+ * It should be used right after setting up the GL context object.
+ *
+ * @see @ref ELEMENTARY_GLVIEW_GLOBAL_USE
+ * @see @ref EVAS_GL_GLOBAL_GLES2_DECLARE
+ * @see @ref EVAS_GL_GLOBAL_GLES2_DEFINE
+ *
+ * @if MOBILE @since_tizen 2.3
+ * @elseif WEARABLE @since_tizen 2.3.1
+ * @endif
+ */
+#define EVAS_GL_GLOBAL_GLES2_USE(evgl, ctx) \
+   do { __evas_gl_glapi = evas_gl_context_api_get(evgl, ctx); } while (0)
+
+
+// End of the convenience functions (global)
+/** @} */
+
+#define glActiveTexture                            __evas_gl_glapi->glActiveTexture
+#define glAttachShader                             __evas_gl_glapi->glAttachShader
+#define glBindAttribLocation                       __evas_gl_glapi->glBindAttribLocation
+#define glBindBuffer                               __evas_gl_glapi->glBindBuffer
+#define glBindFramebuffer                          __evas_gl_glapi->glBindFramebuffer
+#define glBindRenderbuffer                         __evas_gl_glapi->glBindRenderbuffer
+#define glBindTexture                              __evas_gl_glapi->glBindTexture
+#define glBlendColor                               __evas_gl_glapi->glBlendColor
+#define glBlendEquation                            __evas_gl_glapi->glBlendEquation
+#define glBlendEquationSeparate                    __evas_gl_glapi->glBlendEquationSeparate
+#define glBlendFunc                                __evas_gl_glapi->glBlendFunc
+#define glBlendFuncSeparate                        __evas_gl_glapi->glBlendFuncSeparate
+#define glBufferData                               __evas_gl_glapi->glBufferData
+#define glBufferSubData                            __evas_gl_glapi->glBufferSubData
+#define glCheckFramebufferStatus                   __evas_gl_glapi->glCheckFramebufferStatus
+#define glClear                                    __evas_gl_glapi->glClear
+#define glClearColor                               __evas_gl_glapi->glClearColor
+#define glClearDepthf                              __evas_gl_glapi->glClearDepthf
+#define glClearStencil                             __evas_gl_glapi->glClearStencil
+#define glColorMask                                __evas_gl_glapi->glColorMask
+#define glCompileShader                            __evas_gl_glapi->glCompileShader
+#define glCompressedTexImage2D                     __evas_gl_glapi->glCompressedTexImage2D
+#define glCompressedTexSubImage2D                  __evas_gl_glapi->glCompressedTexSubImage2D
+#define glCopyTexImage2D                           __evas_gl_glapi->glCopyTexImage2D
+#define glCopyTexSubImage2D                        __evas_gl_glapi->glCopyTexSubImage2D
+#define glCreateProgram                            __evas_gl_glapi->glCreateProgram
+#define glCreateShader                             __evas_gl_glapi->glCreateShader
+#define glCullFace                                 __evas_gl_glapi->glCullFace
+#define glDeleteBuffers                            __evas_gl_glapi->glDeleteBuffers
+#define glDeleteFramebuffers                       __evas_gl_glapi->glDeleteFramebuffers
+#define glDeleteProgram                            __evas_gl_glapi->glDeleteProgram
+#define glDeleteRenderbuffers                      __evas_gl_glapi->glDeleteRenderbuffers
+#define glDeleteShader                             __evas_gl_glapi->glDeleteShader
+#define glDeleteTextures                           __evas_gl_glapi->glDeleteTextures
+#define glDepthFunc                                __evas_gl_glapi->glDepthFunc
+#define glDepthMask                                __evas_gl_glapi->glDepthMask
+#define glDepthRangef                              __evas_gl_glapi->glDepthRangef
+#define glDetachShader                             __evas_gl_glapi->glDetachShader
+#define glDisable                                  __evas_gl_glapi->glDisable
+#define glDisableVertexAttribArray                 __evas_gl_glapi->glDisableVertexAttribArray
+#define glDrawArrays                               __evas_gl_glapi->glDrawArrays
+#define glDrawElements                             __evas_gl_glapi->glDrawElements
+#define glEnable                                   __evas_gl_glapi->glEnable
+#define glEnableVertexAttribArray                  __evas_gl_glapi->glEnableVertexAttribArray
+#define glFinish                                   __evas_gl_glapi->glFinish
+#define glFlush                                    __evas_gl_glapi->glFlush
+#define glFramebufferRenderbuffer                  __evas_gl_glapi->glFramebufferRenderbuffer
+#define glFramebufferTexture2D                     __evas_gl_glapi->glFramebufferTexture2D
+#define glFrontFace                                __evas_gl_glapi->glFrontFace
+#define glGenBuffers                               __evas_gl_glapi->glGenBuffers
+#define glGenerateMipmap                           __evas_gl_glapi->glGenerateMipmap
+#define glGenFramebuffers                          __evas_gl_glapi->glGenFramebuffers
+#define glGenRenderbuffers                         __evas_gl_glapi->glGenRenderbuffers
+#define glGenTextures                              __evas_gl_glapi->glGenTextures
+#define glGetActiveAttrib                          __evas_gl_glapi->glGetActiveAttrib
+#define glGetActiveUniform                         __evas_gl_glapi->glGetActiveUniform
+#define glGetAttachedShaders                       __evas_gl_glapi->glGetAttachedShaders
+#define glGetAttribLocation                        __evas_gl_glapi->glGetAttribLocation
+#define glGetBooleanv                              __evas_gl_glapi->glGetBooleanv
+#define glGetBufferParameteriv                     __evas_gl_glapi->glGetBufferParameteriv
+#define glGetError                                 __evas_gl_glapi->glGetError
+#define glGetFloatv                                __evas_gl_glapi->glGetFloatv
+#define glGetFramebufferAttachmentParameteriv      __evas_gl_glapi->glGetFramebufferAttachmentParameteriv
+#define glGetIntegerv                              __evas_gl_glapi->glGetIntegerv
+#define glGetProgramiv                             __evas_gl_glapi->glGetProgramiv
+#define glGetProgramInfoLog                        __evas_gl_glapi->glGetProgramInfoLog
+#define glGetRenderbufferParameteriv               __evas_gl_glapi->glGetRenderbufferParameteriv
+#define glGetShaderiv                              __evas_gl_glapi->glGetShaderiv
+#define glGetShaderInfoLog                         __evas_gl_glapi->glGetShaderInfoLog
+#define glGetShaderPrecisionFormat                 __evas_gl_glapi->glGetShaderPrecisionFormat
+#define glGetShaderSource                          __evas_gl_glapi->glGetShaderSource
+#define glGetString                                __evas_gl_glapi->glGetString
+#define glGetTexParameterfv                        __evas_gl_glapi->glGetTexParameterfv
+#define glGetTexParameteriv                        __evas_gl_glapi->glGetTexParameteriv
+#define glGetUniformfv                             __evas_gl_glapi->glGetUniformfv
+#define glGetUniformiv                             __evas_gl_glapi->glGetUniformiv
+#define glGetUniformLocation                       __evas_gl_glapi->glGetUniformLocation
+#define glGetVertexAttribfv                        __evas_gl_glapi->glGetVertexAttribfv
+#define glGetVertexAttribiv                        __evas_gl_glapi->glGetVertexAttribiv
+#define glGetVertexAttribPointerv                  __evas_gl_glapi->glGetVertexAttribPointerv
+#define glHint                                     __evas_gl_glapi->glHint
+#define glIsBuffer                                 __evas_gl_glapi->glIsBuffer
+#define glIsEnabled                                __evas_gl_glapi->glIsEnabled
+#define glIsFramebuffer                            __evas_gl_glapi->glIsFramebuffer
+#define glIsProgram                                __evas_gl_glapi->glIsProgram
+#define glIsRenderbuffer                           __evas_gl_glapi->glIsRenderbuffer
+#define glIsShader                                 __evas_gl_glapi->glIsShader
+#define glIsTexture                                __evas_gl_glapi->glIsTexture
+#define glLineWidth                                __evas_gl_glapi->glLineWidth
+#define glLinkProgram                              __evas_gl_glapi->glLinkProgram
+#define glPixelStorei                              __evas_gl_glapi->glPixelStorei
+#define glPolygonOffset                            __evas_gl_glapi->glPolygonOffset
+#define glReadPixels                               __evas_gl_glapi->glReadPixels
+#define glReleaseShaderCompiler                    __evas_gl_glapi->glReleaseShaderCompiler
+#define glRenderbufferStorage                      __evas_gl_glapi->glRenderbufferStorage
+#define glSampleCoverage                           __evas_gl_glapi->glSampleCoverage
+#define glScissor                                  __evas_gl_glapi->glScissor
+#define glShaderBinary                             __evas_gl_glapi->glShaderBinary
+#define glShaderSource                             __evas_gl_glapi->glShaderSource
+#define glStencilFunc                              __evas_gl_glapi->glStencilFunc
+#define glStencilFuncSeparate                      __evas_gl_glapi->glStencilFuncSeparate
+#define glStencilMask                              __evas_gl_glapi->glStencilMask
+#define glStencilMaskSeparate                      __evas_gl_glapi->glStencilMaskSeparate
+#define glStencilOp                                __evas_gl_glapi->glStencilOp
+#define glStencilOpSeparate                        __evas_gl_glapi->glStencilOpSeparate
+#define glTexImage2D                               __evas_gl_glapi->glTexImage2D
+#define glTexParameterf                            __evas_gl_glapi->glTexParameterf
+#define glTexParameterfv                           __evas_gl_glapi->glTexParameterfv
+#define glTexParameteri                            __evas_gl_glapi->glTexParameteri
+#define glTexParameteriv                           __evas_gl_glapi->glTexParameteriv
+#define glTexSubImage2D                            __evas_gl_glapi->glTexSubImage2D
+#define glUniform1f                                __evas_gl_glapi->glUniform1f
+#define glUniform1fv                               __evas_gl_glapi->glUniform1fv
+#define glUniform1i                                __evas_gl_glapi->glUniform1i
+#define glUniform1iv                               __evas_gl_glapi->glUniform1iv
+#define glUniform2f                                __evas_gl_glapi->glUniform2f
+#define glUniform2fv                               __evas_gl_glapi->glUniform2fv
+#define glUniform2i                                __evas_gl_glapi->glUniform2i
+#define glUniform2iv                               __evas_gl_glapi->glUniform2iv
+#define glUniform3f                                __evas_gl_glapi->glUniform3f
+#define glUniform3fv                               __evas_gl_glapi->glUniform3fv
+#define glUniform3i                                __evas_gl_glapi->glUniform3i
+#define glUniform3iv                               __evas_gl_glapi->glUniform3iv
+#define glUniform4f                                __evas_gl_glapi->glUniform4f
+#define glUniform4fv                               __evas_gl_glapi->glUniform4fv
+#define glUniform4i                                __evas_gl_glapi->glUniform4i
+#define glUniform4iv                               __evas_gl_glapi->glUniform4iv
+#define glUniformMatrix2fv                         __evas_gl_glapi->glUniformMatrix2fv
+#define glUniformMatrix3fv                         __evas_gl_glapi->glUniformMatrix3fv
+#define glUniformMatrix4fv                         __evas_gl_glapi->glUniformMatrix4fv
+#define glUseProgram                               __evas_gl_glapi->glUseProgram
+#define glValidateProgram                          __evas_gl_glapi->glValidateProgram
+#define glVertexAttrib1f                           __evas_gl_glapi->glVertexAttrib1f
+#define glVertexAttrib1fv                          __evas_gl_glapi->glVertexAttrib1fv
+#define glVertexAttrib2f                           __evas_gl_glapi->glVertexAttrib2f
+#define glVertexAttrib2fv                          __evas_gl_glapi->glVertexAttrib2fv
+#define glVertexAttrib3f                           __evas_gl_glapi->glVertexAttrib3f
+#define glVertexAttrib3fv                          __evas_gl_glapi->glVertexAttrib3fv
+#define glVertexAttrib4f                           __evas_gl_glapi->glVertexAttrib4f
+#define glVertexAttrib4fv                          __evas_gl_glapi->glVertexAttrib4fv
+#define glVertexAttribPointer                      __evas_gl_glapi->glVertexAttribPointer
+#define glViewport                                 __evas_gl_glapi->glViewport
+
+// GLES 2.0 extensions
+#define glGetProgramBinaryOES                      __evas_gl_glapi->glGetProgramBinaryOES
+#define glProgramBinaryOES                         __evas_gl_glapi->glProgramBinaryOES
+#define glMapBufferOES                             __evas_gl_glapi->glMapBufferOES
+#define glUnmapBufferOES                           __evas_gl_glapi->glUnmapBufferOES
+#define glGetBufferPointervOES                     __evas_gl_glapi->glGetBufferPointervOES
+#define glTexImage3DOES                            __evas_gl_glapi->glTexImage3DOES
+#define glTexSubImage3DOES                         __evas_gl_glapi->glTexSubImage3DOES
+#define glCopyTexSubImage3DOES                     __evas_gl_glapi->glCopyTexSubImage3DOES
+#define glCompressedTexImage3DOES                  __evas_gl_glapi->glCompressedTexImage3DOES
+#define glCompressedTexSubImage3DOES               __evas_gl_glapi->glCompressedTexSubImage3DOES
+#define glFramebufferTexture3DOES                  __evas_gl_glapi->glFramebufferTexture3DOES
+#define glBindVertexArrayOES                       __evas_gl_glapi->glBindVertexArrayOES
+#define glDeleteVertexArraysOES                    __evas_gl_glapi->glDeleteVertexArraysOES
+#define glGenVertexArraysOES                       __evas_gl_glapi->glGenVertexArraysOES
+#define glIsVertexArrayOES                         __evas_gl_glapi->glIsVertexArrayOES
+#define glGetPerfMonitorGroupsAMD                  __evas_gl_glapi->glGetPerfMonitorGroupsAMD
+#define glGetPerfMonitorCountersAMD                __evas_gl_glapi->glGetPerfMonitorCountersAMD
+#define glGetPerfMonitorGroupStringAMD             __evas_gl_glapi->glGetPerfMonitorGroupStringAMD
+#define glGetPerfMonitorCounterStringAMD           __evas_gl_glapi->glGetPerfMonitorCounterStringAMD
+#define glGetPerfMonitorCounterInfoAMD             __evas_gl_glapi->glGetPerfMonitorCounterInfoAMD
+#define glGenPerfMonitorsAMD                       __evas_gl_glapi->glGenPerfMonitorsAMD
+#define glDeletePerfMonitorsAMD                    __evas_gl_glapi->glDeletePerfMonitorsAMD
+#define glSelectPerfMonitorCountersAMD             __evas_gl_glapi->glSelectPerfMonitorCountersAMD
+#define glBeginPerfMonitorAMD                      __evas_gl_glapi->glBeginPerfMonitorAMD
+#define glEndPerfMonitorAMD                        __evas_gl_glapi->glEndPerfMonitorAMD
+#define glGetPerfMonitorCounterDataAMD             __evas_gl_glapi->glGetPerfMonitorCounterDataAMD
+#define glCopyTextureLevelsAPPLE                   __evas_gl_glapi->glCopyTextureLevelsAPPLE
+#define glRenderbufferStorageMultisampleAPPLE      __evas_gl_glapi->glRenderbufferStorageMultisampleAPPLE
+#define glResolveMultisampleFramebufferAPPLE       __evas_gl_glapi->glResolveMultisampleFramebufferAPPLE
+#define glFenceSyncAPPLE                           __evas_gl_glapi->glFenceSyncAPPLE
+#define glIsSyncAPPLE                              __evas_gl_glapi->glIsSyncAPPLE
+#define glDeleteSyncAPPLE                          __evas_gl_glapi->glDeleteSyncAPPLE
+#define glClientWaitSyncAPPLE                      __evas_gl_glapi->glClientWaitSyncAPPLE
+#define glWaitSyncAPPLE                            __evas_gl_glapi->glWaitSyncAPPLE
+#define glGetInteger64vAPPLE                       __evas_gl_glapi->glGetInteger64vAPPLE
+#define glGetSyncivAPPLE                           __evas_gl_glapi->glGetSyncivAPPLE
+#define glDiscardFramebufferEXT                    __evas_gl_glapi->glDiscardFramebufferEXT
+#define glMapBufferRangeEXT                        __evas_gl_glapi->glMapBufferRangeEXT
+#define glFlushMappedBufferRangeEXT                __evas_gl_glapi->glFlushMappedBufferRangeEXT
+#define glMultiDrawArraysEXT                       __evas_gl_glapi->glMultiDrawArraysEXT
+#define glMultiDrawElementsEXT                     __evas_gl_glapi->glMultiDrawElementsEXT
+#define glRenderbufferStorageMultisampleEXT        __evas_gl_glapi->glRenderbufferStorageMultisampleEXT
+#define glFramebufferTexture2DMultisampleEXT       __evas_gl_glapi->glFramebufferTexture2DMultisampleEXT
+#define glGetGraphicsResetStatusEXT                __evas_gl_glapi->glGetGraphicsResetStatusEXT
+#define glReadnPixelsEXT                           __evas_gl_glapi->glReadnPixelsEXT
+#define glGetnUniformfvEXT                         __evas_gl_glapi->glGetnUniformfvEXT
+#define glGetnUniformivEXT                         __evas_gl_glapi->glGetnUniformivEXT
+#define glTexStorage1DEXT                          __evas_gl_glapi->glTexStorage1DEXT
+#define glTexStorage2DEXT                          __evas_gl_glapi->glTexStorage2DEXT
+#define glTexStorage3DEXT                          __evas_gl_glapi->glTexStorage3DEXT
+#define glTextureStorage1DEXT                      __evas_gl_glapi->glTextureStorage1DEXT
+#define glTextureStorage2DEXT                      __evas_gl_glapi->glTextureStorage2DEXT
+#define glTextureStorage3DEXT                      __evas_gl_glapi->glTextureStorage3DEXT
+#define glRenderbufferStorageMultisampleIMG        __evas_gl_glapi->glRenderbufferStorageMultisampleIMG
+#define glFramebufferTexture2DMultisampleIMG       __evas_gl_glapi->glFramebufferTexture2DMultisampleIMG
+#define glDeleteFencesNV                           __evas_gl_glapi->glDeleteFencesNV
+#define glGenFencesNV                              __evas_gl_glapi->glGenFencesNV
+#define glIsFenceNV                                __evas_gl_glapi->glIsFenceNV
+#define glTestFenceNV                              __evas_gl_glapi->glTestFenceNV
+#define glGetFenceivNV                             __evas_gl_glapi->glGetFenceivNV
+#define glFinishFenceNV                            __evas_gl_glapi->glFinishFenceNV
+#define glSetFenceNV                               __evas_gl_glapi->glSetFenceNV
+#define glGetDriverControlsQCOM                    __evas_gl_glapi->glGetDriverControlsQCOM
+#define glGetDriverControlStringQCOM               __evas_gl_glapi->glGetDriverControlStringQCOM
+#define glEnableDriverControlQCOM                  __evas_gl_glapi->glEnableDriverControlQCOM
+#define glDisableDriverControlQCOM                 __evas_gl_glapi->glDisableDriverControlQCOM
+#define glExtGetTexturesQCOM                       __evas_gl_glapi->glExtGetTexturesQCOM
+#define glExtGetBuffersQCOM                        __evas_gl_glapi->glExtGetBuffersQCOM
+#define glExtGetRenderbuffersQCOM                  __evas_gl_glapi->glExtGetRenderbuffersQCOM
+#define glExtGetFramebuffersQCOM                   __evas_gl_glapi->glExtGetFramebuffersQCOM
+#define glExtGetTexLevelParameterivQCOM            __evas_gl_glapi->glExtGetTexLevelParameterivQCOM
+#define glExtTexObjectStateOverrideiQCOM           __evas_gl_glapi->glExtTexObjectStateOverrideiQCOM
+#define glExtGetTexSubImageQCOM                    __evas_gl_glapi->glExtGetTexSubImageQCOM
+#define glExtGetBufferPointervQCOM                 __evas_gl_glapi->glExtGetBufferPointervQCOM
+#define glExtGetShadersQCOM                        __evas_gl_glapi->glExtGetShadersQCOM
+#define glExtGetProgramsQCOM                       __evas_gl_glapi->glExtGetProgramsQCOM
+#define glExtIsProgramBinaryQCOM                   __evas_gl_glapi->glExtIsProgramBinaryQCOM
+#define glExtGetProgramBinarySourceQCOM            __evas_gl_glapi->glExtGetProgramBinarySourceQCOM
+#define glStartTilingQCOM                          __evas_gl_glapi->glStartTilingQCOM
+#define glEndTilingQCOM                            __evas_gl_glapi->glEndTilingQCOM
+
+// glEvasGL functions
+#define glEvasGLImageTargetTexture2DOES            __evas_gl_glapi->glEvasGLImageTargetTexture2DOES
+#define glEvasGLImageTargetRenderbufferStorageOES  __evas_gl_glapi->glEvasGLImageTargetRenderbufferStorageOES
+
+// Evas GL glue layer
+#define evasglCreateImage                          __evas_gl_glapi->evasglCreateImage
+#define evasglCreateImageForContext                __evas_gl_glapi->evasglCreateImageForContext
+#define evasglDestroyImage                         __evas_gl_glapi->evasglDestroyImage
+#define evasglCreateSync                           __evas_gl_glapi->evasglCreateSync
+#define evasglDestroySync                          __evas_gl_glapi->evasglDestroySync
+#define evasglClientWaitSync                       __evas_gl_glapi->evasglClientWaitSync
+#define evasglSignalSync                           __evas_gl_glapi->evasglSignalSync
+#define evasglGetSyncAttrib                        __evas_gl_glapi->evasglGetSyncAttrib
+#define evasglWaitSync                             __evas_gl_glapi->evasglWaitSync
+
+/**
+ * @ingroup Evas_GL_GLES2_Helpers
+ * @brief Macro to check that the GL APIs are properly set (GLES 2.0)
+ * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ */
+#define EVAS_GL_GLES2_API_CHECK() \
+   ((__evas_gl_glapi != NULL) && (__evas_gl_glapi->version == EVAS_GL_API_VERSION) && (glActiveTexture))
+
+/**
+ * @}
+ */
+
+#endif
+
index 00511f3..8160f48 100644 (file)
@@ -1,6 +1,6 @@
 MAINTAINERCLEANFILES = Makefile.in
 
-SUBDIRS = canvas cache cache2 cserve cserve2 file engines include
+SUBDIRS = canvas cache cache2 cserve cserve2 file engines filters include
 EVAS_STATIC_MODULE =
 EVAS_STATIC_LIBADD =
 
@@ -48,20 +48,6 @@ SUBDIRS += ../modules/engines/psl1ght/
 EVAS_STATIC_MODULE += ../modules/engines/psl1ght/libevas_engine_psl1ght.la
 EVAS_STATIC_LIBADD += @evas_engine_psl1ght_libs@
 endif
-if EVAS_STATIC_BUILD_SOFTWARE_16
-SUBDIRS += ../modules/engines/software_16/
-EVAS_STATIC_MODULE += ../modules/engines/software_16/libevas_engine_software_16.la
-endif
-if EVAS_STATIC_BUILD_SOFTWARE_16_WINCE
-SUBDIRS += ../modules/engines/software_16_wince/
-EVAS_STATIC_MODULE += ../modules/engines/software_16_wince/libevas_engine_software_16_wince.la
-EVAS_STATIC_LIBADD += @evas_engine_software_16_wince_libs@
-endif
-if EVAS_STATIC_BUILD_SOFTWARE_16_X11
-SUBDIRS += ../modules/engines/software_16_x11/
-EVAS_STATIC_MODULE += ../modules/engines/software_16_x11/libevas_engine_software_16_x11.la
-EVAS_STATIC_LIBADD += @evas_engine_software_16_x11_libs@
-endif
 if EVAS_STATIC_BUILD_SOFTWARE_8
 SUBDIRS += ../modules/engines/software_8/
 EVAS_STATIC_MODULE += ../modules/engines/software_8/libevas_engine_software_8.la
@@ -71,13 +57,6 @@ SUBDIRS += ../modules/engines/software_8_x11/
 EVAS_STATIC_MODULE += ../modules/engines/software_8_x11/libevas_engine_software_8_x11.la
 EVAS_STATIC_LIBADD += @evas_engine_software_8_x11_libs@
 endif
-if EVAS_STATIC_BUILD_SOFTWARE_16_SDL
-SUBDIRS += \
-       ../modules/engines/software_16_sdl/
-EVAS_STATIC_MODULE += \
-       ../modules/engines/software_16_sdl/libevas_engine_software_16_sdl.la
-EVAS_STATIC_LIBADD += @SDL_LIBS@
-endif
 if EVAS_STATIC_BUILD_SOFTWARE_DDRAW
 SUBDIRS += ../modules/engines/software_ddraw/
 EVAS_STATIC_MODULE += ../modules/engines/software_ddraw/libevas_engine_software_ddraw.la
@@ -185,7 +164,7 @@ AM_CPPFLAGS = \
 -DPACKAGE_BIN_DIR=\"$(bindir)\" \
 -DPACKAGE_LIB_DIR=\"$(libdir)\" \
 -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FREETYPE_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @HARFBUZZ_CFLAGS@ \
@@ -196,7 +175,7 @@ AM_CPPFLAGS = \
 
 lib_LTLIBRARIES = libevas.la
 
-includes_HEADERS = Evas.h Evas_GL.h
+includes_HEADERS = Evas.h Evas_GL.h Evas_GL_GLES1_Helpers.h Evas_GL_GLES2_Helpers.h
 includesdir = $(includedir)/evas-@VMAJ@
 
 libevas_la_SOURCES = main.c
@@ -226,7 +205,7 @@ engines/common/libevas_engine_common.la \
 @EET_LIBS@ \
 @FONTCONFIG_LIBS@ \
 @pthread_libs@ \
-@EINA_LIBS@ \
+@EVAS_GENERAL_LIBS@ \
 $(EVAS_STATIC_MODULE) \
 $(EVAS_STATIC_LIBADD) \
 @PIXMAN_LIBS@ \
@@ -251,13 +230,6 @@ cache2/libevas_cache2.la
 
 endif
 
-if BUILD_ENGINE_SOFTWARE_16
-
-libevas_la_LIBADD += engines/common_16/libevas_engine_common_16.la
-libevas_la_DEPENDENCIES += engines/common_16/libevas_engine_common_16.la
-
-endif
-
 if BUILD_ENGINE_SOFTWARE_8
 
 libevas_la_LIBADD += engines/common_8/libevas_engine_common_8.la
@@ -265,9 +237,13 @@ libevas_la_DEPENDENCIES += engines/common_8/libevas_engine_common_8.la
 
 endif
 
+# Evas filters (text effects)
+libevas_la_LIBADD += filters/libevas_filters.la
+libevas_la_DEPENDENCIES += filters/libevas_filters.la
+
 libevas_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@
 
 ### Evas_GL we are still using it in our code, so just don't install it.
 EXTRA_DIST=Evas_GL.h
 
-DIST_SUBDIRS = canvas cache cache2 cserve cserve2 file engines include
+DIST_SUBDIRS = canvas cache cache2 cserve cserve2 file engines filters include
index feb5c94..d25932f 100644 (file)
@@ -9,7 +9,7 @@ AM_CPPFLAGS = -I. -I$(top_srcdir)/src/lib -I$(top_srcdir)/src/lib/include \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
-@EINA_CFLAGS@
+@EVAS_GENERAL_CFLAGS@
 
 noinst_LTLIBRARIES      = libevas_cache.la
 libevas_cache_la_SOURCES  = \
index 5ec1af2..8634fed 100644 (file)
@@ -117,7 +117,7 @@ _evas_cache_engine_image_alloc(Evas_Cache_Engine_Image *cache,
    if (eim)
      evas_cache_engine_image_drop(eim);
    eina_stringshare_del(hkey);
-   evas_cache_image_drop(ie);
+   if (ie) evas_cache_image_drop(ie);
    return NULL;
 }
 
index 8d96964..816bea6 100755 (executable)
@@ -903,6 +903,7 @@ evas_cache_image_copied_data(Evas_Cache_Image *cache,
         return NULL;
      }
    im->references = 1;
+   im->flags.loaded = EINA_TRUE;
    if (cache->func.debug) cache->func.debug("copied-data", im);
    return im;
 }
@@ -1244,6 +1245,10 @@ evas_cache_image_wakeup(void)
 {
 #ifdef BUILD_ASYNC_PRELOAD
    if (_evas_cache_mutex_init > 0)
-     eina_condition_broadcast(&cond_wakeup);
+     {
+        LKL(wakeup);
+        eina_condition_broadcast(&cond_wakeup);
+        LKU(wakeup);
+     }
 #endif
 }
index 5eebaed..5baeba9 100644 (file)
@@ -7,10 +7,12 @@
 #endif
 
 #ifdef BUILD_ASYNC_PRELOAD
-# include <pthread.h>
-# ifdef __linux__
-# include <sys/syscall.h>
-# endif
+#include <pthread.h>
+#ifdef __linux__
+#include <sys/syscall.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
 #endif
 
 #include "evas_common.h"
@@ -20,6 +22,7 @@
 #ifdef BUILD_ASYNC_PRELOAD
 
 static int _threads_max = 0;
+static int _threads_priority = 19;
 
 typedef struct _Evas_Preload_Pthread_Worker Evas_Preload_Pthread_Worker;
 typedef struct _Evas_Preload_Pthread_Data Evas_Preload_Pthread_Data;
@@ -79,6 +82,12 @@ _evas_preload_thread_worker(void *data)
    Evas_Preload_Pthread_Worker *work;
 
    eina_sched_prio_drop();
+
+   /// main thread was stuck by preload thread. set priority the lowest value.
+#ifdef __linux__
+   setpriority(PRIO_PROCESS, 0, _threads_priority);
+#endif
+
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
 on_error:
@@ -213,9 +222,11 @@ evas_preload_thread_run(void (*func_heavy) (void *data),
    LKL(_mutex);
    if (_threads_count == 0)
      {
-       LKU(_mutex);
-       if (work->func_cancel) work->func_cancel(work->data);
-       free(work);
+        _workers = EINA_INLIST_CONTAINER_GET(eina_inlist_remove(EINA_INLIST_GET(_workers), EINA_INLIST_GET(work)), Evas_Preload_Pthread_Worker);
+
+        LKU(_mutex);
+        if (work->func_cancel) work->func_cancel(work->data);
+        free(work);
         return NULL;
      }
    LKU(_mutex);
index bb9019d..2eaf0b9 100644 (file)
@@ -8,11 +8,12 @@ AM_CPPFLAGS        = -I. \
                       -DPACKAGE_BIN_DIR=\"$(bindir)\" \
                       -DPACKAGE_LIB_DIR=\"$(libdir)\" \
                       -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
-                       @EVIL_CFLAGS@ \
+                      @EVIL_CFLAGS@ \
                       @FREETYPE_CFLAGS@ \
                        @PIXMAN_CFLAGS@ \
-                      @EINA_CFLAGS@ \
-                       @PIXMAN_CFLAGS@
+                      @EVAS_GENERAL_CFLAGS@ \
+                       @PIXMAN_CFLAGS@ \
+                       @FRIBIDI_CFLAGS@
 
 if EVAS_CSERVE2
 
index d0c8e12..2ed5c50 100644 (file)
@@ -13,7 +13,7 @@ AM_CPPFLAGS = \
 @EET_CFLAGS@ \
 @FONTCONFIG_CFLAGS@ \
 @EVAS_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @EVIL_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@
@@ -23,6 +23,7 @@ libevas_canvas_la_SOURCES  = \
 evas_callbacks.c \
 evas_clip.c \
 evas_data.c \
+evas_device.c \
 evas_events.c \
 evas_filter.c \
 evas_focus.c \
index bd2e3a8..c984325 100644 (file)
@@ -19,6 +19,7 @@
 
 static int _fd_write = -1;
 static int _fd_read = -1;
+static pid_t _fd_pid = 0;
 
 static int _init_evas_event = 0;
 
@@ -32,6 +33,26 @@ struct _Evas_Event_Async
    Evas_Callback_Type       type;
 };
 
+Eina_Bool
+_evas_fd_close_on_exec(int fd)
+{
+#ifdef HAVE_FCNTL
+   int flags;
+
+   flags = fcntl(fd, F_GETFD);
+   if (flags == -1)
+     return EINA_FALSE;
+
+   flags |= FD_CLOEXEC;
+   if (fcntl(fd, F_SETFD, flags) == -1)
+     return EINA_FALSE;
+   return EINA_TRUE;
+#else
+   (void) fd;
+   return EINA_FALSE;
+#endif
+}
+
 int
 evas_async_events_init(void)
 {
@@ -40,12 +61,17 @@ evas_async_events_init(void)
    _init_evas_event++;
    if (_init_evas_event > 1) return _init_evas_event;
 
+   _fd_pid = getpid();
+   
    if (pipe(filedes) == -1)
      {
        _init_evas_event = 0;
        return 0;
      }
 
+   _evas_fd_close_on_exec(filedes[0]);
+   _evas_fd_close_on_exec(filedes[1]);
+
    _fd_read = filedes[0];
    _fd_write = filedes[1];
 
@@ -68,12 +94,23 @@ evas_async_events_shutdown(void)
    return _init_evas_event;
 }
 
+static void
+_evas_async_events_fork_handle(void)
+{
+   int i, count = _init_evas_event;
+   
+   if (getpid() == _fd_pid) return;
+   for (i = 0; i < count; i++) evas_async_events_shutdown();
+   for (i = 0; i < count; i++) evas_async_events_init();
+}
+
 #endif
 
 EAPI int
 evas_async_events_fd_get(void)
 {
 #ifdef BUILD_ASYNC_EVENTS
+   _evas_async_events_fork_handle();
    return _fd_read;
 #else
    return -1;
@@ -90,6 +127,8 @@ evas_async_events_process(void)
 
    if (_fd_read == -1) return 0;
 
+   _evas_async_events_fork_handle();
+   
    do
      {
        check = read(_fd_read, &ev, sizeof (Evas_Event_Async *));
@@ -134,6 +173,8 @@ evas_async_events_put(const void *target, Evas_Callback_Type type, void *event_i
    if (!func) return 0;
    if (_fd_write == -1) return 0;
 
+   _evas_async_events_fork_handle();
+   
    ev = calloc(1, sizeof (Evas_Event_Async));
    if (!ev) return 0;
 
index dfd8099..ec6feb9 100644 (file)
@@ -14,9 +14,12 @@ _evas_post_event_callback_call(Evas *e)
 {
    Evas_Post_Callback *pc;
    int skip = 0;
+   static int first_run = 1; // FIXME: This is a workaround to prevent this
+                             // function from being called recursively.
 
-   if (e->delete_me) return;
+   if (e->delete_me || (!first_run)) return;
    _evas_walk(e);
+   first_run = 0;
    EINA_LIST_FREE(e->post_events, pc)
      {
         if ((!skip) && (!e->delete_me) && (!pc->delete_me))
@@ -25,6 +28,7 @@ _evas_post_event_callback_call(Evas *e)
           }
         EVAS_MEMPOOL_FREE(_mp_pc, pc);
      }
+   first_run = 1;
    _evas_unwalk(e);
 }
 
index b1ff8c2..116749c 100644 (file)
@@ -7,7 +7,7 @@ evas_object_clip_dirty(Evas_Object *obj)
    Eina_List *l;
    Evas_Object *data;
 
-   if (obj->cur.cache.clip.dirty) return ;
+   if (obj->cur.cache.clip.dirty) return;
 
    obj->cur.cache.clip.dirty = 1;
    EINA_LIST_FOREACH(obj->clip.clipees, l, data)
@@ -22,9 +22,9 @@ evas_object_recalc_clippees(Evas_Object *obj)
 
    if (obj->cur.cache.clip.dirty)
      {
-       evas_object_clip_recalc(obj);
-       EINA_LIST_FOREACH(obj->clip.clipees, l, data)
-         evas_object_recalc_clippees(data);
+        evas_object_clip_recalc(obj);
+        EINA_LIST_FOREACH(obj->clip.clipees, l, data)
+          evas_object_recalc_clippees(data);
      }
 }
 
@@ -33,20 +33,20 @@ evas_object_clippers_was_visible(Evas_Object *obj)
 {
    if (obj->prev.visible)
      {
-       if (obj->prev.clipper)
-         return evas_object_clippers_is_visible(obj->prev.clipper);
-       return 1;
+        if (obj->prev.clipper)
+          return evas_object_clippers_is_visible(obj->prev.clipper);
+        return 1;
      }
    return 0;
 }
 
 /* aaaaargh (pirate voice) ... notes!
- * 
+ *
  * we have a big problem until now that's gone undetected... until yesterday.
  * that problem involves clips and maps and smart objects. hooray! 3 of the
  * more complex bits of evas - and maps and smart objects  being one of the
  * nastiest ones.
- * 
+ *
  * what is the problem? when a clip crosses a map boundary. that is to say
  * that when the clipper and clippee are not within the child tree of the
  * mapped object. in this case "bad stuff" happens. basically as clips are
@@ -63,22 +63,31 @@ evas_object_clippers_was_visible(Evas_Object *obj)
  * thats silly-expensive and i was about to fix it that way but it has since
  * dawned on me that that is just going to kill performance in some critical
  * areas like during object setup and manipulation, as well as teardown.
- * 
+ *
  * aaaaagh! best for now is to document this as a "don't do it damnit!" thing
  * and have the apps avoid it. but even then - how to do this? this is not
  * easy. everywhere i turn so far i come up to either expensive operations,
  * breaks in logic, or nasty re-work of apps or4 the whole concept of clipping,
  * smart objects and maps... and that will have to wait for evas 2.0
- * 
+ *
  * the below does clip fixups etc. in the even a clip spans a map boundary.
  * not pretty, but necessary.
  */
 
 #define MAP_ACROSS 1
 static void
-evas_object_child_map_across_mark(Evas_Object *obj, Evas_Object *map_obj, Eina_Bool force)
+evas_object_child_map_across_mark(Evas_Object *obj, Evas_Object *map_obj, Eina_Bool force, Eina_Hash *visited)
 {
 #ifdef MAP_ACROSS
+   Eina_Bool clear_visited = EINA_FALSE;
+   if (!visited)
+     {
+        visited = eina_hash_pointer_new(NULL);
+        clear_visited = EINA_TRUE;
+     }
+   if (eina_hash_find(visited, &obj) == (void *)1) goto end;
+   else eina_hash_add(visited, &obj, (void *)1);
+
    if ((obj->cur.map_parent != map_obj) || force)
      {
         obj->cur.map_parent = map_obj;
@@ -87,24 +96,26 @@ evas_object_child_map_across_mark(Evas_Object *obj, Evas_Object *map_obj, Eina_B
         if (obj->smart.smart)
           {
              Evas_Object *obj2;
-             
+
              EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
                {
                   // if obj has its own map - skip it. already done
                   if ((obj2->cur.map) && (obj2->cur.usemap)) continue;
-                  evas_object_child_map_across_mark(obj2, map_obj, force);
+                  evas_object_child_map_across_mark(obj2, map_obj, force, visited);
                }
           }
         else if (obj->clip.clipees)
           {
              Eina_List *l;
              Evas_Object *obj2;
-             
+
              EINA_LIST_FOREACH(obj->clip.clipees, l, obj2)
-                evas_object_child_map_across_mark(obj2, map_obj, force);
+               evas_object_child_map_across_mark(obj2, map_obj, force, visited);
           }
      }
-#endif   
+end:
+   if (clear_visited) eina_hash_free(visited);
+#endif
 }
 
 void
@@ -113,8 +124,8 @@ evas_object_clip_across_check(Evas_Object *obj)
 #ifdef MAP_ACROSS
    if (!obj->cur.clipper) return;
    if (obj->cur.clipper->cur.map_parent != obj->cur.map_parent)
-      evas_object_child_map_across_mark(obj, obj->cur.map_parent, 1);
-#endif   
+     evas_object_child_map_across_mark(obj, obj->cur.map_parent, 1, NULL);
+#endif
 }
 
 void
@@ -126,40 +137,61 @@ evas_object_clip_across_clippees_check(Evas_Object *obj)
 
    if (!obj->clip.clipees) return;
 // schloooooooooooow:
-//   evas_object_child_map_across_mark(obj, obj->cur.map_parent, 1);
+//   evas_object_child_map_across_mark(obj, obj->cur.map_parent, 1, NULL);
 // buggy:
-   evas_object_child_map_across_mark(obj, obj->cur.map_parent, 0);
+   evas_object_child_map_across_mark(obj, obj->cur.map_parent, 0, NULL);
    if (obj->cur.cache.clip.dirty)
      {
-       EINA_LIST_FOREACH(obj->clip.clipees, l, obj2)
-           evas_object_clip_across_clippees_check(obj2);
+        EINA_LIST_FOREACH(obj->clip.clipees, l, obj2)
+          evas_object_clip_across_clippees_check(obj2);
      }
-#endif   
+#endif
 }
 
 // this function is called on an object when map is enabled or disabled on it
 // thus creating a "map boundary" at that point.
-// 
+//
 // FIXME: flip2 test broken in elm - might be show/hide of clips
 void
 evas_object_mapped_clip_across_mark(Evas_Object *obj)
 {
 #ifdef MAP_ACROSS
    if ((obj->cur.map) && (obj->cur.usemap))
-      evas_object_child_map_across_mark(obj, obj, 0);
+     evas_object_child_map_across_mark(obj, obj, 0, NULL);
    else
      {
         if (obj->smart.parent)
-           evas_object_child_map_across_mark
-           (obj, obj->smart.parent->cur.map_parent, 0);
+          evas_object_child_map_across_mark
+            (obj, obj->smart.parent->cur.map_parent, 0, NULL);
         else
-           evas_object_child_map_across_mark(obj, NULL, 0);
-    }
+          evas_object_child_map_across_mark(obj, NULL, 0, NULL);
+     }
 #endif
 }
 
+static void
+_evas_object_clip_mask_unset(Evas_Object *obj)
+{
+   if (!obj || !obj->mask.is_mask) return;
+   if (obj->clip.clipees) return;
+
+   /* this frees the clip surface. is this correct? */
+   obj->mask.is_mask = EINA_FALSE;
+   obj->mask.redraw = EINA_FALSE;
+   obj->mask.is_alpha = EINA_FALSE;
+   if (obj->mask.surface)
+     {
+        obj->layer->evas->engine.func->image_map_surface_free
+           (obj->layer->evas->engine.data.output, obj->mask.surface);
+        obj->mask.surface = NULL;
+     }
+   obj->mask.w = 0;
+   obj->mask.h = 0;
+}
+
 /* public functions */
 extern const char *o_rect_type;
+extern const char *o_image_type;
 
 EAPI void
 evas_object_clip_set(Evas_Object *obj, Evas_Object *clip)
@@ -169,8 +201,8 @@ evas_object_clip_set(Evas_Object *obj, Evas_Object *clip)
    MAGIC_CHECK_END();
    if (!clip)
      {
-       evas_object_clip_unset(obj);
-       return;
+        evas_object_clip_unset(obj);
+        return;
      }
    MAGIC_CHECK(clip, Evas_Object, MAGIC_OBJ);
    return;
@@ -209,43 +241,40 @@ evas_object_clip_set(Evas_Object *obj, Evas_Object *clip)
 
    if (evas_object_intercept_call_clip_set(obj, clip)) return;
    // illegal to set anything but a rect as a clip
-   if (clip->type != o_rect_type)
+   if (clip->type != o_rect_type && clip->type != o_image_type)
      {
-        ERR("For now a clip on other object than a rectangle is disabled");
+        ERR("For now a clip on other object than a rectangle or an image is disabled");
         return;
      }
    if (obj->smart.smart)
      {
-       if (obj->smart.smart->smart_class->clip_set)
-         obj->smart.smart->smart_class->clip_set(obj, clip);
+        if (obj->smart.smart->smart_class->clip_set)
+          obj->smart.smart->smart_class->clip_set(obj, clip);
      }
    if (obj->cur.clipper)
      {
-       /* unclip */
-       obj->cur.clipper->clip.clipees = eina_list_remove(obj->cur.clipper->clip.clipees, obj);
-       if (!obj->cur.clipper->clip.clipees)
-         {
-            obj->cur.clipper->cur.have_clipees = 0;
-            if (obj->cur.clipper->cur.visible)
-              evas_damage_rectangle_add(obj->cur.clipper->layer->evas,
-                                        obj->cur.clipper->cur.geometry.x,
-                                        obj->cur.clipper->cur.geometry.y,
-                                        obj->cur.clipper->cur.geometry.w,
-                                        obj->cur.clipper->cur.geometry.h);
-         }
-       evas_object_change(obj->cur.clipper);
-       evas_object_change(obj);
-       obj->cur.clipper = NULL;
+        /* unclip */
+        obj->cur.clipper->clip.clipees = eina_list_remove(obj->cur.clipper->clip.clipees, obj);
+        if (!obj->cur.clipper->clip.clipees)
+          {
+             obj->cur.clipper->cur.have_clipees = 0;
+             _evas_object_clip_mask_unset(obj->cur.clipper);
+          }
+        evas_object_change(obj->cur.clipper);
+        evas_object_change(obj);
+        obj->cur.clipper = NULL;
      }
+
+   /* image object clipper */
+   if (clip->type == o_image_type)
+     clip->mask.is_mask = EINA_TRUE;
+
    /* clip me */
    if ((!clip->clip.clipees) && (clip->cur.visible))
      {
-       /* Basically it just went invisible */
-       clip->changed = 1;
-       clip->layer->evas->changed = 1;
-       evas_damage_rectangle_add(clip->layer->evas,
-                                 clip->cur.geometry.x, clip->cur.geometry.y,
-                                 clip->cur.geometry.w, clip->cur.geometry.h);
+        /* Basically it just went invisible */
+        clip->changed = 1;
+        clip->layer->evas->changed = 1;
      }
    obj->cur.clipper = clip;
    clip->clip.clipees = eina_list_append(clip->clip.clipees, obj);
@@ -256,35 +285,21 @@ evas_object_clip_set(Evas_Object *obj, Evas_Object *clip)
           evas_object_update_bounding_box(clip);
      }
 
-   /* If it's NOT a rectangle set the mask bits too */
-   /* FIXME: Optmz ths chck */
-   if (clip->type == o_rect_type)
-      obj->cur.mask = NULL;
-   else
-     {
-       void *engdata;
-        obj->cur.mask = clip;
-       engdata = clip->func->engine_data_get(clip);
-       /* FIXME: Images only */
-       clip->layer->evas->engine.func->image_mask_create(
-                                     clip->layer->evas->engine.data.output,
-                                     engdata);
-     }
    evas_object_change(clip);
    evas_object_change(obj);
    evas_object_clip_dirty(obj);
    evas_object_recalc_clippees(obj);
-   if ((!obj->smart.smart) && 
+   if ((!obj->smart.smart) &&
        (!((obj->cur.map) && (obj->cur.usemap))))
      {
-       if (evas_object_is_in_output_rect(obj,
-                                         obj->layer->evas->pointer.x,
-                                         obj->layer->evas->pointer.y, 1, 1))
-         evas_event_feed_mouse_move(obj->layer->evas,
-                                    obj->layer->evas->pointer.x,
-                                    obj->layer->evas->pointer.y,
-                                    obj->layer->evas->last_timestamp,
-                                    NULL);
+        if (evas_object_is_in_output_rect(obj,
+                                          obj->layer->evas->pointer.x,
+                                          obj->layer->evas->pointer.y, 1, 1))
+          evas_event_feed_mouse_move(obj->layer->evas,
+                                     obj->layer->evas->pointer.x,
+                                     obj->layer->evas->pointer.y,
+                                     obj->layer->evas->last_timestamp,
+                                     NULL);
      }
    evas_object_clip_across_check(obj);
 }
@@ -309,39 +324,34 @@ evas_object_clip_unset(Evas_Object *obj)
    if (evas_object_intercept_call_clip_unset(obj)) return;
    if (obj->smart.smart)
      {
-       if (obj->smart.smart->smart_class->clip_unset)
-         obj->smart.smart->smart_class->clip_unset(obj);
+        if (obj->smart.smart->smart_class->clip_unset)
+          obj->smart.smart->smart_class->clip_unset(obj);
      }
    if (obj->cur.clipper)
      {
         obj->cur.clipper->clip.clipees = eina_list_remove(obj->cur.clipper->clip.clipees, obj);
-       if (!obj->cur.clipper->clip.clipees)
-         {
-            obj->cur.clipper->cur.have_clipees = 0;
-            if (obj->cur.clipper->cur.visible)
-              evas_damage_rectangle_add(obj->cur.clipper->layer->evas,
-                                        obj->cur.clipper->cur.geometry.x,
-                                        obj->cur.clipper->cur.geometry.y,
-                                        obj->cur.clipper->cur.geometry.w,
-                                        obj->cur.clipper->cur.geometry.h);
-         }
-       evas_object_change(obj->cur.clipper);
+        if (!obj->cur.clipper->clip.clipees)
+          {
+             obj->cur.clipper->cur.have_clipees = 0;
+             _evas_object_clip_mask_unset(obj->cur.clipper);
+          }
+        evas_object_change(obj->cur.clipper);
      }
    obj->cur.clipper = NULL;
    evas_object_change(obj);
    evas_object_clip_dirty(obj);
    evas_object_recalc_clippees(obj);
-   if ((!obj->smart.smart) && 
+   if ((!obj->smart.smart) &&
        (!((obj->cur.map) && (obj->cur.usemap))))
      {
-       if (evas_object_is_in_output_rect(obj,
-                                         obj->layer->evas->pointer.x,
-                                         obj->layer->evas->pointer.y, 1, 1))
-         evas_event_feed_mouse_move(obj->layer->evas,
-                                    obj->layer->evas->pointer.x,
-                                    obj->layer->evas->pointer.y,
+        if (evas_object_is_in_output_rect(obj,
+                                          obj->layer->evas->pointer.x,
+                                          obj->layer->evas->pointer.y, 1, 1))
+          evas_event_feed_mouse_move(obj->layer->evas,
+                                     obj->layer->evas->pointer.x,
+                                     obj->layer->evas->pointer.y,
                                      obj->layer->evas->last_timestamp,
-                                    NULL);
+                                     NULL);
      }
    evas_object_clip_across_check(obj);
 }
@@ -354,3 +364,4 @@ evas_object_clipees_get(const Evas_Object *obj)
    MAGIC_CHECK_END();
    return obj->clip.clipees;
 }
+
diff --git a/src/lib/canvas/evas_device.c b/src/lib/canvas/evas_device.c
new file mode 100644 (file)
index 0000000..95204be
--- /dev/null
@@ -0,0 +1,253 @@
+#include "evas_common.h"
+#include "evas_private.h"
+
+EAPI Evas_Device *
+evas_device_new(Evas *e)
+{
+   Evas_Device *dev;
+   
+   MAGIC_CHECK(e, Evas, MAGIC_EVAS);
+   return NULL;
+   MAGIC_CHECK_END();
+   dev = calloc(1, sizeof(Evas_Device));
+   if (!dev) return NULL;
+   dev->magic = MAGIC_DEV;
+   dev->evas = e;
+   dev->ref = 1;
+   e->devices = eina_list_append(e->devices, dev);
+   evas_event_callback_call(e, EVAS_CALLBACK_DEVICE_CHANGED, dev);
+   return dev;
+}
+
+EAPI void
+evas_device_free(Evas_Device *dev)
+{
+   MAGIC_CHECK(dev, Evas_Device, MAGIC_DEV);
+   return;
+   MAGIC_CHECK_END();
+   if (dev->ref == 1)
+     {
+        Evas_Device *dev2;
+        
+        EINA_LIST_FREE(dev->children, dev2)
+          {
+             dev2->parent = NULL;
+             evas_device_free(dev2);
+          }
+        if (dev->src)
+          {
+             _evas_device_unref(dev->src);
+             dev->src = NULL;
+          }
+        dev->parent = NULL;
+     }
+   _evas_device_unref(dev);
+}
+
+EAPI void
+evas_device_push(Evas *e, Evas_Device *dev)
+{
+   MAGIC_CHECK(e, Evas, MAGIC_EVAS);
+   return;
+   MAGIC_CHECK_END();
+   MAGIC_CHECK(dev, Evas_Device, MAGIC_DEV);
+   return;
+   MAGIC_CHECK_END();
+   if (!e->cur_device)
+     {
+        e->cur_device = eina_array_new(4);
+        if (!e->cur_device) return;
+     }
+   dev->ref++;
+   eina_array_push(e->cur_device, dev);
+}
+
+EAPI void
+evas_device_pop(Evas *e)
+{
+   Evas_Device *dev;
+   
+   MAGIC_CHECK(e, Evas, MAGIC_EVAS);
+   return;
+   MAGIC_CHECK_END();
+   dev = eina_array_pop(e->cur_device);
+   if (dev) _evas_device_unref(dev);
+}
+
+EAPI const Eina_List *
+evas_device_list(Evas *e, const Evas_Device *dev)
+{
+   MAGIC_CHECK(e, Evas, MAGIC_EVAS);
+   return NULL;
+   MAGIC_CHECK_END();
+   if (dev)
+     {
+        MAGIC_CHECK(dev, Evas_Device, MAGIC_DEV);
+        return NULL;
+        MAGIC_CHECK_END();
+     }
+   if (dev) return dev->children;
+   return e->devices;
+}
+
+EAPI void
+evas_device_name_set(Evas_Device *dev, const char *name)
+{
+   MAGIC_CHECK(dev, Evas_Device, MAGIC_DEV);
+   return;
+   MAGIC_CHECK_END();
+   eina_stringshare_replace(&(dev->name), name);
+   evas_event_callback_call(dev->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev);
+}
+
+EAPI const char *
+evas_device_name_get(const Evas_Device *dev)
+{
+   MAGIC_CHECK(dev, Evas_Device, MAGIC_DEV);
+   return NULL;
+   MAGIC_CHECK_END();
+   return dev->name;
+}
+
+EAPI void
+evas_device_description_set(Evas_Device *dev, const char *desc)
+{
+   MAGIC_CHECK(dev, Evas_Device, MAGIC_DEV);
+   return;
+   MAGIC_CHECK_END();
+   eina_stringshare_replace(&(dev->desc), desc);
+   evas_event_callback_call(dev->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev);
+}
+
+EAPI const char *
+evas_device_description_get(const Evas_Device *dev)
+{
+   MAGIC_CHECK(dev, Evas_Device, MAGIC_DEV);
+   return NULL;
+   MAGIC_CHECK_END();
+   return dev->desc;
+}
+
+EAPI void
+evas_device_parent_set(Evas_Device *dev, Evas_Device *parent)
+{
+   MAGIC_CHECK(dev, Evas_Device, MAGIC_DEV);
+   return;
+   MAGIC_CHECK_END();
+   if (parent)
+     {
+        MAGIC_CHECK(parent, Evas_Device, MAGIC_DEV);
+        return;
+        MAGIC_CHECK_END();
+     }
+   if (dev->parent == parent) return;
+   if (dev->parent)
+     dev->parent->children = eina_list_remove(dev->parent->children, dev);
+   dev->parent = parent;
+   if (parent)
+     parent->children = eina_list_append(parent->children, dev);
+   evas_event_callback_call(dev->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev);
+}
+
+EAPI const Evas_Device *
+evas_device_parent_get(const Evas_Device *dev)
+{
+   MAGIC_CHECK(dev, Evas_Device, MAGIC_DEV);
+   return NULL;
+   MAGIC_CHECK_END();
+   return dev->parent;
+}
+
+EAPI void
+evas_device_class_set(Evas_Device *dev, Evas_Device_Class clas)
+{
+   MAGIC_CHECK(dev, Evas_Device, MAGIC_DEV);
+   return;
+   MAGIC_CHECK_END();
+   dev->clas = clas;
+   evas_event_callback_call(dev->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev);
+}
+
+EAPI Evas_Device_Class
+evas_device_class_get(const Evas_Device *dev)
+{
+   MAGIC_CHECK(dev, Evas_Device, MAGIC_DEV);
+   return EVAS_DEVICE_CLASS_NONE;
+   MAGIC_CHECK_END();
+   return dev->clas;
+}
+
+EAPI void
+evas_device_emulation_source_set(Evas_Device *dev, Evas_Device *src)
+{
+   MAGIC_CHECK(dev, Evas_Device, MAGIC_DEV);
+   return;
+   MAGIC_CHECK_END();
+   if (src)
+     {
+        MAGIC_CHECK(src, Evas_Device, MAGIC_DEV);
+        return;
+        MAGIC_CHECK_END();
+     }
+   if (dev->src == src) return;
+   if (dev->src) _evas_device_unref(dev->src);
+   dev->src = src;
+   if (dev->src) dev->src->ref++;
+   evas_event_callback_call(dev->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev);
+}
+
+EAPI const Evas_Device *
+evas_device_emulation_source_get(const Evas_Device *dev)
+{
+   MAGIC_CHECK(dev, Evas_Device, MAGIC_DEV);
+   return NULL;
+   MAGIC_CHECK_END();
+   return dev->src;
+}
+
+void
+_evas_device_cleanup(Evas *e)
+{
+   Evas_Device *dev;
+   
+   if (e->cur_device)
+     {
+        while ((dev = eina_array_pop(e->cur_device)))
+          _evas_device_unref(dev);
+        eina_array_free(e->cur_device);
+        e->cur_device = NULL;
+     }
+   EINA_LIST_FREE(e->devices, dev)
+     {
+        evas_device_free(dev);
+     }
+}
+
+Evas_Device *
+_evas_device_top_get(const Evas *e)
+{
+   int num;
+   
+   if (!e->cur_device) return NULL;
+   num = eina_array_count(e->cur_device);
+   if (num < 1) return NULL;
+   return eina_array_data_get(e->cur_device, num - 1);
+}
+
+void
+_evas_device_ref(Evas_Device *dev)
+{
+   dev->ref++;
+}
+
+void
+_evas_device_unref(Evas_Device *dev)
+{
+   dev->ref--;
+   if (dev->ref > 0) return;
+   if (dev->name) eina_stringshare_del(dev->name);
+   if (dev->desc) eina_stringshare_del(dev->desc);
+   dev->magic = 0;
+   free(dev);
+}
+
old mode 100644 (file)
new mode 100755 (executable)
index 20a0a32..1c99a81
@@ -15,9 +15,26 @@ _evas_event_havemap_adjust(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Eina_
    if ((!obj->cur.usemap) || (!obj->cur.map) || (!obj->cur.map->count == 4))
       return;
 
-   evas_map_coords_get(obj->cur.map, *x, *y, x, y, mouse_grabbed);
-   *x += obj->cur.geometry.x;
-   *y += obj->cur.geometry.y;
+   if(evas_map_coords_get(obj->cur.map, *x, *y, x, y, mouse_grabbed))
+     {
+        *x += obj->cur.geometry.x;
+        *y += obj->cur.geometry.y;
+     }
+}
+
+static void
+_evas_event_framespace_adjust(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+  if (obj->is_frame) return;
+  
+  if ((!obj->smart.parent) && (obj->smart.smart))
+    {
+       Evas *evas;
+
+       evas = obj->layer->evas;
+       if (x) *x -= evas->framespace.x;
+       if (y) *y -= evas->framespace.y;
+    }
 }
 
 static Eina_List *
@@ -25,7 +42,7 @@ _evas_event_object_list_raw_in_get(Evas *e, Eina_List *in,
                                    const Eina_Inlist *list, Evas_Object *stop,
                                    int x, int y, int *no_rep)
 {
-   Evas_Object *obj;
+   Evas_Object *obj = NULL;
    int inside;
 
    if (!list) return in;
@@ -39,14 +56,20 @@ _evas_event_object_list_raw_in_get(Evas *e, Eina_List *in,
              return in;
           }
         if (evas_event_passes_through(obj)) continue;
+        if (evas_object_is_source_invisible(obj)) continue;
         if ((obj->cur.visible) && (obj->delete_me == 0) &&
             (!obj->clip.clipees) &&
             (evas_object_clippers_is_visible(obj)))
           {
              if (obj->smart.smart)
                {
+                  Evas_Object *clip = obj->cur.clipper;
                   int norep = 0;
 
+                  if (clip && clip->mask.is_mask && clip->precise_is_inside)
+                    if (!evas_object_is_inside(clip, x, y))
+                      continue;
+
                   if ((obj->cur.usemap) && (obj->cur.map) &&
                       (obj->cur.map->count == 4))
                     {
@@ -81,7 +104,7 @@ _evas_event_object_list_raw_in_get(Evas *e, Eina_List *in,
                             obj->cur.bounding_box.y <= y &&
                             obj->cur.bounding_box.y + obj->cur.bounding_box.h >= y) ||
                            (obj->cur.geometry.x <= x &&
-                            obj->cur.geometry.y + obj->cur.geometry.w >= x &&
+                            obj->cur.geometry.x + obj->cur.geometry.w >= x &&
                             obj->cur.geometry.y <= y &&
                             obj->cur.geometry.y + obj->cur.geometry.h >= y))
                          in = _evas_event_object_list_in_get
@@ -99,7 +122,11 @@ _evas_event_object_list_raw_in_get(Evas *e, Eina_List *in,
                }
              else
                {
-                  inside = evas_object_is_in_output_rect(obj, x, y, 1, 1);
+                  Evas_Object *clip = obj->cur.clipper;
+                  if (clip && clip->mask.is_mask && clip->precise_is_inside)
+                    inside = evas_object_is_inside(clip, x, y);
+                  else
+                    inside = evas_object_is_in_output_rect(obj, x, y, 1, 1);
 
                   if (inside)
                     {
@@ -137,18 +164,18 @@ _evas_event_object_list_in_get(Evas *e, Eina_List *in,
                                const Eina_Inlist *list, Evas_Object *stop,
                                int x, int y, int *no_rep)
 {
-   if (!list) return NULL;
+   if (!list) return in;
    return _evas_event_object_list_raw_in_get(e, in, list->last, stop, x, y,
                                              no_rep);
 }
 
 Eina_List *
-evas_event_objects_event_list(Evas *e, Evas_Object *stop, int x, int y)
+_evas_event_objects_event_list_no_frozen_check(Evas *e, Evas_Object *stop, int x, int y)
 {
    Evas_Layer *lay;
    Eina_List *in = NULL;
 
-   if ((!e->layers) || (e->events_frozen > 0)) return NULL;
+   if (!e->layers) return NULL;
    EINA_INLIST_REVERSE_FOREACH((EINA_INLIST_GET(e->layers)), lay)
      {
         int no_rep = 0;
@@ -160,6 +187,22 @@ evas_event_objects_event_list(Evas *e, Evas_Object *stop, int x, int y)
    return in;
 }
 
+EAPI Eina_List *
+evas_tree_objects_at_xy_get(Evas *e, Evas_Object *stop, int x, int y)
+{
+   MAGIC_CHECK(e, Evas, MAGIC_EVAS);
+   return NULL;
+   MAGIC_CHECK_END();
+   return _evas_event_objects_event_list_no_frozen_check(e, stop, x, y);
+}
+
+Eina_List *
+evas_event_objects_event_list(Evas *e, Evas_Object *stop, int x, int y)
+{
+   if ((!e->layers) || (e->events_frozen > 0)) return NULL;
+   return _evas_event_objects_event_list_no_frozen_check(e, stop, x, y);
+}
+
 static Eina_List *
 evas_event_list_copy(Eina_List *list)
 {
@@ -258,7 +301,7 @@ evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags, unsigned int
    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
    return;
    MAGIC_CHECK_END();
-
+   INF("ButtonEvent:down time=%u button=%d downs=%d", timestamp, b, e->pointer.downs);
    if ((b < 1) || (b > 32)) return;
 
    e->pointer.button |= (1 << (b - 1));
@@ -281,6 +324,8 @@ evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags, unsigned int
    ev.flags = flags;
    ev.timestamp = timestamp;
    ev.event_flags = e->default_event_flags;
+   ev.dev = _evas_device_top_get(e);
+   if (ev.dev) _evas_device_ref(ev.dev);
 
    _evas_walk(e);
    /* append new touch point to the touch point list */
@@ -321,6 +366,7 @@ evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags, unsigned int
         if (obj->delete_me) continue;
         ev.canvas.x = e->pointer.x;
         ev.canvas.y = e->pointer.y;
+        _evas_event_framespace_adjust(obj, &ev.canvas.x, &ev.canvas.y);
         _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y, obj->mouse_grabbed);
 
         if (e->events_frozen <= 0)
@@ -334,6 +380,7 @@ evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags, unsigned int
    _evas_post_event_callback_call(e);
    /* update touch point's state to EVAS_TOUCH_POINT_STILL */
    _evas_touch_point_update(e, 0, e->pointer.x, e->pointer.y, EVAS_TOUCH_POINT_STILL);
+   if (ev.dev) _evas_device_unref(ev.dev);
    _evas_unwalk(e);
 }
 
@@ -359,7 +406,9 @@ _post_up_handle(Evas *e, unsigned int timestamp, const void *data)
    ev.locks = &(e->locks);
    ev.timestamp = timestamp;
    ev.event_flags = e->default_event_flags;
-
+   ev.dev = _evas_device_top_get(e);
+   if (ev.dev) _evas_device_ref(ev.dev);
+   
    /* get new list of ins */
    ins = evas_event_objects_event_list(e, NULL, e->pointer.x, e->pointer.y);
    /* go thru old list of in objects */
@@ -368,6 +417,7 @@ _post_up_handle(Evas *e, unsigned int timestamp, const void *data)
      {
         ev.canvas.x = e->pointer.x;
         ev.canvas.y = e->pointer.y;
+        _evas_event_framespace_adjust(obj, &ev.canvas.x, &ev.canvas.y);
         _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y, obj->mouse_grabbed);
         if ((!eina_list_data_find(ins, obj)) ||
             (!e->pointer.inside))
@@ -407,6 +457,7 @@ _post_up_handle(Evas *e, unsigned int timestamp, const void *data)
           {
              ev_in.canvas.x = e->pointer.x;
              ev_in.canvas.y = e->pointer.y;
+             _evas_event_framespace_adjust(obj_itr, &ev_in.canvas.x, &ev_in.canvas.y);
              _evas_event_havemap_adjust(obj_itr, &ev_in.canvas.x, &ev_in.canvas.y, obj_itr->mouse_grabbed);
              if (!eina_list_data_find(e->pointer.object.in, obj_itr))
                {
@@ -441,6 +492,7 @@ _post_up_handle(Evas *e, unsigned int timestamp, const void *data)
      }
    if (e->pointer.inside)
       evas_event_feed_mouse_move(e, e->pointer.x, e->pointer.y, timestamp, data);
+   if (ev.dev) _evas_device_unref(ev.dev);
    return post_called;
 }
 
@@ -452,7 +504,7 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t
    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
    return;
    MAGIC_CHECK_END();
-
+   INF("ButtonEvent:up time=%u button=%d downs=%d", timestamp, b, e->pointer.downs);
    if ((b < 1) || (b > 32)) return;
    if (e->pointer.downs <= 0) return;
 
@@ -481,7 +533,9 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t
         ev.flags = flags;
         ev.timestamp = timestamp;
         ev.event_flags = e->default_event_flags;
-
+        ev.dev = _evas_device_top_get(e);
+        if (ev.dev) _evas_device_ref(ev.dev);
+        
         _evas_walk(e);
         /* update released touch point */
         _evas_touch_point_update(e, 0, e->pointer.x, e->pointer.y, EVAS_TOUCH_POINT_UP);
@@ -490,6 +544,7 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t
           {
              ev.canvas.x = e->pointer.x;
              ev.canvas.y = e->pointer.y;
+             _evas_event_framespace_adjust(obj, &ev.canvas.x, &ev.canvas.y);
              _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y, obj->mouse_grabbed);
              if ((obj->pointer_mode == EVAS_OBJECT_POINTER_MODE_AUTOGRAB) &&
                  (obj->mouse_grabbed > 0))
@@ -513,6 +568,7 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t
         if (copy) copy = eina_list_free(copy);
         e->last_mouse_up_counter++;
         _evas_post_event_callback_call(e);
+        if (ev.dev) _evas_device_unref(ev.dev);
      }
 
    if (e->pointer.mouse_grabbed == 0)
@@ -535,6 +591,8 @@ EAPI void
 evas_event_feed_mouse_cancel(Evas *e, unsigned int timestamp, const void *data)
 {
    int i;
+   Evas_Coord_Touch_Point *point;
+   Eina_List *l, *ll;
 
    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
    return;
@@ -548,7 +606,13 @@ evas_event_feed_mouse_cancel(Evas *e, unsigned int timestamp, const void *data)
         if ((e->pointer.button & (1 << i)))
           evas_event_feed_mouse_up(e, i + 1, 0, timestamp, data);
      }
-   // FIXME: multi cancel too?
+   EINA_LIST_FOREACH_SAFE(e->touch_points, l, ll, point)
+     {
+        if ((point->state == EVAS_TOUCH_POINT_DOWN) ||
+            (point->state == EVAS_TOUCH_POINT_MOVE))
+          evas_event_feed_multi_up(e, point->id, point->x, point->y,
+                                   0, 0, 0, 0, 0, 0, 0, 0, timestamp, data);
+     }
    _evas_unwalk(e);
 }
 
@@ -581,7 +645,9 @@ evas_event_feed_mouse_wheel(Evas *e, int direction, int z, unsigned int timestam
    ev.locks = &(e->locks);
    ev.timestamp = timestamp;
    ev.event_flags = e->default_event_flags;
-
+   ev.dev = _evas_device_top_get(e);
+   if (ev.dev) _evas_device_ref(ev.dev);
+   
    _evas_walk(e);
    copy = evas_event_list_copy(e->pointer.object.in);
 
@@ -589,6 +655,7 @@ evas_event_feed_mouse_wheel(Evas *e, int direction, int z, unsigned int timestam
      {
         ev.canvas.x = e->pointer.x;
         ev.canvas.y = e->pointer.y;
+        _evas_event_framespace_adjust(obj, &ev.canvas.x, &ev.canvas.y);
         _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y, obj->mouse_grabbed);
         if ((e->events_frozen <= 0) && !evas_event_freezes_through(obj))
           evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_WHEEL, &ev, event_id);
@@ -597,6 +664,7 @@ evas_event_feed_mouse_wheel(Evas *e, int direction, int z, unsigned int timestam
    if (copy) copy = eina_list_free(copy);
    _evas_post_event_callback_call(e);
 
+   if (ev.dev) _evas_device_unref(ev.dev);
    _evas_unwalk(e);
 }
 
@@ -659,11 +727,14 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
              ev.locks = &(e->locks);
              ev.timestamp = timestamp;
              ev.event_flags = e->default_event_flags;
+             ev.dev = _evas_device_top_get(e);
+             if (ev.dev) _evas_device_ref(ev.dev);
              copy = evas_event_list_copy(e->pointer.object.in);
              EINA_LIST_FOREACH(copy, l, obj)
                {
                   ev.cur.canvas.x = e->pointer.x;
                   ev.cur.canvas.y = e->pointer.y;
+                  _evas_event_framespace_adjust(obj, &ev.cur.canvas.x, &ev.cur.canvas.y);
                   _evas_event_havemap_adjust(obj, &ev.cur.canvas.x,
                                              &ev.cur.canvas.y,
                                              obj->mouse_grabbed);
@@ -672,6 +743,8 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
                        obj->mouse_grabbed) &&
                       (!evas_event_passes_through(obj)) &&
                       (!evas_event_freezes_through(obj)) &&
+                      (!evas_object_is_source_invisible(obj) ||
+                       obj->mouse_grabbed) &&
                       (!obj->clip.clipees))
                     {
                        if ((px != x) || (py != y))
@@ -689,6 +762,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
                   if (e->delete_me) break;
                }
              _evas_post_event_callback_call(e);
+             if (ev.dev) _evas_device_unref(ev.dev);
           }
           {
              Evas_Event_Mouse_Out ev;
@@ -707,7 +781,9 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
              ev.locks = &(e->locks);
              ev.timestamp = timestamp;
              ev.event_flags = e->default_event_flags;
-
+             ev.dev = _evas_device_top_get(e);
+             if (ev.dev) _evas_device_ref(ev.dev);
+             
              if (copy) eina_list_free(copy);
              while (outs)
                {
@@ -719,6 +795,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
                     {
                        ev.canvas.x = e->pointer.x;
                        ev.canvas.y = e->pointer.y;
+                       _evas_event_framespace_adjust(obj, &ev.canvas.x, &ev.canvas.y);
                        _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y, obj->mouse_grabbed);
                        e->pointer.object.in = eina_list_remove(e->pointer.object.in, obj);
                        if (obj->mouse_in)
@@ -733,6 +810,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
                     }
                }
              _evas_post_event_callback_call(e);
+             if (ev.dev) _evas_device_unref(ev.dev);
           }
      }
    else
@@ -762,7 +840,9 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
         ev.locks = &(e->locks);
         ev.timestamp = timestamp;
         ev.event_flags = e->default_event_flags;
-
+        ev.dev = _evas_device_top_get(e);
+        if (ev.dev) _evas_device_ref(ev.dev);
+        
         ev2.buttons = e->pointer.button;
         ev2.output.x = e->pointer.x;
         ev2.output.y = e->pointer.y;
@@ -773,6 +853,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
         ev2.locks = &(e->locks);
         ev2.timestamp = timestamp;
         ev2.event_flags = e->default_event_flags;
+        ev2.dev = ev.dev;
 
         ev3.buttons = e->pointer.button;
         ev3.output.x = e->pointer.x;
@@ -784,6 +865,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
         ev3.locks = &(e->locks);
         ev3.timestamp = timestamp;
         ev3.event_flags = e->default_event_flags;
+        ev3.dev = ev.dev;
 
         /* get all new in objects */
         ins = evas_event_objects_event_list(e, NULL, x, y);
@@ -802,6 +884,8 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
                  eina_list_data_find(ins, obj) &&
                  (!evas_event_passes_through(obj)) &&
                  (!evas_event_freezes_through(obj)) &&
+                 (!evas_object_is_source_invisible(obj) ||
+                  obj->mouse_grabbed) &&
                  (!obj->clip.clipees) &&
                  ((!obj->precise_is_inside) || evas_object_is_inside(obj, x, y))
                 )
@@ -822,6 +906,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
                        obj->mouse_in = 0;
                        ev2.canvas.x = e->pointer.x;
                        ev2.canvas.y = e->pointer.y;
+                       _evas_event_framespace_adjust(obj, &ev2.canvas.x, &ev2.canvas.y);
                        _evas_event_havemap_adjust(obj, &ev2.canvas.x, &ev2.canvas.y, obj->mouse_grabbed);
                        if (e->events_frozen <= 0)
                           evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_OUT, &ev2, event_id);
@@ -840,6 +925,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
           {
              ev3.canvas.x = e->pointer.x;
              ev3.canvas.y = e->pointer.y;
+             _evas_event_framespace_adjust(obj, &ev3.canvas.x, &ev3.canvas.y);
              _evas_event_havemap_adjust(obj, &ev3.canvas.x, &ev3.canvas.y, obj->mouse_grabbed);
              /* if its not in the old list of ins send an enter event */
              if (!eina_list_data_find(e->pointer.object.in, obj))
@@ -866,6 +952,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
              eina_list_free(ins);
           }
         _evas_post_event_callback_call(e);
+        if (ev.dev) _evas_device_unref(ev.dev);
      }
    _evas_unwalk(e); 
    return;
@@ -898,7 +985,9 @@ nogrep:
         ev.locks = &(e->locks);
         ev.timestamp = timestamp;
         ev.event_flags = e->default_event_flags;
-
+        ev.dev = _evas_device_top_get(e);
+        if (ev.dev) _evas_device_ref(ev.dev);
+        
         ev2.buttons = e->pointer.button;
         ev2.output.x = e->pointer.x;
         ev2.output.y = e->pointer.y;
@@ -909,7 +998,8 @@ nogrep:
         ev2.locks = &(e->locks);
         ev2.timestamp = timestamp;
         ev2.event_flags = e->default_event_flags;
-
+        ev2.dev = ev.dev;
+        
         ev3.buttons = e->pointer.button;
         ev3.output.x = e->pointer.x;
         ev3.output.y = e->pointer.y;
@@ -920,6 +1010,7 @@ nogrep:
         ev3.locks = &(e->locks);
         ev3.timestamp = timestamp;
         ev3.event_flags = e->default_event_flags;
+        ev3.dev = ev.dev;
 
         /* go thru old list of in objects */
         copy = evas_event_list_copy(e->pointer.object.in);
@@ -963,6 +1054,8 @@ nogrep:
                  eina_list_data_find(newin, obj) &&
                  (!evas_event_passes_through(obj)) &&
                  (!evas_event_freezes_through(obj)) &&
+                 (!evas_object_is_source_invisible(obj) ||
+                  obj->mouse_grabbed) &&
                  (!obj->clip.clipees) &&
                  ((!obj->precise_is_inside) || evas_object_is_inside(obj, x, y))
                 )
@@ -971,6 +1064,7 @@ nogrep:
                     {
                        ev.cur.canvas.x = e->pointer.x;
                        ev.cur.canvas.y = e->pointer.y;
+                       _evas_event_framespace_adjust(obj, &ev.cur.canvas.x, &ev.cur.canvas.y);
                        _evas_event_havemap_adjust(obj, &ev.cur.canvas.x, &ev.cur.canvas.y, obj->mouse_grabbed);
                        evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_MOVE, &ev, event_id);
                     }
@@ -983,6 +1077,7 @@ nogrep:
                        obj->mouse_in = 0;
                        ev2.canvas.x = e->pointer.x;
                        ev2.canvas.y = e->pointer.y;
+                       _evas_event_framespace_adjust(obj, &ev2.canvas.x, &ev2.canvas.y);
                        _evas_event_havemap_adjust(obj, &ev2.canvas.x, &ev2.canvas.y, obj->mouse_grabbed);
                        if (e->events_frozen <= 0)
                           evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_OUT, &ev2, event_id);
@@ -1001,6 +1096,7 @@ nogrep:
           {
              ev3.canvas.x = e->pointer.x;
              ev3.canvas.y = e->pointer.y;
+             _evas_event_framespace_adjust(obj, &ev3.canvas.x, &ev3.canvas.y);
              _evas_event_havemap_adjust(obj, &ev3.canvas.x, &ev3.canvas.y, obj->mouse_grabbed);
              /* if its not in the old list of ins send an enter event */
              if (!eina_list_data_find(e->pointer.object.in, obj))
@@ -1020,6 +1116,7 @@ nogrep:
         e->pointer.object.in = newin;
 
         _evas_post_event_callback_call(e);
+        if (ev.dev) _evas_device_unref(ev.dev);
      }
    _evas_unwalk(e);
 }
@@ -1056,7 +1153,9 @@ evas_event_feed_mouse_in(Evas *e, unsigned int timestamp, const void *data)
    ev.locks = &(e->locks);
    ev.timestamp = timestamp;
    ev.event_flags = e->default_event_flags;
-
+   ev.dev = _evas_device_top_get(e);
+   if (ev.dev) _evas_device_ref(ev.dev);
+   
    _evas_walk(e);
    /* get new list of ins */
    ins = evas_event_objects_event_list(e, NULL, e->pointer.x, e->pointer.y);
@@ -1064,6 +1163,7 @@ evas_event_feed_mouse_in(Evas *e, unsigned int timestamp, const void *data)
      {
         ev.canvas.x = e->pointer.x;
         ev.canvas.y = e->pointer.y;
+        _evas_event_framespace_adjust(obj, &ev.canvas.x, &ev.canvas.y);
         _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y, obj->mouse_grabbed);
         if (!eina_list_data_find(e->pointer.object.in, obj))
           {
@@ -1082,6 +1182,7 @@ evas_event_feed_mouse_in(Evas *e, unsigned int timestamp, const void *data)
    e->pointer.object.in = ins;
    _evas_post_event_callback_call(e);
    evas_event_feed_mouse_move(e, e->pointer.x, e->pointer.y, timestamp, data);
+   if (ev.dev) _evas_device_unref(ev.dev);
    _evas_unwalk(e);
 }
 
@@ -1112,7 +1213,9 @@ evas_event_feed_mouse_out(Evas *e, unsigned int timestamp, const void *data)
    ev.locks = &(e->locks);
    ev.timestamp = timestamp;
    ev.event_flags = e->default_event_flags;
-
+   ev.dev = _evas_device_top_get(e);
+   if (ev.dev) _evas_device_ref(ev.dev);
+   
    _evas_walk(e);
    /* if our mouse button is inside any objects */
      {
@@ -1125,6 +1228,7 @@ evas_event_feed_mouse_out(Evas *e, unsigned int timestamp, const void *data)
           {
              ev.canvas.x = e->pointer.x;
              ev.canvas.y = e->pointer.y;
+             _evas_event_framespace_adjust(obj, &ev.canvas.x, &ev.canvas.y);
              _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y, obj->mouse_grabbed);
              if (obj->mouse_in)
                {
@@ -1144,6 +1248,7 @@ evas_event_feed_mouse_out(Evas *e, unsigned int timestamp, const void *data)
         e->pointer.mouse_grabbed = 0;
         _evas_post_event_callback_call(e);
      }
+   if (ev.dev) _evas_device_unref(ev.dev);
    _evas_unwalk(e);
 }
 
@@ -1165,7 +1270,7 @@ evas_event_feed_multi_down(Evas *e,
    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
    return;
    MAGIC_CHECK_END();
-
+   INF("ButtonEvent:multi down time=%u device=%d downs=%d", timestamp, d, e->pointer.downs);
    e->pointer.downs++;
    if (e->events_frozen > 0) return;
    e->last_timestamp = timestamp;
@@ -1191,7 +1296,9 @@ evas_event_feed_multi_down(Evas *e,
    ev.flags = flags;
    ev.timestamp = timestamp;
    ev.event_flags = e->default_event_flags;
-
+   ev.dev = _evas_device_top_get(e);
+   if (ev.dev) _evas_device_ref(ev.dev);
+   
    _evas_walk(e);
    /* append new touch point to the touch point list */
    _evas_touch_point_append(e, d, x, y);
@@ -1214,6 +1321,7 @@ evas_event_feed_multi_down(Evas *e,
         ev.canvas.y = y;
         ev.canvas.xsub = fx;
         ev.canvas.ysub = fy;
+        _evas_event_framespace_adjust(obj, &ev.canvas.x, &ev.canvas.y);
         _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y, obj->mouse_grabbed);
         if (x != ev.canvas.x)
           ev.canvas.xsub = ev.canvas.x; // fixme - lost precision
@@ -1227,6 +1335,7 @@ evas_event_feed_multi_down(Evas *e,
    _evas_post_event_callback_call(e);
    /* update touch point's state to EVAS_TOUCH_POINT_STILL */
    _evas_touch_point_update(e, d, x, y, EVAS_TOUCH_POINT_STILL);
+   if (ev.dev) _evas_device_unref(ev.dev);
    _evas_unwalk(e);
 }
 
@@ -1247,7 +1356,7 @@ evas_event_feed_multi_up(Evas *e,
    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
    return;
    MAGIC_CHECK_END();
-
+   INF("ButtonEvent:multi up time=%u device=%d downs=%d", timestamp, d, e->pointer.downs);
    if (e->pointer.downs <= 0) return;
    e->pointer.downs--;
    if (e->events_frozen > 0) return;
@@ -1274,7 +1383,9 @@ evas_event_feed_multi_up(Evas *e,
    ev.flags = flags;
    ev.timestamp = timestamp;
    ev.event_flags = e->default_event_flags;
-
+   ev.dev = _evas_device_top_get(e);
+   if (ev.dev) _evas_device_ref(ev.dev);
+   
    _evas_walk(e);
    /* update released touch point */
    _evas_touch_point_update(e, d, x, y, EVAS_TOUCH_POINT_UP);
@@ -1285,6 +1396,7 @@ evas_event_feed_multi_up(Evas *e,
         ev.canvas.y = y;
         ev.canvas.xsub = fx;
         ev.canvas.ysub = fy;
+        _evas_event_framespace_adjust(obj, &ev.canvas.x, &ev.canvas.y);
         _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y, obj->mouse_grabbed);
         if (x != ev.canvas.x)
           ev.canvas.xsub = ev.canvas.x; // fixme - lost precision
@@ -1305,6 +1417,7 @@ evas_event_feed_multi_up(Evas *e,
       _evas_post_event_callback_call(e);
    /* remove released touch point from the touch point list */
    _evas_touch_point_remove(e, d);
+   if (ev.dev) _evas_device_unref(ev.dev);
    _evas_unwalk(e);
 }
 
@@ -1357,7 +1470,9 @@ evas_event_feed_multi_move(Evas *e,
         ev.locks = &(e->locks);
         ev.timestamp = timestamp;
         ev.event_flags = e->default_event_flags;
-
+        ev.dev = _evas_device_top_get(e);
+        if (ev.dev) _evas_device_ref(ev.dev);
+        
         copy = evas_event_list_copy(e->pointer.object.in);
         EINA_LIST_FOREACH(copy, l, obj)
           {
@@ -1365,12 +1480,15 @@ evas_event_feed_multi_move(Evas *e,
                  (evas_object_clippers_is_visible(obj) || obj->mouse_grabbed) &&
                  (!evas_event_passes_through(obj)) &&
                  (!evas_event_freezes_through(obj)) &&
+                 (!evas_object_is_source_invisible(obj) ||
+                  obj->mouse_grabbed) &&
                  (!obj->clip.clipees))
                {
                   ev.cur.canvas.x = x;
                   ev.cur.canvas.y = y;
                   ev.cur.canvas.xsub = fx;
                   ev.cur.canvas.ysub = fy;
+                  _evas_event_framespace_adjust(obj, &ev.cur.canvas.x, &ev.cur.canvas.y);
                   _evas_event_havemap_adjust(obj, &ev.cur.canvas.x, &ev.cur.canvas.y, obj->mouse_grabbed);
                   if (x != ev.cur.canvas.x)
                     ev.cur.canvas.xsub = ev.cur.canvas.x; // fixme - lost precision
@@ -1380,7 +1498,9 @@ evas_event_feed_multi_move(Evas *e,
                }
              if (e->delete_me) break;
           }
+        if (copy) eina_list_free(copy);
         _evas_post_event_callback_call(e);
+        if (ev.dev) _evas_device_unref(ev.dev);
      }
    else
      {
@@ -1410,7 +1530,9 @@ evas_event_feed_multi_move(Evas *e,
         ev.locks = &(e->locks);
         ev.timestamp = timestamp;
         ev.event_flags = e->default_event_flags;
-
+        ev.dev = _evas_device_top_get(e);
+        if (ev.dev) _evas_device_ref(ev.dev);
+        
         /* get all new in objects */
         ins = evas_event_objects_event_list(e, NULL, x, y);
         /* go thru old list of in objects */
@@ -1428,6 +1550,8 @@ evas_event_feed_multi_move(Evas *e,
                  eina_list_data_find(ins, obj) &&
                  (!evas_event_passes_through(obj)) &&
                  (!evas_event_freezes_through(obj)) &&
+                 (!evas_object_is_source_invisible(obj) ||
+                  obj->mouse_grabbed) &&
                  (!obj->clip.clipees) &&
                  ((!obj->precise_is_inside) || evas_object_is_inside(obj, x, y))
                 )
@@ -1436,6 +1560,7 @@ evas_event_feed_multi_move(Evas *e,
                   ev.cur.canvas.y = y;
                   ev.cur.canvas.xsub = fx;
                   ev.cur.canvas.ysub = fy;
+                  _evas_event_framespace_adjust(obj, &ev.cur.canvas.x, &ev.cur.canvas.y);
                   _evas_event_havemap_adjust(obj, &ev.cur.canvas.x, &ev.cur.canvas.y, obj->mouse_grabbed);
                   if (x != ev.cur.canvas.x)
                     ev.cur.canvas.xsub = ev.cur.canvas.x; // fixme - lost precision
@@ -1459,6 +1584,7 @@ evas_event_feed_multi_move(Evas *e,
              eina_list_free(ins);
           }
         _evas_post_event_callback_call(e);
+        if (ev.dev) _evas_device_unref(ev.dev);
      }
    _evas_unwalk(e);
 }
@@ -1492,7 +1618,9 @@ evas_event_feed_key_down(Evas *e, const char *keyname, const char *key, const ch
    ev.compose = compose;
    ev.timestamp = timestamp;
    ev.event_flags = e->default_event_flags;
-
+   ev.dev = _evas_device_top_get(e);
+   if (ev.dev) _evas_device_ref(ev.dev);
+   
    if (e->grabs)
      {
         Eina_List *l;
@@ -1547,6 +1675,7 @@ evas_event_feed_key_down(Evas *e, const char *keyname, const char *key, const ch
                                           &ev, event_id);
      }
    _evas_post_event_callback_call(e);
+   if (ev.dev) _evas_device_unref(ev.dev);
    _evas_unwalk(e);
 }
 
@@ -1578,7 +1707,9 @@ evas_event_feed_key_up(Evas *e, const char *keyname, const char *key, const char
    ev.compose = compose;
    ev.timestamp = timestamp;
    ev.event_flags = e->default_event_flags;
-
+   ev.dev = _evas_device_top_get(e);
+   if (ev.dev) _evas_device_ref(ev.dev);
+   
    if (e->grabs)
      {
         Eina_List *l;
@@ -1632,6 +1763,7 @@ evas_event_feed_key_up(Evas *e, const char *keyname, const char *key, const char
                                           &ev, event_id);
      }
    _evas_post_event_callback_call(e);
+   if (ev.dev) _evas_device_unref(ev.dev);
    _evas_unwalk(e);
 }
 
@@ -1657,7 +1789,9 @@ evas_event_feed_hold(Evas *e, int hold, unsigned int timestamp, const void *data
    ev.data = (void *)data;
    ev.timestamp = timestamp;
    ev.event_flags = e->default_event_flags;
-
+   ev.dev = _evas_device_top_get(e);
+   if (ev.dev) _evas_device_ref(ev.dev);
+   
    _evas_walk(e);
    copy = evas_event_list_copy(e->pointer.object.in);
    EINA_LIST_FOREACH(copy, l, obj)
@@ -1668,6 +1802,7 @@ evas_event_feed_hold(Evas *e, int hold, unsigned int timestamp, const void *data
      }
    if (copy) copy = eina_list_free(copy);
    _evas_post_event_callback_call(e);
+   if (ev.dev) _evas_device_unref(ev.dev);
    _evas_unwalk(e);
    _evas_object_event_new();
 }
@@ -1682,7 +1817,7 @@ evas_object_freeze_events_set(Evas_Object *obj, Eina_Bool freeze)
    freeze = !!freeze;
    if (obj->freeze_events == freeze) return;
    obj->freeze_events = freeze;
-   evas_object_smart_member_cache_invalidate(obj, EINA_FALSE, EINA_TRUE);
+   evas_object_smart_member_cache_invalidate(obj, EINA_FALSE, EINA_TRUE, EINA_FALSE);
 }
 
 EAPI Eina_Bool
@@ -1703,7 +1838,7 @@ evas_object_pass_events_set(Evas_Object *obj, Eina_Bool pass)
    pass = !!pass;
    if (obj->pass_events == pass) return;
    obj->pass_events = pass;
-   evas_object_smart_member_cache_invalidate(obj, EINA_TRUE, EINA_FALSE);
+   evas_object_smart_member_cache_invalidate(obj, EINA_TRUE, EINA_FALSE, EINA_FALSE);
    if (evas_object_is_in_output_rect(obj,
                                      obj->layer->evas->pointer.x,
                                      obj->layer->evas->pointer.y, 1, 1) &&
index 93f307b..f7a99af 100644 (file)
 
 #include "evas_common.h"
 #include "evas_private.h"
+// TIZEN ONLY(20140314): Remove warning message casusing by setlocale.
+#include "locale.h"
+//
 
 /* font dir cache */
 static Eina_Hash *font_dirs = NULL;
 static Eina_List *fonts_cache = NULL;
 static Eina_List *fonts_zero = NULL;
+static Eina_List *global_font_path = NULL;
 
 typedef struct _Fndat Fndat;
 
@@ -50,9 +54,37 @@ static Evas_Font_Dir *object_text_font_cache_dir_add(char *dir);
 static void object_text_font_cache_dir_del(char *dir, Evas_Font_Dir *fd);
 static int evas_object_text_font_string_parse(char *buffer, char dest[14][256]);
 
+// TIZEN ONLY(20140207): Remove our own font config.
+/*
 #ifdef HAVE_FONTCONFIG
-static int fc_init = 0;
+static FcConfig *fc_config = NULL;
 #endif
+*/
+//
+
+static void
+evas_font_init(void)
+{
+   DBG("ENTER:: evas_font_init");
+   static Eina_Bool fc_init = EINA_FALSE;
+   if (fc_init)
+   {
+      DBG("RETURN:: evas_font_init");
+      return;
+   }
+   fc_init = EINA_TRUE;
+#ifdef HAVE_FONTCONFIG
+   // TIZEN ONLY(20140207): Remove our own font config.
+   //fc_config = FcInitLoadConfigAndFonts();
+   if (!FcInit())
+     {
+        fc_init = EINA_FALSE;
+        ERR("Fc-config failed to initialize!");
+     }
+    DBG("DONE:: evas_font_init");
+   //
+#endif
+}
 
 void
 evas_font_dir_cache_free(void)
@@ -64,16 +96,16 @@ evas_font_dir_cache_free(void)
    font_dirs = NULL;
 
 #ifdef HAVE_FONTCONFIG
-/* this is bad i got a:
- * fccache.c:512: FcCacheFini: Assertion fcCacheChains[i] == ((void *)0)' failed.   
- * 
- * all i can do for now is shut this puppy down. butthat breaks, so disable
- * it as in reality - there is little reason to care about the memory not
- * being freed etc.
- * 
- *   fc_init--;
*   if (fc_init == 0) FcFini();
*/
+   // TIZEN ONLY(20140207): Remove our own font config.
+   /*
+   if (fc_config)
+     {
+        FcConfigDestroy(fc_config);
+        fc_config = NULL;
+     }
+   */
  FcFini();
  //
 #endif
 }
 
@@ -213,22 +245,6 @@ evas_font_free(Evas *evas, void *font)
      }
 }
 
-static void
-evas_font_init(void)
-{
-   static int done = 0;
-   if (done) return;
-   done = 1;
-#ifdef HAVE_FONTCONFIG
-   fc_init++;
-   if (fc_init == 1)
-     {
-        FcInit();
-        FcConfigEnableHome(1);
-     }
-#endif
-}
-
 #ifdef HAVE_FONTCONFIG
 static Evas_Font_Set *
 evas_load_fontconfig(Evas *evas, FcFontSet *set, int size,
@@ -263,6 +279,10 @@ static int _fc_slant_map[] =
    FC_SLANT_ITALIC
 };
 
+/* Apparently EXTRABLACK is not always available, hardcode. */
+# ifndef FC_WEIGHT_EXTRABLACK
+#  define FC_WEIGHT_EXTRABLACK 215
+# endif
 static int _fc_weight_map[] =
 {
    FC_WEIGHT_NORMAL,
@@ -431,6 +451,8 @@ evas_font_desc_dup(const Evas_Font_Description *fdesc)
    new->ref = 1;
    new->is_new = EINA_TRUE;
    new->name = eina_stringshare_ref(new->name);
+   new->fallbacks = eina_stringshare_ref(new->fallbacks);
+   new->lang = eina_stringshare_ref(new->lang);
 
    return new;
 }
@@ -493,7 +515,7 @@ evas_font_load(Evas *evas, Evas_Font_Description *fdesc, const char *source, Eva
 #endif
 
    Evas_Font_Set *font = NULL;
-   Eina_List *fonts, *l;
+   Eina_List *fonts, *l, *l_next;
    Fndat *fd;
    Fndat *found_fd = NULL;
    char *nm;
@@ -504,9 +526,20 @@ evas_font_load(Evas *evas, Evas_Font_Description *fdesc, const char *source, Eva
 
    if (fdesc->slant != EVAS_FONT_SLANT_NORMAL)
       wanted_rend |= FONT_REND_SLANT;
-   if (fdesc->weight == EVAS_FONT_WEIGHT_BOLD)
+   if (fdesc->weight >= EVAS_FONT_WEIGHT_BOLD)
       wanted_rend |= FONT_REND_WEIGHT;
 
+   // TIZEN ONLY(20140219)
+   // If there is no description for language, get the locale string.
+   if (!fdesc->lang)
+     {
+        char *locale = (char *)setlocale(0, NULL);
+
+        if (locale)
+          fdesc->lang = eina_stringshare_add(locale);
+     }
+   //
+
    evas_font_init();
 
    EINA_LIST_FOREACH(fonts_cache, l, fd)
@@ -541,7 +574,7 @@ evas_font_load(Evas *evas, Evas_Font_Description *fdesc, const char *source, Eva
      }
 #endif
 
-   EINA_LIST_FOREACH(fonts_zero, l, fd)
+   EINA_LIST_FOREACH_SAFE(fonts_zero, l, l_next, fd)
      {
         if (!evas_font_desc_cmp(fdesc, fd->fdesc))
          {
@@ -599,7 +632,7 @@ evas_font_load(Evas *evas, Evas_Font_Description *fdesc, const char *source, Eva
                                 int fsize = 0;
 
                                 fdata = eet_read(ef, nm, &fsize);
-                                if ((fdata) && (fsize > 0))
+                                if (fdata)
                                   {
                                      font = evas->engine.func->font_memory_load(evas->engine.data.output, source, nm, size, fdata, fsize, wanted_rend);
                                      free(fdata);
@@ -631,6 +664,21 @@ evas_font_load(Evas *evas, Evas_Font_Description *fdesc, const char *source, Eva
                                 if (font) break;
                              }
                         }
+
+                       if (!font)
+                         {
+                            EINA_LIST_FOREACH(global_font_path, ll, dir)
+                              {
+                                 const char *f_file;
+
+                                 f_file = evas_font_dir_cache_find(dir, (char *)nm);
+                                 if (f_file)
+                                   {
+                                      font = evas->engine.func->font_load(evas->engine.data.output, f_file, size, wanted_rend);
+                                      if (font) break;
+                                   }
+                              }
+                         }
                    }
 #ifdef BUILD_FONT_LOADER_EET
               }
@@ -663,9 +711,9 @@ evas_font_load(Evas *evas, Evas_Font_Description *fdesc, const char *source, Eva
                                 if ((fdata) && (fsize > 0))
                                   {
                                      ok = evas->engine.func->font_memory_add(evas->engine.data.output, font, source, nm, size, fdata, fsize, wanted_rend);
-                                     free(fdata);
                                   }
                                 eet_close(ef);
+                                 free(fdata);
                              }
                         }
                       else
@@ -682,6 +730,7 @@ evas_font_load(Evas *evas, Evas_Font_Description *fdesc, const char *source, Eva
                    {
                       Eina_List *ll;
                       char *dir;
+                      RGBA_Font *fn = NULL;
 
                       EINA_LIST_FOREACH(evas->font_path, ll, dir)
                         {
@@ -690,10 +739,27 @@ evas_font_load(Evas *evas, Evas_Font_Description *fdesc, const char *source, Eva
                            f_file = evas_font_dir_cache_find(dir, (char *)nm);
                            if (f_file)
                              {
-                                if (evas->engine.func->font_add(evas->engine.data.output, font, f_file, size, wanted_rend))
+                                fn = (RGBA_Font *)evas->engine.func->font_add(evas->engine.data.output, font, f_file, size, wanted_rend);
+                                if (fn)
                                   break;
                              }
                         }
+
+                       if (!fn)
+                         {
+                            EINA_LIST_FOREACH(global_font_path, ll, dir)
+                              {
+                                 const char *f_file;
+
+                                 f_file = evas_font_dir_cache_find(dir, (char *)nm);
+                                 if (f_file)
+                                   {
+                                      fn = (RGBA_Font *)evas->engine.func->font_add(evas->engine.data.output, font, f_file, size, wanted_rend);
+                                      if (fn)
+                                         break;
+                                   }
+                              }
+                         }
                    }
 #ifdef BUILD_FONT_LOADER_EET
               }
@@ -743,11 +809,17 @@ evas_font_load(Evas *evas, Evas_Font_Description *fdesc, const char *source, Eva
         if (fdesc->lang)
            FcPatternAddString (p_nm, FC_LANG, (FcChar8 *) fdesc->lang);
 
+        // TIZEN ONLY(20140207): Remove our own font config.
+       //FcConfigSubstitute(fc_config, p_nm, FcMatchPattern);
        FcConfigSubstitute(NULL, p_nm, FcMatchPattern);
+        //
        FcDefaultSubstitute(p_nm);
 
        /* do matching */
+        // TIZEN ONLY(20140207): Remove our own font config.
+       //set = FcFontSort(fc_config, p_nm, FcTrue, NULL, &res);
        set = FcFontSort(NULL, p_nm, FcTrue, NULL, &res);
+        //
        if (!set)
          {
             ERR("No fontconfig font matches '%s'. It was the last resource, no font found!", fdesc->name);
@@ -813,7 +885,10 @@ evas_font_dir_available_list(const Evas *evas)
    p = FcPatternCreate();
    os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, NULL);
 
+   // TIZEN ONLY(20140207): Remove our own font config.
+   //if (p && os) set = FcFontList(fc_config, p, os);
    if (p && os) set = FcFontList(NULL, p, os);
+   //
 
    if (p) FcPatternDestroy(p);
    if (os) FcObjectSetDestroy(os);
@@ -834,24 +909,44 @@ evas_font_dir_available_list(const Evas *evas)
 #endif
 
    /* Add fonts in evas font_path*/
-   if (!evas->font_path)
-     return available;
+   if (evas->font_path)
+     {
+        if (!font_dirs) font_dirs = eina_hash_string_superfast_new(NULL);
 
-   if (!font_dirs) font_dirs = eina_hash_string_superfast_new(NULL);
+        EINA_LIST_FOREACH(evas->font_path, l, dir)
+          {
+             Evas_Font_Dir *fd;
 
-   EINA_LIST_FOREACH(evas->font_path, l, dir)
+             fd = eina_hash_find(font_dirs, dir);
+             fd = object_text_font_cache_dir_update(dir, fd);
+             if (fd && fd->aliases)
+               {
+                  Evas_Font_Alias *fa;
+
+                  EINA_LIST_FOREACH(fd->aliases, ll, fa)
+                     available = eina_list_append(available, eina_stringshare_add((char *)fa->alias));
+               }
+          }
+     }
+
+   if (global_font_path)
      {
-       Evas_Font_Dir *fd;
+        if (!font_dirs) font_dirs = eina_hash_string_superfast_new(NULL);
 
-       fd = eina_hash_find(font_dirs, dir);
-       fd = object_text_font_cache_dir_update(dir, fd);
-       if (fd && fd->aliases)
-         {
-            Evas_Font_Alias *fa;
+        EINA_LIST_FOREACH(global_font_path, l, dir)
+          {
+             Evas_Font_Dir *fd;
 
-            EINA_LIST_FOREACH(fd->aliases, ll, fa)
-              available = eina_list_append(available, eina_stringshare_add((char *)fa->alias));
-         }
+             fd = eina_hash_find(font_dirs, dir);
+             fd = object_text_font_cache_dir_update(dir, fd);
+             if (fd && fd->aliases)
+               {
+                  Evas_Font_Alias *fa;
+
+                  EINA_LIST_FOREACH(fd->aliases, ll, fa)
+                     available = eina_list_append(available, eina_stringshare_add((char *)fa->alias));
+               }
+          }
      }
 
    return available;
@@ -886,8 +981,8 @@ object_text_font_cache_dir_update(char *dir, Evas_Font_Dir *fd)
        mt = evas_file_modified_time(dir);
        if (mt != fd->dir_mod_time)
          {
-            object_text_font_cache_dir_del(dir, fd);
             eina_hash_del(font_dirs, dir, fd);
+            object_text_font_cache_dir_del(dir, fd);
          }
        else
          {
@@ -898,8 +993,8 @@ object_text_font_cache_dir_update(char *dir, Evas_Font_Dir *fd)
                  free(tmp);
                  if (mt != fd->fonts_dir_mod_time)
                    {
-                      object_text_font_cache_dir_del(dir, fd);
                       eina_hash_del(font_dirs, dir, fd);
+                      object_text_font_cache_dir_del(dir, fd);
                    }
                  else
                    {
@@ -911,8 +1006,8 @@ object_text_font_cache_dir_update(char *dir, Evas_Font_Dir *fd)
                         }
                       if (mt != fd->fonts_alias_mod_time)
                         {
-                           object_text_font_cache_dir_del(dir, fd);
                            eina_hash_del(font_dirs, dir, fd);
+                           object_text_font_cache_dir_del(dir, fd);
                         }
                       else
                         return fd;
@@ -1229,6 +1324,8 @@ evas_font_path_append(Evas *e, const char *path)
 
    if (!path) return;
    e->font_path = eina_list_append(e->font_path, eina_stringshare_add(path));
+
+   evas_font_init();
 }
 
 EAPI void
@@ -1240,6 +1337,8 @@ evas_font_path_prepend(Evas *e, const char *path)
 
    if (!path) return;
    e->font_path = eina_list_prepend(e->font_path, eina_stringshare_add(path));
+
+   evas_font_init();
 }
 
 EAPI const Eina_List *
@@ -1251,6 +1350,51 @@ evas_font_path_list(const Evas *e)
    return e->font_path;
 }
 
+EAPI void
+evas_font_path_global_append(const char *path)
+{
+   if (!path) return;
+   global_font_path = eina_list_append(global_font_path, eina_stringshare_add(path));
+#ifdef HAVE_FONTCONFIG
+   //if (fc_config)
+   //  FcConfigAppFontAddDir(fc_config, (const FcChar8 *) path);
+   FcConfigAppFontAddDir(NULL, (const FcChar8 *) path);
+#endif
+}
+
+EAPI void
+evas_font_path_global_prepend(const char *path)
+{
+   if (!path) return;
+   global_font_path = eina_list_prepend(global_font_path, eina_stringshare_add(path));
+#ifdef HAVE_FONTCONFIG
+   //if (fc_config)
+   //  FcConfigAppFontAddDir(fc_config, (const FcChar8 *) path);
+   FcConfigAppFontAddDir(NULL, (const FcChar8 *) path);
+#endif
+}
+
+EAPI void
+evas_font_path_global_clear(void)
+{
+   while (global_font_path)
+     {
+        eina_stringshare_del(global_font_path->data);
+        global_font_path = eina_list_remove(global_font_path, global_font_path->data);
+     }
+#ifdef HAVE_FONTCONFIG
+   //if (fc_config)
+   //  FcConfigAppFontClear(fc_config);
+   FcConfigAppFontClear(NULL);
+#endif
+}
+
+EAPI const Eina_List *
+evas_font_path_global_list(void)
+{
+   return global_font_path;
+}
+
 static void
 evas_font_object_rehint(Evas_Object *obj)
 {
@@ -1360,3 +1504,20 @@ evas_font_available_list_free(Evas *e, Eina_List *available)
    evas_font_dir_available_list_free(available);
 }
 
+EAPI void
+evas_font_reinit(void)
+{
+   DBG("ENTER:: evas_font_reinit");
+   Eina_List *l;
+   char *path;
+
+   FcInitReinitialize();
+   DBG("FcInitReinitialize is done!");
+   // TIZEN ONLY(20140207): Remove our own font config.
+   //fc_config = FcConfigGetCurrent();
+   //
+   EINA_LIST_FOREACH(global_font_path, l, path)
+      FcConfigAppFontAddDir(NULL, (const FcChar8 *) path);
+   DBG("DONE:: evas_font_reinit");
+}
+
old mode 100644 (file)
new mode 100755 (executable)
index 58021df..a0ee558
@@ -3,6 +3,8 @@
 #include "evas_private.h"
 #include "Evas_GL.h"
 
+typedef struct _Evas_GL_TLS_data Evas_GL_TLS_data;
+
 struct _Evas_GL
 {
    DATA32      magic;
@@ -10,11 +12,15 @@ struct _Evas_GL
 
    Eina_List  *contexts;
    Eina_List  *surfaces;
+   Eina_Lock   lck;
+   Eina_TLS    resource_key;
+   Eina_List  *resource_list;
 };
 
 struct _Evas_GL_Context
 {
    void    *data;
+   Evas_GL_Context_Version version;
 };
 
 struct _Evas_GL_Surface
@@ -22,6 +28,110 @@ struct _Evas_GL_Surface
    void    *data;
 };
 
+struct _Evas_GL_TLS_data
+{
+   int error_state;
+};
+
+static int _evas_gl_ext_buffer_age_get(Evas_GL *evas_gl);
+static int _evas_gl_ext_update_region_get(Evas_GL *evas_gl, int *x, int *y, int *w, int *h);
+static Evas_GL_Surface * _evas_gl_ext_surface_from_native_create(Evas_GL *evas_gl, Evas_GL_Config *config, int target, void *native);
+static int _evas_gl_ext_surface_is_texture(Evas_GL *evas_gl, Evas_GL_Surface *surf);
+
+static Evas_GL_Ext _evas_gl_ext_funcs[] =
+{
+     {"evas_gl_ext_buffer_age_get", _evas_gl_ext_buffer_age_get},
+     {"evas_gl_ext_update_region_get", _evas_gl_ext_update_region_get},
+     {"evas_gl_ext_surface_from_native_create", _evas_gl_ext_surface_from_native_create},
+     {"evas_gl_ext_surface_is_texture", _evas_gl_ext_surface_is_texture},
+     {NULL, NULL}
+};
+
+
+Evas_GL_TLS_data *
+_evas_gl_internal_tls_get(Evas_GL *evas_gl)
+{
+   Evas_GL_TLS_data *tls_data;
+
+   if (!evas_gl) return NULL;
+
+   if (!(tls_data = eina_tls_get(evas_gl->resource_key)))
+     {
+        tls_data = (Evas_GL_TLS_data*) calloc(1, sizeof(Evas_GL_TLS_data));
+        if (!tls_data)
+          {
+             ERR("Evas_GL: Could not set error!");
+             return NULL;
+          }
+        tls_data->error_state = EVAS_GL_SUCCESS;
+
+        if (eina_tls_set(evas_gl->resource_key, (void*)tls_data) == EINA_TRUE)
+          {
+             LKL(evas_gl->lck);
+             evas_gl->resource_list = eina_list_prepend(evas_gl->resource_list, tls_data);
+             LKU(evas_gl->lck);
+             return tls_data;
+          }
+        else
+          {
+             ERR("Evas_GL: Failed setting TLS data!");
+             free(tls_data);
+             return NULL;
+          }
+     }
+
+   return tls_data;
+}
+
+void
+_evas_gl_internal_tls_destroy(Evas_GL *evas_gl)
+{
+   Evas_GL_TLS_data *tls_data;
+
+   if (!evas_gl) return;
+
+   if (!(tls_data = eina_tls_get(evas_gl->resource_key)))
+     {
+        WRN("Destructor: TLS data was never set!");
+        return;
+     }
+
+   LKL(evas_gl->lck);
+   EINA_LIST_FREE(evas_gl->resource_list, tls_data)
+     free(tls_data);
+
+   if (evas_gl->resource_key)
+     eina_tls_free(evas_gl->resource_key);
+   evas_gl->resource_key = 0;
+   LKU(evas_gl->lck);
+}
+
+void
+_evas_gl_internal_error_set(Evas_GL *evas_gl, int error_enum)
+{
+   Evas_GL_TLS_data *tls_data;
+
+   if (!evas_gl) return;
+
+   tls_data = _evas_gl_internal_tls_get(evas_gl);
+   if (!tls_data) return;
+
+   tls_data->error_state = error_enum;
+}
+
+int
+_evas_gl_internal_error_get(Evas_GL *evas_gl)
+{
+   Evas_GL_TLS_data *tls_data;
+
+   if (!evas_gl) return EVAS_GL_NOT_INITIALIZED;
+
+   tls_data = _evas_gl_internal_tls_get(evas_gl);
+   if (!tls_data) return EVAS_GL_NOT_INITIALIZED;
+
+   return tls_data->error_state;
+}
+
 EAPI Evas_GL *
 evas_gl_new(Evas *e)
 {
@@ -36,14 +146,25 @@ evas_gl_new(Evas *e)
 
    evas_gl->magic = MAGIC_EVAS_GL;
    evas_gl->evas = e;
+   LKI(evas_gl->lck);
 
-   if (!evas_gl->evas->engine.func->gl_context_create)
+   if (!evas_gl->evas->engine.func->gl_engine_init)
      {
         ERR("Evas GL engine not available.");
         free(evas_gl);
         return NULL;
      }
+   evas_gl->evas->engine.func->gl_engine_init(e->engine.data.output);
 
+   // Initialize tls resource key
+   if (eina_tls_new(&(evas_gl->resource_key)) == EINA_FALSE)
+     {
+        ERR("Error creating tls key");
+        free(evas_gl);
+        return NULL;
+     }
+
+   _evas_gl_internal_error_set(evas_gl, EVAS_GL_SUCCESS);
    return evas_gl;
 }
 
@@ -54,7 +175,6 @@ evas_gl_free(Evas_GL *evas_gl)
    return;
    MAGIC_CHECK_END();
 
-
    // Delete undeleted surfaces
    while (evas_gl->surfaces)
      evas_gl_surface_destroy(evas_gl, evas_gl->surfaces->data);
@@ -63,7 +183,11 @@ evas_gl_free(Evas_GL *evas_gl)
    while (evas_gl->contexts)
      evas_gl_context_destroy(evas_gl, evas_gl->contexts->data);
 
+   // Destroy tls
+   _evas_gl_internal_tls_destroy(evas_gl);
+
    evas_gl->magic = 0;
+   LKD(evas_gl->lck);
    free(evas_gl);
 }
 
@@ -97,18 +221,24 @@ evas_gl_surface_create(Evas_GL *evas_gl, Evas_GL_Config *config, int width, int
    if (!config)
      {
         ERR("Invalid Config Pointer!");
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_CONFIG);
         return NULL;
      }
 
-   if ( (width <= 0) || (height <= 0))
+   if ((width <= 0) || (height <= 0))
      {
         ERR("Invalid surface dimensions: %d, %d", width, height);
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_PARAMETER);
         return NULL;
      }
 
    surf = calloc(1, sizeof(Evas_GL_Surface));
 
-   if (!surf) return NULL;
+   if (!surf)
+     {
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_ALLOC);
+        return NULL;
+     }
 
    surf->data = evas_gl->evas->engine.func->gl_surface_create(evas_gl->evas->engine.data.output, config, width, height);
 
@@ -120,7 +250,65 @@ evas_gl_surface_create(Evas_GL *evas_gl, Evas_GL_Config *config, int width, int
      }
 
    // Keep track of the surface creations
+   LKL(evas_gl->lck);
    evas_gl->surfaces = eina_list_prepend(evas_gl->surfaces, surf);
+   LKU(evas_gl->lck);
+
+   return surf;
+}
+
+EAPI Evas_GL_Surface *
+evas_gl_pbuffer_surface_create(Evas_GL *evas_gl, Evas_GL_Config *cfg,
+                               int w, int h, const int *attrib_list)
+{
+   Evas_GL_Surface *surf;
+
+   // Magic
+   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
+   return NULL;
+   MAGIC_CHECK_END();
+
+   if (!cfg)
+     {
+        ERR("Invalid Config Pointer!");
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_CONFIG);
+        return NULL;
+     }
+
+   if ((w <= 0) || (h <= 0))
+     {
+        ERR("Invalid surface dimensions: %d, %d", w, h);
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_PARAMETER);
+        return NULL;
+     }
+
+   if (!evas_gl->evas->engine.func->gl_pbuffer_surface_create)
+     {
+        ERR("Engine does not support PBuffer!");
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_NOT_INITIALIZED);
+        return NULL;
+     }
+
+   surf = calloc(1, sizeof(Evas_GL_Surface));
+   if (!surf)
+     {
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_ALLOC);
+        return NULL;
+     }
+
+   surf->data = evas_gl->evas->engine.func->gl_pbuffer_surface_create
+     (evas_gl->evas->engine.data.output, cfg, w, h, attrib_list);
+   if (!surf->data)
+     {
+        ERR("Engine failed to create a PBuffer!");
+        free(surf);
+        return NULL;
+     }
+
+   // Keep track of the surface creations
+   LKL(evas_gl->lck);
+   evas_gl->surfaces = eina_list_prepend(evas_gl->surfaces, surf);
+   LKU(evas_gl->lck);
 
    return surf;
 }
@@ -136,6 +324,7 @@ evas_gl_surface_destroy(Evas_GL *evas_gl, Evas_GL_Surface *surf)
    if (!surf)
      {
         ERR("Trying to destroy a NULL surface pointer!");
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_SURFACE);
         return;
      }
 
@@ -143,7 +332,9 @@ evas_gl_surface_destroy(Evas_GL *evas_gl, Evas_GL_Surface *surf)
    evas_gl->evas->engine.func->gl_surface_destroy(evas_gl->evas->engine.data.output, surf->data);
 
    // Remove it from the list
+   LKL(evas_gl->lck);
    evas_gl->surfaces = eina_list_remove(evas_gl->surfaces, surf);
+   LKU(evas_gl->lck);
 
    // Delete the object
    free(surf);
@@ -151,7 +342,8 @@ evas_gl_surface_destroy(Evas_GL *evas_gl, Evas_GL_Surface *surf)
 }
 
 EAPI Evas_GL_Context *
-evas_gl_context_create(Evas_GL *evas_gl, Evas_GL_Context *share_ctx)
+evas_gl_context_version_create(Evas_GL *evas_gl, Evas_GL_Context *share_ctx,
+                               Evas_GL_Context_Version version)
 {
    Evas_GL_Context *ctx;
 
@@ -160,23 +352,29 @@ evas_gl_context_create(Evas_GL *evas_gl, Evas_GL_Context *share_ctx)
    return NULL;
    MAGIC_CHECK_END();
 
+   if ((version != EVAS_GL_GLES_1_X) && (version != EVAS_GL_GLES_2_X))
+     {
+        ERR("Can not create an OpenGL-ES %d.x context (not supported).",
+            (int) version);
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_PARAMETER);
+        return NULL;
+     }
+
    // Allocate a context object
    ctx = calloc(1, sizeof(Evas_GL_Context));
    if (!ctx)
      {
         ERR("Unable to create a Evas_GL_Context object");
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_ALLOC);
         return NULL;
      }
 
    // Call engine->gl_create_context
+   ctx->version = version;
    if (share_ctx)
-     {
-        ctx->data = evas_gl->evas->engine.func->gl_context_create(evas_gl->evas->engine.data.output, share_ctx->data);
-     }
+     ctx->data = evas_gl->evas->engine.func->gl_context_create(evas_gl->evas->engine.data.output, share_ctx->data, version);
    else
-     {
-        ctx->data = evas_gl->evas->engine.func->gl_context_create(evas_gl->evas->engine.data.output, NULL);
-     }
+     ctx->data = evas_gl->evas->engine.func->gl_context_create(evas_gl->evas->engine.data.output, NULL, version);
 
    // Set a few variables
    if (!ctx->data)
@@ -187,10 +385,17 @@ evas_gl_context_create(Evas_GL *evas_gl, Evas_GL_Context *share_ctx)
      }
 
    // Keep track of the context creations
+   LKL(evas_gl->lck);
    evas_gl->contexts = eina_list_prepend(evas_gl->contexts, ctx);
+   LKU(evas_gl->lck);
 
    return ctx;
+}
 
+EAPI Evas_GL_Context *
+evas_gl_context_create(Evas_GL *evas_gl, Evas_GL_Context *share_ctx)
+{
+   return evas_gl_context_version_create(evas_gl, share_ctx, EVAS_GL_GLES_2_X);
 }
 
 EAPI void
@@ -204,6 +409,7 @@ evas_gl_context_destroy(Evas_GL *evas_gl, Evas_GL_Context *ctx)
    if (!ctx)
      {
         ERR("Trying to destroy a NULL context pointer!");
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_CONTEXT);
         return;
      }
 
@@ -211,7 +417,9 @@ evas_gl_context_destroy(Evas_GL *evas_gl, Evas_GL_Context *ctx)
    evas_gl->evas->engine.func->gl_context_destroy(evas_gl->evas->engine.data.output, ctx->data);
 
    // Remove it from the list
+   LKL(evas_gl->lck);
    evas_gl->contexts = eina_list_remove(evas_gl->contexts, ctx);
+   LKU(evas_gl->lck);
 
    // Delete the object
    free(ctx);
@@ -226,7 +434,7 @@ evas_gl_make_current(Evas_GL *evas_gl, Evas_GL_Surface *surf, Evas_GL_Context *c
    MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
    return EINA_FALSE;
    MAGIC_CHECK_END();
-   
+
    if ((surf) && (ctx))
      ret = (Eina_Bool)evas_gl->evas->engine.func->gl_make_current(evas_gl->evas->engine.data.output, surf->data, ctx->data);
    else if ((!surf) && (!ctx))
@@ -234,30 +442,93 @@ evas_gl_make_current(Evas_GL *evas_gl, Evas_GL_Surface *surf, Evas_GL_Context *c
    else
      {
         ERR("Bad match between surface: %p and context: %p", surf, ctx);
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_MATCH);
         return EINA_FALSE;
      }
 
    return ret;
 }
 
+EAPI Evas_GL_Context *
+evas_gl_current_context_get(Evas_GL *evas_gl)
+{
+   Evas_GL_Context *comp;
+   void *internal_ctx;
+   Eina_List *li;
+
+   // Magic
+   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
+   return NULL;
+   MAGIC_CHECK_END();
+
+   internal_ctx = evas_gl->evas->engine.func->gl_current_context_get(evas_gl->evas->engine.data.output);
+   if (!internal_ctx)
+     return NULL;
+
+   LKL(evas_gl->lck);
+   EINA_LIST_FOREACH(evas_gl->contexts, li, comp)
+     {
+        if (comp->data == internal_ctx)
+          {
+             LKU(evas_gl->lck);
+             return comp;
+          }
+     }
+
+   ERR("The currently bound context could not be found.");
+   LKU(evas_gl->lck);
+   return NULL;
+}
+
+EAPI Evas_GL_Surface *
+evas_gl_current_surface_get(Evas_GL *evas_gl)
+{
+   Evas_GL_Surface *comp;
+   void *internal_sfc;
+   Eina_List *li;
+
+   // Magic
+   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
+   return NULL;
+   MAGIC_CHECK_END();
+
+   internal_sfc = evas_gl->evas->engine.func->gl_current_surface_get(evas_gl->evas->engine.data.output);
+   if (!internal_sfc)
+     return NULL;
+
+   LKL(evas_gl->lck);
+   EINA_LIST_FOREACH(evas_gl->surfaces, li, comp)
+     {
+        if (comp->data == internal_sfc)
+          {
+             LKU(evas_gl->lck);
+             return comp;
+          }
+     }
+
+   ERR("The currently bound surface could not be found.");
+   LKU(evas_gl->lck);
+   return NULL;
+}
+
 EAPI const char *
 evas_gl_string_query(Evas_GL *evas_gl, int name)
 {
    MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
-   return EINA_FALSE;
+   return "";
    MAGIC_CHECK_END();
 
-   return (const char *)evas_gl->evas->engine.func->gl_string_query(evas_gl->evas->engine.data.output, name);
+   return evas_gl->evas->engine.func->gl_string_query(evas_gl->evas->engine.data.output, name);
 }
 
 EAPI Evas_GL_Func
 evas_gl_proc_address_get(Evas_GL *evas_gl, const char *name)
 {
    MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
-   return EINA_FALSE;
+   return NULL;
    MAGIC_CHECK_END();
 
-   return (Evas_GL_Func)evas_gl->evas->engine.func->gl_proc_address_get(evas_gl->evas->engine.data.output, name);
+   return (Evas_GL_Func)evas_gl->evas->engine.func->gl_proc_address_get(evas_gl->evas->engine.data.output, _evas_gl_ext_funcs, name);
 }
 
 EAPI Eina_Bool
@@ -267,9 +538,17 @@ evas_gl_native_surface_get(Evas_GL *evas_gl, Evas_GL_Surface *surf, Evas_Native_
    return EINA_FALSE;
    MAGIC_CHECK_END();
 
-   if ((!surf) || (!ns))
+   if (!surf)
+     {
+        ERR("Invalid surface!");
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_SURFACE);
+        return EINA_FALSE;
+     }
+
+   if (!ns)
      {
         ERR("Invalid input parameters!");
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_PARAMETER);
         return EINA_FALSE;
      }
 
@@ -284,6 +563,192 @@ evas_gl_api_get(Evas_GL *evas_gl)
    return NULL;
    MAGIC_CHECK_END();
 
-   return (Evas_GL_API*)evas_gl->evas->engine.func->gl_api_get(evas_gl->evas->engine.data.output);
+   return (Evas_GL_API*)evas_gl->evas->engine.func->gl_api_get(evas_gl->evas->engine.data.output, EVAS_GL_GLES_2_X);
+}
+
+EAPI Evas_GL_API *
+evas_gl_context_api_get(Evas_GL *evas_gl, Evas_GL_Context *ctx)
+{
+   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
+   return NULL;
+   MAGIC_CHECK_END();
+
+   if (!ctx)
+     {
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_CONTEXT);
+        return NULL;
+     }
+
+   return (Evas_GL_API*)evas_gl->evas->engine.func->gl_api_get(evas_gl->evas->engine.data.output, ctx->version);
+}
+
+EAPI int
+evas_gl_rotation_get(Evas_GL *evas_gl)
+{
+   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
+   return 0;
+   MAGIC_CHECK_END();
+
+   if (!evas_gl->evas->engine.func->gl_rotation_angle_get)
+     return 0;
+
+   return evas_gl->evas->engine.func->gl_rotation_angle_get(evas_gl->evas->engine.data.output);
+}
+
+EAPI int
+evas_gl_error_get(Evas_GL *evas_gl)
+{
+   int err;
+
+   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
+   return EVAS_GL_NOT_INITIALIZED;
+   MAGIC_CHECK_END();
+
+   if ((err = _evas_gl_internal_error_get(evas_gl)) != EVAS_GL_SUCCESS)
+     goto end;
+
+   if (!evas_gl->evas->engine.func->gl_error_get)
+     err = EVAS_GL_NOT_INITIALIZED;
+   else
+     err = evas_gl->evas->engine.func->gl_error_get(evas_gl->evas->engine.data.output);
+
+end:
+   /* Call to evas_gl_error_get() should set error to EVAS_GL_SUCCESS */
+   _evas_gl_internal_error_set(evas_gl, EVAS_GL_SUCCESS);
+   return err;
+}
+
+EAPI void *
+evas_gl_context_native_get(Evas_GL_Context *ctx)
+{
+   if (!ctx) return NULL;
+
+   return ctx->data;
+}
+
+EAPI Eina_Bool
+evas_gl_surface_query(Evas_GL *evas_gl, Evas_GL_Surface *surface, int attribute, void *value)
+{
+   if (!evas_gl) return EINA_FALSE;
+   if (!surface)
+     {
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_SURFACE);
+        return EINA_FALSE;
+     }
+
+   if (!evas_gl->evas->engine.func->gl_surface_query)
+     {
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_NOT_INITIALIZED);
+        return EINA_FALSE;
+     }
+
+   if (!value)
+     {
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_PARAMETER);
+        return EINA_FALSE;
+     }
+
+   return evas_gl->evas->engine.func->gl_surface_query
+         (evas_gl->evas->engine.data.output, surface->data, attribute, value);
+}
+
+/*-----------------------------*/
+/* Evas GL Extension Functions */
+static int
+_evas_gl_ext_buffer_age_get(Evas_GL *evas_gl)
+{
+   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
+   return 0;
+   MAGIC_CHECK_END();
+
+   if (!evas_gl->evas->engine.func->gl_ext_buffer_age_get) return 0;
+
+   return evas_gl->evas->engine.func->gl_ext_buffer_age_get(evas_gl->evas->engine.data.output);
+}
+
+static int
+_evas_gl_ext_update_region_get(Evas_GL *evas_gl, int *x, int *y, int *w, int *h)
+{
+   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
+   return 0;
+   MAGIC_CHECK_END();
+
+   if (!evas_gl->evas->engine.func->gl_ext_update_region_get) return 0;
+
+   return evas_gl->evas->engine.func->gl_ext_update_region_get(evas_gl->evas->engine.data.output, x, y, w, h);
+}
+
+static Evas_GL_Surface *
+_evas_gl_ext_surface_from_native_create(Evas_GL *evas_gl, Evas_GL_Config *config, int target, void *native)
+{
+   Evas_GL_Surface *surf;
+
+   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
+   return NULL;
+   MAGIC_CHECK_END();
+
+   if (!evas_gl->evas->engine.func->gl_ext_surface_from_native_create)
+     {
+        ERR("API Not supported with this backend of Evas GL");
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_NOT_INITIALIZED);
+        return NULL;
+     }
+
+   if (!config)
+     {
+        ERR("Invalid Config Pointer!");
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_CONFIG);
+        return NULL;
+     }
+
+   if (!target)
+     {
+        ERR("Invalid Target!");
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_PARAMETER);
+        return NULL;
+     }
 
+   if (!native)
+     {
+        ERR("Invalid Native Buffer Pointer!");
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_NATIVE_PIXMAP);
+        return NULL;
+     }
+
+   surf = calloc(1, sizeof(Evas_GL_Surface));
+
+   if (!surf)
+     {
+        _evas_gl_internal_error_set(evas_gl, EVAS_GL_BAD_ALLOC);
+        return NULL;
+     }
+
+   surf->data = evas_gl->evas->engine.func->gl_ext_surface_from_native_create(evas_gl->evas->engine.data.output, config, target, native);
+
+   if (!surf->data)
+     {
+        ERR("Failed creating a surface from the engine.");
+        free(surf);
+        return NULL;
+     }
+
+   // Keep track of the surface creations
+   LKL(evas_gl->lck);
+   evas_gl->surfaces = eina_list_prepend(evas_gl->surfaces, surf);
+   LKU(evas_gl->lck);
+
+   return surf;
+}
+
+static int _evas_gl_ext_surface_is_texture(Evas_GL *evas_gl, Evas_GL_Surface *surf)
+{
+   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
+   return -1;
+   MAGIC_CHECK_END();
+
+   if (!evas_gl->evas->engine.func->gl_ext_surface_is_texture) return -1;
+
+   return evas_gl->evas->engine.func->gl_ext_surface_is_texture(evas_gl->evas->engine.data.output, surf->data);
 }
+
+
index 3fc2172..8e98b6e 100644 (file)
@@ -95,6 +95,7 @@ evas_key_grab_find(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask mod
 void
 evas_object_grabs_cleanup(Evas_Object *obj)
 {
+   if (!obj->layer) return;
    if (obj->layer->evas->walking_grabs)
      {
         Eina_List *l;
@@ -108,11 +109,11 @@ evas_object_grabs_cleanup(Evas_Object *obj)
         while (obj->grabs)
           {
              Evas_Key_Grab *g = obj->grabs->data;
+             obj->layer->evas->grabs =
+                eina_list_remove(obj->layer->evas->grabs, g);
+             obj->grabs = eina_list_remove(obj->grabs, g);
              if (g->keyname) free(g->keyname);
              free(g);
-             obj->layer->evas->grabs = eina_list_remove(obj->layer->evas->grabs,
-                                                        g);
-             obj->grabs = eina_list_remove(obj->grabs, g);
           }
      }
 }
@@ -142,7 +143,7 @@ evas_object_key_grab(Evas_Object *obj, const char *keyname, Evas_Modifier_Mask m
    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
    return EINA_FALSE;
    MAGIC_CHECK_END();
-   if (!keyname) return EINA_FALSE;
+   if (((modifiers == not_modifiers) && (modifiers != 0)) || !keyname) return EINA_FALSE;
    if (exclusive)
      {
         g = evas_key_grab_find(obj, keyname, modifiers, not_modifiers,
index 3c7bc84..7b89069 100644 (file)
@@ -136,11 +136,8 @@ evas_layer_del(Evas_Layer *lay)
 static void
 _evas_object_layer_set_child(Evas_Object *obj, Evas_Object *par, short l)
 {
-   Evas *e;
-   
    if (obj->delete_me) return;
    if (obj->cur.layer == l) return;
-   e = obj->layer->evas;
    evas_object_release(obj, 1);
    obj->cur.layer = l;
    obj->layer = par->layer;
@@ -149,7 +146,7 @@ _evas_object_layer_set_child(Evas_Object *obj, Evas_Object *par, short l)
      {
         Eina_Inlist *contained;
         Evas_Object *member;
-        
+
         contained = (Eina_Inlist *)evas_object_smart_members_get_direct(obj);
         EINA_INLIST_FOREACH(contained, member)
           {
index 6f6b4e1..de5d2bc 100644 (file)
@@ -85,6 +85,7 @@ evas_shutdown(void)
    if (--_evas_init_count != 0)
      return _evas_init_count;
 
+   evas_font_path_global_clear();
 #ifdef BUILD_ASYNC_EVENTS
    _evas_preload_thread_shutdown();
 #endif
@@ -94,7 +95,6 @@ evas_shutdown(void)
 #ifdef BUILD_ASYNC_EVENTS
    evas_async_events_shutdown();
 #endif
-   evas_font_dir_cache_free();
    evas_common_shutdown();
    evas_module_shutdown();
    eina_log_domain_unregister(_evas_log_dom_global);
@@ -127,6 +127,9 @@ evas_new(void)
    e->name_hash = eina_hash_string_superfast_new(NULL);
    eina_clist_init(&e->calc_list);
    eina_clist_init(&e->calc_done);
+   // TIZEN_ONLY(20140822): Added evas_bidi_direction_hint_set, get APIs and applied to textblock, text.
+   e->bidi_direction_hint = EVAS_BIDI_DIRECTION_LTR;
+   //
 
 #define EVAS_ARRAY_SET(E, Array) \
    eina_array_step_set(&E->Array, sizeof (E->Array), 4096);
@@ -185,8 +188,12 @@ evas_free(Evas *e)
                       e->walking_list--;
                       return;
                    }
-                 if (!o->delete_me)
-                   del = 1;
+                  if (!o->delete_me)
+                    {
+                       if (o->ref > 0)
+                         ERR("obj(%p, %s) ref count(%d) is more than 0. This object couldn't be deleted", o, o->type, o->ref);
+                       del = 1;
+                    }
               }
          }
      }
@@ -242,6 +249,8 @@ evas_free(Evas *e)
    EINA_LIST_FREE(e->touch_points, touch_point)
      free(touch_point);
 
+   _evas_device_cleanup(e);
+   
    e->magic = 0;
    free(e);
 }
@@ -261,6 +270,7 @@ evas_output_method_set(Evas *e, int render_method)
    if (e->output.render_method != RENDER_METHOD_INVALID) return;
    /* Request the right engine. */
    em = evas_module_engine_get(render_method);
+
    if (!em) return ;
    if (em->id_engine != render_method) return;
    if (!evas_module_load(em)) return;
@@ -689,3 +699,25 @@ evas_data_argb_unpremul(unsigned int *data, unsigned int len)
    if (!data || (len < 1)) return;
    evas_common_convert_argb_unpremul(data, len);
 }
+
+// TIZEN_ONLY(20140822): Added evas_bidi_direction_hint_set, get APIs and applied to textblock, text.
+EAPI void
+evas_bidi_direction_hint_set(Evas *e, Evas_BiDi_Direction dir)
+{
+   MAGIC_CHECK(e, Evas, MAGIC_EVAS);
+   return;
+   MAGIC_CHECK_END();
+   if (e->bidi_direction_hint != dir)
+     e->bidi_direction_hint = dir;
+}
+
+EAPI Evas_BiDi_Direction
+evas_bidi_direction_hint_get(Evas *e)
+{
+   MAGIC_CHECK(e, Evas, MAGIC_EVAS);
+   return EVAS_BIDI_DIRECTION_LTR;
+   MAGIC_CHECK_END();
+
+   return e->bidi_direction_hint;
+}
+//
index 205acf3..28937df 100644 (file)
@@ -37,7 +37,6 @@ _evas_map_calc_map_geometry(Evas_Object *obj)
    Eina_Bool ch = EINA_FALSE;
 
    if (!obj->cur.map) return;
-
    // WARN: Do not merge below code to SLP until it is fixed.
    // It has an infinite loop bug.
    if (obj->prev.map)
@@ -48,14 +47,12 @@ _evas_map_calc_map_geometry(Evas_Object *obj)
              if (obj->prev.map->count == obj->cur.map->count)
                {
                   const Evas_Map_Point *p2;
-
+                  
                   p = obj->cur.map->points;
                   p2 = obj->prev.map->points;
-
-                  ch = memcmp(p, p2,
-                              sizeof (Evas_Map_Point) * obj->prev.map->count);
-
-                  ch = !!ch;
+                  if (memcmp(p, p2, sizeof(Evas_Map_Point) * 
+                             obj->prev.map->count) != 0)
+                    ch = EINA_TRUE;
                   if (!ch)
                     {
                        if (obj->cache_map) evas_map_free(obj->cache_map); 
@@ -64,12 +61,12 @@ _evas_map_calc_map_geometry(Evas_Object *obj)
                     }
                }
              else
-               ch = 1;
+               ch = EINA_TRUE;
           }
      }
    else
-      ch = 1;
-
+      ch = EINA_TRUE;
+   
    p = obj->cur.map->points;
    p_end = p + obj->cur.map->count;
    x1 = x2 = lround(p->x);
@@ -148,6 +145,7 @@ _evas_map_copy(Evas_Map *dst, const Evas_Map *src)
      memcpy(dst->points, src->points, src->count * sizeof(Evas_Map_Point));
    dst->smooth = src->smooth;
    dst->alpha = src->alpha;
+   dst->move_sync = src->move_sync;
    dst->persp = src->persp;
    return EINA_TRUE;
 }
@@ -160,6 +158,7 @@ _evas_map_dup(const Evas_Map *orig)
    memcpy(copy->points, orig->points, orig->count * sizeof(Evas_Map_Point));
    copy->smooth = orig->smooth;
    copy->alpha = orig->alpha;
+   copy->move_sync = orig->move_sync;
    copy->persp = orig->persp;
    return copy;
 }
@@ -169,9 +168,6 @@ _evas_map_free(Evas_Object *obj, Evas_Map *m)
 {
    if (obj)
      {
-        if (m->surface)
-          obj->layer->evas->engine.func->image_map_surface_free
-            (obj->layer->evas->engine.data.output, m->surface);
         if (obj->spans)
           {
              obj->layer->evas->engine.func->image_map_clean(obj->layer->evas->engine.data.output, obj->spans);
@@ -231,14 +227,21 @@ evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y,
    return EINA_FALSE;
    MAGIC_CHECK_END();
 
-   int i, j, edges, edge[m->count][2], douv;
+   if (m->count < 4) return EINA_FALSE;
+
+   Eina_Bool inside = evas_map_inside_get(m, x, y);
+   if ((!mx) && (!my)) return inside;
+
+   // FIXME: need to handle grab mode and extrapolate coords outside map
+   if (grab && !inside) return EINA_FALSE;
+
+   int i, j, edges, edge[m->count][2];
+   Eina_Bool douv = EINA_FALSE;
    Evas_Coord xe[2];
    double u[2] = { 0.0, 0.0 };
    double v[2] = { 0.0, 0.0 };
 
-   if (m->count < 4) return 0;
-   // FIXME need to handle grab mode and extrapolte coords outside
-   // map
+/*
    if (grab)
      {
         Evas_Coord ymin, ymax;
@@ -253,7 +256,8 @@ evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y,
         if (y <= ymin) y = ymin + 1;
         if (y >= ymax) y = ymax - 1;
      }
-   edges = 0;
+*/
+   edges = EINA_FALSE;
    for (i = 0; i < m->count; i++)
      {
         j = (i + 1) % m->count;
@@ -270,8 +274,7 @@ evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y,
              edges++;
           }
      }
-   douv = 0;
-   if ((mx) || (my)) douv = 1;
+   if ((mx) || (my)) douv = EINA_TRUE;
    for (i = 0; i < (edges - 1); i+= 2)
      {
         Evas_Coord yp, yd;
@@ -343,13 +346,14 @@ evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y,
                   if (mx)
                     *mx = u[0] + (((x - xe[0]) * (u[1] - u[0])) /
                                   (xe[1] - xe[0]));
-                 if (my)
+                  if (my)
                     *my = v[0] + (((x - xe[0]) * (v[1] - v[0])) /
                                   (xe[1] - xe[0]));
                }
              return EINA_TRUE;
           }
-        if (grab)
+/*
+                 if (grab)
           {
              if (douv)
                {
@@ -362,6 +366,7 @@ evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y,
                }
              return EINA_TRUE;
           }
+*/
      }
    return EINA_FALSE;
 }
@@ -369,7 +374,29 @@ evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y,
 Eina_Bool
 evas_map_inside_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y)
 {
-   return evas_map_coords_get(m, x, y, NULL, NULL, 0);
+   int i = 0, j = m->count - 1;
+   double pt1_x, pt1_y, pt2_x, pt2_y, tmp_x;
+   Eina_Bool inside = EINA_FALSE;
+
+   //Check the point inside the map coords by using Jordan curve theorem.
+   for (i = 0; i < m->count; i++)
+     {
+        pt1_x = m->points[i].x;
+        pt1_y = m->points[i].y;
+        pt2_x = m->points[j].x;
+        pt2_y = m->points[j].y;
+
+        //Is the point inside the map on y axis?
+        if (((y >= pt1_y) && (y < pt2_y)) || ((y >= pt2_y) && (y < pt1_y)))
+          {
+             //Check the point is left side of the line segment.
+             tmp_x = (pt1_x + ((pt2_x - pt1_x) / (pt2_y - pt1_y)) *
+                      ((double)y - pt1_y));
+             if ((double)x < tmp_x) inside = !inside;
+          }
+        j = i;
+     }
+   return inside;
 }
 
 static Eina_Bool
@@ -411,6 +438,13 @@ evas_object_map_enable_set(Evas_Object *obj, Eina_Bool enabled)
      }
    else
      {
+        if (obj->map.surface)
+          {
+             obj->layer->evas->engine.func->image_map_surface_free
+               (obj->layer->evas->engine.data.output,
+                   obj->map.surface);
+             obj->map.surface = NULL;
+          }
         if (obj->cur.map)
           {
              _evas_map_calc_geom_change(obj);
@@ -452,19 +486,18 @@ evas_object_map_set(Evas_Object *obj, const Evas_Map *map)
    return;
    MAGIC_CHECK_END();
 
-   if (!map || map->count < 4)
+   if ((!map) || (map->count < 4))
      {
+        if (obj->map.surface)
+          {
+             obj->layer->evas->engine.func->image_map_surface_free
+               (obj->layer->evas->engine.data.output,
+                   obj->map.surface);
+             obj->map.surface = NULL;
+          }
         if (obj->cur.map)
           {
              obj->changed_map = EINA_TRUE;
-
-             if (obj->cur.map->surface)
-               {
-                  obj->layer->evas->engine.func->image_map_surface_free
-                    (obj->layer->evas->engine.data.output,
-                     obj->cur.map->surface);
-                  obj->cur.map->surface = NULL;
-               }
              obj->prev.geometry = obj->cur.map->normal_geometry;
 
              if (obj->prev.map == obj->cur.map)
@@ -579,6 +612,31 @@ evas_map_alpha_get(const Evas_Map *m)
    return m->alpha;
 }
 
+EAPI void
+evas_map_util_object_move_sync_set(Evas_Map *m, Eina_Bool enabled)
+{
+   MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
+   return;
+   MAGIC_CHECK_END();
+
+   if (!enabled)
+     {
+        m->move_sync.diff_x = 0;
+        m->move_sync.diff_y = 0;
+     }
+   m->move_sync.enabled = !!enabled;
+}
+
+EAPI Eina_Bool
+evas_map_util_object_move_sync_get(const Evas_Map *m)
+{
+   MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
+   return EINA_FALSE;
+   MAGIC_CHECK_END();
+
+   return m->move_sync.enabled;
+}
+
 EAPI Evas_Map *
 evas_map_dup(const Evas_Map *m)
 {
@@ -636,9 +694,9 @@ evas_map_point_coord_get(const Evas_Map *m, int idx, Evas_Coord *x, Evas_Coord *
 
    if (idx >= m->count) goto error;
    p = m->points + idx;
-   if (x) *x = p->x;
-   if (y) *y = p->y;
-   if (z) *z = p->z;
+   if (x) *x = lround(p->x);
+   if (y) *y = lround(p->y);
+   if (z) *z = lround(p->z);
    return;
 
  error:
@@ -899,6 +957,49 @@ evas_map_util_3d_rotate(Evas_Map *m, double dx, double dy, double dz,
 }
 
 EAPI void
+evas_map_util_quat_rotate(Evas_Map *m, double qx, double qy, double qz,
+                          double qw, double cx, double cy, double cz)
+{
+   MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
+   return;
+   MAGIC_CHECK_END();
+
+   Evas_Map_Point *p, *p_end;
+
+   p = m->points;
+   p_end = p + m->count;
+
+   for (; p < p_end; p++)
+     {
+       double x, y, z, uvx, uvy, uvz, uuvx, uuvy, uuvz;
+
+       x = p->x - cx;
+       y = p->y - cy;
+       z = p->z - cz;
+
+       uvx = qy * z - qz * y;
+       uvy = qz * x - qx * z;
+       uvz = qx * y - qy * x;
+
+       uuvx = qy * uvz - qz * uvy;
+       uuvy = qz * uvx - qx * uvz;
+       uuvz = qx * uvy - qy * uvx;
+
+       uvx *= (2.0f * qw);
+       uvy *= (2.0f * qw);
+       uvz *= (2.0f * qw);
+
+       uuvx *= 2.0f;
+       uuvy *= 2.0f;
+       uuvz *= 2.0f;
+
+       p->px = p->x = cx + x + uvx + uuvx;
+       p->py = p->y = cy + y + uvy + uuvy;
+       p->z = cz + z + uvz + uuvz;
+     }
+}
+
+EAPI void
 evas_map_util_3d_lighting(Evas_Map *m,
                           Evas_Coord lx, Evas_Coord ly, Evas_Coord lz,
                           int lr, int lg, int lb, int ar, int ag, int ab)
@@ -1048,7 +1149,10 @@ evas_map_util_clockwise_get(Evas_Map *m)
    return EINA_FALSE;
 }
 
-void
+/****************************************************************************/
+/* If the return value is true, the map surface should be redrawn.          */
+/****************************************************************************/
+Eina_Bool
 evas_object_map_update(Evas_Object *obj,
                        int x, int y,
                        int imagew, int imageh,
@@ -1069,9 +1173,11 @@ evas_object_map_update(Evas_Object *obj,
         obj->changed_map = EINA_TRUE;
      }
 
-   if (!obj->changed_map) return ;
+   evas_object_map_move_sync(obj);
+
+   if (!obj->changed_map) return EINA_FALSE;
 
-   if (obj->cur.map && obj->spans && obj->cur.map->count != obj->spans->count)
+   if (obj->spans && obj->cur.map->count != obj->spans->count)
      {
         if (obj->spans)
           {
@@ -1085,7 +1191,7 @@ evas_object_map_update(Evas_Object *obj,
      obj->spans = calloc(1, sizeof (RGBA_Map) +
                          sizeof (RGBA_Map_Point) * (obj->cur.map->count - 1));
 
-   if (!obj->spans) return ;
+   if (!obj->spans) return EINA_FALSE;
 
    obj->spans->count = obj->cur.map->count;
    obj->spans->x = x;
@@ -1100,7 +1206,7 @@ evas_object_map_update(Evas_Object *obj,
    p = obj->cur.map->points;
    p_end = p + obj->cur.map->count;
    pt = pts;
-             
+
    pts[0].px = obj->cur.map->persp.px << FP;
    pts[0].py = obj->cur.map->persp.py << FP;
    pts[0].foc = obj->cur.map->persp.foc << FP;
@@ -1114,8 +1220,10 @@ evas_object_map_update(Evas_Object *obj,
         pt->fx = p->px;
         pt->fy = p->py;
         pt->fz = p->z;
-        pt->u = ((lround(p->u) * imagew) / uvw) * FP1;
-        pt->v = ((lround(p->v) * imageh) / uvh) * FP1;
+        if (imagew == 0) pt->u = 0;
+        else pt->u = ((lround(p->u) * imagew) / uvw) * FP1;
+        if (imageh == 0) pt->v = 0;
+        else pt->v = ((lround(p->v) * imageh) / uvh) * FP1;
         if      (pt->u < 0) pt->u = 0;
         else if (pt->u > (imagew * FP1)) pt->u = (imagew * FP1);
         if      (pt->v < 0) pt->v = 0;
@@ -1128,4 +1236,55 @@ evas_object_map_update(Evas_Object *obj,
      }
 
    // Request engine to update it's point
+
+   obj->changed_map = EINA_FALSE;
+
+   return obj->changed_pchange;
+}
+
+void
+evas_map_object_move_diff_set(Evas_Map *m,
+                              Evas_Coord diff_x,
+                              Evas_Coord diff_y)
+{
+   MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
+   return;
+   MAGIC_CHECK_END();
+
+   m->move_sync.diff_x += diff_x;
+   m->move_sync.diff_y += diff_y;
+}
+
+void
+evas_object_map_move_sync(Evas_Object *obj)
+{
+   Evas_Map *m;
+   Evas_Map_Point *p;
+   Evas_Coord diff_x, diff_y;
+   int i, count;
+
+   if (!obj) return;
+
+   if ((!obj->cur.map->move_sync.enabled) ||
+       ((obj->cur.map->move_sync.diff_x == 0) &&
+        (obj->cur.map->move_sync.diff_y == 0)))
+     return;
+
+   m = obj->cur.map;
+   p = m->points;
+   count = m->count;
+   diff_x = m->move_sync.diff_x;
+   diff_y = m->move_sync.diff_y;
+
+   for (i = 0; i < count; i++, p++)
+     {
+        p->px += diff_x;
+        p->py += diff_y;
+        p->x += diff_x;
+        p->y += diff_y;
+     }
+   m->move_sync.diff_x = 0;
+   m->move_sync.diff_y = 0;
+
+   _evas_map_calc_map_geometry(obj);
 }
index e29c5f5..25f075f 100644 (file)
@@ -1,4 +1,5 @@
 #include "evas_common.h"
+#include "evas_private.h"
 
 #ifdef _WIN32_WCE
 # undef remove
@@ -126,6 +127,12 @@ _on_child_del(void *data, Evas *evas __UNUSED__, Evas_Object *o, void *einfo __U
    const Evas_Object_Box_Api *api;
    Evas_Object *box = data;
 
+   if ((!box) || box->delete_me)
+     {
+        ERR("parent box [%p] is invalid", box);
+        return;
+     }
+
    EVAS_OBJECT_BOX_DATA_GET(box, priv);
    api = priv->api;
 
@@ -760,11 +767,17 @@ evas_object_box_layout_horizontal(Evas_Object *o, Evas_Object_Box_Data *priv, vo
 
    n_children = eina_list_count(priv->children);
    if (!n_children)
-     return;
+     {
+        evas_object_size_hint_min_set(o, 0, 0);
+        return;
+     }
 
    objects = (Evas_Object_Box_Option **)alloca(sizeof(Evas_Object_Box_Option *) * n_children);
    if (!objects)
-     return;
+     {
+        evas_object_size_hint_min_set(o, 0, 0);
+        return;
+     }
 
    evas_object_geometry_get(o, &x, &y, &w, &h);
    global_pad = priv->pad.h;
@@ -918,11 +931,17 @@ evas_object_box_layout_vertical(Evas_Object *o, Evas_Object_Box_Data *priv, void
 
    n_children = eina_list_count(priv->children);
    if (!n_children)
-     return;
+     {
+        evas_object_size_hint_min_set(o, 0, 0);
+        return;
+     }
 
    objects = (Evas_Object_Box_Option **)alloca(sizeof(Evas_Object_Box_Option *) * n_children);
    if (!objects)
-     return;
+     {
+        evas_object_size_hint_min_set(o, 0, 0);
+        return;
+     }
 
    evas_object_geometry_get(o, &x, &y, &w, &h);
    global_pad = priv->pad.v;
@@ -1020,7 +1039,10 @@ evas_object_box_layout_homogeneous_horizontal(Evas_Object *o, Evas_Object_Box_Da
 
    n_children = eina_list_count(priv->children);
    if (!n_children)
-     return;
+     {
+        evas_object_size_hint_min_set(o, 0, 0);
+        return;
+     }
 
    evas_object_geometry_get(o, &x, &y, &w, &h);
 
@@ -1081,7 +1103,10 @@ evas_object_box_layout_homogeneous_vertical(Evas_Object *o, Evas_Object_Box_Data
 
    n_children = eina_list_count(priv->children);
    if (!n_children)
-     return;
+     {
+        evas_object_size_hint_min_set(o, 0, 0);
+        return;
+     }
 
    evas_object_geometry_get(o, &x, &y, &w, &h);
 
@@ -1142,7 +1167,10 @@ evas_object_box_layout_homogeneous_max_size_horizontal(Evas_Object *o, Evas_Obje
 
    n_children = eina_list_count(priv->children);
    if (!n_children)
-     return;
+     {
+        evas_object_size_hint_min_set(o, 0, 0);
+        return;
+     }
 
    evas_object_geometry_get(o, &x, &y, &w, &h);
 
@@ -1226,7 +1254,10 @@ evas_object_box_layout_homogeneous_max_size_vertical(Evas_Object *o, Evas_Object
 
    n_children = eina_list_count(priv->children);
    if (!n_children)
-     return;
+     {
+        evas_object_size_hint_min_set(o, 0, 0);
+        return;
+     }
 
    evas_object_geometry_get(o, &x, &y, &w, &h);
 
@@ -1378,20 +1409,17 @@ evas_object_box_layout_flow_horizontal(Evas_Object *o, Evas_Object_Box_Data *pri
 
    n_children = eina_list_count(priv->children);
    if (!n_children)
-     return;
+     {
+        evas_object_size_hint_min_set(o, 0, 0);
+        return;
+     }
 
    /* *per row* arrays */
    row_max_h = (int *)alloca(sizeof(int) * n_children);
-   if (!row_max_h)
-     return;
    row_break = (int *)alloca(sizeof(int) * n_children);
-   if (!row_break)
-     return;
    row_width = (int *)alloca(sizeof(int) * n_children);
-   if (!row_width)
-     return;
 
-   memset(row_width, 0, sizeof(row_width));
+   memset(row_width, 0, sizeof(int) * n_children);
 
    evas_object_geometry_get(o, &x, &y, &w, &h);
 
@@ -1558,20 +1586,17 @@ evas_object_box_layout_flow_vertical(Evas_Object *o, Evas_Object_Box_Data *priv,
 
    n_children = eina_list_count(priv->children);
    if (!n_children)
-     return;
+     {
+        evas_object_size_hint_min_set(o, 0, 0);
+        return;
+     }
 
    /* *per col* arrays */
    col_max_w = (int *)alloca(sizeof(int) * n_children);
-   if (!col_max_w)
-     return;
    col_break = (int *)alloca(sizeof(int) * n_children);
-   if (!col_break)
-     return;
    col_height = (int *)alloca(sizeof(int) * n_children);
-   if (!col_height)
-     return;
 
-   memset(col_height, 0, sizeof(col_height));
+   memset(col_height, 0, sizeof(int) * n_children);
 
    evas_object_geometry_get(o, &x, &y, &w, &h);
 
index bae0809..b878461 100755 (executable)
@@ -21,6 +21,8 @@
 /* private magic number for image objects */
 static const char o_type[] = "image";
 
+const char *o_image_type = o_type;
+
 /* private struct for rectangle object internal data */
 typedef struct _Evas_Object_Image      Evas_Object_Image;
 
@@ -32,12 +34,12 @@ struct _Evas_Object_Image
       int                  spread;
       Evas_Coord_Rectangle fill;
       struct {
-        short         w, h, stride;
+           short         w, h, stride;
       } image;
       struct {
-        short         l, r, t, b;
-        unsigned char fill;
-         double        scale;
+           short         l, r, t, b;
+           unsigned char fill;
+           double        scale;
       } border;
 
       Evas_Object   *source;
@@ -51,6 +53,8 @@ struct _Evas_Object_Image
       unsigned char  has_alpha :1;
       unsigned char  opaque :1;
       unsigned char  opaque_valid :1;
+      Eina_Bool      src_cut_w : 1;
+      Eina_Bool      src_cut_h : 1;
    } cur, prev;
 
    int               pixels_checked_out;
@@ -82,22 +86,25 @@ struct _Evas_Object_Image
 
    void             *engine_data;
 
-   unsigned char     changed : 1;
-   unsigned char     dirty_pixels : 1;
-   unsigned char     filled : 1;
-   unsigned char     proxyrendering : 1;
-   unsigned char     preloading : 1;
-   unsigned char     video_rendering : 1;
-   unsigned char     video_surface : 1;
-   unsigned char     video_visible : 1;
-   unsigned char     created : 1;
+   Eina_Bool         changed : 1;
+   Eina_Bool         dirty_pixels : 1;
+   Eina_Bool         filled : 1;
+   Eina_Bool         preloading : 1;
+   Eina_Bool         video_surface : 1;
+   Eina_Bool         video_visible : 1;
+   Eina_Bool         created : 1;
+   Eina_Bool         proxyrendering : 1;
+   Eina_Bool         proxy_src_clip : 1;
+   Eina_Bool         direct_render : 1;
+   Eina_Bool         written : 1;
+   Eina_Bool         native_video : 1;
 };
 
 /* private methods for image objects */
 static void evas_object_image_unload(Evas_Object *obj, Eina_Bool dirty);
 static void evas_object_image_load(Evas_Object *obj);
-static Evas_Coord evas_object_image_figure_x_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret);
-static Evas_Coord evas_object_image_figure_y_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret);
+static Evas_Coord evas_object_image_figure_x_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Eina_Bool src_cut, Evas_Coord *size_ret);
+static Evas_Coord evas_object_image_figure_y_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Eina_Bool src_cut, Evas_Coord *size_ret);
 
 static void evas_object_image_init(Evas_Object *obj);
 static void *evas_object_image_new(void);
@@ -159,7 +166,7 @@ _evas_object_image_cleanup(Evas_Object *obj, Evas_Object_Image *o)
 {
    if ((o->preloading) && (o->engine_data))
      {
-        o->preloading = 0;
+        o->preloading = EINA_FALSE;
         obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
                                                                  o->engine_data,
                                                                  obj);
@@ -182,8 +189,7 @@ evas_object_image_add(Evas *e)
    evas_object_image_init(obj);
    evas_object_inject(obj, e);
    o = (Evas_Object_Image *)(obj->object_data);
-   o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output,
-                                                                      o->engine_data);
+   o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output, o->engine_data);
    return obj;
 }
 
@@ -235,7 +241,7 @@ _create_tmpf(Evas_Object *obj, void *data, int size, char *format __UNUSED__)
    if (fd < 0)
      {
         const char *tmpdir = getenv("TMPDIR");
-        
+
         if (!tmpdir)
           {
              tmpdir = getenv("TMP");
@@ -245,7 +251,7 @@ _create_tmpf(Evas_Object *obj, void *data, int size, char *format __UNUSED__)
                   if (!tmpdir) tmpdir = "/tmp";
                }
           }
-        snprintf(buf, sizeof(buf), "%s/.evas-tmpf-%i-%p-%i-XXXXXX", 
+        snprintf(buf, sizeof(buf), "%s/.evas-tmpf-%i-%p-%i-XXXXXX",
                  tmpdir, (int)getpid(), data, (int)size);
         fd = mkstemp(buf);
         if (fd < 0) return;
@@ -259,12 +265,12 @@ _create_tmpf(Evas_Object *obj, void *data, int size, char *format __UNUSED__)
 #ifdef __linux__
    unlink(buf);
 #endif
-   
+
    eina_mmap_safety_enabled_set(EINA_TRUE);
-   
-   dst = mmap(NULL, size, 
-              PROT_READ | PROT_WRITE, 
-              MAP_SHARED, 
+
+   dst = mmap(NULL, size,
+              PROT_READ | PROT_WRITE,
+              MAP_SHARED,
               fd, 0);
    if (dst == MAP_FAILED)
      {
@@ -302,7 +308,7 @@ evas_object_image_memfile_set(Evas_Object *obj, void *data, int size, char *form
    evas_object_image_file_set(obj, NULL, NULL);
    // invalidate the cache effectively
    evas_object_image_alpha_set(obj, !o->cur.has_alpha);
-   evas_object_image_alpha_set(obj, !o->cur.has_alpha);
+   evas_object_image_alpha_set(obj, o->cur.has_alpha);
 
    if ((size < 1) || (!data)) return;
 
@@ -321,6 +327,7 @@ evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key)
 {
    Evas_Object_Image *o;
    Evas_Image_Load_Opts lo;
+   Eina_Bool resize_call = EINA_FALSE;
 
    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
    return;
@@ -332,14 +339,14 @@ evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key)
    if ((o->tmpf) && (file != o->tmpf)) _cleanup_tmpf(obj);
    if ((o->cur.file) && (file) && (!strcmp(o->cur.file, file)))
      {
-       if ((!o->cur.key) && (!key))
-         return;
-       if ((o->cur.key) && (key) && (!strcmp(o->cur.key, key)))
-         return;
+        if ((!o->cur.key) && (!key))
+          return;
+        if ((o->cur.key) && (key) && (!strcmp(o->cur.key, key)))
+          return;
      }
-/*
- * WTF? why cancel a null image preload? this is just silly (tm)
-   if (!o->engine_data)
+   /*
   * WTF? why cancel a null image preload? this is just silly (tm)
+    if (!o->engine_data)
      obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
                                                              o->engine_data,
                                                              obj);
@@ -357,13 +364,10 @@ evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key)
      {
         if (o->preloading)
           {
-             o->preloading = 0;
-             obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
-                                                                      o->engine_data,
-                                                                      obj);
+             o->preloading = EINA_FALSE;
+             obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, o->engine_data, obj);
           }
-        obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
-                                                  o->engine_data);
+        obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output, o->engine_data);
      }
    o->load_error = EVAS_LOAD_ERROR_NONE;
    lo.scale_down_by = o->load_opts.scale_down_by;
@@ -376,41 +380,47 @@ evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key)
    lo.region.h = o->load_opts.region.h;
    lo.orientation = o->load_opts.orientation;
    o->engine_data = obj->layer->evas->engine.func->image_load(obj->layer->evas->engine.data.output,
-                                                             o->cur.file,
-                                                             o->cur.key,
-                                                             &o->load_error,
-                                                             &lo);
+                                                              o->cur.file,
+                                                              o->cur.key,
+                                                              &o->load_error,
+                                                              &lo);
    if (o->engine_data)
      {
-       int w, h;
-       int stride;
-
-       obj->layer->evas->engine.func->image_size_get(obj->layer->evas->engine.data.output,
-                                                     o->engine_data, &w, &h);
-       if (obj->layer->evas->engine.func->image_stride_get)
-         obj->layer->evas->engine.func->image_stride_get(obj->layer->evas->engine.data.output,
-                                                         o->engine_data, &stride);
-       else
-         stride = w * 4;
-       o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get(obj->layer->evas->engine.data.output,
-                                                                         o->engine_data);
-       o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output,
-                                                                           o->engine_data);
-       o->cur.image.w = w;
-       o->cur.image.h = h;
-       o->cur.image.stride = stride;
+        int w, h;
+        int stride;
+
+        obj->layer->evas->engine.func->image_size_get(obj->layer->evas->engine.data.output, o->engine_data, &w, &h);
+        if (obj->layer->evas->engine.func->image_stride_get)
+          obj->layer->evas->engine.func->image_stride_get(obj->layer->evas->engine.data.output, o->engine_data, &stride);
+        else
+          stride = w * 4;
+        o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get(obj->layer->evas->engine.data.output, o->engine_data);
+        o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output, o->engine_data);
+
+        if ((o->cur.image.w != w) || (o->cur.image.h != h))
+          resize_call = EINA_TRUE;
+
+        o->cur.image.w = w;
+        o->cur.image.h = h;
+        o->cur.image.stride = stride;
      }
    else
      {
-       if (o->load_error == EVAS_LOAD_ERROR_NONE)
-         o->load_error = EVAS_LOAD_ERROR_GENERIC;
-       o->cur.has_alpha = 1;
-       o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
-       o->cur.image.w = 0;
-       o->cur.image.h = 0;
-       o->cur.image.stride = 0;
+        if (o->load_error == EVAS_LOAD_ERROR_NONE)
+          o->load_error = EVAS_LOAD_ERROR_GENERIC;
+        o->cur.has_alpha = 1;
+        o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
+
+        if ((o->cur.image.w != 0) || (o->cur.image.h != 0))
+          resize_call = EINA_TRUE;
+
+        o->cur.image.w = 0;
+        o->cur.image.h = 0;
+        o->cur.image.stride = 0;
      }
-   o->changed = 1;
+   o->written = EINA_FALSE;
+   o->changed = EINA_TRUE;
+   if (resize_call) evas_object_inform_call_image_resize(obj);
    evas_object_change(obj);
 }
 
@@ -434,6 +444,48 @@ evas_object_image_file_get(const Evas_Object *obj, const char **file, const char
    if (key) *key = o->cur.key;
 }
 
+EAPI void
+evas_object_image_source_visible_set(Evas_Object *obj, Eina_Bool visible)
+{
+   Evas_Object_Image *o;
+
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return;
+   MAGIC_CHECK_END();
+   o = (Evas_Object_Image *)(obj->object_data);
+   MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
+   return;
+   MAGIC_CHECK_END();
+   if (!o->cur.source) return;
+
+   visible = !!visible;
+   if (o->cur.source->proxy.src_invisible == !visible) return;
+   o->cur.source->proxy.src_invisible = !visible;
+   o->cur.source->changed_src_visible = EINA_TRUE;
+   evas_object_smart_member_cache_invalidate(o->cur.source, EINA_FALSE,
+                                             EINA_FALSE, EINA_TRUE);
+   evas_object_change(obj);
+}
+
+EAPI Eina_Bool
+evas_object_image_source_visible_get(const Evas_Object *obj)
+{
+   Evas_Object_Image *o;
+   Eina_Bool visible = EINA_FALSE;
+
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return EINA_FALSE;
+   MAGIC_CHECK_END();
+
+   o = (Evas_Object_Image *)(obj->object_data);
+   MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
+   return EINA_FALSE;
+   MAGIC_CHECK_END();
+
+   visible = !o->cur.source->proxy.src_invisible;
+   return visible;
+}
+
 EAPI Eina_Bool
 evas_object_image_source_set(Evas_Object *obj, Evas_Object *src)
 {
@@ -513,6 +565,40 @@ evas_object_image_source_unset(Evas_Object *obj)
 }
 
 EAPI void
+evas_object_image_source_clip_set(Evas_Object *obj, Eina_Bool source_clip)
+{
+   Evas_Object_Image *o;
+
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return;
+   MAGIC_CHECK_END();
+
+   o = obj->object_data;
+
+   source_clip = !!source_clip;
+   if (o->proxy_src_clip == source_clip) return;
+   o->proxy_src_clip = source_clip;
+
+   if (!o->cur.source) return;
+
+   evas_object_change(o->cur.source);
+}
+
+EAPI Eina_Bool
+evas_object_image_source_clip_get(const Evas_Object *obj)
+{
+   Evas_Object_Image *o;
+
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return EINA_FALSE;
+   MAGIC_CHECK_END();
+
+   o = obj->object_data;
+
+   return o->proxy_src_clip;
+}
+
+EAPI void
 evas_object_image_border_set(Evas_Object *obj, int l, int r, int t, int b)
 {
    Evas_Object_Image *o;
@@ -537,7 +623,7 @@ evas_object_image_border_set(Evas_Object *obj, int l, int r, int t, int b)
    o->cur.border.t = t;
    o->cur.border.b = b;
    o->cur.opaque_valid = 0;
-   o->changed = 1;
+   o->changed = EINA_TRUE;
    evas_object_change(obj);
 }
 
@@ -581,7 +667,7 @@ evas_object_image_border_center_fill_set(Evas_Object *obj, Evas_Border_Fill_Mode
    MAGIC_CHECK_END();
    if (fill == o->cur.border.fill) return;
    o->cur.border.fill = fill;
-   o->changed = 1;
+   o->changed = EINA_TRUE;
    evas_object_change(obj);
 }
 
@@ -618,15 +704,18 @@ evas_object_image_filled_set(Evas_Object *obj, Eina_Bool setting)
 
    o->filled = setting;
    if (!o->filled)
-     evas_object_event_callback_del(obj, EVAS_CALLBACK_RESIZE, evas_object_image_filled_resize_listener);
+     evas_object_event_callback_del(obj, EVAS_CALLBACK_RESIZE,
+                                    evas_object_image_filled_resize_listener);
    else
      {
-       Evas_Coord w, h;
+        Evas_Coord w, h;
 
-       evas_object_geometry_get(obj, NULL, NULL, &w, &h);
-       evas_object_image_fill_set(obj, 0, 0, w, h);
+        evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+        evas_object_image_fill_set(obj, 0, 0, w, h);
 
-       evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, evas_object_image_filled_resize_listener, NULL);
+        evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
+                                       evas_object_image_filled_resize_listener,
+                                       NULL);
      }
 }
 
@@ -660,7 +749,7 @@ evas_object_image_border_scale_set(Evas_Object *obj, double scale)
    MAGIC_CHECK_END();
    if (scale == o->cur.border.scale) return;
    o->cur.border.scale = scale;
-   o->changed = 1;
+   o->changed = EINA_TRUE;
    evas_object_change(obj);
 }
 
@@ -706,7 +795,8 @@ evas_object_image_fill_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Co
    o->cur.fill.w = w;
    o->cur.fill.h = h;
    o->cur.opaque_valid = 0;
-   o->changed = 1;
+   if (o->cur.source) o->cur.source->proxy.redraw = EINA_TRUE;
+   o->changed = EINA_TRUE;
    evas_object_change(obj);
 }
 
@@ -751,7 +841,7 @@ evas_object_image_fill_spread_set(Evas_Object *obj, Evas_Fill_Spread spread)
    MAGIC_CHECK_END();
    if (spread == (Evas_Fill_Spread)o->cur.spread) return;
    o->cur.spread = spread;
-   o->changed = 1;
+   o->changed = EINA_TRUE;
    evas_object_change(obj);
 }
 
@@ -793,9 +883,7 @@ evas_object_image_size_set(Evas_Object *obj, int w, int h)
    o->cur.image.w = w;
    o->cur.image.h = h;
    if (o->engine_data)
-      o->engine_data = obj->layer->evas->engine.func->image_size_set(obj->layer->evas->engine.data.output,
-                                                                     o->engine_data,
-                                                                     w, h);
+      o->engine_data = obj->layer->evas->engine.func->image_size_set(obj->layer->evas->engine.data.output, o->engine_data, w, h);
    else
       o->engine_data = obj->layer->evas->engine.func->image_new_from_copied_data
       (obj->layer->evas->engine.data.output, w, h, NULL, o->cur.has_alpha,
@@ -820,6 +908,7 @@ evas_object_image_size_set(Evas_Object *obj, int w, int h)
      }
    else
       stride = w * 4;
+   o->written = EINA_TRUE;
    o->cur.image.stride = stride;
 
 /* FIXME - in engine call above
@@ -829,7 +918,8 @@ evas_object_image_size_set(Evas_Object *obj, int w, int h)
                                                                     o->cur.has_alpha);
 */
    EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
-   o->changed = 1;
+   o->changed = EINA_TRUE;
+   evas_object_inform_call_image_resize(obj);
    evas_object_change(obj);
 }
 
@@ -899,26 +989,19 @@ evas_object_image_data_convert(Evas_Object *obj, Evas_Colorspace to_cspace)
    MAGIC_CHECK_END();
    if ((o->preloading) && (o->engine_data))
      {
-        o->preloading = 0;
-        obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
-                                                                 o->engine_data,
-                                                                 obj);
+        o->preloading = EINA_FALSE;
+        obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, o->engine_data, obj);
      }
    if (!o->engine_data) return NULL;
    if (o->video_surface)
      o->video.update_pixels(o->video.data, obj, &o->video);
    if (o->cur.cspace == to_cspace) return NULL;
    data = NULL;
-   o->engine_data = 
-     obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
-                                                   o->engine_data, 0, &data,
-                                                   &o->load_error);
+   o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output, o->engine_data, 0, &data, &o->load_error);
    result = evas_object_image_data_convert_internal(o, data, to_cspace);
    if (o->engine_data)
      {
-        o->engine_data = 
-          obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
-                                                        o->engine_data, data);
+        o->engine_data = obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output, o->engine_data, data);
      }
 
   return result;
@@ -928,6 +1011,7 @@ evas_object_image_data_set(Evas_Object *obj, void *data)
 {
    Evas_Object_Image *o;
    void *p_data;
+   Eina_Bool resize_call = EINA_FALSE;
 
    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
    return;
@@ -940,17 +1024,17 @@ evas_object_image_data_set(Evas_Object *obj, void *data)
    p_data = o->engine_data;
    if (data)
      {
-       if (o->engine_data)
+        if (o->engine_data)
           {
-             o->engine_data = 
+             o->engine_data =
                obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
                                                              o->engine_data,
                                                              data);
           }
-       else
+        else
           {
-             o->engine_data = 
-               obj->layer->evas->engine.func->image_new_from_data(obj->layer->evas->engine.data.output,
+             o->engine_data =
+                obj->layer->evas->engine.func->image_new_from_data(obj->layer->evas->engine.data.output,
                                                                   o->cur.image.w,
                                                                   o->cur.image.h,
                                                                   data,
@@ -960,7 +1044,7 @@ evas_object_image_data_set(Evas_Object *obj, void *data)
         if (o->engine_data)
           {
              int stride = 0;
-             
+
              if (obj->layer->evas->engine.func->image_scale_hint_set)
                 obj->layer->evas->engine.func->image_scale_hint_set
                 (obj->layer->evas->engine.data.output,
@@ -968,7 +1052,7 @@ evas_object_image_data_set(Evas_Object *obj, void *data)
              if (obj->layer->evas->engine.func->image_content_hint_set)
                 obj->layer->evas->engine.func->image_content_hint_set
                 (obj->layer->evas->engine.data.output,
-                    o->engine_data, o->content_hint); 
+                    o->engine_data, o->content_hint);
              if (obj->layer->evas->engine.func->image_stride_get)
                 obj->layer->evas->engine.func->image_stride_get
                 (obj->layer->evas->engine.data.output,
@@ -977,17 +1061,19 @@ evas_object_image_data_set(Evas_Object *obj, void *data)
                 stride = o->cur.image.w * 4;
              o->cur.image.stride = stride;
          }
+        o->written = EINA_TRUE;
      }
    else
      {
-       if (o->engine_data)
-         obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
-                                                   o->engine_data);
-       o->load_error = EVAS_LOAD_ERROR_NONE;
-       o->cur.image.w = 0;
-       o->cur.image.h = 0;
-       o->cur.image.stride = 0;
-       o->engine_data = NULL;
+        if (o->engine_data)
+          obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output, o->engine_data);
+        o->load_error = EVAS_LOAD_ERROR_NONE;
+        if ((o->cur.image.w != 0) || (o->cur.image.h != 0))
+          resize_call = EINA_TRUE;
+        o->cur.image.w = 0;
+        o->cur.image.h = 0;
+        o->cur.image.stride = 0;
+        o->engine_data = NULL;
      }
 /* FIXME - in engine call above
    if (o->engine_data)
@@ -998,11 +1084,11 @@ evas_object_image_data_set(Evas_Object *obj, void *data)
    if (o->pixels_checked_out > 0) o->pixels_checked_out--;
    if (p_data != o->engine_data)
      {
-       EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
-       o->pixels_checked_out = 0;
+        EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
+        o->written = EINA_TRUE;
+        o->pixels_checked_out = 0;
      }
-   o->changed = 1;
-   evas_object_change(obj);
+   if (resize_call) evas_object_inform_call_image_resize(obj);
 }
 
 EAPI void *
@@ -1029,11 +1115,7 @@ evas_object_image_data_get(const Evas_Object *obj, Eina_Bool for_writing)
       obj->layer->evas->engine.func->image_content_hint_set
       (obj->layer->evas->engine.data.output,
           o->engine_data, o->content_hint);
-   o->engine_data = 
-     obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
-                                                   o->engine_data,
-                                                   for_writing, &data,
-                                                   &o->load_error);
+   o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output, o->engine_data, for_writing, &data, &o->load_error);
 
    /* if we fail to get engine_data, we have to return NULL */
    if (!o->engine_data) return NULL;
@@ -1053,7 +1135,8 @@ evas_object_image_data_get(const Evas_Object *obj, Eina_Bool for_writing)
    o->pixels_checked_out++;
    if (for_writing)
      {
-       EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
+        EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
+        o->written = EINA_TRUE;
      }
 
    return data;
@@ -1073,9 +1156,9 @@ evas_object_image_preload(Evas_Object *obj, Eina_Bool cancel)
    MAGIC_CHECK_END();
    if (!o->engine_data)
      {
-        o->preloading = 1;
-       evas_object_inform_call_image_preloaded(obj);
-       return;
+        o->preloading = EINA_TRUE;
+        evas_object_inform_call_image_preloaded(obj);
+        return;
      }
    // FIXME: if already busy preloading, then dont request again until
    // preload done
@@ -1083,7 +1166,7 @@ evas_object_image_preload(Evas_Object *obj, Eina_Bool cancel)
      {
         if (o->preloading)
           {
-             o->preloading = 0;
+             o->preloading = EINA_FALSE;
              obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
                                                                       o->engine_data,
                                                                       obj);
@@ -1093,7 +1176,7 @@ evas_object_image_preload(Evas_Object *obj, Eina_Bool cancel)
      {
         if (!o->preloading)
           {
-             o->preloading = 1;
+             o->preloading = EINA_TRUE;
              obj->layer->evas->engine.func->image_data_preload_request(obj->layer->evas->engine.data.output,
                                                                        o->engine_data,
                                                                        obj);
@@ -1119,8 +1202,8 @@ evas_object_image_data_copy_set(Evas_Object *obj, void *data)
        (o->cur.image.h <= 0)) return;
    if (o->engine_data)
      obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output,
-                                              o->engine_data);
-   o->engine_data = 
+                                               o->engine_data);
+   o->engine_data =
      obj->layer->evas->engine.func->image_new_from_copied_data(obj->layer->evas->engine.data.output,
                                                                o->cur.image.w,
                                                                o->cur.image.h,
@@ -1131,7 +1214,7 @@ evas_object_image_data_copy_set(Evas_Object *obj, void *data)
      {
         int stride = 0;
 
-        o->engine_data = 
+        o->engine_data =
           obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
                                                          o->engine_data,
                                                          o->cur.has_alpha);
@@ -1150,6 +1233,7 @@ evas_object_image_data_copy_set(Evas_Object *obj, void *data)
         else
            stride = o->cur.image.w * 4;
         o->cur.image.stride = stride;
+        o->written = EINA_TRUE;
      }
    o->pixels_checked_out = 0;
    EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
@@ -1170,9 +1254,11 @@ evas_object_image_data_update_add(Evas_Object *obj, int x, int y, int w, int h)
    MAGIC_CHECK_END();
    RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, o->cur.image.w, o->cur.image.h);
    if ((w <= 0)  || (h <= 0)) return;
+   if (!o->written) return;
    NEW_RECT(r, x, y, w, h);
    if (r) o->pixel_updates = eina_list_append(o->pixel_updates, r);
-   o->changed = 1;
+
+   o->changed = EINA_TRUE;
    evas_object_change(obj);
 }
 
@@ -1190,7 +1276,7 @@ evas_object_image_alpha_set(Evas_Object *obj, Eina_Bool has_alpha)
    MAGIC_CHECK_END();
    if ((o->preloading) && (o->engine_data))
      {
-        o->preloading = 0;
+        o->preloading = EINA_FALSE;
         obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
                                                                  o->engine_data,
                                                                  obj);
@@ -1203,7 +1289,7 @@ evas_object_image_alpha_set(Evas_Object *obj, Eina_Bool has_alpha)
      {
         int stride = 0;
 
-        o->engine_data = 
+        o->engine_data =
           obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
                                                          o->engine_data,
                                                          o->cur.has_alpha);
@@ -1222,6 +1308,7 @@ evas_object_image_alpha_set(Evas_Object *obj, Eina_Bool has_alpha)
         else
            stride = o->cur.image.w * 4;
         o->cur.image.stride = stride;
+        o->written = EINA_TRUE;
      }
    evas_object_image_data_update_add(obj, 0, 0, o->cur.image.w, o->cur.image.h);
    EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o);
@@ -1259,7 +1346,7 @@ evas_object_image_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth_scale)
        ((!smooth_scale) && (!o->cur.smooth_scale)))
      return;
    o->cur.smooth_scale = smooth_scale;
-   o->changed = 1;
+   o->changed = EINA_TRUE;
    evas_object_change(obj);
 }
 
@@ -1292,7 +1379,7 @@ evas_object_image_reload(Evas_Object *obj)
    MAGIC_CHECK_END();
    if ((o->preloading) && (o->engine_data))
      {
-        o->preloading = 0;
+        o->preloading = EINA_FALSE;
         obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
                                                                  o->engine_data,
                                                                  obj);
@@ -1306,7 +1393,7 @@ evas_object_image_reload(Evas_Object *obj)
    evas_object_image_load(obj);
    o->prev.file = NULL;
    o->prev.key = NULL;
-   o->changed = 1;
+   o->changed = EINA_TRUE;
    evas_object_change(obj);
 }
 
@@ -1316,6 +1403,7 @@ evas_object_image_save(const Evas_Object *obj, const char *file, const char *key
    Evas_Object_Image *o;
    DATA32 *data = NULL;
    int quality = 80, compress = 9, ok = 0;
+   char *encoding = NULL;
    RGBA_Image *im;
 
    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
@@ -1326,29 +1414,30 @@ evas_object_image_save(const Evas_Object *obj, const char *file, const char *key
    return 0;
    MAGIC_CHECK_END();
 
-   if (!o->engine_data) return 0;
-   o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
-                                                                 o->engine_data,
-                                                                 0,
-                                                                 &data,
-                                                                  &o->load_error);
+   if (!o->engine_data)
+     {
+        ERR("the engine_data of object is null");
+        return 0;
+     }
+   o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output, o->engine_data, 0, &data, &o->load_error);
    if (flags)
      {
-       char *p, *pp;
-       char *tflags;
+        char *p, *pp;
+        char *tflags;
 
-       tflags = alloca(strlen(flags) + 1);
-       strcpy(tflags, flags);
-       p = tflags;
-       while (p)
-         {
-            pp = strchr(p, ' ');
-            if (pp) *pp = 0;
-            sscanf(p, "quality=%i", &quality);
-            sscanf(p, "compress=%i", &compress);
-            if (pp) p = pp + 1;
-            else break;
-         }
+        tflags = alloca(strlen(flags) + 1);
+        strcpy(tflags, flags);
+        p = tflags;
+        while (p)
+          {
+             pp = strchr(p, ' ');
+             if (pp) *pp = 0;
+             sscanf(p, "quality=%i", &quality);
+             sscanf(p, "compress=%i", &compress);
+             sscanf(p, "encoding=%ms", &encoding);
+             if (pp) p = pp + 1;
+             else break;
+          }
      }
    im = (RGBA_Image*) evas_cache_image_data(evas_common_image_cache_get(),
                                             o->cur.image.w,
@@ -1358,25 +1447,27 @@ evas_object_image_save(const Evas_Object *obj, const char *file, const char *key
                                             EVAS_COLORSPACE_ARGB8888);
    if (im)
      {
-       if (o->cur.cspace == EVAS_COLORSPACE_ARGB8888)
-         im->image.data = data;
-       else
-         im->image.data = evas_object_image_data_convert_internal(o,
-                                                                  data,
-                                                                  EVAS_COLORSPACE_ARGB8888);
-       if (im->image.data)
-         {
-            ok = evas_common_save_image_to_file(im, file, key, quality, compress);
+        if (o->cur.cspace == EVAS_COLORSPACE_ARGB8888)
+          im->image.data = data;
+        else
+          im->image.data = evas_object_image_data_convert_internal(o,
+                                                                   data,
+                                                                   EVAS_COLORSPACE_ARGB8888);
+        if (im->image.data)
+          {
+             ok = evas_common_save_image_to_file(im, file, key, quality, compress, encoding);
 
-            if (o->cur.cspace != EVAS_COLORSPACE_ARGB8888)
-              free(im->image.data);
-         }
+             if (o->cur.cspace != EVAS_COLORSPACE_ARGB8888)
+               free(im->image.data);
+          }
 
-       evas_cache_image_drop(&im->cache_entry);
+        evas_cache_image_drop(&im->cache_entry);
      }
    o->engine_data = obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
                                                                   o->engine_data,
                                                                   data);
+
+   free(encoding);
    return ok;
 }
 
@@ -1421,7 +1512,7 @@ evas_object_image_pixels_import(Evas_Object *obj, Evas_Pixel_Import_Source *pixe
                    obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
                                                                   o->engine_data,
                                                                   o->cur.has_alpha);
-                 o->changed = 1;
+                 o->changed = EINA_TRUE;
                  evas_object_change(obj);
               }
          }
@@ -1429,41 +1520,30 @@ evas_object_image_pixels_import(Evas_Object *obj, Evas_Pixel_Import_Source *pixe
 #endif
 #ifdef BUILD_CONVERT_YUV
       case EVAS_PIXEL_FORMAT_YUV420P_601:
-         {
-            if (o->engine_data)
-              {
-                 DATA32 *image_pixels = NULL;
-
-                 o->engine_data =
-                   obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
-                                                                 o->engine_data,
-                                                                 1,
-                                                                 &image_pixels,
-                                                                  &o->load_error);
-                 if (image_pixels)
-                   evas_common_convert_yuv_420p_601_rgba((DATA8 **) pixels->rows,
-                                                         (DATA8 *) image_pixels,
-                                                         o->cur.image.w,
-                                                         o->cur.image.h);
-                 if (o->engine_data)
-                   o->engine_data =
-                   obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
-                                                                 o->engine_data,
-                                                                 image_pixels);
-                 if (o->engine_data)
-                   o->engine_data =
-                   obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
-                                                                  o->engine_data,
-                                                                  o->cur.has_alpha);
-                 o->changed = 1;
-                 evas_object_change(obj);
-              }
-         }
-       break;
+          {
+             if (o->engine_data)
+               {
+                  DATA32 *image_pixels = NULL;
+
+                  o->engine_data =
+                     obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output, o->engine_data, 1, &image_pixels,&o->load_error);
+                  if (image_pixels)
+                    evas_common_convert_yuv_420p_601_rgba((DATA8 **) pixels->rows, (DATA8 *) image_pixels, o->cur.image.w, o->cur.image.h);
+                  if (o->engine_data)
+                    o->engine_data =
+                       obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output, o->engine_data, image_pixels);
+                  if (o->engine_data)
+                    o->engine_data =
+                       obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output, o->engine_data, o->cur.has_alpha);
+                  o->changed = EINA_TRUE;
+                  evas_object_change(obj);
+               }
+          }
+        break;
 #endif
       default:
-       return 0;
-       break;
+        return 0;
+        break;
      }
    return 1;
 }
@@ -1496,9 +1576,9 @@ evas_object_image_pixels_dirty_set(Evas_Object *obj, Eina_Bool dirty)
    MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
    return;
    MAGIC_CHECK_END();
-   if (dirty) o->dirty_pixels = 1;
-   else o->dirty_pixels = 0;
-   o->changed = 1;
+   if (dirty) o->dirty_pixels = EINA_TRUE;
+   else o->dirty_pixels = EINA_FALSE;
+   o->changed = EINA_TRUE;
    evas_object_change(obj);
 }
 
@@ -1534,11 +1614,11 @@ evas_object_image_load_dpi_set(Evas_Object *obj, double dpi)
    o->load_opts.dpi = dpi;
    if (o->cur.file)
      {
-       evas_object_image_unload(obj, 0);
+        evas_object_image_unload(obj, 0);
         evas_object_inform_call_image_unloaded(obj);
-       evas_object_image_load(obj);
-       o->changed = 1;
-       evas_object_change(obj);
+        evas_object_image_load(obj);
+        o->changed = EINA_TRUE;
+        evas_object_change(obj);
      }
 }
 
@@ -1574,11 +1654,11 @@ evas_object_image_load_size_set(Evas_Object *obj, int w, int h)
    o->load_opts.h = h;
    if (o->cur.file)
      {
-       evas_object_image_unload(obj, 0);
+        evas_object_image_unload(obj, 0);
         evas_object_inform_call_image_unloaded(obj);
-       evas_object_image_load(obj);
-       o->changed = 1;
-       evas_object_change(obj);
+        evas_object_image_load(obj);
+        o->changed = EINA_TRUE;
+        evas_object_change(obj);
      }
 }
 
@@ -1614,11 +1694,11 @@ evas_object_image_load_scale_down_set(Evas_Object *obj, int scale_down)
    o->load_opts.scale_down_by = scale_down;
    if (o->cur.file)
      {
-       evas_object_image_unload(obj, 0);
+        evas_object_image_unload(obj, 0);
         evas_object_inform_call_image_unloaded(obj);
-       evas_object_image_load(obj);
-       o->changed = 1;
-       evas_object_change(obj);
+        evas_object_image_load(obj);
+        o->changed = EINA_TRUE;
+        evas_object_change(obj);
      }
 }
 
@@ -1657,11 +1737,11 @@ evas_object_image_load_region_set(Evas_Object *obj, int x, int y, int w, int h)
    o->load_opts.region.h = h;
    if (o->cur.file)
      {
-       evas_object_image_unload(obj, 0);
+        evas_object_image_unload(obj, 0);
         evas_object_inform_call_image_unloaded(obj);
-       evas_object_image_load(obj);
-       o->changed = 1;
-       evas_object_change(obj);
+        evas_object_image_load(obj);
+        o->changed = EINA_TRUE;
+        evas_object_change(obj);
      }
 }
 
@@ -1730,9 +1810,7 @@ evas_object_image_colorspace_set(Evas_Object *obj, Evas_Colorspace cspace)
 
    o->cur.cspace = cspace;
    if (o->engine_data)
-     obj->layer->evas->engine.func->image_colorspace_set(obj->layer->evas->engine.data.output,
-                                                        o->engine_data,
-                                                        cspace);
+     obj->layer->evas->engine.func->image_colorspace_set(obj->layer->evas->engine.data.output, o->engine_data, cspace);
 }
 
 EAPI Evas_Colorspace
@@ -1765,36 +1843,36 @@ evas_object_image_video_surface_set(Evas_Object *obj, Evas_Video_Surface *surf)
    _evas_object_image_cleanup(obj, o);
    if (o->video_surface)
      {
-        o->video_surface = 0;
-       obj->layer->evas->video_objects = eina_list_remove(obj->layer->evas->video_objects, obj);
+        o->video_surface = EINA_FALSE;
+        obj->layer->evas->video_objects = eina_list_remove(obj->layer->evas->video_objects, obj);
      }
 
    if (surf)
      {
         if (surf->version != EVAS_VIDEO_SURFACE_VERSION) return ;
 
-       if (!surf->update_pixels ||
-           !surf->move ||
-           !surf->resize ||
-           !surf->hide ||
-           !surf->show)
-         return ;
+        if (!surf->update_pixels ||
+            !surf->move ||
+            !surf->resize ||
+            !surf->hide ||
+            !surf->show)
+          return ;
 
         o->created = EINA_TRUE;
-       o->video_surface = 1;
-       o->video = *surf;
+        o->video_surface = EINA_TRUE;
+        o->video = *surf;
 
-       obj->layer->evas->video_objects = eina_list_append(obj->layer->evas->video_objects, obj);
+        obj->layer->evas->video_objects = eina_list_append(obj->layer->evas->video_objects, obj);
      }
    else
      {
-        o->video_surface = 0;
-       o->video.update_pixels = NULL;
-       o->video.move = NULL;
-       o->video.resize = NULL;
-       o->video.hide = NULL;
-       o->video.show = NULL;
-       o->video.data = NULL;
+        o->video_surface = EINA_FALSE;
+        o->video.update_pixels = NULL;
+        o->video.move = NULL;
+        o->video.resize = NULL;
+        o->video.hide = NULL;
+        o->video.show = NULL;
+        o->video.data = NULL;
      }
 }
 
@@ -1831,10 +1909,10 @@ evas_object_image_native_surface_set(Evas_Object *obj, Evas_Native_Surface *surf
    if ((surf) &&
        ((surf->version < 2) ||
         (surf->version > EVAS_NATIVE_SURFACE_VERSION))) return;
-   o->engine_data = 
-      obj->layer->evas->engine.func->image_native_set(obj->layer->evas->engine.data.output,
-                                                      o->engine_data,
-                                                      surf);
+   o->engine_data = obj->layer->evas->engine.func->image_native_set(obj->layer->evas->engine.data.output, o->engine_data, surf);
+   if ((surf) &&
+       (surf->type == EVAS_NATIVE_SURFACE_TIZEN))
+       o->native_video = EINA_TRUE;
 }
 
 EAPI Evas_Native_Surface *
@@ -1850,8 +1928,7 @@ evas_object_image_native_surface_get(const Evas_Object *obj)
    return NULL;
    MAGIC_CHECK_END();
    if (!obj->layer->evas->engine.func->image_native_get) return NULL;
-   return obj->layer->evas->engine.func->image_native_get(obj->layer->evas->engine.data.output,
-                                                         o->engine_data);
+   return obj->layer->evas->engine.func->image_native_get(obj->layer->evas->engine.data.output, o->engine_data);
 }
 
 EAPI void
@@ -1871,10 +1948,10 @@ evas_object_image_scale_hint_set(Evas_Object *obj, Evas_Image_Scale_Hint hint)
    if (o->engine_data)
      {
         int stride = 0;
-        
+
         if (obj->layer->evas->engine.func->image_scale_hint_set)
-           obj->layer->evas->engine.func->image_scale_hint_set
-           (obj->layer->evas->engine.data.output,
+          obj->layer->evas->engine.func->image_scale_hint_set
+             (obj->layer->evas->engine.data.output,
                o->engine_data, o->scale_hint);
         if (obj->layer->evas->engine.func->image_stride_get)
            obj->layer->evas->engine.func->image_stride_get
@@ -1918,7 +1995,7 @@ evas_object_image_content_hint_set(Evas_Object *obj, Evas_Image_Content_Hint hin
    if (o->engine_data)
      {
         int stride = 0;
-        
+
         if (obj->layer->evas->engine.func->image_content_hint_set)
            obj->layer->evas->engine.func->image_content_hint_set
            (obj->layer->evas->engine.data.output,
@@ -2127,7 +2204,7 @@ evas_object_image_animated_frame_set(Evas_Object *obj, int frame_index)
    o->prev.frame = o->cur.frame;
    o->cur.frame = frame_index;
 
-   o->changed = 1;
+   o->changed = EINA_TRUE;
    evas_object_change(obj);
 
 }
@@ -2154,37 +2231,37 @@ evas_image_cache_reload(Evas *e)
    evas_image_cache_flush(e);
    EINA_INLIST_FOREACH(e->layers, layer)
      {
-       Evas_Object *obj;
+        Evas_Object *obj;
 
-       EINA_INLIST_FOREACH(layer->objects, obj)
-         {
-            Evas_Object_Image *o;
+        EINA_INLIST_FOREACH(layer->objects, obj)
+          {
+             Evas_Object_Image *o;
 
-            o = (Evas_Object_Image *)(obj->object_data);
-            if (o->magic == MAGIC_OBJ_IMAGE)
-              {
-                 evas_object_image_unload(obj, 1);
+             o = (Evas_Object_Image *)(obj->object_data);
+             if (o->magic == MAGIC_OBJ_IMAGE)
+               {
+                  evas_object_image_unload(obj, 1);
                   evas_object_inform_call_image_unloaded(obj);
-              }
-         }
+               }
+          }
      }
    evas_image_cache_flush(e);
    EINA_INLIST_FOREACH(e->layers, layer)
      {
-       Evas_Object *obj;
+        Evas_Object *obj;
 
-       EINA_INLIST_FOREACH(layer->objects, obj)
-         {
-            Evas_Object_Image *o;
+        EINA_INLIST_FOREACH(layer->objects, obj)
+          {
+             Evas_Object_Image *o;
 
-            o = (Evas_Object_Image *)(obj->object_data);
-            if (o->magic == MAGIC_OBJ_IMAGE)
-              {
-                 evas_object_image_load(obj);
-                 o->changed = 1;
-                 evas_object_change(obj);
-              }
-         }
+             o = (Evas_Object_Image *)(obj->object_data);
+             if (o->magic == MAGIC_OBJ_IMAGE)
+               {
+                  evas_object_image_load(obj);
+                  o->changed = EINA_TRUE;
+                  evas_object_change(obj);
+               }
+          }
      }
    evas_image_cache_flush(e);
 }
@@ -2217,7 +2294,7 @@ evas_image_max_size_get(const Evas *e, int *maxw, int *maxh)
    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
    return EINA_FALSE;
    MAGIC_CHECK_END();
-   
+
    if (maxw) *maxw = 0xffff;
    if (maxh) *maxh = 0xffff;
    if (!e->engine.func->image_max_size_get) return EINA_FALSE;
@@ -2236,14 +2313,24 @@ _proxy_unset(Evas_Object *proxy)
    o = proxy->object_data;
    if (!o->cur.source) return;
 
+   if (o->cur.source->proxy.surface)
+     {
+        proxy->layer->evas->engine.func->image_map_surface_free(proxy->layer->evas->engine.data.output,
+                                                                o->cur.source->proxy.surface);
+        o->cur.source->proxy.surface = NULL;
+     }
+
    o->cur.source->proxy.proxies = eina_list_remove(o->cur.source->proxy.proxies, proxy);
 
+   if (!o->cur.source->proxy.proxies) o->cur.source->proxy.redraw = EINA_FALSE;
    o->cur.source = NULL;
    if (o->cur.defmap)
      {
         evas_map_free(o->cur.defmap);
         o->cur.defmap = NULL;
      }
+   o->cur.src_cut_w = EINA_FALSE;
+   o->cur.src_cut_h = EINA_FALSE;
 }
 
 
@@ -2274,11 +2361,11 @@ _proxy_error(Evas_Object *proxy, void *context, void *output, void *surface,
    int r = rand() % 255;
    int g = rand() % 255;
    int b = rand() % 255;
-   
+
    /* XXX: Eina log error or something I'm sure
     * If it bugs you, just fix it.  Don't tell me */
    if (VERBOSE_PROXY_ERROR) printf("Err: Argh! Recursive proxies.\n");
-   
+
    func = proxy->layer->evas->engine.func;
    func->context_color_set(output, context, r, g, b, 255);
    func->context_multiplier_unset(output, context);
@@ -2290,40 +2377,63 @@ _proxy_error(Evas_Object *proxy, void *context, void *output, void *surface,
    return;
 }
 
-/*
+/* Check the proxy just shows a part of the source area.
+   If so, proxy doens't need to allocate whole size of the source surface.
+   This related code could be removed once the gl texture maximum size
+   limitation is unleashed. */
 static void
-_proxy_subrender_recurse(Evas_Object *obj, Evas_Object *clip, void *output, void *surface, void *ctx, int x, int y)
+_proxy_area_get(Evas_Object *proxy_obj, Evas_Object_Image *o, Evas_Object *source, Evas_Coord_Point* offset, Evas_Coord_Size* size, Eina_Bool *src_cut_w, Eina_Bool *src_cut_h)
 {
-   Evas_Object *obj2;
-   Evas *e = obj->layer->evas;
-   
-   if (obj->clip.clipees) return;
-   if (!obj->cur.visible) return;
-   if ((!clip) || (clip != obj->cur.clipper))
+   double scale_x = (double) source->cur.geometry.w / (double) o->cur.fill.w;
+   double scale_y = (double) source->cur.geometry.h / (double) o->cur.fill.h;
+   size->w = ((double) proxy_obj->cur.geometry.w * scale_x);
+   size->h = ((double) proxy_obj->cur.geometry.h * scale_y);
+
+   //Need to draw whole area of the source.
+   /* Tizen Only: Since Proxy has the texture size limitation problem,
+      we set a key value for entry magnifier so that evas does some hackish way.
+      This hackish code should be removed once evas supports a mechanism like a
+      virtual texture. */
+   /* if ((o->cur.fill.x > 0) ||
+        ((o->cur.fill.x + o->cur.fill.w) < proxy_obj->cur.geometry.w)) */
+   if (!evas_object_data_get(proxy_obj, "tizenonly") &&
+       ((o->cur.fill.x > 0) ||
+         ((o->cur.fill.x + o->cur.fill.w) < proxy_obj->cur.geometry.w)))
      {
-        if (!obj->cur.cache.clip.visible) return;
-        if ((obj->cur.cache.clip.a == 0) &&
-            (obj->cur.render_op == EVAS_RENDER_BLEND)) return;
+        size->w = source->cur.geometry.w;
+        offset->x = -source->cur.geometry.x;
+        *src_cut_w = EINA_FALSE;
      }
-   if ((obj->func->is_visible) && (!obj->func->is_visible(obj))) return;
-   
-   if (!obj->pre_render_done)
-      obj->func->render_pre(obj);
-   ctx = e->engine.func->context_new(output);
-   if (obj->smart.smart)
+   //Need to draw only a part of the source.
+   else
      {
-        EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
-          {
-             _proxy_subrender_recurse(obj2, clip, output, surface, ctx, x, y);
-          }
+        offset->x = -(source->cur.geometry.x -
+                      ((double) o->cur.fill.x * scale_x));
+        *src_cut_w = EINA_TRUE;
+     }
+   //Need to draw whole area of the source.
+   /* Tizen Only: Since Proxy has the texture size limitation problem,
+      we set a key value for entry magnifier so that evas does some hackish way.
+      This hackish code should be removed once evas supports a mechanism like a
+      virtual texture. */
+   /* if ((o->cur.fill.y > 0) ||
+        ((o->cur.fill.y + o->cur.fill.h) < proxy_obj->cur.geometry.h)) */
+   if (!evas_object_data_get(proxy_obj, "tizenonly") &&
+       ((o->cur.fill.y > 0) ||
+         ((o->cur.fill.y + o->cur.fill.h) < proxy_obj->cur.geometry.h)))
+     {
+        size->h = source->cur.geometry.h;
+        offset->y = -source->cur.geometry.y;
+        *src_cut_h = EINA_FALSE;
      }
+   //Need to draw only a part of the source.
    else
      {
-        obj->func->render(obj, output, ctx, surface, x, y);
+        offset->y = -(source->cur.geometry.y -
+                      ((double) o->cur.fill.y * scale_y));
+        *src_cut_h = EINA_TRUE;
      }
-   e->engine.func->context_free(output, ctx);
 }
-*/
 
 /**
  * Render the source object when a proxy is set.
@@ -2331,242 +2441,84 @@ _proxy_subrender_recurse(Evas_Object *obj, Evas_Object *clip, void *output, void
  * Used to force a draw if necessary, else just makes sures it's available.
  */
 static void
-_proxy_subrender(Evas *e, Evas_Object *source)
+_proxy_subrender(Evas *e, Evas_Object *source, Evas_Object *proxy)
 {
    void *ctx;
-/*   Evas_Object *obj2, *clip;*/
    int w, h;
+   Evas_Object_Image *o;
+   Evas_Coord_Point offset;
+   Evas_Coord_Size size;
+   Eina_Bool src_cut_w, src_cut_h;
 
    if (!source) return;
 
+   o = proxy->object_data;
+   _proxy_area_get(proxy, o, source, &offset, &size, &src_cut_w, &src_cut_h);
+   o->cur.src_cut_w = src_cut_w;
+   o->cur.src_cut_h = src_cut_h;
+
    w = source->cur.geometry.w;
    h = source->cur.geometry.h;
 
    source->proxy.redraw = EINA_FALSE;
 
    /* We need to redraw surface then */
-   if ((source->proxy.surface) && 
-       ((source->proxy.w != w) || (source->proxy.h != h)))
+   if ((source->proxy.surface) &&
+       ((source->proxy.w != size.w) || (source->proxy.h != size.h)))
      {
         e->engine.func->image_map_surface_free(e->engine.data.output,
                                                source->proxy.surface);
         source->proxy.surface = NULL;
      }
-   
+
    /* FIXME: Hardcoded alpha 'on' */
    /* FIXME (cont): Should see if the object has alpha */
    if (!source->proxy.surface)
      {
         source->proxy.surface = e->engine.func->image_map_surface_new
-           (e->engine.data.output, w, h, 1);
-        source->proxy.w = w;
-        source->proxy.h = h;
+           (e->engine.data.output, size.w, size.h, 1);
+        source->proxy.w = size.w;
+        source->proxy.h = size.h;
      }
 
+   if (!source->proxy.surface) return;
+
    ctx = e->engine.func->context_new(e->engine.data.output);
-   e->engine.func->context_color_set(e->engine.data.output, ctx, 0, 0, 0, 0);
-   e->engine.func->context_render_op_set(e->engine.data.output, ctx, EVAS_RENDER_COPY);
+   e->engine.func->context_color_set(e->engine.data.output, ctx, 0, 0, 0,
+                                     0);
+   e->engine.func->context_render_op_set(e->engine.data.output, ctx,
+                                         EVAS_RENDER_COPY);
    e->engine.func->rectangle_draw(e->engine.data.output, ctx,
-                                  source->proxy.surface, 0, 0, w, h);
-   e->engine.func->context_free(e->engine.data.output, ctx);
-   
-   ctx = e->engine.func->context_new(e->engine.data.output);
-   evas_render_mapped(e, source, ctx, source->proxy.surface,
-                      -source->cur.geometry.x,
-                      -source->cur.geometry.y,
-                      1, 0, 0, e->output.w, e->output.h);
+                                  source->proxy.surface, 0, 0, size.w, size.h);
    e->engine.func->context_free(e->engine.data.output, ctx);
-   source->proxy.surface = e->engine.func->image_dirty_region
-      (e->engine.data.output, source->proxy.surface, 0, 0, w, h);
-/*   
+
    ctx = e->engine.func->context_new(e->engine.data.output);
-   if (source->smart.smart)
-     {
-        clip = evas_object_smart_clipped_clipper_get(source);
-        EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(source), obj2)
-          {
-             _proxy_subrender_recurse(obj2, clip, e->engine.data.output,
-                                      source->proxy.surface,
-                                      ctx,
-                                      -source->cur.geometry.x,
-                                      -source->cur.geometry.y);
-          }
-     }
-   else
-     {
-        if (!source->pre_render_done)
-           source->func->render_pre(source);
-        source->func->render(source, e->engine.data.output, ctx,
-                             source->proxy.surface,
-                             -source->cur.geometry.x,
-                             -source->cur.geometry.y);
-     }
-   
-   e->engine.func->context_free(e->engine.data.output, ctx);
-   source->proxy.surface = e->engine.func->image_dirty_region
-      (e->engine.data.output, source->proxy.surface, 0, 0, w, h);
- */
-}
 
-#if 0 // filtering disabled
-/*
- *
- * Note that this is similar to proxy_subrender_recurse.  It should be
- * possible to merge I guess
- */
-static void
-image_filter_draw_under_recurse(Evas *e, Evas_Object *obj, Evas_Object *stop,
-                                void *output, void *ctx, void *surface,
-                                int x, int y)
-{
-   Evas_Object *obj2;
-   
-   if (obj->clip.clipees) return;
-   /* FIXME: Doing bounding box test */
-   if (!evas_object_is_in_output_rect(obj, stop->cur.geometry.x,
-                                      stop->cur.geometry.y,
-                                      stop->cur.geometry.w,
-                                      stop->cur.geometry.h))
-      return;
-   
-   if (!evas_object_is_visible(obj)) return;
-   obj->pre_render_done = 1;
-   ctx = e->engine.func->context_new(output);
-   
-   if (obj->smart.smart)
-     {
-        EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
-          {
-             if (obj2 == stop) return;
-             image_filter_draw_under_recurse(e, obj2, stop, output, surface, 
-                                             ctx, x, y);
-          }
-     }
-   else
-      obj->func->render(obj, output, ctx, surface, x ,y);
-   e->engine.func->context_free(output, ctx);
-}
+   Eina_Bool source_clip = evas_object_image_source_clip_get(proxy);
 
-/*
- * Draw all visible objects intersecting an object which are _beneath_ it.
- */
-static void
-image_filter_draw_under(Evas *e, Evas_Object *stop, void *output, void *ctx, void *surface, int dx, int dy)
-{
-   Evas_Layer *lay;
-   int x, y;
-   
-   x = stop->cur.geometry.x - dx;
-   y = stop->cur.geometry.y - dy;
-   
-   EINA_INLIST_FOREACH(e->layers, lay)
-     {
-        Evas_Object *obj;
-        EINA_INLIST_FOREACH(lay->objects, obj)
-          {
-             if (obj->delete_me) continue;
-             if (obj == stop) return;
-             /* FIXME: Do bounding box check */
-             image_filter_draw_under_recurse(e, obj, stop, output, ctx, 
-                                             surface, -x, -y);
-          }
-     }
-   e->engine.func->image_dirty_region(output, surface, 0, 0, 300, 300);
-   e->engine.func->output_flush(output);
-}
+   Evas_Proxy_Render_Data proxy_render_data = {
+        .proxy_obj = proxy,
+        .src_obj = source,
+        .source_clip = source_clip
+   };
 
-/*
- * Update the filtered object.
- *
- * Creates a new context, and renders stuff (filtered) onto that.
- */
-Filtered_Image *
-image_filter_update(Evas *e, Evas_Object *obj, void *src, int imagew, int imageh, int *outw, int *outh)
-{
-   int w, h;
-   void *ctx;
-   Evas_Filter_Info *info;
-   void *surface;
-   Eina_Bool alpha;
-   
-   info = obj->filter;
-   
-   if (info->mode == EVAS_FILTER_MODE_BELOW)
-     {
-        w = obj->cur.geometry.w;
-        h = obj->cur.geometry.h;
-        evas_filter_get_size(info, w, h, &imagew, &imageh, EINA_TRUE);
-        alpha = EINA_FALSE;
-     }
-   else
-     {
-        evas_filter_get_size(info, imagew, imageh, &w, &h, EINA_FALSE);
-        alpha = e->engine.func->image_alpha_get(e->engine.data.output, src);
-     }
-   
-   /* Certain filters may make alpha images anyway */
-   if (alpha == EINA_FALSE) alpha = evas_filter_always_alpha(info);
-   
-   surface = e->engine.func->image_map_surface_new(e->engine.data.output, w, h,
-                                                   alpha);
-   
-   if (info->mode == EVAS_FILTER_MODE_BELOW)
-     {
-        void *subsurface;
-        int disw, dish;
-        int dx, dy;
-        disw = obj->cur.geometry.w;
-        dish = obj->cur.geometry.h;
-        dx = (imagew - w) >> 1;
-        dy = (imageh - h) >> 1;
-        subsurface = e->engine.func->image_map_surface_new
-           (e->engine.data.output, imagew, imageh, 1);
-        ctx = e->engine.func->context_new(e->engine.data.output);
-        e->engine.func->context_color_set(e->engine.data.output, ctx, 0, 255, 0, 255);
-        e->engine.func->context_render_op_set(e->engine.data.output, ctx, EVAS_RENDER_COPY);
-        e->engine.func->rectangle_draw(e->engine.data.output, ctx,
-                                       subsurface, 0, 0, imagew, imageh);
-        
-        image_filter_draw_under(e, obj, e->engine.data.output, ctx,
-                                subsurface, dx, dy);
-        
-        e->engine.func->context_free(e->engine.data.output, ctx);
-        
-        ctx = e->engine.func->context_new(e->engine.data.output);
-        
-        e->engine.func->image_draw_filtered(e->engine.data.output,
-                                            ctx, surface, subsurface, info);
-        
-        e->engine.func->context_free(e->engine.data.output, ctx);
-        
-        e->engine.func->image_map_surface_free(e->engine.data.output,
-                                               subsurface);
-     }
-   else
-     {
-        ctx = e->engine.func->context_new(e->engine.data.output);
-        e->engine.func->image_draw_filtered(e->engine.data.output,
-                                            ctx, surface, src, info);
-        e->engine.func->context_free(e->engine.data.output, ctx);
-     }
-   
-   e->engine.func->image_dirty_region(e->engine.data.output, surface, 
-                                      0, 0, w, h);
-   if (outw) *outw = w;
-   if (outh) *outh = h;
-   return e->engine.func->image_filtered_save(src, surface,
-                                              obj->filter->key,
-                                              obj->filter->len);
+   evas_render_mapped(e, source, ctx, source->proxy.surface, offset.x, offset.y,
+                      1, 0, 0, e->output.w, e->output.h, &proxy_render_data, 1,
+                      EINA_TRUE);
+   e->engine.func->context_free(e->engine.data.output, ctx);
+
+   source->proxy.surface = e->engine.func->image_dirty_region
+      (e->engine.data.output, source->proxy.surface, 0, 0, size.w, size.h);
 }
-#endif
 
 static void
 evas_object_image_unload(Evas_Object *obj, Eina_Bool dirty)
 {
    Evas_Object_Image *o;
-   
+   Eina_Bool resize_call = EINA_FALSE;
+
    o = (Evas_Object_Image *)(obj->object_data);
-   
+
    if ((!o->cur.file) ||
        (o->pixels_checked_out > 0)) return;
    if (dirty)
@@ -2582,7 +2534,7 @@ evas_object_image_unload(Evas_Object *obj, Eina_Bool dirty)
      {
         if (o->preloading)
           {
-             o->preloading = 0;
+             o->preloading = EINA_FALSE;
              obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
                                                                       o->engine_data,
                                                                       obj);
@@ -2594,9 +2546,11 @@ evas_object_image_unload(Evas_Object *obj, Eina_Bool dirty)
    o->load_error = EVAS_LOAD_ERROR_NONE;
    o->cur.has_alpha = 1;
    o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
+   if ((o->cur.image.w != 0) || (o->cur.image.h != 0)) resize_call = EINA_TRUE;
    o->cur.image.w = 0;
    o->cur.image.h = 0;
    o->cur.image.stride = 0;
+   if (resize_call) evas_object_inform_call_image_resize(obj);
 }
 
 static void
@@ -2625,74 +2579,95 @@ evas_object_image_load(Evas_Object *obj)
           &lo);
    if (o->engine_data)
      {
-       int w, h;
-       int stride = 0;
+        int w, h;
+        int stride = 0;
+        Eina_Bool resize_call = EINA_FALSE;
 
-       obj->layer->evas->engine.func->image_size_get
-           (obj->layer->evas->engine.data.output,
-               o->engine_data, &w, &h);
-       if (obj->layer->evas->engine.func->image_stride_get)
-         obj->layer->evas->engine.func->image_stride_get
+        obj->layer->evas->engine.func->image_size_get
            (obj->layer->evas->engine.data.output,
-               o->engine_data, &stride);
-       else
-         stride = w * 4;
-       o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get
+            o->engine_data, &w, &h);
+        if (obj->layer->evas->engine.func->image_stride_get)
+          obj->layer->evas->engine.func->image_stride_get
+             (obj->layer->evas->engine.data.output,
+              o->engine_data, &stride);
+        else
+          stride = w * 4;
+        o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get
            (obj->layer->evas->engine.data.output,
-               o->engine_data);
-       o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get
+            o->engine_data);
+        o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get
            (obj->layer->evas->engine.data.output,
-               o->engine_data);
-       o->cur.image.w = w;
-       o->cur.image.h = h;
-       o->cur.image.stride = stride;
+            o->engine_data);
+        if ((o->cur.image.w != w) || (o->cur.image.h != h))
+          resize_call = EINA_TRUE;
+        o->cur.image.w = w;
+        o->cur.image.h = h;
+        o->cur.image.stride = stride;
+        if (resize_call) evas_object_inform_call_image_resize(obj);
      }
    else
      {
-       o->load_error = EVAS_LOAD_ERROR_GENERIC;
+        o->load_error = EVAS_LOAD_ERROR_GENERIC;
      }
 }
 
 static Evas_Coord
-evas_object_image_figure_x_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret)
+evas_object_image_figure_x_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Eina_Bool src_cut, Evas_Coord *size_ret)
 {
    Evas_Coord w;
 
    w = ((size * obj->layer->evas->output.w) /
-       (Evas_Coord)obj->layer->evas->viewport.w);
+        (Evas_Coord)obj->layer->evas->viewport.w);
    if (size <= 0) size = 1;
+
+   /* Proxy has the surface that's filled with the filled area.
+      So it doesn't need to figure out the filled area again */
+   if (src_cut)
+     {
+        start = 0;
+        size = obj->cur.geometry.w;
+     }
+
    if (start > 0)
      {
-       while (start - size > 0) start -= size;
+        while (start - size > 0) start -= size;
      }
    else if (start < 0)
      {
-       while (start < 0) start += size;
+        while (start < 0) start += size;
      }
    start = ((start * obj->layer->evas->output.w) /
-           (Evas_Coord)obj->layer->evas->viewport.w);
+            (Evas_Coord)obj->layer->evas->viewport.w);
    *size_ret = w;
    return start;
 }
 
 static Evas_Coord
-evas_object_image_figure_y_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Evas_Coord *size_ret)
+evas_object_image_figure_y_fill(Evas_Object *obj, Evas_Coord start, Evas_Coord size, Eina_Bool src_cut, Evas_Coord *size_ret)
 {
    Evas_Coord h;
 
    h = ((size * obj->layer->evas->output.h) /
-       (Evas_Coord)obj->layer->evas->viewport.h);
+        (Evas_Coord)obj->layer->evas->viewport.h);
    if (size <= 0) size = 1;
+
+   /* Proxy has the surface that's filled with the filled area.
+      So it doesn't need to figure out the filled area again */
+   if (src_cut)
+     {
+        start = 0;
+        size = obj->cur.geometry.h;
+     }
    if (start > 0)
      {
-       while (start - size > 0) start -= size;
+        while (start - size > 0) start -= size;
      }
    else if (start < 0)
      {
-       while (start < 0) start += size;
+        while (start < 0) start += size;
      }
    start = ((start * obj->layer->evas->output.h) /
-           (Evas_Coord)obj->layer->evas->viewport.h);
+            (Evas_Coord)obj->layer->evas->viewport.h);
    *size_ret = h;
    return start;
 }
@@ -2741,8 +2716,11 @@ evas_object_image_new(void)
    o->cur.spread = EVAS_TEXTURE_REPEAT;
    o->cur.opaque_valid = 0;
    o->cur.source = NULL;
+   o->cur.src_cut_w = EINA_FALSE;
+   o->cur.src_cut_h = EINA_FALSE;
    o->prev = o->cur;
    o->tmpf_fd = -1;
+   o->proxy_src_clip = EINA_TRUE;
    return o;
 }
 
@@ -2766,7 +2744,7 @@ evas_object_image_free(Evas_Object *obj)
      {
         if (o->preloading)
           {
-             o->preloading = 0;
+             o->preloading = EINA_FALSE;
              obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
                                                                       o->engine_data,
                                                                       obj);
@@ -2776,8 +2754,8 @@ evas_object_image_free(Evas_Object *obj)
      }
    if (o->video_surface)
      {
-        o->video_surface = 0;
-       obj->layer->evas->video_objects = eina_list_remove(obj->layer->evas->video_objects, obj);
+        o->video_surface = EINA_FALSE;
+        obj->layer->evas->video_objects = eina_list_remove(obj->layer->evas->video_objects, obj);
      }
    o->engine_data = NULL;
    o->magic = 0;
@@ -2806,6 +2784,13 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
         return;
      }
 
+   /* Mask sanity */
+   if (obj->mask.is_mask && (surface != obj->mask.surface))
+     {
+        ERR("Drawing a mask to another surface? Something's wrong...");
+        return;
+     }
+
    /* We are displaying the overlay */
    if (o->video_visible)
      {
@@ -2829,27 +2814,27 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
      }
 
    obj->layer->evas->engine.func->context_color_set(output,
-                                                   context,
-                                                   255, 255, 255, 255);
+                                                    context,
+                                                    255, 255, 255, 255);
 
    if ((obj->cur.cache.clip.r == 255) &&
        (obj->cur.cache.clip.g == 255) &&
        (obj->cur.cache.clip.b == 255) &&
        (obj->cur.cache.clip.a == 255))
      {
-       obj->layer->evas->engine.func->context_multiplier_unset(output,
-                                                               context);
+        obj->layer->evas->engine.func->context_multiplier_unset(output,
+                                                                context);
      }
    else
      obj->layer->evas->engine.func->context_multiplier_set(output,
-                                                          context,
-                                                          obj->cur.cache.clip.r,
-                                                          obj->cur.cache.clip.g,
-                                                          obj->cur.cache.clip.b,
-                                                          obj->cur.cache.clip.a);
+                                                           context,
+                                                           obj->cur.cache.clip.r,
+                                                           obj->cur.cache.clip.g,
+                                                           obj->cur.cache.clip.b,
+                                                           obj->cur.cache.clip.a);
 
    obj->layer->evas->engine.func->context_render_op_set(output, context,
-                                                       obj->cur.render_op);
+                                                        obj->cur.render_op);
 
    if (!o->cur.source)
      {
@@ -2880,112 +2865,233 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
      }
    else
      {
-        o->proxyrendering = 1;
-        _proxy_subrender(obj->layer->evas, o->cur.source);
+        o->proxyrendering = EINA_TRUE;
+        _proxy_subrender(obj->layer->evas, o->cur.source, obj);
         pixels = o->cur.source->proxy.surface;
         imagew = o->cur.source->proxy.w;
         imageh = o->cur.source->proxy.h;
         uvw = imagew;
         uvh = imageh;
-        o->proxyrendering = 0;
+        o->proxyrendering = EINA_FALSE;
      }
 
-#if 0 // filtering disabled
-   /* Now check/update filter */
-   if (obj->filter && obj->filter->filter)
+   ///Jiyoun: This code will be modified after opensource fix lockup issue
+   evas_object_inform_call_render_pre(obj);
+
+   // Clear out the pixel get stuff..
+   if (obj->layer->evas->engine.func->gl_get_pixels_set)
      {
-        Filtered_Image *fi = NULL;
-        //printf("%p has filter: %s\n", obj,obj->filter->dirty?"dirty":"clean");
-        if (obj->filter->dirty)
+        obj->layer->evas->engine.func->gl_get_pixels_set(output, NULL, NULL, NULL);
+     }
+   if (obj->layer->evas->engine.func->image_direct_set)
+     {
+        obj->layer->evas->engine.func->image_direct_set(output, o->engine_data, EINA_FALSE);
+     }
+
+   if (pixels)
+     {
+        Evas_Coord idw, idh, idx, idy;
+        int ix, iy, iw, ih;
+        //int direct_render = 0;
+        Eina_Bool direct_override = 0;
+        int direct_force_off = 0;
+
+        if (o->dirty_pixels)
           {
-             if (obj->filter->mode != EVAS_FILTER_MODE_BELOW)
+             if (o->func.get_pixels)
                {
-                  uint32_t len;
-                  uint8_t *key;
-                  
-                  if (obj->filter->key) free(obj->filter->key);
-                  obj->filter->key = NULL;
-                  obj->filter->len = 0;
-                  key = evas_filter_key_get(obj->filter, &len);
-                  if (key)
+                  if (obj->layer->evas->engine.func->image_native_get)
                     {
-                       obj->filter->key = key;
-                       obj->filter->len = len;
-                       fi = obj->layer->evas->engine.func->image_filtered_get
-                          (o->engine_data, key, len);
-                       if (obj->filter->cached && fi != obj->filter->cached)
+                       Evas_Native_Surface *ns;
+
+                       ns = obj->layer->evas->engine.func->image_native_get(obj->layer->evas->engine.data.output, o->engine_data);
+                       if (ns)
                          {
-                            obj->layer->evas->engine.func->image_filtered_free
-                               (o->engine_data, obj->filter->cached);
-                            obj->filter->cached = NULL;
+                            Eina_Bool direct_renderable = EINA_FALSE;
+
+                            // Check if we can do direct rendering...
+                            if (obj->layer->evas->engine.func->gl_direct_override_get)
+                              obj->layer->evas->engine.func->gl_direct_override_get(output, NULL /*&direct_override*/, &direct_force_off);
+
+                            if (obj->layer->evas->engine.func->gl_surface_direct_renderable_get)
+                              direct_renderable = obj->layer->evas->engine.func->gl_surface_direct_renderable_get(output, ns, &direct_override);
+
+                            if ( (((direct_renderable) &&
+                                   (obj->cur.geometry.w == o->cur.image.w) &&
+                                   (obj->cur.geometry.h == o->cur.image.h) &&
+                                   (obj->cur.color.r == 255) &&
+                                   (obj->cur.color.g == 255) &&
+                                   (obj->cur.color.b == 255) &&
+                                   (obj->cur.color.a == 255) &&
+                                   (!obj->cur.map)
+                                   /* Note: disabled alpha test as we override glClear()
+                                    * &&(!o->cur.has_alpha)
+                                    */) ||
+                                  (direct_override)) &&
+                                 (!direct_force_off) )
+                              {
+
+                                 if (obj->layer->evas->engine.func->gl_get_pixels_set)
+                                   obj->layer->evas->engine.func->gl_get_pixels_set(output, o->func.get_pixels, o->func.get_pixels_data, obj);
+                                 if (obj->layer->evas->engine.func->image_direct_set)
+                                   obj->layer->evas->engine.func->image_direct_set(output, o->engine_data, EINA_TRUE);
+
+                                 o->direct_render = EINA_TRUE;
+                              }
+                            else
+                              o->direct_render = EINA_FALSE;
+                         }
+
+                       if ( (ns) &&
+                            ((ns->type == EVAS_NATIVE_SURFACE_X11) ||
+                            (ns->type == EVAS_NATIVE_SURFACE_TIZEN)))
+                         {
+                            if (obj->layer->evas->engine.func->context_flush)
+                               obj->layer->evas->engine.func->context_flush(output);
                          }
                     }
+
+                  if (!o->direct_render)
+                    {
+                       o->func.get_pixels(o->func.get_pixels_data, obj);
+                       if (obj->layer->evas->engine.func->get_pixels_render_post)
+                          obj->layer->evas->engine.func->get_pixels_render_post(obj->layer->evas->engine.data.output);
+                    }
+
+                  if (o->engine_data != pixels)
+                     pixels = o->engine_data;
+                  o->engine_data = obj->layer->evas->engine.func->image_dirty_region
+                     (obj->layer->evas->engine.data.output, o->engine_data,
+                      0, 0, o->cur.image.w, o->cur.image.h);
                }
-             else if (obj->filter->cached)
-               {
-                  obj->layer->evas->engine.func->image_filtered_free
-                     (o->engine_data, obj->filter->cached);
-               }
-             if (!fi)
-                fi = image_filter_update(obj->layer->evas, obj, pixels, 
-                                         imagew, imageh, &imagew, &imageh);
-             pixels = fi->image;
-             obj->filter->dirty = 0;
-             obj->filter->cached = fi;
+             o->dirty_pixels = EINA_FALSE;
           }
         else
           {
-             fi = obj->filter->cached;
-             pixels = fi->image;
-          }
-     }
-#endif
-   
-   if (pixels)
-     {
-       Evas_Coord idw, idh, idx, idy;
-       int ix, iy, iw, ih;
-        int img_set = 0;
-
-       if (o->dirty_pixels)
-         {
-            if (o->func.get_pixels)
-              {
-                  // Set img object for direct rendering optimization
-                  // Check for image w/h against image geometry w/h
-                  // Check for image color r,g,b,a = {255,255,255,255}
-                  // Check and make sure that there are no maps.
-                  if ( (obj->cur.geometry.w == o->cur.image.w) &&
-                       (obj->cur.geometry.h == o->cur.image.h) &&
-                       (obj->cur.color.r == 255) &&
-                       (obj->cur.color.g == 255) &&
-                       (obj->cur.color.b == 255) &&
-                       (obj->cur.color.a == 255) &&
-                       (!obj->cur.map) )
+             // Check if the it's not dirty but it has direct rendering
+             if (o->direct_render)
+               {
+                  Evas_Native_Surface *ns;
+                  if (obj->layer->evas->engine.func->image_native_get)
                     {
-                       if (obj->layer->evas->engine.func->gl_img_obj_set)
+                       ns = obj->layer->evas->engine.func->image_native_get(obj->layer->evas->engine.data.output, o->engine_data);
+
+                       if (obj->layer->evas->engine.func->gl_direct_override_get)
+                         obj->layer->evas->engine.func->gl_direct_override_get(output, NULL /*&direct_override*/, &direct_force_off);
+                       if (obj->layer->evas->engine.func->gl_surface_direct_renderable_get)
+                         obj->layer->evas->engine.func->gl_surface_direct_renderable_get(output, ns, &direct_override);
+
+                       if (direct_override && !direct_force_off) //Always render directly such as webkit.
                          {
-                            obj->layer->evas->engine.func->gl_img_obj_set(output, obj, o->cur.has_alpha);
-                            img_set = 1;
+                            if (obj->layer->evas->engine.func->gl_get_pixels_set)
+                              obj->layer->evas->engine.func->gl_get_pixels_set(output, o->func.get_pixels, o->func.get_pixels_data, obj);
+                            if (obj->layer->evas->engine.func->image_direct_set)
+                              obj->layer->evas->engine.func->image_direct_set(output, o->engine_data, EINA_TRUE);
+                         }
+                       else //normal
+                         {
+                            o->func.get_pixels(o->func.get_pixels_data, obj);
+                            if (obj->layer->evas->engine.func->get_pixels_render_post)
+                              obj->layer->evas->engine.func->get_pixels_render_post(obj->layer->evas->engine.data.output);
+                            o->direct_render = EINA_FALSE;
                          }
                     }
+               }
+
+          }
 
-                 o->func.get_pixels(o->func.get_pixels_data, obj);
-                 if (o->engine_data != pixels)
-                   pixels = o->engine_data;
-                 o->engine_data = obj->layer->evas->engine.func->image_dirty_region
-                     (obj->layer->evas->engine.data.output, o->engine_data,
-                         0, 0, o->cur.image.w, o->cur.image.h);
-              }
-            o->dirty_pixels = 0;
-         }
         if ((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap))
           {
              evas_object_map_update(obj, x, y, imagew, imageh, uvw, uvh);
 
              obj->layer->evas->engine.func->image_map_draw
-               (output, context, surface, pixels, obj->spans,
-               o->cur.smooth_scale | obj->cur.map->smooth, 0);
+                (output, context, surface, pixels, obj->spans,
+                 o->cur.smooth_scale | obj->cur.map->smooth, 0);
+          }
+        else if (o->native_video)
+          {
+             // for native surface video rendering
+             Evas_Native_Surface *ns;
+             ns = obj->layer->evas->engine.func->image_native_get(obj->layer->evas->engine.data.output, o->engine_data);
+             if ( (ns) &&
+                  (ns->type == EVAS_NATIVE_SURFACE_TIZEN) )
+               {
+                  float ratio = ns->data.tizen.ratio;
+                  if (ratio > 0.01f)
+                    {
+                       // we need to draw a black rectangle underneath the video
+                       // since image dimensions will be different from object dimensions in case of letterbox mode
+                       obj->layer->evas->engine.func->context_color_set(output,
+                                                                        context,
+                                                                        0, 0, 0, 255);
+                       obj->layer->evas->engine.func->context_render_op_set(output, context,
+                                                                  EVAS_RENDER_COPY);
+                       obj->layer->evas->engine.func->rectangle_draw(output,
+                                                                     context,
+                                                                     surface,
+                                                                     obj->cur.geometry.x + x,
+                                                                     obj->cur.geometry.y + y,
+                                                                     obj->cur.geometry.w,
+                                                                     obj->cur.geometry.h);
+                       obj->layer->evas->engine.func->context_render_op_set(output, context,
+                                                                  obj->cur.render_op);
+                       ix = iy = 0;
+                       if (ns->data.tizen.rot == 90 || ns->data.tizen.rot == 270)
+                         {
+                            if (o->cur.fill.w * ratio < o->cur.fill.h)
+                              iy = (double)(o->cur.fill.h - (double)(o->cur.fill.w * ratio)) * 0.5f;
+                            else if (o->cur.fill.w * ratio > o->cur.fill.h)
+                              ix = (double)(o->cur.fill.w - (double)(o->cur.fill.h / ratio)) * 0.5f;
+                         }
+                       else
+                         {
+                            if (o->cur.fill.w < o->cur.fill.h * ratio)
+                              iy = (double)(o->cur.fill.h - (double)(o->cur.fill.w / ratio)) * 0.5f;
+                            else if (o->cur.fill.w > o->cur.fill.h * ratio)
+                              ix = (double)(o->cur.fill.w - (double)(o->cur.fill.h * ratio)) * 0.5f;
+                         }
+
+                       obj->layer->evas->engine.func->image_draw(output,
+                                                            context,
+                                                            surface,
+                                                            pixels,
+                                                            0, 0,
+                                                            imagew,
+                                                            imageh,
+                                                            obj->cur.geometry.x + o->cur.fill.x + ix,
+                                                            obj->cur.geometry.y + o->cur.fill.y + iy,
+                                                            o->cur.fill.w - ix * 2,
+                                                            o->cur.fill.h - iy * 2,
+                                                            o->cur.smooth_scale);
+                    }
+                  else if ((obj->cur.geometry.w > o->cur.fill.w) ||
+                           (obj->cur.geometry.h > o->cur.fill.h))
+                    obj->layer->evas->engine.func->image_draw(output,
+                                                              context,
+                                                              surface,
+                                                              pixels,
+                                                              0, 0,
+                                                              imagew,
+                                                              imageh,
+                                                              o->cur.fill.x + (o->cur.fill.w - imagew) / 2,
+                                                              o->cur.fill.y + (o->cur.fill.h - imageh) / 2,
+                                                              imagew,
+                                                              imageh,
+                                                              o->cur.smooth_scale);
+                  else
+                    obj->layer->evas->engine.func->image_draw(output,
+                                                              context,
+                                                              surface,
+                                                              pixels,
+                                                              0, 0,
+                                                              imagew,
+                                                              imageh,
+                                                              obj->cur.geometry.x + o->cur.fill.x,
+                                                              obj->cur.geometry.y + o->cur.fill.y,
+                                                              o->cur.fill.w,
+                                                              o->cur.fill.h,
+                                                              o->cur.smooth_scale);
+              }
           }
         else
           {
@@ -2996,10 +3102,18 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
               * (which is returned)it may be a new object, however exactly 0
               * of all the evas engines do this. */
              obj->layer->evas->engine.func->image_border_set(output, pixels,
-                                                             o->cur.border.l, o->cur.border.r,
-                                                             o->cur.border.t, o->cur.border.b);
-             idx = evas_object_image_figure_x_fill(obj, o->cur.fill.x, o->cur.fill.w, &idw);
-             idy = evas_object_image_figure_y_fill(obj, o->cur.fill.y, o->cur.fill.h, &idh);
+                                                             o->cur.border.l,
+                                                             o->cur.border.r,
+                                                             o->cur.border.t,
+                                                             o->cur.border.b);
+             idx = evas_object_image_figure_x_fill(obj,
+                                                   o->cur.fill.x,
+                                                   o->cur.fill.w,
+                                                   o->cur.src_cut_w, &idw);
+             idy = evas_object_image_figure_y_fill(obj,
+                                                   o->cur.fill.y,
+                                                   o->cur.fill.h,
+                                                   o->cur.src_cut_h, &idh);
              if (idw < 1) idw = 1;
              if (idh < 1) idh = 1;
              if (idx > 0) idx -= idw;
@@ -3008,11 +3122,11 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
                {
                   Evas_Coord ydy;
                   int dobreak_w = 0;
-                  
+
                   ydy = idy;
                   ix = idx;
-                  if ((o->cur.fill.w == obj->cur.geometry.w) &&
-                      (o->cur.fill.x == 0))
+                  if (((o->cur.fill.w == obj->cur.geometry.w) &&
+                      (o->cur.fill.x == 0)) || o->cur.src_cut_w)
                     {
                        dobreak_w = 1;
                        iw = obj->cur.geometry.w;
@@ -3022,10 +3136,10 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
                   while ((int)idy < obj->cur.geometry.h)
                     {
                        int dobreak_h = 0;
-                       
+
                        iy = idy;
-                       if ((o->cur.fill.h == obj->cur.geometry.h) &&
-                           (o->cur.fill.y == 0))
+                       if (((o->cur.fill.h == obj->cur.geometry.h) &&
+                           (o->cur.fill.y == 0)) || o->cur.src_cut_h)
                          {
                             ih = obj->cur.geometry.h;
                             dobreak_h = 1;
@@ -3053,7 +3167,7 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
                             int inx, iny, inw, inh, outx, outy, outw, outh;
                             int bl, br, bt, bb, bsl, bsr, bst, bsb;
                             int imw, imh, ox, oy;
-                            
+
                             ox = obj->cur.geometry.x + ix + x;
                             oy = obj->cur.geometry.y + iy + y;
                             imw = imagew;
@@ -3062,25 +3176,22 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
                             br = o->cur.border.r;
                             bt = o->cur.border.t;
                             bb = o->cur.border.b;
-                            if ((bl + br) > iw)
-                              {
-                                 bl = iw / 2;
-                                 br = iw - bl;
-                              }
+                            // fix impossible border settings if img pixels not enough
                             if ((bl + br) > imw)
                               {
-                                 bl = imw / 2;
-                                 br = imw - bl;
-                              }
-                            if ((bt + bb) > ih)
-                              {
-                                 bt = ih / 2;
-                                 bb = ih - bt;
+                                 if ((bl + br) > 0)
+                                   {
+                                      bl = (bl * imw) / (bl + br);
+                                      br = imw - bl;
+                                   }
                               }
                             if ((bt + bb) > imh)
                               {
-                                 bt = imh / 2;
-                                 bb = imh - bt;
+                                 if ((bt + bb) > 0)
+                                   {
+                                      bt = (bt * imh) / (bt + bb);
+                                      bb = imh - bt;
+                                   }
                               }
                             if (o->cur.border.scale != 1.0)
                               {
@@ -3093,6 +3204,35 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
                               {
                                   bsl = bl; bsr = br; bst = bt; bsb = bb;
                               }
+                            // adjust output border rendering if it doesnt fit
+                            if ((bsl + bsr) > iw)
+                              {
+                                 int b0 = bsl, b1 = bsr;
+
+                                 if ((bsl + bsr) > 0)
+                                   {
+                                      bsl = (bsl * iw) / (bsl + bsr);
+                                      bsr = iw - bsl;
+                                   }
+                                 if (b0 > 0) bl = (bl * bsl) / b0;
+                                 else bl = 0;
+                                 if (b1 > 0) br = (br * bsr) / b1;
+                                 else br = 0;
+                              }
+                            if ((bst + bsb) > ih)
+                              {
+                                 int b0 = bst, b1 = bsb;
+
+                                 if ((bst + bsb) > 0)
+                                   {
+                                      bst = (bst * ih) / (bst + bsb);
+                                      bsb = ih - bst;
+                                   }
+                                 if (b0 > 0) bt = (bt * bst) / b0;
+                                 else bt = 0;
+                                 if (b1 > 0) bb = (bb * bsb) / b1;
+                                 else bb = 0;
+                              }
                             // #--
                             // |
                             inx = 0; iny = 0;
@@ -3131,6 +3271,7 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
                                  outw = iw - bsl - bsr; outh = ih - bst - bsb;
                                  if ((o->cur.border.fill == EVAS_BORDER_FILL_SOLID) &&
                                      (obj->cur.cache.clip.a == 255) &&
+                                     (!obj->clip.mask) &&
                                      (obj->cur.render_op == EVAS_RENDER_BLEND))
                                    {
                                       obj->layer->evas->engine.func->context_render_op_set(output, context,
@@ -3179,17 +3320,9 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
                   if (dobreak_w) break;
                }
           }
-
-        // Unset img object
-        if (img_set)
-          {
-             if (obj->layer->evas->engine.func->gl_img_obj_set)
-               {
-                  obj->layer->evas->engine.func->gl_img_obj_set(output, NULL, 0);
-                  img_set = 0;
-               }
-          }
      }
+   ///Jiyoun: This code will be modified after opensource fix lockup issue
+   evas_object_inform_call_render_post(obj);
 }
 
 static void
@@ -3214,18 +3347,18 @@ evas_object_image_render_pre(Evas_Object *obj)
      {
         ERR("%p has invalid fill size: %dx%d. Ignored",
             obj, o->cur.fill.w, o->cur.fill.h);
-       return;
+        return;
      }
 
    /* if someone is clipping this obj - go calculate the clipper */
    if (obj->cur.clipper)
      {
-       if (obj->cur.cache.clip.dirty)
-         evas_object_clip_recalc(obj->cur.clipper);
-       obj->cur.clipper->func->render_pre(obj->cur.clipper);
+        if (obj->cur.cache.clip.dirty)
+          evas_object_clip_recalc(obj->cur.clipper);
+        obj->cur.clipper->func->render_pre(obj->cur.clipper);
      }
    /* Proxy: Do it early */
-   if (o->cur.source && 
+   if (o->cur.source &&
        (o->cur.source->proxy.redraw || o->cur.source->changed))
      {
         /* XXX: Do I need to sort out the map here? */
@@ -3239,23 +3372,24 @@ evas_object_image_render_pre(Evas_Object *obj)
    was_v = evas_object_was_visible(obj);
    if (is_v != was_v)
      {
-       evas_object_render_pre_visible_change(&e->clip_changes, obj, is_v, was_v);
-       if (!o->pixel_updates) goto done;
+        evas_object_render_pre_visible_change(&e->clip_changes, obj, is_v, was_v);
+        if (!o->pixel_updates) goto done;
      }
    if (obj->changed_map)
      {
-       evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
+        evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
         goto done;
      }
    /* it's not visible - we accounted for it appearing or not so just abort */
    if (!is_v) goto done;
    /* clipper changed this is in addition to anything else for obj */
-   evas_object_render_pre_clipper_change(&e->clip_changes, obj);
+   if (was_v)
+     evas_object_render_pre_clipper_change(&e->clip_changes, obj);
    /* if we restacked (layer or just within a layer) and don't clip anyone */
    if (obj->restack)
      {
-       evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
-       if (!o->pixel_updates) goto done;
+        evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
+        if (!o->pixel_updates) goto done;
      }
    /* if it changed color */
    if ((obj->cur.color.r != obj->prev.color.r) ||
@@ -3263,62 +3397,62 @@ evas_object_image_render_pre(Evas_Object *obj)
        (obj->cur.color.b != obj->prev.color.b) ||
        (obj->cur.color.a != obj->prev.color.a))
      {
-       evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
-       if (!o->pixel_updates) goto done;
+        evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
+        if (!o->pixel_updates) goto done;
      }
    /* if it changed render op */
    if (obj->cur.render_op != obj->prev.render_op)
      {
-       evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
-       if (!o->pixel_updates) goto done;
+        evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
+        if (!o->pixel_updates) goto done;
      }
    /* if it changed anti_alias */
    if (obj->cur.anti_alias != obj->prev.anti_alias)
      {
-       evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
-       if (!o->pixel_updates) goto done;
+        evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
+        if (!o->pixel_updates) goto done;
      }
    if (o->changed)
      {
-       if (((o->cur.file) && (!o->prev.file)) ||
-           ((!o->cur.file) && (o->prev.file)) ||
-           ((o->cur.key) && (!o->prev.key)) ||
-           ((!o->cur.key) && (o->prev.key))
-           )
-         {
-            evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
-            if (!o->pixel_updates) goto done;
-         }
-       if ((o->cur.image.w != o->prev.image.w) ||
-           (o->cur.image.h != o->prev.image.h) ||
-           (o->cur.has_alpha != o->prev.has_alpha) ||
-           (o->cur.cspace != o->prev.cspace) ||
-           (o->cur.smooth_scale != o->prev.smooth_scale))
-         {
-            evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
-            if (!o->pixel_updates) goto done;
-         }
-       if ((o->cur.border.l != o->prev.border.l) ||
-           (o->cur.border.r != o->prev.border.r) ||
-           (o->cur.border.t != o->prev.border.t) ||
-           (o->cur.border.b != o->prev.border.b) ||
+        if (((o->cur.file) && (!o->prev.file)) ||
+            ((!o->cur.file) && (o->prev.file)) ||
+            ((o->cur.key) && (!o->prev.key)) ||
+            ((!o->cur.key) && (o->prev.key))
+           )
+          {
+             evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
+             if (!o->pixel_updates) goto done;
+          }
+        if ((o->cur.image.w != o->prev.image.w) ||
+            (o->cur.image.h != o->prev.image.h) ||
+            (o->cur.has_alpha != o->prev.has_alpha) ||
+            (o->cur.cspace != o->prev.cspace) ||
+            (o->cur.smooth_scale != o->prev.smooth_scale))
+          {
+             evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
+             if (!o->pixel_updates) goto done;
+          }
+        if ((o->cur.border.l != o->prev.border.l) ||
+            (o->cur.border.r != o->prev.border.r) ||
+            (o->cur.border.t != o->prev.border.t) ||
+            (o->cur.border.b != o->prev.border.b) ||
             (o->cur.border.fill != o->prev.border.fill) ||
             (o->cur.border.scale != o->prev.border.scale))
-         {
-            evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
-            if (!o->pixel_updates) goto done;
-         }
-       if (o->dirty_pixels)
-         {
-            evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
-            if (!o->pixel_updates) goto done;
-         }
-       if (o->cur.frame != o->prev.frame)
-         {
-            evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
-            if (!o->pixel_updates) goto done;
-         }
-       
+          {
+             evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
+             if (!o->pixel_updates) goto done;
+          }
+        if (o->dirty_pixels)
+          {
+             evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
+             if (!o->pixel_updates) goto done;
+          }
+        if (o->cur.frame != o->prev.frame)
+          {
+             evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
+             if (!o->pixel_updates) goto done;
+          }
+
      }
    /* if it changed geometry - and obviously not visibility or color */
    /* calculate differences since we have a constant color fill */
@@ -3346,26 +3480,26 @@ evas_object_image_render_pre(Evas_Object *obj)
                                           obj->prev.geometry.h);
        if (!o->pixel_updates) goto done;
      }
-#endif   
+#endif
    if (((obj->cur.geometry.x != obj->prev.geometry.x) ||
-       (obj->cur.geometry.y != obj->prev.geometry.y) ||
-       (obj->cur.geometry.w != obj->prev.geometry.w) ||
-       (obj->cur.geometry.h != obj->prev.geometry.h))
-       )
+        (obj->cur.geometry.y != obj->prev.geometry.y) ||
+        (obj->cur.geometry.w != obj->prev.geometry.w) ||
+        (obj->cur.geometry.h != obj->prev.geometry.h))
+      )
      {
-       evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
-       if (!o->pixel_updates) goto done;
+        evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
+        if (!o->pixel_updates) goto done;
      }
    if (o->changed)
      {
-       if ((o->cur.fill.x != o->prev.fill.x) ||
-           (o->cur.fill.y != o->prev.fill.y) ||
-           (o->cur.fill.w != o->prev.fill.w) ||
-           (o->cur.fill.h != o->prev.fill.h))
-         {
-            evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
-            if (!o->pixel_updates) goto done;
-         }
+        if ((o->cur.fill.x != o->prev.fill.x) ||
+            (o->cur.fill.y != o->prev.fill.y) ||
+            (o->cur.fill.w != o->prev.fill.w) ||
+            (o->cur.fill.h != o->prev.fill.h))
+          {
+             evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
+             if (!o->pixel_updates) goto done;
+          }
         if (o->pixel_updates)
           {
              if ((o->cur.border.l == 0) &&
@@ -3374,20 +3508,27 @@ evas_object_image_render_pre(Evas_Object *obj)
                  (o->cur.border.b == 0) &&
                  (o->cur.image.w > 0) &&
                  (o->cur.image.h > 0) &&
-                (!((obj->cur.map) && (obj->cur.usemap))))
+                 (!((obj->cur.map) && (obj->cur.usemap))))
                {
                   Eina_Rectangle *rr;
-                  
+
                   EINA_LIST_FREE(o->pixel_updates, rr)
                     {
                        Evas_Coord idw, idh, idx, idy;
                        int x, y, w, h;
-                       
+
                        e->engine.func->image_dirty_region(e->engine.data.output, o->engine_data, rr->x, rr->y, rr->w, rr->h);
-                       
-                       idx = evas_object_image_figure_x_fill(obj, o->cur.fill.x, o->cur.fill.w, &idw);
-                       idy = evas_object_image_figure_y_fill(obj, o->cur.fill.y, o->cur.fill.h, &idh);
-                       
+
+                       idx = evas_object_image_figure_x_fill(obj,
+                                                             o->cur.fill.x,
+                                                             o->cur.fill.w,
+                                                             o->cur.src_cut_w,
+                                                             &idw);
+                       idy = evas_object_image_figure_y_fill(obj,
+                                                             o->cur.fill.y,
+                                                             o->cur.fill.h,
+                                                             o->cur.src_cut_h,
+                                                             &idh);
                        if (idw < 1) idw = 1;
                        if (idh < 1) idh = 1;
                        if (idx > 0) idx -= idw;
@@ -3395,17 +3536,17 @@ evas_object_image_render_pre(Evas_Object *obj)
                        while (idx < obj->cur.geometry.w)
                          {
                             Evas_Coord ydy;
-                            
+
                             ydy = idy;
                             x = idx;
                             w = ((int)(idx + idw)) - x;
                             while (idy < obj->cur.geometry.h)
                               {
                                  Eina_Rectangle r;
-                                 
+
                                  y = idy;
                                  h = ((int)(idy + idh)) - y;
-                                 
+
                                  r.x = (rr->x * w) / o->cur.image.w;
                                  r.y = (rr->y * h) / o->cur.image.h;
                                  r.w = ((rr->w * w) + (o->cur.image.w * 2) - 1) / o->cur.image.w;
@@ -3427,22 +3568,16 @@ evas_object_image_render_pre(Evas_Object *obj)
                }
              else
                {
-                 Eina_Rectangle *r;
-                  
-                 EINA_LIST_FREE(o->pixel_updates, r)
+                  Eina_Rectangle *r;
+
+                  EINA_LIST_FREE(o->pixel_updates, r)
                      eina_rectangle_free(r);
-                 e->engine.func->image_dirty_region(e->engine.data.output, o->engine_data, 0, 0, o->cur.image.w, o->cur.image.h);
-                 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
-                 goto done;
-              }
-         }
-     }
-#if 0 // filtering disabled
-   if (obj->filter && obj->filter->dirty)
-     {
-        evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
+                  e->engine.func->image_dirty_region(e->engine.data.output, o->engine_data, 0, 0, o->cur.image.w, o->cur.image.h);
+                  evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
+                  goto done;
+               }
+          }
      }
-#endif   
    /* it obviously didn't change - add a NO obscure - this "unupdates"  this */
    /* area so if there were updates for it they get wiped. don't do it if we */
    /* aren't fully opaque and we are visible */
@@ -3450,7 +3585,7 @@ evas_object_image_render_pre(Evas_Object *obj)
        evas_object_is_opaque(obj))
      {
         Evas_Coord x, y, w, h;
-        
+
         x = obj->cur.cache.clip.x;
         y = obj->cur.cache.clip.y;
         w = obj->cur.cache.clip.w;
@@ -3487,7 +3622,7 @@ evas_object_image_render_post(Evas_Object *obj)
    /* move cur to prev safely for object data */
    evas_object_cur_prev(obj);
    o->prev = o->cur;
-   o->changed = 0;
+   o->changed = EINA_FALSE;
    /* FIXME: copy strings across */
 }
 
@@ -3562,7 +3697,7 @@ evas_object_image_is_opaque(Evas_Object *obj)
    if ((obj->cur.map) && (obj->cur.usemap))
      {
         Evas_Map *m = obj->cur.map;
-        
+
         if ((m->points[0].a == 255) &&
             (m->points[1].a == 255) &&
             (m->points[2].a == 255) &&
@@ -3630,149 +3765,330 @@ evas_object_image_was_opaque(Evas_Object *obj)
 }
 
 static int
-evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+evas_object_image_is_inside(Evas_Object *obj, Evas_Coord px, Evas_Coord py)
 {
    Evas_Object_Image *o;
-   DATA32 *data;
-   int w, h, stride, iw, ih;
-   int a;
-   int return_value;
+   int imagew, imageh, uvw, uvh;
+   void *pixels;
+   int is_inside = 0;
 
+   /* the following code is similar to evas_object_image_render(), but doesn't
+    * draw, just get the pixels so we can check the transparency.
+    */
    o = (Evas_Object_Image *)(obj->object_data);
-
-   x -= obj->cur.cache.clip.x;
-   y -= obj->cur.cache.clip.y;
-   w = obj->cur.cache.clip.w;
-   h = obj->cur.cache.clip.h;
-   iw = o->cur.image.w;
-   ih = o->cur.image.h;
-
-   if ((x < 0) || (y < 0) || (x >= w) || (y >= h)) return 0;
-   if (!o->cur.has_alpha) return 1;
-
-   // FIXME: proxy needs to be honored
-   if (obj->cur.map)
+   if (!o->cur.source)
+     {
+        pixels = o->engine_data;
+        imagew = o->cur.image.w;
+        imageh = o->cur.image.h;
+        uvw = imagew;
+        uvh = imageh;
+     }
+   else if (o->cur.source->proxy.surface && !o->cur.source->proxy.redraw)
+     {
+        pixels = o->cur.source->proxy.surface;
+        imagew = o->cur.source->proxy.w;
+        imageh = o->cur.source->proxy.h;
+        uvw = imagew;
+        uvh = imageh;
+     }
+   else if (o->cur.source->type == o_type &&
+            ((Evas_Object_Image *)o->cur.source->object_data)->engine_data)
      {
-        x = obj->cur.map->mx;
-        y = obj->cur.map->my;
+        Evas_Object_Image *oi;
+        oi = o->cur.source->object_data;
+        pixels = oi->engine_data;
+        imagew = oi->cur.image.w;
+        imageh = oi->cur.image.h;
+        uvw = o->cur.source->cur.geometry.w;
+        uvh = o->cur.source->cur.geometry.h;
      }
    else
      {
-        int bl, br, bt, bb, bsl, bsr, bst, bsb;
-        
-        bl = o->cur.border.l;
-        br = o->cur.border.r;
-        bt = o->cur.border.t;
-        bb = o->cur.border.b;
-        if ((bl + br) > iw)
-          {
-             bl = iw / 2;
-             br = iw - bl;
-          }
-        if ((bl + br) > iw)
-          {
-             bl = iw / 2;
-             br = iw - bl;
-          }
-        if ((bt + bb) > ih)
-          {
-             bt = ih / 2;
-             bb = ih - bt;
-          }
-        if ((bt + bb) > ih)
+        o->proxyrendering = EINA_TRUE;
+        _proxy_subrender(obj->layer->evas, o->cur.source, obj);
+        pixels = o->cur.source->proxy.surface;
+        imagew = o->cur.source->proxy.w;
+        imageh = o->cur.source->proxy.h;
+        uvw = imagew;
+        uvh = imageh;
+        o->proxyrendering = EINA_FALSE;
+     }
+
+   if (pixels)
+     {
+        Evas_Coord idw, idh, idx, idy;
+        int ix, iy, iw, ih;
+
+        /* TODO: not handling o->dirty_pixels && o->func.get_pixels,
+         * should we handle it now or believe they were done in the last render?
+         */
+        if (o->dirty_pixels)
           {
-             bt = ih / 2;
-             bb = ih - bt;
+             if (o->func.get_pixels)
+               {
+                  ERR("dirty_pixels && get_pixels not supported");
+               }
           }
-        if (o->cur.border.scale != 1.0)
+
+        /* TODO: not handling map, need to apply map to point */
+        if ((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap))
           {
-             bsl = ((double)bl * o->cur.border.scale);
-             bsr = ((double)br * o->cur.border.scale);
-             bst = ((double)bt * o->cur.border.scale);
-             bsb = ((double)bb * o->cur.border.scale);
+             evas_object_map_update(obj, 0, 0, imagew, imageh, uvw, uvh);
+
+             ERR("map not supported");
           }
         else
           {
-             bsl = bl; bsr = br; bst = bt; bsb = bb;
-          }
-        
-        w = o->cur.fill.w;
-        h = o->cur.fill.h;
-        x -= o->cur.fill.x;
-        y -= o->cur.fill.y;
-        x %= w;
-        y %= h;
-        
-        if (x < 0) x += w;
-        if (y < 0) y += h;
-        
-        if (o->cur.border.fill != EVAS_BORDER_FILL_DEFAULT)
-          {
-             if ((x > bsl) && (x < (w - bsr)) &&
-                 (y > bst) && (y < (h - bsb)))
+             RGBA_Image *im;
+             DATA32 *data = NULL;
+             int err = 0;
+
+             im = obj->layer->evas->engine.func->image_data_get
+               (obj->layer->evas->engine.data.output, pixels, 0, &data, &err);
+             if ((!im) || (!data) || (err))
                {
-                  if (o->cur.border.fill == EVAS_BORDER_FILL_SOLID) return 1;
-                  return 0;
+                  ERR("Couldn't get image pixels RGBA_Image %p: im=%p, data=%p, err=%d", pixels, im, data, err);
+                  goto end;
                }
-          }
-        
-        if (x < bsl) x = (x * bl) / bsl;
-        else if (x > (w - bsr)) x = iw - (((w - x) * br) / bsr);
-        else if ((bsl + bsr) < w) x = bl + (((x - bsl) * (iw - bl - br)) / (w - bsl - bsr));
-        else return 1;
-        
-        if (y < bst) y = (y * bt) / bst;
-        else if (y > (h - bsb)) y = ih - (((h - y) * bb) / bsb);
-        else if ((bst + bsb) < h) y = bt + (((y - bst) * (ih - bt - bb)) / (h - bst - bsb));
-        else return 1;
-     }
-   
-   if (x < 0) x = 0;
-   if (y < 0) y = 0;
-   if (x >= iw) x = iw - 1;
-   if (y >= ih) y = ih - 1;
-   
-   stride = o->cur.image.stride;
-   
-   o->engine_data = obj->layer->evas->engine.func->image_data_get
-      (obj->layer->evas->engine.data.output,
-          o->engine_data,
-          0,
-          &data,
-          &o->load_error);
 
-   if (!data)
-     {
-        return_value = 0;
-        goto finish;
-     }
+             idx = evas_object_image_figure_x_fill(obj,
+                                                   o->cur.fill.x, o->cur.fill.w,
+                                                   o->cur.src_cut_w, &idw);
+             idy = evas_object_image_figure_y_fill(obj,
+                                                   o->cur.fill.y, o->cur.fill.h,
+                                                   o->cur.src_cut_h, &idh);
+             if (idw < 1) idw = 1;
+             if (idh < 1) idh = 1;
+             if (idx > 0) idx -= idw;
+             if (idy > 0) idy -= idh;
+             while ((int)idx < obj->cur.geometry.w)
+               {
+                  Evas_Coord ydy;
+                  int dobreak_w = 0;
+                  ydy = idy;
+                  ix = idx;
+                  if ((o->cur.fill.w == obj->cur.geometry.w) &&
+                      (o->cur.fill.x == 0))
+                    {
+                       dobreak_w = 1;
+                       iw = obj->cur.geometry.w;
+                    }
+                  else
+                    iw = ((int)(idx + idw)) - ix;
+                  while ((int)idy < obj->cur.geometry.h)
+                    {
+                       int dobreak_h = 0;
 
-   switch (o->cur.cspace)
-     {
-     case EVAS_COLORSPACE_ARGB8888:
-        data = ((DATA32*)(data) + ((y * (stride >> 2)) + x));
-        a = (*((DATA32*)(data)) >> 24) & 0xff;
-        break;
-     case EVAS_COLORSPACE_RGB565_A5P:
-        data = (void*) ((DATA16*)(data) + (h * (stride >> 1)));
-        data = (void*) ((DATA8*)(data) + ((y * (stride >> 1)) + x));
-        a = (*((DATA8*)(data))) & 0x1f;
-        break;
-     default:
-        return_value = 1;
-        goto finish;
-        break;
-     }
+                       iy = idy;
+                       if ((o->cur.fill.h == obj->cur.geometry.h) &&
+                           (o->cur.fill.y == 0))
+                         {
+                            ih = obj->cur.geometry.h;
+                            dobreak_h = 1;
+                         }
+                       else
+                         ih = ((int)(idy + idh)) - iy;
+                       if ((o->cur.border.l == 0) &&
+                           (o->cur.border.r == 0) &&
+                           (o->cur.border.t == 0) &&
+                           (o->cur.border.b == 0) &&
+                           (o->cur.border.fill != 0))
+                         {
+                            /* NOTE: render handles cserve2 here,
+                             * we don't need to
+                             */
+                              {
+                                 DATA8 alpha = 0;
+                                 if (obj->layer->evas->engine.func->pixel_alpha_get(pixels, px, py, &alpha, 0, 0, imagew, imageh, obj->cur.geometry.x + ix, obj->cur.geometry.y + iy, iw, ih))
+                                   {
+                                      is_inside = alpha > 0;
+                                      dobreak_h = 1;
+                                      dobreak_w = 1;
+                                      break;
+                                   }
+                              }
+                         }
+                       else
+                         {
+                            int inx, iny, inw, inh, outx, outy, outw, outh;
+                            int bl, br, bt, bb, bsl, bsr, bst, bsb;
+                            int imw, imh, ox, oy;
+                            DATA8 alpha = 0;
 
-   return_value = (a != 0);
-   goto finish;
+                            ox = obj->cur.geometry.x + ix;
+                            oy = obj->cur.geometry.y + iy;
+                            imw = imagew;
+                            imh = imageh;
+                            bl = o->cur.border.l;
+                            br = o->cur.border.r;
+                            bt = o->cur.border.t;
+                            bb = o->cur.border.b;
+                            if ((bl + br) > iw)
+                              {
+                                 bl = iw / 2;
+                                 br = iw - bl;
+                              }
+                            if ((bl + br) > imw)
+                              {
+                                 bl = imw / 2;
+                                 br = imw - bl;
+                              }
+                            if ((bt + bb) > ih)
+                              {
+                                 bt = ih / 2;
+                                 bb = ih - bt;
+                              }
+                            if ((bt + bb) > imh)
+                              {
+                                 bt = imh / 2;
+                                 bb = imh - bt;
+                              }
+                            if (o->cur.border.scale != 1.0)
+                              {
+                                 bsl = ((double)bl * o->cur.border.scale);
+                                 bsr = ((double)br * o->cur.border.scale);
+                                 bst = ((double)bt * o->cur.border.scale);
+                                 bsb = ((double)bb * o->cur.border.scale);
+                              }
+                            else
+                              {
+                                  bsl = bl; bsr = br; bst = bt; bsb = bb;
+                              }
+                            // #--
+                            // |
+                            inx = 0; iny = 0;
+                            inw = bl; inh = bt;
+                            outx = ox; outy = oy;
+                            outw = bsl; outh = bst;
+                            if (obj->layer->evas->engine.func->pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+                              {
+                                 is_inside = alpha > 0;
+                                 dobreak_h = 1;
+                                 dobreak_w = 1;
+                                 break;
+                              }
 
-   finish:
+                            // .##
+                            // |
+                            inx = bl; iny = 0;
+                            inw = imw - bl - br; inh = bt;
+                            outx = ox + bsl; outy = oy;
+                            outw = iw - bsl - bsr; outh = bst;
+                            if (obj->layer->evas->engine.func->pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+                              {
+                                 is_inside = alpha > 0;
+                                 dobreak_h = 1;
+                                 dobreak_w = 1;
+                                 break;
+                              }
+                            // --#
+                            //   |
+                            inx = imw - br; iny = 0;
+                            inw = br; inh = bt;
+                            outx = ox + iw - bsr; outy = oy;
+                            outw = bsr; outh = bst;
+                            if (obj->layer->evas->engine.func->pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+                              {
+                                 is_inside = alpha > 0;
+                                 dobreak_h = 1;
+                                 dobreak_w = 1;
+                                 break;
+                              }
+                            // .--
+                            // #  
+                            inx = 0; iny = bt;
+                            inw = bl; inh = imh - bt - bb;
+                            outx = ox; outy = oy + bst;
+                            outw = bsl; outh = ih - bst - bsb;
+                            if (obj->layer->evas->engine.func->pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+                              {
+                                 is_inside = alpha > 0;
+                                 dobreak_h = 1;
+                                 dobreak_w = 1;
+                                 break;
+                              }
+                            // .--.
+                            // |##|
+                            if (o->cur.border.fill > EVAS_BORDER_FILL_NONE)
+                              {
+                                 inx = bl; iny = bt;
+                                 inw = imw - bl - br; inh = imh - bt - bb;
+                                 outx = ox + bsl; outy = oy + bst;
+                                 outw = iw - bsl - bsr; outh = ih - bst - bsb;
+                                 if (obj->layer->evas->engine.func->pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+                                   {
+                                      is_inside = alpha > 0;
+                                      dobreak_h = 1;
+                                      dobreak_w = 1;
+                                      break;
+                                   }
+                              }
+                            // --.
+                            //   #
+                            inx = imw - br; iny = bt;
+                            inw = br; inh = imh - bt - bb;
+                            outx = ox + iw - bsr; outy = oy + bst;
+                            outw = bsr; outh = ih - bst - bsb;
+                            if (obj->layer->evas->engine.func->pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+                              {
+                                 is_inside = alpha > 0;
+                                 dobreak_h = 1;
+                                 dobreak_w = 1;
+                                 break;
+                              }
+                            // |
+                            // #--
+                            inx = 0; iny = imh - bb;
+                            inw = bl; inh = bb;
+                            outx = ox; outy = oy + ih - bsb;
+                            outw = bsl; outh = bsb;
+                            if (obj->layer->evas->engine.func->pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+                              {
+                                 is_inside = alpha > 0;
+                                 dobreak_h = 1;
+                                 dobreak_w = 1;
+                                 break;
+                              }
+                            // |
+                            // .## 
+                            inx = bl; iny = imh - bb;
+                            inw = imw - bl - br; inh = bb;
+                            outx = ox + bsl; outy = oy + ih - bsb;
+                            outw = iw - bsl - bsr; outh = bsb;
+                            if (obj->layer->evas->engine.func->pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+                              {
+                                 is_inside = alpha > 0;
+                                 dobreak_h = 1;
+                                 dobreak_w = 1;
+                                 break;
+                              }
+                            //   |
+                            // --#
+                            inx = imw - br; iny = imh - bb;
+                            inw = br; inh = bb;
+                            outx = ox + iw - bsr; outy = oy + ih - bsb;
+                            outw = bsr; outh = bsb;
+                            if (obj->layer->evas->engine.func->pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+                              {
+                                 is_inside = alpha > 0;
+                                 dobreak_h = 1;
+                                 dobreak_w = 1;
+                                 break;
+                              }
+                         }
+                       idy += idh;
+                       if (dobreak_h) break;
+                    }
+                  idx += idw;
+                  idy = ydy;
+                  if (dobreak_w) break;
+               }
+          }
+     }
 
-   obj->layer->evas->engine.func->image_data_put(obj->layer->evas->engine.data.output,
-                                  o->engine_data,
-                                  data);
-   return return_value;
+ end:
+   return is_inside;
 }
 
 static int
@@ -3837,25 +4153,25 @@ evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_C
 
    switch (o->cur.cspace)
      {
-       case EVAS_COLORSPACE_ARGB8888:
-         out = evas_common_convert_argb8888_to(data,
-                                               o->cur.image.w,
-                                               o->cur.image.h,
-                                               o->cur.image.stride >> 2,
-                                               o->cur.has_alpha,
-                                               to_cspace);
-         break;
-       case EVAS_COLORSPACE_RGB565_A5P:
-         out = evas_common_convert_rgb565_a5p_to(data,
-                                                 o->cur.image.w,
-                                                 o->cur.image.h,
-                                                 o->cur.image.stride >> 1,
-                                                 o->cur.has_alpha,
-                                                 to_cspace);
-         break;
-        case EVAS_COLORSPACE_YCBCR422601_PL:
-           out = evas_common_convert_yuv_422_601_to(data,
-                                                   o->cur.image.w,
+      case EVAS_COLORSPACE_ARGB8888:
+         out = evas_common_convert_argb8888_to(data,
+                                               o->cur.image.w,
+                                               o->cur.image.h,
+                                               o->cur.image.stride >> 2,
+                                               o->cur.has_alpha,
+                                               to_cspace);
+         break;
+      case EVAS_COLORSPACE_RGB565_A5P:
+         out = evas_common_convert_rgb565_a5p_to(data,
+                                                 o->cur.image.w,
+                                                 o->cur.image.h,
+                                                 o->cur.image.stride >> 1,
+                                                 o->cur.has_alpha,
+                                                 to_cspace);
+         break;
+      case EVAS_COLORSPACE_YCBCR422601_PL:
+         out = evas_common_convert_yuv_422_601_to(data,
+                                                  o->cur.image.w,
                                                    o->cur.image.h,
                                                    to_cspace);
           break;
@@ -3873,13 +4189,13 @@ evas_object_image_data_convert_internal(Evas_Object_Image *o, void *data, Evas_C
           break;
         case EVAS_COLORSPACE_YCBCR420TM12601_PL:
           out = evas_common_convert_yuv_420T_601_to(data,
-                                                   o->cur.image.w,
-                                                   o->cur.image.h,
-                                                   to_cspace);
+                                                    o->cur.image.w,
+                                                    o->cur.image.h,
+                                                    to_cspace);
           break;
-       default:
+        default:
           WRN("unknow colorspace: %i\n", o->cur.cspace);
-         break;
+          break;
      }
 
    return out;
@@ -3952,7 +4268,7 @@ _evas_object_image_video_overlay_show(Evas_Object *obj)
         /* Cancel dirty on the image */
         Eina_Rectangle *r;
 
-        o->dirty_pixels = 0;
+        o->dirty_pixels = EINA_FALSE;
         EINA_LIST_FREE(o->pixel_updates, r)
           eina_rectangle_free(r);
      }
index 302da42..ee0ea0d 100644 (file)
@@ -77,3 +77,32 @@ evas_object_inform_call_image_unloaded(Evas_Object *obj)
    evas_object_event_callback_call(obj, EVAS_CALLBACK_IMAGE_UNLOADED, NULL, _evas_event_counter);
    _evas_post_event_callback_call(obj->layer->evas);
 }
+
+void
+evas_object_inform_call_image_resize(Evas_Object *obj)
+{
+   _evas_object_event_new();
+   evas_object_event_callback_call(obj, EVAS_CALLBACK_IMAGE_RESIZE, NULL, _evas_event_counter);
+   _evas_post_event_callback_call(obj->layer->evas);
+}
+
+///Jiyoun: This code will be modified after opensource fix lockup issue
+#define EVAS_CALLBACK_CANVAS_OBJECT_RENDER_PRE 100
+#define EVAS_CALLBACK_CANVAS_OBJECT_RENDER_POST 101
+
+void
+evas_object_inform_call_render_pre(Evas_Object *obj)
+{
+   _evas_object_event_new();
+   evas_object_event_callback_call(obj, EVAS_CALLBACK_CANVAS_OBJECT_RENDER_PRE, NULL, _evas_event_counter);
+   _evas_post_event_callback_call(obj->layer->evas);
+}
+
+void
+evas_object_inform_call_render_post(Evas_Object *obj)
+{
+   _evas_object_event_new();
+   evas_object_event_callback_call(obj, EVAS_CALLBACK_CANVAS_OBJECT_RENDER_POST, NULL, _evas_event_counter);
+   _evas_post_event_callback_call(obj->layer->evas);
+}
+
index 177421d..5a8a631 100644 (file)
@@ -101,12 +101,19 @@ evas_object_line_xy_set(Evas_Object *obj, Evas_Coord x1, Evas_Coord y1, Evas_Coo
    MAGIC_CHECK(o, Evas_Object_Line, MAGIC_OBJ_LINE);
    return;
    MAGIC_CHECK_END();
-   if ((x1 == o->cur.x1) && (y1 == o->cur.y1) &&
-       (x2 == o->cur.x2) && (y2 == o->cur.y2)) return;
+
+   if ((x1 == (obj->cur.geometry.x + o->cur.x1)) &&
+       (y1 == (obj->cur.geometry.y + o->cur.y1)) &&
+       (x2 == (obj->cur.geometry.x + o->cur.x2)) &&
+       (y2 == (obj->cur.geometry.y + o->cur.y2)))
+     {
+        return;
+     }
    if (obj->layer->evas->events_frozen <= 0)
      {
         if (!evas_event_passes_through(obj) &&
-            !evas_event_freezes_through(obj))
+            !evas_event_freezes_through(obj) &&
+            !evas_object_is_source_invisible(obj))
           was = evas_object_is_in_output_rect(obj,
                                               obj->layer->evas->pointer.x,
                                               obj->layer->evas->pointer.y,
@@ -151,7 +158,8 @@ evas_object_line_xy_set(Evas_Object *obj, Evas_Coord x1, Evas_Coord y1, Evas_Coo
                                            obj->layer->evas->pointer.x,
                                            obj->layer->evas->pointer.y, 1, 1);
         if (!evas_event_passes_through(obj) &&
-            !evas_event_freezes_through(obj))
+            !evas_event_freezes_through(obj) &&
+            !evas_object_is_source_invisible(obj))
           {
              if ((is ^ was) && obj->cur.visible)
                evas_event_feed_mouse_move(obj->layer->evas,
index 2fa7748..8584602 100644 (file)
@@ -36,15 +36,21 @@ evas_object_change_reset(Evas_Object *obj)
    obj->changed = EINA_FALSE;
    obj->changed_move = EINA_FALSE;
    obj->changed_color = EINA_FALSE;
-   obj->changed_map = EINA_FALSE;
    obj->changed_pchange = EINA_FALSE;
+   obj->changed_src_visible = EINA_FALSE;
 }
 
 void
 evas_object_cur_prev(Evas_Object *obj)
 {
-   if (!obj->prev.valid_map && (obj->prev.map == obj->cur.map))
-     obj->prev.map = NULL;
+   if (!obj->prev.valid_map)
+     {
+        if (obj->prev.map != obj->cur.map)
+          evas_map_free(obj->prev.map);
+        if (obj->cache_map == obj->prev.map)
+          obj->cache_map = NULL;
+        obj->prev.map = NULL;
+     }
 
    if (obj->cur.map != obj->prev.map)
      {
@@ -66,6 +72,32 @@ evas_object_free(Evas_Object *obj, int clean_layer)
    evas_object_map_set(obj, NULL);
    if (obj->prev.map) evas_map_free(obj->prev.map);
    if (obj->cache_map) evas_map_free(obj->cache_map);
+   if (obj->map.surface)
+     {
+        if (obj->layer)
+          {
+             obj->layer->evas->engine.func->image_map_surface_free
+                (obj->layer->evas->engine.data.output,
+                 obj->map.surface);
+          }
+        obj->map.surface = NULL;
+     }
+   if (obj->mask.is_mask)
+     {
+        obj->mask.is_mask = EINA_FALSE;
+        obj->mask.redraw = EINA_FALSE;
+        obj->mask.is_alpha = EINA_FALSE;
+        obj->mask.w = obj->mask.h = 0;
+        if (obj->mask.surface)
+          {
+             if (obj->layer)
+               {
+                  obj->layer->evas->engine.func->image_map_surface_free
+                       (obj->layer->evas->engine.data.output, obj->mask.surface);
+                  obj->mask.surface = NULL;
+               }
+          }
+     }
    evas_object_grabs_cleanup(obj);
    evas_object_intercept_cleanup(obj);
    if (obj->smart.parent) was_smart_child = 1;
@@ -77,6 +109,11 @@ evas_object_free(Evas_Object *obj, int clean_layer)
    evas_object_clip_changes_clean(obj);
    evas_object_event_callback_all_del(obj);
    evas_object_event_callback_cleanup(obj);
+   if (obj->spans)
+     {
+        free(obj->spans);
+        obj->spans = NULL;
+     }
    while (obj->data.elements)
      {
         Evas_Data_Node *node;
@@ -100,6 +137,7 @@ evas_object_change(Evas_Object *obj)
    Evas_Object *obj2;
    Eina_Bool movch = EINA_FALSE;
 
+   if (!obj->layer) return;
    if (obj->layer->evas->nochange) return;
    obj->layer->evas->changed = EINA_TRUE;
 
@@ -254,6 +292,9 @@ evas_object_render_pre_effect_updates(Eina_Array *rects, Evas_Object *obj, int i
    Eina_Array_Iterator it;
    int x, y, w, h;
 
+   if (!obj) return;
+   if (!obj->layer) return;
+
    if (obj->smart.smart) goto end;
    /* FIXME: was_v isn't used... why? */
    if (!obj->clip.clipees)
@@ -380,6 +421,20 @@ evas_object_was_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
 }
 /* routines apps will call */
 
+void
+evas_object_mapped_across_change(Evas_Object *obj)
+{
+   while (obj)
+     {
+        if (_evas_render_has_map(obj))
+          {
+             obj->changed_pchange = EINA_TRUE;
+             obj->changed_map = EINA_TRUE;
+          }
+        obj = obj->smart.parent;
+     }
+}
+
 EAPI void
 evas_object_ref(Evas_Object *obj)
 {
@@ -412,6 +467,10 @@ evas_object_ref_get(const Evas_Object *obj)
 EAPI void
 evas_object_del(Evas_Object *obj)
 {
+   Evas_Object *proxy;
+   Eina_List *l, *l2;
+
+   if (!obj) return;
    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
    return;
    MAGIC_CHECK_END();
@@ -424,21 +483,32 @@ evas_object_del(Evas_Object *obj)
         return;
      }
 
+   // FIXME: After EO is integrated, remove on_deletion flag.
+   if (obj->on_deletion)
+     {
+        WRN("Object %p [%s] is already deleting", obj, obj->type);
+        return;
+     }
+   obj->on_deletion = 1;
+
    evas_object_hide(obj);
    if (obj->focused)
      {
         obj->focused = EINA_FALSE;
-        obj->layer->evas->focused = NULL;
+        if (obj->layer)
+          obj->layer->evas->focused = NULL;
         _evas_object_event_new();
         evas_object_event_callback_call(obj, EVAS_CALLBACK_FOCUS_OUT, NULL, _evas_event_counter);
-        _evas_post_event_callback_call(obj->layer->evas);
+        if (obj->layer)
+          _evas_post_event_callback_call(obj->layer->evas);
      }
    _evas_object_event_new();
    evas_object_event_callback_call(obj, EVAS_CALLBACK_DEL, NULL, _evas_event_counter);
-   _evas_post_event_callback_call(obj->layer->evas);
-   if (obj->mouse_grabbed > 0)
+   if (obj->layer)
+     _evas_post_event_callback_call(obj->layer->evas);
+   if ((obj->mouse_grabbed > 0) && (obj->layer))
       obj->layer->evas->pointer.mouse_grabbed -= obj->mouse_grabbed;
-   if ((obj->mouse_in) || (obj->mouse_grabbed > 0))
+   if (((obj->mouse_in) || (obj->mouse_grabbed > 0)) && (obj->layer))
       obj->layer->evas->pointer.object.in = eina_list_remove(obj->layer->evas->pointer.object.in, obj);
    obj->mouse_grabbed = 0;
    obj->mouse_in = 0;
@@ -451,14 +521,21 @@ evas_object_del(Evas_Object *obj)
    evas_object_grabs_cleanup(obj);
    while (obj->clip.clipees)
      evas_object_clip_unset(obj->clip.clipees->data);
-   while (obj->proxy.proxies)
-     evas_object_image_source_unset(obj->proxy.proxies->data);
+   EINA_LIST_FOREACH_SAFE(obj->proxy.proxies, l, l2, proxy)
+     {
+        if (!proxy || !proxy->type) continue;
+        if (!strcmp("image", proxy->type))
+          evas_object_image_source_unset(proxy);
+        else if (!strcmp("text", proxy->type))
+          evas_object_text_filter_source_set(proxy, NULL, obj);
+     }
    if (obj->cur.clipper) evas_object_clip_unset(obj);
    evas_object_map_set(obj, NULL);
    if (obj->smart.smart) evas_object_smart_del(obj);
    _evas_object_event_new();
    evas_object_event_callback_call(obj, EVAS_CALLBACK_FREE, NULL, _evas_event_counter);
-   _evas_post_event_callback_call(obj->layer->evas);
+   if (obj->layer)
+     _evas_post_event_callback_call(obj->layer->evas);
    evas_object_smart_cleanup(obj);
    obj->delete_me = 1;
    evas_object_change(obj);
@@ -585,27 +662,28 @@ evas_object_update_bounding_box(Evas_Object *obj)
 EAPI void
 evas_object_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
 {
+   Evas *evas;
    int is, was = 0, pass = 0, freeze = 0;
    int nx = 0, ny = 0;
+   Eina_Bool source_invisible = EINA_FALSE;
 
    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
    return;
    MAGIC_CHECK_END();
    if (obj->delete_me) return;
+   if (!obj->layer) return;
 
    nx = x;
    ny = y;
 
-   if (!obj->is_frame)
+   evas = obj->layer->evas;
+
+   if ((!obj->is_frame) && (obj != evas->framespace.clip))
      {
         if ((!obj->smart.parent) && (obj->smart.smart))
           {
-             int fx, fy;
-
-             evas_output_framespace_get(obj->layer->evas, 
-                                        &fx, &fy, NULL, NULL);
-             nx += fx;
-             ny += fy;
+             nx += evas->framespace.x;
+             ny += evas->framespace.y;
           }
      }
 
@@ -619,11 +697,20 @@ evas_object_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
 
    if ((obj->cur.geometry.x == nx) && (obj->cur.geometry.y == ny)) return;
 
+   Evas_Map *map = evas_object_map_get(obj);
+   if (map && map->move_sync.enabled)
+     {
+        Evas_Coord diff_x = x - obj->cur.geometry.x;
+        Evas_Coord diff_y = y - obj->cur.geometry.y;
+        evas_map_object_move_diff_set(map, diff_x, diff_y);
+     }
+
    if (obj->layer->evas->events_frozen <= 0)
      {
         pass = evas_event_passes_through(obj);
         freeze = evas_event_freezes_through(obj);
-        if ((!pass) && (!freeze))
+        source_invisible = evas_object_is_source_invisible(obj);
+        if ((!pass) && (!freeze) && (!source_invisible))
           was = evas_object_is_in_output_rect(obj,
                                               obj->layer->evas->pointer.x,
                                               obj->layer->evas->pointer.y, 1, 1);
@@ -672,11 +759,13 @@ EAPI void
 evas_object_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
 {
    int is, was = 0, pass = 0, freeze =0;
+   Eina_Bool source_invisible = EINA_FALSE;
 
    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
    return;
    MAGIC_CHECK_END();
    if (obj->delete_me) return;
+   if (!obj->layer) return;
    if (w < 0) w = 0; if (h < 0) h = 0;
 
    if (evas_object_intercept_call_resize(obj, w, h)) return;
@@ -693,6 +782,7 @@ evas_object_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
      {
         pass = evas_event_passes_through(obj);
         freeze = evas_event_freezes_through(obj);
+        source_invisible = evas_object_is_source_invisible(obj);
         if ((!pass) && (!freeze))
           was = evas_object_is_in_output_rect(obj,
                                               obj->layer->evas->pointer.x,
@@ -744,13 +834,14 @@ evas_object_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
 EAPI void
 evas_object_geometry_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
 {
+   Evas *evas;
    int nx = 0, ny = 0;
 
    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
    if (x) *x = 0; if (y) *y = 0; if (w) *w = 0; if (h) *h = 0;
    return;
    MAGIC_CHECK_END();
-   if (obj->delete_me)
+   if ((obj->delete_me) || (!obj->layer))
      {
         if (x) *x = 0; if (y) *y = 0; if (w) *w = 0; if (h) *h = 0;
         return;
@@ -759,22 +850,14 @@ evas_object_geometry_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, E
    nx = obj->cur.geometry.x;
    ny = obj->cur.geometry.y;
 
-   if (!obj->is_frame)
-     {
-        int fx, fy;
-
-        evas_output_framespace_get(obj->layer->evas, 
-                                   &fx, &fy, NULL, NULL);
+   evas = obj->layer->evas;
 
+   if ((!obj->is_frame) && (obj != evas->framespace.clip))
+     {
         if ((!obj->smart.parent) && (obj->smart.smart))
           {
-             if (nx > 0) nx -= fx;
-             if (ny > 0) ny -= fy;
-          }
-        else if ((obj->smart.parent) && (!obj->smart.smart))
-          {
-             if (nx > 0) nx -= fx;
-             if (ny > 0) ny -= fy;
+             if (nx > 0) nx -= evas->framespace.x;
+             if (ny > 0) ny -= evas->framespace.y;
           }
      }
 
@@ -797,6 +880,33 @@ _evas_object_size_hint_alloc(Evas_Object *obj)
    obj->size_hints->max.h = -1;
    obj->size_hints->align.x = 0.5;
    obj->size_hints->align.y = 0.5;
+   obj->size_hints->dispmode = EVAS_DISPLAY_MODE_NONE;
+}
+
+EAPI Evas_Display_Mode
+evas_object_size_hint_display_mode_get(const Evas_Object *obj)
+{
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return EVAS_DISPLAY_MODE_NONE;
+   MAGIC_CHECK_END();
+   if ((!obj->size_hints) || obj->delete_me)
+     return EVAS_DISPLAY_MODE_NONE;
+   return obj->size_hints->dispmode;
+}
+
+EAPI void
+evas_object_size_hint_display_mode_set(Evas_Object *obj, Evas_Display_Mode dispmode)
+{
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return;
+   MAGIC_CHECK_END();
+   if (obj->delete_me)
+     return;
+   _evas_object_size_hint_alloc(obj);
+   if (obj->size_hints->dispmode == dispmode) return;
+   obj->size_hints->dispmode = dispmode;
+
+   evas_object_inform_call_changed_size_hints(obj);
 }
 
 EAPI void
@@ -1039,6 +1149,7 @@ evas_object_show(Evas_Object *obj)
    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
    return;
    MAGIC_CHECK_END();
+   if (!obj->layer) return;
    if (obj->delete_me) return;
    if (evas_object_intercept_call_show(obj)) return;
    if (obj->smart.smart)
@@ -1058,7 +1169,8 @@ evas_object_show(Evas_Object *obj)
         evas_object_clip_across_clippees_check(obj);
         evas_object_recalc_clippees(obj);
         if ((!evas_event_passes_through(obj)) &&
-            (!evas_event_freezes_through(obj)))
+            (!evas_event_freezes_through(obj)) &&
+            (!evas_object_is_source_invisible(obj)))
           {
              if (!obj->smart.smart)
                {
@@ -1082,6 +1194,7 @@ evas_object_hide(Evas_Object *obj)
    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
    return;
    MAGIC_CHECK_END();
+   if (!obj->layer) return;
    if (obj->delete_me) return;
    if (evas_object_intercept_call_hide(obj)) return;
    if (obj->smart.smart)
@@ -1094,6 +1207,20 @@ evas_object_hide(Evas_Object *obj)
         return;
      }
    obj->cur.visible = 0;
+
+   if (obj->mask.is_mask)
+     {
+        obj->mask.redraw = EINA_FALSE;
+        obj->mask.is_alpha = EINA_FALSE;
+        obj->mask.w = obj->mask.h = 0;
+        if (obj->mask.surface)
+          {
+             obj->layer->evas->engine.func->image_map_surface_free
+                   (obj->layer->evas->engine.data.output, obj->mask.surface);
+             obj->mask.surface = NULL;
+          }
+     }
+
    evas_object_change(obj);
    evas_object_clip_dirty(obj);
    if (obj->layer->evas->events_frozen <= 0)
@@ -1101,7 +1228,8 @@ evas_object_hide(Evas_Object *obj)
         evas_object_clip_across_clippees_check(obj);
         evas_object_recalc_clippees(obj);
         if ((!evas_event_passes_through(obj)) &&
-            (!evas_event_freezes_through(obj)))
+            (!evas_event_freezes_through(obj)) &&
+            (!evas_object_is_source_invisible(obj)))
           {
              if ((!obj->smart.smart) ||
                  ((obj->cur.map) && (obj->cur.map->count == 4) && (obj->cur.usemap)))
@@ -1320,7 +1448,7 @@ evas_object_evas_get(const Evas_Object *obj)
    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
    return NULL;
    MAGIC_CHECK_END();
-   if (obj->delete_me) return NULL;
+   if ((obj->delete_me) || (!obj->layer)) return NULL;
    return obj->layer->evas;
 }
 
@@ -1346,6 +1474,7 @@ evas_object_top_at_xy_get(const Evas *e, Evas_Coord x, Evas_Coord y, Eina_Bool i
              if (obj->delete_me) continue;
              if ((!include_pass_events_objects) &&
                  (evas_event_passes_through(obj))) continue;
+             if (evas_object_is_source_invisible(obj)) continue;
              if ((!include_hidden_objects) && (!obj->cur.visible)) continue;
              evas_object_clip_recalc(obj);
              if ((evas_object_is_in_output_rect(obj, xx, yy, 1, 1)) &&
@@ -1391,6 +1520,7 @@ evas_object_top_in_rectangle_get(const Evas *e, Evas_Coord x, Evas_Coord y, Evas
              if (obj->delete_me) continue;
              if ((!include_pass_events_objects) &&
                  (evas_event_passes_through(obj))) continue;
+             if (evas_object_is_source_invisible(obj)) continue;
              if ((!include_hidden_objects) && (!obj->cur.visible)) continue;
              evas_object_clip_recalc(obj);
              if ((evas_object_is_in_output_rect(obj, xx, yy, ww, hh)) &&
@@ -1424,6 +1554,7 @@ evas_objects_at_xy_get(const Evas *e, Evas_Coord x, Evas_Coord y, Eina_Bool incl
              if (obj->delete_me) continue;
              if ((!include_pass_events_objects) &&
                  (evas_event_passes_through(obj))) continue;
+             if (evas_object_is_source_invisible(obj)) continue;
              if ((!include_hidden_objects) && (!obj->cur.visible)) continue;
              evas_object_clip_recalc(obj);
              if ((evas_object_is_in_output_rect(obj, xx, yy, 1, 1)) &&
@@ -1475,6 +1606,7 @@ evas_objects_in_rectangle_get(const Evas *e, Evas_Coord x, Evas_Coord y, Evas_Co
              if (obj->delete_me) continue;
              if ((!include_pass_events_objects) &&
                  (evas_event_passes_through(obj))) continue;
+             if (evas_object_is_source_invisible(obj)) continue;
              if ((!include_hidden_objects) && (!obj->cur.visible)) continue;
              evas_object_clip_recalc(obj);
              if ((evas_object_is_in_output_rect(obj, xx, yy, ww, hh)) &&
index 34931b2..c9bdd58 100644 (file)
@@ -106,7 +106,8 @@ evas_object_polygon_point_add(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
    if (obj->layer->evas->events_frozen <= 0)
      {
         if (!evas_event_passes_through(obj) &&
-            !evas_event_freezes_through(obj))
+            !evas_event_freezes_through(obj) &&
+            !evas_object_is_source_invisible(obj))
           was = evas_object_is_in_output_rect(obj,
                                               obj->layer->evas->pointer.x,
                                               obj->layer->evas->pointer.y,
@@ -175,7 +176,8 @@ evas_object_polygon_point_add(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
                                            obj->layer->evas->pointer.x,
                                            obj->layer->evas->pointer.y, 1, 1);
         if (!evas_event_passes_through(obj) &&
-            !evas_event_freezes_through(obj) )
+            !evas_event_freezes_through(obj) &&
+            !evas_object_is_source_invisible(obj))
           {
              if ((is ^ was) && obj->cur.visible)
                evas_event_feed_mouse_move(obj->layer->evas,
@@ -193,6 +195,7 @@ EAPI void
 evas_object_polygon_points_clear(Evas_Object *obj)
 {
    Evas_Object_Polygon *o;
+   void *list_data;
    int is, was;
 
    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
@@ -205,10 +208,9 @@ evas_object_polygon_points_clear(Evas_Object *obj)
    was = evas_object_is_in_output_rect(obj,
                                        obj->layer->evas->pointer.x,
                                        obj->layer->evas->pointer.y, 1, 1);
-   while (o->points)
+   EINA_LIST_FREE(o->points, list_data)
      {
-        free(o->points->data);
-        o->points = eina_list_remove(o->points, o->points->data);
+        free(list_data);
      }
    obj->cur.geometry.x = 0;
    obj->cur.geometry.y = 0;
@@ -273,6 +275,7 @@ static void
 evas_object_polygon_free(Evas_Object *obj)
 {
    Evas_Object_Polygon *o;
+   void *list_data;
 
    /* frees private object data. very simple here */
    o = (Evas_Object_Polygon *)(obj->object_data);
@@ -280,10 +283,9 @@ evas_object_polygon_free(Evas_Object *obj)
    return;
    MAGIC_CHECK_END();
    /* free obj */
-   while (o->points)
+   EINA_LIST_FREE(o->points, list_data)
      {
-        free(o->points->data);
-        o->points = eina_list_remove(o->points, o->points->data);
+        free(list_data);
      }
    o->engine_data = obj->layer->evas->engine.func->polygon_points_clear(obj->layer->evas->engine.data.output,
                                                                         obj->layer->evas->engine.data.context,
@@ -366,7 +368,7 @@ evas_object_polygon_render_pre(Evas_Object *obj)
         evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes, obj, is_v, was_v);
         goto done;
      }
-   if (obj->changed_map)
+   if (obj->changed_map || obj->changed_src_visible)
      {
         evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
                                             obj);
index fa90f42..9677378 100644 (file)
@@ -194,7 +194,7 @@ evas_object_rectangle_render_pre(Evas_Object *obj)
        evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes, obj, is_v, was_v);
        goto done;
      }
-   if (obj->changed_map)
+   if (obj->changed_map || obj->changed_src_visible)
      {
         evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
                                             obj);
index 431edd2..b7db35f 100644 (file)
@@ -104,14 +104,15 @@ EAPI const void *
 evas_object_smart_interface_get(const Evas_Object *obj,
                                 const char *name)
 {
-   unsigned int i;
    Evas_Smart *s;
+   unsigned int i;
 
    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
    return NULL;
    MAGIC_CHECK_END();
 
    s = evas_object_smart_smart_get(obj);
+   if (!s) return NULL;
 
    for (i = 0; i < s->interfaces.size; i++)
      {
@@ -138,6 +139,7 @@ evas_object_smart_interface_data_get(const Evas_Object *obj,
    MAGIC_CHECK_END();
 
    s = evas_object_smart_smart_get(obj);
+   if (!s) return NULL;
 
    for (i = 0; i < s->interfaces.size; i++)
      {
@@ -216,7 +218,7 @@ evas_object_smart_member_add(Evas_Object *obj, Evas_Object *smart_obj)
    obj->layer->usage++;
    obj->smart.parent = smart_obj;
    o->contained = eina_inlist_append(o->contained, EINA_INLIST_GET(obj));
-   evas_object_smart_member_cache_invalidate(obj, EINA_TRUE, EINA_TRUE);
+   evas_object_smart_member_cache_invalidate(obj, EINA_TRUE, EINA_TRUE, EINA_TRUE);
    obj->restack = 1;
    evas_object_change(obj);
    evas_object_mapped_clip_across_mark(obj);
@@ -238,6 +240,8 @@ evas_object_smart_member_del(Evas_Object *obj)
    if (!obj->smart.parent) return;
 
    smart_obj = obj->smart.parent;
+   evas_object_mapped_across_change(smart_obj);
+
    if (smart_obj->smart.smart->smart_class->member_del)
      smart_obj->smart.smart->smart_class->member_del(smart_obj, obj);
 
@@ -245,7 +249,7 @@ evas_object_smart_member_del(Evas_Object *obj)
    o->contained = eina_inlist_remove(o->contained, EINA_INLIST_GET(obj));
    o->member_count--;
    obj->smart.parent = NULL;
-   evas_object_smart_member_cache_invalidate(obj, EINA_TRUE, EINA_TRUE);
+   evas_object_smart_member_cache_invalidate(obj, EINA_TRUE, EINA_TRUE, EINA_TRUE);
    obj->layer->usage--;
    obj->cur.layer = obj->layer->layer;
    evas_object_inject(obj, obj->layer->evas);
@@ -813,6 +817,8 @@ evas_call_smarts_calculate(Evas *e)
 {
    Eina_Clist *elem;
    Evas_Object *obj;
+   static int debug_count = 0;
+   static int debug_count1 = 0;
 
 //   printf("+CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALC-----------v\n");
    evas_event_freeze(e);
@@ -820,7 +826,8 @@ evas_call_smarts_calculate(Evas *e)
 
    while (NULL != (elem = eina_clist_head(&e->calc_list)))
      {
-        Evas_Object_Smart *o;
+       debug_count ++;
+       Evas_Object_Smart *o;
 
         /* move the item to the processed list */
         obj = EINA_CLIST_ENTRY(elem, Evas_Object, calc_entry);
@@ -839,11 +846,15 @@ evas_call_smarts_calculate(Evas *e)
 
    while (NULL != (elem = eina_clist_head(&e->calc_done)))
      {
-        obj = EINA_CLIST_ENTRY(elem, Evas_Object, calc_entry);
-        obj->recalculate_cycle = 0;
-        eina_clist_remove(&obj->calc_entry);
+       debug_count1 ++;
+       obj = EINA_CLIST_ENTRY(elem, Evas_Object, calc_entry);
+       obj->recalculate_cycle = 0;
+       eina_clist_remove(&obj->calc_entry);
+
      }
 
+   debug_count = 0;
+   debug_count1 = 0;
    e->in_smart_calc--;
    if (e->in_smart_calc == 0) e->smart_calc_count++;
    evas_event_thaw(e);
@@ -860,6 +871,31 @@ evas_object_smart_changed(Evas_Object *obj)
    evas_object_smart_need_recalculate_set(obj, 1);
 }
 
+Eina_Bool
+evas_object_smart_changed_get(Evas_Object *obj)
+{
+   Evas_Object *o2;
+
+   if (!evas_object_is_visible(obj) && !evas_object_was_visible(obj))
+     return EINA_FALSE;
+
+  if (!obj->clip.clipees)
+    {
+       if (obj->changed && !obj->smart.smart) return EINA_TRUE;
+       if (_evas_render_has_map(obj))
+         {
+            if (((obj->changed_pchange) && (obj->changed_map)) ||
+                (obj->changed_color))
+              return EINA_TRUE;
+         }
+    }
+
+   EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), o2)
+     if (evas_object_smart_changed_get(o2)) return EINA_TRUE;
+
+   return EINA_FALSE;
+}
+
 /* internal calls */
 static void
 evas_object_smart_callbacks_clear(Evas_Object *obj)
@@ -897,12 +933,15 @@ evas_object_smart_del(Evas_Object *obj)
    if ((s) && (s->smart_class->del)) s->smart_class->del(obj);
    if (obj->smart.parent) evas_object_smart_member_del(obj);
 
-   for (i = 0; i < s->interfaces.size; i++)
+   if (s)
      {
-        const Evas_Smart_Interface *iface;
+        for (i = 0; i < s->interfaces.size; i++)
+          {
+             const Evas_Smart_Interface *iface;
 
-        iface = s->interfaces.array[i];
-        if (iface->del) iface->del(obj);
+             iface = s->interfaces.array[i];
+             if (iface->del) iface->del(obj);
+          }
      }
 
    free(obj->interface_privates);
@@ -947,7 +986,8 @@ evas_object_smart_cleanup(Evas_Object *obj)
 void
 evas_object_smart_member_cache_invalidate(Evas_Object *obj,
                                           Eina_Bool pass_events,
-                                          Eina_Bool freeze_events)
+                                          Eina_Bool freeze_events,
+                                          Eina_Bool source_invisible)
 {
    Evas_Object_Smart *o;
    Evas_Object *member;
@@ -960,6 +1000,8 @@ evas_object_smart_member_cache_invalidate(Evas_Object *obj,
      obj->parent_cache.pass_events_valid = EINA_FALSE;
    if (freeze_events)
      obj->parent_cache.freeze_events_valid = EINA_FALSE;
+   if (source_invisible)
+     obj->parent_cache.src_invisible_valid = EINA_FALSE;
 
    o = obj->object_data;
    if (o->magic != MAGIC_OBJ_SMART) return;
@@ -967,7 +1009,7 @@ evas_object_smart_member_cache_invalidate(Evas_Object *obj,
    EINA_INLIST_FOREACH(o->contained, member)
      evas_object_smart_member_cache_invalidate(member,
                                                pass_events,
-                                               freeze_events);
+                                               freeze_events, source_invisible);
 }
 
 void
@@ -1234,7 +1276,7 @@ evas_object_smart_render_pre(Evas_Object *obj)
 
    e = obj->layer->evas;
 
-   if (obj->changed_map)
+   if (obj->changed_map || obj->changed_src_visible)
      {
        evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
      }
index abec3af..cd830c0 100644 (file)
@@ -198,6 +198,7 @@ _evas_object_table_cache_reset(Evas_Object_Table_Data *priv)
    Evas_Object_Table_Cache *c = priv->cache;
    int size;
 
+   if (!c) return;
    c->total.expands.v = 0;
    c->total.expands.h = 0;
    c->total.min.w = 0;
@@ -479,8 +480,10 @@ _evas_object_table_calculate_layout_homogeneous(Evas_Object *o, Evas_Object_Tabl
 
         cx = x + ((opt->col * ww) / priv->size.cols);
         cw = x + (((opt->col + opt->colspan) * ww) / priv->size.cols) - cx;
+        cw += (opt->colspan - 1) * priv->pad.v;
         cy = y + ((opt->row * hh) / priv->size.rows);
         ch = y + (((opt->row + opt->rowspan) * hh) / priv->size.rows) - cy;
+        ch += (opt->rowspan - 1) * priv->pad.h;
 
         cx += (opt->col) * priv->pad.h;
         cy += (opt->row) * priv->pad.v;
@@ -637,10 +640,8 @@ _evas_object_table_calculate_hints_regular(Evas_Object *o, Evas_Object_Table_Dat
    _evas_object_table_cache_reset(priv);
 
    /* cache interesting data */
-   memset(c->expands.h, 1, priv->size.cols);
-   memset(c->expands.v, 1, priv->size.rows);
-   memset(c->weights.h, 0, priv->size.cols);
-   memset(c->weights.v, 0, priv->size.rows);
+   memset(c->expands.h, 1, priv->size.cols * sizeof(Eina_Bool));
+   memset(c->expands.v, 1, priv->size.rows * sizeof(Eina_Bool));
    EINA_LIST_FOREACH(priv->children, l, opt)
      {
         Evas_Object *child = opt->obj;
@@ -679,14 +680,14 @@ _evas_object_table_calculate_hints_regular(Evas_Object *o, Evas_Object_Table_Dat
           }
 
         if (!opt->expand_h)
-          memset(c->expands.h + opt->col, 0, opt->colspan);
+          memset(c->expands.h + opt->col, 0, opt->colspan * sizeof(Eina_Bool));
         else
           {
              for (i = opt->col; i < opt->col + opt->colspan; i++)
                c->weights.h[i] += (weightw / (double)opt->colspan);
           }
         if (!opt->expand_v)
-          memset(c->expands.v + opt->row, 0, opt->rowspan);
+          memset(c->expands.v + opt->row, 0, opt->rowspan * sizeof(Eina_Bool));
         else
           {
              for (i = opt->row; i < opt->row + opt->rowspan; i++)
@@ -773,8 +774,10 @@ _evas_object_table_calculate_layout_regular(Evas_Object *o, Evas_Object_Table_Da
    Evas_Coord *cols = NULL, *rows = NULL;
    Evas_Coord x, y, w, h;
 
-   evas_object_geometry_get(o, &x, &y, &w, &h);
    c = priv->cache;
+   if (!c) return;
+
+   evas_object_geometry_get(o, &x, &y, &w, &h);
 
    /* handle horizontal */
    if ((c->total.expands.h <= 0) || (c->total.min.w >= w))
@@ -849,13 +852,16 @@ _evas_object_table_calculate_layout_regular(Evas_Object *o, Evas_Object_Table_Da
      }
 
  end:
-   if (cols != c->sizes.h)
-     {
-        if (cols) free(cols);
-     }
-   if (rows != c->sizes.v)
+   if (priv->cache)
      {
-        if (rows) free(rows);
+        if (cols != c->sizes.h)
+          {
+             if (cols) free(cols);
+          }
+        if (rows != c->sizes.v)
+          {
+             if (rows) free(rows);
+          }
      }
 }
 
@@ -1068,20 +1074,40 @@ evas_object_table_pack_get(const Evas_Object *o, Evas_Object *child, unsigned sh
 EAPI Eina_Bool
 evas_object_table_pack(Evas_Object *o, Evas_Object *child, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan)
 {
+   Eina_Bool optalloc = EINA_FALSE;
+
    Evas_Object_Table_Option *opt;
 
    EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN_VAL(o, priv, 0);
 
+   if (colspan < 1)
+     {
+        ERR("colspan < 1");
+        return EINA_FALSE;
+     }
+   if ((0xffff - col) < colspan)
+     {
+        ERR("col + colspan > 0xffff");
+        return EINA_FALSE;
+     }
+   if ((col + colspan) >= 0x7ffff)
+     {
+        WRN("col + colspan getting rather large (>32767)");
+     }
    if (rowspan < 1)
      {
         ERR("rowspan < 1");
         return EINA_FALSE;
      }
-   if (colspan < 1)
+   if ((0xffff - row) < rowspan)
      {
-        ERR("colspan < 1");
+        ERR("row + rowspan > 0xffff");
         return EINA_FALSE;
      }
+   if ((row + rowspan) >= 0x7ffff)
+     {
+        WRN("row + rowspan getting rather large (>32767)");
+     }
 
    opt = _evas_object_table_option_get(child);
    if (!opt)
@@ -1092,6 +1118,7 @@ evas_object_table_pack(Evas_Object *o, Evas_Object *child, unsigned short col, u
              ERR("could not allocate table option data.");
              return EINA_FALSE;
           }
+        optalloc = EINA_TRUE;
      }
 
    opt->obj = child;
@@ -1129,6 +1156,7 @@ evas_object_table_pack(Evas_Object *o, Evas_Object *child, unsigned short col, u
              priv->size.cols = max_col;
              priv->size.rows = max_row;
           }
+        if (optalloc) free(opt);
      }
    else
      {
old mode 100644 (file)
new mode 100755 (executable)
index 2afc588..3ba5ba8
@@ -1,5 +1,9 @@
 #include "evas_common.h" /* Includes evas_bidi_utils stuff. */
 #include "evas_private.h"
+// TIZEN ONLY (20131106) : Font effect for tizen.
+#include <math.h>
+
+#include "evas_filter.h"
 
 /* save typing */
 #define ENFN obj->layer->evas->engine.func
@@ -11,11 +15,18 @@ static const char o_type[] = "text";
 /* private struct for text object internal data */
 typedef struct _Evas_Object_Text Evas_Object_Text;
 typedef struct _Evas_Object_Text_Item Evas_Object_Text_Item;
+// HAVE_UNICODE_EMOTICON(2013.12.06): refactored emoticon drawing.
+typedef struct _Evas_Object_Text_Emoticon_Item Evas_Object_Text_Emoticon_Item;
+//
 
 struct _Evas_Object_Text
 {
    DATA32               magic;
 
+   // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+   Eina_List                  *emoticons;
+   //
+
    struct {
       const char          *utf8_text; /* The text exposed to the API */
       const char          *font;
@@ -27,6 +38,19 @@ struct _Evas_Object_Text
       } outline, shadow, glow, glow2;
 
       unsigned char        style;
+      double               ellipsis;
+      Eina_Unicode        *text;
+
+      // special effects. VERY EXPERIMENTAL for now.
+      struct {
+         Eina_Stringshare    *code;
+         Evas_Filter_Program *chain;
+         Eina_Hash           *sources; // Evas_Filter_Proxy_Binding
+         int                  sources_count;
+         void                *output;
+         Eina_Bool            changed : 1;
+         Eina_Bool            invalid : 1; // Code parse failed
+      } filter;
    } cur, prev;
 
    float                       ascent, descent;
@@ -37,13 +61,39 @@ struct _Evas_Object_Text
 
    Evas_Font_Set              *font;
 
+   struct {
+      Evas_Object_Text_Item    *ellipsis_start;
+      Evas_Object_Text_Item    *ellipsis_end;
+      Evas_Coord                w, h;
+      int                       advance;
+      Eina_Bool                 ellipsis;
+   } last_computed;
+
    char                        changed : 1;
 };
 
+// HAVE_UNICODE_EMOTICON(2013.12.06): refactored emoticon drawing.
+struct _Evas_Object_Text_Emoticon_Item
+{
+   Evas                            *e;
+   void                            *engine_data;
+   int                              img_w, img_h;
+   // HAVE_UNICODE_EMOTICON(20140626): Adjust emoticon ascent, descent and height.
+   int                              ascent, descent;
+   //
+   Evas_Coord                       x, y, w, h;
+   Eina_Bool                        visible : 1;
+};
+//
+
 struct _Evas_Object_Text_Item
 {
    EINA_INLIST;
 
+   // HAVE_UNICODE_EMOTICON(2013.12.06): refactored emoticon drawing.
+   Evas_Object_Text_Emoticon_Item *emoticon_item;
+   //
+
    size_t               text_pos;
    size_t               visual_pos;
    Evas_Text_Props      text_props;
@@ -66,8 +116,17 @@ static int evas_object_text_is_opaque(Evas_Object *obj);
 static int evas_object_text_was_opaque(Evas_Object *obj);
 
 static void evas_object_text_scale_update(Evas_Object *obj);
-static void _evas_object_text_recalc(Evas_Object *obj);
-
+static void _evas_object_text_recalc(Evas_Object *obj, Eina_Unicode *text);
+
+// HAVE_UNICODE_EMOTICON(2013.12.06): refactored emoticon drawing.
+static void _evas_object_text_emoticon_update_geometry(Evas_Object *obj);
+static void _evas_object_text_emoticon_update_size(Evas_Object_Text *o, Evas_Object_Text_Item *it);
+//
+// TIZEN ONLY (20131106) : Font effect for tizen.
+static int evas_object_text_effect_outerglow_alpha_get(int x, int y, double opacity, int size);
+static int evas_object_text_effect_soft_outerglow_alpha_get(int x, int y, double opacity, int size);
+static int evas_object_text_effect_shadow_alpha_get(int x, int y, double opacity, int softness);
+//
 static const Evas_Object_Func object_func =
 {
    /* methods (compulsory) */
@@ -99,6 +158,173 @@ static const Evas_Object_Func object_func =
 
 EVAS_MEMPOOL(_mp_obj);
 
+// HAVE_UNICODE_EMOTICON(2013.12.06): refactored emoticon drawing.
+Evas_Object_Text_Emoticon_Item *
+_text_emoticon_img_new(Evas *e, Evas_Object *obj, Eina_Unicode str)
+{
+   const char *value;
+   char unicode_str[15];
+   char image_file[127];
+   int load_error = EVAS_LOAD_ERROR_NONE;
+   Evas_Image_Load_Opts opts = { EINA_FALSE, 0, 0, 0, 0, { 0, 0, 0, 0 }, 0 };
+   Evas_Object_Text_Emoticon_Item *item;
+
+   value = getenv("EVAS_UNICODE_EMOTICON_IMAGE_DISABLE");
+   if (value && !strcmp(value, "1"))
+     return NULL;
+
+   item = calloc(1, sizeof(Evas_Object_Text_Emoticon_Item));
+   if (!item)
+     {
+        ERR("Failed to allocate emoticon item, textb(%p)", obj);
+        return NULL;
+     }
+   eina_convert_xtoa(str, unicode_str);
+   if (strlen(unicode_str) <= 2)
+     {
+        snprintf(image_file, sizeof(image_file),
+                 "%s/u00%s.png", UNICODE_EMOTICON_FOLDER, unicode_str);
+     }
+   else
+     {
+        snprintf(image_file, sizeof(image_file),
+                 "%s/u%s.png", UNICODE_EMOTICON_FOLDER, unicode_str);
+     }
+
+   item->engine_data = e->engine.func->image_load(e->engine.data.output,
+                                                  image_file,
+                                                  NULL,
+                                                  &load_error,
+                                                  &opts);
+   if (!item->engine_data || (load_error != EVAS_LOAD_ERROR_NONE))
+     {
+        DBG("Failed to emoticon image, textblock(%p) error(%d)", obj, load_error);
+        free(item);
+        return NULL;
+     }
+   e->engine.func->image_size_get(e->engine.data.output, item->engine_data,
+                                  &item->img_w, &item->img_h);
+   return item;
+}
+
+// HAVE_UNICODE_EMOTICON(2013.12.06): refactored emoticon drawing.
+static void
+_text_emoticon_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
+{
+   Evas_Object_Text *o;
+   Evas_Object_Text_Item *it;
+   Eina_List *l;
+   Evas *e = obj->layer->evas;
+   Evas_Object_Text_Emoticon_Item *eitem;
+
+   o = (Evas_Object_Text *)(obj->object_data);
+
+   e->engine.func->context_color_set(output, context, 255, 255, 255, 255);
+   if ((obj->cur.cache.clip.r == 255) &&
+       (obj->cur.cache.clip.g == 255) &&
+       (obj->cur.cache.clip.b == 255) &&
+       (obj->cur.cache.clip.a == 255))
+        e->engine.func->context_multiplier_unset(output, context);
+   else if (obj->cur.clipper)
+     {
+        e->engine.func->context_multiplier_set(output, context,
+                                            obj->cur.clipper->cur.cache.clip.r,
+                                            obj->cur.clipper->cur.cache.clip.g,
+                                            obj->cur.clipper->cur.cache.clip.b,
+                                            obj->cur.clipper->cur.cache.clip.a);
+     }
+
+   EINA_LIST_FOREACH(o->emoticons, l, it)
+     {
+        eitem = it->emoticon_item;
+        if (!eitem->visible) continue;
+        e->engine.func->image_draw(output, context, surface, eitem->engine_data,
+                                   0, 0, eitem->img_w, eitem->img_h,
+                                   (eitem->x + x), (eitem->y + y),
+                                   eitem->w, eitem->h,
+                                   EINA_TRUE);
+     }
+}
+
+// HAVE_UNICODE_EMOTICON(2013.12.06): refactored emoticon drawing.
+static void
+_evas_object_text_emoticon_update_geometry(Evas_Object *obj)
+{
+   Evas_Object_Text *o;
+   Evas_Object_Text_Item *it;
+   Eina_List *l;
+   int ex, ey, center_offset = 0;
+
+   o = (Evas_Object_Text *)(obj->object_data);
+   if (o->emoticons)
+     {
+        EINA_LIST_FOREACH(o->emoticons, l, it)
+          {
+             if (!it->emoticon_item) continue;
+
+             //Compute emoticon position
+             if (it->h < o->max_ascent + o->max_descent)
+               center_offset = (o->max_ascent + o->max_descent - it->h) / 2;
+
+             ex = obj->cur.geometry.x + it->x;
+             ey = obj->cur.geometry.y + center_offset;
+
+             it->emoticon_item->x = ex;
+             it->emoticon_item->y = ey;
+
+             //Check the visibility
+             if (evas_object_is_in_output_rect(obj,
+                                               it->emoticon_item->x,
+                                               it->emoticon_item->y,
+                                               it->emoticon_item->w,
+                                               it->emoticon_item->h))
+               it->emoticon_item->visible = EINA_TRUE;
+             else
+               it->emoticon_item->visible = EINA_FALSE;
+          }
+     }
+}
+
+// HAVE_UNICODE_EMOTICON(2013.12.06): refactored emoticon drawing.
+static void
+_evas_object_text_emoticon_update_size(Evas_Object_Text *o, Evas_Object_Text_Item *it)
+{
+   float emoticon_size;
+   // HAVE_UNICODE_EMOTICON(20140626): Adjust emoticon ascent, descent and height.
+   float emoticon_ascent;
+   float emoticon_descent;
+   //
+   float aspect = 1;
+   int emo_w, emo_h;
+
+   if (!it->emoticon_item) return;
+
+   emoticon_size = (float)(o->cur.size) * 72 / 62;
+   // HAVE_UNICODE_EMOTICON(20140626): Adjust emoticon ascent, descent and height.
+   emoticon_ascent = (float)(o->cur.size) * 93 / 100;
+   emoticon_descent = (float)(o->cur.size) * 27 / 100;
+   it->emoticon_item->ascent = (int)emoticon_ascent;
+   if ((emoticon_ascent - it->emoticon_item->ascent) >= 0.5)
+     it->emoticon_item->ascent++;
+   it->emoticon_item->descent = (int)emoticon_descent;
+   if ((emoticon_descent - it->emoticon_item->descent) >= 0.5)
+     it->emoticon_item->descent++;
+   //
+
+   if (it->emoticon_item->img_w != 0 && it->emoticon_item->img_h != 0)
+     aspect = (float)it->emoticon_item->img_w / (float)it->emoticon_item->img_h;
+
+   emo_w = (int)emoticon_size * aspect;
+   emo_h = (int)emoticon_size;
+   it->w = emo_w;
+   // HAVE_UNICODE_EMOTICON(20140626): Adjust emoticon ascent, descent and height.
+   it->h = it->emoticon_item->ascent + it->emoticon_item->descent;
+   //
+   it->adv = emo_w;
+   it->emoticon_item->w = emo_w;
+   it->emoticon_item->h = emo_h;
+}
+
 static int
 _evas_object_text_char_coords_get(const Evas_Object *obj,
       const Evas_Object_Text *o,
@@ -114,6 +340,15 @@ _evas_object_text_char_coords_get(const Evas_Object *obj,
              int ret;
              ret = ENFN->font_char_coords_get(ENDT, o->font,
                    &it->text_props, pos - it->text_pos, x, y, w, h);
+
+             // HAVE_UNICODE_EMOTICON(2013.12.06): refactored emoticon drawing.
+             if (it->emoticon_item)
+               {
+                  *w = it->w;
+                  *h = it->h;
+               }
+             //
+
              if (x) *x += it->x;
              return ret;
           }
@@ -128,18 +363,94 @@ _evas_object_text_item_clean(Evas_Object_Text_Item *it)
 }
 
 static void
-_evas_object_text_items_clear(Evas_Object_Text *o)
+_evas_object_text_item_del(Evas_Object_Text *o, Evas_Object_Text_Item *it)
 {
-   Evas_Object_Text_Item *it;
+   if (!o || !it) return;
+   // HAVE_UNICODE_EMOTICON(2013.12.06): refactored emoticon drawing.
+   if (it->emoticon_item)
+     {
+        o->emoticons = eina_list_remove(o->emoticons, it);
+
+        if (it->emoticon_item->engine_data)
+          {
+             Evas *e = it->emoticon_item->e;
+             e->engine.func->image_free(e->engine.data.output,
+                                        it->emoticon_item->engine_data);
+          }
+        free(it->emoticon_item);
+        it->emoticon_item = NULL;
+     }
+   //
+
+   if (o->last_computed.ellipsis_start == it)
+     o->last_computed.ellipsis_start = NULL;
+   else if (o->last_computed.ellipsis_end == it)
+     o->last_computed.ellipsis_end = NULL;
+
+   if ((EINA_INLIST_GET(it)->next) ||
+       (EINA_INLIST_GET(it)->prev) ||
+       (EINA_INLIST_GET(o->items) == (EINA_INLIST_GET(it))))
+   o->items = (Evas_Object_Text_Item *) eina_inlist_remove(
+         EINA_INLIST_GET(o->items),
+         EINA_INLIST_GET(it));
+   _evas_object_text_item_clean(it);
+   free(it);
+}
 
+static void
+_evas_object_text_items_clean(Evas_Object *obj, Evas_Object_Text *o)
+{
+   /* FIXME: also preserve item */
+   if ((o->cur.font == o->prev.font) &&
+       (o->cur.fdesc == o->prev.fdesc) &&
+       (o->cur.size == o->prev.size) &&
+       (!memcmp(&o->cur.outline, &o->prev.outline, sizeof (o->cur.outline))) &&
+       (!memcmp(&o->cur.shadow, &o->prev.shadow, sizeof (o->cur.shadow))) &&
+       (!memcmp(&o->cur.glow, &o->prev.glow, sizeof (o->cur.glow))) &&
+       (!memcmp(&o->cur.glow2, &o->prev.glow2, sizeof (o->cur.glow2))) &&
+       (o->cur.style == o->prev.style) &&
+       (obj->cur.scale == obj->prev.scale))
+     {
+        if ((o->last_computed.ellipsis_start) &&
+            (o->last_computed.ellipsis_start == o->items))
+          o->items = (Evas_Object_Text_Item *) eina_inlist_remove(EINA_INLIST_GET(o->items),
+                                                                  EINA_INLIST_GET(o->last_computed.ellipsis_start));
+        if ((o->last_computed.ellipsis_end) &&
+            (EINA_INLIST_GET(o->last_computed.ellipsis_end) == EINA_INLIST_GET(o->items)->last))
+          o->items = (Evas_Object_Text_Item *) eina_inlist_remove(EINA_INLIST_GET(o->items),
+                                                                  EINA_INLIST_GET(o->last_computed.ellipsis_end));
+     }
+   else
+     {
+        _evas_object_text_item_del(o, o->last_computed.ellipsis_start);
+        o->last_computed.ellipsis_start = NULL;
+        _evas_object_text_item_del(o, o->last_computed.ellipsis_end);
+        o->last_computed.ellipsis_end = NULL;
+     }
    while (o->items)
      {
-        it = o->items;
-        o->items = (Evas_Object_Text_Item *) eina_inlist_remove(
-              EINA_INLIST_GET(o->items),
-              EINA_INLIST_GET(it));
-        _evas_object_text_item_clean(it);
-        free(it);
+        _evas_object_text_item_del(o, o->items);
+     }
+}
+
+static void
+_evas_object_text_items_clear(Evas_Object_Text *o)
+{
+   if ((o->last_computed.ellipsis_start) &&
+       (o->last_computed.ellipsis_start != o->items))
+     {
+        _evas_object_text_item_del(o, o->last_computed.ellipsis_start);
+     }
+   o->last_computed.ellipsis_start = NULL;
+   if ((o->last_computed.ellipsis_end) &&
+       (EINA_INLIST_GET(o->last_computed.ellipsis_end) != EINA_INLIST_GET(o->items)->last))
+     {
+        _evas_object_text_item_del(o, o->last_computed.ellipsis_end);
+     }
+   o->last_computed.ellipsis_end = NULL;
+   while (o->items)
+     {
+        _evas_object_text_item_del(o, o->items);
      }
 }
 
@@ -222,6 +533,11 @@ _evas_object_text_char_at_coords(const Evas_Object *obj,
      {
         if ((it->x <= cx) && (cx < it->x + it->adv))
           {
+             // HAVE_UNICODE_EMOTICON(2013.12.06): refactored emoticon drawing.
+             if (it->emoticon_item)
+               return it->text_pos;
+             //
+
              return it->text_pos + ENFN->font_char_at_coords_get(ENDT,
                    o->font,
                    &it->text_props,
@@ -235,23 +551,9 @@ _evas_object_text_char_at_coords(const Evas_Object *obj,
 }
 
 static Evas_Coord
-_evas_object_text_horiz_advance_get(const Evas_Object *obj,
-      const Evas_Object_Text *o)
+_evas_object_text_horiz_advance_get(const Evas_Object_Text *o)
 {
-   Evas_Object_Text_Item *it, *last_it = NULL;
-   Evas_Coord adv;
-   (void) obj;
-
-   adv = 0;
-   EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
-     {
-        adv += it->adv;
-        last_it = it;
-     }
-
-   if (last_it && (last_it->w > last_it->adv))
-      adv += last_it->w - last_it->adv;
-   return adv;
+   return o->last_computed.advance;
 }
 
 static Evas_Coord
@@ -320,6 +622,7 @@ evas_object_text_font_set(Evas_Object *obj, const char *font, Evas_Font_Size siz
    Evas_Object_Text *o;
    int is, was = 0, pass = 0, freeze = 0;
    Evas_Font_Description *fdesc;
+   Eina_Bool source_invisible = EINA_FALSE;
 
    if ((!font) || (size <= 0)) return;
    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
@@ -330,10 +633,18 @@ evas_object_text_font_set(Evas_Object *obj, const char *font, Evas_Font_Size siz
    return;
    MAGIC_CHECK_END();
 
-   fdesc = evas_font_desc_new();
-   evas_font_name_parse(fdesc, font);
+   if (!(o->cur.font && !strcmp(font, o->cur.font)))
+     {
+        fdesc = evas_font_desc_new();
+        evas_font_name_parse(fdesc, font);
+     }
+   else
+     {
+        fdesc = evas_font_desc_ref(o->cur.fdesc);
+     }
+
    if (o->cur.fdesc && !evas_font_desc_cmp(fdesc, o->cur.fdesc) &&
-         (size == o->cur.size))
+       (size == o->cur.size))
      {
         evas_font_desc_unref(fdesc);
         return;
@@ -350,7 +661,8 @@ evas_object_text_font_set(Evas_Object *obj, const char *font, Evas_Font_Size siz
      {
         pass = evas_event_passes_through(obj);
         freeze = evas_event_freezes_through(obj);
-        if ((!pass) && (!freeze))
+        source_invisible = evas_object_is_source_invisible(obj);
+        if ((!pass) && (!freeze) && (!source_invisible))
           was = evas_object_is_in_output_rect(obj,
                                               obj->layer->evas->pointer.x,
                                               obj->layer->evas->pointer.y, 1, 1);
@@ -379,8 +691,9 @@ evas_object_text_font_set(Evas_Object *obj, const char *font, Evas_Font_Size siz
         o->max_ascent = 0;
         o->max_descent = 0;
      }
-   _evas_object_text_recalc(obj);
+   _evas_object_text_recalc(obj, o->cur.text);
    o->changed = 1;
+   o->cur.filter.changed = EINA_TRUE;
    evas_object_change(obj);
    evas_object_clip_dirty(obj);
    evas_object_coords_recalc(obj);
@@ -423,6 +736,16 @@ evas_object_text_font_get(const Evas_Object *obj, const char **font, Evas_Font_S
    if (size) *size = o->cur.size;
 }
 
+static void
+_evas_object_text_item_update_sizes(Evas_Object *obj, Evas_Object_Text *o, Evas_Object_Text_Item *it)
+{
+   ENFN->font_string_size_get(ENDT,
+         o->font,
+         &it->text_props,
+         &it->w, &it->h);
+   it->adv = ENFN->font_h_advance_get(ENDT, o->font,
+         &it->text_props);
+}
 
 /**
  * @internal
@@ -451,13 +774,7 @@ _evas_object_text_item_new(Evas_Object *obj, Evas_Object_Text *o,
         ENFN->font_text_props_info_create(ENDT,
               fi, str + pos, &it->text_props,
               o->bidi_par_props, it->text_pos, len, EVAS_TEXT_PROPS_MODE_SHAPE);
-
-        ENFN->font_string_size_get(ENDT,
-              o->font,
-              &it->text_props,
-              &it->w, &it->h);
-        it->adv = ENFN->font_h_advance_get(ENDT, o->font,
-              &it->text_props);
+        _evas_object_text_item_update_sizes(obj, o, it);
      }
    o->items = (Evas_Object_Text_Item *)
       eina_inlist_append(EINA_INLIST_GET(o->items), EINA_INLIST_GET(it));
@@ -518,6 +835,62 @@ _evas_object_text_item_order(Evas_Object *obj, Evas_Object_Text *o)
 }
 
 /**
+ * Create ellipsis.
+ */
+static const Eina_Unicode _ellip_str[2] = { 0x2026, '\0' };
+
+/* FIXME: We currently leak ellipsis items. */
+static Evas_Object_Text_Item *
+_layout_ellipsis_item_new(Evas_Object *obj, Evas_Object_Text *o)
+{
+   Evas_Object_Text_Item *ellip_ti = NULL;
+   Evas_Script_Type script;
+   Evas_Font_Instance *script_fi = NULL, *cur_fi = NULL;
+   size_t len = 1; /* The length of _ellip_str */
+
+   script = evas_common_language_script_type_get(_ellip_str, 1);
+
+   if (o->font)
+     {
+        (void) ENFN->font_run_end_get(ENDT, o->font, &script_fi, &cur_fi,
+                                      script, _ellip_str, 1);
+        ellip_ti = _evas_object_text_item_new(obj, o, cur_fi,
+                                              _ellip_str, script, 0, 0, len);
+     }
+
+   return ellip_ti;
+}
+
+/* EINA_TRUE if this item is ok and should be included, false if should be
+ * discarded. */
+static Eina_Bool
+_layout_text_item_trim(Evas_Object *obj, Evas_Object_Text *o, Evas_Object_Text_Item *ti, int idx, Eina_Bool want_start)
+{
+   Evas_Text_Props new_text_props;
+   if (idx >= (int) ti->text_props.text_len)
+      return EINA_FALSE;
+
+   memset(&new_text_props, 0, sizeof (new_text_props));
+
+   while (!evas_common_text_props_split(&ti->text_props, &new_text_props, idx))
+     idx--;
+   if (want_start)
+     {
+        evas_common_text_props_content_unref(&new_text_props);
+     }
+   else
+     {
+        evas_common_text_props_content_unref(&ti->text_props);
+        memcpy(&ti->text_props, &new_text_props, sizeof(ti->text_props));
+        ti->text_pos += idx;
+        ti->visual_pos += idx;
+     }
+   _evas_object_text_item_update_sizes(obj, o, ti);
+
+   return EINA_TRUE;
+}
+
+/**
  * @internal
  * Populates o->items with the items of the text according to text
  *
@@ -526,14 +899,30 @@ _evas_object_text_item_order(Evas_Object *obj, Evas_Object_Text *o)
  * @param text the text to layout
  */
 static void
-_evas_object_text_layout(Evas_Object *obj, Evas_Object_Text *o, const Eina_Unicode *text)
+_evas_object_text_layout(Evas_Object *obj, Evas_Object_Text *o, Eina_Unicode *text)
 {
    EvasBiDiStrIndex *v_to_l = NULL;
+   Evas_Coord advance = 0;
    size_t pos, visual_pos;
    int len = eina_unicode_strlen(text);
+   int l = 0, r = 0;
 #ifdef BIDI_SUPPORT
    int par_len = len;
    int *segment_idxs = NULL;
+#endif
+
+   if (o->items &&
+       !memcmp(&o->cur, &o->prev, sizeof (o->cur)) &&
+       o->cur.text == text &&
+       obj->cur.scale == obj->prev.scale &&
+       ((o->last_computed.advance <= obj->cur.geometry.w && !o->last_computed.ellipsis) ||
+        o->last_computed.w == obj->cur.geometry.w))
+     return ;
+
+   o->last_computed.ellipsis = EINA_FALSE;
+   if (o->items) _evas_object_text_items_clean(obj, o);
+
+#ifdef BIDI_SUPPORT
    if (o->bidi_delimiters)
       segment_idxs = evas_bidi_segment_idxs_get(text, o->bidi_delimiters);
    evas_bidi_paragraph_props_unref(o->bidi_par_props);
@@ -555,10 +944,11 @@ _evas_object_text_layout(Evas_Object *obj, Evas_Object_Text *o, const Eina_Unico
         if (tmp_cut > 0)
            script_len = tmp_cut;
 
-        script = evas_common_language_script_type_get(text, script_len);
+        script = evas_common_language_script_type_get(text + pos, script_len);
 
         while (script_len > 0)
           {
+             Evas_Object_Text_Item *it;
              Evas_Font_Instance *cur_fi = NULL;
              int run_len = script_len;
              if (o->font)
@@ -573,20 +963,254 @@ _evas_object_text_layout(Evas_Object *obj, Evas_Object_Text *o, const Eina_Unico
 #else
              visual_pos = pos;
 #endif
-             _evas_object_text_item_new(obj, o, cur_fi, text, script,
-                   pos, visual_pos, run_len);
+             it = _evas_object_text_item_new(obj, o, cur_fi, text, script,
+                                             pos, visual_pos, run_len);
+
+             // HAVE_UNICODE_EMOTICON(2013.12.06): refactored emoticon drawing.
+             UNICODE_EMOTICON_CHECK(*(text + pos))
+               {
+                  it->emoticon_item = _text_emoticon_img_new(obj->layer->evas, obj, *(text+pos));
+                  if (it->emoticon_item)
+                    {
+                       it->emoticon_item->e = obj->layer->evas;
+                       o->emoticons = eina_list_append(o->emoticons, it);
+                       _evas_object_text_emoticon_update_size(o, it);
+                    }
+               }
+             //
 
+             advance += it->adv;
              pos += run_len;
              script_len -= run_len;
              len -= run_len;
           }
      }
 
+   if (!o->cur.filter.chain)
+     evas_text_style_pad_get(o->cur.style, &l, &r, NULL, NULL);
+   else
+     evas_filter_program_padding_get(o->cur.filter.chain, &l, &r, NULL, NULL);
+
+   /* Handle ellipsis */
+  if (pos && (o->cur.ellipsis >= 0.0) && (advance + l + r > obj->cur.geometry.w) && (obj->cur.geometry.w > 0))
+     {
+        Evas_Coord ellip_frame = obj->cur.geometry.w;
+        Evas_Object_Text_Item *start_ellip_it = NULL, *end_ellip_it = NULL;
+
+        o->last_computed.ellipsis = EINA_TRUE;
+
+        /* Account of the ellipsis item width. As long as ellipsis != 0
+         * we have a left ellipsis. And the same with 1 and right. */
+        if (o->cur.ellipsis != 0)
+          {
+             if (o->last_computed.ellipsis_start)
+               {
+                  start_ellip_it = o->last_computed.ellipsis_start;
+                  o->items = (Evas_Object_Text_Item *)
+                    eina_inlist_append(EINA_INLIST_GET(o->items), EINA_INLIST_GET(start_ellip_it));
+               }
+             else
+               {
+                  start_ellip_it = _layout_ellipsis_item_new(obj, o);
+               }
+             o->last_computed.ellipsis_start = start_ellip_it;
+             ellip_frame -= start_ellip_it->adv;
+          }
+        if (o->cur.ellipsis != 1)
+          {
+             /* FIXME: Should take the last item's font and style and etc. *//* weird it's a text, should always have the same style/font */
+             if (o->last_computed.ellipsis_end)
+               {
+                  end_ellip_it = o->last_computed.ellipsis_end;
+                  o->items = (Evas_Object_Text_Item *)
+                    eina_inlist_append(EINA_INLIST_GET(o->items), EINA_INLIST_GET(end_ellip_it));
+               }
+             else
+               {
+                  end_ellip_it = _layout_ellipsis_item_new(obj, o);
+               }
+             o->last_computed.ellipsis_end = end_ellip_it;
+             ellip_frame -= end_ellip_it->adv;
+          }
+
+        /* The point where we should start from, going for the full
+         * ellip frame. */
+        Evas_Coord ellipsis_coord = o->cur.ellipsis * (advance - ellip_frame);
+        if (start_ellip_it)
+          {
+             Evas_Object_Text_Item *itr = o->items;
+             advance = 0;
+
+             while (itr && (advance + l + r + itr->adv < ellipsis_coord))
+               {
+                  Eina_Inlist *itrn = EINA_INLIST_GET(itr)->next;
+                  if ((itr != start_ellip_it) && (itr != end_ellip_it))
+                    {
+                       advance += itr->adv;
+                       _evas_object_text_item_del(o, itr);
+                    }
+                  itr = (Evas_Object_Text_Item *) itrn;
+               }
+             if (itr && (itr != start_ellip_it))
+               {
+                  int cut = 1 + ENFN->font_last_up_to_pos(ENDT,
+                        o->font,
+                        &itr->text_props,
+                        ellipsis_coord - (advance + l + r),
+                        0);
+                  if (cut > 0)
+                    {
+                       start_ellip_it->text_pos = itr->text_pos;
+                       start_ellip_it->visual_pos = itr->visual_pos;
+                       if (!_layout_text_item_trim(obj, o, itr, cut, EINA_FALSE))
+                         {
+                            _evas_object_text_item_del(o, itr);
+                         }
+                    }
+               }
+
+            o->items = (Evas_Object_Text_Item *) eina_inlist_remove(EINA_INLIST_GET(o->items), EINA_INLIST_GET(start_ellip_it));
+             o->items = (Evas_Object_Text_Item *) eina_inlist_prepend(EINA_INLIST_GET(o->items), EINA_INLIST_GET(start_ellip_it));
+          }
+
+        if (end_ellip_it)
+          {
+             Evas_Object_Text_Item *itr = o->items;
+             int idx = 0;
+             advance = 0;
+
+             while (itr)
+               {
+                  if (itr != end_ellip_it) /* was start_ellip_it */
+                    {
+                       if (advance + l + r + itr->adv >= ellip_frame)
+                         {
+                            break;
+                         }
+                       advance += itr->adv;
+                    }
+                  idx++;
+                  itr = (Evas_Object_Text_Item *) EINA_INLIST_GET(itr)->next;
+               }
+
+             if (itr == end_ellip_it)
+               {
+                  /* FIXME: We shouldn't do anything. */
+               }
+
+             int cut = ENFN->font_last_up_to_pos(ENDT,
+                   o->font,
+                   &itr->text_props,
+                   ellip_frame - (advance + l + r),
+                   0);
+
+             if (cut >= 0)
+               {
+                  end_ellip_it->text_pos = itr->text_pos + cut;
+                  end_ellip_it->visual_pos = itr->visual_pos + cut;
+                  // HAVE_UNICODE_EMOTICON(2013.12.06): refactored emoticon drawing.
+                  if (itr->emoticon_item)
+                    {
+                       o->emoticons = eina_list_remove(o->emoticons, itr);
+
+                       if (itr->emoticon_item->engine_data)
+                         {
+                            Evas *e = obj->layer->evas;
+                            e->engine.func->image_free(e->engine.data.output,
+                                                       itr->emoticon_item->engine_data);
+                         }
+                       free(itr->emoticon_item);
+                       itr->emoticon_item = NULL;
+                    }
+                  //
+                  if (_layout_text_item_trim(obj, o, itr, cut, EINA_TRUE))
+                    {
+                       itr = (Evas_Object_Text_Item *) EINA_INLIST_GET(itr)->next;
+                    }
+               }
+
+             /* Remove the rest of the items */
+             while (itr)
+               {
+                  Eina_Inlist *itrn = EINA_INLIST_GET(itr)->next;
+                  if ((itr != start_ellip_it) && (itr != end_ellip_it))
+                     _evas_object_text_item_del(o, itr);
+                  itr = (Evas_Object_Text_Item *) itrn;
+               }
+          }
+     }
+   if (o->cur.text != text) free(o->cur.text);
+   o->cur.text = text;
+   o->prev = o->cur;
+
+   {
+      Evas_Object_Text_Item *itr = o->items;
+      advance = 0;
+
+      while (itr)
+        {
+           advance += itr->adv;
+           itr = (Evas_Object_Text_Item *) EINA_INLIST_GET(itr)->next;
+        }
+      o->last_computed.advance = advance;
+   }
+
    _evas_object_text_item_order(obj, o);
 
+   // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+   _evas_object_text_emoticon_update_geometry(obj);
+   //
+
    if (v_to_l) free(v_to_l);
 }
 
+static void
+_text_resize(void *data,
+             Evas *e EINA_UNUSED,
+             Evas_Object *obj,
+             void *event_info EINA_UNUSED)
+{
+   Evas_Object_Text *o = data;
+
+   _evas_object_text_recalc(obj, o->cur.text);
+}
+
+EAPI void
+evas_object_text_ellipsis_set(Evas_Object *obj, double ellipsis)
+{
+   Evas_Object_Text *o;
+
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return;
+   MAGIC_CHECK_END();
+   o = (Evas_Object_Text *)(obj->object_data);
+   MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
+   return;
+   MAGIC_CHECK_END();
+
+   if (o->cur.ellipsis == ellipsis) return ;
+
+   o->cur.ellipsis = ellipsis;
+   o->changed = 1;
+   evas_object_change(obj);
+   evas_object_clip_dirty(obj);
+}
+
+EAPI double
+evas_object_text_ellipsis_get(const Evas_Object *obj)
+{
+   Evas_Object_Text *o;
+
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return -1;
+   MAGIC_CHECK_END();
+   o = (Evas_Object_Text *)(obj->object_data);
+   MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
+   return -1;
+   MAGIC_CHECK_END();
+
+   return o->cur.ellipsis;
+}
 
 EAPI void
 evas_object_text_text_set(Evas_Object *obj, const char *_text)
@@ -594,7 +1218,7 @@ evas_object_text_text_set(Evas_Object *obj, const char *_text)
    Evas_Object_Text *o;
    int is, was, len;
    Eina_Unicode *text;
-   
+
    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
    return;
    MAGIC_CHECK_END();
@@ -616,23 +1240,14 @@ evas_object_text_text_set(Evas_Object *obj, const char *_text)
 
    if (o->items) _evas_object_text_items_clear(o);
 
-   if ((text) && (*text)) 
-     {
-        _evas_object_text_layout(obj, o, text);
-       eina_stringshare_replace(&o->cur.utf8_text, _text);
-        o->prev.utf8_text = NULL;
-    }
-   else 
-     {
-       eina_stringshare_replace(&o->cur.utf8_text, NULL);
-     }
-   if (text)
-     {
-        free(text);
-        text = NULL;
-     }
-   _evas_object_text_recalc(obj);
+   _evas_object_text_recalc(obj, text);
+   eina_stringshare_replace(&o->cur.utf8_text, _text);
+   o->prev.utf8_text = NULL;
+
+   if (o->cur.text != text) free(text);
+
    o->changed = 1;
+   o->cur.filter.changed = EINA_TRUE;
    evas_object_change(obj);
    evas_object_clip_dirty(obj);
    evas_object_coords_recalc(obj);
@@ -646,7 +1261,6 @@ evas_object_text_text_set(Evas_Object *obj, const char *_text)
                                obj->layer->evas->last_timestamp,
                                NULL);
    evas_object_inform_call_resize(obj);
-   if (text) free(text);
 }
 
 EAPI void
@@ -709,10 +1323,25 @@ evas_object_text_direction_get(const Evas_Object *obj)
    MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
    return EVAS_BIDI_DIRECTION_NEUTRAL;
    MAGIC_CHECK_END();
+   // TIZEN_ONLY(20140822): Added evas_bidi_direction_hint_set, get APIs and applied to textblock, text.
+   /*
    if (o->items)
      {
         return o->items->text_props.bidi.dir;
      }
+   */
+   if (o->bidi_par_props)
+     {
+        Evas_BiDi_Direction dir = evas_bidi_direction_hint_get(evas_object_evas_get(obj));
+
+        if (!EVAS_BIDI_PARAGRAPH_DIRECTION_IS_NEUTRAL(o->bidi_par_props))
+          {
+             dir = EVAS_BIDI_PARAGRAPH_DIRECTION_IS_RTL(o->bidi_par_props) ?
+                EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR;
+          }
+        return dir;
+     }
+   //////////
    return EVAS_BIDI_DIRECTION_NEUTRAL;
 }
 
@@ -807,7 +1436,7 @@ evas_object_text_horiz_advance_get(const Evas_Object *obj)
    MAGIC_CHECK_END();
    if (!o->font) return 0;
    if (!o->items) return 0;
-   return _evas_object_text_horiz_advance_get(obj, o);
+   return _evas_object_text_horiz_advance_get(o);
 }
 
 EAPI Evas_Coord
@@ -845,7 +1474,10 @@ evas_object_text_char_pos_get(const Evas_Object *obj, int pos, Evas_Coord *cx, E
    if (!o->items || (pos < 0)) return EINA_FALSE;
    ret = _evas_object_text_char_coords_get(obj, o, (size_t) pos,
             &x, &y, &w, &h);
-   evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
+   if (!o->cur.filter.chain)
+     evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
+   else
+     evas_filter_program_padding_get(o->cur.filter.chain, &l, &r, &t, &b);
    y += o->max_ascent - t;
    x -= l;
    if (x < 0)
@@ -905,7 +1537,10 @@ evas_object_text_char_coords_get(const Evas_Object *obj, Evas_Coord x, Evas_Coor
    if (!o->items) return -1;
    ret = _evas_object_text_char_at_coords(obj, o, x, y - o->max_ascent,
          &rx, &ry, &rw, &rh);
-   evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
+   if (!o->cur.filter.chain)
+     evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
+   else
+     evas_filter_program_padding_get(o->cur.filter.chain, &l, &r, &t, &b);
    ry += o->max_ascent - t;
    rx -= l;
    if (rx < 0)
@@ -1188,7 +1823,10 @@ evas_object_text_style_pad_get(const Evas_Object *obj, int *l, int *r, int *t, i
    return;
    MAGIC_CHECK_END();
    /* use temps to be certain we have initialized values */
-   evas_text_style_pad_get(o->cur.style, &sl, &sr, &st, &sb);
+   if (!o->cur.filter.chain)
+     evas_text_style_pad_get(o->cur.style, &sl, &sr, &st, &sb);
+   else
+     evas_filter_program_padding_get(o->cur.filter.chain, &sl, &sr, &st, &sb);
    if (l) *l = sl;
    if (r) *r = sr;
    if (t) *t = st;
@@ -1203,8 +1841,11 @@ evas_string_char_next_get(const char *str, int pos, int *decoded)
 {
    int p, d;
 
-   if (decoded) *decoded = 0;
-   if ((!str) || (pos < 0)) return 0;
+   if ((!str) || (pos < 0))
+     {
+        if (decoded) *decoded = 0;
+        return 0;
+     }
    p = pos;
    d = eina_unicode_utf8_get_next(str, &p);
    if (decoded) *decoded = d;
@@ -1279,6 +1920,12 @@ evas_text_style_pad_get(Evas_Text_Style_Type style, int *l, int *r, int *t, int
            case EVAS_TEXT_STYLE_OUTLINE:
               out_sz = 1;
               break;
+          case EVAS_TEXT_STYLE_TIZEN_GLOW_SHADOW:
+           case EVAS_TEXT_STYLE_TIZEN_SOFT_GLOW_SHADOW:
+           case EVAS_TEXT_STYLE_TIZEN_SHADOW:
+              out_sz = 1;
+              break;
+
            default:
               break;
           }
@@ -1379,6 +2026,8 @@ evas_object_text_init(Evas_Object *obj)
    /* set up methods (compulsory) */
    obj->func = &object_func;
    obj->type = o_type;
+
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _text_resize, obj->object_data);
 }
 
 static void *
@@ -1392,6 +2041,7 @@ evas_object_text_new(void)
    if (!o) return NULL;
    EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Text);
    o->magic = MAGIC_OBJ_TEXT;
+   o->cur.ellipsis = -1.0;
    o->prev = o->cur;
 #ifdef BIDI_SUPPORT
    o->bidi_par_props = evas_bidi_paragraph_props_new();
@@ -1409,12 +2059,30 @@ evas_object_text_free(Evas_Object *obj)
    MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
    return;
    MAGIC_CHECK_END();
+
+
+   /* free filter output */
+   if (o->cur.filter.output)
+     ENFN->image_free(ENDT, o->cur.filter.output);
+   eina_hash_free(o->cur.filter.sources);
+   evas_filter_program_del(o->cur.filter.chain);
+   eina_stringshare_del(o->cur.filter.code);
+   o->cur.filter.output = NULL;
+   o->cur.filter.chain = NULL;
+   o->cur.filter.sources = NULL;
+   o->cur.filter.code = NULL;
+   o->cur.filter.sources_count = 0;
+
    /* free obj */
-   if (o->items) _evas_object_text_items_clear(o);
+   _evas_object_text_items_clear(o);
+   // HAVE_UNICODE_EMOTICON(2013.12.06): Refactoring draw.
+   o->emoticons = eina_list_free(o->emoticons);
+   //
    if (o->cur.utf8_text) eina_stringshare_del(o->cur.utf8_text);
    if (o->cur.font) eina_stringshare_del(o->cur.font);
    if (o->cur.fdesc) evas_font_desc_unref(o->cur.fdesc);
    if (o->cur.source) eina_stringshare_del(o->cur.source);
+   if (o->cur.text) free(o->cur.text);
    if (o->font) evas_font_free(obj->layer->evas, o->font);
 #ifdef BIDI_SUPPORT
    evas_bidi_paragraph_props_unref(o->bidi_par_props);
@@ -1423,6 +2091,64 @@ evas_object_text_free(Evas_Object *obj)
    EVAS_MEMPOOL_FREE(_mp_obj, o);
 }
 
+///////////////////// TIZEN ONLY (20131106) : Font effect for tizen. /////////////////////
+static int __attribute__((optimize("O0")))
+evas_object_text_effect_outerglow_alpha_get(int x, int y, double opacity, int size)
+{
+   const float SPREAD_COEFF = 1.12f;
+   double sizeD = (double)size;
+   int alpha;
+   double intensity = sqrt((x * x) + (y * y));
+   intensity = (sizeD * SPREAD_COEFF - intensity) / sizeD;
+   if (intensity > 0.0)
+     {
+        intensity = (intensity >= 1.0) ? 1.0 : intensity;
+       intensity = sin(intensity * 3.141592 / 2.0);
+        alpha = (int)((255.0 * opacity) * intensity + 0.5);
+        return alpha;
+     }
+   else
+     return 0;
+}
+
+static int __attribute__((optimize("O0")))
+evas_object_text_effect_soft_outerglow_alpha_get(int x, int y, double opacity, int size)    //
+{
+   const float SPREAD_COEFF = 1.50f;
+   double sizeD = (double)size + 0.3;
+   int alpha;
+   double intensity = sqrt((x * x) + (y * y));
+   intensity = (sizeD * SPREAD_COEFF - intensity) / sizeD;
+   if (intensity > 0.0)
+     {
+        intensity = (intensity >= 1.0) ? 1.0 : intensity;
+        intensity = sin(intensity * 3.141592 / 2.0);
+        alpha =(int)((255.0 * opacity) * intensity + 0.5);
+        return alpha;
+     }
+   else
+     return 0;
+}
+
+static int __attribute__((optimize("O0")))
+evas_object_text_effect_shadow_alpha_get(int x, int y, double opacity, int softness)
+{
+   int alpha;
+   double softnessD = (double)softness;
+   double intensity = sqrt((x * x) + (y * y));
+   intensity = (softnessD - intensity) / softnessD;
+   if (intensity > 0.0)
+     {
+        intensity = sin((intensity * 3.141592) / 2.0);
+        intensity *= intensity;
+        alpha =((255.0 * opacity) * intensity + 0.5) / (softnessD * 2);
+        return alpha;
+     }
+   else
+     return 0;
+}
+//////////////////////////////////////////////////////////////////////////////////////////
+
 static void
 evas_object_text_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
 {
@@ -1442,7 +2168,10 @@ evas_object_text_render(Evas_Object *obj, void *output, void *context, void *sur
 
    /* render object to surface with context, and offxet by x,y */
    o = (Evas_Object_Text *)(obj->object_data);
-   evas_text_style_pad_get(o->cur.style, &sl, NULL, &st, NULL);
+   if (!o->cur.filter.chain)
+     evas_text_style_pad_get(o->cur.style, &sl, NULL, &st, NULL);
+   else
+     evas_filter_program_padding_get(o->cur.filter.chain, &sl, NULL, &st, NULL);
    ENFN->context_multiplier_unset(output, context);
    ENFN->context_render_op_set(output, context, obj->cur.render_op);
    /* FIXME: This clipping is just until we fix inset handling correctly. */
@@ -1514,6 +2243,156 @@ evas_object_text_render(Evas_Object *obj, void *output, void *context, void *sur
                     obj->cur.geometry.h, \
                     &it->text_props);
 
+   /* FIXME/WARNING
+    * The code below is EXPERIMENTAL, and not to be considered usable or even
+    * remotely similar to its final form. You've been warned :)
+    */
+
+   if (!o->cur.filter.invalid && (o->cur.filter.chain || o->cur.filter.code))
+     {
+        int X, Y, W, H;
+        Evas_Filter_Context *filter;
+        const int inbuf = 1;
+        const int outbuf = 2;
+        void *filter_ctx;
+        Eina_Bool ok;
+        int ox = 0, oy = 0;
+        Image_Entry *previous = o->cur.filter.output;
+        const Eina_Bool do_async = EINA_FALSE;
+
+        /* NOTE: Font effect rendering is now done ENTIRELY on CPU.
+         * So we rely on cache/cache2 to allocate a real image buffer,
+         * that we can draw to. The OpenGL texture will be created only
+         * after the rendering has been done, as we simply push the output
+         * image to GL.
+         */
+
+        W = obj->cur.geometry.w;
+        H = obj->cur.geometry.h;
+        X = obj->cur.geometry.x;
+        Y = obj->cur.geometry.y;
+
+        // Prepare color multiplier
+        ENFN->context_color_set(ENDT, context, 255, 255, 255, 255);
+        if ((obj->cur.cache.clip.r == 255) && (obj->cur.cache.clip.g == 255) &&
+            (obj->cur.cache.clip.b == 255) && (obj->cur.cache.clip.a == 255))
+          ENFN->context_multiplier_unset(ENDT, context);
+        else
+          ENFN->context_multiplier_set(ENDT, context,
+                                       obj->cur.cache.clip.r,
+                                       obj->cur.cache.clip.g,
+                                       obj->cur.cache.clip.b,
+                                       obj->cur.cache.clip.a);
+
+        if (!o->cur.filter.chain)
+          {
+             Evas_Filter_Program *pgm;
+             pgm = evas_filter_program_new("Evas_Text");
+             evas_filter_program_source_set_all(pgm, o->cur.filter.sources);
+             if (!evas_filter_program_parse(pgm, o->cur.filter.code))
+               {
+                  ERR("Filter program parsing failed");
+                  evas_filter_program_del(pgm);
+                  o->cur.filter.invalid = EINA_TRUE;
+                  goto normal_render;
+               }
+             o->cur.filter.chain = pgm;
+             o->cur.filter.invalid = EINA_FALSE;
+          }
+        else if (previous)
+          {
+             Eina_Bool redraw = o->cur.filter.changed;
+
+             // Scan proxies to find if any changed
+             if (!redraw && o->cur.filter.sources)
+               {
+                  Evas_Filter_Proxy_Binding *pb;
+                  Eina_Iterator *iter;
+
+                  iter = eina_hash_iterator_data_new(o->cur.filter.sources);
+                  EINA_ITERATOR_FOREACH(iter, pb)
+                    {
+                       if (pb->eo_source->changed)
+                         {
+                            redraw = EINA_TRUE;
+                            break;
+                         }
+                    }
+                  eina_iterator_free(iter);
+               }
+
+             if (!redraw)
+               {
+                  // Render this image only
+                  ENFN->image_draw(ENDT, context,
+                                   surface, previous,
+                                   0, 0, W, H,         // src
+                                   X + x, Y + y, W, H, // dst
+                                   EINA_FALSE);
+                  return;
+               }
+          }
+
+        filter = evas_filter_context_new(obj->layer->evas, do_async);
+        ok = evas_filter_context_program_use(filter, o->cur.filter.chain);
+        if (!filter || !ok)
+          {
+             ERR("Parsing failed?");
+             evas_filter_context_destroy(filter);
+             goto normal_render;
+          }
+
+        // Proxies
+        evas_filter_context_proxy_render_all(filter, obj, EINA_FALSE);
+
+        // Draw Context
+        filter_ctx = ENFN->context_new(ENDT);
+        ENFN->context_color_set(ENDT, filter_ctx, 255, 255, 255, 255);
+
+        // Allocate all buffers now
+        evas_filter_context_buffers_allocate_all(filter, W, H);
+        evas_filter_target_set(filter, context, surface, X + x, Y + y);
+
+        // Steal output and release previous
+        o->cur.filter.output = evas_filter_buffer_backing_steal(filter, outbuf);
+        if (o->cur.filter.output != previous)
+          evas_filter_buffer_backing_release(filter, previous);
+
+        // Render text to input buffer
+        EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
+          if ((o->font) && (it->text_props.len > 0))
+            {
+               evas_filter_font_draw(filter, filter_ctx, inbuf, o->font,
+                                     sl + ox + it->x,
+                                     st + oy + (int) o->max_ascent,
+                                     &it->text_props,
+                                     do_async);
+            }
+
+        ENFN->context_free(ENDT, filter_ctx);
+
+        // Add post-run callback and run filter
+        evas_filter_context_autodestroy(filter);
+        ok = evas_filter_run(filter);
+        o->cur.filter.changed = EINA_FALSE;
+
+        if (ok)
+          {
+             DBG("Effect rendering done.");
+             return;
+          }
+        else
+          {
+             ERR("Rendering failed");
+             o->cur.filter.invalid = EINA_TRUE;
+             goto normal_render;
+          }
+     }
+
+   /* End of the EXPERIMENTAL code */
+
+normal_render:
+
    /* shadows */
    shad_dst = shad_sz = dx = dy = haveshad = 0;
    switch (o->cur.style & EVAS_TEXT_STYLE_MASK_BASIC)
@@ -1587,6 +2466,11 @@ evas_object_text_render(Evas_Object *obj, void *output, void *context, void *sur
      }
    EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
      {
+        // HAVE_UNICODE_EMOTICON(2013.12.06): refactored emoticon drawing.
+        if (it->emoticon_item)
+          continue;
+        //
+
         /* Shadows */
         if (haveshad)
           {
@@ -1661,25 +2545,110 @@ evas_object_text_render(Evas_Object *obj, void *output, void *context, void *sur
                }
           }
 
+        // TIZEN ONLY (20131106) : Font effect for tizen.
+        if ((o->cur.style == EVAS_TEXT_STYLE_TIZEN_GLOW_SHADOW) ||
+            (o->cur.style == EVAS_TEXT_STYLE_TIZEN_SOFT_GLOW_SHADOW) ||
+            (o->cur.style == EVAS_TEXT_STYLE_TIZEN_SHADOW))
+          {
+
+             if (o->cur.style == EVAS_TEXT_STYLE_TIZEN_GLOW_SHADOW) // HOME_SCREEN_ICON
+               {
+                  int size = 2;
+                  int softness = 3;
+
+                  for (j = -size; j <= size; j++)
+                    {
+                       for (i = -size; i <= size; i++)
+                         {
+                            int alpha = evas_object_text_effect_outerglow_alpha_get(i, j, 0.30, size); // OutGlow2
+                            if (alpha == 0) continue;
+                            COLOR_SET_AMUL(o, cur, glow, alpha);
+                            DRAW_TEXT(j, i);
+                         }
+                    }
+                  for (j = -softness; j <= softness; j++)
+                    {
+                       for (i = -softness; i <= softness; i++)
+                         {
+                            if ((i != 0) && (j != 0))
+                              {
+                                 int alpha = evas_object_text_effect_shadow_alpha_get(i, j, 0.80, softness); // DropShadow
+                                 if (alpha == 0) continue;
+                                 COLOR_SET_AMUL(o, cur, shadow, alpha);
+                                 DRAW_TEXT(j, i + 2);
+                              }
+                         }
+                    }
+               }
+             else if (o->cur.style == EVAS_TEXT_STYLE_TIZEN_SOFT_GLOW_SHADOW) // DYNAMIC_BOX_IMPORT_IMAGE
+               {
+                  int size = 1;
+                  int softness = 1;
+
+                  for (j = -size; j <= size; j++)
+                    {
+                       for (i = -size; i <= size; i++)
+                         {
+                            if ((i != 0) && (j != 0))
+                              {
+                                 int alpha = evas_object_text_effect_soft_outerglow_alpha_get(i, j, 0.40, size); // OutGlow3
+                                 if(alpha == 0) continue;
+                                 COLOR_SET_AMUL(o, cur, glow, alpha);
+                                 DRAW_TEXT(j, i);
+                              }
+                         }
+                    }
+                  for (j = -softness; j <= softness; j++)
+                    {
+                       for (i = -softness; i <= softness; i++)
+                         {
+                            int alpha = evas_object_text_effect_shadow_alpha_get(i, j, 0.65, softness); // DropShadow
+                            if(alpha == 0) continue;
+                            COLOR_SET_AMUL(o, cur, shadow, alpha);
+                            DRAW_TEXT(j, i + 2);
+                         }
+                    }
+               }
+             else if (o->cur.style == EVAS_TEXT_STYLE_TIZEN_SHADOW) // DYNAMIC_BOX_IMAGE
+               {
+                  int softness = 3;
+
+                  for (j = -softness; j <= softness; j++)
+                    {
+                       for (i = -softness; i <= softness; i++)
+                         {
+                            int alpha = evas_object_text_effect_shadow_alpha_get(i, j, 0.5, softness); // DropShadow
+                            if(alpha == 0) continue;
+                            COLOR_SET_AMUL(o, cur, shadow, alpha);
+                            DRAW_TEXT(j, i + 2);
+                         }
+                    }
+               }
+          }
+        //////////////////////
+
         /* normal text */
         COLOR_ONLY_SET(obj, cur.cache, clip);
         DRAW_TEXT(0, 0);
      }
+
+   // HAVE_UNICODE_EMOTICON(2013.12.06): refactored emoticon drawing.
+   _text_emoticon_render(obj, output, context, surface, x, y);
+   //
 }
 
 static void
 evas_object_text_render_pre(Evas_Object *obj)
 {
    Evas_Object_Text *o;
-   int is_v, was_v;
-
+   int is_v = 0, was_v = 0;
    /* dont pre-render the obj twice! */
    if (obj->pre_render_done) return;
    obj->pre_render_done = 1;
    /* pre-render phase. this does anything an object needs to do just before
-    rendering. This could mean loading the image data, retrieving it from 
+    rendering. This could mean loading the image data, retrieving it from
     elsewhere, decoding video etc.
-    Then when this is done the object needs to figure if it changed and 
+    Then when this is done the object needs to figure if it changed and
     if so what and where and add the appropriate redraw rectangles */
    o = (Evas_Object_Text *)(obj->object_data);
    /* if someone is clipping this obj - go calculate the clipper */
@@ -1689,17 +2658,29 @@ evas_object_text_render_pre(Evas_Object *obj)
          evas_object_clip_recalc(obj->cur.clipper);
        obj->cur.clipper->func->render_pre(obj->cur.clipper);
      }
+   /* If object size changed and ellipsis is set */
+   if (((o->cur.ellipsis >= 0.0 ||
+        o->cur.ellipsis != o->prev.ellipsis) &&
+       ((obj->cur.geometry.w != o->last_computed.w) ||
+        (obj->cur.geometry.h != o->last_computed.h))) ||
+       (obj->cur.scale != obj->prev.scale))
+     {
+        _evas_object_text_recalc(obj, o->cur.text);
+        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
+                                            obj);
+       goto done;
+     }
    /* now figure what changed and add draw rects
     if it just became visible or invisible */
    is_v = evas_object_is_visible(obj);
    was_v = evas_object_was_visible(obj);
    if (is_v != was_v)
      {
-       evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes, 
+       evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes,
                                              obj, is_v, was_v);
        goto done;
      }
-   if (obj->changed_map)
+   if (obj->changed_map || obj->changed_src_visible)
      {
         evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
                                             obj);
@@ -1712,7 +2693,7 @@ evas_object_text_render_pre(Evas_Object *obj)
    /* if we restacked (layer or just within a layer) and dont clip anyone */
    if (obj->restack)
      {
-       evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, 
+       evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
                                            obj);
        goto done;
      }
@@ -1722,7 +2703,7 @@ evas_object_text_render_pre(Evas_Object *obj)
        (obj->cur.color.b != obj->prev.color.b) ||
        (obj->cur.color.a != obj->prev.color.a))
      {
-       evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, 
+       evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
                                            obj);
        goto done;
      }
@@ -1734,52 +2715,27 @@ evas_object_text_render_pre(Evas_Object *obj)
        (obj->cur.geometry.w != obj->prev.geometry.w) ||
        (obj->cur.geometry.h != obj->prev.geometry.h))
      {
-       evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, 
+       evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
                                            obj);
        goto done;
      }
    if (obj->cur.render_op != obj->prev.render_op)
      {
-       evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, 
-                                           obj);
-       goto done;
-     }
-   if (obj->cur.scale != obj->prev.scale)
-     {
-       evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, 
+       evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
                                            obj);
        goto done;
      }
    if (o->changed)
      {
-       if ((o->cur.size != o->prev.size) ||
-           ((o->cur.font != o->prev.font)) ||
-           ((o->cur.utf8_text != o->prev.utf8_text)) ||
-           ((o->cur.style != o->prev.style)) ||
-           ((o->cur.shadow.r != o->prev.shadow.r)) ||
-           ((o->cur.shadow.g != o->prev.shadow.g)) ||
-           ((o->cur.shadow.b != o->prev.shadow.b)) ||
-           ((o->cur.shadow.a != o->prev.shadow.a)) ||
-           ((o->cur.outline.r != o->prev.outline.r)) ||
-           ((o->cur.outline.g != o->prev.outline.g)) ||
-           ((o->cur.outline.b != o->prev.outline.b)) ||
-           ((o->cur.outline.a != o->prev.outline.a)) ||
-           ((o->cur.glow.r != o->prev.glow.r)) ||
-           ((o->cur.glow.g != o->prev.glow.g)) ||
-           ((o->cur.glow.b != o->prev.glow.b)) ||
-           ((o->cur.glow.a != o->prev.glow.a)) ||
-           ((o->cur.glow2.r != o->prev.glow2.r)) ||
-           ((o->cur.glow2.g != o->prev.glow2.g)) ||
-           ((o->cur.glow2.b != o->prev.glow2.b)) ||
-           ((o->cur.glow2.a != o->prev.glow2.a)))
-         {
-            evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, 
-                                                obj);
-            goto done;
-         }
+        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
+                                            obj);
+        goto done;
      }
    done:
-   evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes, 
+   // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+   _evas_object_text_emoticon_update_geometry(obj);
+   //
+   evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes,
                                         obj, is_v, was_v);
 }
 
@@ -1796,11 +2752,11 @@ evas_object_text_render_post(Evas_Object *obj)
    evas_object_clip_changes_clean(obj);
    /* move cur to prev safely for object data */
    evas_object_cur_prev(obj);
-   o->prev = o->cur;
+   /* o->prev = o->cur; */
    o->changed = 0;
 }
 
-static unsigned int 
+static unsigned int
 evas_object_text_id_get(Evas_Object *obj)
 {
    Evas_Object_Text *o;
@@ -1810,7 +2766,7 @@ evas_object_text_id_get(Evas_Object *obj)
    return MAGIC_OBJ_TEXT;
 }
 
-static unsigned int 
+static unsigned int
 evas_object_text_visual_id_get(Evas_Object *obj)
 {
    Evas_Object_Text *o;
@@ -1833,7 +2789,7 @@ evas_object_text_engine_data_get(Evas_Object *obj)
 static int
 evas_object_text_is_opaque(Evas_Object *obj __UNUSED__)
 {
-   /* this returns 1 if the internal object data implies that the object is 
+   /* this returns 1 if the internal object data implies that the object is
     currently fully opaque over the entire gradient it occupies */
    return 0;
 }
@@ -1878,8 +2834,9 @@ _evas_object_text_rehint(Evas_Object *obj)
                                       obj->layer->evas->pointer.x,
                                       obj->layer->evas->pointer.y, 1, 1);
    /* DO II */
-   _evas_object_text_recalc(obj);
+   _evas_object_text_recalc(obj, o->cur.text);
    o->changed = 1;
+   o->cur.filter.changed = EINA_TRUE;
    evas_object_change(obj);
    evas_object_clip_dirty(obj);
    evas_object_coords_recalc(obj);
@@ -1896,43 +2853,268 @@ _evas_object_text_rehint(Evas_Object *obj)
 }
 
 static void
-_evas_object_text_recalc(Evas_Object *obj)
+_evas_object_text_recalc(Evas_Object *obj, Eina_Unicode *text)
 {
    Evas_Object_Text *o;
-   Eina_Unicode *text = NULL;
    o = (Evas_Object_Text *)(obj->object_data);
 
-   if (o->items) _evas_object_text_items_clear(o);
-   if (o->cur.utf8_text)
-     text = eina_unicode_utf8_to_unicode(o->cur.utf8_text,
-           NULL);
-
    if (!text) text = eina_unicode_strdup(EINA_UNICODE_EMPTY_STRING);
 
    _evas_object_text_layout(obj, o, text);
 
-   if (text) free(text);
+   /* Calc ascent/descent. */
+     {
+        Evas_Object_Text_Item *item;
+
+        for (item = o->items ; item ;
+              item = EINA_INLIST_CONTAINER_GET(
+                 EINA_INLIST_GET(item)->next, Evas_Object_Text_Item))
+          {
+             int asc = 0, desc = 0;
+             int max_asc = 0, max_desc = 0;
+
+             /* Skip items without meaning full information. */
+             if (!item->text_props.font_instance)
+                continue;
+
+             asc = evas_common_font_instance_ascent_get(item->text_props.font_instance);
+             desc = evas_common_font_instance_descent_get(item->text_props.font_instance);
+
+             // HAVE_UNICODE_EMOTICON(20140626): Adjust emoticon ascent, descent and height.
+             if (item->emoticon_item)
+               {
+                  _evas_object_text_emoticon_update_size(o, item);
+                  asc = item->emoticon_item->ascent;
+                  desc = item->emoticon_item->descent;
+               }
+             //
+
+             if (asc > o->ascent)
+                o->ascent = asc;
+             if (desc > o->descent)
+                o->descent = desc;
+
+             max_asc = evas_common_font_instance_max_ascent_get(item->text_props.font_instance);
+             max_desc = evas_common_font_instance_max_descent_get(item->text_props.font_instance);
+
+             // HAVE_UNICODE_EMOTICON(2013.12.06): refactored emoticon drawing.
+             if (item->emoticon_item)
+               {
+                  max_asc = item->emoticon_item->ascent;
+                  max_desc = item->emoticon_item->descent;
+               }
+             //
+
+             if (max_asc > o->max_ascent)
+                o->max_ascent = max_asc;
+             if (max_desc > o->max_descent)
+                o->max_descent = max_desc;
+          }
+     }
 
    if ((o->font) && (o->items))
      {
-       int w, h;
-       int l = 0, r = 0, t = 0, b = 0;
+        int w, h;
+        int l = 0, r = 0, t = 0, b = 0;
 
-        w = _evas_object_text_horiz_advance_get(obj, o);
+        w = _evas_object_text_horiz_advance_get(o);
         h = _evas_object_text_vert_advance_get(obj, o);
-       evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
-       obj->cur.geometry.w = w + l + r;
+        if (!o->cur.filter.chain)
+          evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
+        else
+          evas_filter_program_padding_get(o->cur.filter.chain, &l, &r, &t, &b);
+
+        if (o->cur.ellipsis >= 0.0)
+          {
+             obj->cur.geometry.w = w + l + r < obj->cur.geometry.w || obj->cur.geometry.w == 0 ?
+                      w + l + r : obj->cur.geometry.w;
+          }
+        else
+          {
+             obj->cur.geometry.w = w + l + r;
+          }
         obj->cur.geometry.h = h + t + b;
-////        obj->cur.cache.geometry.validity = 0;
+        ////        obj->cur.cache.geometry.validity = 0;
      }
    else
      {
-       int t = 0, b = 0;
+        int t = 0, b = 0;
 
-       evas_text_style_pad_get(o->cur.style, NULL, NULL, &t, &b);
-       obj->cur.geometry.w = 0;
+        if (!o->cur.filter.chain)
+          evas_text_style_pad_get(o->cur.style, NULL, NULL, &t, &b);
+        else
+          evas_filter_program_padding_get(o->cur.filter.chain, NULL, NULL, &t, &b);
+        obj->cur.geometry.w = 0;
         obj->cur.geometry.h = o->max_ascent + o->max_descent + t + b;
-////        obj->cur.cache.geometry.validity = 0;
+        ////        obj->cur.cache.geometry.validity = 0;
      }
+   o->last_computed.w = obj->cur.geometry.w;
+   o->last_computed.h = obj->cur.geometry.h;
+   evas_object_clip_dirty(obj);
+}
+
+// TIZEN_ONLY(20150513): Add evas_object_text/textblock_ellipsis_status_get internal API.
+EAPI Eina_Bool
+evas_object_text_ellipsis_status_get(const Evas_Object *obj)
+{
+   Evas_Object_Text *o;
+
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return EINA_FALSE;
+   MAGIC_CHECK_END();
+
+   o = (Evas_Object_Text *)(obj->object_data);
+   return o->last_computed.ellipsis;
+}
+//
+
+/* EXPERIMENTAL CODE BEGIN */
+
+EAPI void
+evas_object_text_filter_program_set(Evas_Object *obj, const char *arg)
+{
+   Evas_Object_Text *o;
+   Evas_Filter_Program *pgm = NULL;
+
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return;
+   MAGIC_CHECK_END();
+   o = (Evas_Object_Text *)(obj->object_data);
+   MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
+   return;
+   MAGIC_CHECK_END();
+
+   if (!o) return;
+   if (o->cur.filter.code == arg) return;
+   if (o->cur.filter.code && arg && !strcmp(arg, o->cur.filter.code)) return;
+
+   // Parse filter program
+   evas_filter_program_del(o->cur.filter.chain);
+   if (arg)
+     {
+        pgm = evas_filter_program_new("Evas_Text: Filter Program");
+        evas_filter_program_source_set_all(pgm, o->cur.filter.sources);
+        if (!evas_filter_program_parse(pgm, arg))
+          {
+             ERR("Parsing failed!");
+             evas_filter_program_del(pgm);
+             pgm = NULL;
+          }
+     }
+   o->cur.filter.chain = pgm;
+   o->cur.filter.changed = EINA_TRUE;
+   o->cur.filter.invalid = (pgm == NULL);
+   eina_stringshare_replace(&o->cur.filter.code, arg);
+
+   // Update object
+   _evas_object_text_items_clear(o);
+   o->changed = 1;
+   _evas_object_text_recalc(obj, o->cur.text);
+   evas_object_change(obj);
+   evas_object_clip_dirty(obj);
+   evas_object_coords_recalc(obj);
+   evas_object_inform_call_resize(obj);
+}
+
+static void
+_filter_source_hash_free_cb(void *data)
+{
+   Evas_Filter_Proxy_Binding *pb = data;
+   Evas_Object *proxy, *source;
+   Evas_Object_Text *o;
+
+   proxy = pb->eo_proxy;
+   source = pb->eo_source;
+   if (source)
+     source->proxy.proxies = eina_list_remove(source->proxy.proxies, pb->eo_proxy);
+
+   o = (Evas_Object_Text *) (pb->eo_proxy ? pb->eo_proxy->object_data : NULL);
+   if (o && proxy)
+     {
+        o->cur.filter.sources_count--;
+        //if (!o->cur.filter.sources_count)
+          //proxy->proxy->is_proxy = EINA_FALSE;
+     }
+
+   eina_stringshare_del(pb->name);
+   free(pb);
+}
+
+EAPI void
+evas_object_text_filter_source_set(Evas_Object *obj, const char *name,
+                                   Evas_Object *source)
+{
+   Evas_Object_Text *o;
+   Evas_Filter_Program *pgm;
+   Evas_Filter_Proxy_Binding *pb, *pb_old = NULL;
+
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return;
+   MAGIC_CHECK_END();
+   o = (Evas_Object_Text *)(obj->object_data);
+   MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
+   return;
+   MAGIC_CHECK_END();
+
+   pgm = o->cur.filter.chain;
+
+   if (!name)
+     {
+        if (!source || !o->cur.filter.sources) return;
+        if (eina_hash_del_by_data(o->cur.filter.sources, source))
+          goto update;
+        return;
+     }
+
+   if (!o->cur.filter.sources)
+     {
+        o->cur.filter.sources = eina_hash_string_small_new
+              (EINA_FREE_CB(_filter_source_hash_free_cb));
+     }
+   else
+     {
+        pb_old = eina_hash_find(o->cur.filter.sources, name);
+        if (pb_old)
+          {
+             if (pb_old->eo_source == source) goto update;
+             eina_hash_del(o->cur.filter.sources, name, pb_old);
+          }
+     }
+
+   if (!source)
+     {
+        pb_old = eina_hash_find(o->cur.filter.sources, name);
+        if (!pb_old) return;
+        eina_hash_del_by_key(o->cur.filter.sources, name);
+        goto update;
+     }
+
+   pb = calloc(1, sizeof(*pb));
+   pb->eo_proxy = obj;
+   pb->eo_source = source;
+   pb->name = eina_stringshare_add(name);
+
+   if (!eina_list_data_find(source->proxy.proxies, obj))
+     source->proxy.proxies = eina_list_append(source->proxy.proxies, obj);
+
+   //proxy_write->is_proxy = EINA_TRUE;
+
+   eina_hash_add(o->cur.filter.sources, pb->name, pb);
+   o->cur.filter.sources_count++;
+
+   evas_filter_program_source_set_all(pgm, o->cur.filter.sources);
+
+   // Update object
+update:
+   o->cur.filter.changed = EINA_TRUE;
+   o->cur.filter.invalid = EINA_FALSE;
+   _evas_object_text_items_clear(o);
+   o->changed = 1;
+   _evas_object_text_recalc(obj, o->cur.text);
+   evas_object_change(obj);
+   evas_object_clip_dirty(obj);
+   evas_object_coords_recalc(obj);
+   evas_object_inform_call_resize(obj);
 }
 
+/* EXPERIMENTAL CODE END */
old mode 100644 (file)
new mode 100755 (executable)
index 804d5c9..6f50b6d
@@ -64,6 +64,8 @@
 #include "evas_common.h"
 #include "evas_private.h"
 #include <stdlib.h>
+// TIZEN ONLY (20131106) : Font effect for tizen.
+#include <math.h>
 
 #ifdef HAVE_LINEBREAK
 #include "linebreak.h"
 static const char o_type[] = "textblock";
 
 /* The char to be inserted instead of visible formats */
-#define _REPLACEMENT_CHAR 0xFFFC
+#define _REPLACEMENT_CHAR 0x00A0
 #define _PARAGRAPH_SEPARATOR 0x2029
 #define _NEWLINE '\n'
 #define _TAB '\t'
 
-#define _REPLACEMENT_CHAR_UTF8 "\xEF\xBF\xBC"
+#define _REPLACEMENT_CHAR_UTF8 "\xC2\xA0"
 #define _PARAGRAPH_SEPARATOR_UTF8 "\xE2\x80\xA9"
 #define _NEWLINE_UTF8 "\n"
 #define _TAB_UTF8 "\t"
@@ -129,6 +131,10 @@ static const char o_type[] = "textblock";
      } \
    while(0)
 
+// HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+typedef struct _Evas_Object_Textblock_Emoticon_Item Evas_Object_Textblock_Emoticon_Item;
+//
+
 /* private struct for textblock object internal data */
 /**
  * @internal
@@ -197,6 +203,15 @@ typedef struct _Evas_Object_Textblock_Format_Item Evas_Object_Textblock_Format_I
 typedef struct _Evas_Object_Textblock_Format      Evas_Object_Textblock_Format;
 
 /**
+ * // TIZEN_ONLY(20131218)
+ * // Add evas_textblock_cursor_range_text_valid_markup_get API.
+ * @internal
+ * @typedef Evas_Object_Textblock_Format_Pair_Item
+ * For *valid_markup_get.
+ */
+typedef struct _Evas_Object_Textblock_Format_Pair_Item Evas_Object_Textblock_Format_Pair_Item;
+
+/**
  * @internal
  * @def IS_AT_END(ti, ind)
  * Return true if ind is at the end of the text item, false otherwise.
@@ -289,6 +304,21 @@ struct _Evas_Object_Textblock_Node_Format
    Eina_Bool                           format_change : 1;
    Eina_Bool                           is_new : 1;
 };
+/**
+ * @internal
+ * @typedef Evas_Textblock_Iterator
+ * A textblock iterator.
+ */
+typedef struct _Evas_Textblock_Iterator Evas_Textblock_Iterator;
+
+// TIZEN_ONLY(20131218)
+// Add evas_textblock_cursor_range_text_valid_markup_get API.
+struct _Evas_Object_Textblock_Format_Pair_Item
+{
+   char                               *format;
+   Eina_Bool                           void_closer;
+};
+//
 
 /* The default tags to use */
 static const Evas_Object_Style_Tag_Base default_tags[] = {
@@ -367,6 +397,11 @@ struct _Evas_Object_Textblock_Item
    Evas_Textblock_Item_Type             type;
    Evas_Object_Textblock_Node_Text     *text_node;
    Evas_Object_Textblock_Format        *format;
+
+   // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+   Evas_Object_Textblock_Line          *ln;
+   //
+
    size_t                               text_pos;
 #ifdef BIDI_SUPPORT
    size_t                               visual_pos;
@@ -384,6 +419,11 @@ struct _Evas_Object_Textblock_Item
 struct _Evas_Object_Textblock_Text_Item
 {
    Evas_Object_Textblock_Item       parent;
+
+   // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+   Evas_Object_Textblock_Emoticon_Item *emoticon_item;
+   //
+
    Evas_Text_Props                  text_props;
    Evas_Coord                       inset;
    Evas_Coord                       x_adjustment; /* Used to indicate by how
@@ -404,6 +444,10 @@ struct _Evas_Object_Textblock_Format_Item
 struct _Evas_Object_Textblock_Format
 {
    Evas_Object_Textblock_Node_Format *fnode;
+   // TIZEN_ONLY(20140702): Add pressed_color tag feature
+   Eina_List           *duplicated_formats;
+   Evas_Object_Textblock_Format *duplicated_from;
+   //
    double               halign;
    double               valign;
    struct {
@@ -416,7 +460,8 @@ struct _Evas_Object_Textblock_Format
       struct {
         unsigned char  r, g, b, a;
       } normal, underline, underline2, underline_dash, outline, shadow, glow, glow2, backing,
-       strikethrough;
+       strikethrough,
+        pressed_color; // TIZEN_ONLY(20140702): Add pressed_color tag feature
    } color;
    struct {
       int               l, r;
@@ -432,6 +477,10 @@ struct _Evas_Object_Textblock_Format
    double               linefill;
    double               ellipsis;
    unsigned char        style;
+   // TIZEN_ONLY(20140702): Add pressed_color tag feature
+   Eina_Bool            is_pressed : 1;
+   Eina_Bool            has_pressed_color : 1;
+   //
    Eina_Bool            wrap_word : 1;
    Eina_Bool            wrap_char : 1;
    Eina_Bool            wrap_mixed : 1;
@@ -460,6 +509,25 @@ struct _Evas_Textblock_Cursor
    Evas_Object_Textblock_Node_Text *node;
 };
 
+// HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+struct _Evas_Object_Textblock_Emoticon_Item
+{
+   EINA_INLIST;
+   void                            *engine_data;
+   Evas_Object_Textblock_Node_Text *text_node;
+   Evas_Object_Textblock_Text_Item *ti;
+   Eina_Unicode                     unicode;
+   int                              pos;
+   int                              img_w, img_h;
+   // HAVE_UNICODE_EMOTICON(20140626): Adjust emoticon ascent, descent and height.
+   int                              ascent, descent;
+   //
+   Evas_Coord                       x, y, w, h;
+   Eina_Bool                        visible : 1;
+   Eina_Bool                        assigned : 1;
+};
+//
+
 /* Size of the index array */
 #define TEXTBLOCK_PAR_INDEX_SIZE 10
 struct _Evas_Object_Textblock
@@ -476,9 +544,21 @@ struct _Evas_Object_Textblock
    Evas_Object_Textblock_Paragraph    *paragraphs;
    Evas_Object_Textblock_Paragraph    *par_index[TEXTBLOCK_PAR_INDEX_SIZE];
 
+   // TIZEN_ONLY(20140702): Add pressed_color tag feature
+   Eina_Bool                           has_pressed_color;
+   Evas_Object_Textblock_Format       *pressed_format;
+   Evas_Object_Textblock_Format       *prev_pressed_format;
+   //
    Evas_Object_Textblock_Text_Item    *ellip_ti;
+   Eina_List                          *ellip_prev_it;
    Eina_List                          *anchors_a;
    Eina_List                          *anchors_item;
+
+   // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+   Eina_List                          *emoticons;
+   Evas_Object_Textblock_Emoticon_Item *emoticon_items;
+   //
+
    int                                 last_w, last_h;
    struct {
       int                              l, r, t, b;
@@ -489,7 +569,7 @@ struct _Evas_Object_Textblock
    const char                         *repch;
    const char                         *bidi_delimiters;
    struct {
-      int                              w, h;
+      int                              w, h, oneline_h;
       Eina_Bool                        valid : 1;
    } formatted, native;
    Eina_Bool                           redraw : 1;
@@ -498,6 +578,16 @@ struct _Evas_Object_Textblock
    Eina_Bool                           format_changed : 1;
    Eina_Bool                           have_ellipsis : 1;
    Eina_Bool                           legacy_newline : 1;
+   // TIZEN_ONLY(20150513): Add evas_object_text/textblock_ellipsis_status_get internal API.
+   Eina_Bool                           last_computed_ellipsis : 1;
+   //
+};
+
+struct _Evas_Textblock_Iterator
+{
+   Eina_Iterator                       iterator; /**< Eina Iterator. */
+   Eina_List                           *list; /**< Head of list. */
+   Eina_List                           *current; /**< Current node in loop. */
 };
 
 /* private methods for textblock objects */
@@ -518,6 +608,15 @@ static int evas_object_textblock_was_opaque(Evas_Object *obj);
 static void evas_object_textblock_coords_recalc(Evas_Object *obj);
 
 static void evas_object_textblock_scale_update(Evas_Object *obj);
+// TIZEN_ONLY(20140626): Update format when the textblock style is updated.
+static void _evas_object_textblock_format_update(Evas_Object_Textblock *o);
+//
+
+// TIZEN ONLY (20131106) : Font effect for tizen.
+static int evas_object_textblock_effect_outerglow_alpha_get(int x,int y, double opacity, int size);
+static int evas_object_textblock_effect_soft_outerglow_alpha_get(int x,int y, double opacity, int size);
+static int evas_object_textblock_effect_shadow_alpha_get(int x,int y,double opacity,int softness);
+//
 
 static const Evas_Object_Func object_func =
 {
@@ -538,7 +637,7 @@ static const Evas_Object_Func object_func =
      evas_object_textblock_was_opaque,
      NULL,
      NULL,
-     evas_object_textblock_coords_recalc,
+     NULL, //evas_object_textblock_coords_recalc,
      evas_object_textblock_scale_update,
      NULL,
      NULL,
@@ -575,12 +674,328 @@ static Evas_Object_Textblock_Node_Format *_evas_textblock_cursor_node_format_bef
 static size_t _evas_textblock_node_format_pos_get(const Evas_Object_Textblock_Node_Format *fmt);
 static void _evas_textblock_node_format_remove(Evas_Object_Textblock *o, Evas_Object_Textblock_Node_Format *n, int visual_adjustment);
 static void _evas_textblock_node_format_free(Evas_Object_Textblock *o, Evas_Object_Textblock_Node_Format *n);
+static Evas_Object_Textblock_Node_Text *_evas_textblock_node_text_new(void);
 static void _evas_textblock_node_text_free(Evas_Object_Textblock_Node_Text *n);
 static void _evas_textblock_changed(Evas_Object_Textblock *o, Evas_Object *obj);
 static void _evas_textblock_invalidate_all(Evas_Object_Textblock *o);
 static void _evas_textblock_cursors_update_offset(const Evas_Textblock_Cursor *cur, const Evas_Object_Textblock_Node_Text *n, size_t start, int offset);
 static void _evas_textblock_cursors_set_node(Evas_Object_Textblock *o, const Evas_Object_Textblock_Node_Text *n, Evas_Object_Textblock_Node_Text *new_node);
 
+// HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+Evas_Object_Textblock_Emoticon_Item *_emoticon_img_new(Evas *e, Evas_Object *obj, const Eina_Unicode *str);
+static void _evas_object_textblock_emoticon_update_geometry(Evas_Object *obj);
+static void _evas_object_textblock_emoticon_update_size(Evas_Object_Textblock_Text_Item *ti);
+static void _evas_object_textblock_emoticon_item_range_text_node_change(const Evas_Object_Textblock *o, Evas_Object_Textblock_Node_Text *from,
+                                                                        Evas_Object_Textblock_Node_Text *to, int start, int end);
+static void _evas_object_textblock_emoticon_item_range_delete(Evas *e, Evas_Object_Textblock *o, Evas_Object_Textblock_Node_Text *n, int start, int end);
+//
+
+// HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+Evas_Object_Textblock_Emoticon_Item *
+_emoticon_img_new(Evas *e, Evas_Object *obj, const Eina_Unicode *str)
+{
+   const char *value;
+   char unicode_str[15];
+   char image_file[127];
+   int load_error = EVAS_LOAD_ERROR_NONE;
+   Evas_Image_Load_Opts opts = { EINA_FALSE, 0, 0, 0, 0, { 0, 0, 0, 0 }, 0 };
+   Evas_Object_Textblock_Emoticon_Item *item;
+
+   value = getenv("EVAS_UNICODE_EMOTICON_IMAGE_DISABLE");
+   if (value && !strcmp(value, "1"))
+     return NULL;
+
+   item = calloc(1, sizeof(Evas_Object_Textblock_Emoticon_Item));
+   if (!item)
+     {
+        ERR("Failed to allocate emoticon item, textblock(%p)", obj);
+        return NULL;
+     }
+   eina_convert_xtoa(*str, unicode_str);
+   if (strlen(unicode_str) <= 2)
+     {
+        snprintf(image_file, sizeof(image_file),
+                 "%s/u00%s.png", UNICODE_EMOTICON_FOLDER, unicode_str);
+     }
+   else
+     {
+        snprintf(image_file, sizeof(image_file),
+                 "%s/u%s.png", UNICODE_EMOTICON_FOLDER, unicode_str);
+     }
+
+   item->engine_data = e->engine.func->image_load(e->engine.data.output,
+                                                  image_file,
+                                                  NULL,
+                                                  &load_error,
+                                                  &opts);
+   if (!item->engine_data || (load_error != EVAS_LOAD_ERROR_NONE))
+     {
+        DBG("Failed to emoticon image, textblock(%p) error(%d)", obj, load_error);
+        free(item);
+        return NULL;
+     }
+   e->engine.func->image_size_get(e->engine.data.output, item->engine_data,
+                                  &item->img_w, &item->img_h);
+   return item;
+}
+
+
+// HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+static void
+_evas_object_textblock_emoticon_update_geometry(Evas_Object *obj)
+{
+   Evas_Object_Textblock *o;
+   Evas_Object_Textblock_Text_Item *ti;
+   Eina_List *l;
+   int ex, ey, center_offset = 0;
+
+   o = (Evas_Object_Textblock *)(obj->object_data);
+
+   EINA_LIST_FOREACH(o->emoticons, l, ti)
+     {
+        if (!ti->emoticon_item || !ti->parent.ln) continue;
+        if (!ti->parent.ln->par) continue;
+
+        //Compute emoticon position
+        ex = obj->cur.geometry.x + ti->parent.x + ti->parent.ln->x;
+        ey = obj->cur.geometry.y + ti->parent.ln->y + ti->parent.ln->par->y;
+
+        if (ti->parent.h < ti->parent.ln->h)
+          center_offset = (ti->parent.ln->h - ti->parent.h) / 2;
+
+        ey += center_offset;
+
+        ti->emoticon_item->x = ex;
+        ti->emoticon_item->y = ey;
+
+        //Check the visibility
+        //(2013.09.11) There's a scenario to show emoticon
+        //when it is in the proxy image of the object not in the output rect.
+#if 0
+        if (evas_object_is_in_output_rect(obj,
+                                          ti->emoticon_item->x,
+                                          ti->emoticon_item->y,
+                                          ti->emoticon_item->w,
+                                          ti->emoticon_item->h))
+          ti->emoticon_item->visible = EINA_TRUE;
+        else
+          ti->emoticon_item->visible = EINA_FALSE;
+#endif
+        ti->emoticon_item->visible = EINA_TRUE;
+        ti->emoticon_item->x -= obj->cur.geometry.x;
+        ti->emoticon_item->y -= obj->cur.geometry.y;
+
+     }
+}
+
+// HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+static void
+_evas_object_textblock_emoticon_update_size(Evas_Object_Textblock_Text_Item *ti)
+{
+   float emoticon_size;
+   // HAVE_UNICODE_EMOTICON(20140626): Adjust emoticon ascent, descent and height.
+   float emoticon_ascent;
+   float emoticon_descent;
+   //
+   float aspect = 1;
+   int emo_w, emo_h;
+
+   if (!ti->emoticon_item) return;
+
+   emoticon_size = (float)(ti->parent.format->font.size) * 72 / 62;
+   // HAVE_UNICODE_EMOTICON(20140626): Adjust emoticon ascent, descent and height.
+   emoticon_ascent = (float)(ti->parent.format->font.size) * 93 / 100;
+   emoticon_descent = (float)(ti->parent.format->font.size) * 27 / 100;
+   ti->emoticon_item->ascent = (int)emoticon_ascent;
+   if ((emoticon_ascent - ti->emoticon_item->ascent) >= 0.5)
+     ti->emoticon_item->ascent++;
+   ti->emoticon_item->descent = (int)emoticon_descent;
+   if ((emoticon_descent - ti->emoticon_item->descent) >= 0.5)
+     ti->emoticon_item->descent++;
+   //
+
+   if (ti->emoticon_item->img_w != 0 && ti->emoticon_item->img_h != 0)
+     aspect = (float)ti->emoticon_item->img_w / (float)ti->emoticon_item->img_h;
+
+   emo_w = (int)emoticon_size * aspect;
+   emo_h = (int)emoticon_size;
+   ti->parent.w = emo_w;
+   // HAVE_UNICODE_EMOTICON(20140626): Adjust emoticon ascent, descent and height.
+   ti->parent.h = ti->emoticon_item->ascent + ti->emoticon_item->descent;
+   //
+   ti->parent.adv = emo_w;
+   ti->emoticon_item->w = emo_w;
+   ti->emoticon_item->h = emo_h;
+}
+
+// HAVE_UNICODE_EMOTICON(2013.10.07): Change text node of emoticon item.
+static void
+_evas_object_textblock_emoticon_item_range_text_node_change(const Evas_Object_Textblock *o, Evas_Object_Textblock_Node_Text *from, Evas_Object_Textblock_Node_Text *to, int start, int end)
+{
+   Evas_Object_Textblock_Emoticon_Item *emoticon_item;
+   if (!o) return;
+
+   if (o->emoticon_items)
+     {
+        Eina_Inlist *itrn;
+        EINA_INLIST_FOREACH_SAFE(EINA_INLIST_GET(o->emoticon_items), itrn,
+                                 emoticon_item)
+          {
+             if (emoticon_item->text_node == from &&
+                 emoticon_item->pos >= start &&
+                 emoticon_item->pos < end)
+               {
+                  emoticon_item->text_node = to;
+               }
+          }
+     }
+}
+
+// HAVE_UNICODE_EMOTICON(2013.10.07): Delete emoticon items when the string of text node is deleted.
+static void
+_evas_object_textblock_emoticon_item_range_delete(Evas *e, Evas_Object_Textblock *o, Evas_Object_Textblock_Node_Text *n, int start, int end)
+{
+   Evas_Object_Textblock_Emoticon_Item *emoticon_item;
+   Eina_Inlist *itrn;
+
+   if (!o) return;
+
+   EINA_INLIST_FOREACH_SAFE(EINA_INLIST_GET(o->emoticon_items), itrn,
+                            emoticon_item)
+     {
+        if ((emoticon_item->text_node == n) &&
+            (emoticon_item->pos >= start) &&
+            (emoticon_item->pos < end))
+          {
+             e->engine.func->image_free(e->engine.data.output,
+                                        emoticon_item->engine_data);
+             if (emoticon_item->ti) emoticon_item->ti->emoticon_item = NULL;
+             o->emoticons = eina_list_remove(o->emoticons, emoticon_item->ti);
+             o->emoticon_items = (Evas_Object_Textblock_Emoticon_Item *)
+                eina_inlist_remove(EINA_INLIST_GET(o->emoticon_items),
+                                   EINA_INLIST_GET(emoticon_item));
+             free(emoticon_item);
+          }
+     }
+}
+
+// HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+static void
+_emoticon_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
+{
+   Evas_Object_Textblock *o;
+   Evas_Object_Textblock_Text_Item *ti;
+   Eina_List *l;
+   Evas *e = obj->layer->evas;
+   Evas_Object_Textblock_Emoticon_Item *eitem;
+
+   o = (Evas_Object_Textblock *)(obj->object_data);
+
+   e->engine.func->context_color_set(output, context, 255, 255, 255, 255);
+   if ((obj->cur.cache.clip.r == 255) &&
+       (obj->cur.cache.clip.g == 255) &&
+       (obj->cur.cache.clip.b == 255) &&
+       (obj->cur.cache.clip.a == 255))
+        e->engine.func->context_multiplier_unset(output, context);
+   else if (obj->cur.clipper)
+     {
+        e->engine.func->context_multiplier_set(output, context,
+                                            obj->cur.clipper->cur.cache.clip.r,
+                                            obj->cur.clipper->cur.cache.clip.g,
+                                            obj->cur.clipper->cur.cache.clip.b,
+                                            obj->cur.clipper->cur.cache.clip.a);
+     }
+
+   EINA_LIST_FOREACH(o->emoticons, l, ti)
+     {
+        eitem = ti->emoticon_item;
+        if (!eitem->visible) continue;
+        e->engine.func->image_draw(output, context, surface, eitem->engine_data,
+                                   0, 0, eitem->img_w, eitem->img_h,
+                                   (eitem->x + x + obj->cur.geometry.x), (eitem->y + y + obj->cur.geometry.y),
+                                   eitem->w, eitem->h,
+                                   EINA_TRUE);
+     }
+}
+
+/** iterator */
+/**
+  * @internal
+  * Returns the value of the current data of list node,
+  * and goes to the next list node.
+  *
+  * @param it the iterator.
+  * @param data the data of the current list node.
+  * @return EINA_FALSE if the current list node does not exists.
+  * Otherwise, returns EINA_TRUE.
+  */
+static Eina_Bool
+_evas_textblock_iterator_next(Evas_Textblock_Iterator *it, void **data)
+{
+   if (!it->current)
+     return EINA_FALSE;
+
+   *data = eina_list_data_get(it->current);
+   it->current = eina_list_next(it->current);
+
+   return EINA_TRUE;
+}
+
+/**
+  * @internal
+  * Gets the iterator container (Eina_List) which created the iterator.
+  * @param it the iterator.
+  * @return A pointer to Eina_List.
+  */
+static Eina_List *
+_evas_textblock_iterator_get_container(Evas_Textblock_Iterator *it)
+{
+   return it->list;
+}
+
+/**
+  * @internal
+  * Frees the iterator container (Eina_List).
+  * @param it the iterator.
+  */
+static void
+_evas_textblock_iterator_free(Evas_Textblock_Iterator *it)
+{
+   while (it->list)
+     it->list = eina_list_remove_list(it->list, it->list);
+   EINA_MAGIC_SET(&it->iterator, 0);
+   free(it);
+}
+
+/**
+  * @internal
+  * Creates newly allocated  iterator associated to a list.
+  * @param list The list.
+  * @return If the memory cannot be allocated, NULL is returned.
+  * Otherwise, a valid iterator is returned.
+  */
+Eina_Iterator *
+_evas_textblock_iterator_new(Eina_List *list)
+{
+   Evas_Textblock_Iterator *it;
+
+   it = calloc(1, sizeof(Evas_Textblock_Iterator));
+   if (!it) return NULL;
+
+   EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
+   it->list = list;
+   it->current = list;
+
+   it->iterator.version = EINA_ITERATOR_VERSION;
+   it->iterator.next = FUNC_ITERATOR_NEXT(_evas_textblock_iterator_next);
+   it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
+                                 _evas_textblock_iterator_get_container);
+   it->iterator.free = FUNC_ITERATOR_FREE(_evas_textblock_iterator_free);
+
+   return &it->iterator;
+}
+
+
 /* styles */
 /**
  * @internal
@@ -694,6 +1109,95 @@ _nodes_clear(const Evas_Object *obj)
      }
 }
 
+///////////////////////////////////////////////////////////
+// TIZEN_ONLY(20140702): Add pressed_color tag feature
+///////////////////////////////////////////////////////////
+void
+_textblock_format_tree_is_pressed(Evas_Object_Textblock_Format *fmt, Eina_Bool is_pressed)
+{
+   Evas_Object_Textblock_Format *child;
+   Eina_List *l;
+
+   fmt->is_pressed = is_pressed;
+   EINA_LIST_FOREACH(fmt->duplicated_formats, l, child)
+     {
+        if (fmt == child)
+          continue;
+        _textblock_format_tree_is_pressed(child, is_pressed);
+     }
+}
+
+static void
+_textblock_mouse_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Evas_Coord x, y, w, h;
+   Evas_Object_Textblock *o;
+   Evas_Object_Textblock_Paragraph *par;
+   Evas_Object_Textblock_Line *line;
+   Evas_Object_Textblock_Item *item;
+   Evas_Event_Mouse_Down *ei = (Evas_Event_Mouse_Down *)event_info;
+
+   o = (Evas_Object_Textblock *)(obj->object_data);
+   if (!o->has_pressed_color) return;
+   evas_object_geometry_get(obj, &x, &y, &w, &h);
+
+   EINA_INLIST_FOREACH(o->paragraphs, par)
+     {
+        if ((ei->output.x >= x) && (ei->output.x <= x + par->w) &&
+            (ei->output.y >= y + par->y) && (ei->output.y <= y + par->y + par->h))
+          {
+             EINA_INLIST_FOREACH(par->lines, line)
+               {
+                  if ((ei->output.x >= x + line->x) && (ei->output.x <= x + line->x + line->w) &&
+                      (ei->output.y >= y + par->y + line->y) && (ei->output.y <= y + par->y + line->y + line->h))
+                    {
+                       EINA_INLIST_FOREACH(line->items, item)
+                         {
+                            if ((ei->output.x >= x + line->x + item->x) && (ei->output.x <= x + line->x + item->x + item->adv))
+                              {
+                                 Evas_Object_Textblock_Format *format = item->format;
+                                 Evas_Object_Textblock_Format *parent = format->duplicated_from;
+                                 if (!format->has_pressed_color)
+                                   {
+                                      o->pressed_format = NULL;
+                                      return;
+                                   }
+                                 while (parent && (parent->has_pressed_color))
+                                   {
+                                      format = parent;
+                                      parent = parent->duplicated_from;
+                                   }
+
+                                 _textblock_format_tree_is_pressed(format, EINA_TRUE);
+                                 o->pressed_format = format;
+                                 evas_object_change(obj);
+                                 return;
+                              }
+                         }
+                       break;
+                    }
+               }
+             break;
+          }
+     }
+   o->pressed_format = NULL;
+}
+
+static void
+_textblock_mouse_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Evas_Object_Textblock *o;
+
+   o = (Evas_Object_Textblock *)(obj->object_data);
+   if (o->pressed_format)
+     {
+        _textblock_format_tree_is_pressed(o->pressed_format, EINA_FALSE);
+        o->pressed_format = NULL;
+        evas_object_change(obj);
+     }
+}
+///////////////////////////////////////////////////////////
+
 /**
  * @internal
  * Unrefs and frees (if needed) a textblock format.
@@ -703,11 +1207,28 @@ _nodes_clear(const Evas_Object *obj)
 static void
 _format_unref_free(const Evas_Object *obj, Evas_Object_Textblock_Format *fmt)
 {
+   Evas_Object_Textblock *o = (Evas_Object_Textblock *)(obj->object_data);
    fmt->ref--;
    if (fmt->ref > 0) return;
    if (fmt->font.fdesc) evas_font_desc_unref(fmt->font.fdesc);
    if (fmt->font.source) eina_stringshare_del(fmt->font.source);
    evas_font_free(obj->layer->evas, fmt->font.font);
+   // TIZEN_ONLY(20140702): Add pressed_color tag feature
+   if (o->pressed_format == fmt)
+     _textblock_format_tree_is_pressed(fmt, EINA_FALSE);
+   o->pressed_format = NULL;
+   if (fmt->duplicated_from)
+     fmt->duplicated_from->duplicated_formats = eina_list_remove(fmt->duplicated_from->duplicated_formats, fmt);
+   if (fmt->duplicated_formats)
+     {
+        Evas_Object_Textblock_Format *format;
+        Eina_List *l;
+        EINA_LIST_FOREACH(fmt->duplicated_formats, l, format)
+           format->duplicated_from = NULL;
+        fmt->duplicated_formats = eina_list_free(fmt->duplicated_formats);
+     }
+   //
+
    free(fmt);
 }
 
@@ -725,6 +1246,19 @@ _item_free(const Evas_Object *obj, Evas_Object_Textblock_Line *ln, Evas_Object_T
      {
         Evas_Object_Textblock_Text_Item *ti = _ITEM_TEXT(it);
 
+        // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+        if (ti->emoticon_item)
+          {
+             Evas_Object_Textblock *o;
+             o = (Evas_Object_Textblock *)(obj->object_data);
+             ti->emoticon_item->assigned = EINA_FALSE;
+             ti->emoticon_item->ti = NULL;
+             ti->emoticon_item->visible = EINA_FALSE;
+             ti->emoticon_item = NULL;
+             o->emoticons = eina_list_remove(o->emoticons, ti);
+          }
+        //
+
         evas_common_text_props_content_unref(&ti->text_props);
      }
    else
@@ -1020,11 +1554,8 @@ _hex_string_get(char ch)
  * @param[out] a The Alpha value - NOT NULL.
  */
 static void
-_format_color_parse(const char *str, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a)
+_format_color_parse(const char *str, int slen, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a)
 {
-   int slen;
-
-   slen = strlen(str);
    *r = *g = *b = *a = 0;
 
    if (slen == 7) /* #RRGGBB */
@@ -1088,6 +1619,9 @@ static const char *glow_colorstr = NULL;
 static const char *glow2_colorstr = NULL;
 static const char *backing_colorstr = NULL;
 static const char *strikethrough_colorstr = NULL;
+// TIZEN_ONLY(20140702): Add pressed_color tag feature
+static const char *pressed_colorstr = NULL;
+//
 static const char *alignstr = NULL;
 static const char *valignstr = NULL;
 static const char *wrapstr = NULL;
@@ -1136,6 +1670,9 @@ _format_command_init(void)
         glow2_colorstr = eina_stringshare_add("glow2_color");
         backing_colorstr = eina_stringshare_add("backing_color");
         strikethrough_colorstr = eina_stringshare_add("strikethrough_color");
+        // TIZEN_ONLY(20140702): Add pressed_color tag feature
+        pressed_colorstr = eina_stringshare_add("pressed_color");
+        //
         alignstr = eina_stringshare_add("align");
         valignstr = eina_stringshare_add("valign");
         wrapstr = eina_stringshare_add("wrap");
@@ -1187,6 +1724,9 @@ _format_command_shutdown(void)
    eina_stringshare_del(glow2_colorstr);
    eina_stringshare_del(backing_colorstr);
    eina_stringshare_del(strikethrough_colorstr);
+   // TIZEN_ONLY(20140702): Add pressed_color tag feature
+   eina_stringshare_del(pressed_colorstr);
+   //
    eina_stringshare_del(alignstr);
    eina_stringshare_del(valignstr);
    eina_stringshare_del(wrapstr);
@@ -1216,19 +1756,22 @@ _format_command_shutdown(void)
  * @param[out] dst the destination string - Should not be NULL.
  * @param[in] src the source string - Should not be NULL.
  */
-static void
-_format_clean_param(char *dst, const char *src)
+static int
+_format_clean_param(Eina_Tmpstr *s)
 {
-   const char *ss;
+   Eina_Tmpstr *ss;
    char *ds;
+   int len = 0;
 
-   ds = dst;
-   for (ss = src; *ss; ss++, ds++)
+   ds = (char*) s;
+   for (ss = s; *ss; ss++, ds++, len++)
      {
         if ((*ss == '\\') && *(ss + 1)) ss++;
         *ds = *ss;
      }
    *ds = 0;
+
+   return len;
 }
 
 /**
@@ -1241,15 +1784,11 @@ _format_clean_param(char *dst, const char *src)
  * @param[in] param the parameter of the command.
  */
 static void
-_format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, const char *cmd, const char *param)
+_format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, const char *cmd, Eina_Tmpstr *param)
 {
    int len;
-   char *tmp_param;
 
-   len = strlen(param);
-   tmp_param = alloca(len + 1);
-
-   _format_clean_param(tmp_param, param);
+   len = _format_clean_param(param);
 
    /* If we are changing the font, create the fdesc. */
    if ((cmd == font_weightstr) || (cmd == font_widthstr) ||
@@ -1271,17 +1810,17 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, const char
 
    if (cmd == fontstr)
      {
-        evas_font_name_parse(fmt->font.fdesc, tmp_param);
+        evas_font_name_parse(fmt->font.fdesc, param);
      }
    else if (cmd == font_fallbacksstr)
      {
-        eina_stringshare_replace(&(fmt->font.fdesc->fallbacks), tmp_param);
+        eina_stringshare_replace(&(fmt->font.fdesc->fallbacks), param);
      }
    else if (cmd == font_sizestr)
      {
         int v;
 
-        v = atoi(tmp_param);
+        v = atoi(param);
         if (v != fmt->font.size)
           {
              fmt->font.size = v;
@@ -1290,87 +1829,139 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, const char
    else if (cmd == font_sourcestr)
      {
         if ((!fmt->font.source) ||
-              ((fmt->font.source) && (strcmp(fmt->font.source, tmp_param))))
+              ((fmt->font.source) && (strcmp(fmt->font.source, param))))
           {
-             if (fmt->font.source) eina_stringshare_del(fmt->font.source);
-             fmt->font.source = eina_stringshare_add(tmp_param);
+             eina_stringshare_replace(&(fmt->font.source), param);
           }
      }
    else if (cmd == font_weightstr)
      {
-        fmt->font.fdesc->weight = evas_font_style_find(tmp_param,
-              tmp_param + strlen(tmp_param), EVAS_FONT_STYLE_WEIGHT);
+        fmt->font.fdesc->weight = evas_font_style_find(param,
+                                                       param + len,
+                                                       EVAS_FONT_STYLE_WEIGHT);
      }
    else if (cmd == font_stylestr)
      {
-        fmt->font.fdesc->slant = evas_font_style_find(tmp_param,
-              tmp_param + strlen(tmp_param), EVAS_FONT_STYLE_SLANT);
+        fmt->font.fdesc->slant = evas_font_style_find(param,
+                                                      param + len,
+                                                      EVAS_FONT_STYLE_SLANT);
      }
    else if (cmd == font_widthstr)
      {
-        fmt->font.fdesc->width = evas_font_style_find(tmp_param,
-              tmp_param + strlen(tmp_param), EVAS_FONT_STYLE_WIDTH);
+        fmt->font.fdesc->width = evas_font_style_find(param,
+                                                      param + len,
+                                                      EVAS_FONT_STYLE_WIDTH);
      }
    else if (cmd == langstr)
      {
-        eina_stringshare_replace(&(fmt->font.fdesc->lang), tmp_param);
+        eina_stringshare_replace(&(fmt->font.fdesc->lang), param);
      }
    else if (cmd == colorstr)
-     _format_color_parse(tmp_param,
+     _format_color_parse(param, len,
            &(fmt->color.normal.r), &(fmt->color.normal.g),
            &(fmt->color.normal.b), &(fmt->color.normal.a));
    else if (cmd == underline_colorstr)
-     _format_color_parse(tmp_param,
+     _format_color_parse(param, len,
            &(fmt->color.underline.r), &(fmt->color.underline.g),
            &(fmt->color.underline.b), &(fmt->color.underline.a));
    else if (cmd == underline2_colorstr)
-     _format_color_parse(tmp_param,
+     _format_color_parse(param, len,
            &(fmt->color.underline2.r), &(fmt->color.underline2.g),
            &(fmt->color.underline2.b), &(fmt->color.underline2.a));
    else if (cmd == underline_dash_colorstr)
-     _format_color_parse(tmp_param,
+     _format_color_parse(param, len,
            &(fmt->color.underline_dash.r), &(fmt->color.underline_dash.g),
            &(fmt->color.underline_dash.b), &(fmt->color.underline_dash.a));
    else if (cmd == outline_colorstr)
-     _format_color_parse(tmp_param,
+     _format_color_parse(param, len,
            &(fmt->color.outline.r), &(fmt->color.outline.g),
            &(fmt->color.outline.b), &(fmt->color.outline.a));
    else if (cmd == shadow_colorstr)
-     _format_color_parse(tmp_param,
+     _format_color_parse(param, len,
            &(fmt->color.shadow.r), &(fmt->color.shadow.g),
            &(fmt->color.shadow.b), &(fmt->color.shadow.a));
    else if (cmd == glow_colorstr)
-     _format_color_parse(tmp_param,
+     _format_color_parse(param, len,
            &(fmt->color.glow.r), &(fmt->color.glow.g),
            &(fmt->color.glow.b), &(fmt->color.glow.a));
    else if (cmd == glow2_colorstr)
-     _format_color_parse(tmp_param,
+     _format_color_parse(param, len,
            &(fmt->color.glow2.r), &(fmt->color.glow2.g),
            &(fmt->color.glow2.b), &(fmt->color.glow2.a));
    else if (cmd == backing_colorstr)
-     _format_color_parse(tmp_param,
+     /**
+      * @page evas_textblock_style_page Evas Textblock Style Options
+      *
+      * @subsection evas_textblock_style_backing_color Backing Color
+      *
+      * Sets a background color for text. The following formats are
+      * accepted:
+      * @li "#RRGGBB"
+      * @li "#RRGGBBAA"
+      * @li "#RGB"
+      * @li "#RGBA"
+      * @code
+      * backing_color=<color>
+      * @endcode
+      */
+     _format_color_parse(param, len,
            &(fmt->color.backing.r), &(fmt->color.backing.g),
            &(fmt->color.backing.b), &(fmt->color.backing.a));
    else if (cmd == strikethrough_colorstr)
-     _format_color_parse(tmp_param,
+     _format_color_parse(param, len,
            &(fmt->color.strikethrough.r), &(fmt->color.strikethrough.g),
            &(fmt->color.strikethrough.b), &(fmt->color.strikethrough.a));
+   // TIZEN_ONLY(20140702): Add pressed_color tag feature
+   else if (cmd == pressed_colorstr)
+     {
+        Evas_Object_Textblock *o = (Evas_Object_Textblock *)(obj->object_data);
+        if (!o->has_pressed_color)
+          {
+             evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN, _textblock_mouse_down_cb, NULL);
+             evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP, _textblock_mouse_up_cb, NULL);
+             o->has_pressed_color = EINA_TRUE;
+          }
+
+        fmt->has_pressed_color = EINA_TRUE;
+        fmt->is_pressed = EINA_FALSE;
+        _format_color_parse(param, len,
+           &(fmt->color.pressed_color.r), &(fmt->color.pressed_color.g),
+           &(fmt->color.pressed_color.b), &(fmt->color.pressed_color.a));
+     }
+   //
    else if (cmd == alignstr)
      {
-        if (!strcmp(tmp_param, "auto"))
+        if (len == 4 && !strcmp(param, "auto"))
           {
              fmt->halign_auto = EINA_TRUE;
           }
         else
           {
-             if (!strcmp(tmp_param, "middle")) fmt->halign = 0.5;
-             else if (!strcmp(tmp_param, "center")) fmt->halign = 0.5;
-             else if (!strcmp(tmp_param, "left")) fmt->halign = 0.0;
-             else if (!strcmp(tmp_param, "right")) fmt->halign = 1.0;
-             else
+             static const struct {
+                const char *param;
+                int len;
+                double halign;
+             } halign_named[] = {
+               { "middle", 6, 0.5 },
+               { "center", 6, 0.5 },
+               { "left", 4, 0.0 },
+               { "right", 5, 1.0 },
+               { NULL, 0, 0.0 }
+             };
+             unsigned int i;
+
+             for (i = 0; halign_named[i].param; i++)
+               if (len == halign_named[i].len &&
+                   !strcmp(param, halign_named[i].param))
+                 {
+                    fmt->halign = halign_named[i].halign;
+                    break;
+                 }
+
+             if (halign_named[i].param == NULL)
                {
                   char *endptr = NULL;
-                  double val = strtod(tmp_param, &endptr);
+                  double val = strtod(param, &endptr);
                   if (endptr)
                     {
                        while (*endptr && _is_white(*endptr))
@@ -1387,16 +1978,33 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, const char
      }
    else if (cmd == valignstr)
      {
-        if (!strcmp(tmp_param, "top")) fmt->valign = 0.0;
-        else if (!strcmp(tmp_param, "middle")) fmt->valign = 0.5;
-        else if (!strcmp(tmp_param, "center")) fmt->valign = 0.5;
-        else if (!strcmp(tmp_param, "bottom")) fmt->valign = 1.0;
-        else if (!strcmp(tmp_param, "baseline")) fmt->valign = -1.0;
-        else if (!strcmp(tmp_param, "base")) fmt->valign = -1.0;
-        else
+        static const struct {
+           const char *param;
+           int len;
+           double valign;
+        } valign_named[] = {
+          { "top", 3, 0.0 },
+          { "middle", 6, 0.5 },
+          { "center", 6, 0.5 },
+          { "bottom", 6, 1.0 },
+          { "baseline", 8, -1.0 },
+          { "base", 4, -1.0 },
+          { NULL, 0, 0 }
+        };
+        unsigned int i;
+
+        for (i = 0; valign_named[i].param; i++)
+          if (len == valign_named[i].len &&
+              !strcmp(valign_named[i].param, param))
+            {
+               fmt->valign = valign_named[i].valign;
+               break;
+            }
+
+        if (valign_named[i].param == NULL)
           {
              char *endptr = NULL;
-             double val = strtod(tmp_param, &endptr);
+             double val = strtod(param, &endptr);
              if (endptr)
                {
                   while (*endptr && _is_white(*endptr))
@@ -1411,109 +2019,123 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, const char
      }
    else if (cmd == wrapstr)
      {
-        if (!strcmp(tmp_param, "word"))
-          {
-             fmt->wrap_word = 1;
-             fmt->wrap_char = fmt->wrap_mixed = 0;
-          }
-        else if (!strcmp(tmp_param, "char"))
-          {
-             fmt->wrap_word = fmt->wrap_mixed = 0;
-             fmt->wrap_char = 1;
-          }
-        else if (!strcmp(tmp_param, "mixed"))
-          {
-             fmt->wrap_word = fmt->wrap_char = 0;
-             fmt->wrap_mixed = 1;
-          }
-        else
-          {
-             fmt->wrap_word = fmt->wrap_mixed = fmt->wrap_char = 0;
-          }
+        static const struct {
+           const char *param;
+           int len;
+           Eina_Bool wrap_word;
+           Eina_Bool wrap_char;
+           Eina_Bool wrap_mixed;
+        } wrap_named[] = {
+          { "word", 4, 1, 0, 0 },
+          { "char", 4, 0, 1, 0 },
+          { "mixed", 5, 0, 0, 1 },
+          { NULL, 0, 0, 0, 0 }
+        };
+        unsigned int i;
+
+        fmt->wrap_word = fmt->wrap_mixed = fmt->wrap_char = 0;
+        for (i = 0; wrap_named[i].param; i++)
+          if (wrap_named[i].len == len &&
+              !strcmp(wrap_named[i].param, param))
+            {
+               fmt->wrap_word = wrap_named[i].wrap_word;
+               fmt->wrap_char = wrap_named[i].wrap_char;
+               fmt->wrap_mixed = wrap_named[i].wrap_mixed;
+               break;
+            }
      }
    else if (cmd == left_marginstr)
      {
-        if (!strcmp(tmp_param, "reset"))
+        if (len == 5 && !strcmp(param, "reset"))
           fmt->margin.l = 0;
         else
           {
-             if (tmp_param[0] == '+')
-               fmt->margin.l += atoi(&(tmp_param[1]));
-             else if (tmp_param[0] == '-')
-               fmt->margin.l -= atoi(&(tmp_param[1]));
+             if (param[0] == '+')
+               fmt->margin.l += atoi(&(param[1]));
+             else if (param[0] == '-')
+               fmt->margin.l -= atoi(&(param[1]));
              else
-               fmt->margin.l = atoi(tmp_param);
+               fmt->margin.l = atoi(param);
              if (fmt->margin.l < 0) fmt->margin.l = 0;
           }
      }
    else if (cmd == right_marginstr)
      {
-        if (!strcmp(tmp_param, "reset"))
+        if (len == 5 && !strcmp(param, "reset"))
           fmt->margin.r = 0;
         else
           {
-             if (tmp_param[0] == '+')
-               fmt->margin.r += atoi(&(tmp_param[1]));
-             else if (tmp_param[0] == '-')
-               fmt->margin.r -= atoi(&(tmp_param[1]));
+             if (param[0] == '+')
+               fmt->margin.r += atoi(&(param[1]));
+             else if (param[0] == '-')
+               fmt->margin.r -= atoi(&(param[1]));
              else
-               fmt->margin.r = atoi(tmp_param);
+               fmt->margin.r = atoi(param);
              if (fmt->margin.r < 0) fmt->margin.r = 0;
           }
      }
    else if (cmd == underlinestr)
      {
-        if (!strcmp(tmp_param, "off"))
-          {
-             fmt->underline = 0;
-             fmt->underline2 = 0;
-          }
-        else if ((!strcmp(tmp_param, "on")) ||
-              (!strcmp(tmp_param, "single")))
-          {
-             fmt->underline = 1;
-             fmt->underline2 = 0;
-          }
-        else if (!strcmp(tmp_param, "double"))
-          {
-             fmt->underline = 1;
-             fmt->underline2 = 1;
-          }
-        else if (!strcmp(tmp_param, "dashed"))
-          fmt->underline_dash = 1;
+        static const struct {
+           const char *param;
+           int len;
+           Eina_Bool underline;
+           Eina_Bool underline2;
+           Eina_Bool underline_dash;
+        } underlines_named[] = {
+          { "off", 3, 0, 0, 0 },
+          { "on", 2, 1, 0, 0 },
+          { "single", 6, 1, 0, 0 },
+          { "double", 6, 1, 1, 0 },
+          { "dashed", 6, 0, 0, 1 },
+          { NULL, 0, 0, 0, 0 }
+        };
+        unsigned int i;
+
+        fmt->underline = fmt->underline2 = fmt->underline_dash = 0;
+        for (i = 0; underlines_named[i].param; ++i)
+          if (underlines_named[i].len == len &&
+              !strcmp(underlines_named[i].param, param))
+            {
+               fmt->underline = underlines_named[i].underline;
+               fmt->underline2 = underlines_named[i].underline2;;
+               fmt->underline_dash = underlines_named[i].underline_dash;
+               break;
+            }
      }
    else if (cmd == strikethroughstr)
      {
-        if (!strcmp(tmp_param, "off"))
+        if (len == 3 && !strcmp(param, "off"))
           fmt->strikethrough = 0;
-        else if (!strcmp(tmp_param, "on"))
+        else if (len == 2 && !strcmp(param, "on"))
           fmt->strikethrough = 1;
      }
    else if (cmd == backingstr)
      {
-        if (!strcmp(tmp_param, "off"))
+        if (len == 3 && !strcmp(param, "off"))
           fmt->backing = 0;
-        else if (!strcmp(tmp_param, "on"))
+        else if (len == 2 && !strcmp(param, "on"))
           fmt->backing = 1;
      }
    else if (cmd == stylestr)
      {
         char *p1, *p2, *p, *pp;
 
-        p1 = alloca(len + 1);
-        *p1 = 0;
         p2 = alloca(len + 1);
         *p2 = 0;
         /* no comma */
-        if (!strstr(tmp_param, ",")) p1 = tmp_param;
+        if (!strstr(param, ",")) p1 = (char *)param;
         else
           {
+             p1 = alloca(len + 1);
+             *p1 = 0;
+
              /* split string "str1,str2" into p1 and p2 (if we have more than
               * 1 str2 eg "str1,str2,str3,str4" then we don't care. p2 just
               * ends up being the last one as right now it's only valid to have
               * 1 comma and 2 strings */
              pp = p1;
-             for (p = tmp_param; *p; p++)
+             for (p = (char *)param; *p; p++)
                {
                   if (*p == ',')
                     {
@@ -1538,8 +2160,13 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, const char
         else if (!strcmp(p1, "far_shadow"))          fmt->style = EVAS_TEXT_STYLE_FAR_SHADOW;
         else if (!strcmp(p1, "soft_shadow"))         fmt->style = EVAS_TEXT_STYLE_SOFT_SHADOW;
         else if (!strcmp(p1, "far_soft_shadow"))     fmt->style = EVAS_TEXT_STYLE_FAR_SOFT_SHADOW;
+        // TIZEN ONLY (20131106) : Font effect for tizen.
+        else if (!strcmp(p1, "tizen_glow_shadow"))   fmt->style = EVAS_TEXT_STYLE_TIZEN_GLOW_SHADOW;
+        else if (!strcmp(p1, "tizen_soft_glow_shadow")) fmt->style = EVAS_TEXT_STYLE_TIZEN_SOFT_GLOW_SHADOW;
+        else if (!strcmp(p1, "tizen_shadow"))        fmt->style = EVAS_TEXT_STYLE_TIZEN_SHADOW;
+        ///////////
         else                                         fmt->style = EVAS_TEXT_STYLE_PLAIN;
-        
+
         if (*p2)
           {
              if      (!strcmp(p2, "bottom_right")) EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET(fmt->style, EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_RIGHT);
@@ -1555,18 +2182,18 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, const char
      }
    else if (cmd == tabstopsstr)
      {
-        fmt->tabstops = atoi(tmp_param);
+        fmt->tabstops = atoi(param);
         if (fmt->tabstops < 1) fmt->tabstops = 1;
      }
    else if (cmd == linesizestr)
      {
-        fmt->linesize = atoi(tmp_param);
+        fmt->linesize = atoi(param);
         fmt->linerelsize = 0.0;
      }
    else if (cmd == linerelsizestr)
      {
         char *endptr = NULL;
-        double val = strtod(tmp_param, &endptr);
+        double val = strtod(param, &endptr);
         if (endptr)
           {
              while (*endptr && _is_white(*endptr))
@@ -1581,13 +2208,13 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, const char
      }
    else if (cmd == linegapstr)
      {
-        fmt->linegap = atoi(tmp_param);
+        fmt->linegap = atoi(param);
         fmt->linerelgap = 0.0;
      }
    else if (cmd == linerelgapstr)
      {
         char *endptr = NULL;
-        double val = strtod(tmp_param, &endptr);
+        double val = strtod(param, &endptr);
         if (endptr)
           {
              while (*endptr && _is_white(*endptr))
@@ -1608,7 +2235,7 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, const char
    else if (cmd == linefillstr)
      {
         char *endptr = NULL;
-        double val = strtod(tmp_param, &endptr);
+        double val = strtod(param, &endptr);
         if (endptr)
           {
              while (*endptr && _is_white(*endptr))
@@ -1623,32 +2250,32 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, const char
    else if (cmd == ellipsisstr)
      {
         char *endptr = NULL;
-        fmt->ellipsis = strtod(tmp_param, &endptr);
+        fmt->ellipsis = strtod(param, &endptr);
         if ((fmt->ellipsis < 0.0) || (fmt->ellipsis > 1.0))
           fmt->ellipsis = -1.0;
         else
           {
              Evas_Object_Textblock *o;
-             
+
              o = (Evas_Object_Textblock *)(obj->object_data);
              o->have_ellipsis = 1;
           }
      }
    else if (cmd == passwordstr)
      {
-        if (!strcmp(tmp_param, "off"))
+        if (len == 3 && !strcmp(param, "off"))
           fmt->password = 0;
-        else if (!strcmp(tmp_param, "on"))
+        else if (len == 2 && !strcmp(param, "on"))
           fmt->password = 1;
      }
    else if (cmd == underline_dash_widthstr)
      {
-        fmt->underline_dash_width = atoi(tmp_param);
+        fmt->underline_dash_width = atoi(param);
         if (fmt->underline_dash_width <= 0) fmt->underline_dash_width = 1;
      }
    else if (cmd == underline_dash_gapstr)
      {
-        fmt->underline_dash_gap = atoi(tmp_param);
+        fmt->underline_dash_gap = atoi(param);
         if (fmt->underline_dash_gap <= 0) fmt->underline_dash_gap = 1;
      }
 }
@@ -1679,33 +2306,50 @@ _format_is_param(const char *item)
  * @param[out] val where to store the value at - Not NULL.
  */
 static void
-_format_param_parse(const char *item, const char **key, const char **val)
+_format_param_parse(const char *item, const char **key, Eina_Tmpstr **val)
 {
-   const char *start, *end, *quote;
+   const char *start, *end;
+   char *tmp, *s, *d;
+   size_t len;
 
    start = strchr(item, '=');
    *key = eina_stringshare_add_length(item, start - item);
    start++; /* Advance after the '=' */
-   /* If we can find a quote, our new delimiter is a quote, not a space. */
-   if ((quote = strchr(start, '\'')))
+   /* If we can find a quote as the first non-space char,
+    * our new delimiter is a quote, not a space. */
+   while (*start == ' ')
+      start++;
+
+   if (*start == '\'')
      {
-        start = quote + 1;
+        start++;
         end = strchr(start, '\'');
+        while ((end) && (end > start) && (end[-1] == '\\'))
+          end = strchr(end + 1, '\'');
      }
    else
      {
         end = strchr(start, ' ');
+        while ((end) && (end > start) && (end[-1] == '\\'))
+          end = strchr(end + 1, ' ');
      }
 
    /* Null terminate before the spaces */
-   if (end)
-     {
-        *val = eina_stringshare_add_length(start, end - start);
-     }
-   else
+   if (end) len = end - start;
+   else len = strlen(start);
+
+   tmp = (char*) eina_tmpstr_add_length(start, len);
+
+   for (d = tmp, s = tmp; *s; s++)
      {
-        *val = eina_stringshare_add(start);
+        if (*s != '\\')
+          {
+            *d = *s;
+             d++;
+          }
      }
+   *d = '\0';
+   *val = tmp;;
 }
 
 /**
@@ -1778,12 +2422,13 @@ _format_fill(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, const char *st
      {
         if (_format_is_param(item))
           {
-             const char *key = NULL, *val = NULL;
+             const char *key = NULL;
+             Eina_Tmpstr *val = NULL;
 
              _format_param_parse(item, &key, &val);
              _format_command(obj, fmt, key, val);
              eina_stringshare_del(key);
-             eina_stringshare_del(val);
+             eina_tmpstr_del(val);
           }
         else
           {
@@ -1818,8 +2463,13 @@ _format_dup(Evas_Object *obj, const Evas_Object_Textblock_Format *fmt)
    return fmt2;
 }
 
-
-
+typedef enum
+{
+   TEXTBLOCK_POSITION_START,
+   TEXTBLOCK_POSITION_END,
+   TEXTBLOCK_POSITION_ELSE,
+   TEXTBLOCK_POSITION_SINGLE
+} Textblock_Position;
 
 /**
  * @internal
@@ -1852,6 +2502,7 @@ struct _Ctxt
    int underline_extend;
    int have_underline, have_underline2;
    double align, valign;
+   Textblock_Position position;
    Eina_Bool align_auto : 1;
    Eina_Bool width_changed : 1;
 };
@@ -1859,6 +2510,7 @@ struct _Ctxt
 static void _layout_text_add_logical_item(Ctxt *c, Evas_Object_Textblock_Text_Item *ti, Eina_List *rel);
 static void _text_item_update_sizes(Ctxt *c, Evas_Object_Textblock_Text_Item *ti);
 static void _layout_do_format(const Evas_Object *obj, Ctxt *c, Evas_Object_Textblock_Format **_fmt, Evas_Object_Textblock_Node_Format *n, int *style_pad_l, int *style_pad_r, int *style_pad_t, int *style_pad_b, Eina_Bool create_item);
+
 /**
  * @internal
  * Adjust the ascent/descent of the format and context.
@@ -1911,26 +2563,139 @@ _layout_format_ascent_descent_adjust(const Evas_Object *obj,
      }
 }
 
-/**
- * @internal
- * Create a new line using the info from the format and update the format
- * and context.
- *
- * @param c The context to work on - Not NULL.
- * @param fmt The format to use info from - NOT NULL.
- */
 static void
-_layout_line_new(Ctxt *c, Evas_Object_Textblock_Format *fmt)
+_layout_item_max_ascent_descent_calc(const Evas_Object *obj,
+      Evas_Coord *maxascent, Evas_Coord *maxdescent,
+      Evas_Object_Textblock_Item *it, Textblock_Position position)
 {
-   c->ln = calloc(1, sizeof(Evas_Object_Textblock_Line));
-   c->align = fmt->halign;
-   c->align_auto = fmt->halign_auto;
-   c->marginl = fmt->margin.l;
-   c->marginr = fmt->margin.r;
-   c->par->lines = (Evas_Object_Textblock_Line *)eina_inlist_append(EINA_INLIST_GET(c->par->lines), EINA_INLIST_GET(c->ln));
-   c->x = 0;
-   c->maxascent = c->maxdescent = 0;
-   c->ln->line_no = -1;
+   void *fi = NULL;
+   *maxascent = *maxdescent = 0;
+
+   if (!it || !it->format || !it->format->font.font)
+      return;
+
+   if (it->type == EVAS_TEXTBLOCK_ITEM_TEXT)
+     {
+        fi = _ITEM_TEXT(it)->text_props.font_instance;
+
+        // HAVE_UNICODE_EMOTICON(20140626): Adjust emoticon ascent, descent and height.
+        if (_ITEM_TEXT(it)->emoticon_item)
+          {
+             *maxascent = _ITEM_TEXT(it)->emoticon_item->ascent;
+             *maxdescent = _ITEM_TEXT(it)->emoticon_item->descent;
+             return;
+          }
+        //
+     }
+
+   if ((position == TEXTBLOCK_POSITION_START) ||
+         (position == TEXTBLOCK_POSITION_SINGLE))
+     {
+        Evas_Coord asc = 0;
+
+        if (fi)
+          {
+             asc = evas_common_font_instance_max_ascent_get(fi);
+          }
+        else
+          {
+             asc = ENFN->font_max_ascent_get(ENDT,
+                   it->format->font.font);
+          }
+
+        if (asc > *maxascent)
+           *maxascent = asc;
+     }
+
+   if ((position == TEXTBLOCK_POSITION_END) ||
+         (position == TEXTBLOCK_POSITION_SINGLE))
+     {
+        /* Calculate max descent. */
+        Evas_Coord desc = 0;
+
+        if (fi)
+          {
+             desc = evas_common_font_instance_max_descent_get(fi);
+          }
+        else
+          {
+             desc = ENFN->font_max_descent_get(ENDT,
+                   it->format->font.font);
+          }
+
+        if (desc > *maxdescent)
+           *maxdescent = desc;
+     }
+}
+
+/**
+ * @internal
+ * Adjust the ascent/descent of the item and context.
+ *
+ * @param maxascent The ascent to update - Not NUL.
+ * @param maxdescent The descent to update - Not NUL.
+ * @param it The format to adjust - NOT NULL.
+ * @param position The position inside the textblock
+ */
+static void
+_layout_item_ascent_descent_adjust(const Evas_Object *obj,
+      Evas_Coord *maxascent, Evas_Coord *maxdescent,
+      Evas_Object_Textblock_Item *it, Textblock_Position position)
+{
+   _layout_format_ascent_descent_adjust(obj, maxascent, maxdescent, it->format);
+
+   if (it->type == EVAS_TEXTBLOCK_ITEM_TEXT)
+     {
+        void *fi = _ITEM_TEXT(it)->text_props.font_instance;
+
+        // HAVE_UNICODE_EMOTICON(20140626): Adjust emoticon ascent, descent and height.
+        if (_ITEM_TEXT(it)->emoticon_item)
+          {
+             *maxascent = _ITEM_TEXT(it)->emoticon_item->ascent;
+             *maxdescent = _ITEM_TEXT(it)->emoticon_item->descent;
+             return;
+          }
+        //
+
+        if ((position == TEXTBLOCK_POSITION_START) ||
+              (position == TEXTBLOCK_POSITION_SINGLE))
+          {
+             int asc = 0;
+
+             if (fi)
+               {
+                  asc = evas_common_font_instance_max_ascent_get(fi);
+               }
+             else
+               {
+                  asc = ENFN->font_max_ascent_get(ENDT, it->format->font.font);
+               }
+             if (maxascent && (asc > *maxascent))
+                *maxascent = asc;
+          }
+     }
+}
+
+/**
+ * @internal
+ * Create a new line using the info from the format and update the format
+ * and context.
+ *
+ * @param c The context to work on - Not NULL.
+ * @param fmt The format to use info from - NOT NULL.
+ */
+static void
+_layout_line_new(Ctxt *c, Evas_Object_Textblock_Format *fmt)
+{
+   c->ln = calloc(1, sizeof(Evas_Object_Textblock_Line));
+   c->align = fmt->halign;
+   c->align_auto = fmt->halign_auto;
+   c->marginl = fmt->margin.l;
+   c->marginr = fmt->margin.r;
+   c->par->lines = (Evas_Object_Textblock_Line *)eina_inlist_append(EINA_INLIST_GET(c->par->lines), EINA_INLIST_GET(c->ln));
+   c->x = 0;
+   c->maxascent = c->maxdescent = 0;
+   c->ln->line_no = -1;
    c->ln->par = c->par;
 }
 
@@ -2051,8 +2816,19 @@ _layout_update_bidi_props(const Evas_Object_Textblock *o,
         par->bidi_props = evas_bidi_paragraph_props_get(text,
               eina_ustrbuf_length_get(par->text_node->unicode),
               segment_idxs);
-        par->direction = EVAS_BIDI_PARAGRAPH_DIRECTION_IS_RTL(par->bidi_props) ?
-           EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR;
+
+        // TIZEN_ONLY(20140822): Added evas_bidi_direction_hint_set, get APIs and applied to textblock, text.
+        //par->direction = EVAS_BIDI_PARAGRAPH_DIRECTION_IS_RTL(par->bidi_props) ?
+        //   EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR;
+        par->direction = evas_bidi_direction_hint_get(evas_object_evas_get(o->cursor->obj));
+
+        if (!EVAS_BIDI_PARAGRAPH_DIRECTION_IS_NEUTRAL(par->bidi_props))
+          {
+             par->direction = EVAS_BIDI_PARAGRAPH_DIRECTION_IS_RTL(par->bidi_props) ?
+                EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR;
+          }
+        //
+
         par->is_bidi = !!par->bidi_props;
         if (segment_idxs) free(segment_idxs);
      }
@@ -2170,7 +2946,15 @@ _layout_format_push(Ctxt *c, Evas_Object_Textblock_Format *fmt,
 {
    if (fmt)
      {
-        fmt = _format_dup(c->obj, fmt);
+        // TIZEN_ONLY(20140702): Add pressed_color tag feature
+        //fmt = _format_dup(c->obj, fmt);
+        Evas_Object_Textblock_Format *fmt2;
+        fmt2 = _format_dup(c->obj, fmt);
+        fmt2->duplicated_from = (Evas_Object_Textblock_Format *)fmt;
+        fmt2->duplicated_formats = NULL;
+        fmt->duplicated_formats = eina_list_append(fmt->duplicated_formats, fmt2);
+        fmt = fmt2;
+        //
         c->format_stack  = eina_list_prepend(c->format_stack, fmt);
         fmt->fnode = fnode;
      }
@@ -2191,6 +2975,11 @@ _layout_format_push(Ctxt *c, Evas_Object_Textblock_Format *fmt,
         fmt->underline_dash_gap = 2;
         fmt->linerelgap = 0.0;
         fmt->password = 1;
+        fmt->ellipsis = -1;
+        // TIZEN_ONLY(20140702): Add pressed_color tag feature
+        fmt->duplicated_formats = NULL;
+        fmt->duplicated_from = NULL;
+        //
      }
    return fmt;
 }
@@ -2288,12 +3077,13 @@ _layout_format_pop(Ctxt *c, const char *format)
 static void
 _layout_format_value_handle(Ctxt *c, Evas_Object_Textblock_Format *fmt, const char *item)
 {
-   const char *key = NULL, *val = NULL;
+   const char *key = NULL;
+   Eina_Tmpstr *val = NULL;
 
    _format_param_parse(item, &key, &val);
    if ((key) && (val)) _format_command(c->obj, fmt, key, val);
    if (key) eina_stringshare_del(key);
-   if (val) eina_stringshare_del(val);
+   if (val) eina_tmpstr_del(val);
    c->align = fmt->halign;
    c->align_auto = fmt->halign_auto;
    c->marginl = fmt->margin.l;
@@ -2413,6 +3203,10 @@ _layout_line_reorder(Evas_Object_Textblock_Line *line)
                     {
                        line->items = (Evas_Object_Textblock_Item *) eina_inlist_remove(EINA_INLIST_GET(line->items), EINA_INLIST_GET(min));
                        line->items = (Evas_Object_Textblock_Item *) eina_inlist_prepend_relative(EINA_INLIST_GET(line->items), EINA_INLIST_GET(min), EINA_INLIST_GET(i));
+
+                       // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+                       i->ln = line;
+                       //
                     }
 
                   i = (Evas_Object_Textblock_Item *) EINA_INLIST_GET(min)->next;
@@ -2433,17 +3227,22 @@ _layout_line_reorder(Evas_Object_Textblock_Line *line)
 /* FIXME: doc */
 static void
 _layout_calculate_format_item_size(const Evas_Object *obj,
-      const Evas_Object_Textblock_Format_Item *fi,
+      Evas_Object_Textblock_Format_Item *fi,
       Evas_Coord *maxascent, Evas_Coord *maxdescent,
       Evas_Coord *_y, Evas_Coord *_w, Evas_Coord *_h)
 {
    /* Adjust sizes according to current line height/scale */
-   Evas_Coord w, h;
+   Evas_Coord w, h, asc = 0, desc = 0;
    const char *p, *s;
 
    s = fi->item;
    w = fi->parent.w;
    h = fi->parent.h;
+   //TIZEN ONLY (1028) : Fix me - For correct align of item format.
+   asc = ENFN->font_ascent_get(ENDT, fi->parent.format->font.font);
+   desc = ENFN->font_descent_get(ENDT, fi->parent.format->font.font);
+   ///
+
    switch (fi->size)
      {
       case SIZE:
@@ -2466,11 +3265,13 @@ _layout_calculate_format_item_size(const Evas_Object *obj,
               int sz = 1;
               if (fi->vsize == VSIZE_FULL)
                 {
-                   sz = *maxdescent + *maxascent;
+                   //TIZEN ONLY (1028) : Fix me - For correct align of item format.
+                   sz = desc + asc;
                 }
               else if (fi->vsize == VSIZE_ASCENT)
                 {
-                   sz = *maxascent;
+                   //TIZEN ONLY (1028) : Fix me - For correct align of item format.
+                   sz = asc;
                 }
               w = (w * sz) / h;
               h = sz;
@@ -2488,14 +3289,15 @@ _layout_calculate_format_item_size(const Evas_Object *obj,
       case SIZE_ABS:
          switch (fi->vsize)
            {
+            //TIZEN ONLY (1028) : Fix me - For correct align of item format.
             case VSIZE_FULL:
-               if (h > (*maxdescent + *maxascent))
+               if ((h - desc) > *maxascent)
                  {
-                    *maxascent += h - (*maxdescent + *maxascent);
+                    *maxascent += h - (desc + asc);
                     *_y = -*maxascent;
                  }
                else
-                  *_y = -(h - *maxdescent);
+                  *_y = -(h - desc);
                break;
             case VSIZE_ASCENT:
                if (h > *maxascent)
@@ -2506,6 +3308,7 @@ _layout_calculate_format_item_size(const Evas_Object *obj,
                else
                   *_y = -h;
                break;
+            /////////////////////////////////////////
             default:
                break;
            }
@@ -2529,6 +3332,43 @@ _layout_calculate_format_item_size(const Evas_Object *obj,
    *_h = h;
 }
 
+static Evas_Coord
+_layout_last_line_max_descent_adjust_calc(Ctxt *c, const Evas_Object_Textblock_Paragraph *last_vis_par)
+{
+   if (last_vis_par->lines)
+     {
+        Evas_Coord maxdescent = 0, descent = 0;
+        Evas_Object_Textblock_Line *ln = (Evas_Object_Textblock_Line *)
+           EINA_INLIST_GET(last_vis_par->lines)->last;
+        Evas_Object_Textblock_Item *it;
+
+        EINA_INLIST_FOREACH(ln->items, it)
+          {
+             if (it->type == EVAS_TEXTBLOCK_ITEM_TEXT)
+               {
+                  Evas_Coord asc = 0, desc = 0;
+                  Evas_Coord masc = 0, mdesc = 0;
+                  _layout_item_ascent_descent_adjust(c->obj, &asc, &desc,
+                        it, c->position);
+                  _layout_item_max_ascent_descent_calc(c->obj, &masc, &mdesc,
+                        it, c->position);
+
+                  if (desc > descent)
+                     descent = desc;
+                  if (mdesc > maxdescent)
+                     maxdescent = mdesc;
+               }
+          }
+
+        if (maxdescent > descent)
+          {
+             return maxdescent - descent;
+          }
+     }
+
+   return 0;
+}
+
 /**
  * @internal
  * Order the items in the line, update it's properties and update it's
@@ -2544,6 +3384,9 @@ _layout_line_finalize(Ctxt *c, Evas_Object_Textblock_Format *fmt)
    Evas_Object_Textblock_Item *it;
    Evas_Coord x = 0;
 
+   if (c->position == TEXTBLOCK_POSITION_START)
+      c->position = TEXTBLOCK_POSITION_ELSE;
+
    /* If there are no text items yet, calc ascent/descent
     * according to the current format. */
    if (c->maxascent + c->maxdescent == 0)
@@ -2562,6 +3405,22 @@ _layout_line_finalize(Ctxt *c, Evas_Object_Textblock_Format *fmt)
                    &c->maxdescent, &fi->y, &fi->parent.w, &fi->parent.h);
              fi->parent.adv = fi->parent.w;
           }
+        else
+          {
+             Evas_Coord asc = 0, desc = 0;
+             _layout_item_ascent_descent_adjust(c->obj, &asc, &desc,
+                   it, c->position);
+
+             // HAVE_UNICODE_EMOTICON(20140626): Adjust emoticon ascent, descent and height.
+             if (_ITEM_TEXT(it)->emoticon_item)
+               it->ln = c->ln;
+             //
+
+             if (asc > c->maxascent)
+                c->maxascent = asc;
+             if (desc > c->maxdescent)
+                c->maxdescent = desc;
+          }
 
 loop_advance:
         it->x = x;
@@ -2658,6 +3517,9 @@ static int
 _layout_text_cutoff_get(Ctxt *c, Evas_Object_Textblock_Format *fmt,
       const Evas_Object_Textblock_Text_Item *ti)
 {
+   // HAVE_UNICODE_EMOTICON(2013.10.07): Fix cutoff position of Emoticon Image.
+   if (ti->emoticon_item) return 0;
+   //
    if (fmt->font.font)
      {
         Evas_Coord x;
@@ -2849,12 +3711,16 @@ _text_item_update_sizes(Ctxt *c, Evas_Object_Textblock_Text_Item *ti)
    if (shx2 > maxx) maxx = shx2;
    inset += -minx;
    ti->x_adjustment = maxx - minx;
-   
+
    ti->inset = inset;
    ti->parent.w = tw + ti->x_adjustment;
    ti->parent.h = th;
    ti->parent.adv = advw;
    ti->parent.x = 0;
+
+   // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+   _evas_object_textblock_emoticon_update_size(ti);
+   //
 }
 
 /**
@@ -2895,6 +3761,10 @@ _layout_text_append(Ctxt *c, Evas_Object_Textblock_Format *fmt, Evas_Object_Text
    Evas_Object_Textblock_Text_Item *ti;
    size_t cur_len = 0;
    Eina_Unicode urepch = 0;
+   // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+   Evas_Object_Textblock_Emoticon_Item *emoticon_item;
+   emoticon_item = c->o->emoticon_items;
+   //
 
    /* prepare a working copy of the string, either filled by the repch or
     * filled with the true values */
@@ -2978,9 +3848,6 @@ skip:
           }
         cur_len -= script_len;
 
-        script = evas_common_language_script_type_get(str, script_len);
-
-
         while (script_len > 0)
           {
              Evas_Font_Instance *cur_fi = NULL;
@@ -2989,6 +3856,8 @@ skip:
              ti->parent.text_node = n;
              ti->parent.text_pos = start + str - tbase;
 
+             script = evas_common_language_script_type_get(str, script_len);
+
              if (ti->parent.format->font.font)
                {
                   run_len = c->ENFN->font_run_end_get(c->ENDT,
@@ -3006,6 +3875,72 @@ skip:
                         cur_fi, str, &ti->text_props, c->par->bidi_props,
                         ti->parent.text_pos, run_len, EVAS_TEXT_PROPS_MODE_SHAPE);
                }
+
+             // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+             UNICODE_EMOTICON_CHECK(*str)
+               {
+                  Eina_Bool done = EINA_FALSE;
+                  if (emoticon_item)
+                    {
+                       while (emoticon_item &&
+                              ((emoticon_item->text_node != n) ||
+                               emoticon_item->assigned))
+                         emoticon_item = (Evas_Object_Textblock_Emoticon_Item *)
+                            (EINA_INLIST_GET(emoticon_item)->next);
+
+                       if (emoticon_item)
+                         {
+                            if (emoticon_item->unicode == *str)
+                              {
+                                 ti->emoticon_item = emoticon_item;
+                                 emoticon_item->pos = ti->parent.text_pos;
+                                 emoticon_item->assigned = EINA_TRUE;
+                                 emoticon_item->ti = ti;
+                                 emoticon_item = (Evas_Object_Textblock_Emoticon_Item *)(EINA_INLIST_GET(emoticon_item)->next);
+                                 c->o->emoticons = eina_list_append(c->o->emoticons, ti);
+                                 ti->parent.ln = NULL;
+                              }
+                            else
+                              {
+                                 ti->emoticon_item =
+                                    _emoticon_img_new(c->obj->layer->evas, c->obj,
+                                                      str);
+                                 if (ti->emoticon_item)
+                                   {
+                                      ti->emoticon_item->unicode = *str;
+                                      ti->emoticon_item->pos = ti->parent.text_pos;
+                                      ti->emoticon_item->assigned = EINA_TRUE;
+                                      ti->emoticon_item->text_node = n;
+                                      ti->emoticon_item->ti = ti;
+                                      c->o->emoticon_items = (Evas_Object_Textblock_Emoticon_Item *)eina_inlist_prepend_relative(
+                                         EINA_INLIST_GET(c->o->emoticon_items), EINA_INLIST_GET(ti->emoticon_item), EINA_INLIST_GET(emoticon_item));
+                                      c->o->emoticons = eina_list_append(c->o->emoticons, ti);
+                                      ti->parent.ln = NULL;
+                                   }
+                              }
+                            done = EINA_TRUE;
+                         }
+                    }
+                  if (!emoticon_item && !done)
+                    {
+                       ti->emoticon_item = _emoticon_img_new(c->obj->layer->evas,
+                                                             c->obj, str);
+                       if (ti->emoticon_item)
+                         {
+                            ti->emoticon_item->unicode = *str;
+                            ti->emoticon_item->pos = ti->parent.text_pos;
+                            ti->emoticon_item->assigned = EINA_TRUE;
+                            ti->emoticon_item->text_node = n;
+                            ti->emoticon_item->ti = ti;
+                            c->o->emoticon_items = (Evas_Object_Textblock_Emoticon_Item *)eina_inlist_append(
+                               EINA_INLIST_GET(c->o->emoticon_items), EINA_INLIST_GET(ti->emoticon_item));
+                            c->o->emoticons = eina_list_append(c->o->emoticons, ti);
+                            ti->parent.ln = NULL;
+                         }
+                    }
+               }
+             //
+
              str += run_len;
              script_len -= run_len;
 
@@ -3137,11 +4072,11 @@ _layout_do_format(const Evas_Object *obj __UNUSED__, Ctxt *c,
         //   item size=20x10 href=name
         //   item relsize=20x10 href=name
         //   item abssize=20x10 href=name
-        // 
+        //
         // optional arguments:
         //   vsize=full
         //   vsize=ascent
-        // 
+        //
         // size == item size (modifies line size) - can be multiplied by
         //   scale factor
         // relsize == relative size (height is current font height, width
@@ -3388,7 +4323,7 @@ _layout_get_word_mixwrap_common(Ctxt *c, Evas_Object_Textblock_Format *fmt,
            the rest works on the last char of the previous string.
            If it's a whitespace, then it's ok, and no need to go back
            because we'll remove it anyway. */
-        if (!_is_white(str[wrap]))
+        if (!_is_white(str[wrap]) || (wrap + 1 == len))
            MOVE_PREV_UNTIL(line_start, wrap);
         /* If there's a breakable point inside the text, scan backwards until
          * we find it */
@@ -3440,7 +4375,7 @@ _layout_get_word_mixwrap_common(Ctxt *c, Evas_Object_Textblock_Format *fmt,
                }
 
 
-             if ((wrap < len) && (wrap > line_start))
+             if ((wrap < len) && (wrap >= line_start))
                {
                   MOVE_NEXT_UNTIL(len, wrap);
                   return wrap;
@@ -3489,8 +4424,7 @@ _layout_ellipsis_item_new(Ctxt *c, const Evas_Object_Textblock_Item *cur_it)
 
    /* We can free it here, cause there's only one ellipsis item per tb. */
    if (c->o->ellip_ti) _item_free(c->obj, NULL, _ITEM(c->o->ellip_ti));
-   c->o->ellip_ti = ellip_ti = _layout_text_item_new(c,
-         eina_list_data_get(eina_list_last(c->format_stack)));
+   c->o->ellip_ti = ellip_ti = _layout_text_item_new(c, cur_it->format);
    ellip_ti->parent.text_node = cur_it->text_node;
    ellip_ti->parent.text_pos = cur_it->text_pos;
    script = evas_common_language_script_type_get(_ellip_str, len);
@@ -3539,6 +4473,10 @@ _layout_handle_ellipsis(Ctxt *c, Evas_Object_Textblock_Item *it, Eina_List *i)
    int wrap;
    ellip_ti = _layout_ellipsis_item_new(c, it);
    last_it = it;
+   // HAVE_UNICODE_EMOTICON(2014.03.19): Hide all of emoticons after ellipsis text item.
+   Evas_Object_Textblock_Text_Item *emoticon_ti;
+   Eina_List *l;
+   //
 
    save_cx = c->x;
    c->w -= ellip_ti->parent.w;
@@ -3563,6 +4501,16 @@ _layout_handle_ellipsis(Ctxt *c, Evas_Object_Textblock_Item *it, Eina_List *i)
         last_it = NULL;
      }
 
+   // HAVE_UNICODE_EMOTICON(2014.03.19): Hide all of emoticons after ellipsis text item.
+   EINA_LIST_FOREACH(c->o->emoticons, l, emoticon_ti)
+     {
+        if (emoticon_ti->parent.text_pos >= it->text_pos)
+          {
+             emoticon_ti->emoticon_item->visible = EINA_FALSE;
+             emoticon_ti->parent.ln = NULL;
+          }
+     }
+   //
    c->x = save_cx;
    c->w += ellip_ti->parent.w;
    /* If we should add this item, do it */
@@ -3581,6 +4529,9 @@ _layout_handle_ellipsis(Ctxt *c, Evas_Object_Textblock_Item *it, Eina_List *i)
    c->ln->items = (Evas_Object_Textblock_Item *)
       eina_inlist_append(EINA_INLIST_GET(c->ln->items),
             EINA_INLIST_GET(_ITEM(ellip_ti)));
+
+   c->position = (c->position == TEXTBLOCK_POSITION_START) ?
+      TEXTBLOCK_POSITION_SINGLE : TEXTBLOCK_POSITION_END;
    _layout_line_finalize(c, ellip_ti->parent.format);
 }
 
@@ -3622,6 +4573,146 @@ _layout_paragraph_render(Evas_Object_Textblock *o,
 #endif
 }
 
+/* calculates items width in current paragraph */
+static inline Evas_Coord
+_calc_items_width(Ctxt *c)
+{
+   Evas_Object_Textblock_Item *it, *last_it = NULL;
+   Eina_List *i;
+   Evas_Coord w = 0;
+
+   if  (!c->par->logical_items)
+      return 0;
+
+   EINA_LIST_FOREACH(c->par->logical_items, i, it)
+     {
+        w += it->adv;
+        last_it = it;
+     }
+
+   //reaching this point when it is the last item
+   if (last_it)
+      w += last_it->w - last_it->adv;
+   return w;
+}
+
+static inline int
+_item_get_cutoff(Ctxt *c, Evas_Object_Textblock_Item *it, Evas_Coord x)
+{
+   int pos = -1;
+   Evas_Object_Textblock_Text_Item *ti;
+   Evas_Object *obj = c->obj;
+
+   ti = (it->type == EVAS_TEXTBLOCK_ITEM_TEXT) ? _ITEM_TEXT(it) : NULL;
+   if (ti && ti->parent.format->font.font)
+     {
+        pos = ENFN->font_last_up_to_pos(ENDT, ti->parent.format->font.font,
+              &ti->text_props, x, 0);
+     }
+   return pos;
+}
+
+/**
+ * @internal
+ * This handles ellipsis prior most of the work in _layout_par.
+ * Currently it is here to handle all value in the range of 0.0 to 0.9999 (<1).
+ * It starts by getting the total width of items, and calculates the 'block' of
+ * text that needs to be removed i.e. sets low and high boundaries
+ * of that block.
+ * All text items that intersect this block will be cut: the edge items (ones
+ * that don't intersect in whole) will be split, and the rest are set to be
+ * visually-deleted.
+ * Note that a special case for visible format items does not
+ * split them, but instead just visually-deletes them (because there are no 
+ * characters to split).
+ */
+static inline void
+_layout_par_ellipsis_items(Ctxt *c, double ellip)
+{
+   Evas_Object_Textblock_Item *it;
+   Evas_Object_Textblock_Text_Item *ellip_ti;
+   Eina_List *i, *j;
+   Evas_Coord items_width, exceed, items_cut;
+   Evas_Coord l, h, off;
+   int pos;
+
+   c->o->ellip_prev_it = NULL;
+
+   /* calc exceed amount */
+   items_width = _calc_items_width(c);
+   exceed = items_width - (c->w - c->o->style_pad.l - c->o->style_pad.r
+                         - c->marginl - c->marginr);
+
+   if (exceed <= 0)
+      return;
+
+   // TIZEN_ONLY(20150513): Add evas_object_text/textblock_ellipsis_status_get internal API.
+   c->o->last_computed_ellipsis = EINA_TRUE;
+   //
+
+     {
+        Evas_Object_Textblock_Item *first_it =
+           _ITEM(eina_list_data_get(c->par->logical_items));
+        ellip_ti = _layout_ellipsis_item_new(c, first_it);
+     }
+   exceed += ellip_ti->parent.adv;
+   items_cut = items_width * ellip;
+   l = items_cut - (exceed * ellip);
+   h = l + exceed; //h = items_cut - (exceed * (1 - ellip))
+
+   off = 0;
+   /* look for the item that is being cut by the lower boundary */
+   i = c->par->logical_items;
+   EINA_LIST_FOREACH(c->par->logical_items, i, it)
+     {
+        if (it->w > (l - off))
+           break;
+        off += it->adv;
+     }
+   c->o->ellip_prev_it = i;
+   if (it) _layout_ellipsis_item_new(c, it);
+
+
+   pos = (it && it->type == EVAS_TEXTBLOCK_ITEM_TEXT) ?
+      (_item_get_cutoff(c, it, l - off)) : -1;
+   if (pos >= 0)
+     {
+        _layout_item_text_split_strip_white(c, _ITEM_TEXT(it), i, pos);
+        off += it->adv;
+        i = eina_list_next(i);
+     }
+
+   /* look for the item that is being cut by the upper boundary */
+   EINA_LIST_FOREACH(i, j, it)
+     {
+        if (it->w > (h - off))
+           break;
+        off += it->adv;
+        /* if item is not being cut by the upper boundary, then
+         * it is contained in the area that we are supposed to
+         * visually remove */
+        it->visually_deleted = EINA_TRUE;
+     }
+
+   pos = (it && it->type == EVAS_TEXTBLOCK_ITEM_TEXT) ?
+      (_item_get_cutoff(c, it, h - off)) : -1;
+   if (pos >= 0)
+      _layout_item_text_split_strip_white(c, _ITEM_TEXT(it), j, pos + 1);
+   if (it)
+      it->visually_deleted = EINA_TRUE;
+}
+
+static inline void
+_layout_par_append_ellipsis(Ctxt *c)
+{
+   Evas_Object_Textblock_Text_Item *ellip_ti = c->o->ellip_ti;
+   c->ln->items = (Evas_Object_Textblock_Item *)
+      eina_inlist_append(EINA_INLIST_GET(c->ln->items),
+            EINA_INLIST_GET(_ITEM(ellip_ti)));
+   ellip_ti->parent.ln = c->ln;
+   c->x += ellip_ti->parent.adv;
+}
+
 /* 0 means go ahead, 1 means break without an error, 2 means
  * break with an error, should probably clean this a bit (enum/macro)
  * FIXME ^ */
@@ -3633,6 +4724,7 @@ _layout_par(Ctxt *c)
    int ret = 0;
    int wrap = -1;
    char *line_breaks = NULL;
+   Eina_Bool skip_ellip = EINA_FALSE;
 
    if (!c->par->logical_items)
      return 2;
@@ -3658,6 +4750,12 @@ _layout_par(Ctxt *c)
                 EINA_INLIST_GET(c->par->lines)->last;
              if (ln)
                 c->line_no = c->par->line_no + ln->line_no + 1;
+
+             /* After this par we are no longer at the beginning, as there
+              * must be some text in the par. */
+             if (c->position == TEXTBLOCK_POSITION_START)
+                c->position = TEXTBLOCK_POSITION_ELSE;
+
              return 0;
           }
         c->par->text_node->dirty = EINA_FALSE;
@@ -3682,6 +4780,7 @@ _layout_par(Ctxt *c)
                     }
                   else
                     {
+                       ititr->visually_deleted = EINA_FALSE;
                        prev_it = ititr;
                     }
                }
@@ -3694,34 +4793,52 @@ _layout_par(Ctxt *c)
    _layout_line_new(c, it->format);
    /* We walk on our own because we want to be able to add items from
     * inside the list and then walk them on the next iteration. */
+
+   /* TODO: We need to consider where ellipsis is used in the current text.
+      Currently, we assume that ellipsis is at the beginning of the
+      paragraph. This is a safe assumption for now, as other usages
+      seem a bit unnatural.*/
+     {
+        double ellip;
+        ellip = it->format->ellipsis;
+        if ((0 <= ellip) && (ellip < 1.0))
+           _layout_par_ellipsis_items(c, ellip);
+     }
+
    for (i = c->par->logical_items ; i ; )
      {
+        Evas_Coord prevdescent = 0, prevascent = 0;
         int adv_line = 0;
         int redo_item = 0;
         it = _ITEM(eina_list_data_get(i));
         /* Skip visually deleted items */
         if (it->visually_deleted)
           {
+             //one more chance for ellipsis special cases
+             if (c->o->ellip_prev_it == i)
+                _layout_par_append_ellipsis(c);
+
              i = eina_list_next(i);
              continue;
           }
 
         if (it->type == EVAS_TEXTBLOCK_ITEM_TEXT)
           {
-             Evas_Object_Textblock_Text_Item *ti = _ITEM_TEXT(it);
-             _layout_format_ascent_descent_adjust(c->obj, &c->maxascent,
-                   &c->maxdescent, ti->parent.format);
+             _layout_item_ascent_descent_adjust(c->obj, &c->maxascent,
+                   &c->maxdescent, it, c->position);
           }
         else
           {
              Evas_Object_Textblock_Format_Item *fi = _ITEM_FORMAT(it);
              if (fi->formatme)
                {
+                  prevdescent = c->maxdescent;
+                  prevascent = c->maxascent;
                   /* If there are no text items yet, calc ascent/descent
                    * according to the current format. */
                   if (c->maxascent + c->maxdescent == 0)
-                     _layout_format_ascent_descent_adjust(c->obj, &c->maxascent,
-                           &c->maxdescent, it->format);
+                     _layout_item_ascent_descent_adjust(c->obj, &c->maxascent,
+                           &c->maxdescent, it, c->position);
 
                   _layout_calculate_format_item_size(c->obj, fi, &c->maxascent,
                         &c->maxdescent, &fi->y, &fi->parent.w, &fi->parent.h);
@@ -3729,6 +4846,69 @@ _layout_par(Ctxt *c)
                }
           }
 
+        /* Handle ellipsis here. If we don't have more width left
+         * and no height left, or no more width left and no wrapping.
+         * Note that this is only for ellipsis == 1.0, and is treated in a
+         * fast path.
+         * Other values of 0.0 <= ellipsis < 1.0 are handled in
+         * _layout_par_ellipsis_items */
+        if (!skip_ellip)
+          {
+             if ((it->format->ellipsis == 1.0) && (c->h >= 0) &&
+                 ((2 * it->h + c->y >
+                   c->h - c->o->style_pad.t - c->o->style_pad.b) ||
+                  (!it->format->wrap_word && !it->format->wrap_char &&
+                   !it->format->wrap_mixed)))
+               {
+                  Evas_Object_Textblock_Text_Item *ellip_ti;
+                  ellip_ti = _layout_ellipsis_item_new(c, it);
+
+                  if ((c->w >= 0) &&
+                      (((c->x + it->adv + ellip_ti->parent.adv) >
+                        (c->w - c->o->style_pad.l - c->o->style_pad.r -
+                         c->marginl - c->marginr)) || (wrap > 0)))
+                    {
+                       Eina_List *ll = i;
+                       int limit = c->w - c->o->style_pad.l - c->o->style_pad.r -
+                          c->marginl - c->marginr - c->x - it->adv;
+
+                       // TIZEN_ONLY(20150513): Add evas_object_text/textblock_ellipsis_status_get internal API.
+                       c->o->last_computed_ellipsis = EINA_TRUE;
+                       //
+
+                       if (limit < 0)
+                         {
+                            _layout_handle_ellipsis(c, it, i);
+                            ret = 1;
+                            goto end;
+                         }
+                       ll = eina_list_next(ll);
+                       while (ll)
+                         {
+                            Evas_Object_Textblock_Item *itt;
+
+                            itt = _ITEM(eina_list_data_get(ll));
+                            if (itt->type != EVAS_TEXTBLOCK_ITEM_TEXT)
+                              {
+                                 Evas_Object_Textblock_Format_Item *itt_fi = _ITEM_FORMAT(itt);
+                                 Evas_Coord _maxa = 0, _maxd = 0, _yy = 0, _ww = 0, _hh = 0;
+                                 _layout_calculate_format_item_size(c->obj, itt_fi, &_maxa,
+                                       &_maxd, &_yy, &_ww, &_hh);
+                                 itt_fi->parent.adv = _ww;
+                              }
+                            limit -= itt->adv;
+                            if (limit < 0)
+                              {
+                                 _layout_handle_ellipsis(c, it, i);
+                                 ret = 1;
+                                 goto end;
+                              }
+                            ll = eina_list_next(ll);
+                         }
+                       skip_ellip = EINA_TRUE;
+                    }
+               }
+          }
 
         /* Check if we need to wrap, i.e the text is bigger than the width,
            or we already found a wrap point. */
@@ -3737,21 +4917,9 @@ _layout_par(Ctxt *c)
                 (c->w - c->o->style_pad.l - c->o->style_pad.r -
                  c->marginl - c->marginr)) || (wrap > 0)))
           {
-             /* Handle ellipsis here. If we don't have more width left
-              * and no height left, or no more width left and no wrapping. */
-             if ((it->format->ellipsis == 1.0) && (c->h >= 0) &&
-                   ((2 * it->h + c->y >
-                     c->h - c->o->style_pad.t - c->o->style_pad.b) ||
-                    (!it->format->wrap_word && !it->format->wrap_char &&
-                     !it->format->wrap_mixed)))
-               {
-                  _layout_handle_ellipsis(c, it, i);
-                  ret = 1;
-                  goto end;
-               }
              /* If we want to wrap and it's worth checking for wrapping
               * (i.e there's actually text). */
-             else if ((it->format->wrap_word || it->format->wrap_char ||
+             if ((it->format->wrap_word || it->format->wrap_char ||
                 it->format->wrap_mixed) && it->text_node)
                {
                   size_t line_start;
@@ -3759,8 +4927,6 @@ _layout_par(Ctxt *c)
 
                   it_len = (it->type == EVAS_TEXTBLOCK_ITEM_FORMAT) ?
                      1 : _ITEM_TEXT(it)->text_props.text_len;
-
-
 #ifdef HAVE_LINEBREAK
                   /* If we haven't calculated the linebreaks yet,
                    * do */
@@ -3852,10 +5018,13 @@ _layout_par(Ctxt *c)
                                     item_pos as the line_start, because
                                     there's already no cut before*/
                                  wrap = -1;
+                                 adv_line = 0;
                               }
-                        }
+                         }
                        else
-                          wrap -= it->text_pos; /* Cut here */
+                         {
+                            wrap -= it->text_pos; /* Cut here */
+                         }
                     }
 
                   if (wrap > 0)
@@ -3869,6 +5038,12 @@ _layout_par(Ctxt *c)
                   else if (wrap == 0)
                     {
                        /* Should wrap before the item */
+
+                       /* We didn't end up using the item, so revert the ascent
+                        * and descent changes. */
+                       c->maxdescent = prevdescent;
+                       c->maxascent = prevascent;
+
                        adv_line = 0;
                        redo_item = 1;
                        _layout_line_advance(c, it->format);
@@ -3898,7 +5073,10 @@ _layout_par(Ctxt *c)
                        adv_line = 1;
                     }
                }
+
              c->x += it->adv;
+             if (c->o->ellip_prev_it == i)
+                _layout_par_append_ellipsis(c);
              i = eina_list_next(i);
           }
         if (adv_line)
@@ -3912,8 +5090,15 @@ _layout_par(Ctxt *c)
              _layout_line_advance(c, it->format);
           }
      }
+
    if (c->ln->items)
      {
+        if (c->par && !EINA_INLIST_GET(c->par)->next)
+          {
+             c->position = (c->position == TEXTBLOCK_POSITION_START) ?
+                TEXTBLOCK_POSITION_SINGLE : TEXTBLOCK_POSITION_END;
+          }
+
         /* Here 'it' is the last format used */
         _layout_line_finalize(c, it->format);
      }
@@ -4022,6 +5207,8 @@ _format_changes_invalidate_text_nodes(Ctxt *c)
              start_n = _NODE_TEXT(EINA_INLIST_GET(start_n)->next);
           }
      }
+
+   eina_list_free(fstack);
 }
 
 
@@ -4283,6 +5470,8 @@ _layout(const Evas_Object *obj, int w, int h, int *w_ret, int *h_ret)
       int par_count = 1; /* Force it to take the first one */
       int par_index_pos = 0;
 
+      c->position = TEXTBLOCK_POSITION_START;
+
       if (par_index_step == 0) par_index_step = 1;
 
       /* Clear all of the index */
@@ -4326,7 +5515,11 @@ _layout(const Evas_Object *obj, int w, int h, int *w_ret, int *h_ret)
             EINA_INLIST_GET(c->paragraphs)->last;
 
       if (last_vis_par)
-         c->hmax = last_vis_par->y + last_vis_par->h;
+        {
+           c->hmax = last_vis_par->y + last_vis_par->h +
+              _layout_last_line_max_descent_adjust_calc(c, last_vis_par);
+        }
+
    }
 
    /* Clean the rest of the format stack */
@@ -4375,11 +5568,31 @@ _relayout(const Evas_Object *obj)
    Evas_Object_Textblock *o;
 
    o = (Evas_Object_Textblock *)(obj->object_data);
+   // TIZEN_ONLY(20150513): Add evas_object_text/textblock_ellipsis_status_get internal API.
+   o->last_computed_ellipsis = EINA_FALSE;
+   //
+   // TIZEN_ONLY(20140702): Add pressed_color tag feature
+   if (o->pressed_format)
+     _textblock_format_tree_is_pressed(o->pressed_format, EINA_FALSE);
+   o->pressed_format = NULL;
+   //
    _layout(obj, obj->cur.geometry.w, obj->cur.geometry.h,
          &o->formatted.w, &o->formatted.h);
+
+   // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+   _evas_object_textblock_emoticon_update_geometry((Evas_Object *)obj);
+   //
+
    o->formatted.valid = 1;
+   o->formatted.oneline_h = 0;
    o->last_w = obj->cur.geometry.w;
    o->last_h = obj->cur.geometry.h;
+   if ((o->paragraphs) && (!EINA_INLIST_GET(o->paragraphs)->next) &&
+       (o->paragraphs->lines) && (!EINA_INLIST_GET(o->paragraphs->lines)->next))
+     {
+        if (obj->cur.geometry.h < o->formatted.h)
+          o->formatted.oneline_h = o->formatted.h;
+     }
    o->changed = 0;
    o->content_changed = 0;
    o->format_changed = EINA_FALSE;
@@ -4405,6 +5618,8 @@ _find_layout_item_line_match(Evas_Object *obj, Evas_Object_Textblock_Node_Text *
    Evas_Object_Textblock *o;
 
    o = (Evas_Object_Textblock *)(obj->object_data);
+
+   evas_object_textblock_coords_recalc(obj);
    if (!o->formatted.valid) _relayout(obj);
 
    found_par = n->par;
@@ -4525,6 +5740,8 @@ evas_textblock_style_set(Evas_Textblock_Style *ts, const char *text)
        (ts->style_text && text && !strcmp(text, ts->style_text)))
       return;
 
+   // TIZEN_ONLY(20140626): Update format when the textblock style is updated.
+   /*
    EINA_LIST_FOREACH(ts->objects, l, obj)
      {
         Evas_Object_Textblock *o;
@@ -4533,6 +5750,8 @@ evas_textblock_style_set(Evas_Textblock_Style *ts, const char *text)
         _evas_textblock_invalidate_all(o);
         _evas_textblock_changed(o, obj);
      }
+   */
+   //
 
    _style_replace(ts, text);
 
@@ -4650,15 +5869,54 @@ evas_textblock_style_set(Evas_Textblock_Style *ts, const char *text)
              p++;
           }
      }
-}
 
-EAPI const char *
+   // TIZEN_ONLY(20140626): Update format when the textblock style is updated.
+   EINA_LIST_FOREACH(ts->objects, l, obj)
+     {
+        Evas_Object_Textblock *o;
+
+        o = (Evas_Object_Textblock *)(obj->object_data);
+        _evas_textblock_invalidate_all(o);
+        _evas_textblock_changed(o, obj);
+
+        _evas_object_textblock_format_update(o);
+     }
+   //
+}
+
+EAPI const char *
 evas_textblock_style_get(const Evas_Textblock_Style *ts)
 {
    if (!ts) return NULL;
    return ts->style_text;
 }
 
+static const char *
+_textblock_format_node_from_style_tag(Evas_Object_Textblock *o, Evas_Object_Textblock_Node_Format *fnode, const char *format, size_t format_len)
+{
+   const char *match;
+   size_t replace_len;
+   if (!o->style_user || !(match = _style_match_tag(o->style_user, format,
+               format_len, &replace_len)))
+     {
+        match = _style_match_tag(o->style, format, format_len,
+              &replace_len);
+     }
+
+   if (match)
+     {
+        if (match[0] != '-')
+          {
+             fnode->opener = EINA_TRUE;
+             if (match[0] != '+')
+               {
+                  fnode->own_closer = EINA_TRUE;
+               }
+          }
+     }
+   return match;
+}
+
 /* textblock styles */
 
 static void
@@ -4688,6 +5946,43 @@ _textblock_style_generic_set(Evas_Object *obj, Evas_Textblock_Style *ts,
      }
    *obj_ts = ts;
 
+   Evas_Object_Textblock_Node_Format *fnode = o->format_nodes;
+   while (fnode)
+     {
+        const char *match;
+        size_t format_len = eina_stringshare_strlen(fnode->orig_format);
+        /* Is this safe to use alloca here? Strings might possibly get large */
+        char *format = alloca(format_len + 2);
+
+        if (!fnode->opener)
+          {
+             format[0] = '/';
+             format[1] = '\0';
+          }
+        else
+          {
+             format[0] = '\0';
+          }
+
+        strcat(format, fnode->orig_format);
+
+        match = _textblock_format_node_from_style_tag(o, fnode, format,
+              format_len);
+
+        if (match && fnode->format && strcmp(match, fnode->format))
+          {
+             if ((*match == '+') || (*match == '-'))
+               {
+                  match++;
+                  while (*match == ' ') match++;
+               }
+             fnode->is_new = EINA_TRUE;
+             eina_stringshare_replace(&fnode->format, match);
+          }
+        fnode = _NODE_FORMAT(EINA_INLIST_GET(fnode)->next);
+     }
+
+   o->format_changed = EINA_TRUE;
    _evas_textblock_invalidate_all(o);
    _evas_textblock_changed(o, obj);
 }
@@ -4912,11 +6207,11 @@ _escaped_char_get(const char *s, const char *s_end)
           }
 
         len = s_end - s;
-        if (len >= sizeof(ustr) + 1)
+        if (len >= sizeof(ustr))
            len = sizeof(ustr);
 
         memcpy(ustr, s, len);
-        ustr[len] = '\0';
+        ustr[len-1] = '\0';
         uchar[0] = strtol(ustr, NULL, base);
 
         if (uchar[0] == 0)
@@ -5019,6 +6314,12 @@ evas_object_textblock_text_markup_set(Evas_Object *obj, const char *text)
         o->markup_text = NULL;
      }
    _nodes_clear(obj);
+
+   o->cursor->node = _evas_textblock_node_text_new();
+   o->text_nodes = _NODE_TEXT(eina_inlist_append(
+            EINA_INLIST_GET(o->text_nodes),
+            EINA_INLIST_GET(o->cursor->node)));
+
    if (!o->style && !o->style_user)
      {
         if (text != o->markup_text)
@@ -5142,6 +6443,8 @@ evas_object_textblock_text_markup_prepend(Evas_Textblock_Cursor *cur, const char
                     }
                }
              /* Unicode object replcament char */
+             // TIZEN_ONLY(20140815): Don't remove NO-BREAK SPACE(0x00A0) character.
+             /*
              else if (!strncmp(_REPLACEMENT_CHAR_UTF8, p,
                       text_len = strlen(_REPLACEMENT_CHAR_UTF8)) ||
                    !strncmp(_NEWLINE_UTF8, p,
@@ -5150,6 +6453,13 @@ evas_object_textblock_text_markup_prepend(Evas_Textblock_Cursor *cur, const char
                       text_len = strlen(_TAB_UTF8)) ||
                    !strncmp(_PARAGRAPH_SEPARATOR_UTF8, p,
                       text_len = strlen(_PARAGRAPH_SEPARATOR_UTF8)))
+              */
+             else if (!strncmp(_NEWLINE_UTF8, p,
+                      text_len = strlen(_NEWLINE_UTF8)) ||
+                   !strncmp(_TAB_UTF8, p,
+                      text_len = strlen(_TAB_UTF8)) ||
+                   !strncmp(_PARAGRAPH_SEPARATOR_UTF8, p,
+                      text_len = strlen(_PARAGRAPH_SEPARATOR_UTF8)))
                {
                   /*FIXME: currently just remove them, maybe do something
                    * fancier in the future, atm it breaks if this char
@@ -5194,34 +6504,76 @@ _markup_get_format_append(Eina_Strbuf *txt, Evas_Object_Textblock_Node_Format *f
 }
 
 /**
+ * // TIZEN_ONLY(20131218)
+ * // Add evas_textblock_cursor_range_text_valid_markup_get API.
  * @internal
- * An helper function to markup get. Appends the text in text.
+ * An helper function to markup get. Prepends the format from fnode to the strbuf txt.
  *
- * @param txt the strbuf to append to.
- * @param text the text to process.
+ * @param txt the strbuf to prepend to.
+ * @param fnode the format node to process.
  */
 static void
-_markup_get_text_append(Eina_Strbuf *txt, const Eina_Unicode *text)
+_markup_get_format_prepend(Eina_Strbuf *txt, Evas_Object_Textblock_Node_Format *fnode)
+{
+   if (fnode->own_closer)
+     eina_strbuf_prepend_printf(txt, "<%s/>", fnode->orig_format);
+   else if (fnode->opener)
+     eina_strbuf_prepend_printf(txt, "<%s>", fnode->orig_format);
+   else
+     eina_strbuf_prepend_printf(txt, "</%s>", fnode->orig_format);
+}
+
+/**
+ * @internal
+ * An helper function to _markup_get_text_append and others, used for getting
+ * back only the "dangerous" escapes.
+ */
+static void
+_markup_get_text_utf8_append(Eina_Strbuf *sbuf, const char *text)
 {
-   char *p = eina_unicode_unicode_to_utf8(text, NULL);
-   char *base = p;
-   while (*p)
+   int ch, pos = 0, pos2 = 0;
+
+   for (;;)
      {
-        const char *escape;
-        int adv;
+        pos = pos2;
+        pos2 = evas_string_char_next_get(text, pos2, &ch);
+        if ((ch <= 0) || (pos2 <= 0)) break;
 
-        escape = _escaped_char_match(p, &adv);
-        if (escape)
-          {
-             p += adv;
-             eina_strbuf_append(txt, escape);
-          }
-        else
+        if (ch == _NEWLINE)
+           eina_strbuf_append(sbuf, "<br/>");
+        else if (ch == _TAB)
+           eina_strbuf_append(sbuf, "<tab/>");
+        else if (ch == '<')
+           eina_strbuf_append(sbuf, "&lt;");
+        else if (ch == '>')
+           eina_strbuf_append(sbuf, "&gt;");
+        else if (ch == '&')
+           eina_strbuf_append(sbuf, "&amp;");
+        else if (ch == _PARAGRAPH_SEPARATOR)
+           eina_strbuf_append(sbuf, "<ps/>");
+        else if (ch == _REPLACEMENT_CHAR)
+           eina_strbuf_append(sbuf, "&#xa0;");
+        else if (ch != '\r')
           {
-             eina_strbuf_append_char(txt, *p);
-             p++;
+             eina_strbuf_append_length(sbuf, text + pos, pos2 - pos);
           }
      }
+}
+
+/**
+ * @internal
+ * An helper function to markup get. Appends the text in text.
+ *
+ * @param txt the strbuf to append to.
+ * @param text the text to process.
+ */
+static void
+_markup_get_text_append(Eina_Strbuf *txt, const Eina_Unicode *text)
+{
+   char *base = eina_unicode_unicode_to_utf8(text, NULL);
+
+   _markup_get_text_utf8_append(txt, base);
+
    free(base);
 }
 EAPI const char *
@@ -5255,7 +6607,7 @@ evas_object_textblock_text_markup_get(const Evas_Object *obj)
           {
              Eina_Unicode tmp_ch;
              off += fnode->offset;
-             
+
              if (off > len) break;
              /* No need to skip on the first run */
              tmp_ch = text[off];
@@ -5372,8 +6724,15 @@ evas_textblock_text_markup_to_utf8(const Evas_Object *obj, const char *text)
                }
              else if (*p == 0)
                {
-                  eina_strbuf_append_length(sbuf, s, p - s);
-                  s = NULL;
+                  if (s)
+                    {
+                       eina_strbuf_append_length(sbuf, s, p - s);
+                       s = NULL;
+                    }
+                  else
+                    {
+                       ERR("There is a invalid markup tag at positoin '%u'. Please check the text.", (unsigned int) (p - text));
+                    }
                }
              if (*p == 0)
                 break;
@@ -5386,8 +6745,15 @@ evas_textblock_text_markup_to_utf8(const Evas_Object *obj, const char *text)
                    * mark the start of the tag */
                   tag_start = p;
                   tag_end = NULL;
-                  eina_strbuf_append_length(sbuf, s, p - s);
-                  s = NULL;
+                  if (s)
+                    {
+                       eina_strbuf_append_length(sbuf, s, p - s);
+                       s = NULL;
+                    }
+                  else
+                    {
+                       ERR("There is a invalid markup tag at positoin '%u'. Please check the text.", (unsigned int) (p - text));
+                    }
                }
           }
         else if (*p == '>')
@@ -5406,8 +6772,15 @@ evas_textblock_text_markup_to_utf8(const Evas_Object *obj, const char *text)
                    * the start of the escape sequence */
                   esc_start = p;
                   esc_end = NULL;
-                  eina_strbuf_append_length(sbuf, s, p - s);
-                  s = NULL;
+                  if (s)
+                    {
+                       eina_strbuf_append_length(sbuf, s, p - s);
+                       s = NULL;
+                    }
+                  else
+                    {
+                       ERR("There is a invalid markup tag at positoin '%u'. Please check the text.", (unsigned int) (p - text));
+                    }
                }
           }
         else if (*p == ';')
@@ -5431,7 +6804,6 @@ evas_textblock_text_utf8_to_markup(const Evas_Object *obj, const char *text)
 {
    Eina_Strbuf *sbuf;
    char *str = NULL;
-   int ch, pos = 0, pos2 = 0;
 
    (void) obj;
 
@@ -5439,31 +6811,8 @@ evas_textblock_text_utf8_to_markup(const Evas_Object *obj, const char *text)
 
    sbuf = eina_strbuf_new();
 
-   for (;;)
-     {
-        pos = pos2;
-        pos2 = evas_string_char_next_get(text, pos2, &ch);
-        if ((ch <= 0) || (pos2 <= 0)) break;
+   _markup_get_text_utf8_append(sbuf, text);
 
-        if (ch == _NEWLINE)
-           eina_strbuf_append(sbuf, "<br/>");
-        else if (ch == _TAB)
-           eina_strbuf_append(sbuf, "<tab/>");
-        else if (ch == '<')
-           eina_strbuf_append(sbuf, "&lt;");
-        else if (ch == '>')
-           eina_strbuf_append(sbuf, "&gt;");
-        else if (ch == '&')
-           eina_strbuf_append(sbuf, "&amp;");
-        else if (ch == _PARAGRAPH_SEPARATOR)
-           eina_strbuf_append(sbuf, "<ps/>");
-        else if (ch == _REPLACEMENT_CHAR)
-           eina_strbuf_append(sbuf, "&#xfffc;");
-        else
-          {
-             eina_strbuf_append_length(sbuf, text + pos, pos2 - pos);
-          }
-     }
    str = eina_strbuf_string_steal(sbuf);
    eina_strbuf_free(sbuf);
    return str;
@@ -5496,6 +6845,9 @@ _evas_textblock_nodes_merge(Evas_Object_Textblock *o, Evas_Object_Textblock_Node
    text = eina_ustrbuf_string_get(from->unicode);
    len = eina_ustrbuf_length_get(from->unicode);
    eina_ustrbuf_append_length(to->unicode, text, len);
+   // HAVE_UNICODE_EMOTICON(2013.10.07): Change text node of emoticon item.
+   _evas_object_textblock_emoticon_item_range_text_node_change(o, from, to, 0, len);
+   //
 
    itr = from->format_node;
    if (itr && (itr->text_node == from))
@@ -5896,6 +7248,11 @@ found:
         Evas_Textblock_Cursor cur;
         cur.obj = obj;
 
+        // HAVE_UNICODE_EMOTICON(2013.10.07): Delete emoticon items when the string of text node is deleted.
+        _evas_object_textblock_emoticon_item_range_delete(obj->layer->evas, o,
+                                                          n->text_node, ind,
+                                                          ind + 1);
+        //
         eina_ustrbuf_remove(n->text_node->unicode, ind, ind + 1);
         if (format && _IS_PARAGRAPH_SEPARATOR(o, format))
           {
@@ -6120,18 +7477,25 @@ evas_textblock_cursor_word_start(Evas_Textblock_Cursor *cur)
    if (!cur) return EINA_FALSE;
    TB_NULL_CHECK(cur->node, EINA_FALSE);
 
+   size_t len = eina_ustrbuf_length_get(cur->node->unicode);
+
    text = eina_ustrbuf_string_get(cur->node->unicode);
 
 #ifdef HAVE_LINEBREAK
      {
         const char *lang = ""; /* FIXME: get lang */
-        size_t len = eina_ustrbuf_length_get(cur->node->unicode);
         breaks = malloc(len);
         set_wordbreaks_utf32((const utf32_t *) text, len, lang, breaks);
      }
 #endif
 
-   i = cur->pos;
+   if ((cur->pos > 0) && (cur->pos == len))
+      cur->pos--;
+
+   for (i = cur->pos ; _is_white(text[i]) && BREAK_AFTER(i) ; i--)
+     {
+        if (i == 0) break;
+     }
 
    for ( ; i > 0 ; i--)
      {
@@ -6161,18 +7525,22 @@ evas_textblock_cursor_word_end(Evas_Textblock_Cursor *cur)
    if (!cur) return EINA_FALSE;
    TB_NULL_CHECK(cur->node, EINA_FALSE);
 
+   size_t len = eina_ustrbuf_length_get(cur->node->unicode);
+
+   if (cur->pos == len)
+      return EINA_TRUE;
+
    text = eina_ustrbuf_string_get(cur->node->unicode);
 
 #ifdef HAVE_LINEBREAK
      {
         const char *lang = ""; /* FIXME: get lang */
-        size_t len = eina_ustrbuf_length_get(cur->node->unicode);
         breaks = malloc(len);
         set_wordbreaks_utf32((const utf32_t *) text, len, lang, breaks);
      }
 #endif
 
-   i = cur->pos;
+   for (i = cur->pos; text[i] && _is_white(text[i]) && (BREAK_AFTER(i)) ; i++);
 
    for ( ; text[i] ; i++)
      {
@@ -6191,8 +7559,8 @@ evas_textblock_cursor_word_end(Evas_Textblock_Cursor *cur)
    return EINA_TRUE;
 }
 
-EAPI Eina_Bool
-evas_textblock_cursor_char_next(Evas_Textblock_Cursor *cur)
+static Eina_Bool
+_evas_textblock_cursor_next(Evas_Textblock_Cursor *cur, Eina_Bool per_cluster)
 {
    int ind;
    const Eina_Unicode *text;
@@ -6202,7 +7570,59 @@ evas_textblock_cursor_char_next(Evas_Textblock_Cursor *cur)
 
    ind = cur->pos;
    text = eina_ustrbuf_string_get(cur->node->unicode);
-   if (text[ind]) ind++;
+
+   if (text[ind])
+     {
+        if (per_cluster)
+          {
+             Evas_Object_Textblock_Paragraph *par = cur->node->par;
+
+             if (par)
+               {
+                  Eina_List *l;
+                  Evas_Object_Textblock_Item *it, *last_it = NULL;
+                  EINA_LIST_FOREACH(par->logical_items, l, it)
+                    {
+                       if (it->text_pos > cur->pos)
+                         {
+                            if (!last_it) last_it = it;
+                            break;
+                         }
+                       last_it = it;
+                    }
+
+                  if (last_it)
+                    {
+                       if ((last_it->type == EVAS_TEXTBLOCK_ITEM_TEXT) &&
+                           (CHECK_LANGUAGE_CLUSTER_AVAILABLE(_ITEM_TEXT(last_it)->text_props.script)))
+                         {
+                            size_t cluster_pos = 0;
+
+                            cluster_pos = last_it->text_pos + evas_common_text_props_cluster_next(
+                               &_ITEM_TEXT(last_it)->text_props, cur->pos - last_it->text_pos);
+
+                            if (cluster_pos == cur->pos)
+                              {
+                                 if (it)
+                                   {
+                                      cluster_pos = it->text_pos;
+                                   }
+                                 else
+                                   {
+                                      cluster_pos = eina_ustrbuf_length_get(cur->node->unicode);
+                                   }
+                              }
+
+                            ind = cluster_pos;
+                         }
+                    }
+               }
+          }
+
+        if (ind <= (int)cur->pos)
+          ind = cur->pos + 1;
+     }
+
    /* Only allow pointing a null if it's the last paragraph.
     * because we don't have a PS there. */
    if (text[ind])
@@ -6229,20 +7649,91 @@ evas_textblock_cursor_char_next(Evas_Textblock_Cursor *cur)
      }
 }
 
-EAPI Eina_Bool
-evas_textblock_cursor_char_prev(Evas_Textblock_Cursor *cur)
+static Eina_Bool
+_evas_textblock_cursor_prev(Evas_Textblock_Cursor *cur, Eina_Bool per_cluster)
 {
    if (!cur) return EINA_FALSE;
    TB_NULL_CHECK(cur->node, EINA_FALSE);
 
    if (cur->pos != 0)
      {
+        if (per_cluster)
+          {
+             Evas_Object_Textblock_Paragraph *par = cur->node->par;
+
+             if (par)
+               {
+                  Eina_List *l;
+                  Evas_Object_Textblock_Item *it, *last_it = NULL;
+                  EINA_LIST_FOREACH(par->logical_items, l, it)
+                    {
+                       if (it->text_pos >= cur->pos)
+                         {
+                            if (!last_it) last_it = it;
+                            break;
+                         }
+                       last_it = it;
+                    }
+
+                  if (last_it)
+                    {
+                       if ((last_it->type == EVAS_TEXTBLOCK_ITEM_TEXT) &&
+                           (CHECK_LANGUAGE_CLUSTER_AVAILABLE(_ITEM_TEXT(last_it)->text_props.script)))
+                         {
+                            size_t i = 0, cluster_temp = 0;
+                            size_t cluster_pos;
+
+                            cluster_pos = last_it->text_pos + evas_common_text_props_cluster_prev(
+                               &_ITEM_TEXT(last_it)->text_props, cur->pos - last_it->text_pos);
+                            cluster_temp = cluster_pos;
+
+                            while ((cur->pos - i > last_it->text_pos) &&
+                                   (cluster_temp == cur->pos - i))
+                              {
+                                 cluster_pos--;
+                                 i++;
+                                 cluster_temp = last_it->text_pos + evas_common_text_props_cluster_prev(
+                                    &_ITEM_TEXT(last_it)->text_props, cur->pos - last_it->text_pos - i);
+                              }
+
+                            cur->pos = cluster_pos;
+                            return EINA_TRUE;
+                         }
+                    }
+               }
+          }
+
         cur->pos--;
         return EINA_TRUE;
      }
+
    return evas_textblock_cursor_paragraph_prev(cur);
 }
 
+EAPI Eina_Bool
+evas_textblock_cursor_cluster_next(Evas_Textblock_Cursor *cur)
+{
+   return _evas_textblock_cursor_next(cur, EINA_TRUE);
+}
+
+EAPI Eina_Bool
+evas_textblock_cursor_cluster_prev(Evas_Textblock_Cursor *cur)
+{
+   return _evas_textblock_cursor_prev(cur, EINA_TRUE);
+}
+
+EAPI Eina_Bool
+evas_textblock_cursor_char_next(Evas_Textblock_Cursor *cur)
+{
+   return _evas_textblock_cursor_next(cur, EINA_FALSE);
+}
+
+EAPI Eina_Bool
+evas_textblock_cursor_char_prev(Evas_Textblock_Cursor *cur)
+{
+   return _evas_textblock_cursor_prev(cur, EINA_FALSE);
+}
+
 EAPI void
 evas_textblock_cursor_paragraph_char_first(Evas_Textblock_Cursor *cur)
 {
@@ -6281,6 +7772,8 @@ evas_textblock_cursor_line_char_first(Evas_Textblock_Cursor *cur)
    if (!cur) return;
    TB_NULL_CHECK(cur->node);
    o = (Evas_Object_Textblock *)(cur->obj->object_data);
+
+   evas_object_textblock_coords_recalc(cur->obj);
    if (!o->formatted.valid) _relayout(cur->obj);
 
    _find_layout_item_match(cur, &ln, &it);
@@ -6315,6 +7808,8 @@ evas_textblock_cursor_line_char_last(Evas_Textblock_Cursor *cur)
    if (!cur) return;
    TB_NULL_CHECK(cur->node);
    o = (Evas_Object_Textblock *)(cur->obj->object_data);
+
+   evas_object_textblock_coords_recalc(cur->obj);
    if (!o->formatted.valid) _relayout(cur->obj);
 
    _find_layout_item_match(cur, &ln, &it);
@@ -6403,6 +7898,43 @@ _evas_textblock_format_is_visible(Evas_Object_Textblock_Node_Format *fnode,
      }
 }
 
+// TIZEN_ONLY(20140626): Update format when the textblock style is updated.
+static void
+_evas_object_textblock_format_update(Evas_Object_Textblock *o)
+{
+   Evas_Object_Textblock_Node_Format *n;
+   const char *pre_stripped_format = NULL;
+
+   EINA_INLIST_FOREACH(o->format_nodes, n)
+     {
+        /* Update format */
+        const char *format;
+        const char *match;
+        size_t format_len = eina_stringshare_strlen(n->orig_format);
+
+        match = _textblock_format_node_from_style_tag(o, n, n->orig_format, format_len);
+        if (!match)
+          continue;
+
+        pre_stripped_format = match;
+
+        /* Strip format */
+          {
+             const char *tmp = pre_stripped_format;
+             if ((*tmp == '+') || (*tmp == '-'))
+               {
+                  tmp++;
+                  while (*tmp == ' ') tmp++;
+               }
+             eina_stringshare_replace(&(n->format), tmp);
+          }
+        format = n->format;
+
+        _evas_textblock_format_is_visible(n, format);
+     }
+}
+//
+
 /**
  * Sets the cursor to the position of where the fmt points to.
  *
@@ -6613,7 +8145,6 @@ _evas_textblock_node_text_adjust_offsets_to_start(Evas_Object_Textblock *o,
       Evas_Object_Textblock_Node_Text *n, size_t start, int end)
 {
    Evas_Object_Textblock_Node_Format *last_node, *itr;
-   Evas_Object_Textblock_Node_Text *new_node;
    int use_end = 1;
    int delta = 0;
    int first = 1;
@@ -6634,30 +8165,15 @@ _evas_textblock_node_text_adjust_offsets_to_start(Evas_Object_Textblock *o,
         end--;
      }
 
-   /* If we are not removing the text node, all should stay in this text
-    * node, otherwise, everything should move to the previous node */
-   if ((start == 0) && !use_end)
+   /* Find the first node after start */
+   while (itr && (itr->text_node == n))
      {
-        new_node = _NODE_TEXT(EINA_INLIST_GET(n)->prev);
-        if (!new_node)
+        pos += itr->offset;
+        if (pos >= start)
           {
-             new_node = n;
+             break;
           }
-     }
-   else
-     {
-        new_node = n;
-     }
-
-   /* Find the first node after start */
-   while (itr && (itr->text_node == n))
-     {
-        pos += itr->offset;
-        if (pos >= start)
-          {
-             break;
-          }
-        itr = _NODE_FORMAT(EINA_INLIST_GET(itr)->next);
+        itr = _NODE_FORMAT(EINA_INLIST_GET(itr)->next);
      }
 
    if (!itr || (itr->text_node != n))
@@ -6706,7 +8222,6 @@ _evas_textblock_node_text_adjust_offsets_to_start(Evas_Object_Textblock *o,
                }
 
           }
-        last_node->text_node = new_node;
      }
 
    return EINA_FALSE;
@@ -6867,6 +8382,8 @@ evas_textblock_cursor_line_set(Evas_Textblock_Cursor *cur, int line)
 
    if (!cur) return EINA_FALSE;
    o = (Evas_Object_Textblock *)(cur->obj->object_data);
+
+   evas_object_textblock_coords_recalc(cur->obj);
    if (!o->formatted.valid) _relayout(cur->obj);
 
    ln = _find_layout_line_num(cur->obj, line);
@@ -7025,6 +8542,9 @@ _evas_textblock_cursor_break_paragraph(Evas_Textblock_Cursor *cur,
         if (len > 0)
           {
              text = eina_ustrbuf_string_get(cur->node->unicode);
+             // HAVE_UNICODE_EMOTICON(2013.10.07): Change text node of emoticon item.
+             _evas_object_textblock_emoticon_item_range_text_node_change(o, cur->node, n, start, start + len);
+             //
              eina_ustrbuf_append_length(n->unicode, text + start, len);
              eina_ustrbuf_remove(cur->node->unicode, start, start + len);
              cur->node->dirty = EINA_TRUE;
@@ -7144,6 +8664,14 @@ _evas_textblock_changed(Evas_Object_Textblock *o, Evas_Object *obj)
    o->formatted.valid = 0;
    o->native.valid = 0;
    o->content_changed = 1;
+   // TIZEN_ONLY(20140702): Add pressed_color tag feature
+   if (o->has_pressed_color)
+     {
+        evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_DOWN, _textblock_mouse_down_cb);
+        evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_UP, _textblock_mouse_up_cb);
+        o->has_pressed_color = EINA_FALSE;
+     }
+   //
    if (o->markup_text)
      {
        free(o->markup_text);
@@ -7290,7 +8818,6 @@ _evas_textblock_node_format_new(Evas_Object_Textblock *o, const char *_format)
      {
         const char *match;
         size_t format_len;
-        size_t replace_len;
 
         format++; /* Advance after '<' */
         format_len = strlen(format);
@@ -7298,31 +8825,20 @@ _evas_textblock_node_format_new(Evas_Object_Textblock *o, const char *_format)
           {
              format_len--; /* We don't care about '>' */
              /* Check if it closes itself. Skip the </> case. */
-             if ((format_len > 1) && format[format_len - 1] == '/')
+             // TIZEN_ONLY(20140620): Check Anchor, Item type before set own closer flag.
+             // if ((format_len > 1) && format[format_len - 1] == '/')
+             if ((format_len > 1) && format[format_len - 1] == '/'
+                 && strncmp(format, "a ", 2) && strncmp(format, "item ", 5))
                {
                   format_len--; /* We don't care about '/' */
                   n->own_closer = EINA_TRUE;
                }
           }
 
-        if (!o->style_user || !(match = _style_match_tag(o->style_user, format,
-                    format_len, &replace_len)))
-          {
-             match = _style_match_tag(o->style, format, format_len,
-                   &replace_len);
-          }
+        match = _textblock_format_node_from_style_tag(o, n, format, format_len);
 
         if (match)
           {
-             if (match[0] != '-')
-               {
-                  n->opener = EINA_TRUE;
-                  if (match[0] != '+')
-                    {
-                       n->own_closer = EINA_TRUE;
-                    }
-               }
-
              pre_stripped_format = match;
           }
         else
@@ -7447,6 +8963,7 @@ evas_textblock_cursor_format_append(Evas_Textblock_Cursor *cur, const char *form
           }
         else
           {
+             fmt = _evas_textblock_node_format_last_at_off(fmt);
              if (evas_textblock_cursor_format_is_visible_get(cur))
                {
                   o->format_nodes = _NODE_FORMAT(eina_inlist_prepend_relative(
@@ -7462,7 +8979,6 @@ evas_textblock_cursor_format_append(Evas_Textblock_Cursor *cur, const char *form
                }
              else
                {
-                  fmt = _evas_textblock_node_format_last_at_off(fmt);
                   o->format_nodes = _NODE_FORMAT(eina_inlist_append_relative(
                            EINA_INLIST_GET(o->format_nodes),
                            EINA_INLIST_GET(n),
@@ -7574,6 +9090,10 @@ evas_textblock_cursor_char_delete(Evas_Textblock_Cursor *cur)
 
    if (chr == 0) return;
    ppos = cur->pos;
+   // HAVE_UNICODE_EMOTICON(2013.10.07): Delete emoticon items when the string of text node is deleted.
+   _evas_object_textblock_emoticon_item_range_delete(cur->obj->layer->evas, o, n,
+                                                     cur->pos, ind);
+   //
    eina_ustrbuf_remove(n->unicode, cur->pos, ind);
    /* Remove a format node if needed, and remove the char only if the
     * fmt node is not visible */
@@ -7670,23 +9190,18 @@ evas_textblock_cursor_range_delete(Evas_Textblock_Cursor *cur1, Evas_Textblock_C
                {
                   should_merge = EINA_TRUE;
                }
-             else
-               {
-                  n = _NODE_TEXT(EINA_INLIST_GET(n1)->prev);
-                  /* Short path */
-                  if (!n)
-                    {
-                       /* Clear the whole textblock - do it nicer. */
-                       evas_object_textblock_text_markup_set(cur1->obj, "");
-                       return;
-                    }
-               }
+             _evas_textblock_node_text_adjust_offsets_to_start(o, n1, cur1->pos, -1);
           }
         else
           {
              should_merge = _evas_textblock_node_text_adjust_offsets_to_start(o,
                    n1, cur1->pos, cur2->pos);
           }
+        // HAVE_UNICODE_EMOTICON(2013.10.07): Delete emoticon items when the string of text node is deleted.
+        _evas_object_textblock_emoticon_item_range_delete(cur1->obj->layer->evas,
+                                                          o, n1, cur1->pos,
+                                                          cur2->pos);
+        //
         eina_ustrbuf_remove(n1->unicode, cur1->pos, cur2->pos);
         _evas_textblock_cursors_update_offset(cur1, cur1->node, cur1->pos, - (cur2->pos - cur1->pos));
      }
@@ -7694,7 +9209,6 @@ evas_textblock_cursor_range_delete(Evas_Textblock_Cursor *cur1, Evas_Textblock_C
      {
         Evas_Object_Textblock_Node_Text *n;
         int len;
-        _evas_textblock_node_text_adjust_offsets_to_start(o, n1, cur1->pos, -1);
         n = _NODE_TEXT(EINA_INLIST_GET(n1)->next);
         /* Remove all the text nodes between */
         while (n && (n != n2))
@@ -7702,15 +9216,24 @@ evas_textblock_cursor_range_delete(Evas_Textblock_Cursor *cur1, Evas_Textblock_C
              Evas_Object_Textblock_Node_Text *nnode;
 
              nnode = _NODE_TEXT(EINA_INLIST_GET(n)->next);
-             _evas_textblock_node_text_adjust_offsets_to_start(o, n, 0, -1);
              _evas_textblock_nodes_merge(o, n1);
              n = nnode;
           }
+        /* After we merged all the nodes, move the formats to the start of
+         * the range. */
+        _evas_textblock_node_text_adjust_offsets_to_start(o, n1, cur1->pos, -1);
+
         should_merge = _evas_textblock_node_text_adjust_offsets_to_start(o, n2,
               0, cur2->pos);
 
         /* Remove the formats and the strings in the first and last nodes */
         len = eina_ustrbuf_length_get(n1->unicode);
+        // HAVE_UNICODE_EMOTICON(2013.10.07): Delete emoticon items when the string of text node is deleted.
+        _evas_object_textblock_emoticon_item_range_delete(cur1->obj->layer->evas,
+                                                          o, n1, cur1->pos, len);
+        _evas_object_textblock_emoticon_item_range_delete(cur1->obj->layer->evas,
+                                                          o, n2, 0, cur2->pos);
+        //
         eina_ustrbuf_remove(n1->unicode, cur1->pos, len);
         eina_ustrbuf_remove(n2->unicode, 0, cur2->pos);
         /* Merge the nodes because we removed the PS */
@@ -7782,11 +9305,12 @@ _evas_textblock_cursor_range_text_markup_get(const Evas_Textblock_Cursor *cur1,
    Evas_Object_Textblock_Node_Text *tnode;
    Eina_Strbuf *buf;
    Evas_Textblock_Cursor *cur2;
-   buf = eina_strbuf_new();
 
    if (!cur1 || !cur1->node) return NULL;
    if (!_cur2 || !_cur2->node) return NULL;
    if (cur1->obj != _cur2->obj) return NULL;
+   buf = eina_strbuf_new();
+
    if (evas_textblock_cursor_compare(cur1, _cur2) > 0)
      {
        const Evas_Textblock_Cursor *tc;
@@ -7806,26 +9330,18 @@ _evas_textblock_cursor_range_text_markup_get(const Evas_Textblock_Cursor *cur1,
      {
         Evas_Object_Textblock_Node_Format *fnode;
         Eina_Unicode *text_base, *text;
+        int cur1_pos = 0, cur2_pos = -1;
         int off = 0;
 
         text_base = text =
            eina_unicode_strndup(eina_ustrbuf_string_get(tnode->unicode),
                                 eina_ustrbuf_length_get(tnode->unicode));
         if (tnode == cur2->node)
-          {
-             fnode = _evas_textblock_node_text_get_first_format_between(tnode,
-                   cur1->pos, cur2->pos);
-          }
-        else if (tnode == cur1->node)
-          {
-             fnode = _evas_textblock_node_text_get_first_format_between(tnode,
-                   cur1->pos, -1);
-          }
-        else
-          {
-             fnode = _evas_textblock_node_text_get_first_format_between(tnode,
-                   0, -1);
-          }
+          cur2_pos = cur2->pos;
+        if (tnode == cur1->node)
+          cur1_pos = cur1->pos;
+        fnode = _evas_textblock_node_text_get_first_format_between(tnode,
+                cur1_pos, cur2_pos);
         /* Init the offset so the first one will count starting from cur1->pos
          * and not the previous format node */
         if (tnode == cur1->node)
@@ -7901,11 +9417,11 @@ _evas_textblock_cursor_range_text_plain_get(const Evas_Textblock_Cursor *cur1, c
    Evas_Object_Textblock_Node_Text *n1, *n2;
    Evas_Textblock_Cursor *cur2;
 
-   buf = eina_ustrbuf_new();
-
    if (!cur1 || !cur1->node) return NULL;
    if (!_cur2 || !_cur2->node) return NULL;
    if (cur1->obj != _cur2->obj) return NULL;
+   buf = eina_ustrbuf_new();
+
    if (evas_textblock_cursor_compare(cur1, _cur2) > 0)
      {
        const Evas_Textblock_Cursor *tc;
@@ -8023,6 +9539,408 @@ evas_textblock_cursor_range_formats_get(const Evas_Textblock_Cursor *cur1, const
 
 }
 
+// TIZEN_ONLY(20131218)
+// Add evas_textblock_cursor_range_text_valid_markup_get API.
+static void
+_evas_textblock_format_search_prepend(Eina_Strbuf *buf, Evas_Object_Textblock_Node_Format *format_node, Eina_List **invalid_fnodes)
+{
+   Eina_List *list = NULL, *l = NULL, *l_next = NULL;
+   Evas_Object_Textblock_Format_Pair_Item *data, *new;
+   Evas_Object_Textblock_Node_Format *fnode, *fn;
+   char *simple_format, *copy;
+
+   fnode = format_node;
+   if (!fnode) return;
+
+   while (fnode)
+     {
+        if (fnode->own_closer) goto next;
+        if (fnode->visible) goto next;
+        if (fnode->opener)
+          {
+             EINA_LIST_FOREACH_SAFE(list, l, l_next, data)
+               {
+                  if (data->void_closer ||
+                      !strncmp(fnode->orig_format, data->format, strlen(data->format)))
+                    {
+                       if (data->format)
+                         free((void *)data->format);
+                       free((void *)data);
+                       list = eina_list_remove_list(list, l);
+                       goto next;
+                    }
+               }
+             EINA_LIST_FOREACH_SAFE(*invalid_fnodes, l, l_next, fn)
+               {
+                  if (!strncmp(fnode->orig_format, fn->orig_format, strlen(fn->orig_format)))
+                    {
+                       *invalid_fnodes = eina_list_remove_list(*invalid_fnodes, l);
+                       goto next;
+                    }
+               }
+             _markup_get_format_prepend(buf, fnode);
+          }
+        else
+          {
+             copy = strdup(fnode->orig_format);
+             simple_format = strtok(copy, " ,=");
+
+             new = calloc(1, sizeof(Evas_Object_Textblock_Format_Pair_Item));
+             if (!simple_format)
+               {
+                  new->void_closer = EINA_TRUE;
+                  new->format = NULL;
+               }
+             else
+               {
+                  new->void_closer = EINA_FALSE;
+                  new->format = calloc(strlen(simple_format) + 1, 1);
+                  strcpy(new->format, simple_format);
+               }
+
+             free(copy);
+             list = eina_list_prepend(list, new);
+          }
+next:
+        fnode = _NODE_FORMAT(EINA_INLIST_GET(fnode)->prev);
+     }
+
+   EINA_LIST_FOREACH(list, l, data)
+     {
+        if (data->format)
+          free((void *)data->format);
+        free((void *)data);
+     }
+   eina_list_free(list);
+}
+
+// TIZEN_ONLY(20131218)
+// Add evas_textblock_cursor_range_text_valid_markup_get API.
+static void
+_evas_textblock_format_search_append(Eina_Strbuf *buf, Evas_Object_Textblock_Node_Format *format_node)
+{
+   Eina_List *list = NULL, *l = NULL, *l_next = NULL;
+   Evas_Object_Textblock_Format_Pair_Item *data, *new;
+   Eina_Bool void_closer = EINA_FALSE;
+   Evas_Object_Textblock_Node_Format *fnode;
+   char *simple_format, *copy;
+
+   fnode = format_node;
+   if (!fnode) return;
+
+   while (fnode)
+     {
+        if (fnode->own_closer) goto next;
+        if (fnode->visible && strncmp(fnode->orig_format, "item", 4)) goto next;
+        if (!fnode->opener)
+          {
+             if (!strcmp(fnode->orig_format, ""))
+               void_closer = EINA_TRUE;
+
+             EINA_LIST_FOREACH_SAFE(list, l, l_next, data)
+               {
+                  if (void_closer || (data->void_closer) ||
+                      !strncmp(fnode->orig_format, data->format, strlen(data->format)))
+                    {
+                       void_closer = EINA_FALSE;
+                       if (data->format)
+                         free((void *)data->format);
+                       free((void *)data);
+                       list = eina_list_remove_list(list, l);
+                       goto next;
+                    }
+               }
+             _markup_get_format_append(buf, fnode);
+          }
+        else
+          {
+             copy = strdup(fnode->orig_format);
+             simple_format = strtok(copy, " ,=");
+
+             new = calloc(1, sizeof(Evas_Object_Textblock_Format_Pair_Item));
+             if (!simple_format)
+               {
+                  new->void_closer = EINA_TRUE;
+                  new->format = NULL;
+               }
+             else
+               {
+                  new->format = calloc(strlen(simple_format) + 1, 1);
+                  strcpy(new->format, simple_format);
+               }
+
+             free(copy);
+             list = eina_list_prepend(list, new);
+          }
+next:
+        fnode = _NODE_FORMAT(EINA_INLIST_GET(fnode)->next);
+     }
+
+   EINA_LIST_FOREACH(list, l, data)
+     {
+        if (data->format)
+          free((void *)data->format);
+        free((void *)data);
+     }
+   eina_list_free(list);
+}
+
+// TIZEN_ONLY(20131218)
+// Add evas_textblock_cursor_range_text_valid_markup_get API.
+static char *
+_evas_textblock_cursor_range_text_valid_markup_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *_cur2)
+{
+   Evas_Object_Textblock_Node_Text *tnode;
+   Evas_Object_Textblock_Node_Format *start_fnode = NULL,*prev_fnode = NULL;
+   Eina_Strbuf *buf;
+   Evas_Textblock_Cursor *cur2;
+   Eina_Bool valid_result;
+   Eina_List *invalid_fnodes = NULL;
+   int item_pair = 0;
+
+   if (!cur1 || !cur1->node) return NULL;
+   if (!_cur2 || !_cur2->node) return NULL;
+   if (cur1->obj != _cur2->obj) return NULL;
+   buf = eina_strbuf_new();
+
+   if (evas_textblock_cursor_compare(cur1, _cur2) > 0)
+     {
+        const Evas_Textblock_Cursor *tc;
+
+        tc = cur1;
+        cur1 = _cur2;
+        _cur2 = tc;
+     }
+   /* Work on a local copy of the cur */
+   cur2 = alloca(sizeof(Evas_Textblock_Cursor));
+   cur2->obj = _cur2->obj;
+   evas_textblock_cursor_copy(_cur2, cur2);
+   valid_result = EINA_FALSE;
+
+   /* Parse the text between the cursors. */
+   for (tnode = cur1->node ; tnode ;
+        tnode = _NODE_TEXT(EINA_INLIST_GET(tnode)->next))
+     {
+        Evas_Object_Textblock_Node_Format *fnode;
+        Eina_Unicode *text_base, *text;
+        int cur1_pos = 0, cur2_pos = -1;
+        int off = 0;
+
+        text_base = text =
+           eina_unicode_strndup(eina_ustrbuf_string_get(tnode->unicode),
+                                eina_ustrbuf_length_get(tnode->unicode));
+        if (tnode == cur2->node)
+          cur2_pos = cur2->pos;
+        if (tnode == cur1->node)
+          cur1_pos = cur1->pos;
+        fnode = _evas_textblock_node_text_get_first_format_between(tnode,
+                cur1_pos, cur2_pos);
+        /* Init the offset so the first one will count starting from cur1->pos
+         * and not the previous format node */
+        if (tnode == cur1->node)
+          {
+             if (fnode)
+               {
+                  off = _evas_textblock_node_format_pos_get(fnode) -
+                     cur1->pos - fnode->offset;
+               }
+             text += cur1->pos;
+          }
+        else
+          {
+             off = 0;
+          }
+
+        // Keep start position for searching format
+        if (tnode == cur1->node)
+          start_fnode = fnode;
+        //////////////
+
+        while (fnode && (fnode->text_node == tnode))
+          {
+             Eina_Unicode tmp_ch;
+             off += fnode->offset;
+             if ((tnode == cur2->node) &&
+                 ((size_t) (text - text_base + off) >= cur2->pos))
+               {
+                  break;
+               }
+             /* No need to skip on the first run */
+             tmp_ch = text[off];
+             text[off] = 0; /* Null terminate the part of the string */
+             if ((!valid_result) && (*text))
+               valid_result = EINA_TRUE;
+
+             _markup_get_text_append(buf, text);
+
+             // Closer item format is invisible and opener item format is visible.
+             // So, we need to get rid of useless item closer format.
+             if (!strncmp(fnode->orig_format, "item", 4))
+               {
+                  if (fnode->opener)
+                    {
+                       item_pair++;
+                       _markup_get_format_append(buf, fnode);
+                    }
+                  else if (item_pair > 0)
+                    {
+                       item_pair--;
+                       _markup_get_format_append(buf, fnode);
+                    }
+               }
+             else
+               {
+                  if ((!fnode->visible) && (!fnode->opener) && (!valid_result))
+                    invalid_fnodes = eina_list_append(invalid_fnodes, fnode);
+                  else
+                    {
+                       if (fnode->visible)
+                         valid_result = EINA_TRUE;
+                       _markup_get_format_append(buf, fnode);
+                    }
+               }
+             ////////////////
+
+             text[off] = tmp_ch; /* Restore the char */
+             text += off;
+             if (fnode->visible)
+               {
+                  off = -1;
+                  text++;
+               }
+             else
+               {
+                  off = 0;
+               }
+             fnode = _NODE_FORMAT(EINA_INLIST_GET(fnode)->next);
+          }
+        /* If we got to the last node, stop and add the rest outside */
+        if (cur2->node == tnode)
+          {
+             /* Add the rest, skip replacement */
+             /* Don't go past the second cursor pos */
+             text_base[cur2->pos] = '\0';
+             _markup_get_text_append(buf, text);
+             free(text_base);
+             if ((!valid_result) && (*text))
+               valid_result = EINA_TRUE;
+
+             // Search valid opener markup tag
+             if (start_fnode)
+               {
+                  _evas_textblock_format_search_prepend(buf, _NODE_FORMAT(EINA_INLIST_GET(start_fnode)->prev), &invalid_fnodes);
+                  prev_fnode = NULL;
+               }
+             else
+               {
+                  size_t pos = cur1->pos;
+                  while (pos > 0 && !prev_fnode)
+                    {
+                       prev_fnode = _evas_textblock_node_text_get_first_format_between(cur1->node,
+                                                                                       --pos, cur1->pos);
+                    }
+                  if (!prev_fnode)
+                    {
+                       Evas_Object_Textblock_Node_Text *prev_tnode, *text_temp;
+                       Evas_Object_Textblock_Node_Format *format_temp;
+
+                       prev_tnode = _NODE_TEXT(EINA_INLIST_GET(cur1->node)->prev);
+
+                       if (prev_tnode)
+                         {
+                            while (1)
+                              {
+                                 prev_fnode = prev_tnode->format_node;
+                                 if (prev_fnode)
+                                   break;
+                                 text_temp = _NODE_TEXT(EINA_INLIST_GET(prev_tnode)->prev);
+                                 if (!text_temp)
+                                   break;
+                                 prev_tnode = text_temp;
+                              }
+                         }
+                       while (prev_fnode)
+                         {
+                            format_temp = _NODE_FORMAT(EINA_INLIST_GET(prev_fnode)->next);
+                            if (!format_temp || (format_temp->text_node != prev_tnode))
+                              break;
+                            prev_fnode = format_temp;
+                         }
+                    }
+                  if (prev_fnode)
+                    _evas_textblock_format_search_prepend(buf, prev_fnode, &invalid_fnodes);
+               }
+             if (invalid_fnodes)
+               invalid_fnodes = eina_list_free(invalid_fnodes);
+
+             // Search valid closer markup tag
+             if (fnode)
+               {
+                  _evas_textblock_format_search_append(buf, fnode);
+               }
+             else if (prev_fnode)
+               {
+                  _evas_textblock_format_search_append(buf, _NODE_FORMAT(EINA_INLIST_GET(prev_fnode)->next));
+               }
+             else
+               {
+                  Evas_Object_Textblock_Node_Format *next_fnode = NULL;
+                  next_fnode = _evas_textblock_node_text_get_first_format_between(tnode, cur2->pos, -1);
+                  Evas_Object_Textblock_Node_Text *text_temp;
+
+                  if (!next_fnode)
+                    {
+                       Evas_Object_Textblock_Node_Text *next_tnode = _NODE_TEXT(EINA_INLIST_GET(tnode)->next);
+                       if (next_tnode)
+                         {
+                            while (1)
+                              {
+                                 next_fnode = next_tnode->format_node;
+                                 if (next_fnode)
+                                   break;
+                                 text_temp = _NODE_TEXT(EINA_INLIST_GET(next_tnode)->next);
+                                 if (!text_temp)
+                                   break;
+                                 next_tnode = text_temp;
+                              }
+                         }
+                    }
+                  if (next_fnode)
+                    _evas_textblock_format_search_append(buf, next_fnode);
+               }
+             ///////////
+             break;
+          }
+        else
+          {
+             /* Add the rest, skip replacement */
+             _markup_get_text_append(buf, text);
+             free(text_base);
+             if ((!valid_result) && (*text))
+               valid_result = EINA_TRUE;
+          }
+     }
+   /* return the string */
+     {
+        char *ret, *utf8_ret;
+        ret = eina_strbuf_string_steal(buf);
+        utf8_ret = evas_textblock_text_markup_to_utf8(NULL, ret);
+        eina_strbuf_free(buf);
+        DBG("RESULT [%s], utf8[%s]", ret, utf8_ret);
+        if ((!utf8_ret) || (!strcmp(utf8_ret, "")))
+          return NULL;
+        return ret;
+     }
+}
+
+// TIZEN_ONLY(20131218)
+// Add evas_textblock_cursor_range_text_valid_markup_get API.
+EAPI char *
+evas_textblock_cursor_range_text_valid_markup_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2)
+{
+   return _evas_textblock_cursor_range_text_valid_markup_get(cur1, cur2);
+}
+
 EAPI char *
 evas_textblock_cursor_range_text_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2, Evas_Textblock_Text_Type format)
 {
@@ -8122,18 +10040,223 @@ evas_textblock_cursor_format_is_visible_get(const Evas_Textblock_Cursor *cur)
    return EVAS_TEXTBLOCK_IS_VISIBLE_FORMAT_CHAR(text[cur->pos]);
 }
 
+#ifdef BIDI_SUPPORT
+static Evas_Object_Textblock_Line*
+_find_layout_line_by_item(Evas_Object_Textblock_Paragraph *par, Evas_Object_Textblock_Item *_it)
+{
+   Evas_Object_Textblock_Line *ln;
+
+   if (par)
+     {
+        EINA_INLIST_FOREACH(par->lines, ln)
+          {
+             Evas_Object_Textblock_Item *it;
+
+             EINA_INLIST_FOREACH(ln->items, it)
+               {
+                  if (_it == it)
+                    return ln;
+               }
+          }
+     }
+   return NULL;
+}
+#endif
+
+EAPI Eina_Bool
+evas_textblock_cursor_geometry_bidi_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_Coord *cx2, Evas_Coord *cy2, Evas_Coord *cw2, Evas_Coord *ch2, Evas_Textblock_Cursor_Type ctype)
+{
+   if (!cur) return EINA_FALSE;
+   Evas_Object_Textblock *o = cur->obj->object_data;
+
+   evas_object_textblock_coords_recalc(cur->obj);
+   if (!o->formatted.valid) _relayout(cur->obj);
+
+   if (ctype == EVAS_TEXTBLOCK_CURSOR_UNDER)
+     {
+        evas_textblock_cursor_pen_geometry_get(cur, cx, cy, cw, ch);
+        return EINA_FALSE;
+     }
+
+#ifdef BIDI_SUPPORT
+#define IS_RTL(par) ((par) % 2)
+#define IS_DIFFERENT_DIR(l1, l2) ((IS_RTL(l1) && (!IS_RTL(l2))) || \
+                                  ((!IS_RTL(l1)) && IS_RTL(l2)))
+   else
+     {
+        Evas_Object_Textblock_Line *ln = NULL;
+        Evas_Object_Textblock_Item *it = NULL;
+        _find_layout_item_match(cur, &ln, &it);
+        if (ln && it)
+          {
+             if (ln->par->is_bidi)
+               {
+                  if (cw) *cw = 0;
+                  if (cw2) *cw2 = 0;
+
+                  /* If we are at the start or the end of the item there's a chance
+                   *                    * we'll want a split cursor.  */
+                  Evas_Object_Textblock_Item *previt = NULL;
+                  Evas_Object_Textblock_Item *it1 = NULL, *it2 = NULL;
+                  Evas_Coord adv1 = 0, adv2 = 0;
+
+                  if (cur->pos == it->text_pos)
+                    {
+                       EvasBiDiLevel par_level, it_level, previt_level;
+
+                       _layout_update_bidi_props(o, ln->par);
+                       par_level = *(ln->par->bidi_props->embedding_levels);
+                       it_level = ln->par->bidi_props->embedding_levels[it->text_pos];
+                       /* Get the logically previous item. */
+                         {
+                            Eina_List *itr;
+                            Evas_Object_Textblock_Item *ititr;
+
+                            EINA_LIST_FOREACH(ln->par->logical_items, itr, ititr)
+                              {
+                                 if (ititr == it)
+                                   break;
+                                 previt = ititr;
+                              }
+
+                            if (previt)
+                              {
+                                 previt_level = ln->par->bidi_props->embedding_levels[previt->text_pos];
+                              }
+                         }
+
+                       if (previt && (it_level != previt_level))
+                         {
+                            Evas_Object_Textblock_Item *curit = NULL, *curit_opp = NULL;
+                            EvasBiDiLevel cur_level;
+
+                            if (it_level > previt_level)
+                              {
+                                 curit = it;
+                                 curit_opp = previt;
+                                 cur_level = it_level;
+                              }
+                            else
+                              {
+                                 curit = previt;
+                                 curit_opp = it;
+                                 cur_level = previt_level;
+                              }
+
+                            if (((curit == it) && (!IS_RTL(par_level))) ||
+                                ((curit == previt) && (IS_RTL(par_level))))
+                              {
+                                 adv1 = (IS_DIFFERENT_DIR(cur_level, par_level)) ?
+                                    curit_opp->adv : 0;
+                                 adv2 = curit->adv;
+                              }
+                            else if (((curit == previt) && (!IS_RTL(par_level))) ||
+                                     ((curit == it) && (IS_RTL(par_level))))
+                              {
+                                 adv1 = (IS_DIFFERENT_DIR(cur_level, par_level)) ?
+                                    0 : curit->adv;
+                                 adv2 = 0;
+                              }
+
+                            if (!IS_DIFFERENT_DIR(cur_level, par_level))
+                              curit_opp = curit;
+
+                            it1 = curit_opp;
+                            it2 = curit;
+                         }
+                       /* Clear the bidi props because we don't need them anymore. */
+                       evas_bidi_paragraph_props_unref(ln->par->bidi_props);
+                       ln->par->bidi_props = NULL;
+                    }
+                  /* Handling last char in line (or in paragraph).
+                   *                    * T.e. prev condition didn't work, so we are not standing in the beginning of item,
+                   *                                       * but in the end of line or paragraph. */
+                  else if (evas_textblock_cursor_eol_get(cur))
+                    {
+                       EvasBiDiLevel par_level, it_level;
+
+                       _layout_update_bidi_props(o, ln->par);
+                       par_level = *(ln->par->bidi_props->embedding_levels);
+                       it_level = ln->par->bidi_props->embedding_levels[it->text_pos];
+
+                       if (it_level > par_level)
+                         {
+                            Evas_Object_Textblock_Item *lastit = it;
+
+                            if (IS_RTL(par_level)) /* RTL par*/
+                              {
+                                 /*  We know, that all the items before current are of the same or bigger embedding level.
+                                  *                                    *  So search backwards for the first one. */
+                                 while (EINA_INLIST_GET(lastit)->prev)
+                                   {
+                                      lastit = _EINA_INLIST_CONTAINER(it, EINA_INLIST_GET(lastit)->prev);
+                                   }
+
+                                 adv1 = 0;
+                                 adv2 = it->adv;
+                              }
+                            else /* LTR par */
+                              {
+                                 /*  We know, that all the items after current are of bigger or same embedding level.
+                                  *                                    *  So search forward for the last one. */
+                                 while (EINA_INLIST_GET(lastit)->next)
+                                   {
+                                      lastit = _EINA_INLIST_CONTAINER(it, EINA_INLIST_GET(lastit)->next);
+                                   }
+
+                                 adv1 = lastit->adv;
+                                 adv2 = 0;
+                              }
+
+                            it1 = lastit;
+                            it2 = it;
+                         }
+                       /* Clear the bidi props because we don't need them anymore. */
+                       evas_bidi_paragraph_props_unref(ln->par->bidi_props);
+                       ln->par->bidi_props = NULL;
+                    }
+
+                  if (it1 && it2)
+                    {
+                       Evas_Object_Textblock_Line *ln1 = NULL, *ln2 = NULL;
+                       ln1 = _find_layout_line_by_item(ln->par, it1);
+                       if (cx) *cx = ln1->x + it1->x + adv1;
+                       if (cy) *cy = ln1->par->y + ln1->y;
+                       if (ch) *ch = ln1->h;
+
+                       ln2 = _find_layout_line_by_item(ln->par, it2);
+                       if (cx2) *cx2 = ln2->x + it2->x + adv2;
+                       if (cy2) *cy2 = ln2->par->y + ln2->y;
+                       if (ch2) *ch2 = ln2->h;
+
+                       return EINA_TRUE;
+                    }
+               }
+          }
+     }
+#undef IS_DIFFERENT_DIR
+#undef IS_RTL
+#else
+   (void) cx2;
+   (void) cy2;
+   (void) cw2;
+   (void) ch2;
+#endif
+   evas_textblock_cursor_geometry_get(cur, cx, cy, cw, ch, NULL, ctype);
+   return EINA_FALSE;
+}
+
 EAPI int
 evas_textblock_cursor_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_BiDi_Direction *dir, Evas_Textblock_Cursor_Type ctype)
 {
    int ret = -1;
-   const Evas_Textblock_Cursor *dir_cur;
-   Evas_Textblock_Cursor cur2;
    Evas_Object_Textblock *o;
    if (!cur) return -1;
    o = (Evas_Object_Textblock *)(cur->obj->object_data);
+
+   evas_object_textblock_coords_recalc(cur->obj);
    if (!o->formatted.valid) _relayout(cur->obj);
 
-   dir_cur = cur;
    if (ctype == EVAS_TEXTBLOCK_CURSOR_UNDER)
      {
         ret = evas_textblock_cursor_pen_geometry_get(cur, cx, cy, cw, ch);
@@ -8143,142 +10266,30 @@ evas_textblock_cursor_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord
         /* In the case of a "before cursor", we should get the coordinates
          * of just after the previous char (which in bidi text may not be
          * just before the current char). */
-        Evas_Coord x, y, h, w;
-        Evas_Object_Textblock_Node_Format *fmt;
+        Evas_Coord x, y, w, h;
 
-        /* If it's at the end of the line, we want to get the position, not
-         * the position of the previous */
-        if ((cur->pos > 0) && !_evas_textblock_cursor_is_at_the_end(cur))
-          {
-#ifdef BIDI_SUPPORT
-             Eina_Bool before_char = EINA_FALSE;
-#endif
-             cur2.obj = cur->obj;
-             evas_textblock_cursor_copy(cur, &cur2);
-             evas_textblock_cursor_char_prev(&cur2);
-
-             fmt = _evas_textblock_cursor_node_format_at_pos_get(&cur2);
+        Evas_Object_Textblock_Line *ln;
+        Evas_Object_Textblock_Item *it;
 
-             if (!fmt || !_IS_LINE_SEPARATOR(fmt->format))
+        ret = evas_textblock_cursor_pen_geometry_get(cur, &x, &y, &w, &h);
+        _find_layout_item_match(cur, &ln, &it);
+        if (ret >= 0)
+          {
+             Evas_BiDi_Direction itdir =
+                (it->type == EVAS_TEXTBLOCK_ITEM_TEXT) ?
+                _ITEM_TEXT(it)->text_props.bidi.dir :
+                _ITEM_FORMAT(it)->bidi_dir;
+             if (itdir == EVAS_BIDI_DIRECTION_RTL)
                {
-                  dir_cur = &cur2;
-#ifdef BIDI_SUPPORT
-                  before_char = EINA_FALSE;
-#endif
+                  if (cx) *cx = x + w;
                }
-#ifdef BIDI_SUPPORT
              else
                {
-                  before_char = EINA_TRUE;
+                  if (cx) *cx = x;
                }
-#endif
-             ret = evas_textblock_cursor_pen_geometry_get(
-                   dir_cur, &x, &y, &w, &h);
-#ifdef BIDI_SUPPORT
-             /* Adjust if the char is an rtl char */
-             if (ret >= 0)
-               {
-                  Eina_Bool is_rtl = EINA_FALSE;
-                  if (dir_cur->node->par->is_bidi)
-                    {
-                       Evas_Object_Textblock_Line *ln;
-                       Evas_Object_Textblock_Item *it;
-                       _find_layout_item_match(dir_cur, &ln, &it);
-                       if ((it->type == EVAS_TEXTBLOCK_ITEM_TEXT) &&
-                             (_ITEM_TEXT(it)->text_props.bidi.dir ==
-                              EVAS_BIDI_DIRECTION_RTL))
-                          is_rtl = EINA_TRUE;
-                       else if ((it->type == EVAS_TEXTBLOCK_ITEM_FORMAT) &&
-                             (_ITEM_FORMAT(it)->bidi_dir ==
-                              EVAS_BIDI_DIRECTION_RTL))
-                          is_rtl = EINA_TRUE;
-                    }
-
-                  if ((!before_char && is_rtl) ||
-                        (before_char && !is_rtl))
-                    {
-                       /* Just don't advance the width */
-                       w = 0;
-                    }
-               }
-#endif
-          }
-        else if (cur->pos == 0)
-          {
-             ret = evas_textblock_cursor_pen_geometry_get(
-                   dir_cur, &x, &y, &w, &h);
-#ifdef BIDI_SUPPORT
-             Eina_Bool is_rtl = EINA_FALSE;
-             if (dir_cur->node && dir_cur->node->par->is_bidi)
-               {
-                  Evas_Object_Textblock_Line *ln;
-                  Evas_Object_Textblock_Item *it;
-                  _find_layout_item_match(dir_cur, &ln, &it);
-                  if ((it->type == EVAS_TEXTBLOCK_ITEM_TEXT) &&
-                        (_ITEM_TEXT(it)->text_props.bidi.dir ==
-                         EVAS_BIDI_DIRECTION_RTL))
-                     is_rtl = EINA_TRUE;
-                  else if ((it->type == EVAS_TEXTBLOCK_ITEM_FORMAT) &&
-                        (_ITEM_FORMAT(it)->bidi_dir ==
-                         EVAS_BIDI_DIRECTION_RTL))
-                     is_rtl = EINA_TRUE;
-               }
-
-             /* Adjust if the char is an rtl char */
-             if ((ret >= 0) && (!is_rtl))
-               {
-                  /* Just don't advance the width */
-                  w = 0;
-               }
-#endif
-          }
-        else
-          {
-             ret = evas_textblock_cursor_pen_geometry_get(
-                   dir_cur, &x, &y, &w, &h);
-          }
-        if (ret >= 0)
-          {
-             if (cx) *cx = x + w;
              if (cy) *cy = y;
-             if (cw) *cw = 0;
-             if (ch) *ch = h;
-          }
-     }
-
-   if (dir && dir_cur && dir_cur->node)
-     {
-#ifdef BIDI_SUPPORT
-        Eina_Bool is_rtl = EINA_FALSE;
-        if (dir_cur->node->par->is_bidi)
-          {
-             Evas_Object_Textblock_Line *ln;
-             Evas_Object_Textblock_Item *it;
-             _find_layout_item_match(dir_cur, &ln, &it);
-             if ((it->type == EVAS_TEXTBLOCK_ITEM_TEXT) &&
-                   (_ITEM_TEXT(it)->text_props.bidi.dir ==
-                    EVAS_BIDI_DIRECTION_RTL))
-                is_rtl = EINA_TRUE;
-             else if ((it->type == EVAS_TEXTBLOCK_ITEM_FORMAT) &&
-                   (_ITEM_FORMAT(it)->bidi_dir ==
-                    EVAS_BIDI_DIRECTION_RTL))
-                is_rtl = EINA_TRUE;
-          }
-
-        if (_evas_textblock_cursor_is_at_the_end(dir_cur) && (dir_cur->pos > 0))
-          {
-             *dir = (is_rtl) ?
-                EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR;
-          }
-        else if (dir_cur->pos > 0)
-          {
-             *dir = (is_rtl) ?
-                EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR;
-          }
-        else
-#endif
-          {
-             *dir = EVAS_BIDI_DIRECTION_LTR;
+             if (cw) *cw = 0;                                                                if (ch) *ch = h;
+             if (dir) *dir = itdir;
           }
      }
    return ret;
@@ -8311,6 +10322,8 @@ _evas_textblock_cursor_char_pen_geometry_common_get(int (*query_func) (void *dat
 
    if (!cur) return -1;
    o = (Evas_Object_Textblock *)(cur->obj->object_data);
+
+   evas_object_textblock_coords_recalc(cur->obj);
    if (!o->formatted.valid) _relayout(cur->obj);
 
    if (!cur->node)
@@ -8358,6 +10371,16 @@ _evas_textblock_cursor_char_pen_geometry_common_get(int (*query_func) (void *dat
                    &x, &y, &w, &h);
           }
 
+        // HAVE_UNICODE_EMOTICON(2013.10.07): Modify Emoticon image area for supporting unicode 6.0 emoticon.
+        if (ti->emoticon_item)
+          {
+             if (pos)
+               x = ti->parent.w;
+             else
+               w = ti->parent.w;
+          }
+        //
+
         x += ln->x + _ITEM(ti)->x;
 
         if (x < ln->x)
@@ -8438,6 +10461,8 @@ evas_textblock_cursor_line_geometry_get(const Evas_Textblock_Cursor *cur, Evas_C
 
    if (!cur) return -1;
    o = (Evas_Object_Textblock *)(cur->obj->object_data);
+
+   evas_object_textblock_coords_recalc(cur->obj);
    if (!o->formatted.valid) _relayout(cur->obj);
    if (!cur->node)
      {
@@ -8476,8 +10501,8 @@ evas_textblock_cursor_visible_range_get(Evas_Textblock_Cursor *start, Evas_Textb
    return EINA_TRUE;
 }
 
-EAPI Eina_Bool
-evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y)
+static Eina_Bool
+_evas_textblock_cursor_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y, Eina_Bool per_cluster)
 {
    Evas_Object_Textblock *o;
    Evas_Object_Textblock_Paragraph *found_par;
@@ -8486,6 +10511,8 @@ evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, E
 
    if (!cur) return EINA_FALSE;
    o = (Evas_Object_Textblock *)(cur->obj->object_data);
+
+   evas_object_textblock_coords_recalc(cur->obj);
    if (!o->formatted.valid) _relayout(cur->obj);
    x += o->style_pad.l;
    y += o->style_pad.t;
@@ -8549,8 +10576,24 @@ evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, E
                                          &ti->text_props,
                                          x - it->x - ln->x, 0,
                                          &cx, &cy, &cw, &ch);
+
+                                 // HAVE_UNICODE_EMOTICON(2013.10.07): Modify Emoticon image area for supporting unicode 6.0 emoticon.
+                                 if (ti->emoticon_item)
+                                   {
+                                      if (x - it->x - ln->x < ti->parent.w / 2)
+                                        pos = 0;
+                                      else
+                                        pos = 1;
+                                   }
+                                 //
+
                                  if (pos < 0)
                                    return EINA_FALSE;
+
+                                 while (per_cluster && (evas_common_text_props_index_find(&ti->text_props, pos) == -1) &&
+                                        CHECK_LANGUAGE_CLUSTER_AVAILABLE(ti->text_props.script))
+                                   pos--;
+
                                  cur->pos = pos + it->text_pos;
                                  cur->node = it->text_node;
                                  return EINA_TRUE;
@@ -8568,22 +10611,39 @@ evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, E
                }
           }
      }
-   else if (o->paragraphs && (y >= o->paragraphs->y + o->formatted.h))
-     {
-        /* If we are after the last paragraph, use the last position in the
-         * text. */
-        evas_textblock_cursor_paragraph_last(cur);
-        return EINA_TRUE;
-     }
-   else if (o->paragraphs && (y < o->paragraphs->y))
+
+   if (o->paragraphs)
      {
-        evas_textblock_cursor_paragraph_first(cur);
-        return EINA_TRUE;
+        Evas_Object_Textblock_Line *first_line = o->paragraphs->lines;
+        if (y >= o->paragraphs->y + o->formatted.h)
+          {
+             /* If we are after the last paragraph, use the last position in the
+              * text. */
+             evas_textblock_cursor_paragraph_last(cur);
+             return EINA_TRUE;
+          }
+        else if (o->paragraphs && (y < (o->paragraphs->y + first_line->y)))
+          {
+             evas_textblock_cursor_paragraph_first(cur);
+             return EINA_TRUE;
+          }
      }
 
    return EINA_FALSE;
 }
 
+EAPI Eina_Bool
+evas_textblock_cursor_cluster_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y)
+{
+   return _evas_textblock_cursor_coord_set(cur, x, y, EINA_TRUE);
+}
+
+EAPI Eina_Bool
+evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y)
+{
+   return _evas_textblock_cursor_coord_set(cur, x, y, EINA_FALSE);
+}
+
 EAPI int
 evas_textblock_cursor_line_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord y)
 {
@@ -8593,6 +10653,8 @@ evas_textblock_cursor_line_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord y)
 
    if (!cur) return -1;
    o = (Evas_Object_Textblock *)(cur->obj->object_data);
+
+   evas_object_textblock_coords_recalc(cur->obj);
    if (!o->formatted.valid) _relayout(cur->obj);
    y += o->style_pad.t;
 
@@ -8785,6 +10847,16 @@ _evas_textblock_cursor_range_in_line_geometry_get(
                    &ti->text_props,
                    start,
                    &x1, &y, &w1, &h);
+
+             // HAVE_UNICODE_EMOTICON(2013.10.07): Modify Emoticon image area for supporting unicode 6.0 emoticon.
+             if (ti->emoticon_item)
+               {
+                  if (start)
+                    x1 = ti->parent.w;
+                  else
+                    w1 = ti->parent.w;
+               }
+             //
           }
         if (!ret)
           {
@@ -8795,6 +10867,17 @@ _evas_textblock_cursor_range_in_line_geometry_get(
               &ti->text_props,
               end,
               &x2, &y, &w2, &h);
+
+        // HAVE_UNICODE_EMOTICON(2013.10.07): Modify Emoticon image area for supporting unicode 6.0 emoticon.
+        if (ti->emoticon_item)
+          {
+             if (end)
+               x2 = ti->parent.w;
+             else
+               w2 = ti->parent.w;
+          }
+        //
+
         if (!ret)
           {
              return NULL;
@@ -8835,6 +10918,23 @@ _evas_textblock_cursor_range_in_line_geometry_get(
              tr->w = w;
           }
      }
+   else if ((it1 == it2) && (it1->type != EVAS_TEXTBLOCK_ITEM_TEXT))
+     {
+        Evas_Coord x, w;
+        x = 0;
+        w = it1->w;
+        _evas_textblock_range_calc_x_w(it1, &x, &w, EINA_TRUE,
+                                       switch_items);
+        if (w > 0)
+          {
+             tr = calloc(1, sizeof(Evas_Textblock_Rectangle));
+             rects = eina_list_append(rects, tr);
+             tr->x = ln->x + it1->x + x;
+             tr->y = ln->par->y + ln->y;
+             tr->h = ln->h;
+             tr->w = w;
+          }
+     }
    else if (it1 != it2)
      {
         /* Get the middle items */
@@ -8855,6 +10955,17 @@ _evas_textblock_cursor_range_in_line_geometry_get(
                    &ti->text_props,
                    start,
                    &x, &y, &w, &h);
+
+             // HAVE_UNICODE_EMOTICON(2013.10.07): Modify Emoticon image area for supporting unicode 6.0 emoticon.
+             if (ti->emoticon_item)
+               {
+                  if (start)
+                    x = ti->parent.w;
+                  else
+                    w = ti->parent.w;
+               }
+             //
+
              if (!ret)
                {
                   /* BUG! Skip the first item */
@@ -8909,6 +11020,17 @@ _evas_textblock_cursor_range_in_line_geometry_get(
                    &ti->text_props,
                    end,
                    &x, &y, &w, &h);
+
+             // HAVE_UNICODE_EMOTICON(2013.10.07): Modify Emoticon image area for supporting unicode 6.0 emoticon.
+             if (ti->emoticon_item)
+               {
+                  if (end)
+                    x = ti->parent.w;
+                  else
+                    w = ti->parent.w;
+               }
+             //
+
              if (!ret)
                {
                   /* BUG! skip the last item */
@@ -8922,8 +11044,16 @@ _evas_textblock_cursor_range_in_line_geometry_get(
           }
         else
           {
-             x = 0;
-             w = it2->w;
+             if (end > 0)
+               {
+                  x = it2->adv;
+                  w = 0;
+               }
+             else
+               {
+                  x = 0;
+                  w = it2->adv;
+               }
              _evas_textblock_range_calc_x_w(it2, &x, &w, EINA_FALSE,
                         switch_items);
           }
@@ -8940,6 +11070,102 @@ _evas_textblock_cursor_range_in_line_geometry_get(
    return rects;
 }
 
+EAPI Eina_Iterator *
+evas_textblock_cursor_range_simple_geometry_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2)
+{
+   Evas_Object_Textblock *o;
+   Evas_Object_Textblock_Line *ln1, *ln2;
+   Evas_Object_Textblock_Item *it1, *it2;
+   Eina_List *rects = NULL;
+   Eina_Iterator *itr = NULL;
+
+   if (!cur1 || !cur1->node) return NULL;
+   if (!cur2 || !cur2->node) return NULL;
+   if (cur1->obj != cur2->obj) return NULL;
+   o = (Evas_Object_Textblock *)(cur1->obj->object_data);
+
+   evas_object_textblock_coords_recalc(cur1->obj);
+   if (!o->formatted.valid) _relayout(cur1->obj);
+
+   if (evas_textblock_cursor_compare(cur1, cur2) > 0)
+     {
+        const Evas_Textblock_Cursor *tc;
+
+        tc = cur1;
+        cur1 = cur2;
+        cur2 = tc;
+     }
+
+   ln1 = ln2 = NULL;
+   it1 = it2 = NULL;
+   _find_layout_item_match(cur1, &ln1, &it1);
+   if (!ln1 || !it1) return NULL;
+   _find_layout_item_match(cur2, &ln2, &it2);
+   if (!ln2 || !it2) return NULL;
+
+   if (ln1 == ln2)
+     {
+        rects = _evas_textblock_cursor_range_in_line_geometry_get(ln1, cur1, cur2);
+     }
+   else
+     {
+        int lm = 0, rm = 0;
+        Eina_List *rects2 = NULL;
+        Evas_Coord w;
+        Evas_Textblock_Cursor *tc;
+        Evas_Textblock_Rectangle *tr;
+
+        if (ln1->items)
+          {
+             Evas_Object_Textblock_Format *fm = ln1->items->format;
+             if (fm)
+               {
+                  lm = fm->margin.l;
+                  rm = fm->margin.r;
+               }
+          }
+
+        evas_object_geometry_get(cur1->obj, NULL, NULL, &w, NULL);
+        rects = _evas_textblock_cursor_range_in_line_geometry_get(ln1, cur1, NULL);
+
+        /* Extend selection rectangle in first line */
+        tc = evas_object_textblock_cursor_new(cur1->obj);
+        evas_textblock_cursor_copy(cur1, tc);
+        evas_textblock_cursor_line_char_last(tc);
+        tr = calloc(1, sizeof(Evas_Textblock_Rectangle));
+        evas_textblock_cursor_pen_geometry_get(tc, &tr->x, &tr->y, &tr->w, &tr->h);
+        if (ln1->par->direction == EVAS_BIDI_DIRECTION_RTL)
+          {
+             tr->w = tr->x + tr->w - rm;
+             tr->x = lm;
+          }
+        else
+          {
+             tr->w = w - tr->x - rm;
+          }
+        rects = eina_list_append(rects, tr);
+        evas_textblock_cursor_free(tc);
+
+        rects2 = _evas_textblock_cursor_range_in_line_geometry_get(ln2, NULL, cur2);
+
+        /* Add middle rect */
+        if (ln1->par->y + ln1->y + ln1->h != ln2->par->y + ln2->y)
+          {
+             tr = calloc(1, sizeof(Evas_Textblock_Rectangle));
+             tr->x = lm;
+             tr->y = ln1->par->y + ln1->y + ln1->h;
+             tr->w = w - tr->x - rm;
+             tr->h = ln2->par->y + ln2->y - tr->y;
+             rects = eina_list_append(rects, tr);
+          }
+        rects = eina_list_merge(rects, rects2);
+     }
+   itr = _evas_textblock_iterator_new(rects);
+
+   return itr;
+}
+
+
 EAPI Eina_List *
 evas_textblock_cursor_range_geometry_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2)
 {
@@ -8953,6 +11179,8 @@ evas_textblock_cursor_range_geometry_get(const Evas_Textblock_Cursor *cur1, cons
    if (!cur2 || !cur2->node) return NULL;
    if (cur1->obj != cur2->obj) return NULL;
    o = (Evas_Object_Textblock *)(cur1->obj->object_data);
+
+   evas_object_textblock_coords_recalc(cur1->obj);
    if (!o->formatted.valid) _relayout(cur1->obj);
    if (evas_textblock_cursor_compare(cur1, cur2) > 0)
      {
@@ -9024,9 +11252,12 @@ evas_textblock_cursor_format_item_geometry_get(const Evas_Textblock_Cursor *cur,
 
    if (!cur || !evas_textblock_cursor_format_is_visible_get(cur)) return EINA_FALSE;
    o = (Evas_Object_Textblock *)(cur->obj->object_data);
+
+   evas_object_textblock_coords_recalc(cur->obj);
    if (!o->formatted.valid) _relayout(cur->obj);
    if (!evas_textblock_cursor_format_is_visible_get(cur)) return EINA_FALSE;
    _find_layout_item_line_match(cur->obj, cur->node, cur->pos, &ln, &it);
+   if (it && (it->type != EVAS_TEXTBLOCK_ITEM_FORMAT)) return EINA_FALSE;
    fi = _ITEM_FORMAT(it);
    if ((!ln) || (!fi)) return EINA_FALSE;
    x = ln->x + fi->parent.x;
@@ -9115,6 +11346,8 @@ EAPI void
 evas_object_textblock_size_formatted_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
 {
    TB_HEAD();
+
+   evas_object_textblock_coords_recalc((Evas_Object *)obj);
    if (!o->formatted.valid) _relayout(obj);
    if (w) *w = o->formatted.w;
    if (h) *h = o->formatted.h;
@@ -9122,7 +11355,7 @@ evas_object_textblock_size_formatted_get(const Evas_Object *obj, Evas_Coord *w,
 
 static void
 _size_native_calc_line_finalize(const Evas_Object *obj, Eina_List *items,
-      Evas_Coord *ascent, Evas_Coord *descent, Evas_Coord *w)
+      Evas_Coord *ascent, Evas_Coord *descent, Evas_Coord *w, Textblock_Position position)
 {
    Evas_Object_Textblock_Item *it;
    Eina_List *i;
@@ -9132,11 +11365,19 @@ _size_native_calc_line_finalize(const Evas_Object *obj, Eina_List *items,
 
    if (it)
      {
+        Evas_Coord asc = 0, desc = 0;
         /* If there are no text items yet, calc ascent/descent
          * according to the current format. */
-        if (*ascent + *descent == 0)
-           _layout_format_ascent_descent_adjust(obj, ascent, descent,
-                 it->format);
+        if (it->format)
+          {
+             _layout_item_ascent_descent_adjust(obj, &asc, &desc,
+                                                it, position);
+          }
+
+        if (asc > *ascent)
+           *ascent = asc;
+        if (desc > *descent)
+           *descent = desc;
 
         /* Add margins. */
         if (it->format)
@@ -9157,6 +11398,21 @@ _size_native_calc_line_finalize(const Evas_Object *obj, Eina_List *items,
              _layout_calculate_format_item_size(obj, fi, ascent,
                    descent, &fy, &fw, &fh);
           }
+        else
+          {
+             Evas_Coord maxasc = 0, maxdesc = 0;
+             /* We are passing else because we don't want anything to be
+              * done wrt position. */
+             _layout_item_ascent_descent_adjust(obj, ascent, descent,
+                   it, TEXTBLOCK_POSITION_ELSE);
+             _layout_item_max_ascent_descent_calc(obj, &maxasc, &maxdesc,
+                   it, position);
+
+             if (maxasc > *ascent)
+                *ascent = maxasc;
+             if (maxdesc > *descent)
+                *descent = maxdesc;
+          }
 
 loop_advance:
         *w += it->adv;
@@ -9168,6 +11424,7 @@ static void
 _size_native_calc_paragraph_size(const Evas_Object *obj,
       const Evas_Object_Textblock *o,
       const Evas_Object_Textblock_Paragraph *par,
+      Textblock_Position *position,
       Evas_Coord *_w, Evas_Coord *_h)
 {
    Eina_List *i;
@@ -9185,7 +11442,7 @@ _size_native_calc_paragraph_size(const Evas_Object *obj,
                       _IS_PARAGRAPH_SEPARATOR(o, fi->item)))
                {
                   _size_native_calc_line_finalize(obj, line_items, &ascent,
-                        &descent, &w);
+                        &descent, &w, *position);
 
                   if (ascent + descent > h)
                      h = ascent + descent;
@@ -9195,6 +11452,7 @@ _size_native_calc_paragraph_size(const Evas_Object *obj,
                      wmax = w;
                   h = 0;
                   ascent = descent = 0;
+                  *position = TEXTBLOCK_POSITION_ELSE;
                   line_items = eina_list_free(line_items);
                }
              else
@@ -9202,9 +11460,9 @@ _size_native_calc_paragraph_size(const Evas_Object *obj,
                   Evas_Coord fw, fh, fy;
                   /* If there are no text items yet, calc ascent/descent
                    * according to the current format. */
-                  if (it && (ascent + descent == 0))
-                     _layout_format_ascent_descent_adjust(obj, &ascent,
-                           &descent, it->format);
+                  if (ascent + descent == 0)
+                     _layout_item_ascent_descent_adjust(obj, &ascent,
+                           &descent, it, *position);
 
                   _layout_calculate_format_item_size(obj, fi, &ascent,
                         &descent, &fy, &fw, &fh);
@@ -9212,12 +11470,20 @@ _size_native_calc_paragraph_size(const Evas_Object *obj,
           }
         else
           {
-             _layout_format_ascent_descent_adjust(obj, &ascent,
-                   &descent, it->format);
+             _layout_item_ascent_descent_adjust(obj, &ascent,
+                   &descent, it, *position);
           }
      }
 
-   _size_native_calc_line_finalize(obj, line_items, &ascent, &descent, &w);
+   if (!EINA_INLIST_GET(par)->next)
+     {
+        *position = (*position == TEXTBLOCK_POSITION_START) ?
+           TEXTBLOCK_POSITION_SINGLE : TEXTBLOCK_POSITION_END;
+     }
+   _size_native_calc_line_finalize(obj, line_items, &ascent, &descent, &w, *position);
+
+   if (*position == TEXTBLOCK_POSITION_START)
+      *position = TEXTBLOCK_POSITION_ELSE;
 
    line_items = eina_list_free(line_items);
 
@@ -9240,13 +11506,16 @@ evas_object_textblock_size_native_get(const Evas_Object *obj, Evas_Coord *w, Eva
      {
         Evas_Coord wmax = 0, hmax = 0;
         Evas_Object_Textblock_Paragraph *par;
+        Textblock_Position position = TEXTBLOCK_POSITION_START;
         /* We just want the layout objects to update, should probably
          * split that. */
+
+        evas_object_textblock_coords_recalc((Evas_Object *)obj);
         if (!o->formatted.valid) _relayout(obj);
         EINA_INLIST_FOREACH(o->paragraphs, par)
           {
              Evas_Coord tw, th;
-             _size_native_calc_paragraph_size(obj, o, par, &tw, &th);
+             _size_native_calc_paragraph_size(obj, o, par, &position, &tw, &th);
              if (tw > wmax)
                 wmax = tw;
              hmax += th;
@@ -9267,6 +11536,8 @@ EAPI void
 evas_object_textblock_style_insets_get(const Evas_Object *obj, Evas_Coord *l, Evas_Coord *r, Evas_Coord *t, Evas_Coord *b)
 {
    TB_HEAD();
+
+   evas_object_textblock_coords_recalc((Evas_Object *)obj);
    if (!o->formatted.valid) _relayout(obj);
    if (l) *l = o->style_pad.l;
    if (r) *r = o->style_pad.r;
@@ -9279,11 +11550,45 @@ evas_object_textblock_style_insets_get(const Evas_Object *obj, Evas_Coord *l, Ev
  * This is an ugly workaround to get around the fact that
  * evas_object_textblock_coords_recalc isn't really called when it's supposed
  * to. When that bug is fixed please remove this. */
+/*
 static void
 _workaround_object_coords_recalc(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
 {
    evas_object_textblock_coords_recalc(obj);
 }
+*/
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+// HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+static void
+_evas_object_textblock_emoticon_clear(Evas_Object *obj)
+{
+   Evas_Object_Textblock *o;
+   Evas_Object_Textblock_Emoticon_Item *emoticon_item;
+   Eina_Inlist *itrn;
+
+   Evas *e = obj->layer->evas;
+   o = (Evas_Object_Textblock *)(obj->object_data);
+
+   o->emoticons = eina_list_free(o->emoticons);
+
+   EINA_INLIST_FOREACH_SAFE(EINA_INLIST_GET(o->emoticon_items), itrn,
+                            emoticon_item)
+     {
+        if (emoticon_item->engine_data)
+          {
+             e->engine.func->image_free(e->engine.data.output,
+                                        emoticon_item->engine_data);
+          }
+
+        if (emoticon_item->ti) emoticon_item->ti->emoticon_item = NULL;
+
+        o->emoticon_items = (Evas_Object_Textblock_Emoticon_Item *)
+           eina_inlist_remove(EINA_INLIST_GET(o->emoticon_items),
+                              EINA_INLIST_GET(emoticon_item));
+        free(emoticon_item);
+     }
+}
 
 /* all nice and private */
 static void
@@ -9323,8 +11628,14 @@ evas_object_textblock_init(Evas_Object *obj)
    evas_object_textblock_text_markup_set(obj, "");
 
    o->legacy_newline = EINA_TRUE;
-   evas_object_event_callback_priority_add(obj, EVAS_CALLBACK_RESIZE, -1000,
-         _workaround_object_coords_recalc, NULL);
+//   evas_object_event_callback_priority_add(obj, EVAS_CALLBACK_RESIZE, -1000,
+//         _workaround_object_coords_recalc, NULL);
+
+   // TIZEN_ONLY(20140702): Add pressed_color tag feature
+   o->pressed_format = NULL;
+   o->prev_pressed_format = NULL;
+   o->has_pressed_color = EINA_FALSE;
+   //
 }
 
 static void *
@@ -9348,6 +11659,10 @@ evas_object_textblock_free(Evas_Object *obj)
 {
    Evas_Object_Textblock *o;
 
+   // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+   _evas_object_textblock_emoticon_clear(obj);
+   //
+
    _evas_object_textblock_clear_all(obj);
    evas_object_textblock_style_set(obj, NULL);
    while (evas_object_textblock_style_user_peek(obj))
@@ -9369,8 +11684,67 @@ evas_object_textblock_free(Evas_Object *obj)
    o->magic = 0;
    EVAS_MEMPOOL_FREE(_mp_obj, o);
   _format_command_shutdown();
+
+
+}
+
+///////////////////// TIZEN ONLY (20131106) : Font effect for tizen. /////////////////////
+static int __attribute__((optimize("O0")))
+evas_object_textblock_effect_outerglow_alpha_get(int x,int y, double opacity, int size)
+{
+    const float SPREAD_COEFF = 1.12f;
+    double sizeD = (double)size;
+    int alpha;
+    double intensity = sqrt((x * x) + (y * y));
+    intensity = (sizeD * SPREAD_COEFF - intensity) / sizeD;
+    if (intensity > 0.0)
+      {
+         intensity = (intensity >= 1.0) ? 1.0 : intensity;
+         intensity = sin(intensity * 3.141592 / 2.0);
+         alpha = (int)((255.0 * opacity) * intensity + 0.5);
+         return alpha;
+      }
+    else
+      return 0;
+}
+
+static int __attribute__((optimize("O0")))
+evas_object_textblock_effect_soft_outerglow_alpha_get(int x,int y, double opacity, int size)
+{
+    const float SPREAD_COEFF = 1.50f;
+    double sizeD = (double)size + 0.3;
+    int alpha;
+    double intensity = sqrt((x * x) + (y * y));
+    intensity = (sizeD * SPREAD_COEFF - intensity) / sizeD;
+    if (intensity > 0.0)
+      {
+         intensity = (intensity >= 1.0) ? 1.0 : intensity;
+         intensity = sin(intensity * 3.141592 / 2.0);
+         alpha =(int)((255.0 * opacity) * intensity + 0.5);
+         return alpha;
+      }
+    else
+      return 0;
 }
 
+static int __attribute__((optimize("O0")))
+evas_object_textblock_effect_shadow_alpha_get(int x,int y,double opacity,int softness)
+{
+   int alpha;
+   double softnessD = (double)softness;
+   double intensity = sqrt((x * x) + (y * y));
+   intensity = (softnessD - intensity) / softnessD;
+   if (intensity > 0.0)
+     {
+        intensity = sin((intensity * 3.141592) / 2.0);
+        intensity *= intensity;
+        alpha =((255.0 * opacity) * intensity + 0.5) / (softnessD * 2);
+        return alpha;
+     }
+   else
+     return 0;
+}
+//////////////////////////////////////////////////////////////////////////////////////////
 
 static void
 evas_object_textblock_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
@@ -9389,10 +11763,22 @@ evas_object_textblock_render(Evas_Object *obj, void *output, void *context, void
          {0, 1, 2, 1, 0}
      };
 
+   Eina_Bool instant_pre = EINA_FALSE;
+
+   /* FIXME: render_pre() won't be called if the textblock is a member of the
+      mapped parent. Especially, textblock should be cared since it's geometry
+      is updated in the render pre time. */
+   if (!obj->pre_render_done)
+     {
+        evas_object_textblock_render_pre(obj);
+        instant_pre = EINA_TRUE;
+     }
+
    /* render object to surface with context, and offxet by x,y */
    o = (Evas_Object_Textblock *)(obj->object_data);
    obj->layer->evas->engine.func->context_multiplier_unset(output,
                                                           context);
+   ENFN->context_render_op_set(output, context, obj->cur.render_op);
    /* FIXME: This clipping is just until we fix inset handling correctly. */
    ENFN->context_clip_clip(output, context,
                               obj->cur.geometry.x + x,
@@ -9400,6 +11786,7 @@ evas_object_textblock_render(Evas_Object *obj, void *output, void *context, void
                               obj->cur.geometry.w,
                               obj->cur.geometry.h);
    clip = ENFN->context_clip_get(output, context, &cx, &cy, &cw, &ch);
+
    /* If there are no paragraphs and thus there are no lines,
     * there's nothing left to do. */
    if (!o->paragraphs) return;
@@ -9533,17 +11920,59 @@ evas_object_textblock_render(Evas_Object *obj, void *output, void *context, void
              _og = itr->format->color.oname.g; \
              _ob = itr->format->color.oname.b; \
              _oa = itr->format->color.oname.a; \
-             if (!EINA_INLIST_GET(itr)->next) \
+             DRAW_RECT(itr->x, oy, itr->adv, oh, _or, _og, _ob, _oa); \
+          } \
+     } \
+   while (0)
+
+////////////////////////////////////////////////////////////////
+// TIZEN_ONLY(20140702): Add pressed_color tag feature
+////////////////////////////////////////////////////////////////
+#define COLOR_SET_CHECK_PRESSED(col) \
+   if (itr->format->has_pressed_color && \
+       itr->format->is_pressed) \
+     { \
+        ENFN->context_color_set(output, context, \
+              (obj->cur.cache.clip.r * ti->parent.format->color.pressed_color.r) / 255, \
+              (obj->cur.cache.clip.g * ti->parent.format->color.pressed_color.g) / 255, \
+              (obj->cur.cache.clip.b * ti->parent.format->color.pressed_color.b) / 255, \
+              (obj->cur.cache.clip.a * ti->parent.format->color.pressed_color.a) / 255); \
+     } \
+   else \
+     { \
+        ENFN->context_color_set(output, context, \
+              (obj->cur.cache.clip.r * ti->parent.format->color.col.r) / 255, \
+              (obj->cur.cache.clip.g * ti->parent.format->color.col.g) / 255, \
+              (obj->cur.cache.clip.b * ti->parent.format->color.col.b) / 255, \
+              (obj->cur.cache.clip.a * ti->parent.format->color.col.a) / 255); \
+     }
+
+#define DRAW_FORMAT_CHECK_PRESSED(oname, oy, oh) \
+   do \
+     { \
+        if (itr->format->oname) \
+          { \
+             unsigned char _or, _og, _ob, _oa; \
+             if (itr->format->has_pressed_color && \
+                 itr->format->is_pressed) \
                { \
-                  DRAW_RECT(itr->x, oy, itr->w, oh, _or, _og, _ob, _oa); \
+                  _or = itr->format->color.pressed_color.r; \
+                  _og = itr->format->color.pressed_color.g; \
+                  _ob = itr->format->color.pressed_color.b; \
+                  _oa = itr->format->color.pressed_color.a; \
                } \
              else \
                { \
-                  DRAW_RECT(itr->x, oy, itr->adv, oh, _or, _og, _ob, _oa); \
+                  _or = itr->format->color.oname.r; \
+                  _og = itr->format->color.oname.g; \
+                  _ob = itr->format->color.oname.b; \
+                  _oa = itr->format->color.oname.a; \
                } \
+             DRAW_RECT(itr->x, oy, itr->adv, oh, _or, _og, _ob, _oa); \
           } \
      } \
    while (0)
+////////////////////////////////////////////////////////////////
 
      {
         Evas_Coord look_for_y = 0 - (obj->cur.geometry.y + y);
@@ -9579,6 +12008,9 @@ evas_object_textblock_render(Evas_Object *obj, void *output, void *context, void
         Evas_Object_Textblock_Text_Item *ti;
         ti = (itr->type == EVAS_TEXTBLOCK_ITEM_TEXT) ? _ITEM_TEXT(itr) : NULL;
         if (!ti) continue;
+        // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+        if (ti->emoticon_item) continue;
+        //
 
         shad_dst = shad_sz = dx = dy = haveshad = 0;
         switch (ti->parent.format->style & EVAS_TEXT_STYLE_MASK_BASIC)
@@ -9681,6 +12113,9 @@ evas_object_textblock_render(Evas_Object *obj, void *output, void *context, void
         Evas_Object_Textblock_Text_Item *ti;
         ti = (itr->type == EVAS_TEXTBLOCK_ITEM_TEXT) ? _ITEM_TEXT(itr) : NULL;
         if (!ti) continue;
+        // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+        if (ti->emoticon_item) continue;
+        //
 
         if (ti->parent.format->style == EVAS_TEXT_STYLE_GLOW)
           {
@@ -9704,12 +12139,102 @@ evas_object_textblock_render(Evas_Object *obj, void *output, void *context, void
      }
    ITEM_WALK_END();
 
+   // TIZEN ONLY (20131106) : Font effect for tizen.
+   ITEM_WALK()
+     {
+        Evas_Object_Textblock_Text_Item *ti;
+        ti = (itr->type == EVAS_TEXTBLOCK_ITEM_TEXT) ? _ITEM_TEXT(itr) : NULL;
+        if (!ti) continue;
+        // HAVE_UNICODE_EMOTICON(20140626): Skip effect for emoticon.
+        if (ti->emoticon_item) continue;
+        //
+        if ((ti->parent.format->style & EVAS_TEXT_STYLE_MASK_BASIC) == EVAS_TEXT_STYLE_TIZEN_GLOW_SHADOW) // HOME_SCREEN_ICON
+          {
+             int size = 2;
+             int softness = 3;
+
+             for (j = -size; j <= size; j++)
+               {
+                  for (i = -size; i <= size; i++)
+                    {
+                       int alpha = evas_object_textblock_effect_outerglow_alpha_get(i,j, 0.30, size); // OutGlow2
+                       if(alpha == 0)
+                         continue;
+                       COLOR_SET_AMUL(glow, alpha);
+                       DRAW_TEXT(j, i);
+                    }
+               }
+             for (j = -softness; j <= softness; j++)
+               {
+                  for (i = -softness; i <= softness; i++)
+                    {
+                       if (i != 0 && j != 0)
+                         {
+                            int alpha = evas_object_textblock_effect_shadow_alpha_get(i, j, 0.80, softness); // DropShadow
+                            if(alpha == 0) continue;
+                            COLOR_SET_AMUL(shadow, alpha);
+                            DRAW_TEXT(j, i + 2);
+                         }
+                    }
+               }
+          }
+        if ((ti->parent.format->style & EVAS_TEXT_STYLE_MASK_BASIC) == EVAS_TEXT_STYLE_TIZEN_SOFT_GLOW_SHADOW)
+          {
+             int size = 1;
+             int softness = 1;
+
+             for (j = -size; j <= size; j++)
+               {
+                  for (i = -size; i <= size; i++)
+                    {
+                       if (i != 0 && j != 0)
+                         {
+                            int alpha = evas_object_textblock_effect_soft_outerglow_alpha_get(i, j, 0.40, size); // OutGlow3
+                            if(alpha == 0) continue;
+                            COLOR_SET_AMUL(glow, alpha);
+                            DRAW_TEXT(j, i);
+                         }
+                    }
+               }
+             for (j = -softness; j <= softness; j++)
+               {
+                  for (i = -softness; i <= softness; i++)
+                    {
+                       int alpha = evas_object_textblock_effect_shadow_alpha_get(i, j, 0.65, softness); // DropShadow
+                       if(alpha == 0) continue;
+                       COLOR_SET_AMUL(shadow, alpha);
+                       DRAW_TEXT(j, i + 2);
+                    }
+               }
+          }
+        if ((ti->parent.format->style & EVAS_TEXT_STYLE_MASK_BASIC) == EVAS_TEXT_STYLE_TIZEN_SHADOW)
+          {
+             int softness = 3;
+
+             for (j = -softness; j <= softness; j++)
+               {
+                  for (i = -softness; i <= softness; i++)
+                    {
+                       int alpha = evas_object_textblock_effect_shadow_alpha_get(i, j, 0.5, softness); // DropShadow
+                       if(alpha == 0) continue;
+                       COLOR_SET_AMUL(shadow, alpha);
+                       DRAW_TEXT(j, i + 2);
+                    }
+               }
+          }
+     }
+   ITEM_WALK_END();
+   ////////////////////////////////////////////////////////////////////
+
    /* outlines */
    ITEM_WALK()
      {
         Evas_Object_Textblock_Text_Item *ti;
         ti = (itr->type == EVAS_TEXTBLOCK_ITEM_TEXT) ? _ITEM_TEXT(itr) : NULL;
         if (!ti) continue;
+        // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+        if (ti->emoticon_item) continue;
+        //
 
         if ((ti->parent.format->style == EVAS_TEXT_STYLE_OUTLINE) ||
               (ti->parent.format->style == EVAS_TEXT_STYLE_OUTLINE_SHADOW) ||
@@ -9746,25 +12271,61 @@ evas_object_textblock_render(Evas_Object *obj, void *output, void *context, void
         /* NORMAL TEXT */
         if (ti)
           {
+             // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+             if (!ti->emoticon_item)
+               {
+                  // TIZEN_ONLY(20140702): Add pressed_color tag feature
+                  //COLOR_SET(normal);
+                  COLOR_SET_CHECK_PRESSED(normal);
+                  //
+                  DRAW_TEXT(0, 0);
+               }
+             //
+             /*
+
              COLOR_SET(normal);
              DRAW_TEXT(0, 0);
+              */
           }
 
         /* STRIKETHROUGH */
-        DRAW_FORMAT(strikethrough, (ln->h / 2), 1);
+        // TIZEN_ONLY(20140702): Add pressed_color tag feature
+        //DRAW_FORMAT(strikethrough, (ln->h / 2), 4);
+        DRAW_FORMAT_CHECK_PRESSED(strikethrough, (ln->h / 2), 4);
+        //
 
         /* UNDERLINE */
-        DRAW_FORMAT(underline, ln->baseline + 1, 1);
+        // TIZEN ONLY : for not overlapping with characters.
+        //DRAW_FORMAT(underline, ln->h - 2, 1);
+        //DRAW_FORMAT(underline, ln->baseline + 1, 1);
+        // TIZEN_ONLY(20140702): Add pressed_color tag feature
+        DRAW_FORMAT_CHECK_PRESSED(underline, ln->h - 2, 1);
+        //
 
         /* UNDERLINE DASHED */
-        DRAW_FORMAT_DASHED(underline_dash, ln->baseline + 1, 1,
-                         ti->parent.format->underline_dash_width,
-                         ti->parent.format->underline_dash_gap);
+        // TIZEN ONLY : for not overlapping with characters.
+        DRAW_FORMAT_DASHED(underline_dash, ln->h - 2, 1,
+                           itr->format->underline_dash_width,
+                           itr->format->underline_dash_gap);
+        //DRAW_FORMAT_DASHED(underline_dash, ln->baseline + 1, 1,
+        //                   ti->parent.format->underline_dash_width,
+        //                   ti->parent.format->underline_dash_gap);
 
         /* UNDERLINE2 */
-        DRAW_FORMAT(underline2, ln->baseline + 3, 1);
+        // TIZEN ONLY : for not overlapping with characters.
+        //DRAW_FORMAT(underline2, ln->h, 1);
+        //DRAW_FORMAT(underline2, ln->baseline + 3, 1);
+        // TIZEN_ONLY(20140702): Add pressed_color tag feature
+        DRAW_FORMAT_CHECK_PRESSED(underline2, ln->h, 1);
+        //
      }
    ITEM_WALK_END();
+
+   _emoticon_render(obj, output, context, surface, x, y);
+
+   /* FIXME: render_post() should be called if the render_pre() is called
+      instantly. */
+   if (instant_pre) evas_object_textblock_render_post(obj);
 }
 
 static void
@@ -9782,6 +12343,8 @@ evas_object_textblock_render_pre(Evas_Object *obj)
    /* then when this is done the object needs to figure if it changed and */
    /* if so what and where and add the appropriate redraw textblocks */
    o = (Evas_Object_Textblock *)(obj->object_data);
+
+   evas_object_textblock_coords_recalc(obj);
    if ((o->changed) || (o->content_changed) || (o->format_changed) ||
        ((obj->cur.geometry.w != o->last_w) ||
            (((o->valign != 0.0) || (o->have_ellipsis)) &&
@@ -9818,7 +12381,7 @@ evas_object_textblock_render_pre(Evas_Object *obj)
        evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes, obj, is_v, was_v);
        goto done;
      }
-   if (obj->changed_map)
+   if (obj->changed_map || obj->changed_src_visible)
      {
         evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
                                             obj);
@@ -9854,7 +12417,25 @@ evas_object_textblock_render_pre(Evas_Object *obj)
        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
        goto done;
      }
+   if (obj->cur.render_op != obj->prev.render_op)
+     {
+        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
+        goto done;
+     }
+   // TIZEN_ONLY(20140702): Add pressed_color tag feature
+   if (o->pressed_format != o->prev_pressed_format)
+     {
+        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
+        goto done;
+     }
+   //
    done:
+   // TIZEN_ONLY(20140702): Add pressed_color tag feature
+   o->prev_pressed_format = o->pressed_format;
+   //
+   // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+   _evas_object_textblock_emoticon_update_geometry(obj);
+   //
    evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes, obj, is_v, was_v);
 }
 
@@ -9924,9 +12505,25 @@ evas_object_textblock_coords_recalc(Evas_Object *obj)
    Evas_Object_Textblock *o;
 
    o = (Evas_Object_Textblock *)(obj->object_data);
-   if ((obj->cur.geometry.w != o->last_w) ||
+   if (
+       // width changed thus we may have to re-wrap or change centering etc.
+       (obj->cur.geometry.w != o->last_w) ||
+       // if valign not top OR we have ellipsis, then if height changed we need to re-eval valign or ... spot
        (((o->valign != 0.0) || (o->have_ellipsis)) &&
-           (obj->cur.geometry.h != o->last_h)))
+           (
+               ((o->formatted.oneline_h == 0) &&
+                   (obj->cur.geometry.h != o->last_h)) ||
+
+               ((o->formatted.oneline_h != 0) &&
+                   (((obj->cur.geometry.h != o->last_h) &&
+                     (o->formatted.oneline_h < obj->cur.geometry.h))))
+           )
+       ) ||
+       // obviously if content text changed we need to reformat it
+       (o->content_changed) ||
+       // if format changed (eg styles) we need to re-format/match tags etc.
+       (o->format_changed)
+      )
      {
        o->formatted.valid = 0;
        o->changed = 1;
@@ -9941,6 +12538,8 @@ evas_object_textblock_scale_update(Evas_Object *obj)
    o = (Evas_Object_Textblock *)(obj->object_data);
    _evas_textblock_invalidate_all(o);
    _evas_textblock_changed(o, obj);
+   o->last_w = -1;
+   o->last_h = -1;
 }
 
 void
@@ -9963,7 +12562,7 @@ _evas_object_textblock_rehint(Evas_Object *obj)
                     {
                        Evas_Object_Textblock_Text_Item *ti = _ITEM_TEXT(it);
                        if (ti->parent.format->font.font)
-                         {  
+                         {
                             evas_font_load_hinting_set(obj->layer->evas,
                                   ti->parent.format->font.font,
                                   obj->layer->evas->hinting);
@@ -9976,6 +12575,14 @@ _evas_object_textblock_rehint(Evas_Object *obj)
    _evas_textblock_changed(o, obj);
 }
 
+// TIZEN_ONLY(20150513): Add evas_object_text/textblock_ellipsis_status_get internal API.
+EAPI Eina_Bool
+evas_object_textblock_ellipsis_status_get(const Evas_Object *obj)
+{
+   TB_HEAD_RETURN(EINA_FALSE);
+   return o->last_computed_ellipsis;
+}
+
 /**
  * @}
  */
@@ -9993,6 +12600,7 @@ _evas_textblock_check_item_node_link(Evas_Object *obj)
    o = (Evas_Object_Textblock *)(obj->object_data);
    if (!o) return EINA_FALSE;
 
+   evas_object_textblock_coords_recalc(obj);
    if (!o->formatted.valid) _relayout(obj);
 
    EINA_INLIST_FOREACH(o->paragraphs, par)
index f047518..ffba710 100644 (file)
@@ -194,7 +194,7 @@ evas_object_textgrid_textprop_ref(Evas_Object *obj, Evas_Object_Textgrid *o, Ein
 
    if (o->last_glyphs)
      {
-        if (o->last_mask && (o->last_mask & codepoint) == o->last_mask)
+        if ((o->last_mask) && ((o->last_mask & codepoint) == o->last_mask))
           goto end;
      }
 
@@ -235,8 +235,8 @@ evas_object_textgrid_textprop_ref(Evas_Object *obj, Evas_Object_Textgrid *o, Ein
         goto end;
      }
 
-   while (shift > 8
-          && o->master[offset].next[(codepoint & mask) >> shift] != 0)
+   while ((shift > 8)
+          && (o->master[offset].next[(codepoint & mask) >> shift] != 0))
      {
         offset = o->master[offset].next[(codepoint & mask) >> shift];
         mask >>= 4;
@@ -322,7 +322,12 @@ evas_object_textgrid_textprop_unref(Evas_Object_Textgrid *o, unsigned int props_
           eina_array_push(&o->glyphs_cleanup,
                           (void *)((unsigned long)props_index));
         else
-          evas_common_text_props_content_unref(props);
+          {
+             Evas_Glyph *glyphs = props->glyphs;
+             int glyphs_length = props->glyphs_length;
+
+             evas_common_text_props_content_nofree_unref(props);
+          }
      }
 }
 
@@ -456,8 +461,8 @@ evas_object_textgrid_free(Evas_Object *obj)
 
         props_index = (unsigned int) (intptr_t) eina_array_pop(&o->glyphs_cleanup);
         prop = &(o->glyphs[props_index >> 8].props[props_index & 0xFF]);
-        
-        evas_common_text_props_content_unref(prop);
+
+        evas_common_text_props_content_nofree_unref(prop);
         if (!prop->info)
           {
              o->glyphs_used[props_index >> 8]--;
@@ -734,7 +739,7 @@ evas_object_textgrid_render_pre(Evas_Object *obj)
        evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes, obj, is_v, was_v);
        goto done;
      }
-   if (obj->changed_map)
+   if (obj->changed_map || obj->changed_src_visible)
      {
         evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
                                             obj);
@@ -853,7 +858,7 @@ evas_object_textgrid_render_post(Evas_Object *obj)
         props_index = (unsigned int) (intptr_t) eina_array_pop(&o->glyphs_cleanup);
         prop = &(o->glyphs[props_index >> 8].props[props_index & 0xFF]);
         
-        evas_common_text_props_content_unref(prop);
+        evas_common_text_props_content_nofree_unref(prop);
         if (!prop->info)
           {
              o->glyphs_used[props_index >> 8]--;
@@ -1066,6 +1071,7 @@ evas_object_textgrid_font_set(Evas_Object *obj, const char *font_name, Evas_Font
    Evas_Object_Textgrid *o;
    int is, was = 0, pass = 0, freeze = 0;
    Evas_Font_Description *font_description;
+   Eina_Bool source_invisible = EINA_FALSE;
    
    if ((!font_name) || (!*font_name) || (font_size <= 0))
      return;
@@ -1099,7 +1105,8 @@ evas_object_textgrid_font_set(Evas_Object *obj, const char *font_name, Evas_Font
      {
         pass = evas_event_passes_through(obj);
         freeze = evas_event_freezes_through(obj);
-        if ((!pass) && (!freeze))
+        source_invisible = evas_object_is_source_invisible(obj);
+        if ((!pass) && (!freeze) && (!source_invisible))
           was = evas_object_is_in_output_rect(obj,
                                               obj->layer->evas->pointer.x,
                                               obj->layer->evas->pointer.y,
@@ -1186,7 +1193,7 @@ evas_object_textgrid_font_set(Evas_Object *obj, const char *font_name, Evas_Font
         props_index = (unsigned int) (intptr_t) eina_array_pop(&o->glyphs_cleanup);
         prop = &(o->glyphs[props_index >> 8].props[props_index & 0xFF]);
         
-        evas_common_text_props_content_unref(prop);
+        evas_common_text_props_content_nofree_unref(prop);
         if (!prop->info)
           {
              o->glyphs_used[props_index >> 8]--;
@@ -1322,6 +1329,7 @@ evas_object_textgrid_palette_set(Evas_Object *obj, Evas_Textgrid_Palette pal, in
              if (!c)
                {
                   ERR("Evas can not allocate memory");
+                  free(color);
                   return;
                }
              eina_array_push(palette, c);
old mode 100644 (file)
new mode 100755 (executable)
index 29941a0..6c41691
@@ -5,11 +5,13 @@
 #include "evas_cs2_private.h"
 #endif
 
-// debug rendering
-/* #define REND_DGB 1 */
+/* debug rendering
+ * NOTE: Define REND_DBG 1 in evas_private.h to enable debugging. Don't define
+ * it here since the flag is used on other places too. */
+
 /* #define STDOUT_DBG 1 */
 
-#ifdef REND_DGB
+#ifdef REND_DBG
 static FILE *dbf = NULL;
 
 static void
@@ -47,6 +49,8 @@ rend_dbg(const char *txt)
 #define RDI(x)
 #endif
 
+static void evas_render_mask_subrender(Evas *evas, Evas_Object *mask, Evas_Object *prev_mask);
+
 static Eina_List *
 evas_render_updates_internal(Evas *e, unsigned char make_updates, unsigned char do_draw);
 
@@ -92,6 +96,13 @@ evas_obscured_clear(Evas *e)
 }
 
 static Eina_Bool
+_evas_clip_changes_free(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
+{
+   eina_rectangle_free(data);
+   return EINA_TRUE;
+}
+
+static Eina_Bool
 _evas_render_had_map(Evas_Object *obj)
 {
    return ((obj->prev.map) && (obj->prev.usemap));
@@ -148,6 +159,62 @@ _evas_render_cur_clip_cache_del(Evas *e, Evas_Object *obj)
 }
 
 static void
+_evas_proxy_redraw_set(Evas *e, Evas_Object *obj, Eina_Bool render)
+{
+   Evas_Object *proxy;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(obj->proxy.proxies, l, proxy)
+     {
+        /* Flag need redraw on proxy too */
+        proxy->proxy.redraw = EINA_TRUE;
+
+        if (render)
+          {
+             proxy->func->render_pre(proxy);
+             _evas_render_prev_cur_clip_cache_add(e, proxy);
+          }
+
+        //Update the proxies recursively.
+        _evas_proxy_redraw_set(e, proxy, render);
+     }
+}
+
+static void
+_evas_mask_redraw_set(Evas *e EINA_UNUSED,
+                      Evas_Object *obj)
+{
+   Evas_Object *clippee;
+   Eina_List *l;
+
+   obj->mask.redraw = EINA_TRUE;
+
+   if (!obj->cur.cache.clip.dirty)
+     obj->cur.cache.clip.dirty = EINA_TRUE;
+
+   EINA_LIST_FOREACH(obj->clip.clipees, l, clippee)
+     {
+        evas_object_clip_recalc(clippee);
+     }
+}
+
+static inline Eina_Bool
+_evas_render_object_changed_get(Evas_Object *obj)
+{
+   if (obj->smart.smart)
+     return evas_object_smart_changed_get(obj);
+   else
+     return obj->changed;
+}
+
+static inline Eina_Bool
+_evas_render_object_is_mask(Evas_Object *obj)
+{
+   if (!obj) return EINA_FALSE;
+   return (obj->mask.is_mask && obj->clip.clipees);
+}
+
+static void
 _evas_render_phase1_direct(Evas *e,
                            Eina_Array *active_objects,
                            Eina_Array *restack_objects __UNUSED__,
@@ -155,44 +222,54 @@ _evas_render_phase1_direct(Evas *e,
                            Eina_Array *render_objects)
 {
    unsigned int i;
-   Eina_List *l;
-   Evas_Object *proxy;
 
    RD("  [--- PHASE 1 DIRECT\n");
    for (i = 0; i < active_objects->count; i++)
      {
-        Evas_Object *obj;
+        Evas_Object *obj = eina_array_data_get(active_objects, i);
 
-        obj = eina_array_data_get(active_objects, i);
-        if (obj->changed)
+        if (obj->changed) evas_object_clip_recalc(obj);
+
+        if (obj->proxy.proxies)
           {
-             /* Flag need redraw on proxy too */
-             evas_object_clip_recalc(obj);
-            EINA_LIST_FOREACH(obj->proxy.proxies, l, proxy)
-               proxy->proxy.redraw = EINA_TRUE;
+             /* is proxy source */
+             if (_evas_render_object_changed_get(obj))
+               _evas_proxy_redraw_set(e, obj, EINA_FALSE);
+          }
+        if (_evas_render_object_is_mask(obj))
+          {
+             /* is image clipper */
+             if (_evas_render_object_changed_get(obj))
+               _evas_mask_redraw_set(e, obj);
           }
      }
    for (i = 0; i < render_objects->count; i++)
      {
-        Evas_Object *obj;
+        Evas_Object *obj = eina_array_data_get(render_objects, i);
 
-        obj = eina_array_data_get(render_objects, i);
         RD("    OBJ [%p] changed %i\n", obj, obj->changed);
+
         if (obj->changed)
           {
              /* Flag need redraw on proxy too */
              evas_object_clip_recalc(obj);
              obj->func->render_pre(obj);
-             if (obj->proxy.redraw)
+
+             if (obj->proxy.redraw || obj->mask.redraw)
                _evas_render_prev_cur_clip_cache_add(e, obj);
-             if (obj->proxy.proxies)
+
+             if (!obj->smart.smart || evas_object_smart_changed_get(obj))
                {
-                  obj->proxy.redraw = EINA_TRUE;
-                  EINA_LIST_FOREACH(obj->proxy.proxies, l, proxy)
+                  /* proxy sources */
+                  if (obj->proxy.proxies)
                     {
-                       proxy->func->render_pre(proxy);
-                       _evas_render_prev_cur_clip_cache_add(e, proxy);
+                       obj->proxy.redraw = EINA_TRUE;
+                       _evas_proxy_redraw_set(e, obj, EINA_TRUE);
                     }
+
+                  /* clipper objects (image masks) */
+                  if (_evas_render_object_is_mask(obj))
+                    _evas_mask_redraw_set(e, obj);
                }
 
              RD("      pre-render-done smart:%p|%p  [%p, %i] | [%p, %i] has_map:%i had_map:%i\n",
@@ -203,7 +280,7 @@ _evas_render_phase1_direct(Evas *e,
                 _evas_render_has_map(obj),
                 _evas_render_had_map(obj));
              if ((obj->smart.smart) &&
-                 (_evas_render_has_map(obj)))
+                 (_evas_render_has_map(obj) || (obj->changed_src_visible)))
                {
                   RD("      has map + smart\n");
                   _evas_render_prev_cur_clip_cache_add(e, obj);
@@ -234,11 +311,9 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
                                    Eina_Array *render_objects,
                                    int restack,
                                    int *redraw_all,
-                                   Eina_Bool mapped_parent
-#ifdef REND_DGB
-                                   , int level
-#endif
-                                  )
+                                   Eina_Bool mapped_parent,
+                                   Eina_Bool src_changed,
+                                   int level)
 {
    Eina_Bool clean_them = EINA_FALSE;
    Evas_Object *obj2;
@@ -260,7 +335,12 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
 
    /* build active object list */
    evas_object_clip_recalc(obj);
-   is_active = evas_object_is_active(obj);
+   if (src_changed) is_active = EINA_TRUE;
+   else
+     {
+        is_active = evas_object_is_active(obj);
+        if (is_active && obj->proxy.proxies) src_changed = is_active;
+     }
    obj->is_active = is_active;
 
    RDI(level);
@@ -269,7 +349,7 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
    if ((!mapped_parent) && ((is_active) || (obj->delete_me != 0)))
      eina_array_push(active_objects, obj);
 
-#ifdef REND_DGB
+#ifdef REND_DBG
    if (!is_active)
      {
         RDI(level);
@@ -295,6 +375,14 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
      {
         RDI(level);
         RD("      obj mapped\n");
+        if (!hmap && obj->cur.clipper)
+          {
+             // Fix some bad clipping issues before an evas map animation starts
+             evas_object_change(obj->cur.clipper);
+             evas_object_clip_dirty(obj->cur.clipper);
+             evas_object_clip_recalc(obj->cur.clipper);
+             evas_object_update_bounding_box(obj);
+          }
         if (obj->changed)
           {
              if (map != hmap) *redraw_all = 1;
@@ -318,11 +406,9 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
                                                                render_objects,
                                                                obj->restack,
                                                                redraw_all,
-                                                               EINA_TRUE
-#ifdef REND_DGB
-                                                               , level + 1
-#endif
-                                                              );
+                                                               EINA_TRUE,
+                                                               src_changed,
+                                                               level + 1);
                          }
                     }
                }
@@ -346,6 +432,14 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
                   *redraw_all = 1;
                }
           }
+        if (obj->cur.clipper)
+          {
+             // Fix some bad clipping issues after an evas_map animation finishes
+             evas_object_change(obj->cur.clipper);
+             evas_object_clip_dirty(obj->cur.clipper);
+             evas_object_clip_recalc(obj->cur.clipper);
+             evas_object_update_bounding_box(obj);
+          }
      }
 
    /* handle normal rendering. this object knows how to handle maps */
@@ -367,20 +461,42 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
                                                      render_objects,
                                                      obj->restack,
                                                      redraw_all,
-                                                     mapped_parent
-#ifdef REND_DGB
-                                                     , level + 1
-#endif
-                                                    );
+                                                     mapped_parent,
+                                                     src_changed,
+                                                     level + 1);
                }
           }
         else
           {
-             if ((is_active) && (!obj->clip.clipees) &&
-                 _evas_render_is_relevant(obj))
+             if ((!obj->clip.clipees) && _evas_render_is_relevant(obj))
+               {
+                  if (is_active)
+                    {
+                       RDI(level);
+                       RD("      relevant + active\n");
+                       if (obj->restack)
+                         eina_array_push(restack_objects, obj);
+                       else
+                         {
+                            eina_array_push(render_objects, obj);
+                            obj->render_pre = EINA_TRUE;
+                         }
+                    }
+                  else
+                    {
+                       /* It goes to be hidden. Prev caching should be replaced
+                          by the current (hidden) state. */
+                       if (evas_object_is_visible(obj) !=
+                           evas_object_was_visible(obj))
+                         evas_object_cur_prev(obj);
+
+                       RDI(level);
+                       RD("      skip - not smart, not active or clippees or not relevant\n");
+                    }
+               }
+             else if (is_active && _evas_render_object_is_mask(obj) &&
+                      (evas_object_is_visible(obj) || evas_object_was_visible(obj)))
                {
-                  RDI(level);
-                  RD("      relevant + active\n");
                   if (obj->restack)
                     eina_array_push(restack_objects, obj);
                   else
@@ -388,6 +504,9 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
                        eina_array_push(render_objects, obj);
                        obj->render_pre = EINA_TRUE;
                     }
+
+                  RDI(level);
+                  RD("      relevant + active: clipper image\n");
                }
              else
                {
@@ -423,11 +542,9 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
                                                              render_objects,
                                                              restack,
                                                              redraw_all,
-                                                             mapped_parent
-#ifdef REND_DGB
-                                                             , level + 1
-#endif
-                                                            );
+                                                             mapped_parent,
+                                                             src_changed,
+                                                             level + 1);
                        }
                }
              else
@@ -454,6 +571,14 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
                     }
                }
           }
+        else if (is_active && _evas_render_object_is_mask(obj) &&
+                 evas_object_is_visible(obj))
+          {
+             RDI(level);
+             RD("      visible clipper image\n");
+             eina_array_push(render_objects, obj);
+             obj->render_pre = EINA_TRUE;
+          }
  /*       else if (obj->smart.smart)
           {
              RDI(level);
@@ -469,11 +594,8 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
                                                      delete_objects,
                                                      render_objects,
                                                      restack,
-                                                     redraw_all
-#ifdef REND_DGB
-                                                     , level + 1
-#endif
-                                                    );
+                                                     redraw_all,
+                                                     level + 1);
                }
           }
 */
@@ -504,11 +626,7 @@ _evas_render_phase1_process(Evas *e,
           {
              clean_them |= _evas_render_phase1_object_process
                 (e, obj, active_objects, restack_objects, delete_objects,
-                 render_objects, 0, redraw_all, EINA_FALSE
-#ifdef REND_DGB
-                 , 1
-#endif
-                );
+                 render_objects, 0, redraw_all, EINA_FALSE, EINA_FALSE, 1);
           }
      }
    RD("  ---]\n");
@@ -600,6 +718,7 @@ pending_change(void *data, void *gdata __UNUSED__)
    if (obj->pre_render_done)
      {
         RD("  OBJ [%p] pending change %i -> 0, pre %i\n", obj, obj->changed, obj->pre_render_done);
+        obj->func->render_post(obj);
         obj->pre_render_done = EINA_FALSE;
         evas_object_change_reset(obj);
      }
@@ -800,27 +919,97 @@ _evas_render_can_use_overlay(Evas *e, Evas_Object *obj)
    return EINA_TRUE;
 }
 
+static void
+_evas_render_mapped_context_clip_set(Evas_Object *obj, Evas *e, void *ctx, Evas_Proxy_Render_Data *proxy_render_data, int off_x, int off_y)
+{
+   int x, y, w, h;
+   Eina_Bool proxy_src_clip = EINA_TRUE;
+
+   if (proxy_render_data) proxy_src_clip = proxy_render_data->source_clip;
+
+   if (proxy_src_clip)
+     {
+        x = obj->cur.cache.clip.x;
+        y = obj->cur.cache.clip.y;
+        w = obj->cur.cache.clip.w;
+        h = obj->cur.cache.clip.h;
+
+        RECTS_CLIP_TO_RECT(x, y, w, h,
+                           obj->cur.clipper->cur.cache.clip.x,
+                           obj->cur.clipper->cur.cache.clip.y,
+                           obj->cur.clipper->cur.cache.clip.w,
+                           obj->cur.clipper->cur.cache.clip.h);
+
+        e->engine.func->context_clip_set(e->engine.data.output,
+                                         ctx, x + off_x, y + off_y, w, h);
+     }
+   else
+     {
+        //FIXME: Consider to clip by the proxy clipper.
+        if (proxy_render_data->src_obj != obj)
+          {
+             x = obj->cur.clipper->cur.geometry.x + off_x;
+             y = obj->cur.clipper->cur.geometry.y + off_y;
+             w = obj->cur.clipper->cur.geometry.w;
+             h = obj->cur.clipper->cur.geometry.h;
+             e->engine.func->context_clip_set(e->engine.data.output, ctx, x, y,
+                                              w, h);
+          }
+     }
+}
+
 Eina_Bool
 evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
                    int off_x, int off_y, int mapped,
-                   int ecx, int ecy, int ecw, int ech
-#ifdef REND_DGB
-                   , int level
-#endif
-                  )
+                   int ecx, int ecy, int ecw, int ech,
+                   Evas_Proxy_Render_Data *proxy_render_data, int level,
+                   Eina_Bool use_mapped_ctx)
 {
    void *ctx;
+   Eina_Bool restore_image_clip = EINA_FALSE, old_use_clip = EINA_FALSE;
+   int oldm_x = 0, oldm_y = 0, ocx = 0, ocy = 0, ocw = 0, och = 0;
    Evas_Object *obj2;
    Eina_Bool clean_them = EINA_FALSE;
+   Eina_Bool proxy_src_clip = EINA_TRUE;
+   void *oldm_sfc = NULL;
+
+   if (!proxy_render_data)
+     {
+        if (evas_object_is_source_invisible(obj))
+          return clean_them;
+     }
+   else
+     proxy_src_clip = proxy_render_data->source_clip;
 
    evas_object_clip_recalc(obj);
 
    RDI(level);
    RD("      { evas_render_mapped(%p, %p,   %p, %p,   %i, %i,   %i,   %i)\n", e, obj, context, surface, off_x, off_y, mapped, level);
+
    if (mapped)
      {
-        if ((!evas_object_is_visible(obj)) || (obj->clip.clipees) ||
-            (obj->cur.have_clipees))
+        if (_evas_render_object_is_mask(obj))
+          {
+             if (!use_mapped_ctx || (surface != obj->mask.surface))
+               {
+                  RDI(level);
+                  RD("      }\n");
+                  return clean_them;
+               }
+             // else don't return: draw mask in its surface
+          }
+        else if (proxy_src_clip)
+          {
+             if ((!evas_object_is_visible(obj)) || (obj->clip.clipees)
+                 || (obj->cur.have_clipees))
+               {
+                  RDI(level);
+                  RD("      }\n");
+                  return clean_them;
+               }
+          }
+        else if (!evas_object_is_proxy_visible(obj) ||
+                 obj->clip.clipees || obj->cur.have_clipees)
           {
              RDI(level);
              RD("      }\n");
@@ -837,7 +1026,8 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
      }
 
    // set render_pre - for child objs that may not have gotten it.
-   obj->pre_render_done = EINA_TRUE;
+   //obj->pre_render_done = EINA_TRUE;
+
    RD("          Hasmap: %p (%d) %p %d -> %d\n",obj->func->can_map,
       obj->func->can_map ? obj->func->can_map(obj): -1,
       obj->cur.map, obj->cur.usemap,
@@ -859,63 +1049,35 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
              RD("      }\n");
              return clean_them;
           }
-        evas_object_map_update(obj, off_x, off_y, sw, sh, sw, sh);
+        changed = evas_object_map_update(obj, off_x, off_y, sw, sh, sw, sh);
 
-        if (obj->cur.map->surface)
+        if (obj->map.surface)
           {
-             if ((obj->cur.map->surface_w != sw) ||
-                 (obj->cur.map->surface_h != sh))
+             if ((obj->map.surface_w != sw) ||
+                 (obj->map.surface_h != sh))
                {
                   RDI(level);
                   RD("        new surf: %ix%i\n", sw, sh);
                   obj->layer->evas->engine.func->image_map_surface_free
-                     (e->engine.data.output, obj->cur.map->surface);
-                  obj->cur.map->surface = NULL;
+                     (e->engine.data.output, obj->map.surface);
+                  obj->map.surface = NULL;
                }
           }
-        if (!obj->cur.map->surface)
+        if (!obj->map.surface)
           {
-             obj->cur.map->surface_w = sw;
-             obj->cur.map->surface_h = sh;
+             obj->map.surface_w = sw;
+             obj->map.surface_h = sh;
 
-             obj->cur.map->surface =
+             obj->map.surface =
                 obj->layer->evas->engine.func->image_map_surface_new
-                (e->engine.data.output, obj->cur.map->surface_w,
-                 obj->cur.map->surface_h,
+                (e->engine.data.output, obj->map.surface_w,
+                 obj->map.surface_h,
                  obj->cur.map->alpha);
              RDI(level);
              RD("        fisrt surf: %ix%i\n", sw, sh);
              changed = EINA_TRUE;
           }
-        if (obj->smart.smart)
-          {
-             Evas_Object *o2;
-
-             EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), o2)
-               {
-                  if (!evas_object_is_visible(o2) &&
-                      !evas_object_was_visible(o2))
-                    {
-                       evas_object_change_reset(o2);
-                       continue;
-                    }
-                  if (o2->changed)
-                    {
-                       changed = EINA_TRUE;
-                       evas_object_change_reset(o2);
-                       break;
-                    }
-               }
-             if (obj->changed_color) changed = EINA_TRUE;
-             evas_object_change_reset(obj);
-          }
-        else if (obj->changed)
-          {
-             if (((obj->changed_pchange) && (obj->changed_map)) ||
-                 (obj->changed_color))
-               changed = EINA_TRUE;
-             evas_object_change_reset(obj);
-          }
+        if (!changed) changed = evas_object_smart_changed_get(obj);
 
         /* mark the old map as invalid, so later we don't reuse it as a
          * cache. */
@@ -923,7 +1085,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
            obj->prev.valid_map = EINA_FALSE;
 
         // clear surface before re-render
-        if ((changed) && (obj->cur.map->surface))
+        if ((changed) && (obj->map.surface))
           {
              int off_x2, off_y2;
 
@@ -940,10 +1102,10 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
                      (e->engine.data.output, ctx, EVAS_RENDER_COPY);
                   e->engine.func->rectangle_draw(e->engine.data.output,
                                                  ctx,
-                                                 obj->cur.map->surface,
+                                                 obj->map.surface,
                                                  0, 0,
-                                                 obj->cur.map->surface_w,
-                                                 obj->cur.map->surface_h);
+                                                 obj->map.surface_w,
+                                                 obj->map.surface_h);
                   e->engine.func->context_free(e->engine.data.output, ctx);
                }
              ctx = e->engine.func->context_new(e->engine.data.output);
@@ -955,21 +1117,27 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
                      (evas_object_smart_members_get_direct(obj), obj2)
                        {
                           clean_them |= evas_render_mapped(e, obj2, ctx,
-                                                           obj->cur.map->surface,
+                                                           obj->map.surface,
                                                            off_x2, off_y2, 1,
-                                                           ecx, ecy, ecw, ech
-#ifdef REND_DGB
-                                                           , level + 1
-#endif
-                                                          );
+                                                           ecx, ecy, ecw, ech,
+                                                           proxy_render_data,
+                                                           level + 1,
+                                                           EINA_FALSE);
+                          /* We aren't sure this object will be rendered by
+                             normal(not proxy) drawing after, we reset this
+                             only in case of normal drawing. For optmizing,
+                             push this object in an array then reset them
+                             in the end of the rendering.*/
+                          if (!proxy_render_data)
+                            evas_object_change_reset(obj2);
                        }
                }
              else
                {
                   int x = 0, y = 0, w = 0, h = 0;
 
-                  w = obj->cur.map->surface_w;
-                  h = obj->cur.map->surface_h;
+                  w = obj->map.surface_w;
+                  h = obj->map.surface_h;
                   RECTS_CLIP_TO_RECT(x, y, w, h,
                                      obj->cur.geometry.x + off_x2,
                                      obj->cur.geometry.y + off_y2,
@@ -979,7 +1147,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
                   e->engine.func->context_clip_set(e->engine.data.output,
                                                    ctx, x, y, w, h);
                   obj->func->render(obj, e->engine.data.output, ctx,
-                                    obj->cur.map->surface, off_x2, off_y2);
+                                    obj->map.surface, off_x2, off_y2);
                }
              e->engine.func->context_free(e->engine.data.output, ctx);
              rendered = EINA_TRUE;
@@ -990,60 +1158,55 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
 
         if (rendered)
           {
-             obj->cur.map->surface = e->engine.func->image_dirty_region
-                (e->engine.data.output, obj->cur.map->surface,
-                 0, 0, obj->cur.map->surface_w, obj->cur.map->surface_h);
+             obj->map.surface = e->engine.func->image_dirty_region
+                (e->engine.data.output, obj->map.surface,
+                 0, 0, obj->map.surface_w, obj->map.surface_h);
              obj->cur.valid_map = EINA_TRUE;
           }
         e->engine.func->context_clip_unset(e->engine.data.output,
                                            context);
-        if (obj->cur.map->surface)
+        if (obj->map.surface)
           {
-             if (obj->smart.smart)
+             if (obj->cur.clipper)
                {
-                  if (obj->cur.clipper)
+                  evas_object_clip_recalc(obj);
+
+                  if (obj->smart.smart)
                     {
-                       int x, y, w, h;
                        Evas_Object *tobj;
 
                        obj->cur.cache.clip.dirty = EINA_TRUE;
                        tobj = obj->cur.map_parent;
                        obj->cur.map_parent = obj->cur.clipper->cur.map_parent;
-                       evas_object_clip_recalc(obj);
                        obj->cur.map_parent = tobj;
-                       x = obj->cur.cache.clip.x;
-                       y = obj->cur.cache.clip.y;
-                       w = obj->cur.cache.clip.w;
-                       h = obj->cur.cache.clip.h;
-                       RECTS_CLIP_TO_RECT(x, y, w, h,
-                                          obj->cur.clipper->cur.cache.clip.x,
-                                          obj->cur.clipper->cur.cache.clip.y,
-                                          obj->cur.clipper->cur.cache.clip.w,
-                                          obj->cur.clipper->cur.cache.clip.h);
-                       e->engine.func->context_clip_set(e->engine.data.output,
-                                                        context,
-                                                        x + off_x, y + off_y, w, h);
                     }
-               }
-             else
-               {
-                  if (obj->cur.clipper)
+                  _evas_render_mapped_context_clip_set(obj, e, context,
+                                                       proxy_render_data,
+                                                       off_x, off_y);
+
+                  /* Clipper masks */
+                  if (_evas_render_object_is_mask(obj->cur.clipper))
                     {
-                       int x, y, w, h;
+                       // This path can be hit when we're multiplying masks on top of each other...
+                       Evas_Object *mask = obj->cur.clipper;
+                       if (mask->mask.redraw || !mask->mask.surface)
+                         evas_render_mask_subrender(obj->layer->evas, mask, obj->clip.prev_mask);
 
-                       evas_object_clip_recalc(obj);
-                       x = obj->cur.cache.clip.x;
-                       y = obj->cur.cache.clip.y;
-                       w = obj->cur.cache.clip.w;
-                       h = obj->cur.cache.clip.h;
-                       RECTS_CLIP_TO_RECT(x, y, w, h,
-                                          obj->cur.clipper->cur.cache.clip.x,
-                                          obj->cur.clipper->cur.cache.clip.y,
-                                          obj->cur.clipper->cur.cache.clip.w,
-                                          obj->cur.clipper->cur.cache.clip.h);
-                       e->engine.func->context_clip_set(e->engine.data.output,
-                                                        context,
-                                                        x + off_x, y + off_y, w, h);
+                       if (mask->mask.surface)
+                         {
+                            restore_image_clip = EINA_TRUE;
+                            e->engine.func->context_clip_image_get
+                                  (e->engine.data.output, context,
+                                   &oldm_sfc, &oldm_x, &oldm_y);
+                            old_use_clip = e->engine.func->context_clip_get
+                                  (e->engine.data.output, context,
+                                   &ocx, &ocy, &ocw, &och);
+                            e->engine.func->context_clip_image_set
+                                  (e->engine.data.output, context,
+                                   mask->mask.surface,
+                                   mask->cur.geometry.x + off_x,
+                                   mask->cur.geometry.y + off_y);
+                         }
                     }
                }
           }
@@ -1051,46 +1214,99 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
           e->engine.func->context_clip_clip(e->engine.data.output,
                                             context,
                                             ecx, ecy, ecw, ech);
-        if (obj->cur.cache.clip.visible)
+        if (obj->cur.cache.clip.visible || !proxy_src_clip)
           {
              obj->layer->evas->engine.func->context_multiplier_unset
                (e->engine.data.output, context);
+             obj->layer->evas->engine.func->context_render_op_set
+               (e->engine.data.output, context, obj->cur.render_op);
              obj->layer->evas->engine.func->image_map_draw
                (e->engine.data.output, context, surface,
-                   obj->cur.map->surface, obj->spans,
+                   obj->map.surface, obj->spans,
                    obj->cur.map->smooth, 0);
           }
+
+        if (restore_image_clip)
+          {
+             if (old_use_clip)
+               e->engine.func->context_clip_set(e->engine.data.output, context, ocx, ocy, ocw, och);
+             else
+               e->engine.func->context_clip_unset(e->engine.data.output, context);
+             e->engine.func->context_clip_image_set
+               (e->engine.data.output, context, oldm_sfc, oldm_x, oldm_y);
+          }
+
         // FIXME: needs to cache these maps and
         // keep them only rendering updates
         //        obj->layer->evas->engine.func->image_map_surface_free
-        //          (e->engine.data.output, obj->cur.map->surface);
-        //        obj->cur.map->surface = NULL;
+        //          (e->engine.data.output, obj->map.surface);
+        //        obj->map.surface = NULL;
      }
-   else
+   else // not "has map"
      {
+#if 0
         if (0 && obj->cur.cached_surface)
           fprintf(stderr, "We should cache '%s' [%i, %i, %i, %i]\n",
                   evas_object_type_get(obj),
                   obj->cur.bounding_box.x, obj->cur.bounding_box.x,
                   obj->cur.bounding_box.w, obj->cur.bounding_box.h);
+#endif
         if (mapped)
           {
              RDI(level);
              RD("        draw child of mapped obj\n");
-             ctx = e->engine.func->context_new(e->engine.data.output);
+             if (use_mapped_ctx)
+               ctx = context;
+             else
+               ctx = e->engine.func->context_new(e->engine.data.output);
              if (obj->smart.smart)
                {
+                  /* Clipper masks */
+                  if (obj->cur.clipper &&
+                      _evas_render_object_is_mask(obj->cur.clipper))
+                    {
+                       // This path can be hit when we're multiplying masks on top of each other...
+                       Evas_Object *mask = obj->cur.clipper;
+
+                       evas_object_clip_recalc(obj);
+
+                       if (mask->mask.redraw || !mask->mask.surface)
+                         evas_render_mask_subrender(obj->layer->evas, mask, obj->clip.prev_mask);
+
+                       if (mask->mask.surface)
+                         {
+                            restore_image_clip = EINA_TRUE;
+                            e->engine.func->context_clip_image_get
+                                  (e->engine.data.output, ctx,
+                                   &oldm_sfc, &oldm_x, &oldm_y);
+                            old_use_clip = e->engine.func->context_clip_get
+                                  (e->engine.data.output, ctx,
+                                   &ocx, &ocy, &ocw, &och);
+                            e->engine.func->context_clip_image_set
+                                  (e->engine.data.output, ctx,
+                                   mask->mask.surface,
+                                   mask->cur.geometry.x + off_x,
+                                   mask->cur.geometry.y + off_y);
+                         }
+                    }
+
                   EINA_INLIST_FOREACH
                      (evas_object_smart_members_get_direct(obj), obj2)
                        {
                           clean_them |= evas_render_mapped(e, obj2, ctx,
                                                            surface,
                                                            off_x, off_y, 1,
-                                                           ecx, ecy, ecw, ech
-#ifdef REND_DGB
-                                                           , level + 1
-#endif
-                                                          );
+                                                           ecx, ecy, ecw, ech,
+                                                           proxy_render_data,
+                                                           level + 1,
+                                                           restore_image_clip | use_mapped_ctx);
+                          /* We aren't sure this object will be rendered by
+                             normal(not proxy) drawing after, we reset this
+                             only in case of normal drawing. For optmizing,
+                             push this object in an array then reset them
+                             in the end of the rendering.*/
+                          if (!proxy_render_data)
+                            evas_object_change_reset(obj2);
                        }
                }
              else
@@ -1099,75 +1315,120 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
 
                   if (obj->cur.clipper)
                     {
-                       RD("        clip: %i %i %ix%i [%i %i %ix%i]\n",
-                          obj->cur.cache.clip.x + off_x,
-                          obj->cur.cache.clip.y + off_y,
-                          obj->cur.cache.clip.w,
-                          obj->cur.cache.clip.h,
-                          obj->cur.geometry.x + off_x,
-                          obj->cur.geometry.y + off_y,
-                          obj->cur.geometry.w,
-                          obj->cur.geometry.h);
-
-                       RD("        clipper: %i %i %ix%i\n",
-                          obj->cur.clipper->cur.cache.clip.x + off_x,
-                          obj->cur.clipper->cur.cache.clip.y + off_y,
-                          obj->cur.clipper->cur.cache.clip.w,
-                          obj->cur.clipper->cur.cache.clip.h);
-
-                       int x, y, w, h;
-
-                       if (_evas_render_has_map(obj))
+                       if (_evas_render_has_map(obj) ||
+                           _evas_render_object_is_mask(obj->cur.clipper))
                          evas_object_clip_recalc(obj);
+                       _evas_render_mapped_context_clip_set(obj, e, ctx,
+                                                            proxy_render_data,
+                                                            off_x, off_y);
 
-                       x = obj->cur.cache.clip.x + off_x;
-                       y = obj->cur.cache.clip.y + off_y;
-                       w = obj->cur.cache.clip.w;
-                       h = obj->cur.cache.clip.h;
-
-                       RECTS_CLIP_TO_RECT(x, y, w, h,
-                                          obj->cur.clipper->cur.cache.clip.x + off_x,
-                                          obj->cur.clipper->cur.cache.clip.y + off_y,
-                                          obj->cur.clipper->cur.cache.clip.w,
-                                          obj->cur.clipper->cur.cache.clip.h);
+                       /* Clipper masks */
+                       if (_evas_render_object_is_mask(obj->cur.clipper))
+                         {
+                            // This path can be hit when we're multiplying masks on top of each other...
+                            Evas_Object *mask = obj->cur.clipper;
+                            if (mask->mask.redraw || !mask->mask.surface)
+                              evas_render_mask_subrender(obj->layer->evas, mask, obj->clip.prev_mask);
 
-                       e->engine.func->context_clip_set(e->engine.data.output,
-                                                        ctx, x, y, w, h);
+                            if (mask->mask.surface)
+                              {
+                                 restore_image_clip = EINA_TRUE;
+                                 e->engine.func->context_clip_image_get
+                                       (e->engine.data.output, ctx,
+                                        &oldm_sfc, &oldm_x, &oldm_y);
+                                 old_use_clip = e->engine.func->context_clip_get
+                                       (e->engine.data.output, ctx,
+                                        &ocx, &ocy, &ocw, &och);
+                                 e->engine.func->context_clip_image_set
+                                       (e->engine.data.output, ctx,
+                                        mask->mask.surface,
+                                        mask->cur.geometry.x + off_x,
+                                        mask->cur.geometry.y + off_y);
+                              }
+                         }
                     }
                   obj->func->render(obj, e->engine.data.output, ctx,
                                     surface, off_x, off_y);
                }
-             e->engine.func->context_free(e->engine.data.output, ctx);
+             if (restore_image_clip)
+               {
+                  if (old_use_clip)
+                    e->engine.func->context_clip_set(e->engine.data.output, ctx, ocx, ocy, ocw, och);
+                  else
+                    e->engine.func->context_clip_unset(e->engine.data.output, ctx);
+                  e->engine.func->context_clip_image_set
+                    (e->engine.data.output, ctx, oldm_sfc, oldm_x, oldm_y);
+               }
+             if (!use_mapped_ctx)
+               e->engine.func->context_free(e->engine.data.output, ctx);
           }
         else
           {
              if (obj->cur.clipper)
                {
+                  Evas_Object *clipper = obj->cur.clipper;
                   int x, y, w, h;
 
-                  if (_evas_render_has_map(obj))
+                  if (_evas_render_has_map(obj) ||
+                      _evas_render_object_is_mask(clipper))
                     evas_object_clip_recalc(obj);
                   x = obj->cur.cache.clip.x;
                   y = obj->cur.cache.clip.y;
                   w = obj->cur.cache.clip.w;
                   h = obj->cur.cache.clip.h;
                   RECTS_CLIP_TO_RECT(x, y, w, h,
-                                     obj->cur.clipper->cur.cache.clip.x,
-                                     obj->cur.clipper->cur.cache.clip.y,
-                                     obj->cur.clipper->cur.cache.clip.w,
-                                     obj->cur.clipper->cur.cache.clip.h);
+                                     clipper->cur.cache.clip.x,
+                                     clipper->cur.cache.clip.y,
+                                     clipper->cur.cache.clip.w,
+                                     clipper->cur.cache.clip.h);
                   e->engine.func->context_clip_set(e->engine.data.output,
                                                    context,
                                                    x + off_x, y + off_y, w, h);
                   e->engine.func->context_clip_clip(e->engine.data.output,
                                                     context,
                                                     ecx, ecy, ecw, ech);
+#if 0
+                  if (_evas_render_object_is_mask(clipper))
+                    {
+                       // This path can be hit when we're multiplying masks on top of each other...
+                       Evas_Object *mask = obj->cur.clipper;
+                       if (mask->mask.redraw || !mask->mask.surface)
+                         evas_render_mask_subrender(obj->layer->evas, mask, obj->clip.prev_mask);
+
+                       if (mask->mask.surface)
+                         {
+                            restore_image_clip = EINA_TRUE;
+                            e->engine.func->context_clip_image_get
+                                  (e->engine.data.output, context,
+                                   &oldm_sfc, &oldm_x, &oldm_y);
+                            old_use_clip = e->engine.func->context_clip_get
+                                  (e->engine.data.output, context,
+                                   &ocx, &ocy, &ocw, &och);
+                            e->engine.func->context_clip_image_set
+                                  (e->engine.data.output, context,
+                                   mask->mask.surface,
+                                   mask->cur.geometry.x + off_x,
+                                   mask->cur.geometry.y + off_y);
+                         }
+                    }
+#endif
                }
 
              RDI(level);
              RD("        draw normal obj\n");
              obj->func->render(obj, e->engine.data.output, context, surface,
                                off_x, off_y);
+#if 0
+             if (restore_image_clip)
+               {
+                  if (old_use_clip)
+                    e->engine.func->context_clip_set(e->engine.data.output, context, ocx, ocy, ocw, och);
+                  else
+                    e->engine.func->context_clip_unset(e->engine.data.output, context);
+                  e->engine.func->context_clip_image_set
+                    (e->engine.data.output, context, oldm_sfc, oldm_x, oldm_y);
+               }
+#endif
           }
         if (obj->changed_map) clean_them = EINA_TRUE;
      }
@@ -1177,9 +1438,210 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
    return clean_them;
 }
 
+/* @internal
+ * Synchronously render a mask image (or smart object) into a surface.
+ * In SW the target surface will be ALPHA only (GRY8), after conversion.
+ * In GL the target surface will be RGBA for now. TODO: Find out how to
+ *   render GL to alpha, if that's possible.
+ */
+static void
+evas_render_mask_subrender(Evas *evas,
+                           Evas_Object *mask,
+                           Evas_Object *prev_mask)
+{
+   int x, y, w, h, r, g, b, a;
+   Eina_Bool is_image, done = EINA_FALSE;
+   void *ctx;
+
+   if (!mask) return;
+   if (!mask->mask.redraw && mask->mask.surface)
+     {
+        DBG("Requested mask redraw but the redraw flag is off.");
+        return;
+     }
+
+   is_image = (mask->type && !strcmp("image", mask->type));
+
+   x = mask->cur.geometry.x;
+   y = mask->cur.geometry.y;
+   w = mask->cur.geometry.w;
+   h = mask->cur.geometry.h;
+
+   r = mask->cur.color.r;
+   g = mask->cur.color.g;
+   b = mask->cur.color.b;
+   a = mask->cur.color.a;
+   if ((r != 255) || (g != 255) || (b != 255) || (a != 255))
+     {
+        mask->cur.color.r = 255;
+        mask->cur.color.g = 255;
+        mask->cur.color.b = 255;
+        mask->cur.color.a = 255;
+     }
+
+   if (prev_mask == mask)
+     prev_mask = NULL;
+
+   if (prev_mask)
+     {
+        if (!prev_mask->mask.is_mask)
+          {
+             ERR("Passed invalid mask that is not a mask");
+             prev_mask = NULL;
+          }
+        else if (!prev_mask->mask.surface)
+          {
+             // Note: This is preventive code. Never seen it happen.
+             WRN("Mask render order may be invalid");
+             evas_render_mask_subrender(evas, prev_mask, prev_mask->clip.prev_mask);
+          }
+     }
+
+   mask->mask.redraw = EINA_FALSE;
+
+   if (is_image)
+     {
+        Eina_Bool filled = EINA_FALSE;
+
+        if (evas_object_image_filled_get(mask))
+          filled = EINA_TRUE;
+        else
+          {
+             int fx, fy, fw, fh;
+             evas_object_image_fill_get(mask, &fx, &fy, &fw, &fh);
+             if (!fx && !fy && (fw == w) && (fh == h))
+               filled = EINA_TRUE;
+          }
+
+        if (filled && !prev_mask && mask->func->engine_data_get &&
+            mask->layer->evas->engine.func->image_scaled_update)
+          {
+             /* Fast path (for GL) that avoids creating a map surface, render the
+              * scaled image in it, when the shaders can just scale on the fly. */
+             Eina_Bool smooth = evas_object_image_smooth_scale_get(mask);
+             void *original = mask->func->engine_data_get(mask);
+             void *scaled = mask->layer->evas->engine.func->image_scaled_update
+                   (mask->layer->evas->engine.data.output, mask->mask.surface, original, w, h, smooth, EINA_TRUE, EVAS_COLORSPACE_GRY8);
+             if (scaled)
+               {
+                  done = EINA_TRUE;
+                  mask->mask.surface = scaled;
+                  mask->mask.w = w;
+                  mask->mask.h = h;
+                  mask->mask.is_alpha = (mask->layer->evas->engine.func->image_colorspace_get(mask->layer->evas->engine.data.output, scaled) == EVAS_COLORSPACE_GRY8);
+                  mask->mask.is_scaled = EINA_TRUE;
+               }
+          }
+     }
+
+   if (!done)
+     {
+
+        /* delete render surface if changed or if already alpha
+         * (we don't know how to render objects to alpha) */
+        if (mask->mask.surface &&
+            ((w != mask->mask.w) || (h != mask->mask.h) || mask->mask.is_alpha || mask->mask.is_scaled))
+          {
+             mask->layer->evas->engine.func->image_map_surface_free
+                   (mask->layer->evas->engine.data.output, mask->mask.surface);
+             mask->mask.surface = NULL;
+          }
+
+        /* create new RGBA render surface if needed */
+        if (!mask->mask.surface)
+          {
+             mask->mask.surface = mask->layer->evas->engine.func->image_map_surface_new
+                   (mask->layer->evas->engine.data.output, w, h, EINA_TRUE);
+             if (!mask->mask.surface) goto end;
+             mask->mask.is_alpha = EINA_FALSE;
+             mask->mask.is_scaled = EINA_FALSE;
+             mask->mask.w = w;
+             mask->mask.h = h;
+          }
+
+        /* Clear surface with transparency */
+        ctx = mask->layer->evas->engine.func->context_new
+              (mask->layer->evas->engine.data.output);
+
+        mask->layer->evas->engine.func->context_color_set
+              (mask->layer->evas->engine.data.output, ctx, 0, 0, 0, 0);
+        mask->layer->evas->engine.func->context_render_op_set
+              (mask->layer->evas->engine.data.output, ctx, EVAS_RENDER_COPY);
+        mask->layer->evas->engine.func->rectangle_draw
+              (mask->layer->evas->engine.data.output, ctx, mask->mask.surface, 0, 0, w, h);
+        mask->layer->evas->engine.func->context_free
+              (mask->layer->evas->engine.data.output, ctx);
+
+        /* Render mask to RGBA surface */
+        ctx = mask->layer->evas->engine.func->context_new
+              (mask->layer->evas->engine.data.output);
+        if (prev_mask)
+          {
+             mask->layer->evas->engine.func->context_clip_image_set
+                   (mask->layer->evas->engine.data.output, ctx,
+                    prev_mask->mask.surface,
+                    prev_mask->cur.geometry.x - x,
+                    prev_mask->cur.geometry.y - y);
+          }
+        evas_render_mapped(evas, mask, ctx, mask->mask.surface,
+                           -x, -y, 1, 0, 0, evas->output.w, evas->output.h,
+                           NULL, 1, EINA_TRUE);
+        mask->layer->evas->engine.func->context_free
+              (mask->layer->evas->engine.data.output, ctx);
+
+        /* BEGIN HACK */
+
+        /* Now we want to convert this RGBA surface to Alpha.
+         * NOTE: So, this is not going to work with the GL engine but only with
+         *       the SW engine. Here's the detection hack:
+         * FIXME: If you know of a way to support rendering to GL_ALPHA in GL,
+         *        then we should render directly to an ALPHA surface. A priori,
+         *        GLES FBO does not support this.
+         */
+        if (!mask->layer->evas->engine.func->gl_surface_read_pixels)
+          {
+             RGBA_Image *alpha_surface;
+             DATA32 *rgba;
+             DATA8* alpha;
+
+             alpha_surface = mask->layer->evas->engine.func->image_new_from_copied_data
+                   (mask->layer->evas->engine.data.output, w, h, NULL, EINA_TRUE, EVAS_COLORSPACE_GRY8);
+             if (!alpha_surface) goto end;
+
+             /* Copy alpha channel */
+             rgba = ((RGBA_Image *) mask->mask.surface)->image.data;
+             alpha = alpha_surface->image.data8;
+             for (y = h; y; --y)
+               for (x = w; x; --x, alpha++, rgba++)
+                 *alpha = (DATA8) A_VAL(rgba);
+
+             /* Now we can drop the original surface */
+             mask->layer->evas->engine.func->image_map_surface_free
+                   (mask->layer->evas->engine.data.output, mask->mask.surface);
+             mask->mask.surface = alpha_surface;
+             mask->mask.is_alpha = EINA_TRUE;
+          }
+        /* END OF HACK */
+     }
+
+   mask->mask.surface = mask->layer->evas->engine.func->image_dirty_region
+         (mask->layer->evas->engine.data.output, mask->mask.surface, 0, 0, w, h);
+
+end:
+
+   if ((r != 255) || (g != 255) || (b != 255) || (a != 255))
+     {
+        mask->cur.color.r = r;
+        mask->cur.color.g = g;
+        mask->cur.color.b = b;
+        mask->cur.color.a = a;
+     }
+}
+
 static void
 _evas_render_cutout_add(Evas *e, Evas_Object *obj, int off_x, int off_y)
 {
+   if (evas_object_is_source_invisible(obj)) return;
    if (evas_object_is_opaque(obj))
      {
         Evas_Coord cox, coy, cow, coh;
@@ -1258,6 +1720,10 @@ evas_render_updates_internal(Evas *e,
    MAGIC_CHECK_END();
    if (!e->changed) return NULL;
 
+   // Do not render if the output size is 1 x 1.
+   if ((e->output.w == 1) && (e->output.h == 1))
+     return NULL;
+
 #ifdef EVAS_CSERVE2
    if (evas_cserve2_use_get())
       evas_cserve2_dispatch();
@@ -1301,6 +1767,8 @@ evas_render_updates_internal(Evas *e,
    for (i = 0; i < e->restack_objects.count; ++i)
      {
         obj = eina_array_data_get(&e->restack_objects, i);
+        if (_evas_render_object_is_mask(obj))
+          _evas_mask_redraw_set(e, obj);
         obj->func->render_pre(obj);
         _evas_render_prev_cur_clip_cache_add(e, obj);
      }
@@ -1374,8 +1842,11 @@ evas_render_updates_internal(Evas *e,
           {
              /* master clip is already present. check for size changes in the 
               * viewport, and update master clip size if needed */
-             if ((e->viewport.changed) || (e->output.changed))
+             if ((e->viewport.changed) || (e->output.changed) || 
+                 (e->framespace.changed))
                {
+                  evas_object_move(e->framespace.clip, 
+                                   e->framespace.x, e->framespace.y);
                   evas_object_resize(e->framespace.clip,
                                      e->viewport.w - e->framespace.w,
                                      e->viewport.h - e->framespace.h);
@@ -1399,8 +1870,9 @@ evas_render_updates_internal(Evas *e,
              Evas_Object *pclip;
 
              obj = eina_array_data_get(&e->render_objects, i);
-             if (evas_object_is_frame_object_get(obj))
-               continue;
+             if (obj->is_frame) continue;
+
+             if (obj->delete_me) continue;
 
              EINA_RECTANGLE_SET(&obj_rect,
                                 obj->cur.geometry.x, obj->cur.geometry.y,
@@ -1412,6 +1884,10 @@ evas_render_updates_internal(Evas *e,
 
              if (!(pclip = evas_object_clip_get(obj)))
                {
+                  /* skip clipping if the object is itself the 
+                   * framespace clip */
+                  if (obj == e->framespace.clip) continue;
+
                   /* clip this object so it does not draw on the window frame */
                   evas_object_clip_set(obj, e->framespace.clip);
                }
@@ -1437,6 +1913,7 @@ evas_render_updates_internal(Evas *e,
         if (UNLIKELY((evas_object_is_opaque(obj) ||
                       ((obj->func->has_opaque_rect) &&
                        (obj->func->has_opaque_rect(obj)))) &&
+                     (!obj->mask.is_mask) && (!obj->clip.mask) &&
                      evas_object_is_visible(obj) &&
                      (!obj->clip.clipees) &&
                      (obj->cur.visible) &&
@@ -1540,6 +2017,9 @@ evas_render_updates_internal(Evas *e,
                        x = cx; y = cy; w = cw; h = ch;
                        if (((w > 0) && (h > 0)) || (obj->smart.smart))
                          {
+                            Evas_Object *prev_mask = NULL;
+                            Evas_Object *mask = NULL;
+
                             if (!obj->smart.smart)
                               {
                                  RECTS_CLIP_TO_RECT(x, y, w, h,
@@ -1548,20 +2028,34 @@ evas_render_updates_internal(Evas *e,
                                                     obj->cur.cache.clip.w,
                                                     obj->cur.cache.clip.h);
                               }
-                            if (obj->cur.mask)
-                              e->engine.func->context_mask_set(e->engine.data.output,
-                                                               e->engine.data.context,
-                                                               obj->cur.mask->func->engine_data_get(obj->cur.mask),
-                                                               obj->cur.mask->cur.geometry.x + off_x,
-                                                               obj->cur.mask->cur.geometry.y + off_y,
-                                                               obj->cur.mask->cur.geometry.w,
-                                                               obj->cur.mask->cur.geometry.h);
-                            else
-                              e->engine.func->context_mask_unset(e->engine.data.output,
-                                                                 e->engine.data.context);
+
                             e->engine.func->context_clip_set(e->engine.data.output,
                                                              e->engine.data.context,
                                                              x, y, w, h);
+
+                            /* Clipper masks */
+                            if (_evas_render_object_is_mask(obj->cur.clipper))
+                              mask = obj->cur.clipper; // main object clipped by this mask
+                            else if (obj->clip.mask)
+                              mask = obj->clip.mask; // propagated clip
+                            prev_mask = obj->clip.prev_mask;
+
+                            if (mask)
+                              {
+                                 if (mask->mask.redraw || !mask->mask.surface)
+                                   evas_render_mask_subrender(obj->layer->evas, mask, prev_mask);
+
+                                 if (mask->mask.surface)
+                                   {
+                                      e->engine.func->context_clip_image_set
+                                            (e->engine.data.output,
+                                             e->engine.data.context,
+                                             mask->mask.surface,
+                                             mask->cur.geometry.x + off_x,
+                                             mask->cur.geometry.y + off_y);
+                                   }
+                              }
+
 #if 1 /* FIXME: this can slow things down... figure out optimum... coverage */
                             for (j = offset; j < e->temporary_objects.count; ++j)
                               {
@@ -1574,14 +2068,17 @@ evas_render_updates_internal(Evas *e,
 #endif
                             clean_them |= evas_render_mapped(e, obj, e->engine.data.context,
                                                              surface, off_x, off_y, 0,
-                                                             cx, cy, cw, ch
-#ifdef REND_DGB
-                                                             , 1
-#endif
-                                                            );
+                                                             cx, cy, cw, ch,
+                                                             NULL, 1, EINA_FALSE);
 
                             e->engine.func->context_cutout_clear(e->engine.data.output,
                                                                  e->engine.data.context);
+
+                            if (mask)
+                              {
+                                  e->engine.func->context_clip_image_unset
+                                    (e->engine.data.output, e->engine.data.context);
+                              }
                          }
                     }
                }
@@ -1607,6 +2104,12 @@ evas_render_updates_internal(Evas *e,
    for (i = 0; i < e->active_objects.count; ++i)
      {
         obj = eina_array_data_get(&e->active_objects, i);
+
+        // Sometimes objects are located at out of the rendering area(or clipping area), in this case render_pre callback is not called in rendering loop.
+        // if renderer call every active_object's render_post callback , change flags and pixel_updates informations will be cleared.
+        // so renderer should be check pre_render_done and rendering flag and then it call render_post
+        if(!obj->pre_render_done)
+          continue;
         obj->pre_render_done = EINA_FALSE;
         RD("    OBJ [%p] post... %i %i\n", obj, obj->changed, do_draw);
         if ((obj->changed) && (do_draw))
@@ -1641,7 +2144,17 @@ evas_render_updates_internal(Evas *e,
    for (i = 0; i < e->render_objects.count; ++i)
      {
         obj = eina_array_data_get(&e->render_objects, i);
+
+        if(!obj->pre_render_done)
+          continue;
+
         obj->pre_render_done = EINA_FALSE;
+        if ((obj->changed) && (do_draw))
+          {
+             obj->func->render_post(obj);
+             obj->restack = EINA_FALSE;
+             evas_object_change_reset(obj);
+          }
      }
 
    /* delete all objects flagged for deletion now */
@@ -1667,6 +2180,7 @@ evas_render_updates_internal(Evas *e,
         eina_array_clean(&e->render_objects);
         eina_array_clean(&e->restack_objects);
         eina_array_clean(&e->temporary_objects);
+        eina_array_foreach(&e->clip_changes, _evas_clip_changes_free, NULL);
         eina_array_clean(&e->clip_changes);
 /* we should flush here and have a mempool system for this        
         eina_array_flush(&e->active_objects);
@@ -1750,6 +2264,7 @@ evas_render_idle_flush(Evas *e)
    eina_array_flush(&e->delete_objects);
    eina_array_flush(&e->obscuring_objects);
    eina_array_flush(&e->temporary_objects);
+   eina_array_foreach(&e->clip_changes, _evas_clip_changes_free, NULL);
    eina_array_flush(&e->clip_changes);
 
    e->invalidate = EINA_TRUE;
@@ -1764,11 +2279,11 @@ evas_sync(Evas *e)
 static void
 _evas_render_dump_map_surfaces(Evas_Object *obj)
 {
-   if ((obj->cur.map) && obj->cur.map->surface)
+   if ((obj->cur.map) && obj->map.surface)
      {
         obj->layer->evas->engine.func->image_map_surface_free
-           (obj->layer->evas->engine.data.output, obj->cur.map->surface);
-        obj->cur.map->surface = NULL;
+           (obj->layer->evas->engine.data.output, obj->map.surface);
+        obj->map.surface = NULL;
      }
 
    if (obj->smart.smart)
index f39721d..5c2e593 100644 (file)
@@ -255,7 +255,8 @@ _evas_smart_class_callbacks_create(Evas_Smart *s)
 static void
 _evas_smart_class_interfaces_create(Evas_Smart *s)
 {
-   unsigned int i, total_priv_sz;
+   unsigned int i;
+   unsigned int total_priv_sz = 0;
    const Evas_Smart_Class *sc;
 
    /* get number of interfaces on the smart */
index a8dec0d..93a302e 100644 (file)
@@ -26,12 +26,12 @@ evas_object_below_get_internal(const Evas_Object *obj)
      return (Evas_Object *)((EINA_INLIST_GET(obj))->prev);
    else
      {
-        if ((EINA_INLIST_GET((((Evas_Object *)obj)->layer)))->prev)
-          {
-             Evas_Layer *l;
+        Evas_Layer *l = (Evas_Layer *)(EINA_INLIST_GET(obj->layer))->prev;
 
-             l = (Evas_Layer *)((EINA_INLIST_GET((((Evas_Object *)obj)->layer)))->prev);
-             return (Evas_Object *)((EINA_INLIST_GET((l->objects)))->last);
+        for (; l; l = (Evas_Layer *)(EINA_INLIST_GET(l))->prev)
+          {
+             if (l->objects)
+               return (Evas_Object *)((EINA_INLIST_GET((l->objects)))->last);
           }
      }
    return NULL;
@@ -66,7 +66,8 @@ evas_object_raise(Evas_Object *obj)
    evas_object_change(obj);
    evas_object_inform_call_restack(obj);
    if (obj->layer->evas->events_frozen > 0) return;
-   if ((!evas_event_passes_through(obj)) && (!evas_event_freezes_through(obj)))
+   if ((!evas_event_passes_through(obj)) && (!evas_event_freezes_through(obj))
+      && (!evas_object_is_source_invisible(obj)))
      {
         if (!obj->smart.smart)
           {
@@ -113,7 +114,8 @@ evas_object_lower(Evas_Object *obj)
    evas_object_change(obj);
    evas_object_inform_call_restack(obj);
    if (obj->layer->evas->events_frozen > 0) return;
-   if ((!evas_event_passes_through(obj)) && (!evas_event_freezes_through(obj)))
+   if ((!evas_event_passes_through(obj)) && (!evas_event_freezes_through(obj))
+       && (!evas_object_is_source_invisible(obj)))
      {
         if (!obj->smart.smart)
           {
@@ -191,7 +193,8 @@ evas_object_stack_above(Evas_Object *obj, Evas_Object *above)
    evas_object_change(obj);
    evas_object_inform_call_restack(obj);
    if (obj->layer->evas->events_frozen > 0) return;
-   if ((!evas_event_passes_through(obj)) && (!evas_event_freezes_through(obj)))
+   if ((!evas_event_passes_through(obj)) && (!evas_event_freezes_through(obj))
+       && (!evas_object_is_source_invisible(obj)))
      {
         if (!obj->smart.smart)
           {
@@ -269,7 +272,8 @@ evas_object_stack_below(Evas_Object *obj, Evas_Object *below)
    evas_object_change(obj);
    evas_object_inform_call_restack(obj);
    if (obj->layer->evas->events_frozen > 0) return;
-   if ((!evas_event_passes_through(obj)) && (!evas_event_freezes_through(obj)))
+   if ((!evas_event_passes_through(obj)) && (!evas_event_freezes_through(obj))
+       && (!evas_object_is_source_invisible(obj)))
      {
         if (!obj->smart.smart)
           {
index f2bf1e4..8ed10b8 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 -DPACKAGE_BIN_DIR=\"$(bindir)\" \
 -DPACKAGE_LIB_DIR=\"$(libdir)\" \
 -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FREETYPE_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @EET_CFLAGS@ \
@@ -29,4 +29,4 @@ evas_cs_server.c \
 evas_cs_client.c \
 evas_cs_mem.c
 
-libevas_cserve_la_LIBADD = @EINA_LIBS@ @EFL_SHM_OPEN_LIBS@
+libevas_cserve_la_LIBADD = @EVAS_GENERAL_LIBS@ @EFL_SHM_OPEN_LIBS@
index 39d7048..2aa0c5c 100644 (file)
@@ -4,7 +4,7 @@ AM_CPPFLAGS = \
 -I. \
 -I$(top_srcdir)/src/lib \
 -I$(top_srcdir)/src/lib/include \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FREETYPE_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @EET_CFLAGS@ \
@@ -26,6 +26,6 @@ libevas_cserve2_utils_la_SOURCES = \
 evas_cs2_utils.h \
 evas_cs2_utils.c
 
-libevas_cserve2_la_LIBADD = @EINA_LIBS@ libevas_cserve2_utils.la
+libevas_cserve2_la_LIBADD = @EVAS_GENERAL_LIBS@ libevas_cserve2_utils.la
 
 endif
index df45b0a..7fdc053 100644 (file)
@@ -930,7 +930,7 @@ _font_load_server_send(Font_Entry *fe, Message_Type type)
    msg->dpi = fe->dpi;
 
    buf = ((char *)msg) + sizeof(*msg);
-   memcpy(buf, fe->source, source_len);
+   if (source_len > 0) memcpy(buf, fe->source, source_len);
    buf += source_len;
    memcpy(buf, fe->name, path_len);
 
@@ -1043,7 +1043,7 @@ _glyph_request_cb(void *data, const void *msg)
         while (i < nglyphs)
           {
              unsigned int idx, offset, glsize;
-             int rows, width, pitch, num_grays, pixel_mode;
+             int rows, width, pitch;
              CS_Glyph_Out *gl;
 
              memcpy(&idx, buf, sizeof(int));
@@ -1058,10 +1058,6 @@ _glyph_request_cb(void *data, const void *msg)
              buf += sizeof(int);
              memcpy(&pitch, buf, sizeof(int));
              buf += sizeof(int);
-             memcpy(&num_grays, buf, sizeof(int));
-             buf += sizeof(int);
-             memcpy(&pixel_mode, buf, sizeof(int));
-             buf += sizeof(int);
 
              gl = fash_gl_find(fe->fash[grd->hints], idx);
              gl->map = map;
@@ -1070,9 +1066,11 @@ _glyph_request_cb(void *data, const void *msg)
              gl->base.bitmap.rows = rows;
              gl->base.bitmap.width = width;
              gl->base.bitmap.pitch = pitch;
-             gl->base.bitmap.buffer = map->data + gl->offset;
-             gl->base.bitmap.num_grays = num_grays;
-             gl->base.bitmap.pixel_mode = pixel_mode;
+                 gl->base.bitmap.buffer = NULL;
+             gl->base.bitmap.rle_alloc = 0;
+                       gl->base.bitmap.no_free_glout = 1;
+                       gl->base.rle =
+               (unsigned char *) gl->map->mempool.data + gl->offset;
 
              gl->rid = 0;
 
@@ -1132,7 +1130,7 @@ _glyph_request_server_send(Font_Entry *fe, Font_Hint_Flags hints, Eina_Bool used
    msg->nglyphs = nglyphs;
 
    buf = ((char *)msg) + sizeof(*msg);
-   memcpy(buf, fe->source, source_len);
+   if (source_len > 0) memcpy(buf, fe->source, source_len);
    buf += source_len;
    memcpy(buf, fe->name, name_len);
    buf += name_len;
index 0e7706c..7a5dde6 100644 (file)
@@ -1,16 +1,7 @@
-
 MAINTAINERCLEANFILES = Makefile.in
 
 SUBDIRS = common
 
-if BUILD_ENGINE_SOFTWARE_16
-
-SUBDIRS += common_16
-
-endif
-
 if BUILD_ENGINE_SOFTWARE_8
-
 SUBDIRS += common_8
-
 endif
index 1938e6c..fd48101 100644 (file)
@@ -14,7 +14,7 @@ AM_CPPFLAGS        = -I. \
                       @FREETYPE_CFLAGS@ @VALGRIND_CFLAGS@ \
                        @PIXMAN_CFLAGS@ \
                       @EET_CFLAGS@ @pthread_cflags@ \
-                      @EINA_CFLAGS@ \
+                      @EVAS_GENERAL_CFLAGS@ \
                        @FRIBIDI_CFLAGS@ @HARFBUZZ_CFLAGS@ \
                        @PIXMAN_CFLAGS@
 
@@ -26,6 +26,7 @@ evas_op_add_main_.c \
 evas_op_sub_main_.c \
 evas_op_mask_main_.c \
 evas_op_mul_main_.c \
+evas_alpha_main.c \
 evas_blend_main.c \
 evas_blit_main.c \
 evas_convert_color.c \
@@ -46,6 +47,7 @@ evas_font_draw.c \
 evas_font_load.c \
 evas_font_main.c \
 evas_font_query.c \
+evas_font_compress.c \
 evas_image_load.c \
 evas_image_save.c \
 evas_image_main.c \
diff --git a/src/lib/engines/common/evas_alpha_main.c b/src/lib/engines/common/evas_alpha_main.c
new file mode 100644 (file)
index 0000000..928a7ee
--- /dev/null
@@ -0,0 +1,81 @@
+#include "evas_common.h"
+#include "evas_blend_private.h"
+
+/** default op: d = d*(1-sa) + s */
+static void
+_alpha_func_blend(DATA8 *src, DATA8 *dst, int len)
+{
+   int k;
+
+   EINA_SAFETY_ON_NULL_RETURN(src);
+   EINA_SAFETY_ON_NULL_RETURN(dst);
+
+   for (k = len; k; k--)
+     {
+        int val = (*dst * (255 - *src)) / 255 + *src;
+        *dst++ = val;
+        src++;
+     }
+}
+
+/** d = s */
+static void
+_alpha_func_copy(DATA8 *src, DATA8 *dst, int len)
+{
+   EINA_SAFETY_ON_NULL_RETURN(src);
+   EINA_SAFETY_ON_NULL_RETURN(dst);
+
+   memcpy(dst, src, len);
+}
+
+/** d = d*s */
+static void
+_alpha_func_mul(DATA8 *src, DATA8 *dst, int len)
+{
+   int k;
+
+   EINA_SAFETY_ON_NULL_RETURN(src);
+   EINA_SAFETY_ON_NULL_RETURN(dst);
+
+   for (k = len; k; k--)
+     {
+        int val = (*dst * *src) / 255;
+        *dst++ = val;
+        src++;
+     }
+}
+
+
+#if 0
+// Reference ops. In case of alpha, s == sa.
+EVAS_RENDER_BLEND = 0, /**< default op: d = d*(1-sa) + s */
+EVAS_RENDER_BLEND_REL = 1, /**< d = d*(1 - sa) + s*da */
+EVAS_RENDER_COPY = 2, /**< d = s */
+EVAS_RENDER_COPY_REL = 3, /**< d = s*da */
+EVAS_RENDER_ADD = 4, /* d = d + s */
+EVAS_RENDER_ADD_REL = 5, /**< d = d + s*da */
+EVAS_RENDER_SUB = 6, /**< d = d - s */
+EVAS_RENDER_SUB_REL = 7, /* d = d - s*da */
+EVAS_RENDER_TINT = 8, /**< d = d*s + d*(1 - sa) + s*(1 - da) */
+EVAS_RENDER_TINT_REL = 9, /**< d = d*(1 - sa + s) */
+EVAS_RENDER_MASK = 10, /**< d = d*sa */
+EVAS_RENDER_MUL = 11, /**< d = d*s */
+#endif
+
+Alpha_Gfx_Func
+evas_common_alpha_func_get(int op)
+{
+   switch (op)
+     {
+      case EVAS_RENDER_BLEND:
+        return _alpha_func_blend;
+      case EVAS_RENDER_COPY:
+        return _alpha_func_copy;
+      case EVAS_RENDER_MASK:
+      case EVAS_RENDER_MUL:
+        return _alpha_func_mul;
+      default:
+        ERR("Not implemented yet.");
+        return NULL;
+     }
+}
index 1d14951..0029198 100644 (file)
@@ -27,5 +27,8 @@ RGBA_Gfx_Pt_Func     evas_common_gfx_func_composite_pixel_color_pt_get   (Image_
 RGBA_Gfx_Pt_Func     evas_common_gfx_func_composite_mask_color_pt_get    (DATA32 col, RGBA_Image *dst, int op);
 RGBA_Gfx_Pt_Func     evas_common_gfx_func_composite_pixel_mask_pt_get    (Image_Entry_Flags src_flags, RGBA_Image *dst, int op);
 
+/* Alpha/mask functions */
+Alpha_Gfx_Func       evas_common_alpha_func_get (int op);
+
 
 #endif /* _EVAS_BLEND_PRIVATE_H */
index 70a9e90..7abe5fc 100644 (file)
@@ -1,6 +1,30 @@
 #include "evas_common.h"
 #include "evas_convert_color.h"
 
+#ifdef BUILD_NEON
+#include <arm_neon.h>
+#endif
+
+EAPI DATA32
+evas_common_convert_ag_premul(DATA16 *data, unsigned int len)
+{
+   DATA16 *de = data + len;
+   DATA32 nas = 0;
+
+   while (data < de)
+     {
+        DATA16  a = 1 + ((*data >> 8) & 0xff);
+
+        *data = (*data & 0xff00) |
+          ((((*data & 0xff) * a) >> 8) & 0xff);
+        data++;
+
+        if ((a == 1) || (a == 256))
+          nas++;
+     }
+
+   return nas;
+}
 
 EAPI DATA32
 evas_common_convert_argb_premul(DATA32 *data, unsigned int len)
@@ -8,6 +32,42 @@ evas_common_convert_argb_premul(DATA32 *data, unsigned int len)
    DATA32 *de = data + len;
    DATA32 nas = 0;
 
+   #ifdef BUILD_NEON
+   if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+     {
+        uint8x8_t mask_0x00 = vdup_n_u8(0);
+        uint8x8_t mask_0x01 = vdup_n_u8(1);
+        uint8x8_t mask_0xff = vdup_n_u8(255);
+        uint8x8_t cmp;
+
+        while (data <= de - 8)
+          {
+
+             uint8x8x4_t rgba = vld4_u8(data);
+
+             cmp = vand_u8(vorr_u8(
+               vceq_u8(rgba.val[3], mask_0xff),
+               vceq_u8(rgba.val[3], mask_0x00)
+             ), mask_0x01);
+             nas += vpaddl_u32(vpaddl_u16(vpaddl_u8(cmp)));
+
+             uint16x8x4_t lrgba;
+
+             lrgba.val[0] = vmovl_u8(rgba.val[0]);
+             lrgba.val[1] = vmovl_u8(rgba.val[1]);
+             lrgba.val[2] = vmovl_u8(rgba.val[2]);
+
+             rgba.val[0] = vshrn_n_u16(vmlal_u8(lrgba.val[0], rgba.val[0], rgba.val[3]), 8);
+             rgba.val[1] = vshrn_n_u16(vmlal_u8(lrgba.val[1], rgba.val[1], rgba.val[3]), 8);
+             rgba.val[2] = vshrn_n_u16(vmlal_u8(lrgba.val[2], rgba.val[2], rgba.val[3]), 8);
+
+             vst4_u8(data, rgba);
+             data += 8;
+
+          }
+     }
+   #endif
+
    while (data < de)
      {
        DATA32  a = 1 + (*data >> 24);
@@ -29,18 +89,28 @@ evas_common_convert_argb_unpremul(DATA32 *data, unsigned int len)
 {
    DATA32  *de = data + len;
 
+   DATA32 preva = 0;
+   DATA32 prevdata = 0;
+
    while (data < de)
      {
-       DATA32  a = (*data >> 24);
-
-       if ((a > 0) && (a < 255))
-          *data = ARGB_JOIN(a,
-                            (R_VAL(data) * 255) / a,
-                            (G_VAL(data) * 255) / a,
-                            (B_VAL(data) * 255) / a);
-       data++;
+        if (preva == *data)
+          {
+            *data = prevdata;
+          }
+        else
+          {
+            DATA32  a = (*data >> 24);
+            preva = *data;
+            if ((a > 0) && (a < 255))
+               *data = ARGB_JOIN(a,
+                     (R_VAL(data) * 255) / a,
+                     (G_VAL(data) * 255) / a,
+                     (B_VAL(data) * 255) / a);
+            prevdata = *data;
+          }
+        data++;
      }
-
 }
 
 EAPI void
index 0224879..ac47da7 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _EVAS_CONVERT_COLOR_H
 #define _EVAS_CONVERT_COLOR_H
 
-
+EAPI DATA32 evas_common_convert_ag_premul                          (DATA16 *data, unsigned int len);
 EAPI DATA32 evas_common_convert_argb_premul                        (DATA32 *src, unsigned int len);
 EAPI void evas_common_convert_argb_unpremul                        (DATA32 *src, unsigned int len);
 EAPI void evas_common_convert_color_argb_premul                    (int a, int *r, int *g, int *b);
index 013c2e7..bdddd79 100644 (file)
@@ -105,8 +105,6 @@ evas_common_convert_yuv_422_601_to(void *data, int w, int h, Evas_Colorspace csp
         {
            void *dst;
 
-           fprintf(stderr, "to argb888\n");
-
            dst = malloc(sizeof (unsigned int) * w * h);
            if (!dst) return NULL;
 
@@ -132,7 +130,7 @@ evas_common_convert_yuv_422P_601_to(void *data, int w, int h, Evas_Colorspace cs
            if (!dst) return NULL;
 
            evas_common_convert_yuv_420p_601_rgba(data, dst, w, h);
-           break;
+           return dst;
         }
       default:
          break;
@@ -153,7 +151,7 @@ evas_common_convert_yuv_420_601_to(void *data, int w, int h, Evas_Colorspace csp
            if (!dst) return NULL;
 
            evas_common_convert_yuv_420_601_rgba(data, dst, w, h);
-           break;
+           return dst;
         }
       default:
          break;
@@ -174,7 +172,7 @@ evas_common_convert_yuv_420T_601_to(void *data, int w, int h, Evas_Colorspace cs
            if (!dst) return NULL;
 
            evas_common_convert_yuv_420_601_rgba(data, dst, w, h);
-           break;
+           return dst;
         }
       default:
          break;
index da19f9c..bad0880 100644 (file)
@@ -573,7 +573,7 @@ evas_common_convert_func_get(DATA8 *dest, int w, int h __UNUSED__, int depth, DA
        if (depth == 24)
          {
 #ifdef BUILD_CONVERT_24_RGB_888
-            if ((rmask == 0x00ff0000) && (gmask == 0x0000ff00) && (bmask == 0x000000ff))
+            if ((rmask == 0x000000ff) && (gmask == 0x0000ff00) && (bmask == 0x00ff0000))
               {
                  if (rotation == 0)
                    return evas_common_convert_rgba_to_24bpp_rgb_888;
@@ -587,7 +587,7 @@ evas_common_convert_func_get(DATA8 *dest, int w, int h __UNUSED__, int depth, DA
               }
 #endif
 #ifdef BUILD_CONVERT_24_BGR_888
-            if ((rmask == 0x000000ff) && (gmask == 0x0000ff00) && (bmask == 0x00ff0000))
+            if ((rmask == 0x00ff0000) && (gmask == 0x0000ff00) && (bmask == 0x000000ff))
               {
                  if (rotation == 0)
                    return evas_common_convert_rgba_to_24bpp_bgr_888;
index 9efa006..d213b20 100644 (file)
@@ -23,7 +23,7 @@ evas_common_convert_rgba_to_24bpp_rgb_888(DATA32 *src, DATA8 *dst, int src_jump,
             dst_ptr+=3;
          }
        src_ptr += src_jump;
-       dst_ptr += (dst_jump * 3);
+       dst_ptr += dst_jump;
      }
    return;
 }
@@ -55,7 +55,7 @@ evas_common_convert_rgba_to_24bpp_rgb_666(DATA32 *src, DATA8 *dst, int src_jump,
             dst_ptr+=3;
          }
        src_ptr += src_jump;
-       dst_ptr += (dst_jump * 3);
+       dst_ptr += dst_jump;
      }
    return;
 }
@@ -82,7 +82,7 @@ evas_common_convert_rgba_to_24bpp_bgr_888(DATA32 *src, DATA8 *dst, int src_jump,
             dst_ptr+=3;
          }
        src_ptr += src_jump;
-       dst_ptr += (dst_jump * 3);
+       dst_ptr += dst_jump;
      }
    return;
 }
index b007350..f758b50 100755 (executable)
@@ -1,5 +1,8 @@
 #include "evas_common.h"
 #include "evas_convert_rgb_32.h"
+#ifdef BUILD_NEON
+#include <arm_neon.h>
+#endif
 
 #ifdef BUILD_CONVERT_32_RGB_8888
 #ifdef BUILD_CONVERT_32_RGB_ROT0
@@ -49,51 +52,252 @@ evas_common_convert_rgba_to_32bpp_rgb_8888_rot_180 (DATA32 *src, DATA8 *dst, int
 #endif
 
 #ifdef TILE_ROTATE
+#ifdef BUILD_NEON
 #define FAST_SIMPLE_ROTATE(suffix, pix_type) \
    static void \
-   blt_rotated_90_trivial_##suffix(pix_type       *dst, \
+   blt_rotated_90_trivial_##suffix(pix_type * restrict dst, \
                                    int             dst_stride, \
-                                   const pix_type *src, \
+                                   const pix_type * restrict src, \
                                    int             src_stride, \
                                    int             w, \
                                    int             h) \
    { \
       int x, y; \
-      for (y = 0; y < h; y++) \
+      if((w%4) == 0) \
+      { \
+        int klght = 4 * src_stride; \
+        for(y = 0; y < h; y++) \
         { \
-           const pix_type *s = src + (h - y - 1); \
-           pix_type *d = dst + (dst_stride * y); \
+          const pix_type *s = &(src[(h - y - 1)]); \
+          pix_type *d = &(dst[(dst_stride * y)]); \
+          pix_type *ptr1 = s; \
+          pix_type *ptr2 = ptr1 + src_stride; \
+          pix_type *ptr3 = ptr2 + src_stride; \
+          pix_type *ptr4 = ptr3 + src_stride; \
+          for(x = 0; x < w; x+=4) \
+          { \
+            pix_type s_array[4] = {*ptr1, *ptr2, *ptr3, *ptr4}; \
+            vst1q_s32(d, vld1q_s32(s_array)); \
+            d += 4; \
+            ptr1 += klght; \
+            ptr2 += klght; \
+            ptr3 += klght; \
+            ptr4 += klght; \
+          } \
+        } \
+      } \
+      else \
+      { \
+        for (y = 0; y < h; y++) \
+          { \
+             const pix_type *s = &(src[(h - y - 1)]); \
+             pix_type *d = &(dst[(dst_stride * y)]); \
+             for (x = 0; x < w; x++) \
+               { \
+                  *d++ = *s; \
+                  s += src_stride; \
+               } \
+          } \
+      } \
+   } \
+   static void \
+   blt_rotated_270_trivial_##suffix(pix_type * restrict dst, \
+                                    int             dst_stride, \
+                                    const pix_type * restrict src, \
+                                    int             src_stride, \
+                                    int             w, \
+                                    int             h) \
+   { \
+      int x, y; \
+      if((w%4) == 0) \
+      { \
+        int klght = 4 * src_stride; \
+        for(y = 0; y < h; y++) \
+        { \
+          const pix_type *s = &(src[(src_stride * (w - 1)) + y]); \
+          pix_type *d = &(dst[(dst_stride * y)]); \
+          pix_type *ptr1 = s; \
+          pix_type *ptr2 = ptr1 - src_stride; \
+          pix_type *ptr3 = ptr2 - src_stride; \
+          pix_type *ptr4 = ptr3 - src_stride; \
+          for(x = 0; x < w; x+=4) \
+          { \
+            pix_type s_array[4] = {*ptr1, *ptr2, *ptr3, *ptr4}; \
+            vst1q_s32(d, vld1q_s32(s_array)); \
+            d += 4; \
+            ptr1 -= klght; \
+            ptr2 -= klght; \
+            ptr3 -= klght; \
+            ptr4 -= klght; \
+          } \
+        } \
+      } \
+      else \
+      { \
+        for(y = 0; y < h; y++) \
+        { \
+           const pix_type *s = &(src[(src_stride * (w - 1)) + y]); \
+           pix_type *d = &(dst[(dst_stride * y)]); \
            for (x = 0; x < w; x++) \
-             { \
-                *d++ = *s; \
-                s += src_stride; \
-             } \
+           { \
+              *d++ = *s; \
+              s -= src_stride; \
+           } \
+        } \
+      } \
+   } \
+   static void \
+   blt_rotated_90_##suffix(pix_type * restrict dst, \
+                           int             dst_stride, \
+                           const pix_type * restrict src, \
+                           int             src_stride, \
+                           int             w, \
+                           int             h) \
+   { \
+      int x, leading_pixels = 0, trailing_pixels = 0; \
+      const int TILE_SIZE = TILE_CACHE_LINE_SIZE / sizeof(pix_type); \
+      if ((uintptr_t)dst & (TILE_CACHE_LINE_SIZE - 1)) \
+        { \
+           leading_pixels = TILE_SIZE - \
+             (((uintptr_t)dst & (TILE_CACHE_LINE_SIZE - 1)) / sizeof(pix_type)); \
+           if (leading_pixels > w) \
+             leading_pixels = w; \
+           blt_rotated_90_trivial_##suffix(dst, \
+                                           dst_stride, \
+                                           src, \
+                                           src_stride, \
+                                           leading_pixels, \
+                                           h); \
+           dst += leading_pixels; \
+           src += leading_pixels * src_stride; \
+           w -= leading_pixels; \
+        } \
+      if ((uintptr_t)(dst + w) & (TILE_CACHE_LINE_SIZE - 1)) \
+        { \
+           trailing_pixels = (((uintptr_t)(dst + w) & \
+                               (TILE_CACHE_LINE_SIZE - 1)) / sizeof(pix_type)); \
+           if (trailing_pixels > w) \
+             trailing_pixels = w; \
+           w -= trailing_pixels; \
+        } \
+      for (x = 0; x < w; x += TILE_SIZE) \
+        { \
+           blt_rotated_90_trivial_##suffix(dst + x, \
+                                           dst_stride, \
+                                           &(src[(src_stride * x)]), \
+                                           src_stride, \
+                                           TILE_SIZE, \
+                                           h); \
+        } \
+      if (trailing_pixels) \
+        blt_rotated_90_trivial_##suffix(dst + w, \
+                                        dst_stride, \
+                                        &(src[(w * src_stride)]), \
+                                        src_stride, \
+                                        trailing_pixels, \
+                                        h); \
+   } \
+   static void \
+   blt_rotated_270_##suffix(pix_type * restrict dst, \
+                            int             dst_stride, \
+                            const pix_type * restrict src, \
+                            int             src_stride, \
+                            int             w, \
+                            int             h) \
+   { \
+      int x, leading_pixels = 0, trailing_pixels = 0; \
+      const int TILE_SIZE = TILE_CACHE_LINE_SIZE / sizeof(pix_type); \
+      if ((uintptr_t)dst & (TILE_CACHE_LINE_SIZE - 1)) \
+        { \
+           leading_pixels = TILE_SIZE - \
+             (((uintptr_t)dst & (TILE_CACHE_LINE_SIZE - 1)) / sizeof(pix_type)); \
+           if (leading_pixels > w) \
+             leading_pixels = w; \
+           blt_rotated_270_trivial_##suffix(dst, \
+                                            dst_stride, \
+                                            &(src[(src_stride * (w - leading_pixels))]), \
+                                            src_stride, \
+                                            leading_pixels, \
+                                            h); \
+           dst += leading_pixels; \
+           w -= leading_pixels; \
         } \
+      if ((uintptr_t)(dst + w) & (TILE_CACHE_LINE_SIZE - 1)) \
+        { \
+           trailing_pixels = (((uintptr_t)(dst + w) & \
+                               (TILE_CACHE_LINE_SIZE - 1)) / sizeof(pix_type)); \
+           if (trailing_pixels > w) \
+             trailing_pixels = w; \
+           w -= trailing_pixels; \
+           src += trailing_pixels * src_stride; \
+        } \
+      for (x = 0; x < w; x += TILE_SIZE) \
+        { \
+           blt_rotated_270_trivial_##suffix(dst + x, \
+                                            dst_stride, \
+                                            &(src[(src_stride * (w - x - TILE_SIZE))]), \
+                                            src_stride, \
+                                            TILE_SIZE, \
+                                            h); \
+        } \
+      if (trailing_pixels) \
+        blt_rotated_270_trivial_##suffix(dst + w, \
+                                         dst_stride, \
+                                         src - (trailing_pixels * src_stride), \
+                                         src_stride, \
+                                         trailing_pixels, \
+                                         h); \
+   }
+#else
+#define FAST_SIMPLE_ROTATE(suffix, pix_type) \
+   static void \
+   blt_rotated_90_trivial_##suffix(pix_type * restrict dst, \
+                                   int             dst_stride, \
+                                   const pix_type * restrict src, \
+                                   int             src_stride, \
+                                   int             w, \
+                                   int             h) \
+   { \
+      int x, y; \
+      { \
+        for (y = 0; y < h; y++) \
+          { \
+             const pix_type *s = &(src[(h - y - 1)]); \
+             pix_type *d = &(dst[(dst_stride * y)]); \
+             for (x = 0; x < w; x++) \
+               { \
+                  *d++ = *s; \
+                  s += src_stride; \
+               } \
+          } \
+      } \
    } \
    static void \
-   blt_rotated_270_trivial_##suffix(pix_type       *dst, \
+   blt_rotated_270_trivial_##suffix(pix_type * restrict dst, \
                                     int             dst_stride, \
-                                    const pix_type *src, \
+                                    const pix_type * restrict src, \
                                     int             src_stride, \
                                     int             w, \
                                     int             h) \
    { \
       int x, y; \
-      for (y = 0; y < h; y++) \
+      { \
+        for(y = 0; y < h; y++) \
         { \
-           const pix_type *s = src + (src_stride * (w - 1)) + y; \
-           pix_type *d = dst + (dst_stride * y); \
+           const pix_type *s = &(src[(src_stride * (w - 1)) + y]); \
+           pix_type *d = &(dst[(dst_stride * y)]); \
            for (x = 0; x < w; x++) \
-             { \
-                *d++ = *s; \
-                s -= src_stride; \
-             } \
+           { \
+              *d++ = *s; \
+              s -= src_stride; \
+           } \
         } \
+      } \
    } \
    static void \
-   blt_rotated_90_##suffix(pix_type       *dst, \
+   blt_rotated_90_##suffix(pix_type * restrict dst, \
                            int             dst_stride, \
-                           const pix_type *src, \
+                           const pix_type * restrict src, \
                            int             src_stride, \
                            int             w, \
                            int             h) \
@@ -128,7 +332,7 @@ evas_common_convert_rgba_to_32bpp_rgb_8888_rot_180 (DATA32 *src, DATA8 *dst, int
         { \
            blt_rotated_90_trivial_##suffix(dst + x, \
                                            dst_stride, \
-                                           src + (src_stride * x), \
+                                           &(src[(src_stride * x)]), \
                                            src_stride, \
                                            TILE_SIZE, \
                                            h); \
@@ -136,15 +340,15 @@ evas_common_convert_rgba_to_32bpp_rgb_8888_rot_180 (DATA32 *src, DATA8 *dst, int
       if (trailing_pixels) \
         blt_rotated_90_trivial_##suffix(dst + w, \
                                         dst_stride, \
-                                        src + (w * src_stride), \
+                                        &(src[(w * src_stride)]), \
                                         src_stride, \
                                         trailing_pixels, \
                                         h); \
    } \
    static void \
-   blt_rotated_270_##suffix(pix_type       *dst, \
+   blt_rotated_270_##suffix(pix_type * restrict dst, \
                             int             dst_stride, \
-                            const pix_type *src, \
+                            const pix_type * restrict src, \
                             int             src_stride, \
                             int             w, \
                             int             h) \
@@ -159,7 +363,7 @@ evas_common_convert_rgba_to_32bpp_rgb_8888_rot_180 (DATA32 *src, DATA8 *dst, int
              leading_pixels = w; \
            blt_rotated_270_trivial_##suffix(dst, \
                                             dst_stride, \
-                                            src + (src_stride * (w - leading_pixels)), \
+                                            &(src[(src_stride * (w - leading_pixels))]), \
                                             src_stride, \
                                             leading_pixels, \
                                             h); \
@@ -179,7 +383,7 @@ evas_common_convert_rgba_to_32bpp_rgb_8888_rot_180 (DATA32 *src, DATA8 *dst, int
         { \
            blt_rotated_270_trivial_##suffix(dst + x, \
                                             dst_stride, \
-                                            src + (src_stride * (w - x - TILE_SIZE)), \
+                                            &(src[(src_stride * (w - x - TILE_SIZE))]), \
                                             src_stride, \
                                             TILE_SIZE, \
                                             h); \
@@ -193,6 +397,7 @@ evas_common_convert_rgba_to_32bpp_rgb_8888_rot_180 (DATA32 *src, DATA8 *dst, int
                                          h); \
    }
 
+#endif
 FAST_SIMPLE_ROTATE(8888, DATA32)
 #endif
 
index fe90c5b..1d432ae 100644 (file)
@@ -208,7 +208,7 @@ evas_common_cpu_init(void)
 #endif
 }
 
-int
+EAPI int
 evas_common_cpu_has_feature(unsigned int feature)
 {
    return (cpu_feature_mask & feature);
index 28b54cd..e9dac92 100755 (executable)
@@ -143,7 +143,7 @@ evas_common_draw_context_set_color(RGBA_Draw_Context *dc, int r, int g, int b, i
    B_VAL(&(dc->col.col)) = (DATA8)b;
    A_VAL(&(dc->col.col)) = (DATA8)a;
 #ifdef HAVE_PIXMAN
-   if (dc && dc->col.pixman_color_image)
+   if (dc->col.pixman_color_image)
      pixman_image_unref(dc->col.pixman_color_image);
    
    pixman_color_t pixman_color;
@@ -177,47 +177,17 @@ evas_common_draw_context_unset_multiplier(RGBA_Draw_Context *dc)
 EAPI void
 evas_common_draw_context_set_mask(RGBA_Draw_Context *dc, RGBA_Image *mask, int x, int y, int w, int h)
 {
-   dc->mask.mask = mask;
-   dc->mask.x = x;
-   dc->mask.y = y;
-   dc->mask.w = w;
-   dc->mask.h = h;
-
-#ifdef HAVE_PIXMAN
-   if (mask->pixman.im)
-     pixman_image_unref(mask->pixman.im);
-   
-   if (mask->cache_entry.flags.alpha)
-     {
-        mask->pixman.im = pixman_image_create_bits(PIXMAN_a8r8g8b8, w, h, 
-                                                   (uint32_t *)mask->mask.mask,
-                                                   w * 4);
-     }
-   else
-     {
-        mask->pixman.im = pixman_image_create_bits(PIXMAN_x8r8g8b8, w, h, 
-                                                   (uint32_t *)mask->mask.mask,
-                                                   w * 4);
-     }
-#endif
-
+   (void) dc; (void) mask; (void) x; (void) y; (void) w; (void) h;
+   CRIT("This function should not be used.");
+   return;
 }
 
 EAPI void
 evas_common_draw_context_unset_mask(RGBA_Draw_Context *dc)
 {
-   dc->mask.mask = NULL;
-
-#ifdef HAVE_PIXMAN
-   RGBA_Image *mask;
-   mask = (RGBA_Image *)dc->mask.mask;
-
-   if (mask && mask->pixman.im)
-     {
-        pixman_image_unref(mask->pixman.im);
-        mask->pixman.im = NULL;
-     }
-#endif
+   (void) dc;
+   CRIT("This function should not be used.");
+   return;
 }
 
 
index 5c7c1af..ada2a33 100644 (file)
@@ -14,6 +14,10 @@ EAPI int               evas_common_font_ascent_get           (RGBA_Font *fn);
 EAPI int               evas_common_font_descent_get          (RGBA_Font *fn);
 EAPI int               evas_common_font_max_ascent_get       (RGBA_Font *fn);
 EAPI int               evas_common_font_max_descent_get      (RGBA_Font *fn);
+EAPI int               evas_common_font_instance_ascent_get           (RGBA_Font_Int *fi);
+EAPI int               evas_common_font_instance_descent_get          (RGBA_Font_Int *fi);
+EAPI int               evas_common_font_instance_max_ascent_get       (RGBA_Font_Int *fi);
+EAPI int               evas_common_font_instance_max_descent_get      (RGBA_Font_Int *fi);
 EAPI int               evas_common_font_get_line_advance     (RGBA_Font *fn);
 
 /* draw */
@@ -26,7 +30,7 @@ EAPI FT_UInt           evas_common_get_char_index            (RGBA_Font_Int* fi,
 EAPI void              evas_common_font_draw_init            (void);
 EAPI void             evas_common_font_draw_prepare         (Evas_Text_Props *text_props);
 EAPI void              evas_common_font_draw_do(const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Gfx_Func func, RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, const Evas_Text_Props *text_props);
-EAPI Eina_Bool         evas_common_font_draw_prepare_cutout(Cutout_Rects *reuse, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Gfx_Func *func);
+EAPI Eina_Bool         evas_common_font_draw_prepare_cutout(Cutout_Rects **reuse, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Gfx_Func *func);
 
 /* load */
 EAPI void              evas_common_font_dpi_set              (int dpi);
@@ -71,6 +75,11 @@ EAPI int               evas_common_font_query_pen_coords     (RGBA_Font *fn, con
 EAPI int               evas_common_font_query_char_at_coords (RGBA_Font *fn, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch);
 EAPI int               evas_common_font_query_last_up_to_pos (RGBA_Font *fn, const Evas_Text_Props *intl_props, int x, int y);
 EAPI int               evas_common_font_query_run_font_end_get(RGBA_Font *fn, RGBA_Font_Int **script_fi, RGBA_Font_Int **cur_fi, Evas_Script_Type script, const Eina_Unicode *text, int run_len);
+EAPI void              evas_common_font_ascent_descent_get(RGBA_Font *fn, const Evas_Text_Props *text_props, int *ascent, int *descent);
+
+EAPI void             *evas_common_font_glyph_compress(void *data, int num_grays, int pixel_mode, int pitch_data, int w, int h, int *size_ret);
+EAPI void              evas_common_font_glyph_draw(RGBA_Font_Glyph *fg, RGBA_Draw_Context *dc, RGBA_Image *dst_image, int dst_pitch, int x, int y, int cx, int cy, int cw, int ch);
+EAPI DATA8            *evas_common_font_glyph_uncompress(RGBA_Font_Glyph *fg, int *wret, int *hret);
 
 void evas_common_font_load_init(void);
 void evas_common_font_load_shutdown(void);
diff --git a/src/lib/engines/common/evas_font_compress.c b/src/lib/engines/common/evas_font_compress.c
new file mode 100644 (file)
index 0000000..f5a5ca0
--- /dev/null
@@ -0,0 +1,617 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "evas_common.h"
+#include "evas_private.h"
+
+#include "evas_font_private.h"
+#include "evas_blend_private.h"
+
+#ifdef EVAS_CSERVE2
+# include "../cserve2/evas_cs2_private.h"
+#endif
+
+#ifdef BUILD_NEON
+#include <arm_neon.h>
+#endif
+
+#include FT_OUTLINE_H
+#include FT_SYNTHESIS_H
+
+// XXX:
+// XXX: adapt cserve2 to this!
+// XXX:
+
+//--------------------------------------------------------------------------
+//- UTILS ------------------------------------------------------------------
+//--------------------------------------------------------------------------
+static void
+expand_bitmap(DATA8 *src, int pitch, int w, int h, DATA8 *dst)
+{
+   // some glyphs from fonts come in 1bit variety - expand it to 8bit before
+   // compressing as it's easier to deal with a universal format
+   static const DATA8 bitrepl[2] = { 0x00, 0xff };
+   DATA8 *s, *d, bits;
+   int bi, bj, y, end;
+
+   for (y = 0; y < h; y++)
+     {
+        d = dst + (y * w);
+        s = src + (y * pitch);
+        // wall all bytes per row
+        for (bi = 0; bi < w; bi += 8)
+          {
+             bits = *s;
+             if ((w - bi) < 8) end = w - bi;
+             else end = 8;
+             // each byte has 8 bits - expand them out using lookup table above
+             for (bj = 0; bj < end; bj++)
+               {
+                  *d = bitrepl[(bits >> (7 - bj)) & 0x1];
+                  d++;
+               }
+             s++;
+          }
+     }
+}
+
+static inline DATA8
+alpha8to4(int a8)
+{
+   // a4 values are 0x00, 0x11, 0x22, 0x33, ... 0xee, 0xff
+   // increments by 0x11 = 17
+   int a4 = (a8 >> 4) & 0x0f;
+   int v = (a4 << 4) | a4;
+   if ((a8 - v) > 8) a4++;
+   else if ((v - a8) > 8) a4--;
+   return a4; // v = (a4 << 4) | a4;
+}
+
+
+
+//--------------------------------------------------------------------------
+//- RLE 4BIT ---------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+// what is 4bit rle? it's 4 bit per pixel run-length encoding. this means
+// that every row of pixels is compressed int a separate defined list
+// of "runs" where every run is N pixles at value V. RLE works well for
+// things like fonts which have vast regions that are either empty or solid
+// with some transition (anti-alias) pixels in between. it could be that for
+// a black and white alternating pattern it will come out the worst possible
+// case, but this basically "never happens".
+//
+// data is encoded so it's fastr to access and decompress at runtime. we have
+// both a blob of data that is the RLE encoded data for all rows which consist
+// of 1 byte per run, and also a jump table - per row telling us the byte
+// offset inside the RLE data blob where the row data begins. since we know
+// the offset of the next run, we know how many bytes each row is based on
+// this.
+//
+// since rle data may be small (less than 256 bytes) and in almost all cases
+// less than 64k, a jump table of 8 bite per entry is good for many uses, and
+// otherwise 16bits is used. it also supports 32bit jumptables but these are
+// there just in case the data goes beyond 64k - but is unlikely to ever
+// happen in real life. this means jumptables come in 3 formats thus have to
+// have 3 different handling paths. RLE data is the same so it's common code.
+//
+// each byte in the RLE section encodes a run of between 1 and 16 pixels in
+// length. there is no such thing as a run of 0 pixels. the upper 4 bits of
+// the byte encode the length, with 0 being 1 pixel, 1 being 2 pixels,
+// 2 being 3 pixels and so on up top 16 pixels (thus run length is actually
+// (byte >> 4) + 1). the lower 4 bits encode the 4 bit pixel value of the
+// whole run, from 0 to 15. it is accessed via masking (byte & 0xf). thus
+// every run in RLE consumes exactly 1 byte of memory nice and neatly.
+//
+// at the start before the jumptable is a 32bit (int) header. it just has a
+// value at the moment that indicates 0 for it not being RLE data (used by
+// the 4bit packed bitmap), 1 for 8bit jumptable RLE, 2 for 16bit jumptable
+// and 3 for 32bit jumptable. all other values are reserved
+//
+// so data looks like this when packed into a single blob in memory (where
+// xx is the data size of the jump table - 8, 16 or 32bit). there are n
+// lines of data in the jumptable matching to the height of the glyph where
+// n is the height in rows
+//
+// each jumptable row ACTUALLY indicates the byte offset of the NEXT line.
+// the FIRST row of RLE data is assumed to be at offset 0 in the RLE data
+// section, so a special case is used for this. note that jumptable values
+// are OFFSETS starting at 0 which is the first byte in the RLE data section
+//
+// [int] header (0, 1, 2 or  3)
+// [xx] jump table for line 0
+// [xx] jump table for line 1
+// [xx] jump table for line 2
+// ...
+// [xx] jump table for line n - 1
+// [char] first byte of RLE data (beginning of rle data)
+// [char] second byte of RLE data
+// ...
+// [char] last byte of RLE data
+// 
+static DATA8 *
+compress_rle4(DATA8 *src, int pitch, int w, int h, int *size_ret)
+{
+   unsigned char *scratch, *p, *pix, spanval;
+   int *jumptab, x, y, spanlen, spannum, total, size, *iptr, *pos;
+   unsigned short *sptr;
+   DATA8 *dst, *buf, *dptr;
+
+   // these macros make the code more readable and easier to follow, and
+   // avoid replication of dumb blobs of logic
+#define SPAN_ADD(_len, _val) do { (*pos) += 1; *p = ((_len) << 4) | (_val); p++; } while (0)
+#define LAST_SPAN_VAL() (p[-1] & 0x0f)
+#define LAST_SPAN_LEN() (p[-1] >> 4)
+#define LAST_SPAN_DEL() do { (*pos) -= 1; p -= 1; } while (0)
+
+   // create out scratch buffer for compression on the stack - maximum size
+   scratch = p = alloca(pitch * h * 2);
+   // also place our jumptable on the stack too - all ints here - become
+   // smaller char/shorts after jumptable is generated and size known
+   jumptab = alloca(h * sizeof(int));
+   for (y = 0; y < h; y++)
+     {
+        pix = src + (y * pitch);
+        // pos is the position offset from RLE data start that we have to
+        // track to find out where this rows RLE run *ENDS* so keep a
+        // pointer to it and we will keep ++ing it with each REL entry we add
+        pos = &(jumptab[y]);
+        *pos = (int)(p - scratch);
+        // no spans now so init all span things to 0
+        spanval = spanlen = spannum = 0;
+        for (x = 0; x < w; x++)
+          {
+             // round value from a8 to a44
+             DATA8 v = alpha8to4(pix[x]);
+             // if the current pixel value (in 4bit) is not the same as the
+             // span value (n 4 bit) OR... if the span now exceeds 16 pixels
+             // then add/write out the span to our RLE span blob
+             if ((v != spanval) || (spanlen >= 16))
+               {
+                  if (spanlen > 0)
+                    {
+                       SPAN_ADD(spanlen - 1, spanval);
+                       spannum++;
+                    }
+                  spanval = v;
+                  spanlen = 1;
+               }
+             // otherwise make span longer if values are the same
+             else spanlen++;
+          }
+        // do we have a span still being built that we haven't added and that
+        // is NOT transparent (0 value -  there is no point storing spans
+        // at the end of a row that have 0 value
+        if ((spanlen > 0) && (spanval > 0))
+          {
+             SPAN_ADD(spanlen - 1, spanval);
+             spannum++;
+          }
+        // clean up any dangling 0 value at the end of a row as they just
+        // waste space and processing time
+        while ((spannum > 0) && (LAST_SPAN_VAL() == 0))
+          {
+             LAST_SPAN_DEL();
+             spannum--;
+          }
+     }
+   // get the size of RLE data we have plus int header
+   total = (int)(p - scratch);
+   size = sizeof(int) + total;
+   // based on total number of bytes in RLE, use 32, 16 or 8 bit jumptable
+   // and add that to our size
+   if (total > 65535) size += h * 4; // 32bit
+   else if (total > 255) size += h * 2; // 16bit
+   else size += h; // 8bit
+
+   *size_ret = size;
+   // allocate a fresh buffer where we will merge header, jumptable and RLE
+   // spans inot a single block
+   buf = dst = malloc(size);
+   if (!buf) return NULL;
+   // 32bit int header to indicate encoding type (3, 2 or 1)
+   iptr = (int *)dst;
+   if (total > 65535) *iptr = 3; // 32bit jump table
+   else if (total > 255) *iptr = 2; // 16 bit jump table
+   else *iptr = 1; // 8 bit jump table
+   // skip header and write jump table
+   dst += sizeof(int);
+   if (total > 65535) // 32bit jump table
+     {
+        iptr = (int *)dst;
+        for (y = 0; y < h; y++) iptr[y] = jumptab[y];
+        dst += (h * sizeof(int));
+     }
+   else if (total > 255) // 16bit jump table
+     {
+        sptr = (unsigned short *)dst;
+        for (y = 0; y < h; y++) sptr[y] = jumptab[y];
+        dst += (h * sizeof(unsigned short));
+     }
+   else // 8bit jump table
+     {
+        dptr = dst;
+        for (y = 0; y < h; y++) dptr[y] = jumptab[y];
+        dst += (h * sizeof(DATA8));
+     }
+   // copy rest of RLE data at the end of the jumptable and return it
+   memcpy(dst, scratch, total);
+   return buf;
+}
+
+// this decompresses a specific run of RLE data to the destination pointer
+// and finishes reading RLE data before the "end" byte and starts AT the
+// "start" byte within the array pointed to by src. this ASSUMES the dest
+// buffer has already been zeroed out so we can skip runs that are "0"
+static void
+decompress_full_row(DATA8 *src, int start, int end, DATA8 *dst)
+{
+   DATA8 *p = src + start, *e = src + end, *d = dst, len, val;
+
+   while (p < e)
+     {
+        // length is upper 4 bits + 1
+        len = (*p >> 4) + 1;
+        // value when EXPANDED to 8bit is the lower 4 bits REPEATEd in all
+        // 8 bites to ensure it rounds properly.
+        // i.e. lower 4 bits B4B3B2B1 -> B4B3B2B1B4B3B2B1
+        val = *p & 0xf;
+        val |= val << 4;
+        // if it's 0 just skip ahead (assume dst buffer is 0'd out)
+        if (val == 0) d += len;
+        else
+          {
+             // write out "len" pixels of tghe given value
+             while (len > 0)
+               {
+                  *d = val;
+                  d++;
+                  len--;
+               }
+          }
+        // next RLE byte
+        p++;
+     }
+}
+
+// to save copy & paste repeating code, this macro acts as a code generator
+// to create a specific decompress function per jumptable size (8, 16 or 32bit)
+#define DECOMPRESS_ROW_FUNC(_name, _type) \
+static void \
+_name(_type *jumptab, DATA8 *src, DATA8 *dst, int pitch, int h) \
+{ \
+   int y, start, end; \
+   for (y = 0; y < h; y++) \
+     { \
+        if (y > 0) start = jumptab[y - 1]; \
+        else start = 0; \
+        end = jumptab[y]; \
+        decompress_full_row(src, start, end, dst + (y * pitch)); \
+     } \
+}
+// 3 versions of the decompress given 3 jumptable types/sizes
+DECOMPRESS_ROW_FUNC(decompress_jumptab8_rle4, DATA8)
+DECOMPRESS_ROW_FUNC(decompress_jumptab16_rle4, unsigned short)
+DECOMPRESS_ROW_FUNC(decompress_jumptab32_rle4, int)
+
+// decompress a full RLE blob with header into the dst pointer. pitch is
+// the number of bytes between each destination row
+static void
+decompress_rle4(DATA8 *src, DATA8 *dst, int pitch, int w EINA_UNUSED, int h)
+{
+   int header;
+   DATA8 *jumptab;
+
+   // get header value and then skip past to jump table
+   header = *((int *)src);
+   jumptab = src + sizeof(int);
+#define DECOMPRESS_FUNC(_name, _type) _name((_type *)jumptab,  jumptab + (h * sizeof(_type)), dst, pitch, h)
+   if (header == 1)
+     DECOMPRESS_FUNC(decompress_jumptab8_rle4, DATA8);
+   else if (header == 2)
+     DECOMPRESS_FUNC(decompress_jumptab16_rle4, unsigned short);
+   else if (header == 3)
+     DECOMPRESS_FUNC(decompress_jumptab32_rle4, int);
+}
+
+
+
+
+//--------------------------------------------------------------------------
+//- RAW 4BIT ---------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+// this compresses 8bit per pixel font data to 4bit per pixel (with 4 bit MSB
+// per byte holding the left most pixel and 4 bit LSB holding the right pixel
+// data). each row is rounded up to a whole number of bytes so the last
+// pixel may only contain 1, not 2 4bit values and thus we throw away the LSB
+// 4 bits on odd-length rows in the last pixel. at the top of the 4bit packed
+// pixel data is an integer that stores the data type - value of 0 means
+// 4bit packed data. this is so we can share the same generic "rle" pointer
+// between 4bit rle and 4bit packed and easily switch between these 2 encodings
+// based on which one is likely more compact and/or faster at runtime.
+static DATA8 *
+compress_bpp4(DATA8 *src, int pitch, int w, int h, int *size_ret)
+{
+   int pitch2, x, y, *iptr;
+   DATA8 *buf, *p, *d, *s;
+
+   // our horizontal pitch in bytes ... rounding up to account for odd lengths
+   pitch2 = (w + 1) / 2;
+   // allocate the buffer size for header plus data
+   buf = malloc(sizeof(int) + (pitch2 * h));
+   if (!buf) return NULL;
+   // write the header value of 0
+   iptr = (int *)buf;
+   *iptr = 0;
+   // start with the 4 bit packed data body
+   p = buf + sizeof(int);
+   // return size
+   *size_ret = (pitch2 * h) + sizeof(int);
+   for (y = 0; y < h; y++)
+     {
+        s = src + (y * pitch);
+        d = p + (y * pitch2);
+        // walk source row 2 pixels at a time and reduce to 4 bit (upper
+        // 4 bits only needed) and pack
+        for (x = 0; x < (w - 1); x += 2)
+          {
+             DATA8 v1 = alpha8to4(s[0]);
+             DATA8 v2 = alpha8to4(s[1]);
+             *d = (v1 << 4) | v2;
+             s += 2;
+             d++;
+          }
+        /// handle dangling "last" pixel if odd row length
+        if (x < w) *d = (s[0] & 0xf0);
+     }
+   return buf;
+}
+
+// this decompresses packed 4bit data from the encoded data blob into a
+// destination 8bit buffer assumed to be allocated and the right size with
+// the given destination pitch in bytes per line and a row length of w
+// pixels and height of h rows
+static void
+decompress_bpp4(DATA8 *src, DATA8 *dst, int pitch, int w, int h)
+{
+   int pitch2, x, y;
+   DATA8 *d, *s, val;
+   
+   // deal with source pixel to round up for odd length rows
+   pitch2 = (w + 1) / 2;
+   // skip header int
+   src += sizeof(int);
+   for (y = 0; y < h; y++)
+     {
+        s = src + (y * pitch2);
+        d = dst + (y * pitch);
+        // walk 2 pixels at a time (1 source byte) and unpack
+        for (x = 0; x < (w - 1); x += 2)
+          {
+             // take MSB 4 bits (pixel 1)
+             val = (*s) >> 4;
+             // replicate those 4 bits in MSB of dest so it rounds correctly
+             val |= val << 4;
+             // store in dest
+             *d = val;
+             d++;
+             // take LSB 4 bits (pixel 2)
+             val = (*s) & 0xf;
+             // replicate those 4 bits in MSB of dest so it rounds correctly
+             val |= val << 4;
+             // store in dest
+             *d = val;
+             s++;
+             d++;
+          }
+        // deal with odd length rows and take MSB 4 bits and store to dest
+        if (x < w)
+          {
+             val = (*s) >> 4;
+             val |= val << 4;
+             *d = val;
+          }
+     }
+}
+
+
+
+//--------------------------------------------------------------------------
+//- GENERAL ----------------------------------------------------------------
+//--------------------------------------------------------------------------
+EAPI void *
+evas_common_font_glyph_compress(void *data, int num_grays, int pixel_mode,
+                                int pitch_data, int w, int h, int *size_ret)
+{
+   DATA8 *inbuf, *buf;
+   int size = 0, pitch = 0;
+
+   // avoid compressing 0 sized glyph
+   if ((h < 1) || (pitch_data < 1)) return NULL;
+   inbuf = alloca(w * h);
+   // if glyph buffer is 8bit grey - then compress straght
+   if (((num_grays == 256) && (pixel_mode == FT_PIXEL_MODE_GRAY)))
+     {
+        inbuf = data;
+        pitch = pitch_data;
+     }
+   // if glyph is 1bit bitmap - expand it to 8bit grey first
+   else
+     {
+        pitch = w;
+        expand_bitmap(data, pitch_data, w, h, inbuf);
+     }
+   // in testing for small glyphs - eg 16x16 or smaller it seems raw 4bit
+   // encoding is faster (and smaller) than 4bit RLE.
+   if ((w * h) < (16 * 16))
+     // compress to 4bit per pixel, raw
+     buf = compress_bpp4(inbuf, pitch, w, h, &size);
+   else
+     // compress to 4bit per pixel, run length encoded per row
+     buf = compress_rle4(inbuf, pitch, w, h, &size);
+   *size_ret = size;
+   return buf;
+}
+
+// this decompresses a whole block of compressed font data back to 8bit
+// per pixels and deals with both 4bit RLE and 4bit packed encoding modes
+EAPI DATA8 *
+evas_common_font_glyph_uncompress(RGBA_Font_Glyph *fg, int *wret, int *hret)
+{
+   RGBA_Font_Glyph_Out *fgo = fg->glyph_out;
+   DATA8 *buf = calloc(1, fgo->bitmap.width * fgo->bitmap.rows);
+   int *iptr;
+   
+   if (!buf) return NULL;
+   if (wret) *wret = fgo->bitmap.width;
+   if (hret) *hret = fgo->bitmap.rows;
+   iptr = (int *)fgo->rle;
+   if (*iptr > 0) // rle4
+     decompress_rle4(fgo->rle, buf, fgo->bitmap.width,
+                     fgo->bitmap.width, fgo->bitmap.rows);
+   else // bpp4
+     decompress_bpp4(fgo->rle, buf, fgo->bitmap.width,
+                     fgo->bitmap.width, fgo->bitmap.rows);
+   return buf;
+}
+
+// this draws a compressed font glyph and decompresses on the fly as it
+// draws, saving memory bandwidth and providing speedups
+EAPI void
+evas_common_font_glyph_draw(RGBA_Font_Glyph *fg, 
+                            RGBA_Draw_Context *dc,
+                            RGBA_Image *dst_image, int dst_pitch,
+                            int x, int y, int cx, int cy, int cw, int ch)
+{
+   RGBA_Font_Glyph_Out *fgo = fg->glyph_out;
+   int w, h, x1, x2, y1, y2, i, *iptr;
+   DATA32 *dst = dst_image->image.data;
+   DATA32 coltab[16], col;
+   DATA16 mtab[16], v;
+   DATA8 tmp;
+
+   if (!dst) return;
+
+   w = fgo->bitmap.width; h = fgo->bitmap.rows;
+   // skip if totally clipped out
+   if ((y >= (cy + ch)) || ((y + h) <= cy) ||
+       (x >= (cx + cw)) || ((x + w) <= cx)) return;
+   // figure y1/y2 limit range
+   y1 = 0; y2 = h;
+   if ((y + y1) < cy) y1 = cy - y;
+   if ((y + y2) > (cy + ch)) y2 = cy + ch - y;
+   // figure x1/x2 limit range
+   x1 = 0; x2 = w;
+   if ((x + x1) < cx) x1 = cx - x;
+   if ((x + x2) > (cx + cw)) x2 = cx + cw - x;
+   col = dc->col.col;
+   if (dst_image->cache_entry.space == EVAS_COLORSPACE_GRY8)
+     {
+        // FIXME: Font draw not optimized for Alpha targets! SLOW!
+        // This is not pretty :)
+
+        DATA8 *dst8 = dst_image->image.data8 + x + (y * dst_pitch);
+        Alpha_Gfx_Func func;
+        DATA8 *src8;
+        int row;
+
+        func = evas_common_alpha_func_get(dc->render_op);
+        src8 = evas_common_font_glyph_uncompress(fg, NULL, NULL);
+        if (!src8) return;
+
+        for (row = y1; row < y2; row++)
+          {
+             DATA8 *d = dst8 + ((row - y1) * dst_pitch);
+             DATA8 *s = src8 + (row * w) + x1;
+             func(s, d, x2 - x1);
+          }
+        free(src8);
+     }
+   else if (dc->clip.mask)
+     {
+        RGBA_Gfx_Func func;
+        DATA8 *src8, *mask;
+        DATA32 *buf, *ptr, *buf_ptr;
+        RGBA_Image *im = dc->clip.mask;
+        DATA8 *mbegin = im->image.data8;
+        DATA8 *mend = mbegin + (im->cache_entry.w * im->cache_entry.h);
+        int row;
+
+        buf = alloca(sizeof(DATA32) * w * h);
+        buf_ptr = buf;
+        for (i = 0; i < w*h; i++)
+          {
+             *buf_ptr = 0;
+             buf_ptr++;
+          }
+        // Step 1: alpha glyph drawing
+        src8 = evas_common_font_glyph_uncompress(fg, NULL, NULL);
+        if (!src8) return;
+
+        // Step 2: color blending to buffer
+        func = evas_common_gfx_func_composite_mask_color_span_get(col, dst_image, dst_pitch, dc->render_op);
+        for (row = y1; row < y2; row++)
+          {
+             buf_ptr = buf + (row * w) + x1;
+             DATA8 *s = src8 + (row * w) + x1;
+             func(NULL, s, col, buf_ptr, x2 - x1);
+          }
+        free(src8);
+
+        // Step 3: masking to destination
+        func = evas_common_gfx_func_composite_pixel_mask_span_get(im, dst_image, dst_pitch, dc->render_op);
+        for (row = y1; row < y2; row++)
+          {
+             mask = im->image.data8
+                + (y + row - dc->clip.mask_y) * im->cache_entry.w
+                + (x + x1 - dc->clip.mask_x);
+
+             /* FIXME!!! Quick workaround crashes */
+             if ((mask < mbegin) || ((mask + x2 - x1) > mend))
+               continue;
+
+             ptr = dst + (x + x1) + ((y + row) * dst_pitch);
+             buf_ptr = buf + (row * w) + x1;
+             func(buf_ptr, mask, 0, ptr, x2 - x1);
+          }
+     }
+   else
+     {
+        // build fast multiply + mask color tables to avoid compute. this works
+        // because of our very limited 4bit range of alpha values
+        for (i = 0; i <= 0xf; i++)
+          {
+             v = (i << 4) | i;
+             coltab[i] = MUL_SYM(v, col);
+             tmp = (coltab[i] >> 24);
+             mtab[i] = 256 - (tmp + (tmp >> 7));
+          }
+#ifdef BUILD_MMX
+        if (evas_common_cpu_has_feature(CPU_FEATURE_MMX))
+          {
+#define MMX 1
+#include "evas_font_compress_draw.c"
+#undef MMX
+          }
+        else
+#endif
+
+#ifdef BUILD_NEON
+           if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+             {
+#define NEON 1
+#include "evas_font_compress_draw.c"
+#undef NEON
+             }
+           else
+#endif
+
+             {
+#include "evas_font_compress_draw.c"
+             }
+     }
+}
diff --git a/src/lib/engines/common/evas_font_compress_draw.c b/src/lib/engines/common/evas_font_compress_draw.c
new file mode 100644 (file)
index 0000000..0102e01
--- /dev/null
@@ -0,0 +1,435 @@
+// inherited from parent func
+//   RGBA_Font_Glyph_Out *fgo;
+//   int w, h, x1, x2, y1, y2, i, *iptr;
+//   DATA32 coltab[16], col;
+//   DATA16 mtab[16], v;
+//   DATA8 tmp;
+
+// blend a pixel using pre-computed multiplied col and inverse mul value
+#define MMX_BLEND(_dst, _col, _mul) \
+   MOV_P2R(_dst, mm1, mm0) \
+   MOV_A2R(_mul, mm3) \
+   MOV_P2R(_col, mm2, mm0) \
+   MUL4_256_R2R(mm3, mm1) \
+   paddw_r2r(mm2, mm1); \
+   MOV_R2P(mm1, _dst, mm0)
+
+#define C_BLEND(_dst, _col, _mul) \
+   _dst = _col + MUL_256(_mul, _dst)
+
+#ifdef BUILD_NEON
+#define NEON_BLEND(_dst, _col, _mul) \
+   __asm__ __volatile__( \
+       ".fpu neon \n\t" \
+       "vmov.i32 d0[0], %[dst_in] \n\t" \
+       "veor d3, d3, d3 \n\t" \
+       "vzip.8  d0, d3 \n\t" \
+       "vdup.16 d1, %[mul] \n\t" \
+       "vmul.i16 d0, d0, d1 \n\t" \
+       "veor d2, d2, d2 \n\t" \
+       "vuzp.8 d0, d2 \n\t" \
+       "vmov.i32 d3[0], %[col] \n\t" \
+       "vadd.i32 d2, d2, d3 \n\t" \
+       "vmov.i32 %[dst_out], d2[0] \n\t" \
+       : [dst_out] "=r" (_dst) \
+       : [dst_in] "r" (_dst), [mul] "r" (_mul), [col] "r" (_col) \
+       : "d0", "d1", "d2", "d3" \
+   );
+#endif
+
+#define MMX_BLEND4(_dst, _col, _mul) \
+   MMX_BLEND(_dst[0], _col, _mul); \
+   MMX_BLEND(_dst[1], _col, _mul); \
+   MMX_BLEND(_dst[2], _col, _mul); \
+   MMX_BLEND(_dst[3], _col, _mul);
+
+#define C_BLEND4(_dst, _col, _mul) \
+   C_BLEND(_dst[0], _col, _mul); \
+   C_BLEND(_dst[1], _col, _mul); \
+   C_BLEND(_dst[2], _col, _mul); \
+   C_BLEND(_dst[3], _col, _mul);
+
+#ifdef BUILD_NEON
+#define NEON_BLEND4(_dst, _col, _mul) \
+   { \
+      uint32x2x2_t _vdst = vld2_u32(_dst); \
+      uint16x8x2_t _vdst_res; \
+      uint8x8_t _vmul = vdup_n_u8(_mul); \
+      _vdst_res.val[0] = vmull_u8(vreinterpret_u8_u32(_vdst.val[0]), _vmul); \
+      _vdst_res.val[1] = vmull_u8(vreinterpret_u8_u32(_vdst.val[1]), _vmul); \
+      _vdst.val[0] = vreinterpret_u32_u8(vshrn_n_u16(_vdst_res.val[0], 8)); \
+      _vdst.val[1] = vreinterpret_u32_u8(vshrn_n_u16(_vdst_res.val[1], 8)); \
+      uint32x2_t _vcol = vdup_n_u32(_col); \
+      _vdst.val[0] = vadd_u32(_vcol, _vdst.val[0]); \
+      _vdst.val[1] = vadd_u32(_vcol, _vdst.val[1]); \
+      vst2_u32(_dst, _vdst); \
+   }
+#endif
+
+// copy 64bits in 1 go (special mmx - no such thing in C here)
+#define MMX_COPY64(_dst, _src) \
+   movq_r2m(_src, _dst)
+
+// a loop of 64bit copies
+#define MMX_COPY64LOOP(_dst, _len) \
+   if (_len >= 2) \
+   { \
+      while (_len > 1) \
+        { \
+           MMX_COPY64(_dst[0], mm7); \
+           _dst += 2; _len -= 2; \
+        } \
+   }
+
+#ifdef BUILD_NEON
+#define NEON_COPY128(_dst, _src) \
+   vst1q_u32(_dst, vdupq_n_u32(_src))
+
+#define NEON_COPY128LOOP(_dst, _len) \
+    while (_len >= 4) \
+    { \
+       NEON_COPY128(_dst, t); \
+       _dst += 4; _len -= 4; \
+    }
+#endif
+
+#ifdef MMX
+#define blend_func MMX_BLEND
+#define blend4_func MMX_BLEND4
+#elif defined NEON
+#define blend_func NEON_BLEND
+#define blend4_func NEON_BLEND4
+#else
+#define blend_func C_BLEND
+#define blend4_func C_BLEND4
+#endif
+
+// if we build for mmx optimizations, we need to set up a few things in advance
+// like the mm0 register is always all 0'd to fill in 0 padding when
+// unpacking values to registers. also mm7 is reserved to hold an unpacked
+// and dumpliacted coltab entry for the final entry (max color). so it's
+// [col][col] in the 63bit register with both 32bit colors doublicated
+#ifdef MMX
+pxor_r2r(mm0, mm0);
+movd_m2r(coltab[0xf], mm7);
+punpckldq_r2r(mm7, mm7);
+#endif
+
+// check header for typ (rle4 or bpp4)
+iptr = (int *)fgo->rle;
+if (*iptr > 0) // rle4
+{
+   DATA8 *p = fgo->rle, *e, *s;
+   DATA32 *d0, *d, t;
+   DATA16 len;
+   int xx, yy, dif;
+
+   iptr = (int *)p;
+   p += sizeof(int);
+   d0 = dst + x + (y * dst_pitch);
+// this may seem horrible to put a massive blob of logic into a macro like
+// this, but this is for speed reasons, so we can generate slightly different
+// versions of the same blob of code logic that hold different optimizations
+// inside (eg mmx/sse/neon asm etc.)
+#define EXPAND_RLE(_donelabel, _extn, _2copy, _4copy, _blend, _blend4) \
+   if ((x1 == 0) && (x2 == w)) /* unclipped  horizontally */ \
+   { \
+      d0 += x1; \
+      for (yy = y1; yy < y2; yy++) \
+        { \
+           /* figure out source ptr and end ptr based on jumptable */ \
+           if (yy > 0) s = p + jumptab[yy - 1]; \
+           else s = p; \
+           e = p + jumptab[yy]; \
+           d = d0 + (yy * dst_pitch); \
+           /* walk until we hit the end of the src data */ \
+           while (s < e) \
+             { \
+                /* read the run length from RLE data and value */ \
+                len = (*s >> 4) + 1; \
+                v = *s & 0xf; \
+                /* if value is 0 we can just skip ahead entire run and do */ \
+                /* nothng as empty space doesn't need any work */ \
+                if (v == 0) d += len; \
+                /* if the value ends up being solid (inverse alpha is 0) */ \
+                else if (mtab[v] == 0) \
+                  { \
+                     /* just COPY the color data direct to destination */ \
+                     t = coltab[0xf]; \
+                     /* this is a special 2 pixel (64bit dest) copy for */ \
+                     /* speed - eg mmx etc. */ \
+                     _2copy; \
+                     _4copy; \
+                     /* do cleanup of left-over pixels after the 2 pixel */ \
+                     /* copy above (if there is any such code) */ \
+                     while (len > 0) \
+                       { \
+                          /* just a plain copy of looked up value */ \
+                          *d = t; \
+                          d++; len--; \
+                       } \
+                  } \
+                else if (mtab[v] == 256) \
+                  { \
+                     t = coltab[v]; \
+                     while (len > 0) \
+                       { \
+                          *d += t; \
+                          d++; len--; \
+                       } \
+                  } \
+                /* our font mask value is between 0 and 15 (0xf) so we */ \
+                /* have to actually blend it to each dest pixel */ \
+                else \
+                  { \
+                      while (len >= 4) \
+                      { \
+                          _blend4; \
+                          d += 4;len -= 4; \
+                      } \
+                      while (len > 0) \
+                       { \
+                          /* do blend using op provided by params */ \
+                          _blend; \
+                          d++; len--; \
+                       } \
+                  } \
+                s++; \
+             } \
+        } \
+   } \
+   else /* clipped horizontally (needs extra skip/cut logic) */ \
+   { \
+      /* init out pos to 0 here (we reset AFTER each horiz loop later */ \
+      xx = 0; \
+      for (yy = y1; yy < y2; yy++) \
+        { \
+           /* figure out source ptr and end ptr based on jumptable */ \
+           if (yy > 0) s = p + jumptab[yy - 1]; \
+           else s = p; \
+           e = p + jumptab[yy]; \
+           d = d0 + (yy * dst_pitch); \
+           /* walk until we hit the end of the src data and SKIP runs */ \
+           /* that are entirely before the start (x1) point and any */ \
+           /* run that spans over the start point is truncated at the */ \
+           /* start of the run */ \
+           while (s < e) \
+             { \
+                len = (*s >> 4) + 1; \
+                /* if current pos pluse run length go over the start (x1) */ \
+                /* point of our clip area, then adjust run length and dest */ \
+                /* pointer and position and break out of our RLE skip loop */ \
+                if ((xx + (int)len) > x1) \
+                  { \
+                     dif = x1 - xx; \
+                     len -= dif; d += dif; xx += dif; \
+                     break; \
+                  } \
+                d += len; xx += len; s++; \
+             } \
+           /* walk until we hit the end of the REL run.. OR the end of */ \
+           /* our clip region - the x2 checks are done inside */ \
+           while (s < e) \
+             { \
+                v = *s & 0xf; \
+                /* if value is 0 we can just skip ahead entire run and do */ \
+                /* nothng as empty space doesn't need any work */ \
+                if (v == 0) \
+                  { \
+                     d += len; xx += len; \
+                     /* clip check to stop run */ \
+                     if (xx >= x2) goto _donelabel##_extn; \
+                  } \
+                /* if the value ends up being solid (inverse alpha is 0) */ \
+                else if (mtab[v] == 0) \
+                  { \
+                     /* just COPY the color data direct to destination */ \
+                     t = coltab[0xf]; \
+                     while (len > 0) \
+                       { \
+                          /* clip check to stop run */ \
+                          if (xx >= x2) goto _donelabel##_extn; \
+                          /* just a plain copy of looked up value */ \
+                          *d = t; \
+                          d++; xx++; len--; \
+                       } \
+                  } \
+                else if (mtab[v] == 256) \
+                  { \
+                     /* just COPY the color data direct to destination */ \
+                     t = coltab[v]; \
+                     while (len > 0) \
+                       { \
+                          /* clip check to stop run */ \
+                          if (xx >= x2) goto _donelabel##_extn; \
+                          /* just a plain copy of looked up value */ \
+                          *d += t; \
+                          d++; xx++; len--; \
+                       } \
+                  } \
+                 /* our font mask value is between 0 and 15 (0xf) so we */ \
+                /* have to actually blend it to each dest pixel */ \
+                else \
+                  { \
+                      while (len >= 4) \
+                      { \
+                          /* clip check to stop run */ \
+                          if (xx >= x2 - 3) break; \
+                           _blend4; \
+                          d += 4; xx += 4, len -= 4; \
+                      } \
+                      while (len > 0) \
+                       { \
+                          /* clip check to stop run */ \
+                          if (xx >= x2) goto _donelabel##_extn; \
+                          /* do blend using op provided by params */ \
+                          _blend; \
+                          d++; xx++; len--; \
+                       } \
+                  } \
+                s++; \
+                /* extra check here so length fetch after doesn't break */ \
+                if (s >= e) break; \
+                /* get length of NEXT RLE run at the end here */ \
+                len = (*s >> 4) + 1; \
+             } \
+_donelabel##_extn: \
+           /* reset horiz pos to 0 ready for next line */ \
+           xx = 0; \
+        } \
+   }
+
+   // and here actually run the appropriate code in the macro/func defined
+   // above, based on the jumptable type (saves passing params on the stack
+   // to a sub function and we'd have to generate the subfunction by macros
+   // anyway, so just cust down code to assume context vars as opposed to
+   // passing them)
+   if (*iptr == 1) // 8 bit jump table
+     {
+        DATA8 *jumptab = p;
+        p += (h * sizeof(DATA8));
+#ifdef MMX
+        EXPAND_RLE(done_8_clipped, _mmx, MMX_COPY64LOOP(d, len), ,
+                   MMX_BLEND(d[0], coltab[v], mtab[v]), MMX_BLEND4(d, coltab[v], mtab[v]))
+#elif defined(NEON)
+        EXPAND_RLE(done_8_clipped, _neon, , NEON_COPY128LOOP(d, len),
+                   NEON_BLEND(d[0], coltab[v], mtab[v]), NEON_BLEND4(d, coltab[v], mtab[v]))
+#else
+        EXPAND_RLE(done_8_clipped, _c, , ,
+                   C_BLEND(d[0], coltab[v], mtab[v]), C_BLEND4(d, coltab[v], mtab[v]))
+#endif
+     }
+   else if (*iptr == 2) // 16 bit jump table
+     {
+        unsigned short *jumptab = (unsigned short *)p;
+        p += (h * sizeof(unsigned short));
+#ifdef MMX
+        EXPAND_RLE(done_16_clipped, _mmx, MMX_COPY64LOOP(d, len), ,
+                   MMX_BLEND(d[0], coltab[v], mtab[v]), MMX_BLEND4(d, coltab[v], mtab[v]))
+#elif defined(NEON)
+        EXPAND_RLE(done_16_clipped, _neon, , NEON_COPY128LOOP(d, len),
+                   NEON_BLEND(d[0], coltab[v], mtab[v]), NEON_BLEND4(d, coltab[v], mtab[v]))
+#else
+        EXPAND_RLE(done_16_clipped, _c, , ,
+                   C_BLEND(d[0], coltab[v], mtab[v]), C_BLEND4(d, coltab[v], mtab[v]))
+#endif
+     }
+   else if (*iptr == 3) // 32 bit jump table
+     {
+        int *jumptab = (int *)p;
+        p += (h * sizeof(int));
+#ifdef MMX
+        EXPAND_RLE(done_32_clipped, _mmx, MMX_COPY64LOOP(d, len), ,
+                   MMX_BLEND(d[0], coltab[v], mtab[v]), MMX_BLEND4(d, coltab[v], mtab[v]))
+#elif defined(NEON)
+        EXPAND_RLE(done_32_clipped, _neon, , NEON_COPY128LOOP(d, len),
+                   NEON_BLEND(d[0], coltab[v], mtab[v]), NEON_BLEND4(d, coltab[v], mtab[v]))
+#else
+        EXPAND_RLE(done_32_clipped, _c, , ,
+                   C_BLEND(d[0], coltab[v], mtab[v]), C_BLEND4(d, coltab[v], mtab[v]))
+#endif
+     }
+#undef EXPAND_RLE
+}
+else // bpp4
+{
+   int xx, yy, djump;
+   int pitch2;
+   DATA8 *s, *s0, v0;
+   DATA32 *d;
+
+   d = dst + x + x1 + ((y + y1) * dst_pitch);
+   djump = dst_pitch - (x2 - x1);
+   pitch2 = (w + 1) / 2;
+   s0 = fgo->rle + sizeof(int) + (y1 * pitch2);
+   for (yy = y1; yy < y2; yy++)
+     {
+        s = s0 + (x1 / 2);
+        xx = x1;
+        // do odd pixel at start if there is any
+        if (xx & 0x1)
+          {
+             v = (*s) & 0xf;
+             // fast path - totally solid color can just be written
+             // with no blending done
+             if (mtab[v] == 0) d[0] = coltab[0xf];
+             // blend our color from lookup table
+             else if (v)
+               {
+                  // blend it
+                  blend_func(d[0], coltab[v], mtab[v]);
+               }
+             s++; d++; xx++;
+          }
+        // walk along 2 pixels at a time (1 src pixel is 4 bits packed)
+        for (; xx < (x2 - 1); xx += 2)
+          {
+             v0 = *s;
+             // fast path - totally solid color can just be written
+             // with no blending done - write 2 at once
+             if ((v0 == 0xff) && (mtab[v0 & 0xf] == 0))
+               {
+                  // blend it
+#ifdef MMX
+                  MMX_COPY64(d[0], mm7);
+#else
+                  d[0] = d[1] = coltab[0xf];
+#endif
+               }
+             // if our 2 values are not 0 (as 0's we can skip entirely)
+             else if (v0)
+               {
+                  // get first pixel in MSB and blend it
+                  v = (v0) >> 4;
+                  blend_func(d[0], coltab[v], mtab[v]);
+                  // get next pixel in LSB and blend it
+                  v = (v0) & 0xf;
+                  blend_func(d[1], coltab[v], mtab[v]);
+               }
+             s++; d += 2;
+          }
+        // clean up any leftover pixels at the end
+        if (xx < x2)
+          {
+             v = (*s) >> 4;
+             // fast path - totally solid color can just be written
+             // with no blending done
+             if (mtab[v] == 0) d[0] = coltab[0xf];
+             // blend our color from lookup table
+             else if (v)
+               {
+                  // blend it
+                  blend_func(d[0], coltab[v], mtab[v]);
+               }
+             d++;
+          }
+        d += djump;
+        s0 += pitch2;
+     }
+}
+// with mmx (sse etc.) we need to say we are done with the mmx registers so
+// any fpu usage is restored (early pentiums need this, later x86 do not)
+#ifdef MMX
+evas_common_cpu_end_opt();
+#endif
+
index 7636201..1a33a55 100644 (file)
 
 /* Visual walk helper macros */
 #ifdef OT_SUPPORT
+// TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+/*
 #define _EVAS_FONT_WALK_TEXT_START() \
         Evas_Font_OT_Info *_ot_itr = (text_props->info) ? \
            text_props->info->ot + text_props->start : NULL; \
         if (!_ot_itr) break; \
         for (char_index = 0 ; char_index < text_props->len ; char_index++, _glyph_itr++, _ot_itr++) \
           {
+*/
+#define _EVAS_FONT_WALK_TEXT_START() \
+        Evas_Font_OT_Info *_ot_itr = NULL; \
+        if (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(text_props)) \
+          { \
+             _ot_itr = (text_props->info) ? \
+             text_props->info->ot + text_props->start : NULL; \
+             if (!_ot_itr) break; \
+          } \
+        for (char_index = 0 ; char_index < text_props->len ; \
+             char_index++, _glyph_itr++, \
+             _ot_itr = (_ot_itr) ? _ot_itr + 1 : NULL) \
+          {
+/////////////
 #else
 #define _EVAS_FONT_WALK_TEXT_START() \
         for (char_index = 0 ; char_index < text_props->len ; char_index++, _glyph_itr++) \
@@ -55,6 +71,8 @@
 
 /*FIXME: doc */
 #ifdef OT_SUPPORT
+// TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+/*
 # define EVAS_FONT_WALK_X_OFF \
              (EVAS_FONT_ROUND_26_6_TO_INT(EVAS_FONT_OT_X_OFF_GET(*_ot_itr)))
 # define EVAS_FONT_WALK_Y_OFF \
               text_props->text_offset : \
               EVAS_FONT_WALK_POS \
              )
+*/
+# define EVAS_FONT_WALK_X_OFF \
+             ((_ot_itr) ? \
+             (EVAS_FONT_ROUND_26_6_TO_INT(EVAS_FONT_OT_X_OFF_GET(*_ot_itr))) : 0)
+# define EVAS_FONT_WALK_Y_OFF \
+             ((_ot_itr) ? \
+             (EVAS_FONT_ROUND_26_6_TO_INT(EVAS_FONT_OT_Y_OFF_GET(*_ot_itr))) : 0)
+# define EVAS_FONT_WALK_POS \
+             ((_ot_itr) ? \
+             (EVAS_FONT_OT_POS_GET(*_ot_itr) - text_props->text_offset) : \
+             (((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) ? \
+               (text_props->len - char_index - 1) : \
+               (char_index))))
+# define EVAS_FONT_WALK_POS_NEXT \
+             ((_ot_itr) ? \
+             ((!EVAS_FONT_WALK_IS_LAST) ? \
+              EVAS_FONT_OT_POS_GET(*(_ot_itr + 1)) - \
+               text_props->text_offset : \
+              EVAS_FONT_WALK_POS) : \
+              ((!EVAS_FONT_WALK_IS_LAST) ? \
+              ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) ? \
+               text_props->len - char_index - 2 \
+               : (char_index + 1)) : \
+              EVAS_FONT_WALK_POS))
+# define EVAS_FONT_WALK_POS_PREV \
+             ((_ot_itr) ? \
+             ((char_index > 0) ? \
+             EVAS_FONT_OT_POS_GET(*(_ot_itr - 1)) - \
+              text_props->text_offset : \
+              EVAS_FONT_WALK_POS) : \
+             ((char_index > 0) ? \
+              ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) ? \
+               text_props->len - char_index \
+               : (char_index - 1)) : \
+              EVAS_FONT_WALK_POS))
+////////////
 #else
 # define EVAS_FONT_WALK_X_OFF 0
 # define EVAS_FONT_WALK_Y_OFF 0
index 6f0b6e7..faacd41 100644 (file)
 struct _Evas_Glyph
 {
    RGBA_Font_Glyph *fg;
-   void *data;
-   Eina_Rectangle coord;
+   int x, y;
    FT_UInt idx;
-   int j;
 };
 
 EAPI void
@@ -46,182 +44,40 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, in
    for (it = 0; it < length; ++it, ++glyphs)
      {
         RGBA_Font_Glyph *fg;
-        int chr_x, chr_y;
+        int chr_x, chr_y, w;
 
         fg = glyphs->fg;
 
-       /* FIXME: Why was that moved out of prepare ? This increase cache miss. */
-        glyphs->coord.w = fg->glyph_out->bitmap.width;
-        glyphs->coord.h = fg->glyph_out->bitmap.rows;
-        glyphs->j = fg->glyph_out->bitmap.pitch;
-        glyphs->data = fg->glyph_out->bitmap.buffer;
-
-        if (dc->font_ext.func.gl_new)
+        if ((!fg->ext_dat) && (dc->font_ext.func.gl_new))
           {
              /* extension calls */
              fg->ext_dat = dc->font_ext.func.gl_new(dc->font_ext.data, fg);
              fg->ext_dat_free = dc->font_ext.func.gl_free;
           }
+        w = fg->glyph_out->bitmap.width;
+        chr_x = x + glyphs->x;
+        chr_y = y + glyphs->y;
 
-        chr_x = x + glyphs->coord.x/* EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR */;
-        chr_y = y + glyphs->coord.y/* EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR */;
 
         if (chr_x < (ext_x + ext_w))
           {
-             DATA8 *data;
-             int i, j, w, h;
-
-             data = glyphs->data;
-             j = glyphs->j;
-             w = glyphs->coord.w;
-             if (j < w) j = w;
-             h = glyphs->coord.h;
-
-#ifdef HAVE_PIXMAN
-# ifdef PIXMAN_FONT             
-             int index;
-             DATA32 *font_alpha_buffer;
-             pixman_image_t *font_mask_image;
-
-             font_alpha_buffer = alloca(w * h * sizeof(DATA32));
-             for (index = 0; index < (w * h); index++)
-               font_alpha_buffer[index] = data[index] << 24;
-             
-             font_mask_image = pixman_image_create_bits(PIXMAN_a8r8g8b8, w, h,
-                                                        font_alpha_buffer, 
-                                                        w * sizeof(DATA32));
-
-             if (!font_mask_image)  return;
-# endif
-#endif
 
+                         if ((w > 0) && ((chr_x + w) > ext_x))
                {
-                  if ((j > 0) && (chr_x + w > ext_x))
-                    {
-                       if ((fg->ext_dat) && (dc->font_ext.func.gl_draw))
-                         {
-                            /* ext glyph draw */
-                            dc->font_ext.func.gl_draw(dc->font_ext.data,
-                                                      (void *)dst,
-                                                      dc, fg, chr_x,
-                                                      y - (chr_y - y));
-                         }
-                       else
-                         {
-                            if ((fg->glyph_out->bitmap.num_grays == 256) &&
-                                (fg->glyph_out->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY))
-                              {
-#ifdef HAVE_PIXMAN
-# ifdef PIXMAN_FONT
-                                 if ((dst->pixman.im) && 
-                                     (dc->col.pixman_color_image))
-                                   pixman_image_composite(PIXMAN_OP_OVER, 
-                                                          dc->col.pixman_color_image, 
-                                                          font_mask_image, 
-                                                          dst->pixman.im,
-                                                          chr_x, 
-                                                          y - (chr_y - y), 
-                                                          0, 0, 
-                                                          chr_x, 
-                                                          y - (chr_y - y), 
-                                                          w, h);
-                                 else
-# endif                                   
-#endif
-                                   {
-                                      for (i = 0; i < h; i++)
-                                        {
-                                           int dx, dy;
-                                           int in_x, in_w;
-                                           
-                                           in_x = 0;
-                                           in_w = 0;
-                                           dx = chr_x;
-                                           dy = y - (chr_y - i - y);
-
-                                          if ((dx < (ext_x + ext_w)) &&
-                                              (dy >= (ext_y)) &&
-                                              (dy < (ext_y + ext_h)))
-                                            {
-                                              if (dx + w > (ext_x + ext_w))
-                                                in_w += (dx + w) - (ext_x + ext_w);
-                                              if (dx < ext_x)
-                                                {
-                                                  in_w += ext_x - dx;
-                                                  in_x = ext_x - dx;
-                                                  dx = ext_x;
-                                                }
-                                              if (in_w < w)
-                                                {
-                                                  func(NULL, data + (i * j) + in_x, dc->col.col,
-                                                       im + (dy * im_w) + dx, w - in_w);
-                                                }
-                                            }
-                                        }
-                                   }
-                              }
-                            else
-                              {
-                                 DATA8 *tmpbuf = NULL, *dp, *tp, bits;
-                                 int bi, bj;
-                                 const DATA8 bitrepl[2] = {0x0, 0xff};
-
-                                 tmpbuf = alloca(w);
-                                 for (i = 0; i < h; i++)
-                                   {
-                                      int dx, dy;
-                                      int in_x, in_w, end;
-                                      
-                                      in_x = 0;
-                                      in_w = 0;
-                                      dx = chr_x;
-                                      dy = y - (chr_y - i - y);
-
-                                     tp = tmpbuf;
-                                     dp = data + (i * fg->glyph_out->bitmap.pitch);
-                                     for (bi = 0; bi < w; bi += 8)
-                                       {
-                                         bits = *dp;
-                                         if ((w - bi) < 8) end = w - bi;
-                                         else end = 8;
-                                         for (bj = 0; bj < end; bj++)
-                                           {
-                                             *tp = bitrepl[(bits >> (7 - bj)) & 0x1];
-                                             tp++;
-                                           }
-                                         dp++;
-                                       }
-                                     if ((dx < (ext_x + ext_w)) &&
-                                         (dy >= (ext_y)) &&
-                                         (dy < (ext_y + ext_h)))
-                                       {
-                                         if (dx + w > (ext_x + ext_w))
-                                           in_w += (dx + w) - (ext_x + ext_w);
-                                         if (dx < ext_x)
-                                           {
-                                             in_w += ext_x - dx;
-                                             in_x = ext_x - dx;
-                                             dx = ext_x;
-                                           }
-                                         if (in_w < w)
-                                           {
-                                             func(NULL, tmpbuf + in_x, dc->col.col,
-                                                  im + (dy * im_w) + dx, w - in_w);
-                                           }
-                                        }
-                                   }
-                              }
-                         }
-                    }
-               }
-#ifdef HAVE_PIXMAN
-# ifdef PIXMAN_FONT
-             pixman_image_unref(font_mask_image);
-# endif
-#endif
+                  if ((fg->ext_dat) && (dc->font_ext.func.gl_draw))
+                    dc->font_ext.func.gl_draw(dc->font_ext.data, (void *)dst,
+                                              dc, fg, chr_x, y - (chr_y - y));
+                  else if (fg->glyph_out->rle)
+                    evas_common_font_glyph_draw(fg, dc, dst, im_w,
+                                                chr_x, y - (chr_y - y),
+                                                ext_x, ext_y, ext_w, ext_h);
+                                  
+                               }
           }
         else
-          break;
+          {
+             break;
+          }
      }
 }
 
@@ -267,7 +123,12 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props)
 
         fg = evas_common_font_int_cache_glyph_get(fi, idx);
         if (!fg) continue;
-        if (!fg->glyph_out) evas_common_font_int_cache_glyph_render(fg);
+        if (!fg->glyph_out)
+          if (!evas_common_font_int_cache_glyph_render(fg))
+            {
+               fg = NULL;
+               return;
+            }
 
        if (glyphs_length + 1 >= glyphs_max)
          {
@@ -281,11 +142,12 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props)
          }
 
         glyph = glyphs + glyphs_length++;
+        if (!glyph) return;
 
         glyph->fg = fg;
         glyph->idx = idx;
-        glyph->coord.x = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR;
-        glyph->coord.y = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
+        glyph->x = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR;
+        glyph->y = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
      }
    EVAS_FONT_WALK_TEXT_END();
 
@@ -407,7 +269,7 @@ evas_common_font_draw_do(const Cutout_Rects *reuse, const Eina_Rectangle *clip,
 }
 
 EAPI Eina_Bool
-evas_common_font_draw_prepare_cutout(Cutout_Rects *reuse, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Gfx_Func *func)
+evas_common_font_draw_prepare_cutout(Cutout_Rects **reuse, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Gfx_Func *func)
 {
    int im_w, im_h;
 
@@ -422,7 +284,7 @@ evas_common_font_draw_prepare_cutout(Cutout_Rects *reuse, RGBA_Image *dst, RGBA_
 
    if (dc->cutout.rects)
      {
-        reuse = evas_common_draw_context_apply_cutouts(dc, reuse);
+        *reuse = evas_common_draw_context_apply_cutouts(dc, *reuse);
      }
 
    return EINA_TRUE;
old mode 100644 (file)
new mode 100755 (executable)
index 33126ad..32c1a36
@@ -5,6 +5,7 @@
 
 #include "evas_font_private.h" /* for Frame-Queuing support */
 #include "evas_font_ot.h"
+#include FT_TRUETYPE_TABLES_H
 
 #ifdef EVAS_CSERVE2
 # include "../../cserve2/evas_cs2_private.h"
@@ -69,7 +70,9 @@ _evas_common_font_source_free(RGBA_Font_Source *fs)
 static void
 _evas_common_font_int_free(RGBA_Font_Int *fi)
 {
+   FTLOCK();
    FT_Done_Size(fi->ft.size);
+   FTUNLOCK();
 
    evas_common_font_int_modify_cache_by(fi, -1);
    _evas_common_font_int_clear(fi);
@@ -149,6 +152,7 @@ evas_common_font_source_memory_load(const char *name, const void *data, int data
   if (error)
     {
       FT_Done_Face(fs->ft.face);
+      FTUNLOCK();
       fs->ft.face = NULL;
       free(fs);
       return NULL;
@@ -259,6 +263,7 @@ EAPI void
 evas_common_font_source_free(RGBA_Font_Source *fs)
 {
    fs->references--;
+   fs->current_size = 0;
    if (fs->references > 0) return;
    eina_hash_del(fonts_src, fs->name, fs);
 }
@@ -343,8 +348,18 @@ evas_common_font_int_memory_load(const char *source, const char *name, int size,
    evas_common_font_int_load_complete(fi);
 #ifdef EVAS_CSERVE2
    if (evas_cserve2_use_get())
-     fi->cs2_handler = evas_cserve2_font_load(source, name, size, font_dpi,
-                                              wanted_rend);
+     {
+        fi->cs2_handler = evas_cserve2_font_load(source, name, size, font_dpi,
+                                                 wanted_rend);
+        if (fi->cs2_handler)
+          {
+             if (evas_cserve2_font_load_wait((Font_Entry *)fi->cs2_handler) != 0)
+               {
+                  evas_cserve2_font_free(fi->cs2_handler);
+                  fi->cs2_handler = NULL;
+               }
+          }
+     }
 #endif
    free(fake_name);
    return fi;
@@ -375,8 +390,18 @@ evas_common_font_int_load(const char *name, int size,
    fi = evas_common_font_int_load_init(fi);
 #ifdef EVAS_CSERVE2
    if (evas_cserve2_use_get())
-     fi->cs2_handler = evas_cserve2_font_load(NULL, name, size, font_dpi,
-                                              wanted_rend);
+     {
+        fi->cs2_handler = evas_cserve2_font_load(NULL, name, size, font_dpi,
+                                                 wanted_rend);
+        if (fi->cs2_handler)
+          {
+             if (evas_cserve2_font_load_wait((Font_Entry *)fi->cs2_handler) != 0)
+               {
+                  evas_cserve2_font_free(fi->cs2_handler);
+                  fi->cs2_handler = NULL;
+               }
+          }
+     }
 #endif
 //   evas_common_font_int_load_complete(fi);
    return fi;
@@ -455,13 +480,13 @@ evas_common_font_int_load_complete(RGBA_Font_Int *fi)
    if (fi->src->ft.face->units_per_EM != 0)
      {
         dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
-        ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
+        ret = FONT_METRIC_CONV(val, dv, fi->src->ft.face->size->metrics.y_scale);
      }
    else
      {
         if ((fi->src->ft.face->bbox.yMax == 0) &&
             (fi->src->ft.face->bbox.yMin == 0))
-          ret = (int)fi->ft.size->metrics.ascender / 64;
+          ret = FONT_METRIC_ROUNDUP((int)fi->ft.size->metrics.ascender);
         else
           ret = val;
      }
@@ -470,13 +495,13 @@ evas_common_font_int_load_complete(RGBA_Font_Int *fi)
    if (fi->src->ft.face->units_per_EM != 0)
      {
         dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
-        ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
+        ret = FONT_METRIC_CONV(val, dv, fi->src->ft.face->size->metrics.y_scale);
      }
    else
      {
         if ((fi->src->ft.face->bbox.yMax == 0) &&
             (fi->src->ft.face->bbox.yMin == 0))
-          ret = -(int)fi->ft.size->metrics.descender / 64;
+          ret = FONT_METRIC_ROUNDUP(-(int)fi->ft.size->metrics.descender);
         else
           ret = val;
      }
@@ -492,7 +517,13 @@ evas_common_font_int_load_complete(RGBA_Font_Int *fi)
 
    if ((fi->wanted_rend & FONT_REND_WEIGHT) &&
        !(fi->src->ft.face->style_flags & FT_STYLE_FLAG_BOLD))
-      fi->runtime_rend |= FONT_REND_WEIGHT;
+     {
+        TT_OS2 *tt_os2 = FT_Get_Sfnt_Table(fi->src->ft.face, ft_sfnt_os2);
+        if (!tt_os2 || (tt_os2->usWeightClass < 600))
+          {
+             fi->runtime_rend |= FONT_REND_WEIGHT;
+          }
+     }
 
    return fi;
 }
@@ -658,6 +689,8 @@ evas_common_font_hinting_set(RGBA_Font *fn, Font_Hint_Flags hinting)
    fn->hinting = hinting;
    EINA_LIST_FOREACH(fn->fonts, l, fi)
      {
+        if (fi->hinting != fn->hinting)
+          _evas_common_font_int_clear(fi);
         fi->hinting = fn->hinting;
      }
 }
@@ -742,7 +775,7 @@ _evas_common_font_int_clear(RGBA_Font_Int *fi)
         LKU(fi->ft_mutex);
         return;
      }
-   evas_common_font_int_modify_cache_by(fi, -1);
+   //evas_common_font_int_modify_cache_by(fi, -1); // fixme - this causes eina_list memory leak
    if (fi->references <= 1)
      {
         if (fi->fash)
index ecbe263..cdeb6bc 100644 (file)
@@ -11,6 +11,7 @@
 
 #include FT_OUTLINE_H
 #include FT_SYNTHESIS_H
+#include FT_BITMAP_H
 
 FT_Library      evas_ft_lib = 0;
 static int      initialised = 0;
@@ -69,36 +70,9 @@ evas_common_font_font_all_unload(void)
 }
 
 EAPI int
-evas_common_font_ascent_get(RGBA_Font *fn)
+evas_common_font_instance_ascent_get(RGBA_Font_Int *fi)
 {
    int val;
-   RGBA_Font_Int *fi;
-
-//   evas_common_font_size_use(fn);
-#if 0
-     {
-        Eina_List *l;
-        
-        EINA_LIST_FOREACH(fn->fonts, l, fi)
-          {
-             if (!fi->src->ft.face) continue;
-             if (fi->src->current_size != fi->size)
-               {
-                 FTLOCK();
-                  FT_Activate_Size(fi->ft.size);
-                 FTUNLOCK();
-                  fi->src->current_size = fi->size;
-               }
-             val = (int)fi->src->ft.face->size->metrics.ascender;
-             if (fi->src->ft.face->units_per_EM == 0)
-               return val;
-             dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
-             ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
-             printf(" ==== %p: %i\n", fi, ret);
-          }
-     }
-#endif
-   fi = fn->fonts->data;
    evas_common_font_int_reload(fi);
    if (fi->src->current_size != fi->size)
      {
@@ -112,7 +86,7 @@ evas_common_font_ascent_get(RGBA_Font *fn)
         WRN("NOT SCALABLE!");
      }
    val = (int)fi->src->ft.face->size->metrics.ascender;
-   return val >> 6;
+   return FONT_METRIC_ROUNDUP(val);
 //   printf("%i | %i\n", val, val >> 6);
 //   if (fi->src->ft.face->units_per_EM == 0)
 //     return val;
@@ -122,13 +96,9 @@ evas_common_font_ascent_get(RGBA_Font *fn)
 }
 
 EAPI int
-evas_common_font_descent_get(RGBA_Font *fn)
+evas_common_font_instance_descent_get(RGBA_Font_Int *fi)
 {
    int val;
-   RGBA_Font_Int *fi;
-
-//   evas_common_font_size_use(fn);
-   fi = fn->fonts->data;
    evas_common_font_int_reload(fi);
    if (fi->src->current_size != fi->size)
      {
@@ -138,7 +108,7 @@ evas_common_font_descent_get(RGBA_Font *fn)
         fi->src->current_size = fi->size;
      }
    val = -(int)fi->src->ft.face->size->metrics.descender;
-   return val >> 6;
+   return FONT_METRIC_ROUNDUP(val);
 //   if (fi->src->ft.face->units_per_EM == 0)
 //     return val;
 //   dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
@@ -147,14 +117,11 @@ evas_common_font_descent_get(RGBA_Font *fn)
 }
 
 EAPI int
-evas_common_font_max_ascent_get(RGBA_Font *fn)
+evas_common_font_instance_max_ascent_get(RGBA_Font_Int *fi)
 {
    int val, dv;
    int ret;
-   RGBA_Font_Int *fi;
 
-//   evas_common_font_size_use(fn);
-   fi = fn->fonts->data;
    evas_common_font_int_reload(fi);
   if (fi->src->current_size != fi->size)
      {
@@ -166,25 +133,22 @@ evas_common_font_max_ascent_get(RGBA_Font *fn)
    if ((fi->src->ft.face->bbox.yMax == 0) &&
        (fi->src->ft.face->bbox.yMin == 0) &&
        (fi->src->ft.face->units_per_EM == 0))
-     val = (int)fi->src->ft.face->size->metrics.ascender / 64;
+     val = FONT_METRIC_ROUNDUP((int)fi->src->ft.face->size->metrics.ascender);
    else
      val = (int)fi->src->ft.face->bbox.yMax;
    if (fi->src->ft.face->units_per_EM == 0)
      return val;
    dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
-   ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
+   ret = FONT_METRIC_CONV(val, dv, fi->src->ft.face->size->metrics.y_scale);
    return ret;
 }
 
 EAPI int
-evas_common_font_max_descent_get(RGBA_Font *fn)
+evas_common_font_instance_max_descent_get(RGBA_Font_Int *fi)
 {
    int val, dv;
    int ret;
-   RGBA_Font_Int *fi;
 
-//   evas_common_font_size_use(fn);
-   fi = fn->fonts->data;
    evas_common_font_int_reload(fi);
    if (fi->src->current_size != fi->size)
      {
@@ -196,17 +160,45 @@ evas_common_font_max_descent_get(RGBA_Font *fn)
    if ((fi->src->ft.face->bbox.yMax == 0) &&
        (fi->src->ft.face->bbox.yMin == 0) &&
        (fi->src->ft.face->units_per_EM == 0))
-     val = -(int)fi->src->ft.face->size->metrics.descender / 64;
+     val = FONT_METRIC_ROUNDUP(-(int)fi->src->ft.face->size->metrics.descender);
    else
      val = -(int)fi->src->ft.face->bbox.yMin;
    if (fi->src->ft.face->units_per_EM == 0)
      return val;
    dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
-   ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
+   ret = FONT_METRIC_CONV(val, dv, fi->src->ft.face->size->metrics.y_scale);
    return ret;
 }
 
 EAPI int
+evas_common_font_ascent_get(RGBA_Font *fn)
+{
+//   evas_common_font_size_use(fn);
+   return evas_common_font_instance_ascent_get(fn->fonts->data);
+}
+
+EAPI int
+evas_common_font_descent_get(RGBA_Font *fn)
+{
+//   evas_common_font_size_use(fn);
+   return evas_common_font_instance_descent_get(fn->fonts->data);
+}
+
+EAPI int
+evas_common_font_max_ascent_get(RGBA_Font *fn)
+{
+//   evas_common_font_size_use(fn);
+   return evas_common_font_instance_max_ascent_get(fn->fonts->data);
+}
+
+EAPI int
+evas_common_font_max_descent_get(RGBA_Font *fn)
+{
+//   evas_common_font_size_use(fn);
+   return evas_common_font_instance_max_descent_get(fn->fonts->data);
+}
+
+EAPI int
 evas_common_font_get_line_advance(RGBA_Font *fn)
 {
    int val;
@@ -226,10 +218,10 @@ evas_common_font_get_line_advance(RGBA_Font *fn)
    if ((fi->src->ft.face->bbox.yMax == 0) &&
        (fi->src->ft.face->bbox.yMin == 0) &&
        (fi->src->ft.face->units_per_EM == 0))
-     return val >> 6;
+     return FONT_METRIC_ROUNDUP(val);
    else if (fi->src->ft.face->units_per_EM == 0)
      return val;
-   return val >> 6;
+   return FONT_METRIC_ROUNDUP(val);
 //   dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
 //   ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
 //   return ret;
@@ -242,7 +234,12 @@ _fash_int2_free(Fash_Int_Map2 *fash)
 {
    int i;
 
-   for (i = 0; i < 256; i++) if (fash->bucket[i]) free(fash->bucket[i]);
+   for (i = 0; i < 256; i++)
+     if (fash->bucket[i])
+       {
+          free(fash->bucket[i]);
+          fash->bucket[i] = NULL;
+       }
    free(fash);
 }
 
@@ -251,7 +248,12 @@ _fash_int_free(Fash_Int *fash)
 {
    int i;
 
-   for (i = 0; i < 256; i++) if (fash->bucket[i]) _fash_int2_free(fash->bucket[i]);
+   for (i = 0; i < 256; i++)
+     if (fash->bucket[i])
+       {
+          _fash_int2_free(fash->bucket[i]);
+          fash->bucket[i] = NULL;
+       }
    free(fash);
 }
 
@@ -306,10 +308,19 @@ _fash_glyph_free(Fash_Glyph_Map *fmap)
         RGBA_Font_Glyph *fg = fmap->item[i];
         if ((fg) && (fg != (void *)(-1)))
           {
+                       if (fg->glyph_out)
+                       {
+                               if ((fg->glyph_out->rle) && (fg->glyph_out->bitmap.rle_alloc))
+                         free(fg->glyph_out->rle);
+                               fg->glyph_out->rle = NULL;
+                               if (!fg->glyph_out->bitmap.no_free_glout)
+                                       free(fg->glyph_out);
+                               fg->glyph_out = NULL;
+                       }
+                         
              FT_Done_Glyph(fg->glyph);
              /* extension calls */
              if (fg->ext_dat_free) fg->ext_dat_free(fg->ext_dat);
-             if (fg->glyph_out_free) fg->glyph_out_free(fg->glyph_out);
              free(fg);
              fmap->item[i] = NULL;
           }
@@ -423,7 +434,15 @@ evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt idx)
       FT_Outline_Transform(&fi->src->ft.face->glyph->outline, &transform);
    /* Embolden the outline of Glyph according to rundtime_rend. */
    if (fi->runtime_rend & FONT_REND_WEIGHT)
-      FT_GlyphSlot_Embolden(fi->src->ft.face->glyph);
+     {
+        // Tizen Only (2013.09.16) : Use FT_Outline_Emobolden instead of FT_GlyphSlot_Embolden.
+        //                           FT_GlyphSlot_Embolden changed metrics, it is not pretty
+        // FT_GlyphSlot_Embolden(fi->src->ft.face->glyph);
+        FT_Pos xstr = FT_MulFix( fi->src->ft.face->units_per_EM,
+                                 fi->src->ft.face->size->metrics.y_scale ) / 64;
+        FT_Outline_Embolden( &fi->src->ft.face->glyph->outline, xstr );
+        //
+     }
 
    fg = malloc(sizeof(struct _RGBA_Font_Glyph));
    if (!fg) return NULL;
@@ -492,32 +511,41 @@ evas_common_font_int_cache_glyph_render(RGBA_Font_Glyph *fg)
      {
         FT_Done_Glyph(fg->glyph);
         FTUNLOCK();
-        free(fg);
         if (!fi->fash) fi->fash = _fash_gl_new();
         if (fi->fash) _fash_gl_add(fi->fash, fg->index, (void *)(-1));
+        free(fg);
         return EINA_FALSE;
      }
    FTUNLOCK();
 
    fbg = (FT_BitmapGlyph)fg->glyph;
 
-   fg->glyph_out = malloc(sizeof(RGBA_Font_Glyph_Out));
+   fg->glyph_out = calloc(1, sizeof(RGBA_Font_Glyph_Out));
    fg->glyph_out->bitmap.rows = fbg->bitmap.rows;
    fg->glyph_out->bitmap.width = fbg->bitmap.width;
    fg->glyph_out->bitmap.pitch = fbg->bitmap.pitch;
    fg->glyph_out->bitmap.buffer = fbg->bitmap.buffer;
-   fg->glyph_out->bitmap.num_grays = fbg->bitmap.num_grays;
-   fg->glyph_out->bitmap.pixel_mode = fbg->bitmap.pixel_mode;
-
-   fg->glyph_out_free = free;
-   /* This '+ 200' is just an estimation of how much memory freetype will use
+   fg->glyph_out->bitmap.rle_alloc = EINA_TRUE;
+   
+   /* This '+ 100' is just an estimation of how much memory freetype will use
     * on it's size. This value is not really used anywhere in code - it's
     * only for statistics. */
    size = sizeof(RGBA_Font_Glyph) + sizeof(Eina_List) +
-    (fg->glyph_out->bitmap.width * fg->glyph_out->bitmap.rows) + 200;
+    (fg->glyph_out->bitmap.width * fg->glyph_out->bitmap.rows / 2) + 100;
    fi->usage += size;
    if (fi->inuse) evas_common_font_int_use_increase(size);
 
+   fg->glyph_out->rle = evas_common_font_glyph_compress
+   (fbg->bitmap.buffer, fbg->bitmap.num_grays, fbg->bitmap.pixel_mode,
+    fbg->bitmap.pitch, fbg->bitmap.width, fbg->bitmap.rows,
+    &(fg->glyph_out->rle_size));
+
+   fg->glyph_out->bitmap.buffer = NULL;
+
+   // this may be technically incorrect as we go and free a bitmap buffer
+   // behind the ftglyph's back...
+   FT_Bitmap_Done(evas_ft_lib, &(fbg->bitmap));
+   
    return EINA_TRUE;
 }
 
@@ -573,6 +601,7 @@ evas_common_get_char_index(RGBA_Font_Int* fi, Eina_Unicode gl)
 #endif
 
 //   result = eina_hash_find(fi->indexes, &gl);
+
 //   if (result) goto on_correct;
 //
 //   result = malloc(sizeof (Font_Char_Index));
@@ -592,6 +621,7 @@ evas_common_get_char_index(RGBA_Font_Int* fi, Eina_Unicode gl)
     */
    /* FTLOCK(); */
    result.index = FT_Get_Char_Index(fi->src->ft.face, gl);
+
    /* FTUNLOCK(); */
    result.gl = gl;
 
index 9ed92c7..9fcf6bb 100644 (file)
@@ -166,7 +166,7 @@ evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_i
      }
    else
      {
-        if (right_bound >= (int) (props->text_offset + props->text_len))
+        if (right_bound >= (int) (props->start + props->len))
           {
              items = props->text_offset + props->text_len - base_cluster;
           }
index 2a2a382..e87245a 100644 (file)
@@ -41,10 +41,25 @@ void evas_common_font_int_reload(RGBA_Font_Int *fi);
    (((x + 0x20) & -0x40) >> 6)
 
 # define EVAS_FONT_CHARACTER_IS_INVISIBLE(x) ( \
-      ((0x200C <= (x)) && ((x) <= 0x200D)) || /* ZWNJ..ZWH */ \
+      (0x200C == (x)) || /* ZWNJ */ \
       ((0x200E <= (x)) && ((x) <= 0x200F)) || /* BIDI stuff */ \
       ((0x202A <= (x)) && ((x) <= 0x202E)) /* BIDI stuff */ \
       )
 
+# if 1
+// do proper round (up or down like 1.4 -> 1 and 1.6 -> 2 etc
+#  define FONT_METRIC_CONV(val, dv, scale) \
+   (((long long)((val) * (scale)) + (long long)((dv) * (dv) / 2LL)) \
+     / (long long)((dv) * (dv)))
+#  define FONT_METRIC_ROUNDUP(val) \
+   (((val) + 31) >> 6)
+# else
+// truncate/round down
+#  define FONT_METRIC_CONV(val, dv, scale) \
+   (((val) * (scale)) / ((dv) * (dv)))
+#  define FONT_METRIC_ROUNDUP(val) \
+   ((val) >> 6)
+# endif
+
 # include "evas_font_default_walk.x"
 #endif /* !_EVAS_FONT_PRIVATE_H */
index ddd6a5c..3c59645 100644 (file)
@@ -70,21 +70,30 @@ evas_common_font_query_run_font_end_get(RGBA_Font *fn, RGBA_Font_Int **script_fi
    while (itr < run_end)
      {
         RGBA_Font_Int *tmp_fi;
+        // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+        Eina_Bool emo = EINA_FALSE;
+        //
         /* Itr will end up being the first of the next run  */
         for ( ; itr < run_end ; itr++)
           {
+             // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+             UNICODE_EMOTICON_CHECK(*itr)
+               {
+                  emo = EINA_TRUE;
+                  break;
+               }
+             //
+
              /* 0x1F is the last ASCII contral char, just a hack in
               * the meanwhile. */
              if (*itr <= 0x1F)
                 continue;
              /* Break if either it's not in the font, or if it is in the
               * script's font. */
-             if (fi == *script_fi)
-               {
-                  if (!evas_common_get_char_index(fi, *itr))
-                     break;
-               }
-             else
+             if (!evas_common_get_char_index(fi, *itr))
+                break;
+
+             if (fi != *script_fi)
                {
                   if (evas_common_get_char_index(*script_fi, *itr))
                      break;
@@ -108,6 +117,10 @@ evas_common_font_query_run_font_end_get(RGBA_Font *fn, RGBA_Font_Int **script_fi
              else
                {
                   itr++;
+                  // HAVE_UNICODE_EMOTICON(2013.10.11): Fix emoticon unicode parsing code.
+                  if (emo)
+                    break;
+                  //
                   /* Go through all the chars that can't be rendered with any
                    * font */
                   for ( ; itr < run_end ; itr++)
@@ -133,9 +146,17 @@ evas_common_font_query_run_font_end_get(RGBA_Font *fn, RGBA_Font_Int **script_fi
                     }
                }
              itr++;
+             // HAVE_UNICODE_EMOTICON(2013.10.11): Fix emoticon unicode parsing code.
+             if (emo)
+               break;
+             //
           }
         else
           {
+             // HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+             if (emo)
+               break;
+             //
              /* If this char is not renderable by any font, but the replacement
               * char can be rendered using the currentfont, continue this
               * run. */
@@ -177,12 +198,14 @@ evas_common_font_query_kerning(RGBA_Font_Int *fi, FT_UInt left, FT_UInt right,
    int *result;
    FT_Vector delta;
    int key[2];
+   int hash;
    int error = 1;
 
    key[0] = left;
    key[1] = right;
+   hash = eina_hash_int32(&left, sizeof (int)) ^ eina_hash_int32(&right, sizeof (int));
 
-   result = eina_hash_find(fi->kerning, key);
+   result = eina_hash_find_by_hash(fi->kerning, key, sizeof (int) * 2, hash);
    if (result)
      {
        *kerning = result[2];
@@ -196,7 +219,7 @@ evas_common_font_query_kerning(RGBA_Font_Int *fi, FT_UInt left, FT_UInt right,
    evas_common_font_int_reload(fi);
    FTLOCK();
    if (FT_Get_Kerning(fi->src->ft.face,
-                     key[0], key[1],
+                     left, right,
                      FT_KERNING_DEFAULT, &delta) == 0)
      {
        int *push;
@@ -207,11 +230,11 @@ evas_common_font_query_kerning(RGBA_Font_Int *fi, FT_UInt left, FT_UInt right,
        push = malloc(sizeof (int) * 3);
        if (!push) return 1;
 
-       push[0] = key[0];
-       push[1] = key[1];
+       push[0] = left;
+       push[1] = right;
        push[2] = *kerning;
 
-       eina_hash_direct_add(fi->kerning, push, push);
+       eina_hash_direct_add_by_hash(fi->kerning, push, sizeof(int) * 2, hash, push);
 
        goto on_correct;
      }
@@ -264,6 +287,8 @@ evas_common_font_query_right_inset(RGBA_Font *fn __UNUSED__, const Evas_Text_Pro
    if (gli->width == 0)
       return 0;
 
+   // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+   /*
    return ((gli > text_props->info->glyph) ?
       gli->pen_after - (gli - 1)->pen_after : gli->pen_after) -
       (gli->width + gli->x_bear
@@ -272,6 +297,57 @@ evas_common_font_query_right_inset(RGBA_Font *fn __UNUSED__, const Evas_Text_Pro
               text_props->info->ot[text_props->start + text_props->len - 1]))
 #endif
       );
+   */
+   return ((gli > text_props->info->glyph) ?
+      gli->pen_after - (gli - 1)->pen_after : gli->pen_after) -
+      (gli->width + gli->x_bear
+#ifdef OT_SUPPORT
+       + (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(text_props)) ?
+       EVAS_FONT_ROUND_26_6_TO_INT(EVAS_FONT_OT_X_OFF_GET(
+            text_props->info->ot[text_props->start + text_props->len - 1])) : 0
+#endif
+      );
+   //
+}
+
+/**
+ * @internal
+ * Calculate the ascent/descent of a run. This is different from
+ * evas_common_font_[max]_ascent/descent_get because this one returns the
+ * actual sizee (i.e including accents), and not just what the font reports.
+ *
+ * @param fn the font set to use.
+ * @param text_props the string object.
+ * @param[out] ascent the calculated ascent
+ * @param[out] descent the calculated descent
+ */
+EAPI void
+evas_common_font_ascent_descent_get(RGBA_Font *fn, const Evas_Text_Props *text_props, int *ascent, int *descent)
+{
+   int asc = 0, desc = 0;
+   int max_asc, max_desc;
+
+   max_asc = evas_common_font_ascent_get(fn);
+   max_desc = evas_common_font_descent_get(fn);
+
+   /* FIXME: Not supported yet!!! */
+   desc = max_desc;
+
+   EVAS_FONT_WALK_TEXT_INIT();
+   EVAS_FONT_WALK_TEXT_START()
+     {
+        EVAS_FONT_WALK_TEXT_WORK();
+        if (!EVAS_FONT_WALK_IS_VISIBLE) continue;
+
+        if ((EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR) > asc)
+          {
+             asc = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
+          }
+     }
+   EVAS_FONT_WALK_TEXT_END();
+
+   if (ascent) *ascent = (asc > max_asc) ? asc : max_asc;
+   if (descent) *descent = (desc < max_desc) ? desc : max_desc;
 }
 
 /**
@@ -305,8 +381,15 @@ evas_common_font_query_size(RGBA_Font *fn, const Evas_Text_Props *text_props, in
                 ret_w -= glyph[-1].pen_after;
           }
 #ifdef OT_SUPPORT
-        ret_w += EVAS_FONT_ROUND_26_6_TO_INT(EVAS_FONT_OT_X_OFF_GET(
-              text_props->info->ot[text_props->start + text_props->len - 1]));
+        // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+        //ret_w += EVAS_FONT_ROUND_26_6_TO_INT(EVAS_FONT_OT_X_OFF_GET(
+        //      text_props->info->ot[text_props->start + text_props->len - 1]));
+        if (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(text_props))
+          {
+             ret_w += EVAS_FONT_ROUND_26_6_TO_INT(EVAS_FONT_OT_X_OFF_GET(
+                   text_props->info->ot[text_props->start + text_props->len - 1]));
+          }
+        //
 #endif
         ret_w += last_glyph->width + last_glyph->x_bear;
      }
@@ -440,8 +523,15 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Evas_Text_Props *text_pr
           {
              found = 1;
 #ifdef OT_SUPPORT
-             items = evas_common_font_ot_cluster_size_get(text_props,
-                                                          char_index);
+             // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+             //items = evas_common_font_ot_cluster_size_get(text_props,
+             //                                             char_index);
+             if (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(text_props))
+               {
+                  items = evas_common_font_ot_cluster_size_get(text_props,
+                                                               char_index);
+               }
+             //
 #endif
              item_pos = position - EVAS_FONT_WALK_POS + 1;
           }
@@ -452,8 +542,15 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Evas_Text_Props *text_pr
           {
              found = 1;
 #ifdef OT_SUPPORT
-             items = evas_common_font_ot_cluster_size_get(text_props,
-                                                          char_index);
+             // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+             //items = evas_common_font_ot_cluster_size_get(text_props,
+             //                                             char_index);
+             if (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(text_props))
+               {
+                  items = evas_common_font_ot_cluster_size_get(text_props,
+                                                               char_index);
+               }
+             //
 #endif
              item_pos = items - (position - EVAS_FONT_WALK_POS);
           }
@@ -571,8 +668,13 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Evas_Text_Props *text_pro
           {
              found = 1;
 #ifdef OT_SUPPORT
-             items = evas_common_font_ot_cluster_size_get(text_props,
-                                                          char_index);
+             // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+             //items = evas_common_font_ot_cluster_size_get(text_props,
+             //                                             char_index);
+             if (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(text_props))
+               items = evas_common_font_ot_cluster_size_get(text_props,
+                                                            char_index);
+             //
 #endif
              item_pos = position - EVAS_FONT_WALK_POS + 1;
           }
@@ -583,8 +685,13 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Evas_Text_Props *text_pro
           {
              found = 1;
 #ifdef OT_SUPPORT
-             items = evas_common_font_ot_cluster_size_get(text_props,
-                                                          char_index);
+             // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+             //items = evas_common_font_ot_cluster_size_get(text_props,
+             //                                             char_index);
+             if (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(text_props))
+               items = evas_common_font_ot_cluster_size_get(text_props,
+                                                            char_index);
+             //
 #endif
              item_pos = items - (position - EVAS_FONT_WALK_POS);
           }
@@ -671,8 +778,13 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Evas_Text_Props *text
             (x <= (EVAS_FONT_WALK_PEN_X_AFTER)) && (y >= -asc) && (y <= desc))
           {
 #ifdef OT_SUPPORT
-             items = evas_common_font_ot_cluster_size_get(text_props,
-                                                          char_index);
+             // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+             //items = evas_common_font_ot_cluster_size_get(text_props,
+             //                                             char_index);
+             if (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(text_props))
+               items = evas_common_font_ot_cluster_size_get(text_props,
+                                                            char_index);
+             //
 #endif
              found = 1;
           }
@@ -683,6 +795,7 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Evas_Text_Props *text
    if (found)
      {
         int item_pos;
+        Evas_Coord cx_it, cw_it, cmid;
         Evas_Coord cluster_adv;
         cluster_adv = EVAS_FONT_WALK_PEN_X - cluster_start;
 
@@ -698,12 +811,34 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Evas_Text_Props *text
              part = cluster_adv / items;
              item_pos = items - ((int) ((x - cluster_start) / part)) - 1;
           }
-        if (cx) *cx = EVAS_FONT_WALK_PEN_X +
-          ((cluster_adv / items) * (item_pos - 1));
+
+        cx_it = EVAS_FONT_WALK_PEN_X + ((cluster_adv / items) * (item_pos - 1));
+        cw_it = (cluster_adv / items);
+
+        if (cx) *cx = cx_it;
         if (cy) *cy = -asc;
-        if (cw) *cw = (cluster_adv / items);
+        if (cw) *cw = cw_it;
         if (ch) *ch = asc + desc;
         ret_val = prev_cluster + item_pos;
+
+        /* Check, if x coord points to RIGHT half part of LTR char
+         * or to LEFT half char of RTL char. If so, increment found position */
+        cmid = cx_it + (cw_it / 2);
+        if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR)
+          {
+             if (x > cmid)
+               {
+                  ret_val++;
+               }
+          }
+        else
+          {
+             if (x < cmid)
+               {
+                  ret_val++;
+               }
+          }
+
         goto end;
      }
 end:
@@ -763,9 +898,21 @@ evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Evas_Text_Props *text
                         (y >= -asc) && (y <= desc))
                     {
 #ifdef OT_SUPPORT
-                       ret = EVAS_FONT_OT_POS_GET(
-                             text_props->info->ot[text_props->start + i]) -
-                          text_props->text_offset;
+                       // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+                       //ret = EVAS_FONT_OT_POS_GET(
+                       //   text_props->info->ot[text_props->start + i]) -
+                       //   text_props->text_offset;
+                       if (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(text_props))
+                         {
+                            ret = EVAS_FONT_OT_POS_GET(
+                               text_props->info->ot[text_props->start + i]) -
+                               text_props->text_offset;
+                         }
+                       else
+                         {
+                            ret = text_props->text_len - i - 1;
+                         }
+                       //
 #else
                        ret = text_props->text_len - i - 1;
 #endif
index 766c90c..6e10e86 100644 (file)
@@ -33,7 +33,7 @@ EAPI void              evas_common_image_alpha_line_buffer_release (RGBA_Image *
 EAPI void              evas_common_image_alpha_line_buffer_free    (RGBA_Image *im);
 
 EAPI RGBA_Image       *evas_common_load_image_from_file            (const char *file, const char *key, RGBA_Image_Loadopts *lo, int *error);
-EAPI int               evas_common_save_image_to_file              (RGBA_Image *im, const char *file, const char *key, int quality, int compress);
+EAPI int               evas_common_save_image_to_file              (RGBA_Image *im, const char *file, const char *key, int quality, int compress, const char *encoding);
 
 EAPI void evas_common_rgba_image_scalecache_init(Image_Entry *ie);
 EAPI void evas_common_rgba_image_scalecache_shutdown(Image_Entry *ie);
index 2815ff8..a589ff9 100644 (file)
@@ -22,6 +22,14 @@ evas_common_rgba_image_from_data(Image_Entry* ie_dst, int w, int h, DATA32 *imag
        dst->image.no_free = 1;
        dst->cache_entry.flags.alpha = alpha ? 1 : 0;
        break;
+      case EVAS_COLORSPACE_AGRY88:
+      case EVAS_COLORSPACE_GRY8:
+       dst->cache_entry.w = w;
+       dst->cache_entry.h = h;
+    dst->image.data8 = (DATA8 *) image_data;
+    dst->image.no_free = 1;
+       dst->cache_entry.flags.alpha = 1;
+       break;
       case EVAS_COLORSPACE_YCBCR422P601_PL:
       case EVAS_COLORSPACE_YCBCR422P709_PL:
       case EVAS_COLORSPACE_YCBCR422601_PL:
@@ -56,6 +64,16 @@ evas_common_rgba_image_from_copied_data(Image_Entry* ie_dst, int w, int h, DATA3
          if (image_data)
            memcpy(dst->image.data, image_data, w * h * sizeof(DATA32));
          break;
+      case EVAS_COLORSPACE_AGRY88:
+         dst->cache_entry.flags.alpha = 1;
+         if (image_data)
+           memcpy(dst->image.data8, image_data, w * h * sizeof(DATA16));
+         break;
+      case EVAS_COLORSPACE_GRY8:
+         dst->cache_entry.flags.alpha = 1;
+         if (image_data)
+           memcpy(dst->image.data8, image_data, w * h * sizeof(DATA8));
+         break;
       case EVAS_COLORSPACE_YCBCR422P601_PL:
       case EVAS_COLORSPACE_YCBCR422P709_PL:
       case EVAS_COLORSPACE_YCBCR422601_PL:
@@ -104,16 +122,25 @@ int
 evas_common_rgba_image_colorspace_set(Image_Entry* ie_dst, int cspace)
 {
    RGBA_Image   *dst = (RGBA_Image *) ie_dst;
+   Eina_Bool change = (dst->cache_entry.space != cspace);
 
    switch (cspace)
      {
       case EVAS_COLORSPACE_ARGB8888:
+      case EVAS_COLORSPACE_AGRY88:
+      case EVAS_COLORSPACE_GRY8:
        if (dst->cs.data)
          {
             if (!dst->cs.no_free) free(dst->cs.data);
             dst->cs.data = NULL;
             dst->cs.no_free = 0;
          }
+        if (change && dst->image.data)
+          {
+             if (!dst->image.no_free) free(dst->image.data);
+             dst->image.data = NULL;
+             dst->image.no_free = 0;
+          }
        break;
       case EVAS_COLORSPACE_YCBCR422P601_PL:
       case EVAS_COLORSPACE_YCBCR422P709_PL:
index 386bb76..527d189 100644 (file)
@@ -47,9 +47,11 @@ static const struct ext_loader_s loaders[] =
    MATCHING(".bmp", "bmp"),
    MATCHING(".tga", "tga"),
    MATCHING(".wbmp", "wbmp"),
+   MATCHING(".webp", "webp"),
    MATCHING(".ico", "ico"),
    MATCHING(".cur", "ico"),
    MATCHING(".psd", "psd"),
+   MATCHING(".tgv", "tgv"),
    MATCHING(".pdf", "generic"),
    MATCHING(".ps", "generic"),
    MATCHING(".xcf", "generic"),
@@ -127,7 +129,7 @@ static const struct ext_loader_s loaders[] =
 
 static const char *loaders_name[] =
 { /* in order of most likely needed */
-  "png", "jpeg", "eet", "xpm", "tiff", "gif", "svg", "pmaps", "bmp", "tga", "wbmp", "ico", "psd", "edb", "generic"
+  "png", "jpeg", "eet", "xpm", "tiff", "gif", "svg", "webp", "pmaps", "bmp", "tga", "wbmp", "ico", "psd", "edb", "tgv", "generic"
 };
 
 struct evas_image_foreach_loader_data
@@ -239,9 +241,9 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
                       goto end;
                    }
                  evas_module_unload(em);
-                 INF("failed to load file head using module '%s' (%p): "
-                     "%s (%s)",
-                     loader, em, ie->file, evas_load_error_str(ret));
+                 //INF("failed to load file head using module '%s' (%p): "
+                 //    "%s (%s)",
+                 //    loader, em, ie->file, evas_load_error_str(ret));
               }
             else
               WRN("failed to load module '%s' (%p)", loader, em);
@@ -277,10 +279,10 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
                           loaders_name[i], em, ie->file);
                       goto end;
                    }
-                 else
-                   INF("brute force loader '%s' (%p) failed on %s (%s)",
-                       loaders_name[i], em, ie->file,
-                       evas_load_error_str(ret));
+                   //else
+                   //INF("brute force loader '%s' (%p) failed on %s (%s)",
+                       //loaders_name[i], em, ie->file,
+                       //evas_load_error_str(ret));
 
                  evas_module_unload(em);
               }
index b6735dc..204bdb0 100755 (executable)
@@ -347,8 +347,16 @@ _evas_common_rgba_image_post_surface(Image_Entry *ie)
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_IMAGE   
    RGBA_Image *im = (RGBA_Image *)ie;
-
+   int w, h;
+   
    if (im->pixman.im) pixman_image_unref(im->pixman.im);
+   w = ie->allocated.w;
+   h = ie->allocated.h;
+   if ((w <= 0) || (h <= 0))
+     {
+        w = im->cache_entry.w;
+        h = im->cache_entry.h;
+     }
    if (im->cache_entry.flags.alpha)
      {
         im->pixman.im = pixman_image_create_bits
@@ -356,10 +364,7 @@ _evas_common_rgba_image_post_surface(Image_Entry *ie)
 // FIXME: endianess determines this
             PIXMAN_a8r8g8b8,
 //            PIXMAN_b8g8r8a8,
-            im->cache_entry.w, im->cache_entry.h,
-            im->image.data,
-            im->cache_entry.w * 4
-        );
+            w, h, im->image.data, w * 4);
      }
    else
      {
@@ -368,10 +373,7 @@ _evas_common_rgba_image_post_surface(Image_Entry *ie)
 // FIXME: endianess determines this
             PIXMAN_x8r8g8b8,
 //            PIXMAN_b8g8r8x8,
-            im->cache_entry.w, im->cache_entry.h,
-            im->image.data,
-            im->cache_entry.w * 4
-        );
+            w, h, im->image.data, w * 4);
      }
 # else
    (void)ie;
@@ -395,10 +397,25 @@ _evas_common_rgba_image_surface_alloc(Image_Entry *ie, unsigned int w, unsigned
 #endif
    if (im->image.no_free) return 0;
 
-   if (im->flags & RGBA_IMAGE_ALPHA_ONLY)
-     siz = w * h * sizeof(DATA8);
-   else
-     siz = w * h * sizeof(DATA32);
+   switch (im->cache_entry.space)
+     {
+      case EVAS_COLORSPACE_GRY8: siz = w * h * sizeof(DATA8); break;
+      case EVAS_COLORSPACE_AGRY88: siz = w * h * sizeof(DATA16); break;
+      case EVAS_COLORSPACE_ARGB8888: siz = w * h * sizeof(DATA32); break;
+      case EVAS_COLORSPACE_ETC1:
+      case EVAS_COLORSPACE_RGB8_ETC2:
+        // Need to round width and height independently
+        w += 2; h += 2; // We do duplicate border in ETC1 to have better rendering on GPU.
+        siz = (w / 4 + (w % 4 ? 1 : 0)) * (h / 4 + (h % 4 ? 1 : 0)) * 8;
+        break;
+      case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+      case EVAS_COLORSPACE_ETC1_ALPHA:
+         w += 2; h += 2;
+         siz = (w / 4 + (w % 4 ? 1 : 0)) * (h / 4 + (h % 4 ? 1 : 0)) * 16;
+         break;
+      default:
+        return -1;
+     }
 
    if (im->image.data)
      {
@@ -407,7 +424,7 @@ _evas_common_rgba_image_surface_alloc(Image_Entry *ie, unsigned int w, unsigned
         surfs = eina_list_remove(surfs, ie);
 #endif        
      }
-   im->image.data = malloc(siz);
+   im->image.data = calloc(1, siz);
    if (!im->image.data) return -1;
    ie->allocated.w = w;
    ie->allocated.h = h;
@@ -446,6 +463,13 @@ _evas_common_rgba_image_surface_delete(Image_Entry *ie)
 #endif
    if (ie->file)
      DBG("unload: [%p] %s %s", ie, ie->file, ie->key);
+
+   if (im->native.data)
+     {
+        if (im->native.func.free)
+          im->native.func.free(im->native.func.data, im);
+        im->native.data = NULL;
+     }
    if ((im->cs.data) && (im->image.data))
      {
        if (im->cs.data != im->image.data)
@@ -523,17 +547,20 @@ _evas_common_rgba_image_dirty(Image_Entry *ie_dst, const Image_Entry *ie_src)
    evas_common_rgba_image_scalecache_dirty((Image_Entry *)ie_src);
    evas_common_rgba_image_scalecache_dirty(ie_dst);
    evas_cache_image_load_data(&src->cache_entry);
-   if (_evas_common_rgba_image_surface_alloc(&dst->cache_entry,
-                                             src->cache_entry.w, src->cache_entry.h))
+   if (!evas_cache_image_pixels(ie_dst))
      {
+        if (_evas_common_rgba_image_surface_alloc(&dst->cache_entry,
+                                             src->cache_entry.w, src->cache_entry.h))
+          {
 #ifdef EVAS_CSERVE
-        if (ie_src->data1) evas_cserve_image_free((Image_Entry*) ie_src);
+            if (ie_src->data1) evas_cserve_image_free((Image_Entry*) ie_src);
 #endif
 #ifdef EVAS_CSERVE2
-        // if (ie_src->data1) evas_cserve2_image_free((Image_Entry*) ie_src);
-        if (ie_src->data1) ERR("Shouldn't reach this point since we are using cache2.");
+         // if (ie_src->data1) evas_cserve2_image_free((Image_Entry*) ie_src);
+            if (ie_src->data1) ERR("Shouldn't reach this point since we are using cache2.");
 #endif
-        return 1;
+            return 1;
+          }
      }
 
 #ifdef EVAS_CSERVE
@@ -594,7 +621,7 @@ evas_common_image_surface_alpha_tiles_calc(RGBA_Surface *is, int tsize)
    if (is->spans) return;
    if (!is->im->cache_entry.flags.alpha) return;
    /* FIXME: dont handle alpha only images yet */
-   if ((is->im->flags & RGBA_IMAGE_ALPHA_ONLY)) return;
+   if (is->im->space != EVAS_COLORSPACE_GRY8) return;
    if (tsize < 0) tsize = 0;
    is->spans = calloc(1, sizeof(RGBA_Image_Span *) * is->h);
    if (!is->spans) return;
@@ -713,6 +740,8 @@ evas_common_image_colorspace_normalize(RGBA_Image *im)
    switch (im->cache_entry.space)
      {
       case EVAS_COLORSPACE_ARGB8888:
+      case EVAS_COLORSPACE_GRY8:
+      case EVAS_COLORSPACE_AGRY88:
        if (im->image.data != im->cs.data)
          {
 #ifdef EVAS_CSERVE
@@ -952,7 +981,15 @@ evas_common_image_premul(Image_Entry *ie)
    if (!evas_cache_image_pixels(ie)) return ;
    if (!ie->flags.alpha) return;
 
-   nas = evas_common_convert_argb_premul(evas_cache_image_pixels(ie), ie->w * ie->h);
+   switch (ie->space)
+     {
+      case EVAS_COLORSPACE_ARGB8888:
+        nas = evas_common_convert_argb_premul(evas_cache_image_pixels(ie), ie->w * ie->h);
+        break;
+      case EVAS_COLORSPACE_AGRY88:
+        nas = evas_common_convert_ag_premul((void*) evas_cache_image_pixels(ie), ie->w * ie->h);
+      default: return;
+     }
    if ((ALPHA_SPARSE_INV_FRACTION * nas) >= (ie->w * ie->h))
      ie->flags.alpha_sparse = 1;
 }
index d7484c0..e858d53 100644 (file)
@@ -9,7 +9,8 @@
 
 
 int
-evas_common_save_image_to_file(RGBA_Image *im, const char *file, const char *key, int quality, int compress)
+evas_common_save_image_to_file(RGBA_Image *im, const char *file, const char *key,
+                               int quality, int compress, const char *encoding)
 {
    Evas_Image_Save_Func *evas_image_save_func = NULL;
    char *p;
@@ -30,6 +31,8 @@ evas_common_save_image_to_file(RGBA_Image *im, const char *file, const char *key
           saver = "eet";
        if (!strcasecmp(p, "edb"))
           saver = "edb";
+    if (!strcasecmp(p, "tgv"))
+      saver = "tgv";
      }
 
    if (saver)
@@ -42,8 +45,9 @@ evas_common_save_image_to_file(RGBA_Image *im, const char *file, const char *key
             evas_module_use(em);
             if (evas_module_load(em))
               {
-                 evas_image_save_func = em->functions;
-                 return evas_image_save_func->image_save(im, file, key, quality, compress);
+                  evas_image_save_func = em->functions;
+                  return evas_image_save_func->image_save(im, file, key, quality,
+                                                          compress, encoding);
               }
          }
      }
index 5a2d7a2..dc582db 100644 (file)
@@ -521,7 +521,7 @@ evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst,
  */
    if ((dst_region_w == 0) || (dst_region_h == 0) ||
        (src_region_w == 0) || (src_region_h == 0)) return;
-   LKL(im->cache.lock);
+
    if ((src_region_w == dst_region_w) && (src_region_h == dst_region_h))
      {
         if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
@@ -536,7 +536,6 @@ evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst,
        evas_common_image_colorspace_normalize(im);
 
 //        noscales++;
-        LKU(im->cache.lock);
         if (im->image.data)
           {
              evas_common_scale_rgba_in_to_out_clip_sample(im, dst, dc,
@@ -566,7 +565,6 @@ evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst,
        evas_common_image_colorspace_normalize(im);
 
 //        misses++;
-        LKU(im->cache.lock);
         if (im->image.data)
           {
              if (smooth)
@@ -584,6 +582,7 @@ evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst,
           }
         return;
      }
+   LKL(im->cache.lock);
    if (sci->populate_me)
      {
         int size, osize, used;
@@ -645,6 +644,7 @@ evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst,
                   ct = evas_common_draw_context_new();
                   evas_common_draw_context_set_render_op(ct, _EVAS_RENDER_COPY);
                }
+             LKU(im->cache.lock);
              if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
                {
 #ifdef EVAS_CSERVE2
@@ -654,6 +654,7 @@ evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst,
 #endif
                     evas_cache_image_load_data(&im->cache_entry);
                }
+             LKL(im->cache.lock);
              evas_common_image_colorspace_normalize(im);
              if (im->image.data)
                {
@@ -778,6 +779,7 @@ evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst,
      }
    else
      {
+        LKU(im->cache.lock);
         if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
           {
 #ifdef EVAS_CSERVE2
index 76417f5..a20d88e 100644 (file)
@@ -106,6 +106,7 @@ static void
 _evas_draw_point(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y)
 {
    RGBA_Gfx_Pt_Func pfunc;
+   DATA8 *mask = NULL;
 
    if (!IN_RANGE(x, y, dst->cache_entry.w, dst->cache_entry.h))
        return;
@@ -125,9 +126,27 @@ _evas_draw_point(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y)
 # endif     
 #endif
      {
-        pfunc = evas_common_gfx_func_composite_color_pt_get(dc->col.col, dst, dc->render_op);
-        if (pfunc)
-          pfunc(0, 255, dc->col.col, dst->image.data + (dst->cache_entry.w * y) + x);
+        //pfunc = evas_common_gfx_func_composite_color_pt_get(dc->col.col, dst, dc->render_op);
+        //if (pfunc)
+          //pfunc(0, 255, dc->col.col, dst->image.data + (dst->cache_entry.w * y) + x);
+
+        if (dc->clip.mask)
+          {
+             RGBA_Image *im = dc->clip.mask;
+             mask = im->image.data8
+                + (y - dc->clip.mask_y) * im->cache_entry.w
+                + (x - dc->clip.mask_x);
+             pfunc = evas_common_gfx_func_composite_mask_color_pt_get(dc->col.col, dst, dc->render_op);
+             if (pfunc)
+               pfunc(0, *mask, dc->col.col, dst->image.data + (dst->cache_entry.w * y) + x);
+          }
+        else
+          {
+             pfunc = evas_common_gfx_func_composite_color_pt_get(dc->col.col, dst, dc->render_op);
+             if (pfunc)
+               pfunc(0, 255, dc->col.col, dst->image.data + (dst->cache_entry.w * y) + x);
+          }
+
      }
 }
 
@@ -142,8 +161,9 @@ _evas_draw_simple_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, i
 {
    int     dx, dy, len, lx, ty, rx, by;
    int     clx, cly, clw, clh;
-   int     dstw;
+   int     dstw, mask_w = 0;
    DATA32  *p, color;
+   DATA8   *mask = NULL;
    RGBA_Gfx_Pt_Func pfunc;
    RGBA_Gfx_Func    sfunc;
 
@@ -210,15 +230,30 @@ _evas_draw_simple_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, i
 # endif
 #endif
                {
-                  sfunc = evas_common_gfx_func_composite_color_span_get(color, dst, len, dc->render_op);
-                  if (sfunc)
-                    sfunc(NULL, NULL, color, p, len);
+                  if (dc->clip.mask)
+                    {
+                       RGBA_Image *im = dc->clip.mask;
+                       mask = im->image.data8
+                          + ((y0 - dc->clip.mask_y) * im->cache_entry.w)
+                          + (x0 - dc->clip.mask_x);
+                       sfunc = evas_common_gfx_func_composite_mask_color_span_get(color, dst, len, dc->render_op);
+                       if (sfunc) sfunc(NULL, mask, color, p, len);
+                    }
+                  else
+                    {
+                       sfunc = evas_common_gfx_func_composite_color_span_get(color, dst, len, dc->render_op);
+                       if (sfunc)
+                         sfunc(NULL, NULL, color, p, len);
+                    }
                }
           }
         return;
      }
 
-   pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst, dc->render_op);
+   if (dc->clip.mask)
+     pfunc = evas_common_gfx_func_composite_mask_color_pt_get(color, dst, dc->render_op);
+   else
+     pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst, dc->render_op);
    if (!pfunc) return;
 
    if (dx == 0)
@@ -246,10 +281,27 @@ _evas_draw_simple_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, i
 # endif
 #endif
                {
-                  while (len--)
+                  if (dc->clip.mask)
+                    {
+                       RGBA_Image *im = dc->clip.mask;
+                       mask_w = im->cache_entry.w;
+                       mask = im->image.data8
+                          + ((y0 - dc->clip.mask_y) * mask_w)
+                          + (x0 - dc->clip.mask_x);
+                       while (len--)
+                         {
+                            pfunc(0, *mask, color, p);
+                            p += dstw;
+                            mask += mask_w;
+                         }
+                    }
+                  else
                     {
-                       pfunc(0, 255, color, p);
-                       p += dstw;
+                       while (len--)
+                         {
+                            pfunc(0, 255, color, p);
+                            p += dstw;
+                         }
                     }
                }
           }
@@ -323,6 +375,16 @@ _evas_draw_simple_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, i
              len = y1 - y0 + 1;
              if (dx > 0)  dstw++;
              else  dstw--;
+             if (dc->clip.mask)
+               {
+                  RGBA_Image *im = dc->clip.mask;
+                  mask_w = im->cache_entry.w;
+                  mask = im->image.data8
+                     + ((y0 - dc->clip.mask_y) * mask_w)
+                     + (x0 - dc->clip.mask_x);
+                  if (dx > 0) mask_w++;
+                  else mask_w--;
+               }
           }
         else
           {
@@ -330,6 +392,16 @@ _evas_draw_simple_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, i
              p = dst->image.data + (dstw * y1) + x1;
              if (dx > 0)  dstw--;
              else  dstw++;
+             if (dc->clip.mask)
+               {
+                  RGBA_Image *im = dc->clip.mask;
+                  mask_w = im->cache_entry.w;
+                  mask = im->image.data8
+                     + ((y1 - dc->clip.mask_y) * mask_w)
+                     + (x1 - dc->clip.mask_x);
+                  if (dx > 0) mask_w--;
+                  else mask_w++;
+               }
           }
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_LINE        
@@ -362,7 +434,15 @@ _evas_draw_simple_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, i
              else
 # endif
 #endif
-               pfunc(0, 255, color, p);
+               {
+                  if (mask)
+                    {
+                       pfunc(0, *mask, color, p);
+                       mask += mask_w;
+                    }
+                  else
+                    pfunc(0, 255, color, p);
+               }
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_LINE             
              pixman_x_position += x_unit;
@@ -527,8 +607,9 @@ _evas_draw_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1,
    int     dx, dy, rx, by, p0_in, p1_in, dh, a_a = 0;
    int     delx, dely, xx, yy, dxx, dyy;
    int     clx, cly, clw, clh;
-   int     dstw;
+   int     dstw, mask_w = 0;
    DATA32  *p, *data, color;
+   DATA8   *mask = NULL;
    RGBA_Gfx_Pt_Func pfunc;
 
    dx = x1 - x0;
@@ -566,7 +647,10 @@ _evas_draw_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1,
      }
 
    color = dc->col.col;
-   pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst, dc->render_op);
+   if (dc->clip.mask)
+     pfunc = evas_common_gfx_func_composite_mask_color_pt_get(color, dst, dc->render_op);
+   else
+     pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst, dc->render_op);
    if (!pfunc) return;
 
    clx = dc->clip.x;
@@ -583,11 +667,20 @@ _evas_draw_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1,
    x1 -= clx;
    y1 -= cly;
 
+   if (dc->clip.mask)
+     {
+        RGBA_Image *im = dc->clip.mask;
+        mask_w = im->cache_entry.w;
+        mask = im->image.data8
+           + ((cly - dc->clip.mask_y) * mask_w) + (clx - dc->clip.mask_x);
+     }
+
    /* shallow: x-parametric */
    if ((dy < dx) || (dy < -dx))
      {
        SETUP_LINE_SHALLOW;
 
+        if (mask) mask += (py * mask_w) + px;
        while (px < rx)
          {
            y = (yy >> 16);
@@ -596,6 +689,7 @@ _evas_draw_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1,
              {
                prev_y = y;
                p += dh;
+                if (mask) mask += mask_w;
                py += dely;
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_LINE                 
@@ -630,15 +724,19 @@ _evas_draw_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1,
                                           pix_x, pix_y, 0, 0,
                                           pix_x, pix_y, 1, 1);
                  else
-# endif                         
+# endif
 #endif
-                   pfunc(0, 255, color, p);
+                   {
+                      if (mask) pfunc(0, *mask, color, p);
+                      else pfunc(0, 255, color, p);
+                   }
               }
 
 next_x:
             yy += dyy;
             px++;
             p++;
+            if (mask) mask++;
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_LINE             
             pix_x += pix_x_unit;
@@ -651,6 +749,7 @@ next_x:
    /* steep: y-parametric */
 
    SETUP_LINE_STEEP;
+   if (mask) mask += (py * mask_w) + px;
 
    while (py < by)
      {
@@ -661,6 +760,7 @@ next_x:
              prev_x = x;
              px += delx;
              p += delx;
+             if (mask) mask += delx;
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_LINE
              pix_x += pix_x_unit;
@@ -694,18 +794,22 @@ next_x:
                                       pix_x, pix_y, 0, 0,
                                       pix_x, pix_y, 1, 1);
              else
-# endif                    
+# endif
 #endif
-               pfunc(0, 255, color, p);
+               {
+                  if (mask) pfunc(0, *mask, color, p);
+                  else pfunc(0, 255, color, p);
+               }
           }
 next_y:
        xx += dxx;
        py++;
        p += dstw;
+        if (mask) mask += mask_w;
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_LINE        
         pix_y += pix_y_unit;
-# endif        
+# endif
 #endif
      }
 }
@@ -718,8 +822,9 @@ _evas_draw_line_aa(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x
    int     dx, dy, rx, by, p0_in, p1_in, dh, a_a = 1;
    int     delx, dely, xx, yy, dxx, dyy;
    int     clx, cly, clw, clh;
-   int     dstw;
+   int     dstw, mask_w = 0;
    DATA32  *p, *data, color;
+   DATA8   *mask = NULL;
    RGBA_Gfx_Pt_Func pfunc;
 
    dx = x1 - x0;
@@ -782,11 +887,20 @@ _evas_draw_line_aa(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x
    x1 -= clx;
    y1 -= cly;
 
+   if (dc->clip.mask)
+     {
+        RGBA_Image *im = dc->clip.mask;
+        mask_w = im->cache_entry.w;
+        mask = im->image.data8
+           + ((cly - dc->clip.mask_y) * mask_w) + (clx - dc->clip.mask_x);
+     }
+
    /* shallow: x-parametric */
    if ((dy < dx) || (dy < -dx))
      {
        SETUP_LINE_SHALLOW;
 
+        if (mask) mask += (py * mask_w) + px;
        while (px < rx)
          {
            DATA8   aa;
@@ -796,11 +910,12 @@ _evas_draw_line_aa(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x
              {
                  prev_y = y;
                  p += dh;
+                 if (mask) mask += mask_w;
                  py += dely;
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_LINE                 
                  pix_y += pix_y_unit;
-# endif                 
+# endif
 #endif
              }
            if (!p1_in)
@@ -822,7 +937,7 @@ _evas_draw_line_aa(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x
                       alpha_data_buffer = 255 - aa;
                       aa_mask_image = pixman_image_create_bits(PIXMAN_a8, 1, 1,
                                                                (uint32_t *)&alpha_data_buffer, 4);
-                      
+
                       if ((dst->pixman.im) && (dc->col.pixman_color_image ) &&
                           (!dc->mask.mask))
                         pixman_image_composite(PIXMAN_OP_OVER,
@@ -840,7 +955,10 @@ _evas_draw_line_aa(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x
                       else
 # endif
 #endif
-                        pfunc(0, 255 - aa, color, p);
+                        {
+                           if (mask) pfunc(0, (255 - aa) * (*mask) / 255, color, p);
+                           else pfunc(0, 255 - aa, color, p);
+                        }
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_LINE                       
                       pixman_image_unref(aa_mask_image);
@@ -872,7 +990,10 @@ _evas_draw_line_aa(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x
                       else
 # endif
 #endif
-                        pfunc(0, aa, color, p + dstw);
+                        {
+                           if (mask) pfunc(0, aa * (*(mask + mask_w)) / 255, color, p + dstw);
+                           else pfunc(0, aa, color, p + dstw);
+                        }
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_LINE                       
                       pixman_image_unref(aa_mask_image);
@@ -885,6 +1006,7 @@ next_x:
              yy += dyy;
              px++;
              p++;
+             if (mask) mask++;
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_LINE                       
              pix_x += pix_x_unit;
@@ -896,6 +1018,7 @@ next_x:
    
    /* steep: y-parametric */
    SETUP_LINE_STEEP;
+   if (mask) mask += (py * mask_w) + px;
 
    while (py < by)
      {
@@ -907,6 +1030,7 @@ next_x:
              prev_x = x;
              px += delx;
              p += delx;
+             if (mask) mask += delx;
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_LINE
              pix_x += pix_x_unit;
@@ -949,7 +1073,10 @@ next_x:
                   else
 # endif
 #endif
-                    pfunc(0, 255 - aa, color, p);
+                    {
+                       if (mask) pfunc(0, (255 - aa) * (*mask) / 255, color, p);
+                       else pfunc(0, 255 - aa, color, p);
+                    }
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_LINE
                   pixman_image_unref(aa_mask_image);
@@ -982,7 +1109,10 @@ next_x:
                   else
 # endif
 #endif
-                    pfunc(0, aa, color, p + 1);
+                    {
+                       if (mask) pfunc(0, aa * (*(mask + 1)) / 255, color, p + 1);
+                       else pfunc(0, aa, color, p + 1);
+                    }
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_LINE
                   pixman_image_unref(aa_mask_image);
@@ -994,6 +1124,7 @@ next_x:
        xx += dxx;
        py++;
        p += dstw;
+        if (mask) mask += mask_w;
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_LINE
         pix_y += pix_y_unit;
index 776820f..ab9b684 100644 (file)
@@ -86,10 +86,10 @@ _limit(Span *s, int c1, int c2, int nocol)
 static void
 _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy __UNUSED__, int cw, int ch __UNUSED__)
 {
-   int i, y, yp, yy;
+   int i, y, yp;
    int py[4];
    int edge[4][4], edge_num, swapped, order[4];
-   FPc uv[4][2], u, v, x, h, t, uu, vv;
+   FPc uv[4][2], u, v, x, h, t;
    DATA32 col[4];
    
 #if 1 // maybe faster on x86?
@@ -170,10 +170,11 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
              int e1 = edge[i][0];
              int e2 = edge[i][1];
              FPc t256;
-             
+
              h = (p[e2].y - p[e1].y) >> FP; // height of edge
              if (h < 1) h = 1;
-             t = (((y << FP) + (FP1 / 2) - 1) - p[e1].y) >> FP;
+             //t = (((y << FP) + (FP1 - 2) - 1) - p[e1].y) >> FP;
+             t = (((y << FP) + (FP1 - 1)) - p[e1].y ) >> FP;
              x = p[e2].x - p[e1].x;
              x = p[e1].x + ((x * t) / h);
 
@@ -222,8 +223,10 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
                   pt = t;
                   t = ((z1 - zt) * hf) / dz;
                }
- */
+*/
              u = p[e2].u - p[e1].u;
+             u = p[e1].u + ((u * t) / h);
+/*
              uu = u >> FP;
              if (uu < 0) uu = -uu;
              if (uu == h)
@@ -241,8 +244,10 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
                   else
                      u = p[e1].u + (((u * t) - (FP1 / 2)) / h);
                }
-             
+*/
              v = p[e2].v - p[e1].v;
+             v = p[e1].v + ((v * t) / h);
+/*
              vv = v >> FP;
              if (vv < 0) vv = -vv;
              if (vv == h)
@@ -260,7 +265,7 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
                   else
                      v = p[e1].v + (((v * t) - (FP1 / 2)) / h);
                }
-
+*/
              // FIXME: 3d accuracy for color too
              t256 = (t << 8) / h; // maybe * 255?
              col[i] = INTERP_256(t256, p[e2].col, p[e1].col);
@@ -565,7 +570,7 @@ evas_common_map_rgba_prepare(RGBA_Image *src, RGBA_Image *dst,
                              RGBA_Map *m)
 {
    RGBA_Map_Cutout *spans;
-   Cutout_Rects *rects;
+   Cutout_Rects *rects = NULL;
    Cutout_Rect *r;
    int i;
 
@@ -604,10 +609,6 @@ evas_common_map_rgba_prepare(RGBA_Image *src, RGBA_Image *dst,
         rects = spans->rects;
         spans->rects = NULL;
      }
-   else
-     {
-        rects = evas_common_draw_context_cutouts_new();
-     }
    rects = evas_common_draw_context_apply_cutouts(dc, rects);
    _rgba_map_cutout_resize(m, rects->active);
 
@@ -648,6 +649,17 @@ evas_common_map_rgba_prepare(RGBA_Image *src, RGBA_Image *dst,
 #  undef SCALE_USING_MMX
 #  include "evas_map_image_internal.c"
 # endif
+# ifdef BUILD_NEON
+#  undef FUNC_NAME
+#  undef FUNC_NAME_DO
+#  define FUNC_NAME evas_common_map_rgba_internal_neon
+#  define FUNC_NAME_DO evas_common_map_rgba_internal_neon_do
+#  undef SCALE_USING_NEON
+#  define SCALE_USING_NEON
+#  undef SCALE_USING_MMX
+#  include "evas_map_image_internal.c"
+#  undef SCALE_USING_NEON
+# endif
 #endif
 
 EAPI void
@@ -685,6 +697,11 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst,
           evas_common_map_rgba_internal_mmx(src, dst, dc, p, smooth, level);
         else
 #endif
+#ifdef BUILD_NEON
+        if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+          evas_common_map_rgba_internal_neon(src, dst, dc, p, smooth, level);
+        else
+#endif
 #ifdef BUILD_C
           evas_common_map_rgba_internal(src, dst, dc, p, smooth, level);
 #endif
@@ -709,6 +726,11 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst,
           evas_common_map_rgba_internal_mmx(src, dst, dc, p, smooth, level);
         else
 #endif
+#ifdef BUILD_NEON
+        if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+          evas_common_map_rgba_internal_neon(src, dst, dc, p, smooth, level);
+        else
+#endif
 #ifdef BUILD_C
           evas_common_map_rgba_internal(src, dst, dc, p, smooth, level);
 #endif        
@@ -749,6 +771,12 @@ evas_common_map_rgba_do(const Eina_Rectangle *clip,
                                                &spans->spans[0], smooth, level);
         else
 #endif
+#ifdef BUILD_NEON
+        if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+          evas_common_map_rgba_internal_neon_do(src, dst, dc,
+                                               &spans->spans[0], smooth, level);
+        else
+#endif
 #ifdef BUILD_C
           evas_common_map_rgba_internal_do(src, dst, dc,
                                            &spans->spans[0], smooth, level);
@@ -769,6 +797,12 @@ evas_common_map_rgba_do(const Eina_Rectangle *clip,
                                                &spans->spans[i], smooth, level);
         else
 #endif
+#ifdef BUILD_NEON
+        if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+          evas_common_map_rgba_internal_neon_do(src, dst, dc,
+                                               &spans->spans[i], smooth, level);
+        else
+#endif
 #ifdef BUILD_C
           evas_common_map_rgba_internal_do(src, dst, dc,
                                            &spans->spans[i], smooth, level);
index b9bbeb5..6a388ae 100644 (file)
@@ -1,5 +1,7 @@
 //#undef SCALE_USING_MMX
 {
+   DATA8 *mask;
+   RGBA_Image *mask_ie;
    if (smooth)
      {
         for (y = ystart; y <= yend; y++)
@@ -7,36 +9,36 @@
              int x, w, ww;
              FPc u, v, ud, vd, dv, ue, ve;
              DATA32 *d, *s;
-#ifdef COLMUL             
+#ifdef COLMUL
              FPc cv, cd; // col
 # ifdef SCALE_USING_MMX
              FPc cc;
-#endif             
+#endif
              DATA32 c1, c2; // col
-#endif             
+#endif
              Line *line;
-             
+
 #ifdef SCALE_USING_MMX
              pxor_r2r(mm0, mm0);
              MOV_A2R(ALPHA_255, mm5)
 #endif
-               
+
              line = &(spans[y - ystart]);
              for (i = 0; i < 2; i++)
                {
                   Span *span;
-                  
+
                   span = &(line->span[i]);
                   if (span->x1 >= 0)
                     {
                        long long tl;
-                       
+
                        x = span->x1;
                        w = (span->x2 - x);
                        if (w <= 0) continue;
                        dv = (span->o2 - span->o1);
                        if (dv <= 0) continue;
-                       
+
                        ww = w;
                        u = span->u[0] << FPI;
                        if (u < 0) u = 0;
@@ -56,7 +58,7 @@
                        tl = tl / dv;
                        ud = tl;
                        u -= (ud * (span->o1 - (span->x1 << FP))) / FP1;
-                       
+
                        tl = (long long)vd * (w << FP);
                        tl = tl / dv;
                        vd = tl;
                        else
                          d = buf;
 
-#define SMOOTH 1                       
-#ifdef COLMUL             
+#define SMOOTH 1
+#ifdef COLMUL
                        c1 = span->col[0]; // col
                        c2 = span->col[1]; // col
                        cv = 0; // col
                        cd = (255 << 16) / w; // col
-                       
+
                        if (c1 == c2)
                          {
                             if (c1 == 0xffffffff)
                               {
-#endif                         
+#endif
+#define COLSAME 1
 #include "evas_map_image_loop.c"
-#ifdef COLMUL             
+#undef COLSAME
+#ifdef COLMUL
                               }
                             else if ((c1 == 0x0000ff) && (!src->cache_entry.flags.alpha))
                               {
                                  // all black line
 # define COLBLACK 1
+# define COLSAME 1
 # include "evas_map_image_loop.c"
-# undef COLBLACK                                 
+# undef COLSAME
+# undef COLBLACK
                               }
                             else if (c1 == 0x000000)
                               {
                             else
                               {
                                  // generic loop
+# define COLSAME 1
 # include "evas_map_image_loop.c"
+# undef COLSAME
                               }
                          }
                        else
                          {
 # include "evas_map_image_loop.c"
                          }
-#endif                         
+#endif
                        if (!direct)
                          {
                             d = dst->image.data;
                             d += (y * dst->cache_entry.w) + x;
-                            func(buf, NULL, dc->mul.col, d, w);
+                            if (!dc->clip.mask)
+                              func(buf, NULL, dc->mul.col, d, w);
+                            else
+                              {
+                                 mask_ie = dc->clip.mask;
+                                 mask = mask_ie->image.data8
+                                    + (y - dc->clip.mask_y) * mask_ie->cache_entry.w
+                                    + (x - dc->clip.mask_x);
+                                 if (dc->mul.use) func2(buf, NULL, dc->mul.col, buf, w);
+                                 func(buf, mask, 0, d, w);
+                              }
                          }
                     }
                   else break;
 #ifdef COLMUL
              FPc cv, cd; // col
              DATA32 c1, c2; // col
-#endif             
+#endif
              Line *line;
-             
+
              line = &(spans[y - ystart]);
              for (i = 0; i < 2; i++)
                {
                   Span *span;
-                  
+
                   span = &(line->span[i]);
                   if (span->x1 >= 0)
                     {
                        x = span->x1;
                        w = (span->x2 - x);
-                       
+
                        if (w <= 0) continue;
                        ww = w;
                        u = span->u[0] << FPI;
                          {
                             if (c1 == 0xffffffff)
                               {
-#endif                                 
+#endif
+#define COLSAME 1
 #include "evas_map_image_loop.c"
+#undef COLSAME
 #ifdef COLMUL
                               }
                             else if ((c1 == 0x0000ff) && (!src->cache_entry.flags.alpha))
                               {
                                  // all black line
 # define COLBLACK 1
+# define COLSAME 1
 # include "evas_map_image_loop.c"
-# undef COLBLACK                                 
+# undef COLSAME
+# undef COLBLACK
                               }
                             else if (c1 == 0x000000)
                               {
                             else
                               {
                                  // generic loop
+# define COLSAME 1
 # include "evas_map_image_loop.c"
+# undef COLSAME
                               }
                          }
                        else
                             // generic loop
 # include "evas_map_image_loop.c"
                          }
-#endif                       
+#endif
                        if (!direct)
                          {
                             d = dst->image.data;
                             d += (y * dst->cache_entry.w) + x;
-                            func(buf, NULL, dc->mul.col, d, w);
+                            if (!dc->clip.mask)
+                              func(buf, NULL, dc->mul.col, d, w);
+                            else
+                              {
+                                 mask_ie = dc->clip.mask;
+                                 mask = mask_ie->image.data8
+                                    + (y - dc->clip.mask_y) * mask_ie->cache_entry.w
+                                    + (x - dc->clip.mask_x);
+                                 if (dc->mul.use) func2(buf, NULL, dc->mul.col, buf, w);
+                                 func(buf, mask, 0, d, w);
+                              }
                          }
                     }
                   else break;
index 8f4660f..7c5811b 100644 (file)
@@ -10,7 +10,7 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
    int ytop, ybottom, ystart, yend, y, sw, shp, swp, direct;
    Line *spans;
    DATA32 *buf = NULL, *sp;
-   RGBA_Gfx_Func func = NULL;
+   RGBA_Gfx_Func func = NULL, func2 = NULL;
    int havea = 0;
    int havecol = 4;
 
@@ -84,27 +84,37 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
    // if operation is solid, bypass buf and draw func and draw direct to dst
    direct = 0;
    if ((!src->cache_entry.flags.alpha) && (!dst->cache_entry.flags.alpha) &&
-       (!dc->mul.use) && (!havea))
+       (!dc->mul.use) && (!havea) && (!dc->clip.mask))
      {
         direct = 1;
      }
    else
      {
         int pa;
-        
+
         buf = alloca(cw * sizeof(DATA32));
         pa = src->cache_entry.flags.alpha;
         if (havea) src->cache_entry.flags.alpha = 1;
-        if (dc->mul.use)
-          func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, cw, dc->render_op);
+
+        if (!dc->clip.mask)
+          {
+             if (dc->mul.use)
+               func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, cw, dc->render_op);
+             else
+               func = evas_common_gfx_func_composite_pixel_span_get(src, dst, cw, dc->render_op);
+          }
         else
-          func = evas_common_gfx_func_composite_pixel_span_get(src, dst, cw, dc->render_op);
+          {
+             func = evas_common_gfx_func_composite_pixel_mask_span_get(src, dst, cw, dc->render_op);
+             if (dc->mul.use)
+               func2 = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, cw, EVAS_RENDER_COPY);
+          }
         src->cache_entry.flags.alpha = pa;
      }
-    
+
    if (!havecol)
      {
-#undef COLMUL     
+#undef COLMUL
 #include "evas_map_image_core.c"
      }
    else
@@ -122,7 +132,7 @@ FUNC_NAME_DO(RGBA_Image *src, RGBA_Image *dst,
 {
    Line *spans;
    DATA32 *buf = NULL, *sp;
-   RGBA_Gfx_Func func = NULL;
+   RGBA_Gfx_Func func = NULL, func2 = NULL;
    int cx, cy, cw, ch;
    int ystart, yend, y, sw, shp, swp, direct;
    int havecol;
@@ -160,16 +170,26 @@ FUNC_NAME_DO(RGBA_Image *src, RGBA_Image *dst,
         buf = alloca(cw * sizeof(DATA32));
         pa = src->cache_entry.flags.alpha;
         if (ms->havea) src->cache_entry.flags.alpha = 1;
-        if (dc->mul.use)
-          func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, cw, dc->render_op);
+
+        if (!dc->clip.mask)
+          {
+             if (dc->mul.use)
+               func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, cw, dc->render_op);
+             else
+               func = evas_common_gfx_func_composite_pixel_span_get(src, dst, cw, dc->render_op);
+          }
         else
-          func = evas_common_gfx_func_composite_pixel_span_get(src, dst, cw, dc->render_op);
+          {
+             func = evas_common_gfx_func_composite_pixel_mask_span_get(src, dst, cw, dc->render_op);
+             if (dc->mul.use)
+               func2 = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, cw, EVAS_RENDER_COPY);
+          }
         src->cache_entry.flags.alpha = pa;
      }
-    
+
    if (!havecol)
      {
-#undef COLMUL     
+#undef COLMUL
 #include "evas_map_image_core.c"
      }
    else
index c434386..8315ac7 100644 (file)
@@ -1,5 +1,32 @@
 #ifdef SMOOTH
 {
+# ifdef SCALE_USING_MMX
+#   ifdef COLMUL
+#    ifdef COLSAME
+   MOV_P2R(c1, mm7, mm0); // col
+#    endif   
+#   endif   
+#  endif   
+# ifdef SCALE_USING_NEON
+   FPU_NEON;
+   VMOV_I2R_NEON(q2, #255);
+#  ifndef COLBLACK
+#   ifdef COLMUL
+   // this part can be done here as c1 and c2 are constants in the cycle
+   FPU_NEON;
+   VMOV_M2R_NEON(d18, c1);
+   VEOR_NEON(q8);
+#    ifndef COLSAME
+   VMOV_M2R_NEON(d19, c2);
+#    endif
+   VZIP_NEON(q9, q8);
+#    ifndef COLSAME
+   VMOV_R2R_NEON(d19, d16);
+#    endif
+   // here we have c1 and c2 spread through q9 register
+#   endif
+#  endif
+# endif
    while (ww > 0)
      {
 # ifdef COLBLACK
           }
         INTERP_256_R2R(mm4, mm2, mm1, mm5);
 #   ifdef COLMUL
+#    ifdef COLSAME
+//        MOV_P2R(c1, mm7, mm0); // col
+        MUL4_SYM_R2R(mm7, mm1, mm5); // col
+#    else        
         cc = cv >> 16; // col
         cv += cd; // col
         MOV_A2R(cc, mm2); // col
         MOV_P2R(c2, mm4, mm0); // col
         INTERP_256_R2R(mm2, mm4, mm3, mm5); // col
         MUL4_SYM_R2R(mm3, mm1, mm5); // col
+#    endif        
 #   endif                            
         MOV_R2P(mm1, *d, mm0);
+#  elif defined SCALE_USING_NEON
+        // not sure if we need this condition, but it doesn't affect the result
+        if (val1 | val2 | val3 | val4)
+          {
+            FPU_NEON;
+#   ifdef COLMUL
+            // initialize alpha for interpolation of c1 and c2
+            VDUP_NEON(d15, cv >> 16);
+            // copy c1 and c2 as algorithm will overwrite it
+            VMOV_R2R_NEON(q6, q9);
+            cv += cd; // col
+#   endif
+            VMOV_M2R_NEON(d8, val1);
+            VEOR_NEON(q0);
+            VMOV_M2R_NEON(d9, val3);
+            VMOV_M2R_NEON(d10, val2);
+            VEOR_NEON(q1);
+            VMOV_M2R_NEON(d11, val4);
+            VDUP_NEON(q3, ru);
+            VDUP_NEON(d14, rv);
+            VZIP_NEON(q4, q0);
+            VZIP_NEON(q5, q1);
+            VMOV_R2R_NEON(d9, d0);
+            VMOV_R2R_NEON(d11, d2);
+            // by this point we have all required data in right registers
+            INTERP_256_NEON(q3, q5, q4, q2); // interpolate val1,val2 and val3,val4
+#   ifdef COLMUL
+#    ifdef COLSAME
+            INTERP_256_NEON(d14, d9, d8, d4);
+#    else
+            VSWP_NEON(d9, d12); // move result of val3,val4 interpolation (and c1 if COLMUL is defined) for next step
+            INTERP_256_NEON(q7, q6, q4, q2); // second stage of interpolation, also here c1 and c2 are interpolated
+#    endif
+#   else
+            INTERP_256_NEON(d14, d9, d8, d4);
+#   endif
+#   ifdef COLMUL
+#    ifdef COLSAME
+            MUL4_SYM_NEON(d8, d12, d4);
+#    else
+            MUL4_SYM_NEON(d8, d9, d4); // do required multiplication
+#    endif
+#   endif
+            VMOV_R2M_NEON(q4, d8, d); // save result to d
+          }
+        else
+          *d = val1;
 #  else
         val1 = INTERP_256(ru, val2, val1);
         val3 = INTERP_256(ru, val4, val3);
         val1 = INTERP_256(rv, val3, val1); // col
 #   ifdef COLMUL                            
+#   ifdef COLSAME
+        *d = MUL4_SYM(c1, val1);
+#   else        
         val2 = INTERP_256((cv >> 16), c2, c1); // col
         *d   = MUL4_SYM(val2, val1); // col
         cv += cd; // col
+#   endif
 #   else                            
         *d   = INTERP_256(rv, val3, val1);
 #   endif
 }
 #else
 {
+# ifdef SCALE_USING_NEON
+#  ifndef COLBLACK
+#   ifdef COLMUL
+#    ifdef COLSAME
+   FPU_NEON;
+   VMOV_I2R_NEON(q2, #255);
+   VMOV_M2R_NEON(d10, c1);
+   VEOR_NEON(d0);
+   VZIP_NEON(d10, d0);
+#    else
+   // c1 and c2 are constants inside the cycle
+   FPU_NEON;
+   VMOV_I2R_NEON(q2, #255);
+   VMOV_M2R_NEON(d10, c1);
+   VEOR_NEON(q0);
+   VMOV_M2R_NEON(d11, c2);
+   VZIP_NEON(q5, q0);
+   VMOV_R2R_NEON(d11, d0);
+#    endif
+#   endif
+#  endif
+# endif
    while (ww > 0)
      {
 # ifdef COLMUL
 #  ifndef COLBLACK        
-        DATA32 val1, cval; // col
+        DATA32 val1;
+#   ifdef COLSAME
+#   else        
+        DATA32 cval; // col
+#   endif        
 #  endif
 # endif
 # ifdef COLBLACK
           (u >> (FP + FPI));
 #  ifdef COLMUL
         val1 = *s; // col
+#   ifdef COLSAME
+#    ifdef SCALE_USING_NEON
+        VMOV_M2R_NEON(d1, val1);
+        VEOR_NEON(d0);
+        VZIP_NEON(d1, d0);
+        VMOV_R2R_NEON(d0, d10);
+        MUL4_SYM_NEON(d0, d1, d4)
+        VMOV_R2M_NEON(q0, d0, d);
+#    else
+        *d = MUL4_SYM(c1, val1);
+#    endif
+#   else        
+#    ifdef SCALE_USING_NEON
+        FPU_NEON;
+        VMOV_M2R_NEON(d12, val1);
+        VMOV_R2R_NEON(q4, q5);
+        VEOR_NEON(q1);
+        VDUP_NEON(d15, cv >> 16);
+        VZIP_NEON(q6, q1);
+        INTERP_256_NEON(d15, d9, d8, d4); // interpolate c1 and c2
+        MUL4_SYM_NEON(d8, d12, d4); // multiply
+        VMOV_R2M_NEON(q4, d8, d); // save result
+#    else
         cval = INTERP_256((cv >> 16), c2, c1); // col
         *d = MUL4_SYM(cval, val1);
+#    endif
         cv += cd; // col              
+#   endif        
 #  else
         *d = *s;
 #  endif
index 77435c4..d7b5861 100644 (file)
@@ -40,7 +40,7 @@ libevas_engine_common_op_blend_master_sse3_la_CFLAGS = \
 @FREETYPE_CFLAGS@ @VALGRIND_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @EET_CFLAGS@ @pthread_cflags@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ @HARFBUZZ_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @EVAS_SSE3_CFLAGS@
index 12a0a75..76f6370 100644 (file)
@@ -77,7 +77,7 @@ init_blend_mask_color_span_funcs_c(void)
 static void
 _op_blend_pt_mas_c_dp(DATA32 s, DATA8 m, DATA32 c, DATA32 *d) {
    s = MUL_SYM(m, c);
-   m = 256 - (s >> 24);
+   m = 255 - (s >> 24);
    *d = s + MUL_256(m, *d);
 }
 
old mode 100644 (file)
new mode 100755 (executable)
index f5eb480..dfc64d1
 #ifdef BUILD_NEON
 static void
 _op_blend_mas_c_dp_neon(DATA32 *s __UNUSED__, DATA8 *m, DATA32 c, DATA32 *d, int l) {
-   DATA32 *e;
-
-   DEBUG_FNCOUNT("");
-
-#define AP "blend_mas_c_dp_"
-     asm volatile (
-       ".fpu neon                                              \n\t"
-       "       vdup.i32        q15, %[c]                       \n\t"
-       "       vmov.i8         q14,    #1                      \n\t"
-
-               // If aligned already - straight to quads
-       "       andS            %[tmp], %[d],$0xf               \n\t"
-       "       beq             "AP"quadloops                   \n\t"
-
-       "       andS            %[tmp], %[d],$0x4               \n\t"
-       "       beq             "AP"dualloop                    \n\t"
-
-       AP"singleloop:                                          \n\t"
-       "       vld1.8          d0[0],  [%[m]]!                 \n\t"
-       "       vld1.32         d4[0],  [%[d]]                  \n\t"
-       "       vdup.u8         d0,     d0[0]                   \n\t"
-       "       vmull.u8        q4,     d0, d30                 \n\t"
-       "       vqrshrn.u16     d12,    q4, #8                  \n\t"
-       "       vmvn.u16        d14,    d12                     \n\t"
-       "       vshr.u32        d16,    d14, #24                \n\t"
-       "       vmul.u32        d16,    d16, d28                \n\t"
-       "       vmull.u8        q7,     d16, d4                 \n\t"
-       "       vqrshrn.u16     d0,     q7, #8                  \n\t"
-       "       vqadd.u8        d0,     d0, d12                 \n\t"
-       "       vst1.32         d0[0],  [%[d]]!                 \n\t"
-
-               // Can we go the fast path?
-       "       andS            %[tmp], %[d],$0xf               \n\t"
-       "       beq             "AP"quadloops                   \n\t"
-
-       AP"dualloop:                                            \n\t"
-       "       sub             %[tmp], %[e], %[d]              \n\t"
-       "       cmp             %[tmp], #16                     \n\t"
-       "       blt             "AP"loopout                     \n\t"
-
-       "       vld1.16         d0[0],  [%[m]]!                 \n\t"
-       "       vldm            %[d],   {d4}                    \n\t"
-       "       vmovl.u8        q0,     d0                      \n\t"
-       "       vmovl.u8        q0,     d0                      \n\t"
-       "       vmul.u32        q0,     q14                     \n\t"
-       "       vmull.u8        q4,     d0, d30                 \n\t"
-       "       vqrshrn.u16     d12,    q4, #8                  \n\t"
-       "       vmvn.u16        d14,    d12                     \n\t"
-       "       vshr.u32        d16,    d14, #24                \n\t"
-       "       vmul.u32        d16,    d16, d28                \n\t"
-       "       vmull.u8        q7,     d16, d4                 \n\t"
-       "       vqrshrn.u16     d0,     q7, #8                  \n\t"
-       "       vqadd.u8        q0,     q0, q6                  \n\t"
-       "       vstm            %[d]!,  {d0}                    \n\t"
-
-       AP"quadloops:                                           \n\t"
-       "       sub             %[tmp], %[e], %[d]              \n\t"
-       "       cmp             %[tmp], #16                     \n\t"
-       "       blt             "AP"loopout                     \n\t"
-
-
-       "       sub             %[tmp], %[e], #15               \n\t"
-
-       "       sub             %[d],   #16                     \n\t"
-       AP"fastloop:"
-       "       add             %[d],   #16                     \n\t"
-       "       cmp             %[tmp], %[d]                    \n\t"
-       "       ble             "AP"loopout                     \n\t"
-       AP"quadloopint:                                         \n\t"
-       "       ldr             %[x],   [%[m]]                  \n\t"
-       "       add             %[m], #4                        \n\t"
-       "       cmp             %[x],   #0                      \n\t"
-       "       beq             "AP"fastloop                    \n\t"
-       "       vmov.32         d0[0],  %[x]                    \n\t"
-       "       vldm            %[d], {d4,d5}                   \n\t"
-
-       // Expand M: Fixme: Can we do this quicker?
-       "       vmovl.u8        q0,     d0                      \n\t"
-       "       vmovl.u8        q0,     d0                      \n\t"
-       "       vmul.u32        q0,     q14                     \n\t"
-
-       // Multiply     a * c
-       "       vmull.u8        q4,     d0, d30                 \n\t"
-       "       vmull.u8        q5,     d1, d31                 \n\t"
-
-       // Shorten
-       "       vqrshrn.u16     d12,    q4, #8                  \n\t"
-       "       vqrshrn.u16     d13,    q5, #8                  \n\t"
-
-       // extract negated alpha
-       "       vmvn.u16        q7,     q6                      \n\t"
-       "       vshr.u32        q8,     q7, #24                 \n\t"
-       "       vmul.u32        q8,     q8, q14                 \n\t"
-
-       // Multiply
-       "       vmull.u8        q7,     d16, d4                 \n\t"
-       "       vmull.u8        q8,     d17, d5                 \n\t"
-
-       "       vqrshrn.u16     d0,     q7, #8                  \n\t"
-       "       vqrshrn.u16     d1,     q8, #8                  \n\t"
-
-       // Add
-       "       vqadd.u8        q0,     q0, q6                  \n\t"
-
-       "       vstm            %[d]!,  {d0,d1}                 \n\t"
-
-       "       cmp             %[tmp], %[d]                    \n\t"
-       "       bhi             "AP"quadloopint                 \n\t"
-
-       AP"loopout:                                             \n\t"
-#if NEONDEBUG
-               "cmp            %[d], %[e]              \n\t"
-               "ble            "AP"foo         \n\t"
-               "cmp            %[tmp], %[m]    \n\t"
-               "sub            %[x],   %[x]            \n\t"
-               "vst1.32        d0[0], [%[x]]           \n\t"
-       AP"foo: \n\t"
-#endif
-
-       "       cmp             %[d], %[e]                      \n\t"
-       "       beq             "AP"done                        \n\t"
-       "       sub             %[tmp],%[e], %[d]               \n\t"
-       "       cmp             %[tmp],#4                       \n\t"
-       "       beq             "AP"singleout                   \n\t"
-
-       AP "dualloop2:                                  \n\t"
-               "sub            %[tmp],%[e],$0x8        \n\t"
-       "       vld1.16         d0[0],  [%[m]]!                 \n\t"
-       "       vldm            %[d],   {d4}                    \n\t"
-       "       vmovl.u8        q0,     d0                      \n\t"
-       "       vmovl.u8        q0,     d0                      \n\t"
-       "       vmul.u32        q0,     q14                     \n\t"
-       "       vmull.u8        q4,     d0, d30                 \n\t"
-       "       vqrshrn.u16     d12,    q4, #8                  \n\t"
-       "       vmvn.u16        d14,    d12                     \n\t"
-       "       vshr.u32        d16,    d14, #24                \n\t"
-       "       vmul.u32        d16,    d16, d28                \n\t"
-       "       vmull.u8        q7,     d16, d4                 \n\t"
-       "       vqrshrn.u16     d0,     q7, #8                  \n\t"
-       "       vqadd.u8        q0,     q0, q6                  \n\t"
-       "       vstm            %[d]!,  {d0}                    \n\t"
-
-       "       cmp             %[e], %[d]              \n\t"
-       "       beq             "AP"done                \n\t"
-
-       AP"singleout:                                           \n\t"
-       "       vld1.8          d0[0],  [%[m]]!                 \n\t"
-       "       vld1.32         d4[0],  [%[d]]                  \n\t"
-       "       vdup.u8         d0,     d0[0]                   \n\t"
-       "       vmull.u8        q4,     d0, d30                 \n\t"
-       "       vqrshrn.u16     d12,    q4, #8                  \n\t"
-       "       vmvn.u16        d14,    d12                     \n\t"
-       "       vshr.u32        d16,    d14, #24                \n\t"
-       "       vmul.u32        d16,    d16, d28                \n\t"
-       "       vmull.u8        q7,     d16, d4                 \n\t"
-       "       vqrshrn.u16     d0,     q7, #8                  \n\t"
-       "       vqadd.u8        q0,     q0, q6                  \n\t"
-       "       vst1.32         d0[0],  [%[d]]!                 \n\t"
-
-       AP"done:                                                \n\t"
-#if NEONDEBUG
-               "cmp            %[d], %[e]              \n\t"
-               "beq            "AP"reallydone          \n\t"
-               "sub            %[tmp], %[tmp]          \n\t"
-               "vst1.32        d0[0], [%[tmp]]         \n\t"
-       AP"reallydone:"
-#endif
-       : // Out
-       :  [e] "r" (d + l), [d] "r" (d), [c] "r" (c),
-               [tmp] "r" (7), [m] "r" (m), [x] "r" (0)
-          : "q0", "q1", "q2","q3", "q4","q5","q6", "q7","q8","q14","q15",
-                       "memory" // clobbered
-       );
-#undef AP
+   DATA32 *e = d + l;
+
+   // everything we can do only once per cycle
+   // loading of 'c', initialization of some registers
+   asm volatile (
+        "       .fpu neon                                               \n\t"
+        "       vdup.i32        q15,    %[c]                            \n\t"
+        "       vmov.i8         q14,    #1                              \n\t"
+        "       vmov.i16        q12,    #255                            \n\t"
+
+                :
+                : [c] "r" (c)
+                : "q15", "q14", "q12"
+   );
+   //here we do unaligned part of 'd'
+   while (((int)d & 0xf) && (d < e))
+     {
+        asm volatile (
+                "       vld1.8          d0[0],  [%[m]]!                 \n\t"
+                "       vld1.32         d4[0],  [%[d]]                  \n\t"
+                "       vdup.u8         d0,     d0[0]                   \n\t"
+                "       vmull.u8        q4,     d0, d30                 \n\t"
+                "       vadd.u16        q4,     q4, q12                 \n\t"
+                "       vshrn.u16       d12,    q4, #8                  \n\t"
+                "       vmvn.u16        d14,    d12                     \n\t"
+                "       vshr.u32        d16,    d14, #24                \n\t"
+                "       vmul.u32        d16,    d16, d28                \n\t"
+                "       vmovl.u8        q9,     d4                      \n\t"
+                "       vmull.u8        q7,     d16, d4                 \n\t"
+                "       vadd.u16        q7,     q9, q7                  \n\t"
+                "       vshrn.u16       d0,     q7, #8                  \n\t"
+                "       vadd.u8 d0,     d0,     d12                     \n\t"
+                "       vst1.32         d0[0],  [%[d]]!                 \n\t"
+
+                        : [d] "+r" (d), [m] "+r" (m)
+                        : [c] "r" (c)
+                        : "q0", "q2", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q15", "q14",
+                                "memory"
+        );
+     }
+   //here e - d should be divisible by 4
+   while((unsigned int)d < ((unsigned int)e & 0xfffffff0))
+     {
+        //check if all 4 *m values are zeros
+        int k = *((int *)m);
+        if (k == 0)
+          {
+             m+=4;
+             d+=4;
+             continue;
+          }
+
+        asm volatile (
+                        // load pair '*d' and '*(d+1)' into vector register
+                "       vld1.32         d0[0],  [%[m]]!                 \n\t"
+                "       vldm            %[d],   {q2}                    \n\t"
+                "       vmovl.u8        q0,     d0                      \n\t"
+                "       vmovl.u8        q0,     d0                      \n\t"
+                "       vmul.u32        q0,     q14                     \n\t"
+
+                        // Multiply     a * c
+                "       vmull.u8        q4,     d0, d30                 \n\t"
+                "       vadd.u16        q4,     q4, q12                 \n\t"
+                "       vmull.u8        q5,     d1, d31                 \n\t"
+                "       vadd.u16        q5,     q5, q12                 \n\t"
+
+                        // Shorten
+                "       vshrn.u16       d12,    q4, #8                  \n\t"
+                "       vshrn.u16       d13,    q5, #8                  \n\t"
+
+                        // extract negated alpha
+                "       vmvn.u16        q7,     q6                      \n\t"
+                "       vshr.u32        q8,     q7, #24                 \n\t"
+                "       vmul.u32        q8,     q8, q14                 \n\t"
+
+                        // Multiply
+                "       vmovl.u8        q9,     d4                      \n\t"
+                "       vmull.u8        q7,     d16, d4                 \n\t"
+                "       vadd.u16        q7,     q9, q7                  \n\t"
+                "       vmovl.u8        q10,    d5                      \n\t"
+                "       vmull.u8        q8,     d17, d5                 \n\t"
+                "       vadd.u16        q8,     q10, q8                 \n\t"
+
+                "       vshrn.u16       d0,     q7, #8                  \n\t"
+                "       vshrn.u16       d1,     q8, #8                  \n\t"
+
+                        // Add
+                "       vadd.u8 q0,     q0,     q6                      \n\t"
+
+                "       vstm            %[d]!,  {d0,d1}                 \n\t"
+
+                        : [d] "+r" (d), [m] "+r" (m)
+                        : [c] "r" (c), [x] "r" (42)
+                        : "q0", "q2", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q15", "q14",
+                                "memory"
+        );
+     }
+   //do the remaining part
+   while (d < e)
+     {
+        asm volatile (
+                "       vld1.8          d0[0],  [%[m]]!                 \n\t"
+                "       vld1.32         d4[0],  [%[d]]                  \n\t"
+                "       vdup.u8         d0,     d0[0]                   \n\t"
+                "       vmull.u8        q4,     d0, d30                 \n\t"
+                "       vadd.u16        q4,     q4, q12                 \n\t"
+                "       vshrn.u16       d12,    q4, #8                  \n\t"
+                "       vmvn.u16        d14,    d12                     \n\t"
+                "       vshr.u32        d16,    d14, #24                \n\t"
+                "       vmul.u32        d16,    d16, d28                \n\t"
+                "       vmovl.u8        q9,     d4                      \n\t"
+                "       vmull.u8        q7,     d16, d4                 \n\t"
+                "       vadd.u16        q7,     q9, q7                  \n\t"
+                "       vshrn.u16       d0,     q7, #8                  \n\t"
+                "       vadd.u8 d0,     d0,     d12                     \n\t"
+                "       vst1.32         d0[0],  [%[d]]!                 \n\t"
+
+                        : [d] "+r" (d), [m] "+r" (m)
+                        : [c] "r" (c)
+                        : "q0", "q2", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q15", "q14",
+                                "memory"
+        );
+    }
 }
 #endif
 
index 6e35970..799f7df 100644 (file)
 /* blend pixel x color --> dst */
 #ifdef BUILD_NEON
+
+#include <arm_neon.h>
+
 /* Note: Optimisation is based on keeping _dest_ aligned: else it's a pair of
  * reads, then two writes, a miss on read is 'just' two reads */
 static void
-_op_blend_p_c_dp_neon(DATA32 *s, DATA8 *m __UNUSED__, DATA32 c, DATA32 *d, int l) {
+_op_blend_p_c_dp_neon(DATA32 * __restrict s, DATA8 *m EINA_UNUSED, DATA32 c, DATA32 * __restrict d, int l) {
+
 #define AP     "blend_p_c_dp_"
    asm volatile (
-               ".fpu neon                              \n\t"
-               // Load 'c'
-               "vdup.u32       q7, %[c]                \n\t"
-               "vmov.i8        q6, #1                  \n\t"
-
-               // Choose a loop
-               "andS           %[tmp], %[d], $0xf      \n\t"
-               "beq            "AP"quadstart           \n\t"
-
-               "andS           %[tmp],%[d], $0x4       \n\t"
-               "beq            "AP"dualloop            \n\t"
-
-       AP"singleloop:"
-               "vld1.32        d0[0],  [%[s]]!         \n\t"
-               "vld1.32        d2[0],  [%[d]]          \n\t"
-               //  Mulitply s * c (= sc)
-               "vmull.u8       q4,     d0,d14          \n\t"
-               // sc in d8
-               "vqrshrn.u16    d4,     q4, #8          \n\t"
-
-               // sca in d9
-               "vmvn.u32       d6,     d4              \n\t"
-               "vshr.u32       d6,     d6, #24         \n\t"
-
-               "vmul.u32       d6,     d12, d6         \n\t"
-
-               /* d * alpha */
-               "vmull.u8       q4,     d6, d2          \n\t"
-               "vqrshrn.u16    d0,     q4, #8          \n\t"
-
-               "vqadd.u8       d2,     d0, d4          \n\t"
-
-               // Save dsc + sc
-               "vst1.32        d2[0],  [%[d]]!         \n\t"
-
-               // Now where?
-               // Can we go the fast path?
-               "andS           %[tmp], %[d],$0xf       \n\t"
-               "beq            "AP"quadstart           \n\t"
-
-       AP"dualloop:                                    \n\t"
-               // Check we have enough to bother with!
-               "sub            %[tmp], %[e], %[d]      \n\t"
-               "cmp            %[tmp], #16             \n\t"
-               "blt            "AP"loopout             \n\t"
-
-               //  load 's' -> q0, 'd' -> q1
-               "vldm           %[s]!,  {d0}            \n\t"
-               "vldm           %[d],   {d2}            \n\t"
-               //  Mulitply s * c (= sc)
-               "vmull.u8       q4,     d0,d14          \n\t"
-               // sc in d8
-               "vqrshrn.u16    d4,     q4, #8          \n\t"
-
-               // sca in d9
-               "vmvn.u32       d6,     d4              \n\t"
-               "vshr.u32       d6,     d6, #24         \n\t"
-
-               "vmul.u32       d6,     d12, d6         \n\t"
-
-               /* d * alpha */
-               "vmull.u8       q4,     d6, d2          \n\t"
-               "vqrshrn.u16    d0,     q4, #8          \n\t"
-
-               "vqadd.u8       d2,     d0, d4          \n\t"
-
-               // Save dsc + sc
-               "vst1.32        d2,     [%[d]]!         \n\t"
-
-       AP"quadstart:                                   \n\t"
-               "sub            %[tmp], %[e], %[d]      \n\t"
-               "cmp            %[tmp], #16             \n\t"
-               "blt            "AP"loopout             \n\t"
-
-               "sub            %[tmp], %[e], #15       \n\t"
-
-       AP"quadloop:\n\t"
-               //  load 's' -> q0, 'd' -> q1
-               "vldm   %[s]!, {d0,d1}          \n\t"
-               "vldm   %[d], {d2,d3}           \n\t"
-               //  Mulitply s * c (= sc)
-               "vmull.u8       q4,     d0,d14  \n\t"
-               "vmull.u8       q5,     d1,d14  \n\t"
-
-               // Get sc & sc alpha
-               "vqrshrn.u16    d4,     q4, #8          \n\t"
-               "vqrshrn.u16    d5,     q5, #8          \n\t"
-                       // sc is now in q2, 8bpp
-               // Shift out, then spread alpha for q2
-               "vmvn.u32       q3,     q2              \n\t"
-               "vshr.u32       q3,     q3, $0x18       \n\t"
-               "vmul.u32       q3,     q6,q3           \n\t"
-
-               //  Multiply 'd' by sc.alpha (dsca)
-               "vmull.u8       q4,     d6,d2           \n\t"
-               "vmull.u8       q5,     d7,d3           \n\t"
-
-               "vqrshrn.u16    d0,     q4, #8          \n\t"
-               "vqrshrn.u16    d1,     q5, #8          \n\t"
-
-               "vqadd.u8       q1,     q0, q2          \n\t"
-
-               // Save dsc + sc
-               "vstm           %[d]!,  {d2,d3}         \n\t"
-
-               "cmp            %[tmp], %[d]            \n\t"
-
-               "bhi            "AP"quadloop            \n\t"
-
-       /* Trailing stuff */
-       AP"loopout:                                     \n\t"
-
-               "cmp            %[d], %[e]              \n\t"
-                "beq           "AP"done\n\t"
-               "sub            %[tmp],%[e], %[d]       \n\t"
-               "cmp            %[tmp],$0x04            \n\t"
-               "beq            "AP"singleloop2         \n\t"
-
-               "sub            %[tmp], %[e], #7        \n\t"
-       /* Dual loop */
-       AP"dualloop2:                                   \n\t"
-               "vldm           %[s]!, {d0}             \n\t"
-               "vldm           %[d], {d2}              \n\t"
-               //  Mulitply s * c (= sc)
-               "vmull.u8       q4,     d0,d14          \n\t"
-               // sc in d8
-               "vqrshrn.u16    d4,     q4, #8          \n\t"
-
-               // sca in d9
-               // XXX: I can probably squash one of these 3
-               "vmvn.u32       d6,     d4              \n\t"
-               "vshr.u32       d6,     d6, #24         \n\t"
-               "vmul.u32       d6,     d6, d12         \n\t"
-
-               /* d * alpha */
-               "vmull.u8       q4,     d6, d2          \n\t"
-               "vqrshrn.u16    d0,     q4, #8          \n\t"
-
-               "vqadd.u8       d2,     d0, d4          \n\t"
-
-               // Save dsc + sc
-               "vstm           %[d]!,  {d2}            \n\t"
-
-               "cmp            %[tmp], %[d]            \n\t"
-               "bhi            "AP"dualloop2           \n\t"
-
-               "cmp            %[d], %[e]              \n\t"
-                "beq           "AP"done                \n\t"
-
-       AP"singleloop2:                                 \n\t"
-               "vld1.32        d0[0],  [%[s]]!         \n\t"
-               "vld1.32        d2[0],  [%[d]]          \n\t"
-               //  Mulitply s * c (= sc)
-               "vmull.u8       q4,     d0,d14          \n\t"
-               // sc in d8
-               "vqrshrn.u16    d4,     q4, #8          \n\t"
-
-               // sca in d6
-               "vmvn.u32       d6,     d4              \n\t"
-               "vshr.u32       d6,     d6, #24         \n\t"
-               "vmul.u32       d6,     d12,d6          \n\t"
-
-               /* d * alpha */
-               "vmull.u8       q4,     d6, d2          \n\t"
-               "vqrshrn.u16    d0,     q4, #8          \n\t"
-
-               "vqadd.u8       d2,     d0, d4          \n\t"
-
-               // Save dsc + sc
-               "vst1.32        d2[0],  [%[d]]!         \n\t"
-
-
-       AP"done:"
-               : // No output
-               //
-               : [s] "r" (s), [e] "r" (d + l), [d] "r" (d), [c] "r" (c),
-                       [tmp] "r" (12)
-               : "q0","q1","q2","q3","q4","q5","q6","q7","memory"
-       );
+      ".fpu neon\n\t"
+      "vdup.u32  d0, %[c]\n\t"          // Load 'c'
+      "vmov.u16  q1, $0x00ff\n\t"       // round_mask
+      "vmov.u8   q2, #0\n\t"            // zero register
+      "sub       %[tmp], %[e], #16\n\t"
+      "cmp       %[d], %[tmp]\n\t"
+      "bhi       "AP"skipquad\n\t"
+    AP"quadloop:"
+      "vld1.32   {d6, d7}, [%[s]]!\n\t" // Load 's'
+      "vld1.32   {d8, d9}, [%[d]]\n\t"  // Load 'd'
+      "vmull.u8  q5, d6, d0\n\t"        // s * c
+      "vmull.u8  q6, d7, d0\n\t"
+      "vadd.u16  q5, q5, q1\n\t"        // rounding
+      "vadd.u16  q6, q6, q1\n\t"
+      "vshrn.u16 d10, q5, #8\n\t"       // narrowing
+      "vshrn.u16 d11, q6, #8\n\t"       // sc in q5
+      "vsub.u8   q6, q2, q5\n\t"
+      "vmov      q7, q6\n\t"
+      "vtrn.u8   q7, q6\n\t"
+      "vmov      q7, q6\n\t"
+      "vtrn.u16  q7, q6\n\t"            // q6 - alpha
+      "vmull.u8  q7, d8, d12\n\t"
+      "vmull.u8  q8, d9, d13\n\t"
+      "vshrn.u16 d14, q7, #8\n\t"
+      "vshrn.u16 d15, q8, #8\n\t"       // q7 - d * alpha
+      "vceq.i32  q6, q6, #0\n\t"        // if alpha = 0x100
+      "vbsl      q6, q4, q7\n\t"        // just copy d[i]
+      "vadd.u32  q4, q5, q6\n\t"
+      "vst1.u32  {d8, d9}, [%[d]]!\n\t"
+      "cmp       %[d], %[tmp]\n\t"
+      "bls       "AP"quadloop\n\t"
+    AP"skipquad:"
+      "sub       %[tmp], %[e], #8\n\t"
+      "cmp       %[d], %[tmp]\n\t"
+      "bhi       "AP"skipdouble\n\t"
+    AP"doubleloop:"
+      "vld1.32   d6, [%[s]]!\n\t"
+      "vld1.32   d7, [%[d]]\n\t"
+      "vmull.u8  q4, d6, d0\n\t"
+      "vadd.u16  q4, q4, q1\n\t"
+      "vshrn.u16 d8, q4, #8\n\t"
+      "vsub.u8   d9, d4, d8\n\t"
+      "vmov      d10, d9\n\t"
+      "vtrn.u8   d10, d9\n\t"
+      "vmov      d10, d9\n\t"
+      "vtrn.u16  d10, d9\n\t"           // d9 - alpha
+      "vmull.u8  q5, d7, d9\n\t"
+      "vshrn.u16 d1, q5, #8\n\t"
+      "vceq.i32  d9, d9, #0\n\t"
+      "vbsl      d9, d7, d1\n\t"        // d7 - d[i], d1 - d[i] * alpha
+      "vadd.u32  d7, d8, d9\n\t"
+      "vst1.u32  d7, [%[d]]!\n\t"
+      "cmp       %[d], %[tmp]\n\t"
+      "bls       "AP"doubleloop\n\t"
+    AP"skipdouble:"
+      "cmp       %[d], %[e]\n\t"
+      "beq       "AP"done\n\t"
+    AP"singleloop:"
+      "vld1.32   d6[0], [%[s]]!\n\t"
+      "vld1.32   d7[0], [%[d]]\n\t"
+      "vmull.u8  q4, d6, d0\n\t"
+      "vadd.u16  q4, q4, q1\n\t"
+      "vshrn.u16 d8, q4, #8\n\t"
+      "vsub.u8   d9, d4, d8\n\t"
+      "vmov      d10, d9\n\t"
+      "vtrn.u8   d10, d9\n\t"
+      "vmov      d10, d9\n\t"
+      "vtrn.u16  d10, d9\n\t"           // d9 - alpha
+      "vmull.u8  q5, d7, d9\n\t"
+      "vshrn.u16 d1, q5, #8\n\t"
+      "vceq.i32  d9, d9, #0\n\t"
+      "vbsl      d9, d7, d1\n\t"        // d7 - d[i], d1 - d[i] * alpha
+      "vadd.u32  d7, d8, d9\n\t"
+      "vst1.u32  d7[0], [%[d]]!\n\t"
+      "cmp       %[d], %[e]\n\t"
+      "blt       "AP"singleloop\n\t"
+    AP"done:"
+      : // No output
+      : [s] "r" (s), [d] "r" (d), [c] "r" (c), [e] "r" (d + l), [tmp] "r" (12)
+      : "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "memory"
+   );
 #undef AP
 }
 
@@ -200,13 +106,14 @@ _op_blend_pan_can_dp_neon(DATA32 *s, DATA8 *m __UNUSED__, DATA32 c, DATA32 *d, i
 
 static void
 _op_blend_pan_caa_dp_neon(DATA32 *s, DATA8 *m __UNUSED__, DATA32 c, DATA32 *d, int l) {
-#if 1 
+#if 1
    DATA32 *e;
+   DATA32 sc;
    int alpha;
    c = 1 + (c & 0xff);
    UNROLL8_PLD_WHILE(d, l, e,
                     {
-                       DATA32 sc = MUL_256(c, *s);
+                       sc = MUL_256(c, *s);
                        alpha = 256 - (sc >> 24);
                        *d = sc + MUL_256(alpha, *d);
                        d++;
index a9d0f4b..8451b58 100644 (file)
@@ -26,52 +26,8 @@ _op_blend_p_mas_dp(DATA32 *s, DATA8 *m, DATA32 c, DATA32 *d, int l) {
                      });
 }
 
-static void
-_op_blend_pas_mas_dp(DATA32 *s, DATA8 *m, DATA32 c __UNUSED__, DATA32 *d, int l) {
-   DATA32 *e;
-   int alpha;
-   UNROLL8_PLD_WHILE(d, l, e,
-                     {
-                        alpha = *m;
-                        switch(alpha)
-                          {
-                          case 0:
-                             break;
-                          case 255:
-                             *d = *s;
-                             break;
-                          default:
-                             alpha++;
-                             *d = INTERP_256(alpha, *s, *d);
-                             break;
-                          }
-                        m++;  s++;  d++;
-                     });
-}
-
-static void
-_op_blend_pan_mas_dp(DATA32 *s, DATA8 *m, DATA32 c __UNUSED__, DATA32 *d, int l) {
-   DATA32 *e;
-   int alpha;
-   UNROLL8_PLD_WHILE(d, l, e,
-                     {
-                        alpha = *m;
-                        switch(alpha)
-                          {
-                          case 0:
-                             break;
-                          case 255:
-                             *d = *s;
-                             break;
-                          default:
-                             alpha++;
-                             *d = INTERP_256(alpha, *s, *d);
-                             break;
-                          }
-                        m++;  s++;  d++;
-                     });
-}
-
+#define _op_blend_pas_mas_dp _op_blend_p_mas_dp
+#define _op_blend_pan_mas_dp _op_blend_pas_mas_dp
 
 #define _op_blend_p_mas_dpan _op_blend_p_mas_dp
 #define _op_blend_pas_mas_dpan _op_blend_pas_mas_dp
index 4fa50a9..9494ce6 100644 (file)
@@ -1,8 +1,12 @@
 /* blend pixel x mask --> dst */
 
 #ifdef BUILD_MMX
+
+// FIXME: These functions most likely don't perform the correct operation.
+// Test them with masks and images.
+#if 0
 static void
-_op_blend_pas_mas_dp_mmx(DATA32 *s, DATA8 *m, DATA32 c __UNUSED__, DATA32 *d, int l) {
+_op_blend_pas_mas_dp_mmx(DATA32 *s, DATA8 *m, DATA32 c EINA_UNUSED, DATA32 *d, int l) {
    DATA32 *e = d + l;
    pxor_r2r(mm0, mm0);
    MOV_A2R(ALPHA_256, mm6)
@@ -37,7 +41,7 @@ _op_blend_pas_mas_dp_mmx(DATA32 *s, DATA8 *m, DATA32 c __UNUSED__, DATA32 *d, in
 }
 
 static void
-_op_blend_pan_mas_dp_mmx(DATA32 *s, DATA8 *m, DATA32 c __UNUSED__, DATA32 *d, int l) {
+_op_blend_pan_mas_dp_mmx(DATA32 *s, DATA8 *m, DATA32 c EINA_UNUSED, DATA32 *d, int l) {
    DATA32 *e = d + l;
    MOV_A2R(ALPHA_255, mm5)
    pxor_r2r(mm0, mm0);
@@ -62,8 +66,13 @@ _op_blend_pan_mas_dp_mmx(DATA32 *s, DATA8 *m, DATA32 c __UNUSED__, DATA32 *d, in
        m++;  s++;  d++;
      }
 }
+#else
+// FIXME
+#define _op_blend_p_mas_dp_mmx NULL
+#define _op_blend_pas_mas_dp_mmx _op_blend_p_mas_dp_mmx
+#endif
 
-#define _op_blend_p_mas_dp_mmx _op_blend_pas_mas_dp_mmx
+#define _op_blend_pan_mas_dp_mmx _op_blend_pas_mas_dp_mmx
 
 #define _op_blend_p_mas_dpan_mmx _op_blend_p_mas_dp_mmx
 #define _op_blend_pan_mas_dpan_mmx _op_blend_pan_mas_dp_mmx
@@ -128,9 +137,9 @@ init_blend_pixel_mask_pt_funcs_mmx(void)
 
 #ifdef BUILD_MMX
 
-#define _op_blend_rel_p_mas_dpan_mmx _op_blend_p_mas_dpan_mmx
-#define _op_blend_rel_pas_mas_dpan_mmx _op_blend_pas_mas_dpan_mmx
-#define _op_blend_rel_pan_mas_dpan_mmx _op_blend_pan_mas_dpan_mmx
+#define _op_blend_rel_p_mas_dpan_mmx NULL
+#define _op_blend_rel_pas_mas_dpan_mmx _op_blend_rel_p_mas_dpan_mmx
+#define _op_blend_rel_pan_mas_dpan_mmx _op_blend_rel_pas_mas_dpan_mmx
 
 static void
 init_blend_rel_pixel_mask_span_funcs_mmx(void)
index b252a67..0c1029b 100644 (file)
@@ -1,8 +1,12 @@
 /* blend pixel x mask --> dst */
 
+// FIXME: These functions most likely don't perform the correct operation.
+// Test them with masks and images.
+
 #ifdef BUILD_NEON
+#if 0
 static void
-_op_blend_pas_mas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c __UNUSED__, DATA32 *d, int l) {
+_op_blend_pas_mas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c EINA_UNUSED, DATA32 *d, int l) {
    DATA32 *e;
    int alpha;
    UNROLL8_PLD_WHILE(d, l, e,
@@ -25,7 +29,7 @@ _op_blend_pas_mas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c __UNUSED__, DATA32 *d, i
 }
 
 static void
-_op_blend_pan_mas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c __UNUSED__, DATA32 *d, int l) {
+_op_blend_pan_mas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c EINA_UNUSED, DATA32 *d, int l) {
    DATA32 *e;
    int alpha;
    UNROLL8_PLD_WHILE(d, l, e,
@@ -46,6 +50,11 @@ _op_blend_pan_mas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c __UNUSED__, DATA32 *d, i
                         m++;  s++;  d++;
                      });
 }
+#else
+// FIXME
+#define _op_blend_pas_mas_dp_neon NULL
+#define _op_blend_pan_mas_dp_neon NULL
+#endif
 
 #define _op_blend_p_mas_dp_neon _op_blend_pas_mas_dp_neon
 
index 617b9e2..a7b160a 100644 (file)
@@ -2,6 +2,9 @@
 
 #ifdef BUILD_SSE3
 
+// FIXME: These functions most likely don't perform the correct operation.
+// Test them with masks and images.
+#if 0
 static void
 _op_blend_p_mas_dp_sse3(DATA32 *s, DATA8 *m, DATA32 c, DATA32 *d, int l) {
 
@@ -150,6 +153,12 @@ _op_blend_pas_mas_dp_sse3(DATA32 *s, DATA8 *m, DATA32 c __UNUSED__, DATA32 *d, i
          m += 8; s += 8; d += 8; l -= 8;
       })
 }
+#endif
+
+// FIXME
+#define _op_blend_p_mas_dp_sse3 NULL
+#define _op_blend_pas_mas_dp_sse3 _op_blend_p_mas_dp_sse3
+// -----
 
 #define _op_blend_pan_mas_dp_sse3 _op_blend_pas_mas_dp_sse3
 
@@ -169,8 +178,10 @@ init_blend_pixel_mask_span_funcs_sse3(void)
    op_blend_span_funcs[SP_AN][SM_AS][SC_N][DP_AN][CPU_SSE3] = _op_blend_pan_mas_dpan_sse3;
 }
 
+// FIXME
 #define _op_blend_pt_p_mas_dp_sse3 NULL
 #define _op_blend_pt_pan_mas_dp_sse3 NULL
+// -----
 
 #define _op_blend_pt_pas_mas_dp_sse3 _op_blend_pt_p_mas_dp_sse3
 
@@ -194,6 +205,7 @@ init_blend_pixel_mask_pt_funcs_sse3(void)
 
 /* blend_rel pixel x mask -> dst */
 
+#if 0
 static void
 _op_blend_rel_p_mas_dp_sse3(DATA32 *s, DATA8 *m, DATA32 c, DATA32 *d, int l) {
 
@@ -256,6 +268,10 @@ _op_blend_rel_p_mas_dp_sse3(DATA32 *s, DATA8 *m, DATA32 c, DATA32 *d, int l) {
          d += 8; m += 8; s += 8; l -= 8;
       })
 }
+#else
+// FIXME
+#define _op_blend_rel_p_mas_dp_sse3 NULL
+#endif
 
 #define _op_blend_rel_pas_mas_dp_sse3 _op_blend_rel_p_mas_dp_sse3
 #define _op_blend_rel_pan_mas_dp_sse3 _op_blend_rel_p_mas_dp_sse3
index 1cb50b6..25a51f6 100644 (file)
@@ -241,7 +241,7 @@ _op_blend_pas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c, DATA32 *d, int l) {
                "vld1.32        d4[0], [%[d]]                   \n\t"
 
                "vmvn.u8        d8,     d0                      \n\t"
-
+               "vadd.u8        d8,     d8,  d16                        \n\t"
                "vshr.u32       d8,     d8,$0x18                \n\t"
 
                // Mulitply into all fields
@@ -250,7 +250,13 @@ _op_blend_pas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c, DATA32 *d, int l) {
                // Multiply out
                "vmull.u8       q6,     d8, d4                  \n\t"
 
-               "vqrshrn.u16    d8,     q6, #8                  \n\t"
+               "vqrshrn.u16    d9,     q6, #8                  \n\t"
+
+               //if alpha is 0, set 1. if not, set 0.
+               "vceq.u8        d8, d8, #0                      \n\t"
+
+               // if alpha is 1, choose d4. if not, choose d8.
+               "vbsl       d8, d4, d9\n\t"
 
                // Add to s
                "vqadd.u8       d0,     d0,d8                   \n\t"
@@ -271,8 +277,9 @@ _op_blend_pas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c, DATA32 *d, int l) {
                "vldm   %[s]!,  {d0)                            \n\t"
                "vldm   %[d],   {d4}                            \n\t"
 
-               // Subtract from 255 (ie negate) and extract alpha channel
+               // Subtract from 256 (ie negate) and extract alpha channel
                "vmvn.u8        d8,     d0                      \n\t"
+               "vadd.u8        d8,     d8,  d16                        \n\t"
                "vshr.u32       d8,     d8,$0x18                \n\t"
 
                // Mulitply into all fields
@@ -281,7 +288,13 @@ _op_blend_pas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c, DATA32 *d, int l) {
                // Multiply out
                "vmull.u8       q6,     d8, d4                  \n\t"
 
-               "vqrshrn.u16    d8,     q6, #8                  \n\t"
+               "vqrshrn.u16    d9,     q6, #8                  \n\t"
+
+               //if alpha is 0, set 1. if not, set 0.
+               "vceq.u8        d8, d8, #0                      \n\t"
+
+               // if alpha is 1, choose d4. if not, choose d8.
+               "vbsl       d8, d4, d9\n\t"
 
                // Add to s
                "vqadd.u8       d0,     d0,d8                   \n\t"
@@ -291,49 +304,63 @@ _op_blend_pas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c, DATA32 *d, int l) {
                "bne            "AP"dualloop                    \n\t"
 
 
-        AP"quadstart:                                          \n\t"
+       AP"quadstart:                                           \n\t"
                "sub            %[tmp], %[e], %[d]              \n\t"
                "cmp            %[tmp], #32                     \n\t"
                "blt            "AP"loopout                     \n\t"
 
                "sub            %[tmp], %[e],  #31              \n\t"
 
-        AP"quadloop:\n\t"
+       AP"quadloop:\n"
                "vldm   %[s]!,  {d0,d1,d2,d3)                   \n\t"
                "vldm   %[d],   {d4,d5,d6,d7}                   \n\t"
 
-               // Subtract from 255 (ie negate) and extract alpha channel
+               // Subtract from 256 (ie negate) and extract alpha channel
                "vmvn.u8        q4,     q0                      \n\t"
-                       "vmvn.u8        q5,     q1              \n\t"
+               "vmvn.u8        q5,     q1              \n\t"
+               "vadd.u8        q4,     q4, q8                  \n\t"
+               "vadd.u8        q5,     q5, q8                  \n\t"
                "vshr.u32       q4,     q4,$0x18                \n\t"
-                       "vshr.u32       q5,     q5,$0x18        \n\t"
+               "vshr.u32       q5,     q5,$0x18        \n\t"
 
                // Prepare to preload
                "add    %[pl], %[s], #32                        \n\t"
 
                // Mulitply into all fields
                "vmul.u32       q4,     q4, q8                  \n\t"
-                       "vmul.u32       q5,     q5, q8          \n\t"
+               "vmul.u32       q5,     q5, q8          \n\t"
                "pld    [%[pl]]                                 \n\t"
 
                // Multiply out
-               "vmull.u8       q6,     d8, d4                  \n\t"
-                       "vmull.u8       q7,     d10, d6         \n\t"
-               "vmull.u8       q2,     d9, d5                  \n\t"
-                       "vmull.u8       q3,     d11, d7         \n\t"
+               "vmull.u8       q6,         d8, d4                      \n\t"
+               "vmull.u8       q7,         d9, d5              \n\t"
+               "vmull.u8       q9,     d10, d6                 \n\t"
+               "vmull.u8       q10,    d11, d7         \n\t"
 
                "add    %[pl], %[d], #32                        \n\t"
 
-               "vqrshrn.u16    d8,     q6, #8                  \n\t"
-                       "vqrshrn.u16    d10,    q7, #8          \n\t"
-               "vqrshrn.u16    d9,     q2, #8                  \n\t"
-                       "vqrshrn.u16    d11,    q3, #8          \n\t"
+               "vqrshrn.u16    d12,    q6, #8                  \n\t"
+               "vqrshrn.u16    d13,    q7, #8          \n\t"
+               "vqrshrn.u16    d14,    q9, #8                  \n\t"
+               "vqrshrn.u16    d15,    q10, #8         \n\t"
                "pld    [%[pl]]                                 \n\t"
 
                "cmp            %[tmp], %[pl]                   \n\t"
+
+               //if alpha is 0, set 1. if not, set 0.
+               "vceq.u8        q4, q4, #0                      \n\t"
+               "vceq.u8        q5, q5, #0                      \n\t"
+
+               // if alpha is 1, choose d.
+               "vbsl       d8, d4, d12\n\t"
+               "vbsl       d9, d5, d13\n\t"
+               "vbsl       d10, d6, d14\n\t"
+               "vbsl       d11, d7, d15\n\t"
+
+
                // Add to s
                "vqadd.u8       q0,     q0,q4                   \n\t"
-                       "vqadd.u8       q1,     q1,q5           \n\t"
+               "vqadd.u8       q1,     q1,q5           \n\t"
 
                "vstm           %[d]!,  {d0,d1,d2,d3}           \n\t"
 
@@ -341,7 +368,7 @@ _op_blend_pas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c, DATA32 *d, int l) {
 
        AP "loopout:                                            \n\t"
                "cmp            %[d], %[e]                      \n\t"
-                "beq           "AP"done                        \n\t"
+               "beq            "AP"done                        \n\t"
 
                "sub            %[tmp],%[e], %[d]               \n\t"
                "cmp            %[tmp],$0x04                    \n\t"
@@ -353,8 +380,9 @@ _op_blend_pas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c, DATA32 *d, int l) {
                "vldm           %[s]!,  {d0)                    \n\t"
                "vldm           %[d],   {d4}                    \n\t"
 
-               // Subtract from 255 (ie negate) and extract alpha channel
+               // Subtract from 256 (ie negate) and extract alpha channel
                "vmvn.u8        d8,     d0                      \n\t"
+               "vadd.u8        d8,     d8,  d16                        \n\t"
                "vshr.u32       d8,     d8,$0x18                \n\t"
 
                // Mulitply into all fields
@@ -363,7 +391,13 @@ _op_blend_pas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c, DATA32 *d, int l) {
                // Multiply out
                "vmull.u8       q6,     d8, d4                  \n\t"
 
-               "vqrshrn.u16    d8,     q6, #8                  \n\t"
+               "vqrshrn.u16    d9,     q6, #8                  \n\t"
+
+               //if alpha is 0, set 1. if not, set 0.
+               "vceq.u8        d8, d8, #0                      \n\t"
+
+               // if alpha is 1, choose d4. if not, choose d8.
+               "vbsl       d8, d4, d9\n\t"
 
                // Add to s
                "vqadd.u8       d0,     d0,d8                   \n\t"
@@ -382,7 +416,7 @@ _op_blend_pas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c, DATA32 *d, int l) {
                "vld1.32        d4[0], [%[d]]                   \n\t"
 
                "vmvn.u8        d8,     d0                      \n\t"
-
+               "vadd.u8        d8,     d8,  d16                        \n\t"
                "vshr.u32       d8,     d8,$0x18                \n\t"
 
                // Mulitply into all fields
@@ -391,7 +425,13 @@ _op_blend_pas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c, DATA32 *d, int l) {
                // Multiply out
                "vmull.u8       q6,     d8, d4                  \n\t"
 
-               "vqrshrn.u16    d8,     q6, #8                  \n\t"
+               "vqrshrn.u16    d9,     q6, #8                  \n\t"
+
+               //if alpha is 0, set 1. if not, set 0.
+               "vceq.u8        d8, d8, #0                      \n\t"
+
+               // if alpha is 1, choose d4. if not, choose d8.
+               "vbsl       d8, d4, d9\n\t"
 
                // Add to s
                "vqadd.u8       d0,     d0,d8                   \n\t"
@@ -404,7 +444,7 @@ _op_blend_pas_dp_neon(DATA32 *s, DATA8 *m, DATA32 c, DATA32 *d, int l) {
          : /* In */  [s] "r" (s), [e] "r" (e), [d] "r" (d), [tmp] "r" (tmp),
                [pl] "r" (pl)
          : /* Clobbered */
-                "q0","q1","q2","q3","q4","q5","q6","q7","q8","memory"
+                "q0","q1","q2","q3","q4","q5","q6","q7","q8","q9","q10","memory"
       );
 #undef AP
 }
index 946a293..ec6272a 100644 (file)
@@ -2,6 +2,20 @@
 #include <unistd.h>
 
 #ifdef BUILD_PIPE_RENDER
+
+# ifdef BUILD_PTHREAD
+typedef struct _Thinfo
+{
+   RGBA_Image            *im;
+   int                    thread_num;
+   pthread_t              thread_id;
+   pthread_barrier_t     *barrier;
+   const Eina_Inlist     *tasks;
+   Eina_Array             cutout_trash;
+   Eina_Array             rects_task;
+} Thinfo;
+#endif
+
 static RGBA_Pipe *evas_common_pipe_add(RGBA_Pipe *pipe, RGBA_Pipe_Op **op);
 static void evas_common_pipe_draw_context_copy(RGBA_Draw_Context *dc, RGBA_Pipe_Op *op);
 static void evas_common_pipe_op_free(RGBA_Pipe_Op *op);
@@ -292,7 +306,7 @@ evas_common_pipe_rectangle_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op
    Eina_Bool r;
 
    recycle = evas_pipe_cutout_rects_pop(info);
-   r = evas_common_rectangle_draw_prepare(recycle, dst, &(op->context),
+   r = evas_common_rectangle_draw_prepare(&recycle, dst, &(op->context),
                                           op->op.rect.x, op->op.rect.y,
                                           op->op.rect.w, op->op.rect.h);
    if (recycle->active) op->rects = recycle;
@@ -439,7 +453,7 @@ evas_common_pipe_text_draw_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op
    Eina_Bool r;
 
    recycle = evas_pipe_cutout_rects_pop(info);
-   r = evas_common_font_draw_prepare_cutout(recycle, dst, &(op->context),
+   r = evas_common_font_draw_prepare_cutout(&recycle, dst, &(op->context),
                                            &(op->op.text.func));
    if (recycle->active) op->rects = recycle;
    else evas_pipe_cutout_rects_push(info, recycle);
@@ -487,7 +501,7 @@ evas_common_pipe_op_image_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op)
    Eina_Bool r;
 
    recycle = evas_pipe_cutout_rects_pop(info);
-   r = evas_common_scale_rgba_in_to_out_clip_prepare(recycle,
+   r = evas_common_scale_rgba_in_to_out_clip_prepare(&recycle,
                                                     op->op.image.src, dst,
                                                     &(op->context),
                                                      op->op.image.dx, op->op.image.dy,
index c6a28ff..a2fdb17 100644 (file)
@@ -4,19 +4,6 @@
 #include <sys/time.h>
 #include "language/evas_bidi_utils.h"
 
-#ifdef BUILD_PTHREAD
-typedef struct _Thinfo
-{
-   RGBA_Image            *im;
-   int                    thread_num;
-   pthread_t              thread_id;
-   pthread_barrier_t     *barrier;
-   const Eina_Inlist     *tasks;
-   Eina_Array             cutout_trash;
-   Eina_Array             rects_task;
-} Thinfo;
-#endif
-
 /* image rendering pipelines... new optional system - non-immediate and
  * threadable
  */
index f6c79c8..80bdec0 100644 (file)
@@ -278,7 +278,10 @@ evas_common_polygon_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Po
    free(point);
    free(sorted_index);
 
-   func = evas_common_gfx_func_composite_color_span_get(dc->col.col, dst, 1, dc->render_op);
+   if(dc->clip.mask)
+     func = evas_common_gfx_func_composite_mask_color_span_get(dc->col.col, dst, 1, dc->render_op);
+   else
+     func = evas_common_gfx_func_composite_color_span_get(dc->col.col, dst, 1, dc->render_op);
    if (spans)
      {
        RGBA_Span *span;
@@ -286,6 +289,8 @@ evas_common_polygon_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Po
        EINA_INLIST_FOREACH(spans, span)
          {
             DATA32 *ptr;
+             DATA8 *mask;
+             RGBA_Image *mask_ie;
 
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_POLY
@@ -306,8 +311,17 @@ evas_common_polygon_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Po
 # endif
 #endif
               {
-                ptr = dst->image.data + (span->y * (dst->cache_entry.w)) + span->x;
-                func(NULL, NULL, dc->col.col, ptr, span->w);
+                  ptr = dst->image.data + (span->y * (dst->cache_entry.w)) + span->x;
+                  if (dc->clip.mask)
+                    {
+                       mask_ie = dc->clip.mask;
+                       mask = mask_ie->image.data8
+                          + ((span->y - dc->clip.mask_y) * mask_ie->cache_entry.w)
+                          + (span->x - dc->clip.mask_x);
+                       func(NULL, mask, dc->col.col, ptr, span->w);
+                    }
+                  else
+                    func(NULL, NULL, dc->col.col, ptr, span->w);
               }
           }
        while (spans)
index 8fdcb77..ddae1aa 100644 (file)
@@ -7,7 +7,7 @@ EAPI void           evas_common_rectangle_init          (void);
 EAPI void           evas_common_rectangle_draw          (RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
 
 EAPI void evas_common_rectangle_draw_do(const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
-EAPI Eina_Bool evas_common_rectangle_draw_prepare(Cutout_Rects *reuse, const RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
+EAPI Eina_Bool evas_common_rectangle_draw_prepare(Cutout_Rects **reuse, const RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
 
 #endif /* _EVAS_RECTANGLE_H */
 
index 33fb053..c29d39a 100644 (file)
@@ -49,7 +49,7 @@ evas_common_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y,
 }
 
 EAPI Eina_Bool
-evas_common_rectangle_draw_prepare(Cutout_Rects *reuse, const RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h)
+evas_common_rectangle_draw_prepare(Cutout_Rects **reuse, const RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h)
 {
    if ((w <= 0) || (h <= 0)) return EINA_FALSE;
    if (!(RECTS_INTERSECT(x, y, w, h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
@@ -62,7 +62,7 @@ evas_common_rectangle_draw_prepare(Cutout_Rects *reuse, const RGBA_Image *dst, R
        evas_common_draw_context_clip_clip(dc, x, y, w, h);
        /* our clip is 0 size.. abort */
        if ((dc->clip.w > 0) && (dc->clip.h > 0))
-        reuse = evas_common_draw_context_apply_cutouts(dc, reuse);
+         *reuse = evas_common_draw_context_apply_cutouts(dc, *reuse);
      }
 
    return EINA_TRUE;
@@ -104,6 +104,8 @@ rectangle_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, in
    RGBA_Gfx_Func func;
    int yy;
    DATA32 *ptr;
+   DATA8 *mask = NULL, *mbegin = NULL, *mend = NULL;
+   RGBA_Image *mask_ie = dc->clip.mask;
 
    RECTS_CLIP_TO_RECT(x, y, w, h, dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
    if ((w <= 0) || (h <= 0)) return;
@@ -125,11 +127,32 @@ rectangle_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, in
 # endif     
 #endif
      {
-        func = evas_common_gfx_func_composite_color_span_get(dc->col.col, dst, w, dc->render_op);
+        if (mask_ie)
+          {
+             func = evas_common_gfx_func_composite_mask_color_span_get(dc->col.col, dst, w, dc->render_op);
+             mbegin = mask_ie->image.data8;
+             mend = mbegin + (mask_ie->cache_entry.w * mask_ie->cache_entry.h);
+          }
+        else
+          func = evas_common_gfx_func_composite_color_span_get(dc->col.col, dst, w, dc->render_op);
         ptr = dst->image.data + (y * dst->cache_entry.w) + x;
         for (yy = 0; yy < h; yy++)
           {
-           func(NULL, NULL, dc->col.col, ptr, w);
+             if (mask_ie)
+               {
+                  mask = mask_ie->image.data8
+                     + (y + yy - dc->clip.mask_y) * mask_ie->cache_entry.w
+                     + (x - dc->clip.mask_x);
+                  /* FIXME!!! Quick workaround crashes */
+                  if ((mask < mbegin) || ((mask + w) > mend))
+                    {
+                       ptr += dst->cache_entry.w;
+                       continue;
+                    }
+                  func(NULL, mask, dc->col.col, ptr, w);
+               }
+             else
+               func(NULL, NULL, dc->col.col, ptr, w);
 
            ptr += dst->cache_entry.w;
           }
index bb11c6b..9a0cf61 100644 (file)
@@ -7,7 +7,7 @@ evas_common_scale_init(void)
 }
 
 EAPI Eina_Bool
-evas_common_scale_rgba_in_to_out_clip_prepare(Cutout_Rects *reuse, const RGBA_Image *src __UNUSED__,
+evas_common_scale_rgba_in_to_out_clip_prepare(Cutout_Rects **reuse, const RGBA_Image *src __UNUSED__,
                                              const RGBA_Image *dst,
                                              RGBA_Draw_Context *dc,
                                              int dst_region_x, int dst_region_y,
@@ -26,7 +26,7 @@ evas_common_scale_rgba_in_to_out_clip_prepare(Cutout_Rects *reuse, const RGBA_Im
    /* our clip is 0 size.. abort */
    if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
      return EINA_FALSE;
-   reuse = evas_common_draw_context_apply_cutouts(dc, reuse);
+   *reuse = evas_common_draw_context_apply_cutouts(dc, *reuse);
 
    return EINA_TRUE;
 }
index e2ef8fa..5521c06 100644 (file)
@@ -12,7 +12,7 @@ EAPI void evas_common_rgba_image_scalecache_dump(void);
 
 EAPI void evas_common_scale_rgba_in_to_out_clip_sample_do   (const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h);
 EAPI void evas_common_scale_rgba_in_to_out_clip_smooth_do   (const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h);
-EAPI Eina_Bool evas_common_scale_rgba_in_to_out_clip_prepare     (Cutout_Rects *reuse, const RGBA_Image *src, const RGBA_Image *dst, RGBA_Draw_Context *dc, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h);
+EAPI Eina_Bool evas_common_scale_rgba_in_to_out_clip_prepare     (Cutout_Rects **reuse, const RGBA_Image *src, const RGBA_Image *dst, RGBA_Draw_Context *dc, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h);
 
 
 #endif /* _EVAS_SCALE_MAIN_H */
index 29badba..df67c63 100644 (file)
@@ -16,25 +16,25 @@ evas_common_scale_rgba_in_to_out_clip_smooth_do(const Cutout_Rects *reuse,
                                                 int dst_region_w, int dst_region_h)
 {
    evas_common_scale_rgba_in_to_out_clip_sample_do(reuse, clip, src, dst, dc,
-                                   src_region_x, src_region_y,
-                                   src_region_w, src_region_h,
-                                   dst_region_x, dst_region_y,
-                                   dst_region_w, dst_region_h);
+                                                   src_region_x, src_region_y,
+                                                   src_region_w, src_region_h,
+                                                   dst_region_x, dst_region_y,
+                                                   dst_region_w, dst_region_h);
 }
 
 EAPI void
 evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst,
-                                RGBA_Draw_Context *dc,
-                                int src_region_x, int src_region_y,
-                                int src_region_w, int src_region_h,
-                                int dst_region_x, int dst_region_y,
-                                int dst_region_w, int dst_region_h)
+                                             RGBA_Draw_Context *dc,
+                                             int src_region_x, int src_region_y,
+                                             int src_region_w, int src_region_h,
+                                             int dst_region_x, int dst_region_y,
+                                             int dst_region_w, int dst_region_h)
 {
    evas_common_scale_rgba_in_to_out_clip_sample(src, dst, dc,
-                                   src_region_x, src_region_y,
-                                   src_region_w, src_region_h,
-                                   dst_region_x, dst_region_y,
-                                   dst_region_w, dst_region_h);
+                                                src_region_x, src_region_y,
+                                                src_region_w, src_region_h,
+                                                dst_region_x, dst_region_y,
+                                                dst_region_w, dst_region_h);
 }
 #endif
 #endif
@@ -42,11 +42,11 @@ evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst,
 #ifdef BUILD_SCALE_SAMPLE
 EAPI void
 evas_common_scale_rgba_in_to_out_clip_sample(RGBA_Image *src, RGBA_Image *dst,
-                                RGBA_Draw_Context *dc,
-                                int src_region_x, int src_region_y,
-                                int src_region_w, int src_region_h,
-                                int dst_region_x, int dst_region_y,
-                                int dst_region_w, int dst_region_h)
+                                             RGBA_Draw_Context *dc,
+                                             int src_region_x, int src_region_y,
+                                             int src_region_w, int src_region_h,
+                                             int dst_region_x, int dst_region_y,
+                                             int dst_region_w, int dst_region_h)
 {
    static Cutout_Rects *rects = NULL;
    Cutout_Rect  *r;
@@ -60,12 +60,12 @@ evas_common_scale_rgba_in_to_out_clip_sample(RGBA_Image *src, RGBA_Image *dst,
    /* no cutouts - cut right to the chase */
    if (!dc->cutout.rects)
      {
-       scale_rgba_in_to_out_clip_sample_internal(src, dst, dc,
-                                                 src_region_x, src_region_y,
-                                                 src_region_w, src_region_h,
-                                                 dst_region_x, dst_region_y,
-                                                 dst_region_w, dst_region_h);
-       return;
+        scale_rgba_in_to_out_clip_sample_internal(src, dst, dc,
+                                                  src_region_x, src_region_y,
+                                                  src_region_w, src_region_h,
+                                                  dst_region_x, dst_region_y,
+                                                  dst_region_w, dst_region_h);
+        return;
      }
    /* save out clip info */
    c = dc->clip.use; cx = dc->clip.x; cy = dc->clip.y; cw = dc->clip.w; ch = dc->clip.h;
@@ -74,19 +74,19 @@ evas_common_scale_rgba_in_to_out_clip_sample(RGBA_Image *src, RGBA_Image *dst,
    /* our clip is 0 size.. abort */
    if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
      {
-       dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
-       return;
+        dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
+        return;
      }
    rects = evas_common_draw_context_apply_cutouts(dc, rects);
    for (i = 0; i < rects->active; ++i)
      {
-       r = rects->rects + i;
-       evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
-       scale_rgba_in_to_out_clip_sample_internal(src, dst, dc,
-                                                 src_region_x, src_region_y,
-                                                 src_region_w, src_region_h,
-                                                 dst_region_x, dst_region_y,
-                                                 dst_region_w, dst_region_h);
+        r = rects->rects + i;
+        evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
+        scale_rgba_in_to_out_clip_sample_internal(src, dst, dc,
+                                                  src_region_x, src_region_y,
+                                                  src_region_w, src_region_h,
+                                                  dst_region_x, dst_region_y,
+                                                  dst_region_w, dst_region_h);
 
      }
    /* restore clip info */
@@ -135,21 +135,22 @@ evas_common_scale_rgba_in_to_out_clip_sample_do(const Cutout_Rects *reuse,
 
 static void
 scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst,
-                                         RGBA_Draw_Context *dc,
-                                         int src_region_x, int src_region_y,
-                                         int src_region_w, int src_region_h,
-                                         int dst_region_x, int dst_region_y,
-                                         int dst_region_w, int dst_region_h)
+                                          RGBA_Draw_Context *dc,
+                                          int src_region_x, int src_region_y,
+                                          int src_region_w, int src_region_h,
+                                          int dst_region_x, int dst_region_y,
+                                          int dst_region_w, int dst_region_h)
 {
    int      x, y;
    int     *lin_ptr;
+   int      offset;
    DATA32  *buf, *dptr;
    DATA32 **row_ptr;
    DATA32  *ptr, *dst_ptr, *src_data, *dst_data;
    int      dst_clip_x, dst_clip_y, dst_clip_w, dst_clip_h;
    int      m_clip_x = 0, m_clip_y = 0, m_clip_w = 0, m_clip_h = 0, mdx = 0, mdy = 0;
    int      src_w, src_h, dst_w, dst_h;
-   RGBA_Gfx_Func func;
+   RGBA_Gfx_Func func, func2 = NULL;
    RGBA_Image *maskobj = NULL;
    DATA8   *mask = NULL;
 
@@ -168,59 +169,44 @@ scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst,
 
    if (dc->clip.use)
      {
-       dst_clip_x = dc->clip.x;
-       dst_clip_y = dc->clip.y;
-       dst_clip_w = dc->clip.w;
-       dst_clip_h = dc->clip.h;
-       if (dst_clip_x < 0)
-         {
-            dst_clip_w += dst_clip_x;
-            dst_clip_x = 0;
-         }
-       if (dst_clip_y < 0)
-         {
-            dst_clip_h += dst_clip_y;
-            dst_clip_y = 0;
-         }
-       if ((dst_clip_x + dst_clip_w) > dst_w)
-         dst_clip_w = dst_w - dst_clip_x;
-       if ((dst_clip_y + dst_clip_h) > dst_h)
-         dst_clip_h = dst_h - dst_clip_y;
+        dst_clip_x = dc->clip.x;
+        dst_clip_y = dc->clip.y;
+        dst_clip_w = dc->clip.w;
+        dst_clip_h = dc->clip.h;
+        if (dst_clip_x < 0)
+          {
+             dst_clip_w += dst_clip_x;
+             dst_clip_x = 0;
+          }
+        if (dst_clip_y < 0)
+          {
+             dst_clip_h += dst_clip_y;
+             dst_clip_y = 0;
+          }
+        if ((dst_clip_x + dst_clip_w) > dst_w)
+          dst_clip_w = dst_w - dst_clip_x;
+        if ((dst_clip_y + dst_clip_h) > dst_h)
+          dst_clip_h = dst_h - dst_clip_y;
      }
    else
      {
-       dst_clip_x = 0;
-       dst_clip_y = 0;
-       dst_clip_w = dst_w;
-       dst_clip_h = dst_h;
-     }
-
-   if (dc->mask.mask)
-     {
-        m_clip_x = dc->mask.x;
-        m_clip_y = dc->mask.y;
-        m_clip_w = dc->mask.mask->cache_entry.w;
-        m_clip_h = dc->mask.mask->cache_entry.h;
-        RECTS_CLIP_TO_RECT(m_clip_x, m_clip_y, m_clip_w, m_clip_h,
-                           dst_clip_x, dst_clip_y, dst_clip_w, dst_clip_h);
-        if ((m_clip_w <= 0) || (m_clip_h <= 0)) return;
-        dst_clip_x = m_clip_x;
-        dst_clip_y = m_clip_y;
-        dst_clip_w = m_clip_w;
-        dst_clip_h = m_clip_h;
+        dst_clip_x = 0;
+        dst_clip_y = 0;
+        dst_clip_w = dst_w;
+        dst_clip_h = dst_h;
      }
 
    if (dst_clip_x < dst_region_x)
      {
-       dst_clip_w += dst_clip_x - dst_region_x;
-       dst_clip_x = dst_region_x;
+        dst_clip_w += dst_clip_x - dst_region_x;
+        dst_clip_x = dst_region_x;
      }
    if ((dst_clip_x + dst_clip_w) > (dst_region_x + dst_region_w))
      dst_clip_w = dst_region_x + dst_region_w - dst_clip_x;
    if (dst_clip_y < dst_region_y)
      {
-       dst_clip_h += dst_clip_y - dst_region_y;
-       dst_clip_y = dst_region_y;
+        dst_clip_h += dst_clip_y - dst_region_y;
+        dst_clip_y = dst_region_y;
      }
    if ((dst_clip_y + dst_clip_h) > (dst_region_y + dst_region_h))
      dst_clip_h = dst_region_y + dst_region_h - dst_clip_y;
@@ -233,115 +219,105 @@ scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst,
    /* sanitise x */
    if (src_region_x < 0)
      {
-       dst_region_x -= (src_region_x * dst_region_w) / src_region_w;
-       dst_region_w += (src_region_x * dst_region_w) / src_region_w;
-       src_region_w += src_region_x;
-       src_region_x = 0;
+        dst_region_x -= (src_region_x * dst_region_w) / src_region_w;
+        dst_region_w += (src_region_x * dst_region_w) / src_region_w;
+        src_region_w += src_region_x;
+        src_region_x = 0;
      }
    if (src_region_x >= src_w) return;
    if ((src_region_x + src_region_w) > src_w)
      {
-       dst_region_w = (dst_region_w * (src_w - src_region_x)) / (src_region_w);
-       src_region_w = src_w - src_region_x;
+        dst_region_w = (dst_region_w * (src_w - src_region_x)) / (src_region_w);
+        src_region_w = src_w - src_region_x;
      }
    if (dst_region_w <= 0) return;
    if (src_region_w <= 0) return;
    if (dst_clip_x < 0)
      {
-       dst_clip_w += dst_clip_x;
-       dst_clip_x = 0;
+        dst_clip_w += dst_clip_x;
+        dst_clip_x = 0;
      }
    if (dst_clip_w <= 0) return;
    if (dst_clip_x >= dst_w) return;
    if (dst_clip_x < dst_region_x)
      {
-       dst_clip_w += (dst_clip_x - dst_region_x);
-       dst_clip_x = dst_region_x;
+        dst_clip_w += (dst_clip_x - dst_region_x);
+        dst_clip_x = dst_region_x;
      }
    if ((dst_clip_x + dst_clip_w) > dst_w)
      {
-       dst_clip_w = dst_w - dst_clip_x;
+        dst_clip_w = dst_w - dst_clip_x;
      }
    if (dst_clip_w <= 0) return;
 
    /* sanitise y */
    if (src_region_y < 0)
      {
-       dst_region_y -= (src_region_y * dst_region_h) / src_region_h;
-       dst_region_h += (src_region_y * dst_region_h) / src_region_h;
-       src_region_h += src_region_y;
-       src_region_y = 0;
+        dst_region_y -= (src_region_y * dst_region_h) / src_region_h;
+        dst_region_h += (src_region_y * dst_region_h) / src_region_h;
+        src_region_h += src_region_y;
+        src_region_y = 0;
      }
    if (src_region_y >= src_h) return;
    if ((src_region_y + src_region_h) > src_h)
      {
-       dst_region_h = (dst_region_h * (src_h - src_region_y)) / (src_region_h);
-       src_region_h = src_h - src_region_y;
+        dst_region_h = (dst_region_h * (src_h - src_region_y)) / (src_region_h);
+        src_region_h = src_h - src_region_y;
      }
    if (dst_region_h <= 0) return;
    if (src_region_h <= 0) return;
    if (dst_clip_y < 0)
      {
-       dst_clip_h += dst_clip_y;
-       dst_clip_y = 0;
+        dst_clip_h += dst_clip_y;
+        dst_clip_y = 0;
      }
    if (dst_clip_h <= 0) return;
    if (dst_clip_y >= dst_h) return;
    if (dst_clip_y < dst_region_y)
      {
-       dst_clip_h += (dst_clip_y - dst_region_y);
-       dst_clip_y = dst_region_y;
+        dst_clip_h += (dst_clip_y - dst_region_y);
+        dst_clip_y = dst_region_y;
      }
    if ((dst_clip_y + dst_clip_h) > dst_h)
      {
-       dst_clip_h = dst_h - dst_clip_y;
+        dst_clip_h = dst_h - dst_clip_y;
      }
    if (dst_clip_h <= 0) return;
 
-   /* allocate scale lookup tables */
-   lin_ptr = alloca(dst_clip_w * sizeof(int));
-   row_ptr = alloca(dst_clip_h * sizeof(DATA32 *));
-
    /* figure out dst jump */
    //dst_jump = dst_w - dst_clip_w;
 
    /* figure out dest start ptr */
    dst_ptr = dst_data + dst_clip_x + (dst_clip_y * dst_w);
 
-   if (dc->mask.mask)
+   if (!dc->clip.mask)
      {
-       func = evas_common_gfx_func_composite_pixel_mask_span_get(src, dst, dst_clip_w, dc->render_op);
-       maskobj = dc->mask.mask;
-       mask = maskobj->mask.mask;
-/*
-       if (1 || dst_region_w > src_region_w || dst_region_h > src_region_h){
-              printf("Mask w/h: %d/%d\n",maskobj->cache_entry.w,
-                              maskobj->cache_entry.h);
-              printf("Warning: Unscaled mask (%d/%d) // (%d/%d)\n",
-                              dst_region_w,src_region_w,
-                              dst_region_h,src_region_h);
-       }
- */
+        if (dc->mul.use)
+          func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, dc->render_op);
+        else
+          func = evas_common_gfx_func_composite_pixel_span_get(src, dst, dst_clip_w, dc->render_op);
      }
-   else if (dc->mul.use)
-     func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, dc->render_op);
    else
-     func = evas_common_gfx_func_composite_pixel_span_get(src, dst, dst_clip_w, dc->render_op);
+     {
+        func = evas_common_gfx_func_composite_pixel_mask_span_get(src, dst, dst_clip_w, dc->render_op);
+        if (dc->mul.use)
+          func2 = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, EVAS_RENDER_COPY);
+     }
 
    if ((dst_region_w == src_region_w) && (dst_region_h == src_region_h))
      {
 #ifdef HAVE_PIXMAN
 # ifdef PIXMAN_IMAGE_SCALE_SAMPLE        
-        if ((src->pixman.im) && (dst->pixman.im) && (!dc->mask.mask) &&
+        if ((src->pixman.im) && (dst->pixman.im) && (!dc->clip.mask) &&
             ((!dc->mul.use) ||
-                ((dc->mul.use) && (dc->mul.col == 0xffffffff))) &&
+             ((dc->mul.use) && (dc->mul.col == 0xffffffff))) &&
             ((dc->render_op == _EVAS_RENDER_COPY) ||
-                (dc->render_op == _EVAS_RENDER_BLEND)))
+             (dc->render_op == _EVAS_RENDER_BLEND)))
           {
              pixman_op_t op = PIXMAN_OP_OVER; // _EVAS_RENDER_BLEND
              if ((dc->render_op == _EVAS_RENDER_COPY) || (!src->cache_entry.flags.alpha))
                op = PIXMAN_OP_SRC;
-             
+
              pixman_image_composite(op,
                                     src->pixman.im, NULL,
                                     dst->pixman.im,
@@ -351,113 +327,176 @@ scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst,
                                     dst_clip_x, dst_clip_y,
                                     dst_clip_w, dst_clip_h);
           }
-        else if ((src->pixman.im) && (dst->pixman.im) &&
-                 (dc->mask.mask)  && (dc->mask.mask->pixman.im) &&
-                 ((dc->render_op == _EVAS_RENDER_COPY) ||
-                     (dc->render_op == _EVAS_RENDER_BLEND)))
-          {
-             // In case of pixel and color operation.
-             pixman_op_t op = PIXMAN_OP_OVER; // _EVAS_RENDER_BLEND
-             if ((dc->render_op == _EVAS_RENDER_COPY) || (!src->cache_entry.flags.alpha))
-               op = PIXMAN_OP_SRC;
-             
-             pixman_image_composite(op,
-                                    src->pixman.im, dc->mask.mask->pixman.im,
-                                    dst->pixman.im,
-                                    (dst_clip_x - dst_region_x) + src_region_x,
-                                    (dst_clip_y - dst_region_y) + src_region_y,
-                                    0, 0,
-                                    dst_clip_x, dst_clip_y,
-                                    dst_clip_w, dst_clip_h);
-          }
+        // NOTE: Removed old masking code with pixman
         else
-# endif          
+# endif
 #endif
           {
              ptr = src_data + ((dst_clip_y - dst_region_y + src_region_y) * src_w) + (dst_clip_x - dst_region_x) + src_region_x;
-             if (mask)
+
+             /* image masking */
+             if (dc->clip.mask)
                {
-                  mdx = (m_clip_x - dc->mask.x) + (m_clip_x - dst_clip_x);
-                  mdy = (m_clip_y - dc->mask.y) + (m_clip_y - dst_clip_y);
-                  mask += mdx + (mdy * maskobj->cache_entry.w);
+                  RGBA_Image *im = dc->clip.mask;
+                  DATA8 *mbegin = im->image.data8;
+                  DATA8 *mend = mbegin + (im->cache_entry.w * im->cache_entry.h);
+
+                  if (dc->mul.use)
+                    buf = alloca(dst_clip_w * sizeof(DATA32));
+
+                  for (y = 0; y < dst_clip_h; y++)
+                    {
+                       mask = im->image.data8
+                          + ((dst_clip_y - dc->clip.mask_y + y) * im->cache_entry.w)
+                          + (dst_clip_x - dc->clip.mask_x);
+
+                       /* FIXME!!! Quick workaround crashes */
+                       if ((mask < mbegin) || ((mask + dst_clip_w) > mend))
+                         {
+                            ptr += src_w;
+                            dst_ptr += dst_w;
+                            continue;
+                         }
+
+                       /* * blend here [clip_w *] ptr -> dst_ptr * */
+                       if (dc->mul.use)
+                         {
+                            func2(ptr, NULL, dc->mul.col, buf, dst_clip_w);
+                            func(buf, mask, 0, dst_ptr, dst_clip_w);
+                         }
+                       else
+                         func(ptr, mask, 0, dst_ptr, dst_clip_w);
+
+                       ptr += src_w;
+                       dst_ptr += dst_w;
+                    }
                }
-             for (y = 0; y < dst_clip_h; y++)
+             else
                {
-                /* * blend here [clip_w *] ptr -> dst_ptr * */
-                func(ptr, mask, dc->mul.col, dst_ptr, dst_clip_w);
+                  for (y = 0; y < dst_clip_h; y++)
+                    {
+                       /* * blend here [clip_w *] ptr -> dst_ptr * */
+                       func(ptr, NULL, dc->mul.col, dst_ptr, dst_clip_w);
 
-                ptr += src_w;
-                dst_ptr += dst_w;
-                if (mask) mask += maskobj->cache_entry.w;
+                       ptr += src_w;
+                       dst_ptr += dst_w;
+                    }
                }
-         }
+          }
      }
    else
      {
+        /* allocate scale lookup tables */
+        lin_ptr = alloca(dst_clip_w * sizeof(int));
+        row_ptr = alloca(dst_clip_h * sizeof(DATA32 *));
+
         /* fill scale tables */
-       for (x = 0; x < dst_clip_w; x++)
+        for (x = 0; x < dst_clip_w; x++)
           lin_ptr[x] = (((x + dst_clip_x - dst_region_x) * src_region_w) / dst_region_w) + src_region_x;
-       for (y = 0; y < dst_clip_h; y++)
+        for (y = 0; y < dst_clip_h; y++)
           row_ptr[y] = src_data + (((((y + dst_clip_y - dst_region_y) * src_region_h) / dst_region_h)
                                     + src_region_y) * src_w);
-       /* scale to dst */
-       dptr = dst_ptr;
+
+        /* scale to dst */
+        dptr = dst_ptr;
+        offset = dst_clip_y - dst_region_y;
+
 #ifdef DIRECT_SCALE
-       if ((!src->cache_entry.flags.alpha) &&
+        if ((!src->cache_entry.flags.alpha) &&
             (!dst->cache_entry.flags.alpha) &&
-            (!dc->mul.use))
-         {
-            for (y = 0; y < dst_clip_h; y++)
-              {
-
-                dst_ptr = dptr;
-                for (x = 0; x < dst_clip_w; x++)
-                  {
-                    ptr = row_ptr[y] + lin_ptr[x];
-                    *dst_ptr = *ptr;
-                    dst_ptr++;
-                  }
-
-                dptr += dst_w;
+            (!dc->mul.use) &&
+            (!dc->clip.mask))
+          {
+             for (y = 0; y < dst_clip_h; y++)
+               {
+                  dst_ptr = dptr;
+                  for (x = 0; x < dst_clip_w; x++)
+                    {
+                       ptr = row_ptr[y] + lin_ptr[x];
+                       *dst_ptr = *ptr;
+                       dst_ptr++;
+                    }
+
+                  dptr += dst_w;
                }
-         }
-       else
+          }
+        else
 #endif
-         {
-           /* a scanline buffer */
+          {
+             /* a scanline buffer */
              buf = alloca(dst_clip_w * sizeof(DATA32));
-             for (y = 0; y < dst_clip_h; y++)
+
+             /* image masking */
+             if (dc->clip.mask)
+               {
+                  RGBA_Image *im = dc->clip.mask;
+                  DATA8 *mbegin = im->image.data8;
+                  DATA8 *mend = mbegin + (im->cache_entry.w * im->cache_entry.h);
+
+                  for (y = 0; y < dst_clip_h; y++)
+                    {
+                       dst_ptr = buf;
+                       mask = im->image.data8
+                          + ((dst_clip_y - dc->clip.mask_y + y) * im->cache_entry.w)
+                          + (dst_clip_x - dc->clip.mask_x);
+
+                       /* FIXME!!! Quick workaround crashes */
+                       if ((mask < mbegin) || ((mask + dst_clip_w) > mend))
+                         {
+                            dptr += dst_w;
+                            continue;
+                         }
+
+                       for (x = 0; x < dst_clip_w; x++)
+                         {
+                            ptr = row_ptr[y] + lin_ptr[x];
+                            *dst_ptr = *ptr;
+                            dst_ptr++;
+                         }
+
+                       /* * blend here [clip_w *] buf -> dptr * */
+                       if (dc->mul.use) func2(buf, NULL, dc->mul.col, buf, dst_clip_w);
+                       func(buf, mask, 0, dptr, dst_clip_w);
+
+                       dptr += dst_w;
+                    }
+               }
+             else
                {
-                dst_ptr = buf;
-                for (x = 0; x < dst_clip_w; x++)
-                  {
-                    ptr = row_ptr[y] + lin_ptr[x];
-                    *dst_ptr = *ptr;
-                    dst_ptr++;
-                  }
-                /* * blend here [clip_w *] buf -> dptr * */
-                func(buf, NULL, dc->mul.col, dptr, dst_clip_w);
-
-                dptr += dst_w;
+                  for (y = 0; y < dst_clip_h; y++)
+                    {
+                       dst_ptr = buf;
+                       for (x = 0; x < dst_clip_w; x++)
+                         {
+                            ptr = row_ptr[y] + lin_ptr[x];
+                            *dst_ptr = *ptr;
+                            dst_ptr++;
+                         }
+
+                       /* * blend here [clip_w *] buf -> dptr * */
+                       func(buf, NULL, dc->mul.col, dptr, dst_clip_w);
+
+                       dptr += dst_w;
+                    }
                }
-         }
+          }
      }
 }
 #else
 #ifdef BUILD_SCALE_SMOOTH
 EAPI void
 evas_common_scale_rgba_in_to_out_clip_sample(RGBA_Image *src, RGBA_Image *dst,
-                                RGBA_Draw_Context *dc,
-                                int src_region_x, int src_region_y,
-                                int src_region_w, int src_region_h,
-                                int dst_region_x, int dst_region_y,
-                                int dst_region_w, int dst_region_h)
+                                             RGBA_Draw_Context *dc,
+                                             int src_region_x, int src_region_y,
+                                             int src_region_w, int src_region_h,
+                                             int dst_region_x, int dst_region_y,
+                                             int dst_region_w, int dst_region_h)
 {
    evas_common_scale_rgba_in_to_out_clip_smooth(src, dst, dc,
-                                   src_region_x, src_region_y,
-                                   src_region_w, src_region_h,
-                                   dst_region_x, dst_region_y,
-                                   dst_region_w, dst_region_h);
+                                                src_region_x, src_region_y,
+                                                src_region_w, src_region_h,
+                                                dst_region_x, dst_region_y,
+                                                dst_region_w, dst_region_h);
 }
 
 EAPI void
@@ -471,10 +510,10 @@ evas_common_scale_rgba_in_to_out_clip_sample_do(const Cutout_Rects *reuse,
                                                 int dst_region_w, int dst_region_h)
 {
    evas_common_scale_rgba_in_to_out_clip_smooth_do(reuse, clip, src, dst, dc,
-                                   src_region_x, src_region_y,
-                                   src_region_w, src_region_h,
-                                   dst_region_x, dst_region_y,
-                                   dst_region_w, dst_region_h);
+                                                   src_region_x, src_region_y,
+                                                   src_region_w, src_region_h,
+                                                   dst_region_x, dst_region_y,
+                                                   dst_region_w, dst_region_h);
 }
 #endif
 #endif
index a3cb379..05b9b2a 100644 (file)
@@ -449,6 +449,14 @@ evas_common_scale_rgba_mipmap_down_1x2_mmx(DATA32 *src, DATA32 *dst, int src_w,
 #  undef SCALE_USING_MMX
 #  include "evas_scale_smooth_scaler.c"
 # endif
+# ifdef BUILD_NEON
+#  undef SCALE_FUNC
+#  undef SCALE_USING_NEON
+#  define SCALE_USING_NEON
+#  define SCALE_FUNC evas_common_scale_rgba_in_to_out_clip_smooth_neon
+#  include "evas_scale_smooth_scaler.c"
+#  undef SCALE_USING_NEON
+# endif
 EAPI void
 evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst,
                                 RGBA_Draw_Context *dc,
@@ -484,6 +492,15 @@ evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst,
                                               dst_region_w, dst_region_h);
        else
 # endif
+# ifdef BUILD_NEON
+       if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+         evas_common_scale_rgba_in_to_out_clip_smooth_neon(src, dst, dc,
+                                            src_region_x, src_region_y,
+                                            src_region_w, src_region_h,
+                                            dst_region_x, dst_region_y,
+                                            dst_region_w, dst_region_h);
+       else
+# endif
 # ifdef BUILD_C
          evas_common_scale_rgba_in_to_out_clip_smooth_c(src, dst, dc,
                                             src_region_x, src_region_y,
@@ -517,6 +534,15 @@ evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst,
                                               dst_region_w, dst_region_h);
        else
 # endif
+# ifdef BUILD_NEON
+       if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+         evas_common_scale_rgba_in_to_out_clip_smooth_neon(src, dst, dc,
+                                            src_region_x, src_region_y,
+                                            src_region_w, src_region_h,
+                                            dst_region_x, dst_region_y,
+                                            dst_region_w, dst_region_h);
+       else
+# endif
 # ifdef BUILD_C
          evas_common_scale_rgba_in_to_out_clip_smooth_c(src, dst, dc,
                                             src_region_x, src_region_y,
@@ -561,6 +587,15 @@ evas_common_scale_rgba_in_to_out_clip_smooth_do(const Cutout_Rects *reuse,
                                               dst_region_w, dst_region_h);
        else
 # endif
+# ifdef BUILD_NEON
+       if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+         evas_common_scale_rgba_in_to_out_clip_smooth_neon(src, dst, dc,
+                                            src_region_x, src_region_y,
+                                            src_region_w, src_region_h,
+                                            dst_region_x, dst_region_y,
+                                            dst_region_w, dst_region_h);
+       else
+# endif
 # ifdef BUILD_C
          evas_common_scale_rgba_in_to_out_clip_smooth_c(src, dst, dc,
                                             src_region_x, src_region_y,
@@ -587,6 +622,15 @@ evas_common_scale_rgba_in_to_out_clip_smooth_do(const Cutout_Rects *reuse,
                                               dst_region_w, dst_region_h);
        else
 # endif
+# ifdef BUILD_NEON
+       if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+         evas_common_scale_rgba_in_to_out_clip_smooth_neon(src, dst, dc,
+                                            src_region_x, src_region_y,
+                                            src_region_w, src_region_h,
+                                            dst_region_x, dst_region_y,
+                                            dst_region_w, dst_region_h);
+       else
+# endif
 # ifdef BUILD_C
          evas_common_scale_rgba_in_to_out_clip_smooth_c(src, dst, dc,
                                             src_region_x, src_region_y,
index 599bfda..3b04442 100644 (file)
@@ -186,26 +186,17 @@ SCALE_FUNC(RGBA_Image *src, RGBA_Image *dst,
  *
  */
 
-   /* if 1:1 scale */
-   if ((dst_region_w == src_region_w) &&
-       (dst_region_h == src_region_h))
+   /* scaling up only - dont need anything except original */
+   //  if ((!dc->anti_alias) || ((dst_region_w >= src_region_w) && (dst_region_h >= src_region_h)))
+   if (((dst_region_w >= src_region_w) && (dst_region_h >= src_region_h)))
      {
-#include "evas_scale_smooth_scaler_noscale.c"
+#include "evas_scale_smooth_scaler_up.c"
+        return;
      }
    else
+     /* scaling down... funkiness */
      {
-       /* scaling up only - dont need anything except original */
-//     if ((!dc->anti_alias) || ((dst_region_w >= src_region_w) && (dst_region_h >= src_region_h)))
-       if (((dst_region_w >= src_region_w) && (dst_region_h >= src_region_h)))
-         {
-#include "evas_scale_smooth_scaler_up.c"
-            return;
-         }
-       else
-         /* scaling down... funkiness */
-         {
 #include "evas_scale_smooth_scaler_down.c"
-            return;
-         }
+        return;
      }
 }
index 357eb32..314be38 100644 (file)
@@ -5,23 +5,33 @@
    int     *yapoints, *yapp;
    DATA32  *buf, *src_data;
 
-   RGBA_Gfx_Func      func;
+   RGBA_Gfx_Func      func, func2 = NULL;
 
    src_data = src->image.data;
-   
+
    /* some maximum region sizes to avoid insane calc point tables */
    SCALE_CALC_X_POINTS(xpoints, src_region_w, dst_region_w, dst_clip_x - dst_region_x, dst_clip_w);
    SCALE_CALC_Y_POINTS(ypoints, src_data, src_w, src_region_h, dst_region_h, dst_clip_y - dst_region_y, dst_clip_h);
    SCALE_CALC_A_POINTS(xapoints, src_region_w, dst_region_w, dst_clip_x - dst_region_x, dst_clip_w);
    SCALE_CALC_A_POINTS(yapoints, src_region_h, dst_region_h, dst_clip_y - dst_region_y, dst_clip_h);
-   
+
    /* a scanline buffer */
    buf = alloca(dst_clip_w * sizeof(DATA32));
-   
-   if (dc->mul.use)
-      func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, dc->render_op);
+
+   if (!dc->clip.mask)
+     {
+        if (dc->mul.use)
+          func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, dc->render_op);
+        else
+          func = evas_common_gfx_func_composite_pixel_span_get(src, dst, dst_clip_w, dc->render_op);
+     }
    else
-      func = evas_common_gfx_func_composite_pixel_span_get(src, dst, dst_clip_w, dc->render_op);
+     {
+        func = evas_common_gfx_func_composite_pixel_mask_span_get(src, dst, dst_clip_w, dc->render_op);
+        if (dc->mul.use)
+          func2 = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, EVAS_RENDER_COPY);
+     }
+
    /* scaling down vertically */
    if ((dst_region_w >= src_region_w) &&
        (dst_region_h <  src_region_h))
index 544b8c2..6ea4ca6 100644 (file)
@@ -1,10 +1,12 @@
 {
    int Cx, j;
    DATA32 *pix, *dptr, *pbuf, **yp;
+   DATA8 *mask;
    int r, g, b, a, rr, gg, bb, aa;
    int *xp, xap, yap, pos;
    //int dyy, dxx;
    int w = dst_clip_w;
+   int y;
 
    dptr = dst_ptr;
    pos = (src_region_y * src_w) + src_region_x;
@@ -19,6 +21,7 @@
 
    if (src->cache_entry.flags.alpha)
      {
+        y = 0;
        while (dst_clip_h--)
          {
            while (dst_clip_w--)
                xp++;  xapp++;
              }
 
-           func(buf, NULL, dc->mul.col, dptr, w);
+            if (!dc->clip.mask)
+              func(buf, NULL, dc->mul.col, dptr, w);
+            else
+              {
+                 RGBA_Image *im = dc->clip.mask;
+                 DATA8 *mbegin = im->image.data8;
+                 DATA8 *mend = mbegin + (im->cache_entry.w * im->cache_entry.h);
+                 mask = im->image.data8
+                    + ((dst_clip_y - dc->clip.mask_y + y) * im->cache_entry.w)
+                    + (dst_clip_x - dc->clip.mask_x);
+
+                 /* FIXME!!! Quick workaround crashes */
+                 if ((mask < mbegin) || ((mask + w) > mend))
+                   return;
+
+                 if (dc->mul.use) func2(buf, NULL, dc->mul.col, buf, w);
+                 func(buf, mask, 0, dptr, w);
+              }
+            y++;
 
            pbuf = buf;
            dptr += dst_w;  dst_clip_w = w;
 #ifdef DIRECT_SCALE
         if ((!src->cache_entry.flags.alpha) &&
            (!dst->cache_entry.flags.alpha) &&
-           (!dc->mul.use))
+           (!dc->mul.use) &&
+            (!dc->clip.mask))
          {
             while (dst_clip_h--)
               {
                                          ((b + (1 << 3)) >> 4));
                      xp++;  xapp++;
                    }
-                 
+
                  dptr += dst_w;  dst_clip_w = w;
                  yp++;  yapp++;
                  xp = xpoints;// + dxx;
        else
 #endif
          {
+             y = 0;
             while (dst_clip_h--)
               {
                 while (dst_clip_w--)
                                         ((b + (1 << 3)) >> 4));
                     xp++;  xapp++;
                   }
-                
-                func(buf, NULL, dc->mul.col, dptr, w);
+
+                 if (!dc->clip.mask)
+                   func(buf, NULL, dc->mul.col, dptr, w);
+                 else
+                   {
+                      RGBA_Image *im = dc->clip.mask;
+                      DATA8 *mbegin = im->image.data8;
+                      DATA8 *mend = mbegin + (im->cache_entry.w * im->cache_entry.h);
+                      mask = im->image.data8
+                         + ((dst_clip_y - dc->clip.mask_y + y) * im->cache_entry.w)
+                         + (dst_clip_x - dc->clip.mask_x);
+
+                      /* FIXME!!! Quick workaround crashes */
+                      if ((mask < mbegin) || ((mask + w) > mend))
+                        return;
+
+                      if (dc->mul.use) func2(buf, NULL, dc->mul.col, buf, w);
+                      func(buf, mask, 0, dptr, w);
+                   }
+                 y++;
 
                 pbuf = buf;
                 dptr += dst_w;  dst_clip_w = w;
index 180d37b..956576e 100644 (file)
@@ -1,11 +1,13 @@
 {
    int Cx, Cy, i, j;
    DATA32 *dptr, *sptr, *pix, *pbuf;
+   DATA8 *mask;
    int a, r, g, b, rx, gx, bx, ax;
    int xap, yap, pos;
    //int dyy, dxx;
-   
-   DATA32  **yp; 
+   int y;
+
+   DATA32  **yp;
    int *xp;
    int w = dst_clip_w;
 
 #if 1
    if (src->cache_entry.flags.alpha)
      {
+        y = 0;
        while (dst_clip_h--)
          {
            Cy = *yapp >> 16;
            yap = *yapp & 0xffff;
-                 
+
            while (dst_clip_w--)
              {
                Cx = *xapp >> 16;
                xap = *xapp & 0xffff;
-                      
+
                sptr = *yp + *xp + pos;
                pix = sptr;
                sptr += src_w;
-                      
+
                ax = (A_VAL(pix) * xap) >> 9;
                rx = (R_VAL(pix) * xap) >> 9;
                gx = (G_VAL(pix) * xap) >> 9;
                    gx += (G_VAL(pix) * i) >> 9;
                    bx += (B_VAL(pix) * i) >> 9;
                  }
-                      
+
                a = (ax * yap) >> 14;
                r = (rx * yap) >> 14;
                g = (gx * yap) >> 14;
                b = (bx * yap) >> 14;
-                      
+
                for (j = (1 << 14) - yap; j > Cy; j -= Cy)
                  {
                    pix = sptr;
                        gx += (G_VAL(pix) * i) >> 9;
                        bx += (B_VAL(pix) * i) >> 9;
                      }
-                   
+
                    a += (ax * j) >> 14;
                    r += (rx * j) >> 14;
                    g += (gx * j) >> 14;
                    b += (bx * j) >> 14;
                  }
-               *pbuf++ = ARGB_JOIN(((a + (1 << 4)) >> 5), 
-                                   ((r + (1 << 4)) >> 5), 
-                                   ((g + (1 << 4)) >> 5), 
+               *pbuf++ = ARGB_JOIN(((a + (1 << 4)) >> 5),
+                                   ((r + (1 << 4)) >> 5),
+                                   ((g + (1 << 4)) >> 5),
                                    ((b + (1 << 4)) >> 5));
                xp++;  xapp++;
              }
-           
-           func(buf, NULL, dc->mul.col, dptr, w);
+
+            if (!dc->clip.mask)
+              func(buf, NULL, dc->mul.col, dptr, w);
+            else
+              {
+                 RGBA_Image *im = dc->clip.mask;
+                 DATA8 *mbegin = im->image.data8;
+                 DATA8 *mend = mbegin + (im->cache_entry.w * im->cache_entry.h);
+                 mask = im->image.data8
+                    + ((dst_clip_y - dc->clip.mask_y + y) * im->cache_entry.w)
+                    + (dst_clip_x - dc->clip.mask_x);
+
+                 /* FIXME!!! Quick workaround crashes */
+                 if ((mask < mbegin) || ((mask + w) > mend))
+                   return;
+
+                 if (dc->mul.use) func2(buf, NULL, dc->mul.col, buf, w);
+                 func(buf, mask, 0, dptr, w);
+              }
+            y++;
 
            pbuf = buf;
            dptr += dst_w;   dst_clip_w = w;
 #ifdef DIRECT_SCALE
         if ((!src->cache_entry.flags.alpha) &&
            (!dst->cache_entry.flags.alpha) &&
-           (!dc->mul.use))
+           (!dc->mul.use) &&
+            (!dc->clip.mask))
          {
             while (dst_clip_h--)
               {
                 Cy = *yapp >> 16;
                 yap = *yapp & 0xffff;
-                      
+
                 pbuf = dptr;
                 while (dst_clip_w--)
                   {
                     Cx = *xapp >> 16;
                     xap = *xapp & 0xffff;
-                    
+
                     sptr = *yp + *xp + pos;
                     pix = sptr;
                     sptr += src_w;
-                           
+
                     rx = (R_VAL(pix) * xap) >> 9;
                     gx = (G_VAL(pix) * xap) >> 9;
                     bx = (B_VAL(pix) * xap) >> 9;
                     r = (rx * yap) >> 14;
                     g = (gx * yap) >> 14;
                     b = (bx * yap) >> 14;
-    
+
                     for (j = (1 << 14) - yap; j > Cy; j -= Cy)
                       {
                         pix = sptr;
                             gx += (G_VAL(pix) * i) >> 9;
                             bx += (B_VAL(pix) * i) >> 9;
                           }
-                        
+
                         r += (rx * Cy) >> 14;
                         g += (gx * Cy) >> 14;
                         b += (bx * Cy) >> 14;
                         g += (gx * j) >> 14;
                         b += (bx * j) >> 14;
                       }
-                    *pbuf++ = ARGB_JOIN(0xff, 
-                                        ((r + (1 << 4)) >> 5), 
-                                        ((g + (1 << 4)) >> 5), 
+                    *pbuf++ = ARGB_JOIN(0xff,
+                                        ((r + (1 << 4)) >> 5),
+                                        ((g + (1 << 4)) >> 5),
                                         ((b + (1 << 4)) >> 5));
                     xp++;  xapp++;
                   }
               }
          }
        else
-#endif   
+#endif
          {
+             y = 0;
             while (dst_clip_h--)
               {
                 Cy = *yapp >> 16;
                 yap = *yapp & 0xffff;
-                      
+
                 while (dst_clip_w--)
                   {
                     Cx = *xapp >> 16;
                     xap = *xapp & 0xffff;
-                           
+
                     sptr = *yp + *xp + pos;
                     pix = sptr;
                     sptr += src_w;
-                           
+
                     rx = (R_VAL(pix) * xap) >> 9;
                     gx = (G_VAL(pix) * xap) >> 9;
                     bx = (B_VAL(pix) * xap) >> 9;
                     r = (rx * yap) >> 14;
                     g = (gx * yap) >> 14;
                     b = (bx * yap) >> 14;
-                           
+
                     for (j = (1 << 14) - yap; j > Cy; j -= Cy)
                       {
                         pix = sptr;
                         g += (gx * j) >> 14;
                         b += (bx * j) >> 14;
                       }
-                    *pbuf++ = ARGB_JOIN(0xff, 
-                                        ((r + (1 << 4)) >> 5), 
-                                        ((g + (1 << 4)) >> 5), 
+                    *pbuf++ = ARGB_JOIN(0xff,
+                                        ((r + (1 << 4)) >> 5),
+                                        ((g + (1 << 4)) >> 5),
                                         ((b + (1 << 4)) >> 5));
                     xp++;  xapp++;
                   }
 
-                func(buf, NULL, dc->mul.col, dptr, w);
+                 if (!dc->clip.mask)
+                   func(buf, NULL, dc->mul.col, dptr, w);
+                 else
+                   {
+                      RGBA_Image *im = dc->clip.mask;
+                      DATA8 *mbegin = im->image.data8;
+                      DATA8 *mend = mbegin + (im->cache_entry.w * im->cache_entry.h);
+                      mask = im->image.data8
+                         + ((dst_clip_y - dc->clip.mask_y + y) * im->cache_entry.w)
+                         + (dst_clip_x - dc->clip.mask_x);
+
+                      /* FIXME!!! Quick workaround crashes */
+                      if ((mask < mbegin) || ((mask + w) > mend))
+                        return;
+
+                      if (dc->mul.use) func2(buf, NULL, dc->mul.col, buf, w);
+                      func(buf, mask, 0, dptr, w);
+                   }
+                 y++;
 
                 pbuf = buf;
                 dptr += dst_w;   dst_clip_w = w;
index d7c10f9..9cc3658 100644 (file)
@@ -1,10 +1,12 @@
 {
    int Cy, j;
    DATA32 *dptr, *pix, *pbuf, **yp;
+   DATA8 *mask;
    int r, g, b, a, rr, gg, bb, aa;
    int *xp, xap, yap, pos;
    //int dyy, dxx;
    int w = dst_clip_w;
+   int y;
 
    dptr = dst_ptr;
    pos = (src_region_y * src_w) + src_region_x;
@@ -19,6 +21,7 @@
 
    if (src->cache_entry.flags.alpha)
      {
+        y = 0;
        while (dst_clip_h--)
          {
            Cy = *yapp >> 16;
                                    ((b + (1 << 3)) >> 4));
                xp++;  xapp++;
              }
-           
-           func(buf, NULL, dc->mul.col, dptr, w);
+
+            if (!dc->clip.mask)
+              func(buf, NULL, dc->mul.col, dptr, w);
+            else
+              {
+                 RGBA_Image *im = dc->clip.mask;
+                 DATA8 *mbegin = im->image.data8;
+                 DATA8 *mend = mbegin + (im->cache_entry.w * im->cache_entry.h);
+                 mask = im->image.data8
+                    + ((dst_clip_y - dc->clip.mask_y + y) * im->cache_entry.w)
+                    + (dst_clip_x - dc->clip.mask_x);
+
+                 /* FIXME!!! Quick workaround crashes */
+                 if ((mask < mbegin) || ((mask + w) > mend))
+                   return;
+
+                 if (dc->mul.use) func2(buf, NULL, dc->mul.col, buf, w);
+                 func(buf, mask, 0, dptr, w);
+              }
+            y++;
 
            pbuf = buf;
            dptr += dst_w;  dst_clip_w = w;
 #ifdef DIRECT_SCALE
         if ((!src->cache_entry.flags.alpha) &&
            (!dst->cache_entry.flags.alpha) &&
-           (!dc->mul.use))
+           (!dc->mul.use) &&
+            (!dc->clip.mask))
          {
             while (dst_clip_h--)
               {
        else
 #endif
          {
+             y = 0;
             while (dst_clip_h--)
               {
                 Cy = *yapp >> 16;
                                         ((b + (1 << 3)) >> 4));
                     xp++;  xapp++;
                   }
-                
-                func(buf, NULL, dc->mul.col, dptr, w);
+
+                 if (!dc->clip.mask)
+                   func(buf, NULL, dc->mul.col, dptr, w);
+                 else
+                   {
+                      RGBA_Image *im = dc->clip.mask;
+                      DATA8 *mbegin = im->image.data8;
+                      DATA8 *mend = mbegin + (im->cache_entry.w * im->cache_entry.h);
+                      mask = im->image.data8
+                         + ((dst_clip_y - dc->clip.mask_y + y) * im->cache_entry.w)
+                         + (dst_clip_x - dc->clip.mask_x);
+
+                      /* FIXME!!! Quick workaround crashes */
+                      if ((mask < mbegin) || ((mask + w) > mend))
+                        return;
+
+                      if (dc->mul.use) func2(buf, NULL, dc->mul.col, buf, w);
+                      func(buf, mask, 0, dptr, w);
+                   }
+                 y++;
 
                 pbuf = buf;
                 dptr += dst_w;  dst_clip_w = w;
diff --git a/src/lib/engines/common/evas_scale_smooth_scaler_noscale.c b/src/lib/engines/common/evas_scale_smooth_scaler_noscale.c
deleted file mode 100644 (file)
index 4f7d06b..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-{
-   DATA32 *ptr;
-   RGBA_Gfx_Func func;
-   RGBA_Image *maskobj;
-   DATA8 *mask = NULL;
-
-   ptr = src->image.data + ((dst_clip_y - dst_region_y + src_region_y) * src_w) + (dst_clip_x - dst_region_x) + src_region_x;
-   if (dc->mask.mask)
-     {
-       func = evas_common_gfx_func_composite_pixel_mask_span_get(NULL, NULL, dst_clip_w, dc->render_op);
-       maskobj = dc->mask.mask;
-       mask = maskobj->mask.mask;
-     }
-   else if (dc->mul.use)
-       func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, dc->render_op);
-   else
-       func = evas_common_gfx_func_composite_pixel_span_get(src, dst, dst_clip_w, dc->render_op);
-
-   if (mask)
-     {
-   //     mask += dst_clip_x - dc->mask.x;
-     //   mask += (dst_clip_y - dc->mask.y) * maskobj->cache_entry.w;
-        while (dst_clip_h--)
-          {
-           func(ptr, mask, dc->mul.col, dst_ptr, dst_clip_w);
-
-           ptr += src_w;
-           dst_ptr += dst_w;
-           mask += maskobj->cache_entry.w;
-          }
-     }
-   else
-     {
-        while (dst_clip_h--)
-          {
-           func(ptr, NULL, dc->mul.col, dst_ptr, dst_clip_w);
-
-           ptr += src_w;
-           dst_ptr += dst_w;
-          }
-     }
-}
-
-/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
index 2f323bd..fc8f203 100644 (file)
@@ -10,7 +10,8 @@
 
    DATA32      *psrc, *pdst, *pdst_end;
    DATA32      *buf, *pbuf, *pbuf_end;
-   RGBA_Gfx_Func  func = NULL;
+   DATA8       *mask;
+   RGBA_Gfx_Func  func = NULL, func2 = NULL;
 
    /* check value  to make overflow(only check value related with overflow) */
    if ((src_region_w > SCALE_SIZE_MAX) ||
@@ -19,7 +20,7 @@
    /* a scanline buffer */
    pdst = dst_ptr;  // it's been set at (dst_clip_x, dst_clip_y)
    pdst_end = pdst + (dst_clip_h * dst_w);
-   if (!dc->mul.use)
+   if (!dc->mul.use && !dc->clip.mask)
      {
        if ((dc->render_op == _EVAS_RENDER_BLEND) && !src->cache_entry.flags.alpha)
          { direct_scale = 1;  buf_step = dst->cache_entry.w; }
    if (!direct_scale)
      {
        buf = alloca(dst_clip_w * sizeof(DATA32));
-       if (dc->mul.use)
-          func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, dc->render_op);
-       else
-          func  = evas_common_gfx_func_composite_pixel_span_get(src, dst, dst_clip_w, dc->render_op);
+
+        if (!dc->clip.mask)
+          {
+             if (dc->mul.use)
+               func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, dc->render_op);
+             else
+               func  = evas_common_gfx_func_composite_pixel_span_get(src, dst, dst_clip_w, dc->render_op);
+          }
+        else
+          {
+             func = evas_common_gfx_func_composite_pixel_mask_span_get(src, dst, dst_clip_w, dc->render_op);
+             if (dc->mul.use)
+               func2 = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, EVAS_RENDER_COPY);
+          }
      }
    else
        buf = pdst;
@@ -61,6 +72,7 @@
    if (drh == srh)
      {
        int  sxx0 = sxx;
+        int  y = 0;
        psrc = src->image.data + (src_w * (sry + cy)) + srx;
        while (pdst < pdst_end)
          {
                }
            /* * blend here [clip_w *] buf -> dptr * */
            if (!direct_scale)
-             func(buf, NULL, dc->mul.col, pdst, dst_clip_w);
+              {
+                 if (!dc->clip.mask)
+                   func(buf, NULL, dc->mul.col, pdst, dst_clip_w);
+                 else
+                   {
+                      RGBA_Image *im = dc->clip.mask;
+                      DATA8 *mbegin = im->image.data8;
+                      DATA8 *mend = mbegin + (im->cache_entry.w * im->cache_entry.h);
+                      mask = im->image.data8
+                         + ((dst_clip_y - dc->clip.mask_y + y) * im->cache_entry.w)
+                         + (dst_clip_x - dc->clip.mask_x);
+
+                      /* FIXME!!! Quick workaround crashes */
+                      if ((mask < mbegin) || ((mask + dst_clip_w) > mend))
+                        return;
+
+                      if (dc->mul.use) func2(buf, NULL, dc->mul.col, buf, dst_clip_w);
+                      func(buf, mask, 0, pdst, dst_clip_w);
+                   }
+                 y++;
+              }
 
            pdst += dst_w;
            psrc += src_w;
    else if (drw == srw)
      {
        DATA32  *ps = src->image.data + (src_w * sry) + srx + cx;
+        int y = 0;
 
        while (pdst < pdst_end)
          {
              }
            /* * blend here [clip_w *] buf -> dptr * */
            if (!direct_scale)
-             func(buf, NULL, dc->mul.col, pdst, dst_clip_w);
+              {
+                 if (!dc->clip.mask)
+                   func(buf, NULL, dc->mul.col, pdst, dst_clip_w);
+                 else
+                   {
+                      RGBA_Image *im = dc->clip.mask;
+                      DATA8 *mbegin = im->image.data8;
+                      DATA8 *mend = mbegin + (im->cache_entry.w * im->cache_entry.h);
+                      mask = im->image.data8
+                         + ((dst_clip_y - dc->clip.mask_y + y) * im->cache_entry.w)
+                         + (dst_clip_x - dc->clip.mask_x);
+
+                      /* FIXME!!! Quick workaround crashes */
+                      if ((mask < mbegin) || ((mask + dst_clip_w) > mend))
+                        return;
+
+                      if (dc->mul.use) func2(buf, NULL, dc->mul.col, buf, dst_clip_w);
+                      func(buf, mask, 0, pdst, dst_clip_w);
+                   }
+                 y++;
+              }
+
            pdst += dst_w;
            syy += dsyy;
            buf += buf_step;
      {
        DATA32  *ps = src->image.data + (src_w * sry) + srx;
        int     sxx0 = sxx;
+        int     y = 0;
 
        while (pdst < pdst_end)
          {
            MOV_A2R(ay, mm4)
            pxor_r2r(mm0, mm0);
            MOV_A2R(ALPHA_255, mm5)
+#elif defined SCALE_USING_NEON
+            FPU_NEON;
+            VDUP_NEON(d12, ay);
+            VMOV_I2R_NEON(q2, #255);
 #endif
            pbuf = buf;  pbuf_end = buf + dst_clip_w;
            sxx = sxx0;
                INTERP_256_R2R(mm4, mm2, mm1, mm5)
                MOV_R2P(mm1, *pbuf, mm0)
                pbuf++;
+#elif defined SCALE_USING_NEON
+                if (p0 | p1 | p2 | p3)
+                  {
+                    FPU_NEON;
+                    VMOV_M2R_NEON(d8, p0);
+                    VEOR_NEON(q0);
+                    VMOV_M2R_NEON(d9, p2);
+                    VMOV_M2R_NEON(d10, p1);
+                    VEOR_NEON(q1);
+                    VMOV_M2R_NEON(d11, p3);
+                    VDUP_NEON(q3, ax);
+                    VZIP_NEON(q4, q0);
+                    VZIP_NEON(q5, q1);
+                    VMOV_R2R_NEON(d9, d0);
+                    VMOV_R2R_NEON(d11, d2);
+                    INTERP_256_NEON(q3, q5, q4, q2);
+                    INTERP_256_NEON(d12, d9, d8, d5);
+                    VMOV_R2M_NEON(q4, d8, pbuf);
+                    pbuf++;
+                  }
+                else
+                  *pbuf++ = p0;
 #else
                if (p0 | p1)
                  p0 = INTERP_256(ax, p1, p0);
              }
            /* * blend here [clip_w *] buf -> dptr * */
            if (!direct_scale)
-             func(buf, NULL, dc->mul.col, pdst, dst_clip_w);
+              {
+                 if (!dc->clip.mask)
+                   func(buf, NULL, dc->mul.col, pdst, dst_clip_w);
+                 else
+                   {
+                      RGBA_Image *im = dc->clip.mask;
+                      DATA8 *mbegin = im->image.data8;
+                      DATA8 *mend = mbegin + (im->cache_entry.w * im->cache_entry.h);
+                      mask = im->image.data8
+                         + ((dst_clip_y - dc->clip.mask_y + y) * im->cache_entry.w)
+                         + (dst_clip_x - dc->clip.mask_x);
+
+                      /* FIXME!!! Quick workaround crashes */
+                      if ((mask < mbegin) || ((mask + dst_clip_w) > mend))
+                        return;
+
+                      if (dc->mul.use) func2(buf, NULL, dc->mul.col, buf, dst_clip_w);
+                      func(buf, mask, 0, pdst, dst_clip_w);
+                   }
+                 y++;
+              }
 
            pdst += dst_w;
            syy += dsyy;
index acdcc00..3c0bfc6 100644 (file)
@@ -54,29 +54,87 @@ evas_common_text_props_content_ref(Evas_Text_Props *props)
 }
 
 void
-evas_common_text_props_content_unref(Evas_Text_Props *props)
+evas_common_text_props_content_nofree_unref(Evas_Text_Props *props)
 {
    /* No content in this case */
    if (!props->info)
       return;
 
-   if (props->font_instance)
+   if (--(props->info->refcount) == 0)
      {
-        evas_common_font_int_unref(props->font_instance);
-        props->font_instance = NULL;
+        if (props->font_instance)
+          {
+             evas_common_font_int_unref(props->font_instance);
+             props->font_instance = NULL;
+          }
+
+        /* After unreferencing the glyph array, a thread will still hold
+         * a reference, so this can be safely set to NULL. */
+       free(props->glyphs);
+        props->glyphs = NULL;
+       props->glyphs_length = 0;
+        
+        if (props->info->glyph)
+          free(props->info->glyph);
+#ifdef OT_SUPPORT
+        // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+        //if (props->info->ot)
+        //  free(props->info->ot);
+        if (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(props))
+          {
+             if (props->info->ot)
+               free(props->info->ot);
+          }
+        else
+          {
+             free(props->info);
+             props->info = NULL;
+          }
+        //
+#endif
+        free(props->info);
+        props->info = NULL;
      }
+}
+
+void
+evas_common_text_props_content_unref(Evas_Text_Props *props)
+{
+   /* No content in this case */
+   if (!props->info)
+      return;
    
+   /* After unreferencing the glyph array, a thread will still hold
+    * a reference, so this can be safely set to NULL. */
+   free(props->glyphs);
+   props->glyphs = NULL;
+   props->glyphs_length = 0;
+
    if (--(props->info->refcount) == 0)
      {
-        free(props->glyphs);
-        props->glyphs = NULL;
-        props->glyphs_length = 0;
+        if (props->font_instance)
+          {
+             evas_common_font_int_unref(props->font_instance);
+             props->font_instance = NULL;
+          }
 
         if (props->info->glyph)
           free(props->info->glyph);
 #ifdef OT_SUPPORT
-        if (props->info->ot)
-          free(props->info->ot);
+        // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+        //if (props->info->ot)
+        //  free(props->info->ot);
+        if (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(props))
+          {
+             if (props->info->ot)
+               free(props->info->ot);
+          }
+        else
+          {
+             free(props->info);
+             props->info = NULL;
+          }
+        //
 #endif
         free(props->info);
         props->info = NULL;
@@ -91,8 +149,37 @@ _evas_common_text_props_cluster_move(const Evas_Text_Props *props, int pos,
    if (!right && (prop_pos > 0))
      {
 #ifdef OT_SUPPORT
-        return props->info->ot[props->start + prop_pos - 1].source_cluster -
-           props->text_offset;
+        // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+        /*
+        int base_cluster = props->info->ot[props->start + prop_pos].source_cluster;
+        prop_pos--;
+        for ( ; prop_pos >= 0 ; prop_pos--)
+          {
+             int cur_cluster = props->info->ot[props->start + prop_pos].source_cluster;
+             if (cur_cluster != base_cluster)
+               {
+                  return cur_cluster - props->text_offset;
+               }
+          }
+        */
+        if (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(props))
+          {
+             int base_cluster = props->info->ot[props->start + prop_pos].source_cluster;
+             prop_pos--;
+             for ( ; prop_pos >= 0 ; prop_pos--)
+               {
+                  int cur_cluster = props->info->ot[props->start + prop_pos].source_cluster;
+                  if (cur_cluster != base_cluster)
+                    {
+                       return cur_cluster - props->text_offset;
+                    }
+               }
+          }
+        else
+          {
+             return props->start + prop_pos - 1 - props->text_offset;
+          }
+        //
 #else
         return props->start + prop_pos - 1 - props->text_offset;
 #endif
@@ -100,8 +187,37 @@ _evas_common_text_props_cluster_move(const Evas_Text_Props *props, int pos,
    else if (right && (prop_pos < (int) (props->len - 1)))
      {
 #ifdef OT_SUPPORT
-        return props->info->ot[props->start + prop_pos + 1].source_cluster -
-           props->text_offset;
+        // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+        /*
+        int base_cluster = props->info->ot[props->start + prop_pos].source_cluster;
+        prop_pos++;
+        for ( ; prop_pos < (int) props->len ; prop_pos++)
+          {
+             int cur_cluster = props->info->ot[props->start + prop_pos].source_cluster;
+             if (cur_cluster != base_cluster)
+               {
+                  return cur_cluster - props->text_offset;
+               }
+          }
+        */
+        if (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(props))
+          {
+             int base_cluster = props->info->ot[props->start + prop_pos].source_cluster;
+             prop_pos++;
+             for ( ; prop_pos < (int) props->len ; prop_pos++)
+               {
+                  int cur_cluster = props->info->ot[props->start + prop_pos].source_cluster;
+                  if (cur_cluster != base_cluster)
+                    {
+                       return cur_cluster - props->text_offset;
+                    }
+               }
+          }
+        else
+          {
+             return props->start + prop_pos + 1 - props->text_offset;
+          }
+        //
 #else
         return props->start + prop_pos + 1 - props->text_offset;
 #endif
@@ -138,13 +254,26 @@ evas_common_text_props_index_find(const Evas_Text_Props *props, int _cutoff)
    int max = props->len - 1;
    int mid;
 
+   // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+   if (!CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(props))
+     {
+        if (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
+          {
+             return props->len - _cutoff - 1;
+          }
+        else
+          {
+             return _cutoff;
+          }
+     }
+   //
    _cutoff += props->text_offset;
    ot_info = props->info->ot + props->start;
    /* Should get us closer to the right place. */
    if ((min <= _cutoff) && (_cutoff <= max))
-      mid = _cutoff;
+     mid = _cutoff;
    else
-      mid = (min + max) / 2;
+     mid = (min + max) / 2;
 
    if (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
      {
@@ -152,11 +281,11 @@ evas_common_text_props_index_find(const Evas_Text_Props *props, int _cutoff)
         do
           {
              if (_cutoff > (int) ot_info[mid].source_cluster)
-                max = mid - 1;
+               max = mid - 1;
              else if (_cutoff < (int) ot_info[mid].source_cluster)
-                min = mid + 1;
+               min = mid + 1;
              else
-                break;
+               break;
 
              mid = (min + max) / 2;
           }
@@ -168,11 +297,11 @@ evas_common_text_props_index_find(const Evas_Text_Props *props, int _cutoff)
         do
           {
              if (_cutoff < (int) ot_info[mid].source_cluster)
-                max = mid - 1;
+               max = mid - 1;
              else if (_cutoff > (int) ot_info[mid].source_cluster)
-                min = mid + 1;
+               min = mid + 1;
              else
-                break;
+               break;
 
              mid = (min + max) / 2;
           }
@@ -181,7 +310,7 @@ evas_common_text_props_index_find(const Evas_Text_Props *props, int _cutoff)
 
    /* If we didn't find, abort */
    if (min > max)
-      return -1;
+     return -1;
 
    ot_info += mid;
    if (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
@@ -190,7 +319,7 @@ evas_common_text_props_index_find(const Evas_Text_Props *props, int _cutoff)
         for ( ; mid < (int) props->len ; mid++, ot_info++)
           {
              if (ot_info->source_cluster != (size_t) _cutoff)
-                break;
+               break;
           }
         mid--;
      }
@@ -200,29 +329,34 @@ evas_common_text_props_index_find(const Evas_Text_Props *props, int _cutoff)
         for ( ; mid >= 0 ; mid--, ot_info--)
           {
              if (ot_info->source_cluster != (size_t) _cutoff)
-                break;
+               break;
           }
         mid++;
      }
 
    return mid;
 #else
-   return _cutoff;
-   (void) props;
+   if (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
+     {
+        return props->len - _cutoff - 1;
+     }
+   else
+     {
+        return _cutoff;
+     }
 #endif
 }
 
 /* Won't work in the middle of ligatures, assumes cutoff < len.
  * Also won't work in the middle of indic words, should handle that in a
  * smart way. */
-EAPI void
+EAPI Eina_Bool
 evas_common_text_props_split(Evas_Text_Props *base,
       Evas_Text_Props *ext, int _cutoff)
 {
    size_t cutoff;
 
    /* Translate text cutoff pos to string object cutoff point */
-#ifdef OT_SUPPORT
    _cutoff = evas_common_text_props_index_find(base, _cutoff);
 
    if (_cutoff >= 0)
@@ -231,12 +365,9 @@ evas_common_text_props_split(Evas_Text_Props *base,
      }
    else
      {
-        ERR("Couldn't find the cutoff position. Is it inside a cluster?");
-        return;
+        //Couldn't find the cutoff position. Is it inside a cluster?
+        return EINA_FALSE;
      }
-#else
-   cutoff = (size_t) _cutoff;
-#endif
 
    evas_common_text_props_content_copy_and_ref(ext, base);
    if (base->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
@@ -247,8 +378,19 @@ evas_common_text_props_split(Evas_Text_Props *base,
         base->len = base->len - ext->len;
 
 #ifdef OT_SUPPORT
-        ext->text_offset =
-           ext->info->ot[ext->start + ext->len - 1].source_cluster;
+        // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+        //ext->text_offset =
+        //   ext->info->ot[ext->start + ext->len - 1].source_cluster;
+        if (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(base))
+          {
+             ext->text_offset =
+                ext->info->ot[ext->start + ext->len - 1].source_cluster;
+          }
+        else
+          {
+             ext->text_offset = base->text_offset + base->len;
+          }
+        //
 #else
         ext->text_offset = base->text_offset + base->len;
 #endif
@@ -260,7 +402,13 @@ evas_common_text_props_split(Evas_Text_Props *base,
         base->len = cutoff;
 
 #ifdef OT_SUPPORT
-        ext->text_offset = ext->info->ot[ext->start].source_cluster;
+        // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+        //ext->text_offset = ext->info->ot[ext->start].source_cluster;
+        if (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(base))
+          ext->text_offset = ext->info->ot[ext->start].source_cluster;
+        else
+          ext->text_offset = base->text_offset + base->len;
+        //
 #else
         ext->text_offset = base->text_offset + base->len;
 #endif
@@ -269,6 +417,7 @@ evas_common_text_props_split(Evas_Text_Props *base,
    base->text_len = (ext->text_offset - base->text_offset);
    PROPS_CHANGE(base);
    PROPS_CHANGE(ext);
+   return EINA_TRUE;
 }
 
 /* Won't work in the middle of ligatures */
@@ -374,10 +523,14 @@ _content_create_regular(RGBA_Font_Int *fi, const Eina_Unicode *text,
    FT_Face pface = NULL;
    Evas_Coord pen_x = 0;
    int adv_d, i;
-#if !defined(OT_SUPPORT) && defined(BIDI_SUPPORT)
+   // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
    Eina_Unicode *base_str = NULL;
+   //
+#if !defined(OT_SUPPORT) && defined(BIDI_SUPPORT)
    if (mode == EVAS_TEXT_PROPS_MODE_SHAPE)
      {
+        // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+        //Eina_Unicode *base_str = NULL;
         if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
           {
              text = base_str = eina_unicode_strndup(text, len);
@@ -385,9 +538,28 @@ _content_create_regular(RGBA_Font_Int *fi, const Eina_Unicode *text,
           }
      }
 #else
-   (void) mode;
-   (void) par_props;
-   (void) par_pos;
+   // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+   //(void) mode;
+   //(void) par_props;
+   //(void) par_pos;
+   if (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(text_props))
+     {
+        (void) mode;
+        (void) par_props;
+        (void) par_pos;
+     }
+   else
+     {
+        if (mode == EVAS_TEXT_PROPS_MODE_SHAPE)
+          {
+             if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
+               {
+                  text = base_str = eina_unicode_strndup(text, len);
+                  evas_bidi_shape_string(base_str, par_props, par_pos, len);
+               }
+          }
+     }
+   //
 #endif
 
    FTLOCK();
@@ -462,10 +634,16 @@ _content_create_regular(RGBA_Font_Int *fi, const Eina_Unicode *text,
         prev_index = idx;
      }
    text_props->len = len;
-# if !defined(OT_SUPPORT) && defined(BIDI_SUPPORT)
+   // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+/*
+#if !defined(OT_SUPPORT) && defined(BIDI_SUPPORT)
    if (base_str)
       free(base_str);
-# endif
+#endif
+*/
+   if (base_str)
+      free(base_str);
+   //
 }
 
 EAPI Eina_Bool
@@ -507,9 +685,21 @@ evas_common_text_props_content_create(void *_fi, const Eina_Unicode *text,
    text_props->changed = EINA_TRUE;
 
 #ifdef OT_SUPPORT
-   (void) par_props;
-   (void) par_pos;
-   _content_create_ot(fi, text, text_props, len, mode);
+   // TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+   //(void) par_props;
+   //(void) par_pos;
+   //_content_create_ot(fi, text, text_props, len, mode);
+   if (CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(text_props))
+     {
+        (void) par_props;
+        (void) par_pos;
+        _content_create_ot(fi, text, text_props, len, mode);
+     }
+   else
+     {
+        _content_create_regular(fi, text, text_props, par_props, par_pos, len, mode);
+     }
+   //
 #else
    _content_create_regular(fi, text, text_props, par_props, par_pos, len, mode);
 #endif
@@ -519,3 +709,88 @@ evas_common_text_props_content_create(void *_fi, const Eina_Unicode *text,
    return EINA_TRUE;
 }
 
+
+/**
+ * @internal
+ * Returns the numeric value of HEX chars for example for ch = 'A'
+ * the function will return 10.
+ *
+ * @param ch The HEX char.
+ * @return numeric value of HEX.
+ */
+static int
+_hex_string_get(char ch, Eina_Bool *ok)
+{
+   if ((ch >= '0') && (ch <= '9')) return (ch - '0');
+   else if ((ch >= 'A') && (ch <= 'F')) return (ch - 'A' + 10);
+   else if ((ch >= 'a') && (ch <= 'f')) return (ch - 'a' + 10);
+   *ok = EINA_FALSE;
+   return 0;
+}
+
+/**
+ * @internal
+ * Parses a string of one of the formas:
+ * 1. "#RRGGBB"
+ * 2. "#RRGGBBAA"
+ * 3. "#RGB"
+ * 4. "#RGBA"
+ * To the rgba values.
+ *
+ * @param[in] str The string to parse - NOT NULL.
+ * @param[out] r The Red value - NOT NULL.
+ * @param[out] g The Green value - NOT NULL.
+ * @param[out] b The Blue value - NOT NULL.
+ * @param[out] a The Alpha value - NOT NULL.
+ */
+Eina_Bool
+evas_common_format_color_parse(const char *str, int slen,
+                               unsigned char *r, unsigned char *g,
+                               unsigned char *b, unsigned char *a)
+{
+   Eina_Bool v = EINA_TRUE;
+
+   *r = *g = *b = *a = 0;
+
+   if (slen == 7) /* #RRGGBB */
+     {
+        *r = (_hex_string_get(str[1], &v) << 4) | (_hex_string_get(str[2], &v));
+        *g = (_hex_string_get(str[3], &v) << 4) | (_hex_string_get(str[4], &v));
+        *b = (_hex_string_get(str[5], &v) << 4) | (_hex_string_get(str[6], &v));
+        *a = 0xff;
+     }
+   else if (slen == 9) /* #RRGGBBAA */
+     {
+        *r = (_hex_string_get(str[1], &v) << 4) | (_hex_string_get(str[2], &v));
+        *g = (_hex_string_get(str[3], &v) << 4) | (_hex_string_get(str[4], &v));
+        *b = (_hex_string_get(str[5], &v) << 4) | (_hex_string_get(str[6], &v));
+        *a = (_hex_string_get(str[7], &v) << 4) | (_hex_string_get(str[8], &v));
+     }
+   else if (slen == 4) /* #RGB */
+     {
+        *r = _hex_string_get(str[1], &v);
+        *r = (*r << 4) | *r;
+        *g = _hex_string_get(str[2], &v);
+        *g = (*g << 4) | *g;
+        *b = _hex_string_get(str[3], &v);
+        *b = (*b << 4) | *b;
+        *a = 0xff;
+     }
+   else if (slen == 5) /* #RGBA */
+     {
+        *r = _hex_string_get(str[1], &v);
+        *r = (*r << 4) | *r;
+        *g = _hex_string_get(str[2], &v);
+        *g = (*g << 4) | *g;
+        *b = _hex_string_get(str[3], &v);
+        *b = (*b << 4) | *b;
+        *a = _hex_string_get(str[4], &v);
+        *a = (*a << 4) | *a;
+     }
+   else v = EINA_FALSE;
+
+   *r = (*r * *a) / 255;
+   *g = (*g * *a) / 255;
+   *b = (*b * *a) / 255;
+   return v;
+}
index 675df6c..7ef9d55 100644 (file)
@@ -16,7 +16,701 @@ typedef enum
 # include "language/evas_language_utils.h"
 
 /* Used for showing "malformed" or missing chars */
-#define REPLACEMENT_CHAR 0xFFFD
+#define REPLACEMENT_CHAR 0x00A0
+
+// HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+#define UNICODE_EMOTICON_FOLDER "/usr/share/emoticons/"
+
+// HAVE_UNICODE_EMOTICON(2013.10.07): Basic implementation for supporting unicode 6.0 emoticon.
+#define UNICODE_EMOTICON_MIN_1 0x2600
+#define UNICODE_EMOTICON_MAX_1 0x26FF
+static const
+Eina_Bool _unicode_emoticon_table_1[] = {
+     1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 0, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 0, 1, 1, 1, 0
+};
+
+// HAVE_UNICODE_EMOTICON(2013.12.12): Unicode Emoticon table is modified.
+#define UNICODE_EMOTICON_MIN_2 0x1F300
+#define UNICODE_EMOTICON_MAX_2 0x1F6C5
+static const
+Eina_Bool _unicode_emoticon_table_2[] = {
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+     1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 0, 1, 1,
+     1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+     1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 0, 1, 1, 1, 1, 0,
+     0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 0, 0, 1, 1, 1, 1,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 0, 0, 0, 0, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1
+};
+
+// HAVE_UNICODE_EMOTICON(2013.12.12): Unicode Emoticon table is modified.
+#define UNICODE_EMOTICON_MIN_3 0x1F000
+#define UNICODE_EMOTICON_MAX_3 0x1F251
+static const
+Eina_Bool _unicode_emoticon_table_3[] = {
+     0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+     0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 1, 0, 1, 1, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+     0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+     1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 1, 1
+};
+
+// HAVE_UNICODE_EMOTICON(2013.12.12): Unicode Emoticon table is modified.
+#define UNICODE_EMOTICON_MIN_4 0x203C
+#define UNICODE_EMOTICON_MAX_4 0x25FE
+static const
+Eina_Bool _unicode_emoticon_table_4[] = {
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 1, 1, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 1, 1, 1, 1, 0, 0, 0, 1, 0,
+     0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 1, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 1, 1, 1, 1
+};
+
+// HAVE_UNICODE_EMOTICON(2013.12.12): Unicode Emoticon table is modified.
+#define UNICODE_EMOTICON_MIN_5 0x2702
+#define UNICODE_EMOTICON_MAX_5 0x3299
+static const
+Eina_Bool _unicode_emoticon_table_5[] = {
+     1, 0, 0, 1, 0, 0, 1, 1, 1, 1,
+     1, 0, 0, 1, 0, 0, 1, 0, 1, 0,
+     1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+     1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
+     0, 0, 0, 0, 1, 0, 1, 0, 0, 0,
+     0, 1, 1, 1, 0, 1, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+     1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 1, 0, 0, 0, 0, 1, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 1, 0, 1
+};
+
+// HAVE_UNICODE_EMOTICON(2013.12.12): Unicode Emoticon table is modified.
+#define UNICODE_EMOTICON_CHECK(text) \
+   if ((text >= UNICODE_EMOTICON_MIN_1 && text <= UNICODE_EMOTICON_MAX_1 && _unicode_emoticon_table_1[text - UNICODE_EMOTICON_MIN_1]) \
+       || (text >= UNICODE_EMOTICON_MIN_2 && text <= UNICODE_EMOTICON_MAX_2 && _unicode_emoticon_table_2[text - UNICODE_EMOTICON_MIN_2]) \
+       || (text >= UNICODE_EMOTICON_MIN_3 && text <= UNICODE_EMOTICON_MAX_3 && _unicode_emoticon_table_3[text - UNICODE_EMOTICON_MIN_3]) \
+       || (text >= UNICODE_EMOTICON_MIN_4 && text <= UNICODE_EMOTICON_MAX_4 && _unicode_emoticon_table_4[text - UNICODE_EMOTICON_MIN_4]) \
+       || (text >= UNICODE_EMOTICON_MIN_5 && text <= UNICODE_EMOTICON_MAX_5 && _unicode_emoticon_table_5[text - UNICODE_EMOTICON_MIN_5]))
+//
+
+// TIZEN_ONLY(20140301): Added checking language of text props. We can draw glyphs of specific language without harfbuzz.
+#define CHECK_LANGUAGE_HARFBUZZ_AVAILABLE(text_props) \
+   ((text_props->script != EVAS_SCRIPT_MYANMAR) ? \
+    EINA_TRUE : EINA_FALSE)
+//
+
+#define CHECK_LANGUAGE_CLUSTER_AVAILABLE(script) \
+   (((script == EVAS_SCRIPT_THAI) || \
+     (script == EVAS_SCRIPT_DEVANAGARI) || \
+     (script == EVAS_SCRIPT_BENGALI) || \
+     (script == EVAS_SCRIPT_GUJARATI) || \
+     (script == EVAS_SCRIPT_TELUGU) || \
+     (script == EVAS_SCRIPT_KHMER) || \
+     (script == EVAS_SCRIPT_SINHALA) || \
+     (script == EVAS_SCRIPT_KANNADA) || \
+     (script == EVAS_SCRIPT_MALAYALAM) || \
+     (script == EVAS_SCRIPT_TAMIL)) ? \
+    EINA_TRUE : EINA_FALSE)
 
 typedef struct _Evas_Glyph Evas_Glyph;
 
@@ -81,6 +775,9 @@ void
 evas_common_text_props_content_ref(Evas_Text_Props *props);
 
 void
+evas_common_text_props_content_nofree_unref(Evas_Text_Props *props);
+
+void
 evas_common_text_props_content_unref(Evas_Text_Props *props);
 
 EAPI int
@@ -92,10 +789,13 @@ evas_common_text_props_cluster_prev(const Evas_Text_Props *props, int pos);
 EAPI int
 evas_common_text_props_index_find(const Evas_Text_Props *props, int _cutoff);
 
-EAPI void
+EAPI Eina_Bool
 evas_common_text_props_split(Evas_Text_Props *base, Evas_Text_Props *ext,
       int cutoff);
 EAPI void
 evas_common_text_props_merge(Evas_Text_Props *item1, const Evas_Text_Props *item2);
 
+/* Common to Textblock and Filters */
+Eina_Bool evas_common_format_color_parse(const char *str, int slen, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a);
+
 #endif
old mode 100644 (file)
new mode 100755 (executable)
index bc5e99c..3a09764
@@ -933,6 +933,12 @@ evas_common_tilebuf_get_tile_size(Tilebuf *tb, int *tw, int *th)
    if (th) *th = tb->tile_size.h;
 }
 
+EAPI void
+evas_common_tilebuf_tile_strict_set(Tilebuf *tb, Eina_Bool strict)
+{
+   tb->strict_tiles = strict;
+}
+
 #ifdef EVAS_RECT_SPLIT
 static inline int
 _add_redraw(list_t *rects, int x, int y, int w, int h)
@@ -973,6 +979,11 @@ evas_common_tilebuf_add_redraw(Tilebuf *tb, int x, int y, int w, int h)
      evas_common_regionbuf_span_add(tb->rb, x, x + w - 1, y + i);
    return 1;
  */
+   if ((w <= 0) || (h <= 0)) return 0;
+   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
+   if ((w <= 0) || (h <= 0)) return 0;
+
+   return _add_redraw(&tb->rects, x, y, w, h);
 #elif defined(EVAS_RECT_SPLIT)
    if ((w <= 0) || (h <= 0)) return 0;
    RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
@@ -1166,17 +1177,41 @@ evas_common_tilebuf_get_render_rects(Tilebuf *tb)
  */
 #elif defined(EVAS_RECT_SPLIT)
    list_node_t *n;
+   list_t to_merge;
    Tilebuf_Rect *rects = NULL;
    int bx1 = 0, bx2 = 0, by1 = 0, by2 = 0, num = 0;
 
    if (tb->need_merge)
      {
-        list_t to_merge;
         to_merge = tb->rects;
         tb->rects = list_zeroed;
         rect_list_merge_rects(&tb->rects, &to_merge, FUZZ * FUZZ);
         tb->need_merge = 0;
      }
+   if (tb->strict_tiles)
+     {
+        // round up rects to tb->tile_size.w and tb->tile_size.h
+        to_merge = list_zeroed;
+        for (n = tb->rects.head; n; n = n->next)
+          {
+             int x1, x2, y1, y2;
+             int x, y, w, h;
+
+             x1 = ((rect_node_t *)n)->rect.left;
+             x2 = x1 + ((rect_node_t *)n)->rect.width;
+             y1 = ((rect_node_t *)n)->rect.top;
+             y2 = y1 + ((rect_node_t *)n)->rect.height;
+             x1 = tb->tile_size.w * (x1 / tb->tile_size.w);
+             y1 = tb->tile_size.h * (y1 / tb->tile_size.h);
+             x2 = tb->tile_size.w * ((x2 + tb->tile_size.w - 1) / tb->tile_size.w);
+             y2 = tb->tile_size.h * ((y2 + tb->tile_size.h - 1) / tb->tile_size.h);
+
+             x = x1; y = y1; w = x2 - x1; h = y2 - y1;
+             RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
+             _add_redraw(&to_merge, x, y, w, h);
+          }
+        rect_list_merge_rects(&tb->rects, &to_merge, FUZZ * FUZZ);
+     }
    
    n = tb->rects.head;
    if (n)
index 002cfbe..909bd16 100644 (file)
@@ -87,7 +87,7 @@ evas_bidi_is_rtl_str(const Eina_Unicode *str)
    for ( ; *str ; str++)
      {
         type = fribidi_get_bidi_type((FriBidiChar) *str);
-        if (FRIBIDI_IS_LETTER(type) && FRIBIDI_IS_RTL(type))
+        if (FRIBIDI_IS_RTL(type))
           {
              return EINA_TRUE;
           }
@@ -182,8 +182,10 @@ evas_bidi_segment_idxs_get(const Eina_Unicode *str, const char *delim)
                        if (!tmp_ret)
                          {
                             free(ret);
+                            free(udelim);
                             return NULL;
                          }
+                       ret = tmp_ret;
                     }
                   ret[ret_idx++] = str - str_base;
                   break;
@@ -233,11 +235,12 @@ evas_bidi_paragraph_props_get(const Eina_Unicode *eina_ustr, size_t len,
       return NULL;
 
 
-   if (!evas_bidi_is_rtl_str(eina_ustr)) /* No need to handle bidi */
-     {
-        len = -1;
-        goto cleanup;
-     }
+   // TIZEN_ONLY(20140822): Added evas_bidi_direction_hint_set, get APIs and applied to textblock, text.
+   //if (!evas_bidi_is_rtl_str(eina_ustr)) /* No need to handle bidi */
+   //  {
+   //     len = -1;
+   //     goto cleanup;
+   //  }
 
    len = eina_unicode_strlen(eina_ustr);
    /* The size of fribidichar s different than eina_unicode, convert */
index f1a374b..9ad3ff4 100644 (file)
@@ -90,6 +90,12 @@ struct _Evas_BiDi_Props
 #define EVAS_BIDI_PARAGRAPH_WLTR    FRIBIDI_PAR_WLTR
 #define EVAS_BIDI_PARAGRAPH_WRTL    FRIBIDI_PAR_WRTL
 
+// TIZEN_ONLY(20140822): Added evas_bidi_direction_hint_set, get APIs and applied to textblock, text.
+#define EVAS_BIDI_PARAGRAPH_DIRECTION_IS_NEUTRAL(x)       \
+   (((x) && (x->direction == EVAS_BIDI_PARAGRAPH_NEUTRAL)) ?   \
+    EINA_TRUE : EINA_FALSE)
+//
+
 #define EVAS_BIDI_PARAGRAPH_DIRECTION_IS_RTL(x)       \
    (((x) &&                                \
      ((x->direction == EVAS_BIDI_PARAGRAPH_RTL) ||   \
diff --git a/src/lib/engines/common_16/Makefile.am b/src/lib/engines/common_16/Makefile.am
deleted file mode 100644 (file)
index ef2ab30..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-
-MAINTAINERCLEANFILES = Makefile.in
-
-AM_CPPFLAGS = \
--I. \
--I$(top_srcdir)/src/lib \
--I$(top_srcdir)/src/lib/include \
-@FREETYPE_CFLAGS@ \
-@PIXMAN_CFLAGS@ \
-@VALGRIND_CFLAGS@ \
-@EINA_CFLAGS@ \
-@EET_CFLAGS@ \
-@pthread_cflags@
-
-noinst_LTLIBRARIES = libevas_engine_common_16.la
-
-libevas_engine_common_16_la_SOURCES = \
-evas_soft16_dither_mask.c \
-evas_soft16_font.c \
-evas_soft16_image_scaled_sampled.c \
-evas_soft16_image_unscaled.c \
-evas_soft16_main.c \
-evas_soft16_rectangle.c \
-evas_soft16_line.c \
-evas_soft16_polygon.c
-
-libevas_engine_common_16_la_DEPENDENCIES = $(top_builddir)/config.h
-
-EXTRA_DIST = \
-evas_soft16_point_blend.c \
-evas_soft16_scanline_blend.c \
-evas_soft16_scanline_fill.c
diff --git a/src/lib/engines/common_16/evas_soft16_dither_mask.c b/src/lib/engines/common_16/evas_soft16_dither_mask.c
deleted file mode 100644 (file)
index 566efac..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-#include "evas_common_soft16.h"
-
-#define S16_DM_SIZE      128
-#define S16_DM_BITS      6
-#define S16_DM_DIV       64
-#define S16_DM_MSK       (S16_DM_SIZE - 1)
-#define S16_DM_SHF(_b)   (S16_DM_BITS - (8 - _b))
-
-static const DATA8 dither_table[S16_DM_SIZE][S16_DM_SIZE] =
-{
-     { 0, 41, 23, 5, 17, 39, 7, 15, 62, 23, 40, 51, 31, 47, 9, 32, 52, 27, 57, 25, 6, 61, 27, 52, 37, 7, 40, 63, 18, 36, 10, 42, 25, 62, 45, 34, 20, 42, 37, 14, 35, 29, 50, 10, 61, 2, 40, 8, 37, 12, 58, 22, 5, 41, 10, 39, 0, 60, 11, 46, 2, 55, 38, 17, 36, 59, 13, 54, 37, 56, 8, 29, 16, 13, 63, 22, 41, 55, 7, 20, 49, 14, 23, 55, 37, 23, 19, 36, 15, 49, 23, 63, 30, 14, 38, 27, 53, 13, 22, 41, 19, 31, 7, 19, 50, 30, 49, 16, 3, 32, 56, 40, 29, 34, 8, 48, 19, 45, 4, 51, 12, 46, 35, 49, 16, 42, 12, 62 },
-     { 30, 57, 36, 54, 47, 34, 52, 27, 43, 4, 28, 7, 17, 36, 62, 13, 44, 7, 18, 48, 33, 21, 44, 14, 30, 47, 12, 33, 5, 55, 31, 58, 13, 30, 4, 17, 52, 10, 60, 26, 46, 0, 39, 27, 42, 22, 47, 25, 60, 32, 9, 38, 48, 17, 59, 30, 49, 18, 34, 25, 51, 19, 5, 48, 21, 8, 28, 46, 1, 32, 41, 19, 54, 47, 37, 18, 28, 11, 44, 30, 39, 56, 2, 33, 8, 42, 61, 28, 58, 8, 46, 9, 41, 4, 58, 7, 21, 48, 59, 10, 52, 14, 42, 57, 12, 25, 7, 53, 42, 24, 11, 50, 17, 59, 42, 2, 36, 60, 32, 17, 63, 29, 21, 7, 59, 32, 24, 39 },
-     { 22, 8, 16, 32, 3, 25, 13, 57, 18, 45, 58, 39, 55, 20, 5, 42, 23, 34, 63, 1, 51, 10, 58, 4, 60, 23, 53, 27, 44, 21, 3, 48, 8, 50, 43, 54, 27, 32, 5, 55, 21, 58, 12, 53, 6, 36, 14, 50, 17, 29, 53, 15, 24, 52, 7, 36, 13, 42, 4, 53, 9, 35, 61, 26, 56, 32, 49, 15, 62, 23, 6, 60, 2, 31, 4, 48, 58, 38, 15, 61, 5, 25, 47, 28, 50, 15, 7, 40, 3, 32, 33, 52, 25, 50, 35, 42, 61, 3, 28, 36, 23, 63, 4, 33, 46, 62, 36, 23, 60, 6, 54, 28, 4, 37, 23, 55, 25, 8, 42, 54, 14, 6, 56, 38, 19, 52, 4, 46 },
-     { 48, 53, 43, 12, 45, 63, 30, 37, 9, 34, 21, 1, 25, 47, 29, 58, 3, 54, 15, 39, 29, 17, 38, 35, 20, 43, 1, 49, 15, 59, 29, 39, 22, 35, 16, 23, 1, 47, 39, 18, 8, 44, 25, 31, 57, 19, 63, 4, 45, 3, 42, 61, 1, 31, 45, 20, 57, 29, 62, 21, 32, 41, 14, 44, 3, 39, 5, 34, 10, 43, 51, 35, 23, 52, 40, 10, 21, 1, 53, 18, 51, 43, 12, 62, 18, 54, 26, 51, 20, 57, 14, 1, 62, 16, 11, 18, 32, 39, 17, 44, 1, 48, 26, 37, 18, 2, 51, 14, 28, 45, 35, 18, 57, 13, 47, 11, 51, 20, 2, 39, 31, 47, 25, 1, 50, 11, 60, 7 },
-     { 18, 28, 1, 56, 21, 10, 51, 2, 46, 54, 14, 61, 11, 50, 13, 38, 19, 31, 45, 9, 55, 24, 47, 5, 54, 9, 62, 11, 35, 8, 51, 14, 57, 6, 63, 40, 58, 14, 51, 28, 62, 34, 15, 48, 1, 41, 30, 35, 55, 21, 34, 11, 49, 37, 8, 52, 4, 23, 15, 43, 1, 58, 11, 23, 53, 16, 55, 26, 58, 18, 27, 12, 45, 14, 25, 63, 42, 33, 27, 35, 9, 31, 21, 38, 1, 44, 34, 12, 48, 38, 21, 44, 29, 47, 26, 53, 1, 46, 54, 8, 59, 29, 11, 55, 22, 41, 33, 20, 39, 1, 48, 9, 44, 32, 5, 62, 29, 44, 57, 23, 10, 58, 34, 43, 15, 37, 26, 33 },
-     { 51, 38, 59, 24, 35, 42, 19, 60, 5, 32, 41, 26, 43, 33, 7, 53, 48, 11, 59, 23, 42, 2, 61, 30, 16, 40, 32, 24, 56, 41, 19, 33, 37, 26, 47, 9, 31, 22, 2, 45, 9, 54, 4, 37, 21, 52, 11, 23, 7, 57, 16, 25, 55, 18, 63, 27, 46, 39, 56, 10, 50, 37, 29, 47, 19, 63, 24, 9, 46, 2, 39, 60, 9, 57, 30, 7, 49, 11, 59, 3, 45, 57, 5, 60, 29, 22, 5, 60, 30, 9, 59, 18, 40, 6, 57, 36, 30, 12, 24, 34, 15, 40, 52, 6, 49, 9, 58, 4, 63, 12, 26, 61, 22, 53, 38, 16, 35, 14, 28, 50, 42, 17, 5, 28, 62, 20, 54, 12 },
-     { 26, 6, 31, 15, 49, 6, 38, 27, 22, 49, 16, 56, 2, 62, 30, 21, 0, 36, 28, 6, 49, 32, 13, 52, 26, 50, 19, 46, 3, 26, 62, 0, 53, 12, 29, 3, 53, 41, 60, 24, 38, 13, 58, 16, 43, 9, 59, 39, 46, 28, 44, 40, 2, 33, 13, 41, 16, 6, 47, 31, 26, 17, 57, 6, 38, 0, 42, 36, 29, 52, 20, 31, 48, 0, 34, 56, 20, 36, 23, 54, 14, 41, 24, 37, 10, 55, 46, 25, 16, 45, 36, 4, 55, 23, 15, 8, 50, 62, 5, 56, 44, 20, 13, 28, 59, 31, 24, 47, 31, 52, 37, 17, 40, 0, 26, 49, 3, 60, 7, 33, 0, 61, 53, 40, 8, 45, 2, 41 },
-     { 16, 63, 43, 4, 61, 24, 56, 13, 53, 8, 36, 12, 24, 41, 16, 46, 60, 26, 52, 39, 14, 57, 21, 37, 0, 45, 7, 59, 38, 17, 43, 10, 45, 20, 61, 43, 19, 11, 33, 17, 50, 32, 23, 61, 28, 49, 26, 0, 18, 51, 5, 60, 22, 58, 29, 0, 59, 34, 19, 62, 3, 52, 7, 44, 30, 59, 13, 50, 15, 62, 7, 17, 38, 22, 44, 15, 40, 4, 47, 28, 33, 17, 49, 16, 51, 40, 10, 56, 0, 53, 13, 49, 28, 38, 60, 21, 43, 19, 37, 27, 3, 51, 34, 39, 0, 45, 15, 43, 10, 21, 3, 55, 8, 33, 59, 10, 41, 18, 52, 24, 46, 20, 30, 13, 58, 22, 36, 57 },
-     { 50, 34, 11, 47, 29, 17, 44, 0, 33, 63, 28, 46, 52, 5, 57, 10, 42, 18, 4, 63, 20, 8, 44, 10, 56, 34, 14, 29, 5, 54, 23, 59, 32, 49, 7, 34, 49, 27, 56, 0, 42, 7, 46, 3, 40, 6, 54, 32, 62, 13, 36, 10, 47, 8, 35, 49, 24, 51, 12, 40, 22, 35, 60, 12, 22, 51, 33, 4, 40, 25, 43, 55, 5, 54, 12, 61, 26, 51, 8, 62, 0, 53, 7, 63, 2, 32, 19, 34, 42, 24, 31, 63, 2, 10, 45, 33, 0, 48, 9, 61, 22, 47, 8, 62, 18, 56, 7, 54, 27, 57, 46, 30, 50, 19, 45, 30, 56, 36, 22, 47, 11, 38, 3, 51, 32, 48, 18, 9 },
-     { 0, 21, 40, 19, 52, 9, 37, 48, 20, 40, 3, 18, 27, 38, 35, 22, 31, 56, 13, 35, 46, 28, 60, 40, 27, 18, 61, 50, 41, 30, 7, 36, 2, 25, 16, 57, 5, 15, 47, 29, 55, 19, 30, 52, 15, 34, 20, 12, 43, 30, 20, 54, 25, 44, 53, 12, 38, 5, 55, 27, 48, 15, 33, 27, 45, 8, 19, 28, 56, 11, 33, 49, 18, 36, 29, 2, 45, 16, 39, 19, 31, 43, 27, 35, 20, 52, 26, 6, 61, 11, 41, 17, 29, 51, 20, 56, 25, 32, 41, 17, 53, 31, 25, 14, 42, 23, 35, 16, 38, 6, 34, 12, 15, 62, 6, 21, 13, 1, 63, 9, 55, 27, 43, 25, 14, 4, 31, 55 },
-     { 44, 29, 61, 2, 35, 58, 26, 15, 60, 10, 51, 59, 14, 55, 8, 50, 2, 44, 25, 51, 1, 33, 16, 4, 48, 36, 2, 21, 12, 57, 48, 13, 51, 55, 40, 28, 37, 62, 8, 39, 12, 63, 36, 10, 59, 24, 56, 47, 9, 50, 41, 1, 32, 17, 6, 21, 61, 30, 9, 43, 1, 54, 41, 2, 54, 37, 48, 61, 1, 46, 21, 3, 58, 24, 50, 32, 60, 10, 57, 25, 46, 12, 59, 4, 45, 13, 57, 47, 27, 39, 5, 58, 47, 14, 35, 4, 52, 13, 60, 6, 36, 10, 45, 55, 4, 50, 29, 2, 61, 50, 25, 58, 44, 24, 36, 42, 54, 28, 40, 32, 16, 56, 6, 62, 46, 39, 60, 23 },
-     { 7, 48, 14, 54, 23, 40, 4, 45, 30, 22, 42, 32, 1, 44, 20, 29, 58, 8, 37, 19, 41, 54, 24, 58, 9, 53, 25, 46, 34, 16, 23, 38, 27, 11, 18, 1, 52, 21, 35, 22, 48, 5, 25, 45, 18, 38, 2, 27, 35, 4, 57, 15, 62, 39, 57, 28, 42, 16, 36, 60, 24, 18, 10, 63, 20, 5, 16, 23, 37, 14, 59, 27, 41, 8, 13, 42, 21, 35, 6, 50, 3, 38, 15, 48, 30, 39, 17, 3, 49, 14, 53, 33, 24, 7, 61, 44, 11, 39, 23, 49, 19, 58, 1, 32, 36, 12, 60, 41, 20, 13, 41, 4, 39, 1, 48, 8, 18, 51, 14, 44, 5, 37, 21, 34, 1, 26, 10, 37 },
-     { 53, 36, 27, 9, 50, 12, 32, 55, 2, 57, 7, 17, 48, 34, 63, 15, 40, 26, 62, 11, 49, 6, 31, 39, 22, 42, 6, 63, 1, 39, 60, 4, 42, 61, 32, 45, 24, 44, 2, 60, 16, 41, 53, 1, 33, 61, 49, 17, 63, 23, 45, 26, 33, 3, 23, 46, 2, 50, 20, 4, 45, 34, 49, 30, 39, 58, 44, 31, 53, 34, 6, 52, 30, 47, 63, 1, 53, 22, 42, 31, 58, 23, 54, 22, 61, 8, 36, 59, 22, 35, 21, 1, 55, 40, 27, 16, 30, 54, 2, 29, 43, 16, 39, 63, 21, 46, 26, 10, 48, 32, 19, 53, 30, 56, 26, 60, 33, 4, 61, 23, 49, 59, 15, 53, 19, 58, 42, 16 },
-     { 20, 5, 59, 46, 25, 62, 7, 19, 43, 25, 37, 61, 11, 24, 4, 54, 12, 52, 3, 32, 17, 61, 12, 47, 15, 55, 18, 31, 53, 28, 9, 50, 21, 6, 55, 9, 58, 14, 54, 26, 33, 7, 31, 58, 13, 21, 8, 42, 29, 6, 37, 11, 48, 52, 14, 60, 11, 39, 56, 32, 14, 58, 7, 26, 17, 4, 42, 8, 11, 47, 19, 38, 10, 17, 26, 37, 9, 55, 28, 13, 18, 40, 6, 33, 1, 43, 25, 11, 51, 7, 62, 43, 18, 37, 3, 57, 45, 9, 38, 58, 5, 52, 27, 7, 17, 53, 5, 57, 37, 2, 63, 9, 22, 15, 11, 38, 25, 45, 35, 0, 28, 10, 41, 30, 50, 8, 31, 57 },
-     { 49, 33, 16, 38, 1, 42, 51, 34, 53, 14, 28, 49, 30, 56, 36, 23, 43, 20, 38, 56, 22, 45, 28, 0, 62, 35, 26, 44, 11, 19, 52, 35, 44, 15, 30, 38, 10, 31, 40, 4, 46, 50, 20, 40, 27, 44, 51, 14, 56, 53, 19, 59, 7, 29, 41, 19, 35, 25, 8, 52, 22, 44, 13, 53, 50, 32, 61, 24, 56, 25, 63, 0, 45, 57, 33, 59, 16, 46, 4, 62, 50, 11, 60, 37, 52, 19, 55, 29, 37, 46, 13, 26, 48, 10, 50, 34, 21, 63, 26, 13, 42, 33, 22, 55, 35, 28, 43, 15, 24, 51, 27, 34, 46, 49, 58, 3, 52, 9, 57, 19, 48, 55, 3, 35, 12, 45, 24, 3 },
-     { 41, 11, 56, 28, 18, 31, 22, 10, 37, 6, 47, 13, 3, 41, 9, 46, 0, 48, 29, 6, 34, 10, 55, 37, 20, 8, 49, 3, 41, 59, 14, 25, 0, 63, 19, 47, 27, 51, 17, 57, 23, 10, 61, 6, 54, 3, 38, 31, 0, 22, 34, 43, 20, 55, 31, 0, 49, 63, 29, 38, 3, 62, 28, 40, 0, 22, 14, 35, 2, 48, 15, 43, 23, 14, 3, 29, 49, 20, 39, 34, 0, 44, 29, 9, 15, 47, 5, 42, 0, 31, 58, 5, 31, 61, 23, 15, 0, 47, 19, 50, 24, 3, 59, 11, 44, 0, 31, 59, 6, 42, 17, 60, 0, 39, 20, 31, 43, 17, 29, 40, 12, 25, 60, 22, 52, 15, 63, 29 },
-     { 20, 52, 8, 44, 62, 4, 59, 49, 17, 63, 21, 39, 60, 18, 52, 27, 33, 59, 14, 51, 59, 43, 24, 5, 51, 30, 57, 17, 32, 5, 37, 56, 48, 34, 42, 3, 60, 5, 36, 13, 43, 37, 18, 34, 25, 12, 59, 24, 47, 36, 11, 50, 3, 38, 9, 58, 16, 5, 43, 18, 47, 10, 37, 18, 59, 46, 29, 52, 40, 12, 34, 28, 56, 36, 53, 7, 43, 8, 24, 52, 26, 17, 56, 43, 24, 32, 63, 20, 57, 16, 22, 52, 36, 8, 41, 56, 29, 32, 54, 7, 35, 57, 14, 48, 20, 62, 13, 39, 53, 29, 8, 45, 13, 29, 7, 61, 14, 54, 6, 63, 38, 32, 18, 43, 2, 39, 6, 47 },
-     { 0, 58, 23, 35, 13, 46, 12, 39, 0, 31, 55, 24, 5, 35, 15, 61, 17, 5, 39, 25, 18, 2, 50, 33, 41, 13, 39, 23, 62, 46, 29, 12, 22, 8, 56, 25, 20, 49, 32, 62, 0, 56, 11, 46, 63, 42, 9, 16, 55, 5, 60, 15, 62, 26, 45, 21, 36, 51, 13, 57, 31, 24, 55, 6, 35, 9, 57, 5, 20, 60, 7, 51, 5, 19, 40, 25, 61, 32, 56, 12, 36, 48, 21, 2, 58, 12, 39, 28, 9, 50, 40, 12, 44, 18, 25, 49, 6, 38, 11, 62, 18, 46, 30, 9, 40, 25, 49, 19, 10, 36, 55, 22, 33, 52, 41, 18, 37, 27, 49, 21, 2, 46, 7, 53, 33, 61, 27, 35 },
-     { 41, 31, 5, 39, 51, 26, 33, 57, 27, 41, 9, 44, 54, 29, 48, 7, 44, 36, 57, 10, 31, 63, 16, 45, 11, 60, 1, 47, 7, 20, 43, 3, 58, 36, 13, 52, 39, 7, 15, 28, 22, 48, 30, 21, 1, 29, 49, 44, 27, 17, 40, 30, 24, 42, 12, 53, 33, 7, 47, 20, 1, 42, 11, 49, 25, 43, 17, 32, 45, 27, 41, 21, 31, 62, 11, 49, 2, 15, 42, 5, 63, 7, 41, 27, 49, 6, 54, 23, 46, 34, 2, 28, 54, 3, 59, 12, 46, 17, 42, 28, 40, 1, 37, 51, 5, 55, 2, 34, 47, 16, 3, 62, 47, 5, 23, 56, 1, 44, 12, 34, 51, 16, 57, 11, 25, 17, 54, 13 },
-     { 60, 26, 55, 18, 3, 60, 20, 6, 52, 15, 50, 19, 32, 11, 23, 53, 26, 21, 1, 47, 42, 27, 8, 58, 21, 27, 53, 36, 26, 54, 31, 50, 17, 30, 45, 1, 29, 59, 44, 53, 41, 4, 35, 58, 51, 19, 32, 4, 52, 34, 48, 8, 51, 5, 56, 2, 25, 61, 27, 38, 54, 27, 62, 21, 51, 1, 39, 62, 10, 50, 1, 58, 13, 47, 38, 18, 35, 54, 22, 51, 30, 19, 59, 34, 14, 32, 44, 4, 60, 15, 52, 62, 20, 43, 30, 35, 21, 60, 4, 52, 12, 24, 61, 18, 30, 42, 23, 61, 25, 50, 27, 38, 11, 59, 12, 35, 50, 30, 59, 24, 8, 42, 28, 37, 48, 9, 44, 21 },
-     { 10, 47, 15, 50, 30, 43, 8, 45, 29, 2, 36, 59, 1, 58, 41, 3, 63, 31, 54, 20, 13, 55, 35, 38, 4, 44, 15, 9, 61, 2, 14, 38, 61, 10, 23, 54, 18, 12, 24, 2, 14, 55, 16, 8, 38, 14, 41, 60, 10, 23, 1, 58, 32, 17, 28, 37, 41, 15, 3, 60, 15, 33, 4, 36, 16, 59, 28, 14, 23, 55, 37, 18, 44, 28, 2, 57, 30, 10, 27, 46, 14, 38, 3, 53, 21, 61, 17, 35, 10, 41, 26, 7, 33, 9, 57, 1, 53, 37, 26, 20, 56, 48, 9, 33, 58, 16, 37, 7, 45, 1, 57, 15, 32, 26, 42, 23, 7, 20, 4, 54, 31, 62, 22, 1, 59, 30, 4, 51 },
-     { 36, 2, 38, 11, 24, 36, 54, 22, 62, 47, 25, 8, 28, 45, 16, 38, 12, 43, 9, 37, 49, 3, 23, 52, 18, 30, 50, 33, 19, 42, 49, 26, 6, 40, 47, 35, 63, 38, 50, 33, 60, 26, 36, 47, 24, 57, 6, 26, 39, 63, 19, 44, 14, 46, 61, 9, 50, 30, 45, 23, 10, 50, 44, 8, 31, 54, 6, 46, 36, 4, 30, 54, 8, 52, 22, 41, 4, 60, 40, 0, 58, 24, 45, 10, 37, 1, 48, 30, 56, 17, 38, 48, 24, 47, 19, 39, 14, 8, 45, 32, 2, 34, 27, 44, 4, 52, 11, 56, 31, 21, 40, 19, 44, 51, 2, 63, 46, 58, 36, 43, 14, 5, 50, 38, 14, 56, 40, 23 },
-     { 61, 46, 32, 63, 54, 1, 14, 34, 12, 40, 18, 49, 37, 10, 61, 30, 51, 24, 60, 7, 29, 40, 62, 11, 46, 58, 6, 56, 24, 10, 34, 52, 21, 59, 16, 3, 27, 5, 20, 46, 9, 40, 7, 62, 2, 30, 53, 15, 48, 10, 28, 35, 54, 6, 21, 34, 18, 55, 7, 40, 57, 19, 26, 60, 41, 13, 24, 51, 19, 61, 9, 25, 34, 15, 63, 11, 45, 17, 20, 47, 33, 8, 31, 62, 43, 26, 53, 7, 24, 59, 0, 13, 55, 4, 62, 27, 51, 31, 63, 15, 58, 7, 54, 14, 46, 22, 28, 43, 12, 63, 8, 54, 5, 17, 39, 33, 15, 10, 27, 17, 47, 34, 19, 45, 27, 12, 33, 17 },
-     { 5, 28, 21, 7, 17, 48, 42, 58, 23, 4, 63, 14, 55, 21, 34, 5, 19, 0, 45, 17, 52, 15, 25, 32, 0, 22, 40, 13, 45, 62, 18, 0, 43, 11, 33, 55, 30, 42, 57, 19, 51, 31, 22, 43, 18, 45, 34, 0, 43, 31, 56, 3, 23, 40, 59, 0, 44, 13, 48, 35, 2, 32, 46, 0, 21, 48, 35, 3, 40, 32, 43, 59, 0, 48, 33, 26, 53, 36, 55, 12, 51, 16, 55, 5, 18, 29, 11, 39, 51, 19, 45, 31, 42, 21, 35, 6, 22, 47, 10, 38, 23, 50, 20, 36, 0, 60, 38, 4, 50, 35, 48, 34, 24, 57, 9, 53, 28, 48, 61, 0, 56, 24, 53, 3, 63, 6, 42, 57 },
-     { 13, 53, 45, 40, 58, 27, 6, 16, 38, 51, 33, 30, 43, 2, 47, 56, 40, 50, 33, 57, 27, 5, 47, 42, 60, 36, 16, 54, 28, 4, 37, 57, 28, 51, 22, 8, 45, 14, 6, 39, 0, 54, 11, 59, 28, 12, 50, 21, 61, 13, 19, 38, 49, 11, 25, 37, 58, 29, 22, 63, 14, 56, 12, 53, 30, 63, 9, 57, 26, 12, 47, 16, 23, 39, 50, 6, 31, 2, 25, 6, 28, 41, 36, 22, 50, 57, 42, 3, 34, 8, 28, 61, 11, 50, 16, 54, 41, 0, 55, 43, 5, 29, 41, 63, 25, 16, 53, 18, 26, 10, 21, 0, 61, 30, 41, 22, 3, 38, 20, 39, 29, 8, 41, 16, 36, 52, 22, 19 },
-     { 55, 34, 0, 25, 10, 32, 56, 44, 28, 0, 57, 7, 26, 53, 23, 8, 13, 35, 22, 12, 36, 60, 20, 8, 14, 29, 48, 2, 41, 49, 23, 13, 39, 7, 48, 58, 25, 53, 34, 62, 28, 16, 48, 4, 37, 56, 27, 5, 36, 52, 46, 7, 62, 33, 52, 11, 17, 53, 5, 28, 41, 24, 38, 17, 5, 39, 20, 45, 15, 56, 5, 38, 60, 8, 14, 57, 21, 48, 62, 39, 59, 13, 1, 60, 9, 32, 16, 63, 44, 25, 52, 15, 36, 2, 60, 29, 12, 33, 25, 17, 59, 45, 13, 8, 49, 32, 6, 40, 59, 29, 45, 37, 13, 47, 6, 55, 30, 45, 9, 52, 13, 59, 25, 47, 32, 1, 49, 30 },
-     { 9, 39, 14, 61, 49, 37, 3, 20, 50, 13, 41, 19, 46, 17, 38, 59, 28, 62, 4, 44, 54, 1, 34, 51, 55, 7, 63, 32, 21, 8, 56, 31, 62, 19, 36, 1, 41, 17, 24, 12, 42, 35, 25, 52, 20, 8, 44, 59, 25, 2, 22, 42, 16, 29, 4, 46, 20, 36, 43, 9, 51, 8, 49, 26, 58, 33, 54, 1, 37, 29, 52, 20, 27, 45, 19, 35, 42, 16, 10, 32, 20, 49, 46, 27, 40, 4, 47, 22, 13, 55, 4, 47, 26, 44, 23, 40, 58, 19, 48, 13, 31, 2, 57, 34, 42, 19, 61, 32, 14, 55, 5, 51, 26, 19, 58, 16, 49, 14, 62, 5, 33, 44, 21, 7, 60, 26, 11, 41 },
-     { 62, 24, 47, 29, 8, 19, 53, 11, 60, 24, 32, 61, 4, 55, 31, 2, 49, 16, 39, 9, 31, 24, 43, 17, 26, 38, 11, 25, 58, 43, 12, 35, 3, 46, 15, 32, 63, 4, 49, 56, 2, 60, 10, 32, 63, 17, 39, 12, 55, 30, 57, 9, 48, 55, 39, 24, 60, 2, 58, 31, 19, 61, 34, 3, 42, 11, 22, 46, 7, 61, 10, 42, 3, 55, 32, 1, 58, 28, 44, 54, 4, 34, 23, 15, 56, 20, 37, 58, 6, 30, 38, 18, 63, 9, 32, 5, 51, 3, 62, 37, 52, 18, 39, 23, 3, 51, 9, 47, 1, 23, 43, 15, 60, 35, 11, 40, 1, 36, 31, 26, 57, 2, 37, 54, 18, 44, 58, 16 },
-     { 5, 51, 3, 33, 43, 62, 21, 42, 35, 9, 48, 15, 36, 10, 22, 42, 20, 46, 26, 56, 50, 12, 59, 3, 48, 19, 45, 53, 1, 27, 47, 17, 52, 24, 56, 11, 51, 21, 37, 30, 20, 46, 14, 41, 1, 47, 33, 7, 41, 17, 35, 27, 20, 1, 14, 54, 26, 33, 18, 47, 1, 44, 14, 59, 16, 52, 28, 18, 49, 31, 25, 34, 63, 13, 51, 24, 9, 50, 3, 23, 38, 63, 7, 52, 29, 46, 11, 33, 50, 22, 57, 36, 1, 57, 49, 17, 39, 28, 9, 35, 6, 27, 53, 15, 55, 30, 24, 58, 36, 41, 11, 52, 32, 3, 44, 25, 62, 23, 51, 15, 42, 22, 50, 10, 39, 4, 31, 35 },
-     { 46, 22, 57, 17, 12, 39, 26, 5, 31, 59, 1, 45, 27, 62, 52, 7, 58, 33, 6, 18, 39, 22, 33, 41, 57, 5, 35, 18, 40, 16, 60, 5, 29, 42, 7, 39, 27, 44, 9, 47, 8, 26, 54, 22, 51, 29, 24, 49, 15, 61, 4, 51, 31, 63, 43, 6, 50, 8, 39, 12, 53, 37, 23, 30, 40, 6, 62, 43, 14, 53, 2, 49, 7, 36, 17, 41, 61, 37, 18, 56, 11, 18, 44, 35, 2, 19, 61, 0, 41, 14, 8, 30, 43, 12, 24, 46, 14, 54, 42, 21, 44, 61, 10, 46, 37, 11, 44, 7, 18, 63, 20, 29, 7, 49, 28, 54, 8, 43, 4, 48, 18, 63, 12, 29, 48, 24, 59, 20 },
-     { 13, 36, 28, 54, 35, 2, 56, 46, 16, 49, 22, 40, 11, 34, 14, 43, 29, 12, 63, 48, 2, 61, 7, 15, 28, 30, 50, 9, 61, 33, 38, 23, 54, 13, 61, 33, 3, 59, 16, 35, 58, 40, 5, 38, 13, 57, 3, 58, 37, 21, 45, 12, 39, 7, 35, 30, 13, 56, 22, 62, 27, 6, 55, 10, 48, 21, 33, 2, 38, 23, 40, 20, 44, 29, 59, 4, 26, 12, 33, 47, 28, 53, 31, 13, 59, 41, 27, 49, 26, 54, 45, 16, 53, 21, 35, 7, 59, 26, 11, 56, 1, 24, 33, 4, 28, 62, 21, 49, 31, 2, 56, 39, 24, 58, 13, 17, 37, 21, 56, 10, 38, 0, 34, 55, 15, 43, 1, 52 },
-     { 42, 9, 50, 6, 25, 60, 14, 38, 10, 29, 53, 18, 57, 3, 25, 51, 0, 53, 25, 17, 29, 37, 52, 46, 0, 62, 14, 37, 4, 50, 10, 44, 0, 46, 20, 25, 50, 19, 55, 0, 23, 31, 62, 34, 11, 45, 19, 32, 0, 53, 10, 59, 23, 47, 18, 60, 42, 28, 37, 3, 50, 15, 35, 44, 0, 51, 27, 60, 9, 57, 16, 58, 11, 22, 46, 15, 53, 48, 7, 42, 0, 60, 5, 49, 24, 54, 9, 17, 39, 5, 34, 62, 3, 40, 60, 31, 0, 47, 29, 16, 49, 39, 59, 17, 50, 0, 40, 13, 53, 38, 16, 46, 0, 42, 34, 60, 2, 53, 29, 31, 58, 46, 27, 6, 61, 8, 37, 28 },
-     { 0, 63, 21, 40, 45, 18, 51, 23, 63, 34, 6, 43, 28, 38, 55, 19, 40, 35, 8, 41, 54, 10, 21, 32, 39, 23, 53, 26, 55, 28, 22, 63, 30, 34, 9, 48, 6, 38, 29, 43, 49, 6, 18, 52, 27, 61, 9, 43, 28, 42, 33, 26, 56, 3, 51, 23, 0, 48, 16, 45, 32, 25, 63, 20, 57, 17, 42, 12, 35, 47, 5, 31, 39, 56, 6, 30, 34, 21, 61, 25, 14, 40, 22, 38, 15, 6, 36, 56, 20, 60, 25, 12, 51, 27, 10, 56, 42, 20, 36, 63, 32, 6, 21, 41, 12, 34, 60, 26, 5, 48, 27, 10, 62, 19, 6, 47, 39, 14, 45, 7, 24, 17, 41, 32, 23, 51, 19, 56 },
-     { 45, 31, 15, 59, 4, 33, 7, 47, 0, 41, 13, 61, 4, 47, 9, 23, 60, 14, 57, 31, 4, 45, 59, 6, 58, 10, 44, 20, 8, 42, 15, 6, 55, 17, 58, 31, 53, 12, 61, 10, 15, 57, 43, 2, 23, 35, 48, 14, 54, 6, 18, 49, 15, 38, 11, 34, 62, 9, 21, 58, 11, 41, 4, 31, 38, 8, 29, 55, 19, 36, 27, 52, 0, 25, 50, 43, 1, 39, 8, 55, 35, 51, 10, 30, 45, 62, 29, 2, 46, 10, 32, 48, 18, 38, 5, 22, 33, 8, 51, 3, 14, 44, 54, 25, 57, 30, 18, 52, 33, 22, 59, 28, 36, 52, 32, 21, 26, 50, 5, 55, 35, 60, 14, 54, 4, 40, 16, 33 },
-     { 27, 3, 49, 10, 30, 40, 55, 27, 57, 24, 52, 21, 32, 17, 60, 30, 5, 44, 27, 49, 19, 34, 13, 24, 43, 36, 3, 49, 31, 59, 37, 48, 26, 41, 2, 41, 14, 36, 21, 32, 40, 26, 13, 49, 55, 5, 16, 40, 25, 60, 36, 1, 63, 29, 17, 44, 25, 40, 52, 5, 29, 47, 54, 13, 46, 24, 60, 4, 51, 22, 63, 14, 45, 18, 12, 62, 17, 57, 19, 42, 3, 26, 58, 48, 1, 21, 40, 52, 23, 37, 44, 1, 29, 58, 43, 50, 15, 61, 19, 45, 58, 28, 7, 48, 2, 46, 8, 42, 3, 55, 8, 50, 12, 4, 55, 10, 63, 33, 20, 40, 11, 3, 46, 20, 48, 26, 61, 11 },
-     { 44, 56, 24, 36, 53, 19, 12, 37, 16, 44, 7, 36, 49, 54, 11, 37, 48, 21, 15, 1, 62, 25, 47, 56, 16, 18, 51, 12, 40, 1, 24, 11, 52, 16, 23, 59, 28, 1, 45, 53, 4, 60, 37, 21, 39, 30, 63, 20, 52, 10, 30, 45, 8, 41, 54, 4, 57, 7, 34, 55, 36, 18, 23, 59, 2, 48, 11, 32, 44, 1, 41, 8, 33, 54, 38, 23, 30, 46, 6, 29, 62, 18, 32, 16, 55, 34, 14, 11, 61, 7, 55, 16, 53, 13, 23, 2, 55, 37, 26, 10, 33, 23, 36, 16, 38, 22, 56, 15, 24, 43, 35, 17, 44, 40, 25, 46, 16, 1, 57, 25, 49, 36, 28, 62, 9, 35, 7, 53 },
-     { 17, 38, 8, 61, 1, 50, 26, 62, 3, 31, 56, 15, 1, 26, 40, 2, 34, 51, 56, 36, 42, 9, 38, 2, 29, 60, 32, 57, 19, 62, 34, 47, 4, 57, 39, 7, 44, 63, 24, 18, 46, 28, 8, 54, 1, 34, 7, 46, 3, 37, 50, 23, 57, 21, 13, 46, 31, 20, 43, 15, 1, 61, 8, 33, 37, 17, 56, 26, 15, 49, 24, 59, 28, 3, 56, 9, 52, 32, 13, 49, 10, 43, 5, 45, 8, 25, 59, 42, 28, 33, 19, 40, 8, 63, 35, 47, 25, 4, 40, 52, 1, 60, 12, 53, 63, 9, 29, 60, 37, 19, 1, 62, 31, 20, 58, 12, 41, 30, 43, 9, 18, 52, 22, 1, 39, 30, 58, 21 },
-     { 13, 47, 29, 18, 43, 34, 5, 48, 20, 42, 10, 45, 30, 58, 20, 63, 24, 11, 6, 28, 54, 14, 22, 52, 41, 7, 26, 5, 45, 15, 53, 13, 35, 27, 18, 50, 12, 33, 5, 56, 10, 17, 45, 24, 59, 15, 50, 26, 56, 13, 19, 5, 32, 52, 27, 36, 2, 61, 12, 26, 49, 40, 27, 52, 13, 50, 6, 39, 61, 34, 10, 37, 48, 20, 41, 27, 2, 36, 59, 24, 54, 33, 63, 20, 38, 50, 3, 17, 52, 4, 58, 27, 45, 21, 32, 11, 48, 17, 57, 20, 46, 38, 25, 43, 4, 34, 51, 6, 13, 45, 57, 26, 6, 48, 2, 35, 53, 23, 61, 34, 59, 6, 42, 56, 13, 51, 2, 41 },
-     { 32, 5, 55, 23, 58, 14, 22, 52, 29, 15, 61, 25, 51, 8, 43, 13, 53, 41, 46, 20, 3, 33, 63, 11, 48, 21, 54, 38, 28, 3, 30, 43, 21, 62, 9, 31, 55, 22, 51, 29, 37, 62, 32, 12, 42, 29, 41, 9, 33, 44, 62, 28, 43, 1, 59, 19, 48, 30, 51, 39, 24, 4, 58, 19, 42, 29, 22, 43, 3, 18, 53, 5, 13, 50, 16, 60, 45, 21, 7, 40, 15, 0, 26, 53, 13, 31, 43, 24, 47, 31, 15, 49, 2, 41, 6, 59, 29, 42, 9, 30, 14, 7, 49, 18, 31, 47, 20, 39, 49, 32, 11, 41, 54, 15, 61, 18, 7, 38, 4, 13, 44, 28, 15, 32, 45, 19, 27, 49 },
-     { 63, 34, 11, 39, 2, 45, 37, 8, 59, 39, 33, 4, 36, 17, 48, 5, 29, 18, 32, 61, 39, 50, 5, 27, 35, 0, 46, 12, 22, 49, 60, 6, 54, 0, 38, 49, 2, 42, 15, 40, 0, 47, 20, 51, 3, 57, 18, 61, 22, 0, 39, 16, 55, 12, 35, 8, 41, 22, 6, 59, 16, 45, 10, 36, 0, 62, 9, 54, 30, 58, 21, 43, 63, 31, 7, 35, 12, 48, 58, 28, 47, 37, 41, 9, 57, 20, 61, 0, 36, 11, 57, 35, 23, 52, 37, 18, 0, 62, 22, 55, 35, 62, 27, 54, 0, 15, 61, 28, 2, 59, 22, 9, 37, 27, 33, 51, 29, 48, 19, 50, 25, 37, 10, 57, 5, 37, 60, 8 },
-     { 20, 25, 46, 52, 31, 60, 12, 55, 0, 19, 11, 46, 62, 35, 23, 38, 57, 0, 55, 10, 16, 30, 58, 44, 17, 59, 29, 63, 42, 8, 36, 20, 33, 46, 16, 61, 25, 35, 8, 54, 26, 7, 58, 22, 34, 6, 47, 14, 53, 31, 48, 9, 37, 25, 49, 63, 16, 55, 45, 14, 34, 63, 21, 53, 25, 33, 46, 16, 35, 7, 46, 29, 0, 39, 25, 55, 22, 34, 18, 4, 56, 11, 23, 51, 28, 6, 39, 14, 62, 44, 19, 8, 60, 12, 56, 28, 50, 34, 39, 5, 51, 3, 41, 12, 57, 35, 10, 53, 25, 17, 52, 30, 47, 0, 43, 14, 5, 57, 31, 55, 0, 63, 47, 23, 54, 24, 14, 43 },
-     { 0, 57, 16, 6, 26, 19, 35, 28, 49, 42, 54, 26, 21, 1, 59, 27, 9, 47, 26, 44, 50, 22, 13, 40, 8, 37, 10, 34, 17, 56, 25, 58, 13, 27, 44, 9, 20, 58, 31, 17, 60, 36, 10, 41, 53, 25, 36, 39, 4, 24, 58, 17, 60, 4, 22, 38, 10, 32, 0, 50, 31, 7, 28, 47, 12, 57, 5, 26, 52, 23, 14, 40, 57, 17, 47, 5, 53, 1, 44, 31, 19, 60, 46, 2, 35, 48, 30, 54, 22, 5, 51, 39, 25, 31, 4, 43, 14, 9, 45, 16, 24, 44, 19, 29, 40, 23, 44, 7, 38, 42, 4, 63, 12, 54, 23, 59, 22, 42, 8, 15, 40, 21, 8, 34, 3, 41, 30, 50 },
-     { 39, 10, 48, 33, 41, 54, 5, 47, 23, 13, 32, 7, 52, 44, 14, 39, 58, 18, 35, 6, 37, 2, 60, 24, 55, 19, 53, 2, 51, 32, 1, 41, 51, 4, 40, 29, 47, 3, 52, 44, 13, 49, 28, 16, 1, 62, 11, 27, 52, 35, 5, 42, 29, 47, 14, 56, 28, 53, 26, 38, 9, 56, 40, 3, 38, 15, 41, 60, 1, 37, 50, 25, 11, 28, 61, 19, 42, 62, 10, 52, 39, 6, 32, 14, 58, 17, 7, 26, 42, 34, 27, 10, 54, 40, 20, 63, 26, 53, 21, 61, 32, 7, 59, 48, 3, 56, 18, 31, 58, 14, 49, 21, 36, 16, 45, 9, 36, 24, 62, 45, 27, 31, 53, 17, 49, 12, 62, 18 },
-     { 28, 59, 21, 58, 2, 16, 38, 9, 62, 3, 56, 41, 10, 31, 50, 4, 32, 52, 12, 63, 23, 46, 33, 31, 4, 48, 25, 43, 14, 23, 47, 11, 22, 55, 14, 60, 23, 37, 11, 39, 23, 2, 45, 56, 31, 43, 19, 55, 16, 46, 21, 51, 11, 33, 44, 2, 41, 18, 5, 52, 23, 44, 17, 60, 27, 49, 11, 32, 44, 10, 54, 2, 56, 33, 8, 38, 13, 29, 36, 16, 24, 63, 27, 51, 21, 43, 56, 12, 49, 3, 59, 48, 1, 15, 46, 7, 36, 2, 47, 11, 50, 27, 37, 13, 33, 8, 51, 46, 1, 34, 28, 40, 3, 33, 60, 29, 47, 1, 35, 11, 59, 42, 2, 60, 26, 46, 6, 35 },
-     { 4, 43, 9, 29, 36, 63, 24, 44, 20, 50, 30, 17, 60, 22, 16, 43, 25, 3, 42, 19, 51, 15, 8, 54, 42, 15, 61, 5, 39, 57, 18, 61, 31, 48, 34, 2, 50, 19, 57, 5, 63, 33, 19, 38, 13, 27, 48, 7, 32, 61, 2, 26, 58, 6, 24, 50, 13, 61, 42, 20, 62, 2, 35, 20, 51, 4, 62, 18, 23, 58, 20, 31, 43, 15, 51, 45, 26, 50, 4, 55, 45, 3, 35, 9, 38, 1, 32, 61, 20, 45, 17, 33, 24, 57, 29, 51, 22, 58, 38, 30, 15, 1, 54, 21, 63, 43, 26, 12, 24, 56, 8, 60, 50, 19, 5, 52, 13, 54, 17, 50, 4, 16, 36, 12, 32, 56, 22, 54 },
-     { 51, 25, 40, 53, 12, 49, 15, 57, 34, 7, 38, 47, 2, 36, 55, 8, 61, 30, 56, 7, 28, 59, 48, 11, 27, 35, 21, 45, 28, 36, 9, 38, 6, 16, 24, 63, 10, 32, 28, 43, 21, 53, 5, 60, 8, 57, 3, 45, 11, 37, 15, 54, 40, 20, 62, 36, 27, 34, 11, 48, 30, 15, 54, 8, 30, 42, 22, 34, 48, 13, 35, 63, 4, 37, 22, 2, 59, 9, 41, 23, 13, 41, 49, 18, 59, 24, 40, 5, 37, 30, 9, 61, 44, 6, 37, 11, 33, 17, 5, 55, 41, 60, 23, 39, 17, 5, 30, 62, 41, 16, 46, 25, 11, 56, 39, 26, 20, 38, 29, 39, 22, 52, 44, 20, 48, 1, 38, 14 },
-     { 15, 33, 2, 18, 44, 6, 27, 0, 32, 61, 25, 12, 58, 28, 40, 20, 47, 13, 34, 43, 38, 1, 23, 62, 40, 0, 51, 10, 63, 3, 52, 26, 44, 30, 45, 6, 41, 54, 0, 51, 12, 30, 46, 24, 49, 22, 40, 33, 63, 23, 43, 30, 9, 47, 0, 17, 54, 7, 57, 3, 37, 47, 24, 46, 13, 55, 7, 52, 2, 42, 6, 26, 49, 18, 60, 34, 16, 57, 33, 20, 61, 30, 8, 54, 14, 46, 12, 53, 16, 55, 38, 13, 22, 53, 18, 59, 46, 27, 43, 19, 32, 10, 45, 6, 49, 36, 52, 2, 20, 55, 6, 39, 32, 15, 44, 3, 58, 10, 63, 6, 56, 30, 7, 58, 9, 40, 19, 63 },
-     { 10, 47, 61, 23, 55, 31, 52, 42, 17, 45, 4, 51, 27, 6, 15, 53, 0, 49, 26, 10, 56, 18, 36, 6, 20, 58, 32, 30, 13, 49, 19, 56, 0, 59, 12, 53, 27, 17, 38, 25, 48, 9, 15, 36, 14, 30, 59, 17, 0, 50, 8, 58, 18, 56, 31, 45, 21, 41, 29, 19, 60, 6, 32, 59, 0, 36, 29, 39, 19, 59, 46, 12, 55, 30, 10, 47, 24, 3, 28, 48, 0, 55, 44, 27, 33, 4, 63, 29, 49, 0, 26, 50, 34, 2, 42, 14, 0, 62, 9, 56, 3, 52, 28, 34, 58, 9, 20, 48, 37, 32, 22, 53, 0, 62, 27, 49, 34, 46, 21, 33, 41, 14, 25, 37, 53, 29, 31, 45 },
-     { 56, 28, 7, 37, 11, 36, 20, 9, 54, 14, 39, 19, 34, 63, 45, 37, 24, 17, 60, 31, 21, 45, 53, 29, 47, 15, 7, 55, 40, 23, 34, 14, 42, 20, 37, 35, 15, 59, 7, 62, 34, 40, 59, 1, 51, 42, 10, 28, 54, 21, 35, 5, 38, 13, 36, 4, 59, 12, 39, 53, 15, 43, 9, 21, 39, 62, 16, 56, 25, 9, 32, 38, 0, 41, 14, 51, 40, 53, 43, 11, 37, 17, 5, 22, 57, 39, 19, 7, 42, 21, 60, 10, 31, 63, 25, 52, 30, 49, 36, 25, 48, 17, 61, 14, 22, 42, 29, 13, 60, 11, 47, 18, 35, 41, 7, 23, 4, 16, 51, 11, 0, 48, 61, 3, 17, 50, 5, 24 },
-     { 0, 42, 21, 49, 60, 3, 57, 40, 29, 48, 23, 56, 42, 11, 22, 5, 59, 39, 4, 50, 3, 41, 12, 57, 25, 50, 44, 18, 4, 46, 7, 62, 33, 50, 4, 56, 21, 32, 43, 18, 3, 23, 55, 34, 20, 4, 53, 38, 12, 46, 29, 52, 25, 61, 23, 51, 26, 46, 1, 34, 25, 57, 28, 51, 26, 11, 50, 3, 44, 28, 53, 21, 57, 27, 62, 6, 31, 19, 8, 63, 26, 59, 36, 47, 15, 29, 50, 25, 35, 47, 18, 41, 4, 48, 8, 40, 12, 23, 6, 44, 13, 40, 1, 31, 55, 0, 61, 43, 4, 50, 26, 58, 9, 53, 24, 61, 42, 55, 31, 43, 57, 20, 34, 27, 43, 8, 59, 39 },
-     { 18, 51, 30, 13, 26, 16, 46, 22, 2, 59, 8, 30, 1, 48, 33, 51, 29, 9, 46, 16, 62, 14, 33, 2, 38, 9, 27, 60, 37, 26, 53, 17, 28, 10, 24, 46, 2, 49, 8, 57, 29, 45, 6, 26, 62, 44, 18, 25, 61, 3, 42, 14, 49, 10, 43, 6, 17, 32, 63, 10, 49, 4, 40, 14, 45, 33, 22, 37, 12, 61, 5, 17, 43, 7, 23, 37, 15, 58, 49, 13, 39, 21, 10, 52, 1, 62, 9, 56, 12, 2, 58, 28, 36, 16, 56, 28, 56, 35, 20, 63, 24, 37, 51, 8, 45, 25, 16, 33, 27, 38, 2, 44, 13, 30, 17, 36, 12, 26, 5, 18, 28, 47, 13, 60, 23, 45, 13, 33 },
-     { 55, 4, 62, 34, 52, 38, 7, 63, 32, 37, 13, 53, 25, 62, 18, 12, 55, 41, 27, 35, 24, 49, 31, 52, 17, 63, 34, 1, 56, 12, 41, 2, 48, 58, 39, 16, 61, 27, 41, 52, 13, 19, 50, 39, 11, 31, 57, 6, 32, 40, 20, 55, 1, 28, 33, 57, 48, 8, 37, 22, 44, 18, 53, 1, 61, 5, 54, 16, 47, 36, 50, 24, 55, 34, 48, 45, 1, 30, 33, 46, 2, 50, 32, 42, 25, 34, 43, 21, 38, 52, 23, 45, 14, 54, 21, 4, 44, 16, 53, 29, 10, 47, 19, 57, 12, 54, 39, 10, 51, 15, 63, 21, 57, 40, 51, 1, 48, 57, 37, 62, 2, 38, 9, 52, 1, 35, 58, 22 },
-     { 36, 46, 10, 42, 1, 27, 43, 15, 50, 21, 45, 16, 41, 3, 35, 44, 20, 1, 57, 11, 55, 7, 43, 8, 22, 42, 13, 46, 21, 39, 31, 60, 22, 5, 29, 44, 11, 35, 20, 4, 36, 58, 32, 15, 47, 2, 36, 48, 16, 60, 8, 35, 44, 63, 16, 2, 40, 26, 55, 14, 58, 35, 24, 31, 19, 42, 31, 58, 1, 29, 10, 40, 2, 19, 12, 54, 22, 61, 7, 24, 56, 5, 28, 16, 54, 3, 15, 58, 6, 30, 8, 62, 1, 43, 31, 47, 7, 59, 1, 38, 58, 4, 34, 27, 38, 5, 31, 59, 7, 46, 30, 3, 34, 6, 28, 59, 20, 8, 32, 15, 53, 24, 55, 31, 19, 49, 11, 26 },
-     { 2, 24, 16, 58, 19, 55, 5, 35, 10, 61, 4, 28, 57, 24, 58, 7, 31, 47, 22, 38, 19, 28, 61, 36, 54, 5, 59, 29, 6, 52, 15, 11, 43, 36, 8, 54, 52, 1, 62, 25, 47, 9, 1, 60, 28, 53, 24, 14, 46, 27, 51, 22, 12, 24, 38, 53, 20, 11, 51, 3, 29, 7, 48, 63, 8, 49, 9, 21, 52, 14, 63, 32, 46, 60, 35, 4, 41, 16, 52, 35, 18, 42, 59, 7, 36, 61, 45, 27, 33, 51, 19, 39, 34, 11, 61, 18, 33, 41, 28, 15, 54, 22, 42, 3, 49, 21, 47, 18, 36, 23, 55, 19, 48, 24, 45, 10, 33, 44, 50, 40, 7, 35, 15, 41, 63, 6, 40, 54 },
-     { 62, 41, 32, 8, 47, 28, 60, 24, 44, 30, 38, 49, 9, 33, 14, 40, 50, 14, 60, 2, 54, 40, 0, 20, 25, 39, 16, 49, 24, 35, 57, 47, 19, 61, 33, 18, 23, 37, 13, 55, 31, 43, 22, 41, 17, 8, 42, 58, 0, 37, 5, 56, 31, 54, 7, 30, 60, 33, 42, 17, 59, 39, 12, 27, 38, 17, 35, 41, 27, 45, 20, 7, 25, 15, 29, 58, 27, 47, 11, 40, 14, 54, 23, 46, 19, 31, 11, 40, 13, 49, 5, 58, 24, 51, 26, 6, 50, 20, 49, 9, 32, 46, 17, 60, 14, 63, 24, 1, 57, 41, 9, 43, 14, 62, 16, 52, 3, 27, 14, 22, 61, 45, 4, 28, 9, 47, 29, 17 },
-     { 5, 50, 12, 53, 38, 18, 11, 51, 0, 55, 17, 6, 47, 54, 19, 63, 5, 26, 34, 45, 13, 30, 47, 58, 10, 48, 32, 3, 62, 9, 26, 0, 25, 14, 50, 3, 47, 30, 42, 16, 6, 63, 12, 49, 33, 55, 21, 10, 34, 63, 18, 41, 3, 47, 19, 43, 0, 49, 8, 28, 46, 20, 52, 0, 56, 24, 60, 3, 59, 5, 39, 57, 48, 52, 9, 38, 3, 21, 26, 60, 0, 32, 12, 38, 4, 48, 53, 0, 60, 15, 29, 44, 18, 10, 38, 57, 13, 60, 2, 26, 62, 7, 50, 29, 35, 8, 40, 53, 28, 12, 60, 33, 38, 5, 37, 29, 60, 39, 56, 0, 30, 18, 50, 34, 59, 25, 14, 44 },
-     { 20, 31, 60, 22, 3, 49, 33, 25, 40, 13, 34, 59, 22, 36, 0, 28, 37, 56, 8, 18, 51, 16, 4, 45, 27, 12, 53, 42, 18, 44, 51, 31, 55, 40, 28, 58, 7, 60, 10, 51, 27, 37, 24, 56, 5, 26, 44, 29, 50, 23, 45, 11, 34, 15, 59, 27, 13, 23, 62, 37, 4, 57, 15, 32, 42, 6, 47, 11, 30, 43, 23, 13, 0, 36, 18, 44, 63, 51, 37, 29, 49, 20, 57, 27, 62, 9, 24, 35, 23, 53, 37, 3, 42, 55, 0, 36, 23, 39, 31, 43, 17, 37, 24, 11, 52, 43, 19, 32, 5, 50, 26, 0, 56, 21, 54, 11, 19, 6, 47, 25, 59, 42, 12, 54, 21, 3, 38, 57 },
-     { 48, 0, 35, 27, 44, 14, 59, 7, 57, 46, 26, 2, 42, 12, 52, 43, 10, 27, 53, 42, 32, 62, 37, 21, 34, 61, 7, 23, 36, 4, 38, 12, 41, 5, 17, 45, 22, 27, 39, 21, 59, 0, 45, 18, 39, 62, 3, 38, 14, 7, 54, 26, 61, 39, 9, 52, 45, 36, 18, 50, 10, 34, 44, 22, 50, 14, 36, 55, 17, 34, 53, 62, 33, 26, 56, 6, 31, 12, 6, 53, 9, 44, 2, 50, 20, 40, 55, 17, 47, 7, 26, 63, 22, 32, 48, 16, 46, 8, 52, 12, 57, 41, 0, 56, 25, 3, 61, 14, 45, 35, 18, 44, 12, 46, 23, 42, 32, 51, 35, 10, 17, 36, 23, 1, 45, 52, 32, 10 },
-     { 37, 15, 43, 8, 63, 39, 21, 31, 16, 37, 19, 62, 30, 46, 17, 60, 21, 48, 1, 23, 6, 25, 11, 56, 1, 40, 30, 58, 15, 54, 21, 59, 9, 63, 35, 56, 11, 51, 2, 46, 34, 14, 53, 7, 30, 11, 51, 19, 60, 40, 30, 1, 24, 50, 20, 32, 3, 56, 5, 25, 31, 13, 61, 2, 29, 60, 25, 20, 51, 2, 27, 8, 18, 42, 10, 45, 21, 34, 43, 17, 62, 29, 41, 14, 34, 6, 30, 43, 2, 57, 33, 13, 45, 12, 27, 62, 4, 55, 21, 35, 5, 27, 45, 33, 16, 47, 30, 54, 22, 10, 51, 27, 63, 7, 49, 1, 58, 22, 15, 43, 53, 7, 57, 39, 27, 12, 61, 24 },
-     { 56, 51, 26, 56, 19, 2, 41, 54, 5, 52, 9, 48, 6, 23, 39, 4, 32, 15, 63, 35, 59, 49, 43, 15, 52, 19, 50, 9, 46, 33, 1, 29, 48, 20, 32, 1, 38, 33, 19, 54, 9, 32, 24, 48, 58, 35, 16, 48, 4, 52, 13, 57, 33, 5, 45, 59, 15, 29, 41, 55, 47, 39, 23, 53, 9, 40, 4, 57, 10, 44, 48, 40, 50, 14, 61, 24, 55, 1, 59, 22, 33, 8, 51, 25, 58, 46, 11, 59, 20, 41, 17, 51, 6, 56, 35, 25, 42, 30, 15, 58, 48, 18, 61, 9, 58, 39, 13, 2, 37, 59, 40, 2, 31, 16, 34, 41, 8, 30, 62, 3, 29, 48, 33, 5, 63, 16, 41, 7 },
-     { 22, 4, 46, 11, 33, 51, 29, 10, 62, 24, 43, 27, 15, 58, 50, 25, 54, 44, 9, 38, 18, 3, 29, 57, 32, 5, 26, 43, 17, 61, 24, 52, 8, 42, 23, 53, 15, 61, 7, 28, 57, 43, 4, 40, 20, 2, 43, 25, 32, 35, 21, 43, 17, 48, 10, 22, 38, 54, 11, 21, 1, 58, 16, 30, 48, 18, 46, 32, 38, 13, 22, 4, 59, 35, 2, 51, 30, 39, 15, 47, 4, 56, 13, 37, 1, 28, 16, 52, 32, 9, 61, 29, 38, 19, 3, 52, 10, 48, 1, 32, 11, 40, 20, 36, 6, 22, 49, 29, 55, 6, 20, 56, 36, 52, 19, 60, 26, 46, 18, 54, 40, 13, 20, 46, 35, 19, 49, 29 },
-     { 61, 17, 34, 53, 23, 6, 48, 35, 20, 40, 1, 56, 36, 29, 11, 34, 7, 41, 14, 30, 55, 20, 46, 8, 24, 38, 63, 2, 37, 10, 45, 14, 34, 49, 6, 13, 44, 25, 49, 41, 21, 12, 61, 15, 54, 29, 63, 12, 56, 8, 49, 2, 62, 36, 28, 61, 0, 25, 41, 63, 35, 8, 44, 6, 37, 62, 7, 21, 63, 28, 55, 31, 16, 24, 41, 19, 9, 57, 27, 36, 18, 42, 31, 62, 22, 55, 38, 4, 27, 47, 1, 40, 14, 54, 43, 20, 60, 23, 38, 63, 25, 51, 2, 53, 26, 63, 10, 42, 17, 34, 47, 25, 13, 5, 44, 11, 55, 2, 38, 27, 6, 60, 52, 25, 9, 55, 1, 40 },
-     { 8, 30, 58, 3, 42, 61, 17, 38, 13, 59, 32, 10, 54, 3, 51, 20, 61, 26, 57, 2, 46, 33, 12, 60, 41, 13, 48, 29, 55, 20, 39, 27, 57, 18, 62, 29, 55, 2, 31, 16, 37, 50, 26, 36, 6, 46, 9, 41, 27, 57, 23, 39, 26, 6, 51, 12, 31, 46, 7, 16, 27, 52, 19, 56, 26, 12, 33, 53, 1, 41, 8, 57, 46, 7, 54, 32, 47, 5, 49, 11, 60, 23, 5, 48, 10, 43, 19, 63, 35, 24, 49, 21, 59, 5, 31, 37, 14, 44, 7, 42, 6, 30, 46, 13, 44, 32, 19, 50, 4, 58, 8, 30, 62, 38, 28, 53, 21, 36, 13, 50, 21, 33, 15, 2, 44, 31, 14, 47 },
-     { 37, 13, 39, 16, 28, 9, 57, 0, 25, 49, 21, 45, 18, 47, 12, 42, 0, 49, 22, 39, 16, 53, 25, 36, 0, 52, 22, 16, 6, 60, 4, 51, 0, 26, 37, 47, 10, 36, 63, 5, 57, 0, 18, 59, 23, 33, 51, 19, 0, 44, 15, 11, 54, 17, 42, 35, 53, 18, 58, 33, 49, 4, 34, 42, 0, 50, 43, 25, 16, 49, 34, 20, 37, 28, 12, 63, 16, 38, 25, 44, 0, 40, 52, 17, 35, 3, 50, 14, 8, 53, 11, 36, 25, 45, 9, 62, 0, 54, 28, 17, 50, 55, 15, 24, 57, 0, 53, 34, 23, 41, 15, 45, 0, 49, 16, 4, 48, 9, 63, 45, 0, 42, 58, 37, 61, 22, 54, 26 },
-     { 0, 50, 21, 47, 54, 36, 27, 45, 52, 4, 34, 15, 63, 29, 37, 59, 17, 31, 6, 61, 28, 5, 48, 18, 59, 27, 34, 56, 44, 31, 35, 12, 41, 59, 16, 3, 40, 20, 50, 22, 30, 40, 52, 10, 45, 3, 59, 22, 37, 61, 29, 46, 31, 58, 2, 22, 9, 43, 3, 39, 14, 61, 24, 54, 15, 29, 11, 60, 39, 17, 5, 61, 0, 44, 50, 3, 31, 14, 58, 21, 54, 28, 15, 45, 60, 26, 33, 58, 44, 22, 60, 2, 57, 34, 49, 27, 18, 34, 21, 59, 29, 4, 36, 41, 8, 39, 28, 11, 62, 26, 53, 20, 35, 24, 59, 32, 29, 39, 24, 31, 57, 23, 11, 28, 5, 36, 11, 59 },
-     { 44, 32, 63, 5, 20, 12, 41, 7, 30, 61, 42, 8, 39, 5, 33, 8, 24, 53, 45, 11, 37, 58, 7, 44, 10, 50, 3, 40, 8, 22, 53, 19, 46, 9, 33, 52, 24, 58, 8, 44, 13, 47, 8, 34, 38, 30, 14, 47, 7, 34, 4, 55, 9, 19, 40, 49, 56, 26, 60, 21, 30, 45, 10, 19, 40, 58, 23, 36, 3, 52, 45, 23, 54, 13, 22, 42, 53, 45, 7, 33, 10, 36, 57, 6, 29, 12, 41, 0, 30, 15, 41, 30, 17, 7, 16, 53, 40, 56, 2, 39, 12, 61, 10, 52, 31, 60, 16, 45, 1, 37, 7, 61, 40, 10, 43, 17, 58, 7, 54, 14, 4, 51, 39, 49, 18, 56, 42, 20 },
-     { 14, 6, 24, 36, 56, 49, 22, 60, 18, 14, 23, 51, 26, 57, 21, 52, 41, 14, 35, 50, 19, 31, 40, 23, 33, 14, 63, 17, 32, 47, 7, 62, 23, 30, 56, 11, 42, 27, 14, 60, 35, 19, 28, 61, 17, 55, 25, 39, 53, 17, 42, 21, 38, 63, 25, 5, 14, 36, 12, 50, 1, 37, 59, 32, 2, 51, 6, 56, 27, 32, 11, 30, 38, 26, 60, 8, 26, 19, 62, 39, 50, 2, 21, 39, 53, 23, 56, 19, 49, 39, 5, 46, 55, 23, 42, 4, 31, 11, 47, 26, 45, 22, 48, 18, 21, 5, 48, 25, 57, 14, 47, 30, 3, 56, 12, 50, 1, 42, 19, 47, 35, 17, 8, 30, 45, 25, 4, 51 },
-     { 28, 58, 43, 1, 31, 8, 33, 2, 44, 55, 32, 1, 60, 12, 46, 27, 4, 62, 23, 1, 56, 13, 62, 2, 54, 36, 25, 51, 1, 57, 26, 42, 3, 49, 17, 38, 1, 48, 31, 4, 54, 3, 50, 24, 1, 49, 5, 63, 13, 27, 52, 1, 48, 13, 45, 33, 52, 30, 46, 20, 55, 28, 6, 48, 24, 38, 20, 47, 14, 62, 48, 9, 58, 4, 36, 30, 56, 1, 34, 12, 18, 63, 25, 48, 4, 16, 37, 7, 62, 10, 52, 28, 13, 50, 36, 63, 24, 51, 15, 58, 8, 33, 1, 38, 56, 35, 42, 9, 33, 51, 22, 18, 48, 32, 27, 37, 23, 61, 33, 11, 59, 29, 62, 1, 53, 10, 60, 33 },
-     { 12, 39, 17, 52, 26, 46, 53, 38, 25, 11, 48, 36, 16, 43, 2, 35, 55, 17, 39, 29, 43, 9, 28, 45, 20, 5, 46, 12, 42, 28, 13, 52, 36, 6, 60, 22, 54, 17, 62, 39, 25, 42, 15, 55, 44, 20, 31, 10, 35, 57, 24, 32, 29, 6, 59, 18, 7, 62, 3, 41, 10, 44, 16, 54, 13, 62, 31, 9, 41, 1, 21, 43, 18, 47, 15, 40, 11, 49, 28, 55, 46, 30, 8, 43, 32, 61, 28, 47, 25, 34, 21, 61, 32, 1, 20, 9, 46, 6, 35, 19, 41, 54, 27, 63, 14, 3, 51, 20, 62, 2, 38, 55, 8, 21, 63, 6, 46, 9, 26, 51, 3, 24, 43, 34, 16, 41, 18, 48 },
-     { 62, 23, 55, 9, 15, 62, 19, 13, 58, 40, 6, 30, 54, 19, 50, 31, 10, 44, 6, 59, 21, 47, 51, 15, 60, 39, 30, 54, 21, 61, 19, 33, 14, 29, 43, 11, 34, 45, 7, 21, 10, 56, 36, 6, 38, 11, 58, 42, 2, 47, 11, 60, 50, 16, 41, 28, 38, 23, 47, 17, 35, 63, 22, 33, 42, 5, 45, 17, 53, 35, 25, 56, 33, 6, 51, 19, 60, 23, 43, 15, 5, 40, 58, 13, 51, 1, 45, 11, 54, 3, 43, 8, 37, 48, 59, 29, 39, 21, 61, 43, 3, 31, 10, 44, 24, 29, 60, 12, 28, 40, 11, 25, 43, 52, 14, 41, 16, 57, 44, 20, 40, 55, 12, 21, 57, 27, 35, 2 },
-     { 37, 6, 31, 42, 40, 4, 29, 50, 0, 20, 63, 28, 9, 58, 14, 24, 63, 26, 48, 16, 34, 4, 32, 38, 23, 11, 58, 4, 37, 9, 45, 5, 63, 48, 26, 57, 2, 28, 32, 51, 46, 29, 13, 62, 27, 46, 28, 18, 50, 15, 40, 4, 19, 34, 54, 0, 53, 9, 26, 58, 28, 5, 49, 0, 57, 27, 19, 60, 29, 8, 59, 12, 37, 63, 24, 46, 3, 37, 6, 52, 26, 32, 20, 36, 9, 22, 59, 18, 35, 51, 14, 57, 17, 24, 12, 44, 56, 0, 30, 13, 59, 20, 49, 17, 54, 43, 6, 34, 46, 17, 58, 36, 0, 34, 29, 54, 25, 2, 36, 15, 60, 6, 37, 46, 4, 50, 9, 45 },
-     { 19, 59, 48, 3, 24, 60, 44, 22, 34, 51, 15, 45, 41, 5, 33, 47, 0, 37, 12, 55, 25, 54, 8, 57, 0, 47, 18, 34, 49, 15, 55, 24, 40, 20, 8, 35, 53, 13, 41, 18, 0, 59, 22, 33, 4, 52, 8, 60, 24, 36, 31, 56, 45, 26, 10, 43, 15, 56, 36, 4, 51, 14, 39, 30, 12, 55, 36, 2, 39, 49, 4, 44, 17, 0, 32, 13, 53, 35, 59, 17, 62, 0, 55, 24, 52, 38, 31, 6, 42, 19, 29, 40, 4, 54, 33, 5, 16, 27, 52, 37, 23, 55, 7, 37, 0, 39, 23, 49, 4, 53, 31, 15, 59, 10, 50, 4, 60, 34, 48, 7, 31, 49, 27, 14, 62, 22, 53, 29 },
-     { 46, 21, 14, 51, 36, 17, 7, 57, 10, 32, 3, 37, 22, 60, 39, 18, 56, 20, 42, 3, 36, 10, 44, 26, 41, 29, 53, 27, 2, 39, 30, 52, 0, 59, 15, 48, 23, 61, 6, 58, 37, 12, 40, 49, 16, 39, 20, 44, 0, 62, 8, 21, 3, 59, 23, 32, 49, 31, 12, 44, 22, 59, 18, 50, 24, 7, 43, 52, 15, 23, 41, 26, 51, 28, 55, 39, 21, 27, 10, 42, 12, 45, 27, 47, 3, 15, 63, 26, 55, 0, 60, 26, 45, 18, 62, 38, 58, 49, 8, 47, 4, 33, 46, 29, 57, 13, 56, 16, 59, 21, 5, 47, 23, 39, 18, 44, 13, 22, 28, 53, 19, 0, 58, 32, 41, 7, 26, 13 },
-     { 0, 56, 34, 28, 11, 55, 31, 47, 26, 41, 56, 13, 53, 28, 11, 49, 7, 52, 32, 61, 50, 22, 63, 17, 13, 56, 7, 19, 43, 62, 10, 21, 37, 32, 43, 4, 38, 19, 44, 25, 31, 54, 5, 23, 61, 30, 53, 12, 35, 22, 43, 53, 37, 48, 7, 62, 20, 2, 61, 41, 8, 34, 47, 9, 63, 34, 28, 10, 55, 33, 14, 57, 7, 47, 9, 61, 4, 49, 31, 50, 21, 38, 8, 16, 57, 44, 33, 5, 49, 36, 12, 50, 7, 34, 10, 25, 2, 22, 36, 15, 26, 61, 18, 9, 22, 46, 32, 8, 27, 37, 44, 30, 55, 3, 62, 24, 38, 56, 5, 45, 38, 24, 43, 10, 19, 54, 39, 61 },
-     { 41, 30, 8, 63, 43, 23, 38, 3, 62, 19, 8, 49, 25, 1, 58, 30, 23, 40, 9, 28, 18, 40, 6, 38, 49, 22, 35, 59, 8, 27, 50, 5, 56, 17, 11, 50, 30, 9, 55, 2, 51, 19, 34, 47, 9, 41, 6, 26, 48, 57, 14, 28, 17, 12, 39, 13, 37, 46, 25, 19, 54, 27, 1, 37, 16, 45, 20, 60, 1, 48, 20, 38, 31, 22, 42, 15, 19, 44, 1, 61, 6, 34, 56, 40, 29, 10, 20, 46, 13, 22, 41, 23, 59, 42, 30, 51, 45, 13, 63, 53, 42, 12, 51, 38, 62, 2, 26, 41, 50, 1, 61, 10, 19, 42, 31, 8, 49, 32, 12, 63, 9, 52, 16, 56, 36, 2, 31, 16 },
-     { 52, 5, 47, 20, 1, 53, 12, 50, 16, 35, 43, 21, 33, 43, 16, 44, 3, 59, 14, 46, 1, 30, 60, 33, 2, 45, 12, 42, 31, 47, 14, 33, 46, 25, 55, 27, 60, 36, 16, 42, 14, 46, 26, 1, 55, 15, 63, 32, 2, 38, 5, 47, 33, 61, 30, 52, 4, 57, 6, 38, 11, 43, 61, 24, 52, 3, 31, 22, 42, 10, 62, 3, 59, 11, 35, 57, 33, 54, 24, 14, 29, 48, 18, 2, 60, 41, 53, 24, 32, 62, 3, 53, 15, 1, 55, 17, 32, 40, 6, 31, 1, 40, 28, 5, 35, 52, 19, 63, 13, 33, 17, 41, 52, 26, 15, 57, 1, 20, 42, 17, 35, 27, 48, 5, 25, 50, 44, 11 },
-     { 35, 25, 38, 57, 33, 17, 40, 6, 59, 27, 54, 5, 61, 10, 52, 26, 36, 19, 51, 35, 57, 48, 11, 20, 54, 25, 61, 16, 1, 58, 24, 61, 3, 39, 7, 47, 1, 22, 49, 28, 63, 10, 58, 32, 17, 36, 45, 19, 51, 29, 59, 10, 50, 1, 23, 42, 18, 29, 51, 21, 56, 32, 14, 5, 40, 58, 47, 13, 54, 35, 29, 45, 18, 52, 26, 2, 38, 8, 46, 36, 58, 11, 52, 35, 17, 28, 1, 58, 9, 39, 17, 28, 37, 48, 20, 9, 57, 24, 50, 19, 58, 16, 48, 25, 43, 11, 35, 6, 45, 24, 56, 4, 36, 7, 47, 35, 52, 28, 59, 30, 2, 61, 21, 33, 63, 12, 18, 59 },
-     { 3, 49, 15, 10, 27, 61, 25, 45, 30, 0, 14, 47, 31, 38, 17, 62, 7, 55, 27, 4, 15, 24, 42, 52, 10, 34, 5, 51, 36, 18, 41, 11, 35, 21, 62, 13, 33, 57, 8, 35, 5, 40, 21, 43, 52, 3, 24, 56, 11, 16, 33, 25, 41, 20, 55, 8, 60, 35, 15, 48, 2, 57, 30, 49, 18, 25, 6, 39, 17, 57, 7, 25, 43, 5, 49, 16, 62, 22, 55, 4, 25, 43, 23, 7, 50, 11, 37, 48, 14, 51, 33, 57, 7, 27, 39, 46, 4, 29, 11, 43, 34, 56, 7, 60, 20, 54, 30, 57, 22, 49, 9, 33, 54, 14, 63, 23, 6, 43, 10, 40, 50, 13, 44, 8, 38, 33, 46, 23 },
-     { 55, 39, 22, 50, 44, 4, 36, 9, 52, 23, 37, 59, 21, 2, 46, 13, 31, 41, 11, 45, 62, 29, 6, 37, 19, 48, 30, 23, 44, 7, 53, 28, 54, 16, 41, 29, 44, 18, 52, 24, 60, 15, 48, 7, 27, 59, 9, 34, 42, 54, 7, 63, 4, 46, 31, 27, 45, 0, 40, 26, 34, 17, 37, 10, 53, 29, 36, 50, 2, 27, 51, 11, 61, 37, 23, 41, 30, 7, 18, 50, 39, 14, 63, 32, 45, 61, 19, 30, 25, 44, 2, 47, 23, 63, 11, 34, 59, 37, 60, 3, 22, 14, 44, 30, 15, 0, 47, 15, 3, 38, 61, 20, 27, 45, 11, 39, 51, 16, 55, 3, 22, 54, 29, 58, 1, 57, 6, 29 },
-     { 9, 17, 60, 2, 34, 56, 20, 62, 39, 12, 49, 6, 29, 56, 34, 48, 0, 58, 22, 38, 18, 43, 56, 0, 63, 14, 55, 3, 59, 31, 15, 45, 0, 49, 6, 58, 3, 38, 12, 45, 0, 37, 29, 57, 13, 39, 30, 49, 0, 23, 44, 36, 16, 57, 13, 54, 11, 24, 63, 9, 53, 7, 62, 42, 0, 59, 15, 23, 63, 34, 40, 16, 32, 0, 53, 12, 48, 28, 59, 33, 0, 53, 9, 27, 3, 22, 54, 5, 56, 9, 61, 13, 42, 14, 52, 19, 0, 21, 47, 27, 53, 36, 3, 50, 39, 58, 25, 40, 53, 28, 12, 50, 0, 59, 32, 2, 21, 34, 26, 46, 37, 7, 18, 47, 24, 14, 53, 42 },
-     { 61, 32, 13, 54, 29, 7, 46, 13, 28, 57, 18, 41, 53, 15, 9, 39, 24, 49, 33, 3, 53, 9, 26, 32, 40, 28, 46, 39, 25, 9, 56, 21, 63, 37, 26, 22, 51, 27, 17, 56, 31, 53, 4, 43, 22, 46, 12, 18, 60, 40, 20, 26, 50, 21, 39, 5, 49, 33, 16, 44, 22, 46, 20, 32, 24, 45, 8, 43, 12, 46, 4, 48, 56, 20, 29, 58, 3, 40, 10, 42, 31, 21, 47, 41, 56, 38, 15, 42, 36, 27, 20, 33, 55, 3, 26, 44, 31, 54, 12, 35, 9, 63, 28, 10, 21, 32, 9, 60, 17, 8, 43, 29, 40, 16, 36, 48, 60, 7, 57, 14, 62, 31, 42, 15, 36, 40, 20, 26 },
-     { 0, 37, 47, 23, 41, 18, 32, 48, 1, 35, 8, 25, 4, 26, 63, 20, 54, 8, 16, 61, 35, 23, 51, 15, 58, 7, 12, 20, 50, 34, 42, 4, 38, 10, 32, 47, 8, 60, 41, 20, 9, 25, 50, 19, 62, 1, 37, 56, 28, 8, 53, 11, 3, 58, 34, 43, 19, 60, 38, 4, 58, 31, 3, 51, 11, 55, 38, 30, 21, 58, 19, 26, 9, 44, 36, 13, 46, 20, 62, 24, 13, 60, 5, 28, 12, 34, 7, 59, 0, 53, 45, 6, 38, 30, 50, 7, 62, 16, 41, 5, 46, 18, 55, 42, 51, 5, 45, 23, 34, 48, 19, 58, 5, 25, 54, 19, 13, 41, 28, 21, 0, 49, 10, 60, 4, 51, 9, 45 },
-     { 19, 28, 6, 58, 10, 51, 4, 22, 55, 42, 60, 45, 34, 51, 42, 5, 30, 45, 27, 40, 13, 47, 4, 49, 21, 38, 60, 29, 2, 57, 17, 27, 52, 19, 61, 14, 30, 34, 2, 44, 63, 33, 11, 35, 16, 51, 25, 6, 14, 47, 31, 61, 37, 29, 18, 8, 52, 2, 28, 54, 13, 41, 15, 62, 35, 18, 2, 60, 6, 33, 41, 61, 31, 6, 56, 17, 34, 50, 6, 52, 44, 35, 16, 51, 59, 24, 48, 18, 31, 40, 16, 49, 21, 60, 17, 39, 10, 49, 32, 57, 24, 39, 1, 25, 18, 62, 37, 12, 56, 1, 37, 11, 52, 44, 9, 30, 47, 4, 51, 40, 55, 25, 34, 27, 56, 30, 32, 54 },
-     { 63, 40, 49, 15, 43, 26, 63, 38, 16, 20, 30, 12, 57, 14, 19, 60, 36, 12, 59, 2, 57, 17, 42, 31, 1, 44, 16, 35, 47, 11, 32, 48, 13, 43, 1, 39, 51, 12, 57, 23, 6, 40, 53, 3, 55, 31, 39, 60, 35, 44, 5, 15, 45, 1, 62, 41, 26, 14, 47, 22, 36, 27, 50, 9, 26, 47, 52, 28, 54, 16, 1, 13, 51, 39, 23, 63, 1, 30, 15, 26, 2, 57, 19, 37, 1, 44, 21, 50, 13, 63, 8, 24, 56, 1, 35, 25, 58, 20, 2, 28, 14, 51, 33, 59, 13, 30, 4, 49, 31, 24, 63, 26, 33, 3, 58, 38, 62, 24, 32, 8, 17, 45, 5, 48, 18, 3, 43, 11 },
-     { 21, 4, 24, 34, 59, 1, 37, 11, 53, 5, 47, 2, 22, 40, 32, 1, 24, 50, 21, 29, 38, 25, 63, 8, 55, 24, 53, 6, 62, 23, 59, 3, 54, 20, 58, 24, 5, 46, 15, 38, 48, 14, 27, 42, 23, 7, 46, 10, 17, 58, 25, 52, 23, 32, 49, 12, 55, 30, 40, 7, 59, 1, 56, 21, 39, 4, 23, 15, 37, 46, 55, 42, 21, 4, 48, 8, 45, 54, 37, 55, 32, 8, 46, 10, 30, 54, 4, 41, 25, 29, 36, 48, 11, 43, 14, 47, 5, 43, 53, 36, 61, 10, 45, 6, 41, 54, 27, 43, 16, 55, 6, 46, 18, 42, 23, 15, 1, 45, 12, 60, 37, 22, 62, 12, 39, 59, 16, 52 },
-     { 47, 35, 56, 7, 19, 46, 31, 50, 33, 24, 61, 35, 50, 7, 53, 44, 55, 6, 46, 10, 52, 5, 21, 43, 36, 10, 18, 41, 26, 37, 8, 29, 40, 36, 9, 49, 34, 26, 61, 21, 7, 59, 18, 62, 29, 54, 20, 32, 51, 0, 40, 10, 55, 6, 20, 36, 9, 61, 5, 51, 44, 19, 33, 43, 13, 57, 40, 63, 8, 24, 29, 10, 60, 34, 27, 40, 25, 18, 10, 42, 21, 49, 26, 62, 38, 12, 33, 61, 5, 57, 2, 19, 54, 28, 62, 22, 38, 31, 16, 7, 22, 47, 29, 17, 35, 8, 20, 51, 2, 40, 22, 50, 13, 61, 28, 53, 35, 20, 56, 30, 2, 53, 14, 41, 23, 34, 8, 31 },
-     { 12, 2, 42, 29, 52, 13, 21, 8, 55, 14, 41, 17, 28, 58, 23, 11, 17, 36, 31, 62, 17, 34, 50, 14, 28, 61, 33, 52, 2, 51, 17, 45, 7, 25, 62, 30, 18, 55, 0, 42, 30, 35, 45, 1, 12, 48, 3, 63, 21, 36, 30, 48, 19, 59, 43, 27, 46, 17, 34, 25, 12, 29, 53, 6, 48, 31, 11, 34, 49, 3, 36, 50, 19, 47, 14, 61, 11, 36, 58, 4, 60, 14, 39, 22, 6, 52, 15, 35, 17, 46, 31, 42, 9, 34, 3, 52, 12, 60, 26, 56, 40, 2, 53, 23, 57, 38, 62, 14, 36, 59, 10, 31, 39, 6, 49, 9, 41, 26, 5, 48, 43, 27, 33, 58, 1, 50, 25, 57 },
-     { 61, 37, 15, 61, 3, 39, 58, 43, 26, 0, 44, 10, 47, 3, 37, 63, 28, 43, 13, 39, 3, 57, 30, 59, 0, 48, 5, 43, 13, 22, 60, 33, 55, 15, 42, 4, 52, 10, 45, 13, 54, 4, 24, 49, 37, 26, 41, 14, 42, 9, 61, 13, 38, 23, 3, 53, 0, 58, 21, 42, 63, 10, 17, 61, 25, 0, 58, 28, 17, 44, 57, 12, 27, 0, 55, 5, 52, 28, 23, 47, 29, 0, 43, 17, 58, 28, 47, 23, 55, 10, 58, 23, 51, 40, 18, 33, 45, 0, 49, 8, 32, 61, 19, 48, 0, 26, 7, 47, 29, 18, 44, 0, 56, 34, 20, 59, 15, 51, 37, 18, 10, 52, 7, 20, 46, 9, 38, 17 },
-     { 6, 27, 48, 23, 45, 29, 5, 18, 38, 62, 27, 56, 20, 32, 15, 9, 48, 0, 54, 22, 45, 20, 7, 41, 23, 39, 19, 27, 58, 31, 44, 0, 12, 50, 23, 56, 20, 39, 32, 59, 16, 52, 33, 9, 57, 22, 6, 58, 28, 50, 24, 2, 56, 35, 16, 45, 32, 38, 15, 54, 2, 38, 46, 22, 35, 45, 20, 5, 52, 25, 7, 35, 59, 32, 22, 43, 38, 3, 51, 16, 34, 53, 32, 50, 3, 40, 8, 43, 0, 39, 27, 4, 14, 61, 8, 55, 15, 41, 20, 44, 27, 13, 39, 11, 46, 42, 54, 33, 4, 52, 23, 61, 14, 25, 43, 2, 33, 11, 63, 29, 61, 17, 40, 55, 22, 62, 28, 44 },
-     { 20, 54, 8, 56, 35, 10, 63, 31, 52, 12, 48, 6, 59, 41, 52, 33, 19, 58, 25, 49, 11, 37, 47, 12, 54, 15, 56, 35, 7, 47, 16, 53, 28, 34, 5, 37, 28, 8, 48, 3, 28, 38, 18, 61, 16, 43, 53, 32, 4, 17, 47, 27, 44, 8, 63, 10, 25, 49, 6, 37, 24, 52, 32, 3, 50, 12, 41, 56, 38, 14, 62, 20, 40, 16, 53, 31, 18, 63, 41, 9, 59, 7, 13, 25, 57, 20, 63, 26, 53, 18, 48, 62, 30, 46, 21, 25, 58, 29, 36, 4, 55, 34, 6, 60, 31, 16, 21, 12, 58, 38, 9, 29, 47, 7, 52, 30, 57, 44, 22, 0, 35, 45, 3, 31, 14, 36, 0, 51 },
-     { 42, 14, 33, 24, 16, 49, 40, 2, 22, 33, 16, 36, 25, 1, 21, 61, 38, 8, 33, 4, 62, 26, 29, 60, 6, 46, 30, 11, 63, 4, 36, 40, 19, 57, 46, 11, 41, 63, 22, 25, 58, 10, 46, 2, 34, 27, 11, 38, 56, 34, 12, 53, 18, 33, 41, 51, 13, 28, 60, 20, 47, 14, 29, 59, 16, 62, 8, 22, 32, 47, 9, 49, 2, 44, 7, 12, 45, 6, 20, 27, 45, 24, 62, 42, 36, 11, 33, 15, 37, 7, 32, 10, 37, 1, 35, 50, 6, 11, 63, 24, 52, 15, 50, 24, 3, 37, 56, 27, 34, 22, 49, 16, 36, 62, 17, 39, 4, 15, 54, 24, 50, 8, 58, 26, 49, 54, 11, 30 },
-     { 4, 59, 41, 1, 53, 12, 25, 45, 59, 7, 51, 39, 54, 14, 46, 4, 27, 53, 16, 44, 18, 51, 1, 32, 25, 2, 50, 40, 20, 54, 24, 9, 62, 2, 27, 60, 1, 17, 36, 50, 6, 40, 30, 55, 41, 19, 49, 1, 21, 60, 40, 5, 62, 1, 22, 30, 57, 4, 43, 31, 1, 55, 40, 7, 27, 37, 30, 54, 1, 19, 42, 30, 56, 26, 62, 49, 24, 57, 37, 56, 2, 39, 16, 5, 30, 55, 3, 49, 60, 23, 56, 44, 17, 52, 13, 42, 28, 48, 18, 45, 9, 37, 21, 41, 58, 10, 48, 1, 63, 5, 41, 57, 2, 24, 12, 48, 27, 42, 32, 46, 13, 38, 19, 34, 5, 41, 25, 60 },
-     { 39, 28, 21, 46, 32, 57, 36, 9, 19, 42, 4, 29, 11, 43, 30, 49, 13, 42, 35, 56, 9, 39, 15, 52, 36, 61, 18, 26, 45, 14, 31, 48, 21, 43, 14, 33, 49, 54, 14, 44, 21, 62, 13, 23, 8, 62, 15, 51, 44, 7, 30, 37, 20, 42, 56, 7, 39, 18, 50, 11, 61, 9, 19, 43, 57, 2, 48, 11, 39, 60, 28, 4, 37, 17, 35, 1, 33, 11, 31, 14, 48, 19, 35, 51, 46, 21, 44, 29, 12, 41, 2, 22, 58, 26, 54, 4, 59, 38, 2, 33, 57, 1, 63, 13, 28, 51, 15, 40, 18, 45, 8, 30, 43, 37, 54, 19, 8, 59, 21, 6, 60, 29, 55, 10, 63, 15, 47, 17 },
-     { 3, 50, 10, 62, 18, 5, 27, 49, 60, 23, 55, 18, 62, 24, 56, 10, 59, 28, 2, 23, 34, 59, 43, 20, 10, 42, 8, 49, 1, 37, 57, 6, 51, 29, 53, 7, 23, 31, 5, 32, 51, 0, 35, 54, 45, 31, 5, 26, 36, 24, 55, 15, 48, 29, 14, 48, 26, 60, 21, 41, 36, 26, 50, 33, 14, 44, 17, 24, 52, 15, 46, 23, 54, 6, 47, 21, 60, 50, 4, 53, 29, 61, 8, 23, 1, 60, 19, 6, 53, 16, 47, 34, 6, 39, 16, 31, 12, 20, 53, 22, 30, 43, 25, 46, 35, 6, 44, 32, 53, 26, 55, 19, 11, 59, 5, 33, 51, 1, 35, 53, 25, 3, 42, 23, 44, 32, 7, 53 },
-     { 22, 44, 37, 6, 26, 51, 38, 0, 34, 13, 31, 46, 3, 37, 6, 19, 40, 21, 47, 63, 12, 5, 29, 55, 22, 58, 34, 28, 60, 22, 11, 41, 17, 38, 9, 44, 59, 39, 56, 19, 11, 47, 25, 15, 3, 39, 57, 17, 61, 11, 46, 3, 58, 9, 54, 35, 2, 34, 8, 45, 15, 56, 5, 23, 53, 33, 63, 35, 4, 59, 10, 51, 13, 61, 29, 41, 15, 25, 43, 19, 40, 10, 54, 33, 41, 12, 38, 51, 31, 26, 61, 9, 30, 45, 24, 62, 49, 40, 10, 61, 14, 49, 5, 17, 54, 20, 60, 23, 3, 13, 35, 50, 32, 23, 46, 27, 38, 63, 16, 12, 39, 48, 18, 51, 1, 27, 56, 35 },
-     { 63, 15, 30, 55, 43, 14, 57, 17, 53, 44, 7, 48, 26, 50, 32, 60, 0, 53, 14, 31, 50, 24, 46, 0, 38, 13, 4, 52, 16, 45, 30, 59, 0, 25, 55, 35, 16, 10, 26, 42, 58, 29, 60, 38, 50, 22, 28, 47, 0, 50, 28, 19, 33, 39, 11, 44, 16, 52, 24, 59, 3, 38, 27, 51, 0, 21, 7, 42, 26, 34, 21, 40, 33, 18, 39, 3, 54, 38, 8, 59, 0, 44, 27, 15, 58, 28, 57, 9, 43, 0, 36, 50, 20, 59, 8, 34, 0, 27, 47, 7, 36, 19, 56, 32, 0, 38, 11, 29, 62, 47, 6, 61, 0, 41, 14, 56, 10, 23, 45, 31, 57, 8, 36, 13, 58, 38, 11, 19 },
-     { 0, 34, 12, 47, 21, 2, 40, 30, 11, 25, 61, 20, 40, 15, 35, 22, 45, 36, 7, 41, 17, 57, 9, 48, 32, 62, 44, 24, 35, 3, 54, 13, 33, 63, 19, 4, 48, 22, 62, 2, 37, 8, 33, 6, 20, 52, 9, 32, 43, 13, 39, 63, 25, 4, 49, 23, 62, 32, 9, 30, 48, 18, 63, 12, 46, 29, 58, 13, 48, 8, 57, 31, 0, 51, 9, 58, 12, 22, 47, 29, 35, 22, 49, 5, 46, 4, 34, 20, 63, 24, 56, 11, 41, 3, 51, 19, 56, 35, 17, 58, 28, 42, 9, 45, 59, 26, 51, 42, 17, 36, 25, 15, 53, 21, 44, 3, 30, 55, 5, 50, 21, 28, 61, 32, 6, 49, 28, 46 },
-     { 58, 42, 60, 4, 31, 59, 22, 63, 35, 38, 9, 54, 1, 57, 8, 51, 16, 58, 27, 53, 3, 38, 30, 15, 27, 6, 19, 56, 10, 50, 21, 36, 47, 5, 43, 28, 51, 32, 13, 46, 18, 54, 16, 43, 63, 12, 36, 59, 22, 34, 5, 52, 17, 59, 27, 41, 0, 19, 55, 37, 13, 43, 6, 34, 41, 10, 36, 55, 19, 44, 3, 16, 58, 27, 49, 25, 32, 62, 17, 55, 13, 63, 18, 52, 25, 37, 17, 48, 13, 32, 5, 46, 28, 37, 14, 43, 25, 5, 51, 39, 3, 52, 33, 22, 8, 40, 12, 4, 57, 9, 46, 39, 28, 58, 13, 62, 17, 42, 19, 36, 0, 47, 16, 43, 24, 21, 54, 13 },
-     { 25, 9, 23, 50, 36, 8, 45, 14, 3, 51, 16, 28, 44, 12, 42, 29, 4, 26, 10, 47, 22, 61, 18, 54, 51, 39, 46, 13, 41, 26, 58, 7, 18, 39, 12, 57, 15, 1, 52, 27, 41, 23, 48, 1, 27, 45, 18, 2, 57, 26, 55, 8, 43, 31, 6, 58, 14, 51, 40, 5, 61, 31, 24, 54, 17, 60, 22, 1, 39, 30, 53, 45, 36, 13, 43, 5, 45, 2, 37, 6, 34, 42, 2, 39, 10, 62, 7, 54, 40, 18, 60, 15, 52, 21, 63, 8, 55, 46, 15, 30, 23, 13, 62, 16, 50, 24, 58, 31, 48, 21, 34, 2, 49, 7, 31, 37, 26, 48, 9, 61, 40, 11, 52, 2, 60, 40, 4, 37 },
-     { 52, 28, 39, 16, 54, 19, 29, 55, 42, 20, 58, 33, 24, 63, 18, 55, 39, 62, 43, 34, 12, 40, 6, 35, 2, 25, 8, 62, 34, 1, 31, 42, 61, 27, 53, 24, 40, 61, 34, 8, 59, 4, 30, 56, 40, 6, 53, 42, 10, 48, 16, 37, 12, 46, 21, 36, 47, 11, 28, 45, 22, 10, 57, 2, 49, 31, 14, 44, 61, 11, 25, 6, 23, 63, 18, 36, 28, 56, 20, 51, 11, 48, 27, 56, 32, 22, 45, 30, 2, 42, 27, 39, 1, 44, 23, 31, 38, 22, 11, 61, 43, 54, 4, 47, 35, 2, 44, 16, 28, 54, 12, 62, 18, 43, 10, 52, 1, 58, 33, 15, 29, 56, 20, 34, 9, 30, 48, 17 },
-     { 46, 2, 56, 11, 41, 1, 49, 6, 27, 47, 2, 48, 5, 32, 37, 3, 13, 19, 32, 1, 55, 28, 60, 17, 43, 59, 32, 20, 49, 16, 55, 23, 14, 46, 2, 36, 6, 30, 20, 49, 12, 47, 35, 14, 21, 60, 29, 14, 35, 24, 46, 1, 56, 29, 53, 8, 33, 23, 56, 1, 35, 46, 20, 39, 26, 4, 53, 28, 17, 38, 60, 34, 48, 9, 55, 15, 46, 7, 41, 31, 60, 24, 16, 36, 1, 59, 19, 52, 35, 6, 55, 11, 59, 33, 7, 57, 4, 29, 48, 1, 19, 26, 37, 30, 18, 63, 37, 6, 59, 1, 40, 24, 56, 33, 46, 22, 35, 7, 24, 53, 39, 5, 26, 45, 55, 18, 62, 7 },
-     { 20, 60, 29, 34, 20, 62, 33, 52, 10, 36, 13, 60, 41, 21, 50, 27, 56, 49, 8, 51, 21, 45, 11, 48, 8, 23, 53, 3, 29, 44, 5, 52, 9, 32, 50, 17, 43, 56, 3, 38, 24, 10, 62, 25, 51, 9, 33, 49, 61, 7, 30, 62, 22, 19, 2, 42, 63, 5, 49, 18, 60, 15, 52, 7, 43, 56, 23, 50, 5, 50, 2, 20, 41, 30, 1, 52, 22, 61, 14, 26, 3, 43, 53, 7, 47, 28, 11, 14, 23, 58, 33, 25, 47, 13, 50, 17, 40, 54, 34, 60, 41, 6, 59, 14, 50, 7, 25, 55, 20, 42, 51, 8, 27, 4, 16, 60, 28, 50, 44, 3, 22, 49, 63, 12, 33, 1, 43, 31 },
-     { 36, 5, 46, 8, 44, 24, 13, 39, 25, 57, 31, 18, 8, 52, 10, 45, 6, 30, 36, 24, 63, 4, 33, 26, 57, 40, 15, 56, 37, 12, 40, 25, 37, 58, 11, 63, 21, 45, 16, 60, 31, 53, 18, 33, 3, 45, 23, 0, 20, 54, 40, 15, 50, 38, 60, 16, 25, 42, 29, 38, 7, 41, 25, 62, 18, 33, 8, 35, 42, 16, 32, 56, 12, 39, 59, 19, 34, 9, 49, 38, 57, 12, 21, 50, 14, 40, 61, 44, 50, 9, 49, 19, 3, 29, 35, 62, 12, 24, 7, 18, 52, 32, 10, 46, 21, 41, 32, 11, 36, 29, 14, 34, 60, 38, 54, 11, 41, 14, 19, 57, 32, 16, 7, 41, 51, 25, 14, 57 },
-     { 53, 18, 26, 50, 15, 58, 4, 63, 17, 43, 7, 40, 61, 35, 15, 41, 23, 60, 16, 38, 14, 42, 19, 50, 0, 31, 10, 46, 27, 63, 18, 60, 0, 20, 29, 39, 8, 26, 37, 5, 42, 0, 44, 39, 57, 17, 58, 41, 28, 37, 4, 32, 9, 44, 12, 31, 54, 10, 59, 14, 27, 53, 12, 36, 0, 47, 13, 63, 21, 58, 10, 24, 50, 27, 4, 26, 44, 53, 31, 0, 18, 42, 29, 33, 57, 4, 32, 26, 0, 38, 16, 61, 41, 53, 20, 0, 42, 44, 49, 27, 10, 56, 39, 0, 57, 15, 53, 49, 3, 61, 22, 47, 17, 5, 49, 26, 2, 63, 39, 10, 47, 27, 37, 23, 4, 59, 38, 10 },
-     { 23, 39, 61, 3, 37, 28, 48, 31, 0, 34, 51, 23, 2, 26, 58, 0, 53, 11, 46, 1, 57, 29, 52, 14, 37, 61, 21, 35, 2, 49, 7, 34, 47, 55, 4, 33, 54, 13, 58, 52, 19, 50, 22, 7, 13, 29, 36, 11, 51, 17, 60, 25, 55, 4, 34, 51, 0, 35, 20, 48, 32, 3, 51, 30, 59, 28, 40, 3, 46, 29, 54, 43, 7, 62, 47, 11, 39, 4, 23, 46, 55, 8, 63, 5, 25, 37, 18, 46, 21, 56, 31, 5, 36, 8, 45, 58, 26, 15, 2, 36, 47, 21, 29, 44, 25, 34, 3, 27, 43, 10, 52, 0, 45, 30, 24, 36, 43, 18, 34, 59, 0, 52, 61, 15, 44, 19, 30, 49 },
-     { 0, 27, 12, 43, 54, 9, 22, 53, 21, 46, 15, 55, 29, 47, 20, 33, 39, 28, 59, 35, 9, 44, 5, 24, 47, 7, 52, 17, 56, 22, 30, 42, 14, 26, 45, 18, 49, 1, 24, 34, 11, 27, 55, 32, 61, 47, 2, 56, 6, 44, 13, 47, 36, 27, 58, 22, 16, 47, 40, 4, 57, 38, 21, 45, 16, 9, 56, 26, 11, 38, 0, 22, 36, 17, 33, 57, 16, 30, 62, 15, 35, 40, 20, 45, 59, 10, 54, 8, 63, 13, 52, 27, 22, 57, 28, 12, 32, 51, 55, 22, 63, 4, 16, 54, 12, 62, 45, 19, 58, 13, 32, 40, 20, 56, 7, 57, 9, 54, 6, 29, 42, 21, 8, 55, 35, 47, 6, 41 },
-     { 56, 33, 58, 32, 19, 35, 42, 6, 59, 11, 38, 5, 49, 12, 62, 7, 52, 17, 5, 25, 54, 20, 61, 31, 54, 27, 41, 11, 44, 5, 59, 12, 36, 51, 10, 61, 28, 41, 48, 9, 43, 63, 5, 40, 20, 8, 49, 26, 34, 21, 58, 1, 18, 45, 7, 39, 61, 26, 8, 50, 23, 10, 63, 5, 55, 37, 19, 49, 52, 15, 59, 47, 13, 54, 1, 25, 42, 58, 10, 48, 3, 27, 50, 1, 17, 48, 34, 41, 16, 40, 2, 45, 10, 39, 17, 61, 5, 38, 19, 9, 41, 31, 60, 38, 5, 23, 36, 8, 30, 55, 24, 63, 12, 48, 14, 51, 31, 20, 45, 25, 12, 50, 32, 2, 28, 11, 62, 14 },
-     { 44, 16, 7, 48, 1, 62, 16, 50, 27, 33, 61, 25, 17, 44, 31, 14, 22, 43, 32, 48, 18, 40, 8, 36, 3, 16, 33, 62, 23, 38, 25, 53, 2, 21, 41, 6, 22, 15, 59, 29, 16, 37, 26, 15, 52, 42, 23, 15, 54, 39, 10, 30, 53, 11, 49, 24, 2, 43, 55, 17, 34, 44, 15, 31, 24, 44, 2, 32, 7, 35, 25, 5, 40, 45, 29, 51, 6, 21, 37, 52, 24, 60, 13, 31, 53, 23, 2, 28, 49, 24, 31, 60, 20, 51, 1, 34, 48, 14, 59, 33, 50, 1, 18, 33, 48, 60, 17, 51, 39, 6, 38, 2, 35, 29, 40, 23, 1, 62, 15, 53, 37, 17, 46, 57, 40, 51, 24, 22 },
-     { 5, 37, 52, 24, 45, 13, 40, 3, 45, 9, 19, 42, 56, 4, 37, 46, 56, 2, 63, 11, 51, 1, 49, 13, 59, 45, 39, 1, 48, 15, 58, 9, 46, 31, 54, 35, 57, 38, 3, 46, 56, 4, 47, 57, 1, 30, 38, 63, 3, 46, 28, 63, 41, 14, 33, 62, 19, 32, 13, 28, 61, 1, 53, 42, 11, 60, 22, 62, 27, 42, 61, 31, 19, 8, 61, 12, 32, 55, 2, 18, 33, 12, 43, 36, 9, 62, 30, 55, 6, 58, 35, 7, 43, 29, 54, 23, 43, 30, 3, 25, 11, 45, 52, 28, 7, 14, 42, 1, 22, 50, 16, 53, 19, 59, 4, 46, 33, 41, 4, 35, 58, 5, 26, 13, 20, 2, 34, 54 },
-     { 30, 63, 21, 10, 26, 55, 29, 59, 23, 39, 53, 1, 36, 24, 59, 27, 10, 34, 23, 38, 30, 60, 22, 42, 28, 19, 9, 57, 30, 19, 43, 33, 13, 63, 3, 19, 11, 50, 31, 20, 14, 34, 10, 35, 17, 59, 7, 31, 19, 25, 50, 5, 20, 57, 29, 6, 52, 41, 4, 46, 20, 37, 26, 17, 49, 6, 39, 18, 53, 14, 3, 49, 57, 23, 34, 48, 14, 41, 28, 38, 56, 6, 58, 25, 39, 19, 43, 15, 37, 11, 47, 18, 53, 4, 37, 9, 62, 21, 53, 40, 57, 24, 13, 40, 56, 26, 47, 31, 59, 25, 45, 27, 10, 43, 21, 61, 13, 27, 48, 9, 23, 43, 31, 62, 38, 59, 9, 47 },
-     { 25, 4, 40, 60, 34, 6, 18, 36, 8, 57, 12, 30, 49, 14, 6, 54, 41, 16, 50, 6, 43, 15, 34, 4, 53, 24, 50, 35, 4, 51, 7, 55, 28, 24, 39, 44, 60, 7, 25, 62, 42, 53, 24, 61, 28, 45, 52, 12, 48, 37, 9, 35, 43, 3, 37, 48, 12, 58, 30, 52, 9, 59, 6, 57, 33, 29, 48, 4, 37, 45, 20, 34, 10, 39, 0, 60, 22, 45, 8, 63, 21, 42, 14, 49, 3, 56, 11, 46, 21, 61, 0, 42, 25, 13, 63, 17, 36, 8, 46, 16, 6, 35, 63, 0, 21, 37, 4, 57, 9, 34, 5, 61, 48, 32, 8, 37, 54, 17, 56, 30, 60, 0, 50, 16, 7, 29, 42, 17 },
-     { 32, 50, 15, 48, 2, 43, 52, 25, 47, 16, 32, 63, 21, 52, 40, 19, 0, 61, 29, 58, 20, 56, 26, 46, 12, 55, 6, 22, 62, 32, 17, 40, 0, 49, 34, 8, 27, 32, 48, 0, 21, 39, 5, 44, 12, 6, 22, 40, 0, 57, 16, 60, 23, 17, 54, 22, 36, 15, 24, 39, 19, 34, 47, 23, 0, 54, 13, 51, 24, 9, 55, 16, 52, 27, 44, 20, 4, 54, 26, 49, 0, 30, 46, 16, 29, 51, 34, 4, 52, 28, 33, 15, 57, 39, 26, 49, 0, 56, 27, 31, 48, 20, 43, 29, 53, 11, 46, 19, 41, 13, 55, 18, 0, 57, 26, 51, 2, 44, 6, 38, 14, 40, 22, 45, 36, 53, 3, 57 },
-     { 44, 12, 37, 28, 22, 57, 11, 38, 0, 51, 9, 41, 4, 29, 11, 47, 33, 45, 12, 26, 3, 36, 9, 63, 31, 16, 38, 44, 14, 47, 25, 61, 20, 58, 15, 47, 17, 57, 13, 36, 9, 51, 18, 29, 50, 36, 54, 20, 61, 27, 32, 13, 53, 44, 9, 27, 0, 63, 45, 2, 56, 10, 14, 43, 41, 28, 58, 11, 35, 60, 30, 41, 6, 63, 11, 51, 37, 32, 15, 10, 35, 53, 5, 61, 22, 7, 26, 59, 23, 9, 44, 48, 21, 3, 51, 32, 24, 41, 12, 61, 2, 55, 9, 15, 35, 58, 28, 15, 62, 30, 37, 23, 42, 29, 11, 17, 35, 24, 63, 20, 52, 28, 8, 55, 11, 23, 47, 19 },
-     { 0, 56, 8, 53, 14, 31, 61, 20, 55, 28, 62, 18, 35, 60, 25, 57, 7, 23, 39, 54, 47, 17, 43, 0, 40, 59, 29, 2, 56, 10, 37, 5, 43, 11, 29, 52, 1, 23, 54, 41, 59, 30, 55, 1, 62, 15, 33, 4, 43, 10, 47, 39, 1, 31, 40, 60, 49, 33, 7, 55, 26, 50, 31, 61, 8, 18, 21, 32, 44, 1, 25, 47, 18, 36, 30, 23, 59, 7, 40, 59, 27, 19, 38, 32, 44, 54, 40, 17, 38, 60, 27, 6, 35, 55, 10, 14, 44, 5, 50, 17, 38, 26, 42, 50, 18, 3, 44, 52, 2, 49, 7, 52, 15, 46, 62, 39, 55, 10, 31, 48, 3, 58, 33, 18, 61, 34, 13, 59 },
-     { 39, 27, 63, 20, 35, 41, 4, 45, 26, 5, 38, 13, 44, 2, 50, 17, 37, 52, 2, 13, 28, 58, 24, 51, 21, 8, 34, 48, 27, 42, 18, 51, 31, 56, 5, 36, 38, 44, 4, 17, 26, 11, 38, 23, 42, 8, 56, 39, 24, 51, 5, 56, 21, 59, 14, 6, 18, 42, 22, 35, 16, 37, 3, 25, 39, 46, 63, 5, 50, 17, 58, 8, 55, 3, 50, 12, 43, 17, 47, 2, 51, 9, 62, 12, 1, 35, 13, 50, 1, 37, 12, 51, 19, 29, 46, 59, 22, 58, 33, 45, 22, 60, 10, 32, 61, 39, 8, 33, 25, 36, 20, 60, 38, 4, 21, 5, 28, 45, 12, 18, 42, 11, 49, 1, 27, 40, 6, 30 },
-     { 24, 16, 42, 1, 50, 10, 48, 17, 33, 43, 24, 48, 21, 55, 31, 42, 10, 21, 63, 35, 49, 6, 33, 13, 41, 53, 10, 20, 60, 6, 53, 26, 12, 41, 22, 60, 14, 28, 63, 33, 49, 3, 45, 16, 48, 26, 14, 46, 18, 30, 35, 26, 8, 50, 29, 51, 25, 57, 12, 47, 53, 9, 62, 20, 54, 2, 36, 15, 40, 28, 33, 13, 38, 24, 46, 1, 29, 56, 33, 20, 44, 24, 41, 26, 57, 20, 63, 8, 30, 55, 5, 41, 62, 8, 34, 2, 37, 10, 19, 6, 37, 1, 53, 23, 5, 27, 58, 22, 43, 12, 50, 26, 9, 34, 54, 32, 49, 1, 59, 37, 22, 46, 25, 36, 51, 15, 54, 46 },
-     { 52, 7, 45, 33, 26, 58, 14, 60, 7, 54, 3, 58, 8, 34, 14, 5, 59, 30, 18, 44, 8, 22, 48, 62, 3, 26, 55, 38, 23, 16, 39, 1, 62, 24, 49, 9, 53, 19, 46, 7, 19, 60, 31, 58, 2, 34, 53, 7, 59, 2, 62, 42, 46, 19, 36, 11, 44, 4, 38, 28, 1, 43, 32, 51, 12, 29, 56, 22, 52, 2, 62, 49, 22, 60, 14, 35, 63, 5, 25, 57, 14, 53, 4, 46, 18, 31, 42, 22, 47, 20, 58, 31, 16, 43, 23, 54, 30, 42, 52, 57, 29, 49, 30, 13, 45, 48, 16, 55, 6, 63, 1, 44, 14, 58, 19, 47, 15, 24, 51, 34, 6, 55, 5, 63, 20, 41, 21, 9 },
-     { 30, 62, 18, 55, 5, 23, 39, 29, 49, 30, 15, 36, 28, 46, 60, 25, 39, 46, 4, 32, 61, 40, 15, 30, 36, 45, 14, 2, 49, 33, 57, 45, 18, 32, 3, 45, 30, 2, 35, 52, 40, 27, 13, 21, 38, 63, 20, 28, 37, 23, 16, 10, 13, 55, 2, 62, 21, 32, 60, 17, 58, 23, 5, 40, 16, 48, 7, 45, 10, 26, 43, 19, 6, 31, 52, 21, 39, 16, 48, 9, 37, 28, 36, 55, 7, 48, 3, 59, 15, 45, 25, 1, 53, 13, 47, 7, 62, 15, 4, 25, 12, 41, 18, 60, 38, 11, 34, 19, 39, 31, 29, 56, 23, 42, 3, 27, 60, 41, 8, 16, 61, 29, 43, 9, 32, 2, 60, 34 },
-     { 3, 38, 13, 37, 52, 44, 2, 19, 12, 42, 63, 19, 40, 1, 20, 50, 12, 55, 15, 56, 27, 1, 54, 11, 57, 18, 32, 63, 44, 4, 29, 13, 37, 61, 35, 16, 42, 57, 12, 22, 6, 55, 43, 10, 50, 5, 44, 11, 48, 52, 34, 58, 28, 41, 38, 30, 7, 52, 11, 49, 30, 14, 45, 27, 59, 34, 21, 38, 32, 58, 11, 36, 56, 42, 9, 41, 3, 54, 31, 42, 0, 60, 16, 11, 39, 24, 52, 33, 6, 36, 10, 40, 32, 60, 26, 20, 39, 28, 47, 34, 63, 8, 54, 3, 24, 56, 0, 51, 13, 47, 16, 40, 7, 35, 52, 11, 36, 4, 57, 30, 39, 13, 18, 50, 58, 28, 12, 48 },
-     { 57, 24, 49, 21, 10, 31, 61, 36, 56, 0, 22, 53, 11, 56, 32, 7, 36, 27, 41, 9, 46, 19, 34, 42, 25, 7, 50, 9, 28, 21, 54, 8, 50, 7, 27, 59, 10, 25, 48, 62, 37, 0, 33, 58, 25, 18, 32, 61, 0, 15, 45, 5, 50, 3, 23, 55, 47, 17, 40, 6, 60, 34, 53, 8, 41, 0, 61, 13, 54, 4, 46, 28, 0, 17, 48, 27, 58, 13, 23, 61, 33, 21, 50, 30, 62, 8, 14, 29, 56, 27, 61, 49, 17, 2, 44, 11, 51, 0, 59, 17, 40, 20, 32, 47, 36, 21, 42, 28, 60, 4, 54, 10, 59, 17, 30, 62, 21, 43, 26, 48, 0, 56, 36, 25, 8, 44, 39, 17 },
-     { 10, 42, 4, 59, 27, 47, 8, 23, 51, 32, 45, 6, 37, 26, 48, 43, 62, 0, 21, 53, 38, 12, 51, 5, 60, 47, 24, 37, 59, 15, 35, 47, 22, 55, 0, 50, 21, 40, 6, 29, 15, 52, 24, 8, 41, 55, 13, 29, 40, 56, 24, 31, 19, 33, 61, 15, 0, 35, 24, 42, 21, 2, 19, 57, 24, 15, 30, 50, 20, 25, 40, 16, 57, 34, 61, 8, 29, 45, 6, 49, 11, 47, 2, 44, 19, 57, 38, 50, 12, 42, 21, 4, 35, 52, 28, 56, 23, 36, 13, 45, 4, 52, 27, 14, 6, 62, 9, 45, 21, 37, 25, 46, 33, 49, 0, 44, 7, 53, 13, 19, 53, 31, 3, 47, 15, 56, 22, 51 },
-     { 35, 28, 53, 32, 1, 16, 54, 40, 9, 17, 25, 58, 14, 59, 3, 22, 16, 51, 31, 5, 23, 58, 28, 17, 35, 20, 0, 42, 11, 52, 3, 31, 41, 17, 43, 13, 32, 54, 18, 60, 32, 45, 17, 49, 2, 36, 51, 22, 7, 36, 9, 63, 48, 12, 46, 26, 43, 28, 63, 13, 48, 37, 51, 33, 5, 47, 55, 9, 42, 63, 7, 51, 24, 12, 37, 19, 55, 34, 18, 38, 15, 28, 54, 34, 5, 43, 22, 0, 48, 14, 54, 24, 58, 9, 38, 5, 32, 55, 21, 30, 49, 9, 59, 43, 30, 51, 35, 26, 7, 53, 2, 22, 14, 27, 57, 18, 38, 24, 33, 45, 10, 41, 20, 60, 37, 5, 32, 0 },
-     { 63, 19, 15, 40, 62, 35, 14, 28, 46, 61, 4, 49, 35, 10, 29, 54, 33, 8, 45, 62, 37, 1, 43, 55, 10, 52, 61, 30, 19, 40, 25, 62, 11, 38, 27, 58, 36, 3, 46, 8, 39, 4, 62, 28, 47, 20, 4, 54, 47, 27, 43, 1, 21, 38, 8, 58, 10, 54, 4, 56, 9, 26, 12, 39, 60, 27, 18, 37, 1, 31, 35, 5, 45, 50, 2, 43, 26, 1, 59, 23, 56, 40, 7, 26, 58, 17, 32, 63, 25, 39, 7, 31, 45, 19, 63, 15, 48, 8, 37, 61, 16, 34, 1, 56, 18, 3, 15, 58, 49, 32, 63, 41, 55, 5, 40, 22, 50, 6, 59, 2, 63, 23, 52, 11, 26, 61, 44, 23 },
-     { 11, 56, 46, 6, 22, 43, 58, 3, 34, 21, 38, 30, 18, 44, 52, 13, 41, 57, 17, 28, 14, 49, 25, 7, 33, 39, 26, 6, 56, 48, 1, 20, 56, 5, 46, 9, 19, 51, 30, 25, 56, 21, 35, 14, 57, 42, 16, 33, 10, 57, 17, 59, 41, 25, 53, 37, 20, 40, 30, 18, 31, 62, 44, 22, 3, 44, 11, 48, 23, 53, 18, 60, 29, 22, 62, 15, 53, 47, 10, 41, 3, 19, 52, 36, 13, 46, 10, 35, 3, 61, 41, 16, 1, 50, 26, 42, 18, 46, 2, 25, 54, 20, 39, 23, 47, 31, 41, 12, 38, 17, 8, 19, 31, 48, 12, 61, 9, 54, 29, 35, 15, 38, 6, 43, 34, 14, 7, 47 },
-     { 39, 2, 33, 26, 53, 8, 18, 50, 41, 12, 53, 1, 63, 24, 19, 39, 2, 24, 47, 10, 60, 38, 19, 63, 48, 4, 15, 45, 32, 14, 60, 36, 29, 53, 23, 63, 34, 12, 61, 1, 43, 11, 53, 30, 1, 26, 60, 45, 23, 39, 3, 29, 12, 50, 4, 16, 51, 3, 45, 36, 50, 1, 16, 54, 35, 14, 57, 30, 58, 9, 46, 14, 41, 10, 32, 38, 4, 30, 21, 51, 32, 63, 25, 1, 60, 27, 53, 18, 51, 22, 28, 55, 34, 12, 40, 3, 60, 29, 57, 41, 6, 44, 11, 53, 8, 61, 24, 57, 1, 28, 44, 59, 36, 3, 34, 25, 41, 31, 16, 44, 22, 47, 28, 58, 1, 49, 54, 29 },
-     { 58, 25, 50, 13, 38, 30, 60, 24, 6, 57, 27, 42, 9, 45, 6, 61, 30, 50, 4, 34, 29, 3, 46, 13, 22, 42, 58, 28, 9, 39, 23, 44, 7, 15, 44, 2, 40, 15, 47, 41, 23, 37, 7, 59, 38, 11, 34, 6, 62, 14, 52, 35, 55, 19, 32, 61, 33, 24, 57, 6, 22, 59, 29, 7, 49, 25, 40, 3, 17, 39, 27, 52, 0, 55, 16, 57, 24, 61, 36, 6, 29, 12, 48, 39, 20, 44, 6, 40, 33, 5, 48, 10, 57, 36, 22, 51, 33, 9, 24, 12, 62, 29, 50, 35, 14, 43, 5, 33, 47, 52, 13, 23, 10, 51, 56, 16, 46, 1, 49, 4, 61, 9, 52, 18, 31, 21, 36, 17 },
-     { 19, 42, 9, 48, 2, 44, 11, 37, 48, 20, 33, 16, 55, 35, 49, 15, 37, 20, 59, 16, 53, 22, 56, 31, 50, 11, 34, 54, 16, 51, 4, 49, 33, 53, 21, 28, 56, 24, 31, 9, 52, 16, 48, 24, 44, 13, 51, 20, 31, 49, 18, 6, 34, 2, 44, 14, 47, 8, 15, 43, 13, 41, 33, 52, 20, 61, 7, 51, 34, 62, 4, 20, 36, 33, 43, 8, 46, 13, 53, 17, 45, 42, 9, 31, 52, 11, 30, 56, 13, 59, 17, 44, 27, 6, 62, 11, 43, 17, 49, 38, 26, 2, 16, 27, 58, 21, 54, 18, 26, 5, 35, 61, 43, 27, 7, 39, 14, 58, 37, 55, 20, 33, 13, 40, 62, 10, 55, 5 },
-     { 51, 14, 61, 29, 59, 20, 55, 31, 0, 49, 11, 60, 3, 26, 22, 56, 0, 40, 12, 43, 41, 8, 36, 0, 17, 57, 24, 2, 46, 26, 61, 18, 0, 38, 12, 59, 6, 49, 3, 57, 19, 63, 5, 33, 18, 54, 28, 56, 0, 43, 26, 46, 63, 27, 56, 22, 27, 54, 38, 28, 63, 24, 10, 45, 0, 31, 42, 21, 12, 25, 44, 49, 59, 6, 26, 50, 3, 34, 27, 59, 0, 35, 62, 16, 4, 58, 47, 0, 43, 24, 37, 2, 54, 20, 46, 31, 0, 56, 34, 5, 55, 45, 60, 37, 0, 40, 10, 38, 63, 46, 15, 20, 0, 53, 21, 62, 30, 11, 24, 27, 40, 0, 57, 26, 3, 45, 27, 35 }
-};
-
-EFL_ALWAYS_INLINE void
-_soft16_convert_from_rgba_pt(const DATA32 *src, DATA16 *dst, DATA8 *alpha,
-                            const int x, const int y)
-{
-   DATA8 orig_r, orig_g, orig_b, orig_a;
-
-   orig_r = R_VAL(src);
-   orig_g = G_VAL(src);
-   orig_b = B_VAL(src);
-   orig_a = A_VAL(src);
-
-   if (orig_a == 255)
-     {
-       DATA8 dith5, dith6, dith, r, g, b;
-
-       dith = dither_table[x & S16_DM_MSK][y & S16_DM_MSK];
-       dith5 = dith >> S16_DM_SHF(5);
-       dith6 = dith >> S16_DM_SHF(6);
-
-       r = orig_r >> 3;
-       g = orig_g >> 2;
-       b = orig_b >> 3;
-
-       if (((orig_r - (r << 3)) >= dith5) && (r < 0x1f)) r++;
-       if (((orig_g - (g << 2)) >= dith6) && (g < 0x3f)) g++;
-       if (((orig_b - (b << 3)) >= dith5) && (b < 0x1f)) b++;
-
-       *dst = (r << 11) | (g << 5) | b;
-       *alpha = 31;
-     }
-   else if (orig_a == 0)
-     {
-       *dst = 0;
-       *alpha = 0;
-     }
-   else
-     {
-       DATA8 r, g, b, a;
-       r = orig_r >> 3;
-       g = orig_g >> 2;
-       b = orig_b >> 3;
-       a = (orig_a >> 3) + 1;
-
-       *dst = (r << 11) | (g << 5) | b;
-       *alpha = a;
-     }
-}
-
-static inline void
-_soft16_convert_from_rgba_scanline(const DATA32 *src, DATA16 *dst,
-                                  DATA8 *alpha, const int y, const int w)
-{
-   int x, m;
-
-   m = (w & ~7);
-   x = 0;
-   pld(src, 0);
-
-   while (x < m)
-     {
-       pld(src, 32);
-       UNROLL8({
-          _soft16_convert_from_rgba_pt(src, dst, alpha, x, y);
-          src++;
-          dst++;
-          alpha++;
-          x++;
-       });
-     }
-
-   for (; x < w; x++, src++, dst++, alpha++)
-     _soft16_convert_from_rgba_pt(src, dst, alpha, x, y);
-}
-
-void
-evas_common_soft16_image_convert_from_rgba(Soft16_Image *im, const DATA32 *src)
-{
-   const DATA32 *sp;
-   DATA16 *dp;
-   DATA8 *ap;
-   unsigned int y;
-
-   sp = src;
-   dp = im->pixels;
-   ap = im->alpha;
-
-   for (y = 0; y < im->cache_entry.h; y++, sp += im->cache_entry.w, dp += im->stride, ap += im->stride)
-     _soft16_convert_from_rgba_scanline(sp, dp, ap, y, im->cache_entry.w);
-}
-
-EFL_ALWAYS_INLINE void
-_soft16_convert_from_rgb_pt(const DATA32 *src, DATA16 *dst,
-                           const int x, const int y)
-{
-   DATA8 orig_r, orig_g, orig_b, r, g, b, dith5, dith6, dith;
-
-   orig_r = R_VAL(src);
-   orig_g = G_VAL(src);
-   orig_b = B_VAL(src);
-
-   r = orig_r >> 3;
-   g = orig_g >> 2;
-   b = orig_b >> 3;
-
-   dith = dither_table[x & S16_DM_MSK][y & S16_DM_MSK];
-   dith5 = dith >> S16_DM_SHF(5);
-   dith6 = dith >> S16_DM_SHF(6);
-
-   if (((orig_r - (r << 3)) >= dith5) && (r < 0x1f)) r++;
-   if (((orig_g - (g << 2)) >= dith6) && (g < 0x3f)) g++;
-   if (((orig_b - (b << 3)) >= dith5) && (b < 0x1f)) b++;
-
-   *dst = (r << 11) | (g << 5) | b;
-}
-
-static inline void
-_soft16_convert_from_rgb_scanline(const DATA32 *src, DATA16 *dst, const int y,
-                                 const int w)
-{
-   int x, m;
-
-   m = (w & ~7);
-   x = 0;
-   pld(src, 0);
-
-   while (x < m)
-     {
-       pld(src, 32);
-       UNROLL8({
-          _soft16_convert_from_rgb_pt(src, dst, x, y);
-          src++;
-          dst++;
-          x++;
-       });
-     }
-
-   for (; x < w; x++, src++, dst++)
-     _soft16_convert_from_rgb_pt(src, dst, x, y);
-}
-
-void
-evas_common_soft16_image_convert_from_rgb(Soft16_Image *im, const DATA32 *src)
-{
-   const DATA32 *sp;
-   DATA16 *dp;
-   unsigned int y;
-
-   sp = src;
-   dp = im->pixels;
-
-   for (y = 0; y < im->cache_entry.h; y++, sp += im->cache_entry.w, dp += im->stride)
-     _soft16_convert_from_rgb_scanline(sp, dp, y, im->cache_entry.w);
-}
diff --git a/src/lib/engines/common_16/evas_soft16_font.c b/src/lib/engines/common_16/evas_soft16_font.c
deleted file mode 100644 (file)
index fbad4d2..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-#include "evas_common_soft16.h"
-
-EFL_ALWAYS_INLINE void
-_glyph_pt_mask_solid_solid(DATA16 *dst,
-                          const DATA16 rgb565,
-                          const DATA32 rgb565_unpack,
-                          const DATA8 *mask)
-{
-   DATA8 alpha = *mask >> 3;
-
-   if (alpha == 31) *dst = rgb565;
-   else if (alpha > 0)
-     {
-       DATA32 d;
-
-       d = RGB_565_UNPACK(*dst);
-       d = RGB_565_UNPACKED_BLEND_UNMUL(rgb565_unpack, d, alpha);
-       *dst = RGB_565_PACK(d);
-     }
-}
-
-static void
-_glyph_scanline_mask_solid_solid(DATA16 *dst,
-                                int size,
-                                const DATA16 rgb565,
-                                const DATA32 rgb565_unpack,
-                                const DATA8 *mask)
-{
-   DATA16 *start, *end;
-
-   start = dst;
-   pld(start, 0);
-   pld(mask, 0);
-   end = start + (size & ~3);
-
-   while (start < end)
-     {
-       pld(start, 16);
-       pld(mask, 4);
-       UNROLL4({
-          _glyph_pt_mask_solid_solid(start, rgb565, rgb565_unpack, mask);
-          start++;
-          mask++;
-       });
-     }
-
-   end = start + (size & 3);
-   for (; start < end; start++, mask++)
-      _glyph_pt_mask_solid_solid(start, rgb565, rgb565_unpack, mask);
-}
-
-EFL_ALWAYS_INLINE void
-_glyph_pt_mask_transp_solid(DATA16 *dst,
-                           DATA32 rgb565_unpack,
-                           DATA8 alpha,
-                           const DATA8 *mask)
-{
-   DATA32 a, b;
-   int rel_alpha;
-
-   rel_alpha = *mask >> 3;
-   alpha = (alpha * rel_alpha) >> 5;
-   if (alpha == 0)
-     return;
-
-   alpha++;
-
-   a = ((rgb565_unpack * rel_alpha) >> 5) & RGB_565_UNPACKED_MASK;
-   b = RGB_565_UNPACK(*dst);
-   b = RGB_565_UNPACKED_BLEND(a, b, alpha);
-   *dst = RGB_565_PACK(b);
-}
-
-static void
-_glyph_scanline_mask_transp_solid(DATA16 *dst,
-                                 int size,
-                                 const DATA32 rgb565_unpack,
-                                 const DATA8 rel_alpha,
-                                 const DATA8 *mask)
-{
-   DATA16 *start, *end;
-
-   start = dst;
-   pld(start, 0);
-   pld(mask, 0);
-   end = start + (size & ~3);
-
-   while (start < end)
-     {
-       pld(start, 16);
-       pld(mask, 4);
-       UNROLL4({
-          _glyph_pt_mask_transp_solid(start, rgb565_unpack, rel_alpha, mask);
-          start++;
-          mask++;
-       });
-     }
-
-   end = start + (size & 3);
-   for (; start < end; start++, mask++)
-      _glyph_pt_mask_transp_solid(start, rgb565_unpack, rel_alpha, mask);
-}
-
-static inline void
-_calc_ext(const Soft16_Image *dst, const RGBA_Draw_Context *dc,
-         Eina_Rectangle *ext)
-{
-   EINA_RECTANGLE_SET(ext, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
-
-   if (dc->clip.use)
-     {
-       int v;
-
-       EINA_RECTANGLE_SET(ext, dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
-       if (ext->x < 0)
-         {
-            ext->w += ext->x;
-            ext->x = 0;
-         }
-       if (ext->y < 0)
-         {
-            ext->h += ext->y;
-            ext->y = 0;
-         }
-
-       v = dst->cache_entry.w - ext->x;
-       if (ext->w > v) ext->w = v;
-
-       v = dst->cache_entry.h - ext->y;
-       if (ext->h > v) ext->h = v;
-     }
-}
-
-static inline void
-_glyph_scanline(Soft16_Image *dst, const DATA8 *p_mask,
-               const Eina_Rectangle ext, int dx, int dy, int max_x, int max_y,
-               int w, DATA8 alpha, const DATA16 rgb565,
-               const DATA32 rgb565_unpack)
-{
-   int size, in_x, in_w;
-   DATA16 *p_pixels;
-
-   if ((dx >= max_x) || (dy < ext.y) || (dy >= max_y)) return;
-
-   in_x = 0;
-   in_w = 0;
-
-   if (dx + w > max_x) in_w += (dx + w) - max_x;
-
-   if (dx < ext.x)
-     {
-       in_w += ext.x - dx;
-       in_x = ext.x - dx;
-       dx = ext.x;
-     }
-
-   size = w - in_w;
-   p_pixels = dst->pixels + (dy * dst->stride) + dx;
-   p_mask += in_x;
-
-   if (size > 1)
-     {
-       if (alpha == 31)
-          _glyph_scanline_mask_solid_solid
-              (p_pixels, size, rgb565, rgb565_unpack, p_mask);
-       else if (alpha != 0)
-          _glyph_scanline_mask_transp_solid
-              (p_pixels, size, rgb565_unpack, alpha, p_mask);
-     }
-   else if (size == 1)
-     {
-       if (alpha == 31)
-          _glyph_pt_mask_solid_solid(p_pixels, rgb565, rgb565_unpack, p_mask);
-       else if (alpha != 0)
-          _glyph_pt_mask_transp_solid(p_pixels, rgb565_unpack, alpha, p_mask);
-     }
-}
-
-static void
-_soft16_font_glyph_draw_grayscale(Soft16_Image *dst,
-                                 RGBA_Draw_Context *dc __UNUSED__, RGBA_Font_Glyph *fg __UNUSED__,
-                                 int x, int y, DATA8 alpha, DATA16 rgb565,
-                                 const Eina_Rectangle ext, int bw, int bh,
-                                 int bpitch, const DATA8 *bitmap)
-{
-   const DATA32 rgb565_unpack = RGB_565_UNPACK(rgb565);
-   int i, max_x, max_y;
-
-   max_x = ext.x + ext.w;
-   max_y = ext.y + ext.h;
-
-   for (i = 0; i < bh; i++, bitmap += bpitch)
-      _glyph_scanline(dst, bitmap, ext, x, y + i, max_x, max_y, bw,
-                     alpha, rgb565, rgb565_unpack);
-}
-
-static inline void
-_glyph_create_mask_line(DATA8 *mask, const DATA8 *bitmap, int w)
-{
-   const DATA8 bitrepl[2] = {0x0, 0xff};
-   int i;
-
-   for (i = 0; i < w; i += 8, bitmap++)
-     {
-       int j, size;
-       DATA32 bits;
-
-       if (i + 8 < w) size = 8;
-       else           size = w - i;
-
-       bits = *bitmap;
-
-       for (j = size - 1; j >= 0; j--, mask++)
-         *mask = bitrepl[(bits >> j) & 0x1];
-     }
-}
-
-static void
-_soft16_font_glyph_draw_mono(Soft16_Image *dst,
-                            RGBA_Draw_Context *dc __UNUSED__, RGBA_Font_Glyph *fg __UNUSED__,
-                            int x, int y, DATA8 alpha, DATA16 rgb565,
-                            const Eina_Rectangle ext, int bw, int bh,
-                            int bpitch, const DATA8 *bitmap)
-{
-   const DATA32 rgb565_unpack = RGB_565_UNPACK(rgb565);
-   DATA8 *mask;
-   int i, max_x, max_y;
-
-   max_x = ext.x + ext.w;
-   max_y = ext.y + ext.h;
-
-   mask = alloca(bpitch);
-   for (i = 0; i < bh; i++, bitmap += bpitch)
-     {
-       _glyph_create_mask_line(mask, bitmap, bw);
-       _glyph_scanline(dst, mask, ext, x, y + i, max_x, max_y, bw,
-                       alpha, rgb565, rgb565_unpack);
-     }
-}
-
-void
-evas_common_soft16_font_glyph_draw(void *data, void *dest __UNUSED__, void *context,
-                      RGBA_Font_Glyph *fg, int x, int y)
-{
-   Soft16_Image *dst;
-   RGBA_Draw_Context *dc;
-   const DATA8 *bitmap;
-   DATA8 alpha, r, g, b;
-   DATA16 rgb565;
-   Eina_Rectangle ext;
-   int bpitch, bw, bh;
-
-   dst = data;
-   dc = context;
-
-   alpha = A_VAL(&dc->col.col) >> 3;
-   if (alpha == 0) return; /* precision is 5 bits, 3 bits lost */
-
-   r = R_VAL(&dc->col.col) >> 3;
-   g = G_VAL(&dc->col.col) >> 2;
-   b = B_VAL(&dc->col.col) >> 3;
-
-   if (r > alpha) r = alpha;
-   if (g > (alpha << 1)) g = (alpha << 1);
-   if (b > alpha) b = alpha;
-
-   rgb565 = (r << 11) | (g << 5) | b;
-
-   bitmap = fg->glyph_out->bitmap.buffer;
-   bh = fg->glyph_out->bitmap.rows;
-   bw = fg->glyph_out->bitmap.width;
-   bpitch = fg->glyph_out->bitmap.pitch;
-   if (bpitch < bw) bpitch = bw;
-
-   _calc_ext(dst, dc, &ext);
-
-   if ((fg->glyph_out->bitmap.num_grays == 256) &&
-       (fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays))
-      _soft16_font_glyph_draw_grayscale(dst, dc, fg, x, y, alpha, rgb565,
-                                       ext, bw, bh, bpitch, bitmap);
-   else
-      _soft16_font_glyph_draw_mono(dst, dc, fg, x, y, alpha, rgb565,
-                                  ext, bw, bh, bpitch, bitmap);
-}
-
-void *
-evas_common_soft16_font_glyph_new(void *data __UNUSED__, RGBA_Font_Glyph *fg __UNUSED__)
-{
-   return (void *)1; /* core requires != NULL to work */
-}
-
-void
-evas_common_soft16_font_glyph_free(void *ext_dat __UNUSED__)
-{
-}
diff --git a/src/lib/engines/common_16/evas_soft16_image_scaled_sampled.c b/src/lib/engines/common_16/evas_soft16_image_scaled_sampled.c
deleted file mode 100644 (file)
index 9c9f03c..0000000
+++ /dev/null
@@ -1,471 +0,0 @@
-#include "evas_common_soft16.h"
-#include "evas_soft16_point_blend.c"
-
-static void
-_soft16_image_draw_scaled_solid_solid(Soft16_Image *src,
-                                     Soft16_Image *dst,
-                                     RGBA_Draw_Context *dc __UNUSED__,
-                                     int dst_offset, int w, int h,
-                                     int *offset_x, int *offset_y)
-{
-   DATA16 *dst_itr;
-   int y, w_align;
-
-   w_align = w & ~7;
-
-   dst_itr = dst->pixels + dst_offset;
-   for (y = 0; y < h; y++, dst_itr += dst->stride)
-     {
-       DATA16 *d, *s;
-       int x;
-
-       s = src->pixels + offset_y[y];
-       pld(s, 0);
-       pld(offset_x, 0);
-
-       d = dst_itr;
-       x = 0;
-       while (x < w_align)
-         {
-            pld(s, 32);
-            pld(offset_x + x, 32);
-
-            UNROLL8({
-               _soft16_pt_blend_solid_solid(d, s[offset_x[x]]);
-               x++;
-               d++;
-            });
-         }
-
-       for (; x < w; x++, d++)
-         _soft16_pt_blend_solid_solid(d, s[offset_x[x]]);
-     }
-}
-static void
-_soft16_image_draw_scaled_transp_solid(Soft16_Image *src,
-                                      Soft16_Image *dst,
-                                      RGBA_Draw_Context *dc __UNUSED__,
-                                      int dst_offset, int w, int h,
-                                      int *offset_x, int *offset_y)
-{
-   DATA16 *dst_itr;
-   int y, w_align;
-
-   w_align = w & ~7;
-
-   dst_itr = dst->pixels + dst_offset;
-   for (y = 0; y < h; y++, dst_itr += dst->stride)
-     {
-       DATA16 *d, *s;
-       DATA8 *a;
-       int x;
-
-       s = src->pixels + offset_y[y];
-       a = src->alpha + offset_y[y];
-       pld(s, 0);
-       pld(a, 0);
-       pld(offset_x, 0);
-
-       d = dst_itr;
-       x = 0;
-       while (x < w_align)
-         {
-            pld(s, 32);
-            pld(a, 8);
-            pld(offset_x + x, 32);
-
-            UNROLL8({
-               int off_x = offset_x[x];
-               _soft16_pt_blend_transp_solid(d, s[off_x], a[off_x]);
-               x++;
-               d++;
-            });
-         }
-
-       for (; x < w; x++, d++)
-         _soft16_pt_blend_transp_solid(d, s[offset_x[x]], a[offset_x[x]]);
-     }
-}
-
-static inline void
-_soft16_image_draw_scaled_no_mul(Soft16_Image *src, Soft16_Image *dst,
-                                RGBA_Draw_Context *dc,
-                                int dst_offset, int w, int h,
-                                int *offset_x, int *offset_y)
-{
-   if ((src->cache_entry.flags.alpha && src->alpha) && 
-       (!dst->cache_entry.flags.alpha))
-      _soft16_image_draw_scaled_transp_solid
-       (src, dst, dc, dst_offset, w, h, offset_x, offset_y);
-   else if (!dst->cache_entry.flags.alpha)
-      _soft16_image_draw_scaled_solid_solid
-       (src, dst, dc, dst_offset, w, h, offset_x, offset_y);
-   else
-      ERR("Unsupported draw of scaled images src->cache_entry.flags.alpha=%d, "
-              "dst->cache_entry.flags.alpha=%d, WITHOUT COLOR MUL",
-              src->cache_entry.flags.alpha, dst->cache_entry.flags.alpha);
-}
-
-static void
-_soft16_image_draw_scaled_solid_solid_mul_alpha(Soft16_Image *src,
-                                               Soft16_Image *dst,
-                                               RGBA_Draw_Context *dc __UNUSED__,
-                                               int dst_offset, int w, int h,
-                                               int *offset_x, int *offset_y,
-                                               DATA8 alpha)
-{
-   DATA16 *dst_itr;
-   int y, w_align;
-
-   w_align = w & ~7;
-
-   dst_itr = dst->pixels + dst_offset;
-   for (y = 0; y < h; y++, dst_itr += dst->stride)
-     {
-       DATA16 *d, *s;
-       int x;
-
-       s = src->pixels + offset_y[y];
-       pld(s, 0);
-       pld(offset_x, 0);
-
-       d = dst_itr;
-       x = 0;
-       while (x < w_align)
-         {
-            pld(s, 32);
-            pld(offset_x + x, 32);
-
-            UNROLL8({
-               _soft16_pt_blend_solid_solid_mul_alpha
-                 (d, s[offset_x[x]], alpha);
-               x++;
-               d++;
-            });
-         }
-
-       for (; x < w; x++, d++)
-         _soft16_pt_blend_solid_solid_mul_alpha
-           (d, s[offset_x[x]], alpha);
-     }
-}
-
-static void
-_soft16_image_draw_scaled_transp_solid_mul_alpha(Soft16_Image *src,
-                                                Soft16_Image *dst,
-                                                RGBA_Draw_Context *dc __UNUSED__,
-                                                int dst_offset, int w, int h,
-                                                int *offset_x, int *offset_y,
-                                                DATA8 alpha)
-{
-   DATA16 *dst_itr;
-   int y, w_align;
-
-   w_align = w & ~7;
-
-   dst_itr = dst->pixels + dst_offset;
-   for (y = 0; y < h; y++, dst_itr += dst->stride)
-     {
-       DATA16 *d, *s;
-       DATA8 *a;
-       int x;
-
-       s = src->pixels + offset_y[y];
-       a = src->alpha + offset_y[y];
-       pld(s, 0);
-       pld(a, 0);
-       pld(offset_x, 0);
-
-       d = dst_itr;
-       x = 0;
-       while (x < w_align)
-         {
-            pld(s, 32);
-            pld(a, 8);
-            pld(offset_x + x, 32);
-
-            UNROLL8({
-               int off_x = offset_x[x];
-               _soft16_pt_blend_transp_solid_mul_alpha
-                 (d, s[off_x], a[off_x], alpha);
-               x++;
-               d++;
-            });
-         }
-
-       for (; x < w; x++, d++)
-         _soft16_pt_blend_transp_solid_mul_alpha
-           (d, s[offset_x[x]], a[offset_x[x]], alpha);
-     }
-}
-
-static inline void
-_soft16_image_draw_scaled_mul_alpha(Soft16_Image *src, Soft16_Image *dst,
-                                   RGBA_Draw_Context *dc,
-                                   int dst_offset, int w, int h,
-                                   int *offset_x, int *offset_y, DATA8 a)
-{
-   if ((src->cache_entry.flags.alpha && src->alpha) && 
-       (!dst->cache_entry.flags.alpha))
-      _soft16_image_draw_scaled_transp_solid_mul_alpha
-         (src, dst, dc, dst_offset, w, h, offset_x, offset_y, a);
-   else if (!dst->cache_entry.flags.alpha)
-      _soft16_image_draw_scaled_solid_solid_mul_alpha
-         (src, dst, dc, dst_offset, w, h, offset_x, offset_y, a);
-   else
-     ERR("Unsupported draw of scaled images src->cache_entry.flags.alpha=%d, "
-          "dst->cache_entry.flags.alpha=%d, WITH ALPHA MUL %d",
-          src->cache_entry.flags.alpha, dst->cache_entry.flags.alpha, A_VAL(&dc->mul.col));
-}
-
-static void
-_soft16_image_draw_scaled_solid_solid_mul_color(Soft16_Image *src,
-                                               Soft16_Image *dst,
-                                               RGBA_Draw_Context *dc __UNUSED__,
-                                               int dst_offset, int w, int h,
-                                               int *offset_x, int *offset_y,
-                                               DATA8 r, DATA8 g, DATA8 b,
-                                               DATA8 alpha)
-{
-   DATA16 *dst_itr;
-   int y, w_align;
-
-   w_align = w & ~7;
-
-   dst_itr = dst->pixels + dst_offset;
-
-   if (alpha == 31)
-     for (y = 0; y < h; y++, dst_itr += dst->stride)
-       {
-         DATA16 *d, *s;
-         int x;
-
-         s = src->pixels + offset_y[y];
-         pld(s, 0);
-         pld(offset_x, 0);
-
-         d = dst_itr;
-         x = 0;
-         while (x < w_align)
-           {
-              pld(s, 32);
-              pld(offset_x + x, 32);
-
-              UNROLL8({
-                 _soft16_pt_blend_solid_solid_mul_color_solid
-                   (d, s[offset_x[x]], r, g, b);
-                 x++;
-                 d++;
-              });
-           }
-
-         for (; x < w; x++, d++)
-           _soft16_pt_blend_solid_solid_mul_color_solid
-             (d, s[offset_x[x]], r, g, b);
-       }
-   else
-     for (y = 0; y < h; y++, dst_itr += dst->stride)
-       {
-         DATA16 *d, *s;
-         int x;
-
-         s = src->pixels + offset_y[y];
-         pld(s, 0);
-         pld(offset_x, 0);
-
-         d = dst_itr;
-         x = 0;
-         while (x < w_align)
-           {
-              pld(s, 32);
-              pld(offset_x + x, 32);
-
-              UNROLL8({
-                 _soft16_pt_blend_solid_solid_mul_color_transp
-                   (d, s[offset_x[x]], alpha, r, g, b);
-                 x++;
-                 d++;
-              });
-           }
-
-         for (; x < w; x++, d++)
-           _soft16_pt_blend_solid_solid_mul_color_transp
-             (d, s[offset_x[x]], alpha, r, g, b);
-       }
-}
-
-static void
-_soft16_image_draw_scaled_transp_solid_mul_color(Soft16_Image *src,
-                                                Soft16_Image *dst,
-                                                RGBA_Draw_Context *dc __UNUSED__,
-                                                int dst_offset, int w, int h,
-                                                int *offset_x, int *offset_y,
-                                                DATA8 r, DATA8 g, DATA8 b,
-                                                DATA8 alpha)
-{
-   DATA16 *dst_itr;
-   int y, w_align;
-
-   w_align = w & ~7;
-
-   dst_itr = dst->pixels + dst_offset;
-
-   if (alpha == 31)
-     for (y = 0; y < h; y++, dst_itr += dst->stride)
-       {
-         DATA16 *d, *s;
-         DATA8 *a;
-         int x;
-
-         s = src->pixels + offset_y[y];
-         a = src->alpha + offset_y[y];
-         pld(s, 0);
-         pld(a, 0);
-         pld(offset_x, 0);
-
-         d = dst_itr;
-         x = 0;
-         while (x < w_align)
-           {
-              pld(s, 32);
-              pld(a, 8);
-              pld(offset_x + x, 32);
-
-              UNROLL8({
-                 int off_x = offset_x[x];
-                 _soft16_pt_blend_transp_solid_mul_color_solid
-                   (d, s[off_x], a[off_x], r, g, b);
-                 x++;
-                 d++;
-              });
-           }
-
-         for (; x < w; x++, d++)
-           _soft16_pt_blend_transp_solid_mul_color_solid
-             (d, s[offset_x[x]], a[offset_x[x]], r, g, b);
-       }
-   else
-     for (y = 0; y < h; y++, dst_itr += dst->stride)
-       {
-         DATA16 *d, *s;
-         DATA8 *a;
-         int x;
-
-         s = src->pixels + offset_y[y];
-         a = src->alpha + offset_y[y];
-         pld(s, 0);
-         pld(a, 0);
-         pld(offset_x, 0);
-
-         d = dst_itr;
-         x = 0;
-         while (x < w_align)
-           {
-              pld(s, 32);
-              pld(a, 8);
-              pld(offset_x + x, 32);
-
-              UNROLL8({
-                 int off_x = offset_x[x];
-                 _soft16_pt_blend_transp_solid_mul_color_transp
-                   (d, s[off_x], a[off_x], alpha, r, g, b);
-                 x++;
-                 d++;
-              });
-           }
-
-         for (; x < w; x++, d++)
-           _soft16_pt_blend_transp_solid_mul_color_transp
-             (d, s[offset_x[x]], a[offset_x[x]], alpha, r, g, b);
-       }
-}
-
-static inline void
-_soft16_image_draw_scaled_mul_color(Soft16_Image *src, Soft16_Image *dst,
-                                   RGBA_Draw_Context *dc,
-                                   int dst_offset, int w, int h,
-                                   int *offset_x, int *offset_y,
-                                   DATA8 r, DATA8 g, DATA8 b, DATA8 a)
-{
-   if ((src->cache_entry.flags.alpha && src->alpha) && 
-       (!dst->cache_entry.flags.alpha))
-      _soft16_image_draw_scaled_transp_solid_mul_color
-         (src, dst, dc, dst_offset, w, h, offset_x, offset_y, r, g, b, a);
-   else if (!dst->cache_entry.flags.alpha)
-      _soft16_image_draw_scaled_solid_solid_mul_color
-         (src, dst, dc, dst_offset, w, h, offset_x, offset_y, r, g, b, a);
-   else
-      ERR("Unsupported draw of scaled images src->cache_entry.flags.alpha=%d, "
-              "dst->cache_entry.flags.alpha=%d, WITH COLOR MUL 0x%08x",
-              src->cache_entry.flags.alpha, dst->cache_entry.flags.alpha, dc->mul.col);
-}
-
-static inline void
-_soft16_image_draw_scaled_mul(Soft16_Image *src, Soft16_Image *dst,
-                             RGBA_Draw_Context *dc,
-                             int dst_offset, int w, int h,
-                             int *offset_x, int *offset_y, DATA8 r, DATA8 g,
-                             DATA8 b, DATA8 a)
-{
-   if ((a == r) && (a == (g >> 1)) && (a == b))
-      _soft16_image_draw_scaled_mul_alpha
-       (src, dst, dc, dst_offset, w, h, offset_x, offset_y, a);
-   else
-      _soft16_image_draw_scaled_mul_color
-       (src, dst, dc, dst_offset, w, h, offset_x, offset_y, r, g, b, a);
-}
-
-void
-evas_common_soft16_image_draw_scaled_sampled(Soft16_Image *src, Soft16_Image *dst,
-                                RGBA_Draw_Context *dc,
-                                const Eina_Rectangle sr,
-                                const Eina_Rectangle dr,
-                                const Eina_Rectangle cr)
-{
-   int x, y, dst_offset, *offset_x, *offset_y;
-   DATA16 mul_rgb565;
-   DATA8 r, g, b, a;
-
-   if (!dc->mul.use)
-     {
-       r = b = a = 31;
-       g = 63;
-       mul_rgb565 = 0xffff;
-     }
-   else
-     {
-       a = A_VAL(&dc->mul.col) >> 3;
-       if (a == 0)
-         return;
-
-       r = R_VAL(&dc->mul.col) >> 3;
-       g = G_VAL(&dc->mul.col) >> 2;
-       b = B_VAL(&dc->mul.col) >> 3;
-
-       if (r > a) r = a;
-       if (g > (a << 1)) g = (a << 1);
-       if (b > a) b = a;
-
-       mul_rgb565 = (r << 11) || (g << 5) | b;
-     }
-
-   /* pre-calculated scale tables */
-   offset_x = alloca(cr.w * sizeof(*offset_x));
-   for (x = 0; x < cr.w; x++)
-     offset_x[x] = (((x + cr.x - dr.x) * sr.w) / dr.w) + sr.x;
-
-   offset_y = alloca(cr.h * sizeof(*offset_y));
-   for (y = 0; y < cr.h; y++)
-     offset_y[y] = (((((y + cr.y - dr.y) * sr.h) / dr.h) + sr.y)
-                   * src->stride);
-
-   dst_offset = cr.x + (cr.y * dst->stride);
-
-
-   if (mul_rgb565 == 0xffff)
-     _soft16_image_draw_scaled_no_mul
-       (src, dst, dc, dst_offset, cr.w, cr.h, offset_x, offset_y);
-   else
-     _soft16_image_draw_scaled_mul
-       (src, dst, dc, dst_offset, cr.w, cr.h, offset_x, offset_y, r, g, b, a);
-}
diff --git a/src/lib/engines/common_16/evas_soft16_image_unscaled.c b/src/lib/engines/common_16/evas_soft16_image_unscaled.c
deleted file mode 100644 (file)
index f53fdf0..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-#include "evas_common_soft16.h"
-#include "evas_soft16_scanline_blend.c"
-
-static void
-_soft16_image_draw_unscaled_solid_solid(Soft16_Image *src, Soft16_Image *dst,
-                                       RGBA_Draw_Context *dc __UNUSED__,
-                                       int src_offset, int dst_offset,
-                                       int w, int h)
-{
-   DATA16 *src_itr, *dst_itr;
-   int y;
-
-   src_itr = src->pixels + src_offset;
-   dst_itr = dst->pixels + dst_offset;
-
-   for (y = 0; y < h; y++)
-     {
-       _soft16_scanline_blend_solid_solid(src_itr, dst_itr, w);
-       src_itr += src->stride;
-       dst_itr += dst->stride;
-     }
-}
-
-static void
-_soft16_image_draw_unscaled_transp_solid(Soft16_Image *src, Soft16_Image *dst,
-                                        RGBA_Draw_Context *dc __UNUSED__,
-                                        int src_offset, int dst_offset,
-                                        int w, int h)
-
-{
-   DATA16 *src_itr, *dst_itr;
-   DATA8 *alpha_itr;
-   int y;
-
-   src_itr = src->pixels + src_offset;
-   alpha_itr = src->alpha + src_offset;
-   dst_itr = dst->pixels + dst_offset;
-
-   for (y = 0; y < h; y++)
-     {
-       _soft16_scanline_blend_transp_solid(src_itr, alpha_itr, dst_itr, w);
-       src_itr += src->stride;
-       alpha_itr += src->stride;
-       dst_itr += dst->stride;
-     }
-}
-
-static inline void
-_soft16_image_draw_unscaled_no_mul(Soft16_Image *src, Soft16_Image *dst,
-                                   RGBA_Draw_Context *dc,
-                                   int src_offset, int dst_offset,
-                                   int width, int height)
-{
-   if (src->cache_entry.flags.alpha && (!dst->cache_entry.flags.alpha))
-      _soft16_image_draw_unscaled_transp_solid(src, dst, dc,
-                                               src_offset, dst_offset,
-                                               width, height);
-   else if ((!src->cache_entry.flags.alpha) && (!dst->cache_entry.flags.alpha))
-      _soft16_image_draw_unscaled_solid_solid(src, dst, dc,
-                                              src_offset, dst_offset,
-                                              width, height);
-   else
-     ERR("Unsupported draw of unscaled images src->cache_entry.flags.alpha=%d, "
-              "dst->cache_entry.flags.alpha=%d, WITHOUT COLOR MUL",
-              src->cache_entry.flags.alpha, dst->cache_entry.flags.alpha);
-}
-
-static void
-_soft16_image_draw_unscaled_solid_solid_mul_alpha(Soft16_Image *src,
-                                                  Soft16_Image *dst,
-                                                  RGBA_Draw_Context *dc __UNUSED__,
-                                                  int src_offset,
-                                                  int dst_offset,
-                                                  int w, int h, DATA8 a)
-{
-   DATA16 *src_itr, *dst_itr;
-   int y;
-
-   src_itr = src->pixels + src_offset;
-   dst_itr = dst->pixels + dst_offset;
-
-   for (y = 0; y < h; y++)
-     {
-       _soft16_scanline_blend_solid_solid_mul_alpha(src_itr, dst_itr, w, a);
-       src_itr += src->stride;
-       dst_itr += dst->stride;
-     }
-}
-
-static void
-_soft16_image_draw_unscaled_transp_solid_mul_alpha(Soft16_Image *src,
-                                                   Soft16_Image *dst,
-                                                   RGBA_Draw_Context *dc __UNUSED__,
-                                                   int src_offset,
-                                                   int dst_offset,
-                                                   int w, int h, DATA8 a)
-
-{
-   DATA16 *src_itr, *dst_itr;
-   DATA8 *alpha_itr;
-   int y;
-
-   src_itr = src->pixels + src_offset;
-   alpha_itr = src->alpha + src_offset;
-   dst_itr = dst->pixels + dst_offset;
-
-   for (y = 0; y < h; y++)
-     {
-       _soft16_scanline_blend_transp_solid_mul_alpha(src_itr, alpha_itr,
-                                                      dst_itr, w, a);
-       src_itr += src->stride;
-       alpha_itr += src->stride;
-       dst_itr += dst->stride;
-     }
-}
-
-static inline void
-_soft16_image_draw_unscaled_mul_alpha(Soft16_Image *src, Soft16_Image *dst,
-                                      RGBA_Draw_Context *dc,
-                                      int src_offset, int dst_offset,
-                                      int width, int height, DATA8 a)
-{
-   if (src->cache_entry.flags.alpha && (!dst->cache_entry.flags.alpha))
-      _soft16_image_draw_unscaled_transp_solid_mul_alpha
-         (src, dst, dc, src_offset, dst_offset, width, height, a);
-   else if ((!src->cache_entry.flags.alpha) && (!dst->cache_entry.flags.alpha))
-      _soft16_image_draw_unscaled_solid_solid_mul_alpha
-         (src, dst, dc, src_offset, dst_offset, width, height, a);
-   else
-     ERR("Unsupported draw of unscaled images src->cache_entry.flags.alpha=%d, "
-              "dst->cache_entry.flags.alpha=%d, WITH ALPHA MUL %d",
-              src->cache_entry.flags.alpha, dst->cache_entry.flags.alpha, A_VAL(&dc->mul.col));
-}
-
-static void
-_soft16_image_draw_unscaled_solid_solid_mul_color(Soft16_Image *src,
-                                                  Soft16_Image *dst,
-                                                  RGBA_Draw_Context *dc __UNUSED__,
-                                                  int src_offset,
-                                                  int dst_offset,
-                                                  int w, int h, DATA8 r,
-                                                 DATA8 g, DATA8 b, DATA8 a)
-{
-   DATA16 *src_itr, *dst_itr;
-   int y;
-
-   src_itr = src->pixels + src_offset;
-   dst_itr = dst->pixels + dst_offset;
-
-   if (a == 31)
-      for (y = 0; y < h; y++)
-         {
-            _soft16_scanline_blend_solid_solid_mul_color_solid
-               (src_itr, dst_itr, w, r, g, b);
-            src_itr += src->stride;
-            dst_itr += dst->stride;
-         }
-   else
-      for (y = 0; y < h; y++)
-         {
-            _soft16_scanline_blend_solid_solid_mul_color_transp
-               (src_itr, dst_itr, w, a, r, g, b);
-            src_itr += src->stride;
-            dst_itr += dst->stride;
-         }
-}
-
-static void
-_soft16_image_draw_unscaled_transp_solid_mul_color(Soft16_Image *src,
-                                                   Soft16_Image *dst,
-                                                   RGBA_Draw_Context *dc __UNUSED__,
-                                                   int src_offset,
-                                                   int dst_offset,
-                                                   int w, int h, DATA8 r,
-                                                  DATA8 g, DATA8 b, DATA8 a)
-
-{
-   DATA16 *src_itr, *dst_itr;
-   DATA8 *alpha_itr;
-   int y;
-
-   src_itr = src->pixels + src_offset;
-   alpha_itr = src->alpha + src_offset;
-   dst_itr = dst->pixels + dst_offset;
-
-   if (a == 31)
-      for (y = 0; y < h; y++)
-         {
-            _soft16_scanline_blend_transp_solid_mul_color_solid
-               (src_itr, alpha_itr, dst_itr, w, r, g, b);
-            src_itr += src->stride;
-            alpha_itr += src->stride;
-            dst_itr += dst->stride;
-         }
-   else
-      for (y = 0; y < h; y++)
-         {
-            _soft16_scanline_blend_transp_solid_mul_color_transp
-               (src_itr, alpha_itr, dst_itr, w, a, r, g, b);
-            src_itr += src->stride;
-            alpha_itr += src->stride;
-            dst_itr += dst->stride;
-         }
-}
-
-static inline void
-_soft16_image_draw_unscaled_mul_color(Soft16_Image *src, Soft16_Image *dst,
-                                      RGBA_Draw_Context *dc,
-                                      int src_offset, int dst_offset,
-                                      int width, int height,
-                                     DATA8 r, DATA8 g, DATA8 b, DATA8 a)
-{
-   if (src->cache_entry.flags.alpha && (!dst->cache_entry.flags.alpha))
-     _soft16_image_draw_unscaled_transp_solid_mul_color
-       (src, dst, dc, src_offset, dst_offset, width, height, r, g, b, a);
-   else if ((!src->cache_entry.flags.alpha) && (!dst->cache_entry.flags.alpha))
-     _soft16_image_draw_unscaled_solid_solid_mul_color
-       (src, dst, dc, src_offset, dst_offset, width, height, r, g, b, a);
-   else
-     ERR("Unsupported draw of unscaled images src->cache_entry.flags.alpha=%d, "
-              "dst->cache_entry.flags.alpha=%d, WITH COLOR MUL 0x%08x",
-              src->cache_entry.flags.alpha, dst->cache_entry.flags.alpha, dc->mul.col);
-}
-
-static inline void
-_soft16_image_draw_unscaled_mul(Soft16_Image *src, Soft16_Image *dst,
-                                RGBA_Draw_Context *dc,
-                                int src_offset, int dst_offset,
-                                int width, int height, DATA8 r, DATA8 g,
-                               DATA8 b, DATA8 a)
-{
-   if ((a == r) && (a == (g >> 1)) && (a == b))
-      _soft16_image_draw_unscaled_mul_alpha(src, dst, dc, src_offset,
-                                            dst_offset, width, height, a);
-   else
-      _soft16_image_draw_unscaled_mul_color(src, dst, dc, src_offset,
-                                            dst_offset, width, height,
-                                           r, g, b, a);
-}
-
-void
-evas_common_soft16_image_draw_unscaled(Soft16_Image *src, Soft16_Image *dst,
-                          RGBA_Draw_Context *dc,
-                          const Eina_Rectangle sr,
-                          const Eina_Rectangle dr,
-                          const Eina_Rectangle cr)
-{
-   int src_offset_rows, src_offset, dst_offset;
-   DATA16 mul_rgb565;
-   DATA8 r, g, b, a;
-
-   if (!dc->mul.use)
-     {
-       r = b = a = 31;
-       g = 63;
-       mul_rgb565 = 0xffff;
-     }
-   else
-     {
-       a = A_VAL(&dc->mul.col) >> 3;
-       if (a == 0)
-         return;
-
-       r = R_VAL(&dc->mul.col) >> 3;
-       g = G_VAL(&dc->mul.col) >> 2;
-       b = B_VAL(&dc->mul.col) >> 3;
-
-       if (r > a) r = a;
-       if (g > (a << 1)) g = (a << 1);
-       if (b > a) b = a;
-
-       mul_rgb565 = (r << 11) || (g << 5) | b;
-     }
-
-
-   src_offset_rows = (cr.y - dr.y) + sr.y;
-   src_offset = (src_offset_rows * src->stride) + (cr.x - dr.x) + sr.x;
-
-   dst_offset = cr.x + (cr.y * dst->stride);
-
-   if (mul_rgb565 == 0xffff)
-       _soft16_image_draw_unscaled_no_mul(src, dst, dc, src_offset, dst_offset,
-                                          cr.w, cr.h);
-   else
-       _soft16_image_draw_unscaled_mul(src, dst, dc, src_offset, dst_offset,
-                                       cr.w, cr.h, r, g, b, a);
-}
diff --git a/src/lib/engines/common_16/evas_soft16_line.c b/src/lib/engines/common_16/evas_soft16_line.c
deleted file mode 100644 (file)
index 92e14af..0000000
+++ /dev/null
@@ -1,444 +0,0 @@
-#include "evas_common_soft16.h"
-#include "evas_soft16_scanline_fill.c"
-
-/*
- * All functions except by evas_common_soft16_line_draw() expect x0 <= x1.
- */
-
-static inline int
-_in_range(int value, int min, int max)
-{
-   return min <= value && value <= max;
-}
-
-static inline int
-_is_xy_inside_clip(int x, int y, const struct RGBA_Draw_Context_clip clip)
-{
-   if (!clip.use)
-     return 1;
-
-   if (!_in_range(x, clip.x, clip.x + clip.w - 1))
-     return 0;
-
-   if (!_in_range(y, clip.y, clip.y + clip.h - 1))
-     return 0;
-
-   return 1;
-}
-
-static inline int
-_is_x_inside_clip(int x, const struct RGBA_Draw_Context_clip clip)
-{
-   if (!clip.use)
-     return 1;
-
-   return _in_range(x, clip.x, clip.x + clip.w - 1);
-}
-
-static inline int
-_is_y_inside_clip(int y, const struct RGBA_Draw_Context_clip clip)
-{
-   if (!clip.use)
-     return 1;
-
-   return _in_range(y, clip.y, clip.y + clip.h - 1);
-}
-
-static inline int
-_is_xy_inside_rect(int x, int y, int w, int h)
-{
-   return _in_range(x, 0, w - 1) && _in_range(y, 0, h - 1);
-}
-
-static inline int
-_is_empty_clip(const struct RGBA_Draw_Context_clip clip)
-{
-   return clip.w < 1 || clip.h < 1;
-}
-
-static void
-_soft16_line_point(Soft16_Image *dst, RGBA_Draw_Context *dc, int x, int y)
-{
-   DATA16 rgb565, *dst_itr;
-   DATA8 alpha;
-
-   if (!_is_xy_inside_rect(x, y, dst->cache_entry.w, dst->cache_entry.h))
-     return;
-
-   if (!_is_xy_inside_clip(x, y, dc->clip))
-     return;
-
-   dst_itr = dst->pixels + (dst->stride * y) + x;
-   alpha = A_VAL(&dc->col.col) >> 3;
-   rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
-                                   G_VAL(&dc->col.col),
-                                   B_VAL(&dc->col.col));
-
-   if (alpha == 31)
-     _soft16_pt_fill_solid_solid(dst_itr, rgb565);
-   else if (alpha > 0)
-     {
-       DATA32 rgb565_unpack;
-
-       rgb565_unpack = RGB_565_UNPACK(rgb565);
-       alpha++;
-       _soft16_pt_fill_transp_solid(dst_itr, rgb565_unpack, alpha);
-     }
-}
-
-static void
-_soft16_line_horiz(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int x1, int y)
-{
-   DATA16 rgb565, *dst_itr;
-   DATA8 alpha;
-   int w;
-
-   if (!_is_y_inside_clip(y, dc->clip))
-     return;
-
-   if (x0 < dc->clip.x)
-     x0 = dc->clip.x;
-
-   if (x1 >= dc->clip.x + dc->clip.w)
-     x1 = dc->clip.x + dc->clip.w - 1;
-
-   w = x1 - x0;
-   if (w < 1)
-     return;
-
-   dst_itr = dst->pixels + (dst->stride * y) + x0;
-   alpha = A_VAL(&dc->col.col) >> 3;
-   rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
-                                   G_VAL(&dc->col.col),
-                                   B_VAL(&dc->col.col));
-
-   if (alpha == 31)
-     _soft16_scanline_fill_solid_solid(dst_itr, w, rgb565);
-   else if (alpha > 0)
-     {
-       DATA32 rgb565_unpack;
-
-       rgb565_unpack = RGB_565_UNPACK(rgb565);
-       alpha++;
-       _soft16_scanline_fill_transp_solid(dst_itr, w, rgb565_unpack, alpha);
-     }
-}
-
-static void
-_soft16_line_vert(Soft16_Image *dst, RGBA_Draw_Context *dc, int x, int y0, int y1)
-{
-   DATA16 rgb565, *dst_itr;
-   DATA8 alpha;
-   int h;
-
-   if (!_is_x_inside_clip(x, dc->clip))
-     return;
-
-   if (y1 < y0)
-     {
-       int t;
-       t = y0;
-       y0 = y1;
-       y1 = t;
-     }
-
-   if (y0 < dc->clip.y)
-     y0 = dc->clip.y;
-
-   if (y1 >= dc->clip.y + dc->clip.h)
-     y1 = dc->clip.y + dc->clip.h - 1;
-
-   h = y1 - y0;
-   if (h < 1)
-     return;
-
-   dst_itr = dst->pixels + (dst->stride * y0) + x;
-   alpha = A_VAL(&dc->col.col) >> 3;
-   rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
-                                   G_VAL(&dc->col.col),
-                                   B_VAL(&dc->col.col));
-
-   if (alpha == 31)
-     {
-       for (; h > 0; h--, dst_itr += dst->stride)
-         _soft16_pt_fill_solid_solid(dst_itr, rgb565);
-     }
-   else if (alpha > 0)
-     {
-       DATA32 rgb565_unpack;
-
-       rgb565_unpack = RGB_565_UNPACK(rgb565);
-       alpha++;
-
-       for (; h > 0; h--, dst_itr += dst->stride)
-         _soft16_pt_fill_transp_solid(dst_itr, rgb565_unpack, alpha);
-     }
-}
-
-static inline void
-_soft16_line_45deg_adjust_boundaries(const struct RGBA_Draw_Context_clip clip, int *p_x0, int *p_y0, int *p_x1, int *p_y1)
-{
-   int diff, dy, x0, y0, x1, y1;
-
-   x0 = *p_x0;
-   y0 = *p_y0;
-   x1 = *p_x1;
-   y1 = *p_y1;
-
-   dy = y1 - y0;
-
-   diff = clip.x - x0;
-   if (diff > 0)
-     {
-       x0 = clip.x;
-       y0 += (dy > 0) ? diff : -diff;
-     }
-
-   diff = x1 - (clip.x + clip.w);
-   if (diff > 0)
-     {
-       x1 = clip.x + clip.w;
-       y1 += (dy > 0) ? -diff : diff;
-     }
-
-   if (dy > 0)
-     {
-       diff = clip.y - y0;
-       if (diff > 0)
-         {
-            y0 = clip.y;
-            x0 += diff;
-         }
-
-       diff = y1 - (clip.y + clip.h);
-       if (diff > 0)
-         {
-            y1 = clip.y + clip.h;
-            x1 -= diff;
-         }
-     }
-   else
-     {
-       diff = clip.y - y1;
-       if (diff > 0)
-         {
-            y1 = clip.y;
-            x1 -= diff;
-         }
-
-       diff = y0 - (clip.y + clip.h - 1);
-       if (diff > 0)
-         {
-            y0 = clip.y + clip.h - 1;
-            x0 += diff;
-         }
-     }
-
-   *p_x0 = x0;
-   *p_y0 = y0;
-   *p_x1 = x1;
-   *p_y1 = y1;
-}
-
-static void
-_soft16_line_45deg(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1)
-{
-   int dy, step_dst_itr, len;
-   DATA8 alpha;
-   DATA16 *dst_itr, rgb565;
-
-   alpha = A_VAL(&dc->col.col) >> 3;
-   if (alpha < 1)
-     return;
-
-   rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
-                                   G_VAL(&dc->col.col),
-                                   B_VAL(&dc->col.col));
-
-   dy = y1 - y0;
-   step_dst_itr = 1 + ((dy > 0) ? dst->stride : -dst->stride);
-
-   _soft16_line_45deg_adjust_boundaries(dc->clip, &x0, &y0, &x1, &y1);
-
-   len = (dy > 0) ? (y1 - y0) : (y0 - y1);
-   if (len < 1)
-     return;
-
-   dst_itr = dst->pixels + dst->stride * y0 + x0;
-   if (alpha == 31)
-     {
-       for (; len > 0; len--, dst_itr += step_dst_itr)
-         _soft16_pt_fill_solid_solid(dst_itr, rgb565);
-     }
-   else
-     {
-       DATA32 rgb565_unpack;
-
-       rgb565_unpack = RGB_565_UNPACK(rgb565);
-       alpha++;
-       for (; len > 0; len--, dst_itr += step_dst_itr)
-         _soft16_pt_fill_transp_solid(dst_itr, rgb565_unpack, alpha);
-     }
-}
-
-EFL_ALWAYS_INLINE void
-_soft16_line_aliased_pt(DATA16 *dst_itr, DATA16 rgb565, DATA32 rgb565_unpack, DATA8 alpha)
-{
-   if (alpha == 32)
-     _soft16_pt_fill_solid_solid(dst_itr, rgb565);
-   else
-     _soft16_pt_fill_transp_solid(dst_itr, rgb565_unpack, alpha);
-}
-
-static void
-_soft16_line_aliased(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1)
-{
-   int dx, dy, step_y, step_dst_itr;
-   DATA32 rgb565_unpack;
-   DATA16 rgb565;
-   DATA8 alpha;
-
-   alpha = A_VAL(&dc->col.col) >> 3;
-   if (alpha == 0)
-     return;
-   alpha++;
-
-   rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
-                                   G_VAL(&dc->col.col),
-                                   B_VAL(&dc->col.col));
-   rgb565_unpack = RGB_565_UNPACK(rgb565);
-
-   dx = x1 - x0;
-   dy = y1 - y0;
-
-   if (dy >= 0)
-     {
-       step_y = 1;
-       step_dst_itr = dst->stride;
-     }
-   else
-     {
-       dy = -dy;
-       step_y = -1;
-       step_dst_itr = -dst->stride;
-     }
-
-   if (dx > dy)
-     {
-       DATA16 *dst_itr;
-       int e, x, y;
-
-       e = - (dx / 2);
-       y = y0;
-       dst_itr = dst->pixels + dst->stride * y0 + x0;
-       for (x=x0; x <= x1; x++, dst_itr++)
-         {
-            if (_is_xy_inside_clip(x, y, dc->clip))
-              _soft16_line_aliased_pt(dst_itr, rgb565, rgb565_unpack, alpha);
-
-            e += dy;
-            if (e >= 0)
-              {
-                 dst_itr += step_dst_itr;
-                 y += step_y;
-                 e -= dx;
-              }
-         }
-     }
-   else
-     {
-       DATA16 *dst_itr;
-       int e, x, y;
-
-       e = - (dy / 2);
-       x = x0;
-       dst_itr = dst->pixels + dst->stride * y0 + x0;
-       for (y=y0; y != y1; y += step_y, dst_itr += step_dst_itr)
-         {
-            if (_is_xy_inside_clip(x, y, dc->clip))
-              _soft16_line_aliased_pt(dst_itr, rgb565, rgb565_unpack, alpha);
-
-            e += dx;
-            if (e >= 0)
-              {
-                 dst_itr++;
-                 x++;
-                 e -= dy;
-              }
-         }
-     }
-}
-
-void
-evas_common_soft16_line_draw(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1)
-{
-   struct RGBA_Draw_Context_clip c_bkp, c_tmp;
-   int dx, dy;
-   int  x, y, w, h;
-
-   c_tmp.use = 1;
-   c_tmp.x = 0;
-   c_tmp.y = 0;
-   c_tmp.w = dst->cache_entry.w;
-   c_tmp.h = dst->cache_entry.h;
-
-   /* save out clip info */
-   c_bkp = dc->clip;
-   if (c_bkp.use)
-     {
-       RECTS_CLIP_TO_RECT(c_tmp.x, c_tmp.y, c_tmp.w, c_tmp.h,
-                          c_bkp.x, c_bkp.y, c_bkp.w, c_bkp.h);
-       if (_is_empty_clip(c_tmp))
-         return;
-     }
-
-   x = MIN(x0, x1);
-   y = MIN(y0, y1);
-   w = MAX(x0, x1) - x + 1;
-   h = MAX(y0, y1) - y + 1;
-
-   RECTS_CLIP_TO_RECT(c_tmp.x, c_tmp.y, c_tmp.w, c_tmp.h, x, y, w, h);
-   if (_is_empty_clip(c_tmp))
-     return;
-
-   /* Check if the line doesn't cross the clip area */
-   if (x0 < c_tmp.x && x1 < c_tmp.x)
-     return;
-   if (x0 >= c_tmp.x + c_tmp.w && x1 >= c_tmp.x + c_tmp.w)
-     return;
-   if (y0 < c_tmp.y && y1 < c_tmp.y)
-     return;
-   if (y0 >= c_tmp.y + c_tmp.h && y1 >= c_tmp.y + c_tmp.h)
-     return;
-
-   dc->clip = c_tmp;
-   dx = x1 - x0;
-   dy = y1 - y0;
-
-   if (dx < 0)
-     {
-       int t;
-
-       t = x0;
-       x0 = x1;
-       x1 = t;
-
-       t = y0;
-       y0 = y1;
-       y1 = t;
-     }
-
-   if (dx == 0 && dy == 0)
-     _soft16_line_point(dst, dc, x0, y0);
-   else if (dx == 0)
-     _soft16_line_vert(dst, dc, x0, y0, y1);
-   else if (dy == 0)
-     _soft16_line_horiz(dst, dc, x0, x1, y0);
-   else if (dy == dx || dy == -dx)
-     _soft16_line_45deg(dst, dc, x0, y0, x1, y1);
-   else
-     _soft16_line_aliased(dst, dc, x0, y0, x1, y1);
-
-   /* restore clip info */
-   dc->clip = c_bkp;
-}
diff --git a/src/lib/engines/common_16/evas_soft16_main.c b/src/lib/engines/common_16/evas_soft16_main.c
deleted file mode 100644 (file)
index 5258b7d..0000000
+++ /dev/null
@@ -1,593 +0,0 @@
-#include "evas_common_soft16.h"
-
-static Evas_Cache_Image *eci = NULL;
-static int               reference = 0;
-
-static Image_Entry      *_evas_common_soft16_image_new(void);
-static void              _evas_common_soft16_image_delete(Image_Entry *ie);
-
-static int               _evas_common_soft16_image_surface_alloc(Image_Entry *ie, unsigned int w, unsigned int h);
-static void              _evas_common_soft16_image_surface_delete(Image_Entry *ie);
-static DATA32          *_evas_common_soft16_image_surface_pixels(Image_Entry *ie);
-
-static int               _evas_common_load_soft16_image_from_file(Image_Entry *ie);
-static void              _evas_common_soft16_image_unload(Image_Entry *ie);
-
-static void              _evas_common_soft16_image_dirty_region(Image_Entry *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h);
-static int               _evas_common_soft16_image_dirty(Image_Entry *ie_dst, const Image_Entry *ie_src);
-
-static int               _evas_common_soft16_image_ram_usage(Image_Entry *ie);
-
-static int               _evas_common_soft16_image_size_set(Image_Entry *ie_dst, const Image_Entry *ie_im, unsigned int w, unsigned int h);
-static int               _evas_common_soft16_image_from_copied_data(Image_Entry* ie_dst, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace);
-static int               _evas_common_soft16_image_from_data(Image_Entry* ie_dst, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace);
-static int               _evas_common_soft16_image_colorspace_set(Image_Entry* ie_dst, int cspace);
-
-static int               _evas_common_load_soft16_image_data_from_file(Image_Entry *ie);
-
-/* static void */
-/* _evas_common_soft16_image_debug(const char* context, Image_Entry *eim) */
-/* { */
-/*    DBG("[16] %p = [%s] {%s,%s} %i [%i|%i]", eim, context, eim->file, eim->key, eim->references, eim->w, eim->h); */
-/* } */
-
-static const Evas_Cache_Image_Func      _evas_common_soft16_image_func =
-{
-   _evas_common_soft16_image_new,
-   _evas_common_soft16_image_delete,
-   _evas_common_soft16_image_surface_alloc,
-   _evas_common_soft16_image_surface_delete,
-   _evas_common_soft16_image_surface_pixels,
-   _evas_common_load_soft16_image_from_file,
-   _evas_common_soft16_image_unload,
-   _evas_common_soft16_image_dirty_region,
-   _evas_common_soft16_image_dirty,
-   _evas_common_soft16_image_size_set,
-   _evas_common_soft16_image_from_copied_data,
-   _evas_common_soft16_image_from_data,
-   _evas_common_soft16_image_colorspace_set,
-   _evas_common_load_soft16_image_data_from_file,
-   _evas_common_soft16_image_ram_usage,
-/*    _evas_common_soft16_image_debug */
-   NULL
-};
-
-EAPI void
-evas_common_soft16_image_init(void)
-{
-   if (!eci)
-     eci = evas_cache_image_init(&_evas_common_soft16_image_func);
-   reference++;
-}
-
-EAPI void
-evas_common_soft16_image_shutdown(void)
-{
-   if (--reference == 0)
-     {
-// DISABLE for now - something wrong with cache shutdown freeing things
-// still in use - rage_thumb segv's now.
-// 
-// actually - i think i see it. cache ref goes to 0 (and thus gets freed)
-// because in eng_setup() when a buffer changes size it is FIRST freed
-// THEN allocated again - thus brignhjing ref to 0 then back to 1 immediately
-// where it should stay at 1. - see evas_engine.c in the buffer enigne for
-// example. eng_output_free() is called BEFORE _output_setup(). although this
-// is only a SIGNE of the problem. we can patch this up with either freeing
-// after the setup (so we just pt a ref of 2 then back to 1), or just 
-// evas_common_image_init() at the start and evas_common_image_shutdown()
-// after it all. really ref 0 should only be reached when no more canvases
-// with no more objects exist anywhere.
-
-// ENABLE IT AGAIN, hope it is fixed. Gustavo @ January 22nd, 2009.
-        evas_cache_image_shutdown(eci);
-        eci = NULL;
-     }
-}
-
-EAPI Evas_Cache_Image *
-evas_common_soft16_image_cache_get(void)
-{
-   return eci;
-}
-
-static Image_Entry *
-_evas_common_soft16_image_new(void)
-{
-   Soft16_Image *im;
-
-   im = calloc(1, sizeof(Soft16_Image));
-   if (!im) return NULL;
-
-   im->stride = -1;
-
-   return (Image_Entry *) im;
-}
-
-static void
-_evas_common_soft16_image_delete(Image_Entry *ie)
-{
-   memset(ie, 0xFF, sizeof (Soft16_Image));
-   free(ie);
-}
-
-static int
-_evas_common_soft16_image_surface_alloc(Image_Entry *ie, unsigned int w, unsigned int h)
-{
-   Soft16_Image *im = (Soft16_Image *) ie;
-
-   if (im->stride < 0) im->stride = _calc_stride(w);
-
-   im->pixels = realloc(im->pixels, IMG_BYTE_SIZE(im->stride, h, ie->flags.alpha));
-   if (!im->pixels) return -1;
-
-   if (ie->flags.alpha)
-     {
-        im->alpha = (DATA8 *)(im->pixels + (im->stride * h));
-        im->flags.free_alpha = 0;
-     }
-   im->flags.free_pixels = 1;
-
-   return 0;
-}
-
-static void
-_evas_common_soft16_image_surface_delete(Image_Entry *ie)
-{
-   Soft16_Image *im = (Soft16_Image *) ie;
-
-   if (im->flags.free_pixels)
-     free(im->pixels);
-   im->pixels = NULL;
-   im->flags.free_pixels = 0;
-
-   if (im->flags.free_alpha)
-     free(im->alpha);
-   im->alpha = NULL;
-   im->flags.free_alpha = 0;
-}
-
-static DATA32 *
-_evas_common_soft16_image_surface_pixels(Image_Entry *ie __UNUSED__)
-{
-   abort();
-
-   return NULL;
-}
-
-static int
-_evas_common_load_soft16_image_from_file(Image_Entry *ie)
-{
-   Soft16_Image *sim = (Soft16_Image *) ie;
-   RGBA_Image   *im;
-   int           error = 0;
-
-   im = (RGBA_Image *) evas_cache_image_request(evas_common_image_cache_get(), sim->cache_entry.file, sim->cache_entry.key, &sim->cache_entry.load_opts, &error);
-   sim->source = im;
-   if (!sim->source) return -1;
-
-   sim->cache_entry.w = sim->source->cache_entry.w;
-   sim->cache_entry.h = sim->source->cache_entry.h;
-   ie->flags.alpha = im->cache_entry.flags.alpha;
-   sim->cache_entry.info = im->cache_entry.info;
-   if (sim->stride < 0) sim->stride = _calc_stride(sim->cache_entry.w);
-
-   return 0;
-}
-
-static void
-_evas_common_soft16_image_unload(Image_Entry *ie __UNUSED__)
-{
-}
-
-static void
-_evas_common_soft16_image_dirty_region(Image_Entry *im __UNUSED__, unsigned int x __UNUSED__, unsigned int y __UNUSED__, unsigned int w __UNUSED__, unsigned int h __UNUSED__)
-{
-}
-
-static int
-_evas_common_soft16_image_dirty(Image_Entry *ie_dst, const Image_Entry *ie_src)
-{
-   Soft16_Image *dst = (Soft16_Image *) ie_dst;
-   Soft16_Image *src = (Soft16_Image *) ie_src;
-
-   evas_cache_image_load_data(&src->cache_entry);
-   evas_cache_image_surface_alloc(&dst->cache_entry,
-                                  src->cache_entry.w, src->cache_entry.h);
-
-/*    evas_common_blit_rectangle(src, dst, 0, 0, src->cache_entry.w, src->cache_entry.h, 0, 0); */
-
-   return 0;
-}
-
-static int
-_evas_common_soft16_image_ram_usage(Image_Entry *ie)
-{
-   Soft16_Image *im = (Soft16_Image *) ie;
-
-   if (im->pixels && im->flags.free_pixels)
-     return IMG_BYTE_SIZE(im->stride, im->cache_entry.h, ie->flags.alpha);
-   return 0;
-}
-
-static int
-_evas_common_soft16_image_size_set(Image_Entry *ie_dst, const Image_Entry *ie_im, unsigned int w __UNUSED__, unsigned int h __UNUSED__)
-{
-   Soft16_Image *dst = (Soft16_Image *) ie_dst;
-   Soft16_Image *im = (Soft16_Image *) ie_im;
-
-   dst->flags = im->flags;
-
-   return 0;
-}
-
-static int
-_evas_common_soft16_image_from_data(Image_Entry* ie_dst, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace __UNUSED__)
-{
-   Soft16_Image *im = (Soft16_Image *) ie_dst;
-
-   /* FIXME: handle colorspace */
-   ie_dst->w = w;
-   ie_dst->h = h;
-   ie_dst->flags.alpha = alpha;
-
-   im->flags.free_pixels = 0;
-   im->flags.free_alpha = 0;
-   if (im->stride < 0)
-        im->stride = _calc_stride(w);
-
-   /* FIXME: That's bad, the application must be aware of the engine internal. */
-   im->pixels = (DATA16 *) image_data;
-   if (ie_dst->flags.alpha)
-     im->alpha = (DATA8 *)(im->pixels + (im->stride * h));
-
-   return 0;
-}
-
-static int
-_evas_common_soft16_image_from_copied_data(Image_Entry* ie_dst, unsigned int w __UNUSED__, unsigned int h, DATA32 *image_data, int alpha __UNUSED__, int cspace __UNUSED__)
-{
-   Soft16_Image *im = (Soft16_Image *) ie_dst;
-
-   /* FIXME: handle colorspace */
-   if (image_data)
-     memcpy(im->pixels, image_data, IMG_BYTE_SIZE(im->stride, h, ie_dst->flags.alpha));
-   else
-     memset(im->pixels, 0, IMG_BYTE_SIZE(im->stride, h, ie_dst->flags.alpha));
-
-   return 0;
-}
-
-static int
-_evas_common_soft16_image_colorspace_set(Image_Entry* ie_dst __UNUSED__, int cspace __UNUSED__)
-{
-   /* FIXME: handle colorspace */
-   return 0;
-}
-
-static int
-_evas_common_load_soft16_image_data_from_file(Image_Entry *ie)
-{
-   Soft16_Image *im = (Soft16_Image *) ie;
-
-   if (im->pixels) return 0;
-   if (!im->source) return -1;
-
-   evas_cache_image_load_data(&im->source->cache_entry);
-   if (im->source->image.data)
-     {
-        DATA32 *sp;
-
-        evas_cache_image_surface_alloc(&im->cache_entry,
-                                       im->source->cache_entry.w,
-                                       im->source->cache_entry.h);
-
-        sp = im->source->image.data;
-        if (im->alpha)
-          evas_common_soft16_image_convert_from_rgba(im, sp);
-        else
-          evas_common_soft16_image_convert_from_rgb(im, sp);
-     }
-   evas_cache_image_drop(&im->source->cache_entry);
-   im->cache_entry.info.module = NULL;
-   im->cache_entry.info.loader = NULL;
-   im->source = NULL;
-
-   return 0;
-}
-
-/* Soft16_Image * */
-/* evas_common_soft16_image_new(int w, int h, int stride, int have_alpha, DATA16 *pixels, */
-/*              int copy) */
-/* { */
-/*    Soft16_Image *im; */
-
-/*    if (stride < 0) stride = _calc_stride(w); */
-
-/*    im = evas_common_soft16_image_alloc(w, h, stride, have_alpha, copy); */
-/*    if (!im) return NULL; */
-
-/*    if (pixels) */
-/*      { */
-/*     if (copy) */
-/*       memcpy(im->pixels, pixels, IMG_BYTE_SIZE(stride, h, have_alpha)); */
-/*     else */
-/*       { */
-/*          im->pixels = pixels; */
-/*          if (have_alpha) im->alpha = (DATA8 *)(im->pixels + (stride * h)); */
-/*       } */
-/*      } */
-/*    return im; */
-/* } */
-
-static inline void
-_get_clip(const RGBA_Draw_Context *dc, const Soft16_Image *im,
-         Eina_Rectangle *clip)
-{
-   if (dc->clip.use)
-     {
-       EINA_RECTANGLE_SET(clip, dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
-       if (clip->x < 0)
-         {
-            clip->w += clip->x;
-            clip->x = 0;
-         }
-       if (clip->y < 0)
-         {
-            clip->h += clip->y;
-            clip->y = 0;
-         }
-       if ((clip->x + clip->w) > (int)im->cache_entry.w) clip->w = im->cache_entry.w - clip->x;
-       if ((clip->y + clip->h) > (int)im->cache_entry.h) clip->h = im->cache_entry.h - clip->y;
-     }
-   else
-     {
-       EINA_RECTANGLE_SET(clip, 0, 0, im->cache_entry.w, im->cache_entry.h);
-     }
-}
-
-static inline int
-_is_empty_rectangle(const Eina_Rectangle *r)
-{
-   return (r->w < 1) || (r->h < 1);
-}
-
-static inline void
-_shrink(int *s_pos, int *s_size, int pos, int size)
-{
-   int d;
-
-   d = (*s_pos) - pos;
-   if (d < 0)
-     {
-       (*s_size) += d;
-       (*s_pos) = pos;
-     }
-
-   d = size + pos - (*s_pos);
-   if ((*s_size) > d)
-     (*s_size) = d;
-}
-
-static int
-_soft16_adjust_areas(Eina_Rectangle *src,
-                    int src_max_x, int src_max_y,
-                    Eina_Rectangle *dst,
-                    int dst_max_x, int dst_max_y,
-                    Eina_Rectangle *dst_clip)
-{
-   if (_is_empty_rectangle(src) ||
-       _is_empty_rectangle(dst) ||
-       _is_empty_rectangle(dst_clip))
-     return 0;
-
-   /* shrink clip */
-   _shrink(&dst_clip->x, &dst_clip->w, dst->x, dst->w);
-   _shrink(&dst_clip->y, &dst_clip->h, dst->y, dst->h);
-   if (_is_empty_rectangle(dst_clip)) return 0;
-
-   /* sanitise x */
-   if (src->x < 0)
-     {
-       dst->x -= (src->x * dst->w) / src->w;
-       dst->w += (src->x * dst->w) / src->w;
-       src->w += src->x;
-       src->x = 0;
-     }
-   if (src->x >= src_max_x) return 0;
-   if ((src->x + src->w) > src_max_x)
-     {
-       dst->w = (dst->w * (src_max_x - src->x)) / (src->w);
-       src->w = src_max_x - src->x;
-     }
-   if (dst->w <= 0) return 0;
-   if (src->w <= 0) return 0;
-   if (dst_clip->x < 0)
-     {
-       dst_clip->w += dst_clip->x;
-       dst_clip->x = 0;
-     }
-   if (dst_clip->w <= 0) return 0;
-   if (dst_clip->x >= dst_max_x) return 0;
-
-   _shrink(&dst_clip->x, &dst_clip->w, 0, dst_max_x);
-   if (dst_clip->w <= 0) return 0;
-
-   /* sanitise y */
-   if (src->y < 0)
-     {
-       dst->y -= (src->y * dst->h) / src->h;
-       dst->h += (src->y * dst->h) / src->h;
-       src->h += src->y;
-       src->y = 0;
-     }
-   if (src->y >= src_max_y) return 0;
-   if ((src->y + src->h) > src_max_y)
-     {
-       dst->h = (dst->h * (src_max_y - src->y)) / (src->h);
-       src->h = src_max_y - src->y;
-     }
-   if (dst->h <= 0) return 0;
-   if (src->h <= 0) return 0;
-   if (dst_clip->y < 0)
-     {
-       dst_clip->h += dst_clip->y;
-       dst_clip->y = 0;
-     }
-   if (dst_clip->h <= 0) return 0;
-   if (dst_clip->y >= dst_max_y) return 0;
-
-   _shrink(&dst_clip->y, &dst_clip->h, 0, dst_max_y);
-   if (dst_clip->h <= 0) return 0;
-
-   return 1;
-}
-
-static void
-_soft16_image_draw_sampled_int(Soft16_Image *src, Soft16_Image *dst,
-                              RGBA_Draw_Context *dc,
-                              Eina_Rectangle sr, Eina_Rectangle dr)
-{
-   Eina_Rectangle cr;
-
-   if (!(RECTS_INTERSECT(dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
-     return;
-   if (!(RECTS_INTERSECT(sr.x, sr.y, sr.w, sr.h, 0, 0, src->cache_entry.w, src->cache_entry.h)))
-     return;
-
-   _get_clip(dc, dst, &cr);
-   if (!_soft16_adjust_areas(&sr, src->cache_entry.w, src->cache_entry.h, &dr, dst->cache_entry.w, dst->cache_entry.h, &cr))
-     return;
-
-   if ((dr.w == sr.w) && (dr.h == sr.h))
-     evas_common_soft16_image_draw_unscaled(src, dst, dc, sr, dr, cr);
-   else
-     evas_common_soft16_image_draw_scaled_sampled(src, dst, dc, sr, dr, cr);
-}
-
-EAPI void
-evas_common_soft16_image_draw(Soft16_Image *src, Soft16_Image *dst,
-                 RGBA_Draw_Context *dc,
-                 int src_region_x, int src_region_y,
-                 int src_region_w, int src_region_h,
-                 int dst_region_x, int dst_region_y,
-                 int dst_region_w, int dst_region_h,
-                 int smooth __UNUSED__)
-{
-   static Cutout_Rects *rects = NULL;
-   Eina_Rectangle sr, dr;
-   Cutout_Rect  *r;
-   struct RGBA_Draw_Context_clip clip_bkp;
-   int i;
-
-   /* handle cutouts here! */
-   EINA_RECTANGLE_SET(&dr, dst_region_x, dst_region_y, dst_region_w, dst_region_h);
-
-   if (_is_empty_rectangle(&dr)) return;
-   if (!(RECTS_INTERSECT(dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
-     return;
-
-   EINA_RECTANGLE_SET(&sr, src_region_x, src_region_y, src_region_w, src_region_h);
-
-   if (_is_empty_rectangle(&sr)) return;
-   if (!(RECTS_INTERSECT(sr.x, sr.y, sr.w, sr.h, 0, 0, src->cache_entry.w, src->cache_entry.h)))
-     return;
-
-   /* no cutouts - cut right to the chase */
-   if (!dc->cutout.rects)
-     {
-       _soft16_image_draw_sampled_int(src, dst, dc, sr, dr);
-       return;
-     }
-
-   /* save out clip info */
-   clip_bkp = dc->clip;
-   evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
-   evas_common_draw_context_clip_clip(dc, dst_region_x, dst_region_y, dst_region_w, dst_region_h);
-   /* our clip is 0 size.. abort */
-   if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
-     {
-       dc->clip = clip_bkp;
-       return;
-     }
-   rects = evas_common_draw_context_apply_cutouts(dc, rects);
-   for (i = 0; i < rects->active; i++)
-     {
-       r = rects->rects + i;
-       evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
-       _soft16_image_draw_sampled_int(src, dst, dc, sr, dr);
-     }
-   dc->clip = clip_bkp;
-}
-
-EAPI Soft16_Image *
-evas_common_soft16_image_alpha_set(Soft16_Image *im, int have_alpha)
-{
-   Soft16_Image   *new_im;
-
-   if (im->cache_entry.flags.alpha == have_alpha) return im;
-
-   new_im = (Soft16_Image *) evas_cache_image_alone(&im->cache_entry);
-
-   new_im->cache_entry.flags.alpha = have_alpha;
-
-   if (im->cache_entry.w > 0
-       && im->cache_entry.h)
-     new_im = (Soft16_Image *) evas_cache_image_size_set(&new_im->cache_entry, im->cache_entry.w, im->cache_entry.h);
-
-   return new_im;
-}
-
-/* Soft16_Image * */
-/* evas_common_soft16_image_size_set(Soft16_Image *old_im, int w, int h) */
-/* { */
-/*    Soft16_Image *new_im; */
-/*    DATA16 *dp, *sp; */
-/*    int i, cw, ch, ew; */
-
-/*    if ((old_im->cache_entry.w == w) && (old_im->cache_entry.h == h)) return old_im; */
-
-/*    new_im = evas_common_soft16_image_new(w, h, -1, old_im->flags.have_alpha, NULL, 1); */
-
-/*    if (old_im->cache_entry.w < new_im->cache_entry.w) */
-/*      cw = old_im->cache_entry.w; */
-/*    else */
-/*      cw = new_im->cache_entry.w; */
-
-/*    ew = new_im->cache_entry.w - cw; */
-
-/*    if (old_im->cache_entry.h < new_im->cache_entry.h) */
-/*      ch = old_im->cache_entry.h; */
-/*    else */
-/*      ch = new_im->cache_entry.h; */
-
-/*    dp = new_im->pixels; */
-/*    sp = old_im->pixels; */
-/*    for (i = 0; i < ch; i++) */
-/*      { */
-/*     memcpy(dp, sp, cw * sizeof(DATA16)); */
-/*     if (ew > 0) memset(dp, 0, ew * sizeof(DATA16)); */
-
-/*     dp += new_im->stride; */
-/*     sp += old_im->stride; */
-/*      } */
-
-/*    if (old_im->flags.have_alpha) */
-/*      { */
-/*     DATA8 *dp, *sp; */
-
-/*     dp = new_im->alpha; */
-/*     sp = old_im->alpha; */
-/*     for (i = 0; i < ch; i++) */
-/*       { */
-/*          memcpy(dp, sp, cw * sizeof(DATA8)); */
-/*          if (ew > 0) memset(dp, 0, ew * sizeof(DATA8)); */
-
-/*          dp += new_im->stride; */
-/*          sp += old_im->stride; */
-/*       } */
-/*      } */
-
-/*    evas_cache_image_drop(&old_im->cache_entry); */
-/*    return new_im; */
-/* } */
diff --git a/src/lib/engines/common_16/evas_soft16_point_blend.c b/src/lib/engines/common_16/evas_soft16_point_blend.c
deleted file mode 100644 (file)
index 8cd02d5..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/** NOTE: This file is meant to be included by users **/
-
-/** NOTE2: r, g, b parameters are 16bits, so you can pass 0 to 256 inclusive.
- **        this is due our division by 256 when multiplying the color.
- **/
-
-/*****************************************************************************
- * Scanline processing
- *
- *    _soft16_pt_<description>_<src>_<dst>[_<modifier>]()
- *
- ****************************************************************************/
-
-/***********************************************************************
- * Regular blend operations
- */
-
-EFL_ALWAYS_INLINE void
-_soft16_pt_blend_transp_solid(DATA16 *p_dst, DATA16 src, DATA8 alpha)
-{
-   if (alpha == 31) *p_dst = src;
-   else if (alpha != 0)
-     {
-        DATA32 a, b;
-
-        a = RGB_565_UNPACK(src);
-        b = RGB_565_UNPACK(*p_dst);
-        b = RGB_565_UNPACKED_BLEND(a, b, alpha);
-        *p_dst = RGB_565_PACK(b);
-     }
-}
-
-EFL_ALWAYS_INLINE void
-_soft16_pt_blend_solid_solid(DATA16 *p_dst, DATA16 src)
-{
-   *p_dst = src;
-}
-
-/***********************************************************************
- * Blend operations taking an extra alpha (fade in, out)
- */
-
-EFL_ALWAYS_INLINE void
-_soft16_pt_blend_transp_solid_mul_alpha(DATA16 *p_dst, DATA16 src, DATA8 alpha, DATA8 rel_alpha)
-{
-   DATA32 a, b;
-
-   alpha = (alpha * rel_alpha) >> 5;
-   if (alpha == 0)
-     return;
-
-   alpha++;
-
-   a = ((RGB_565_UNPACK(src) * rel_alpha) >> 5) & RGB_565_UNPACKED_MASK;
-   b = RGB_565_UNPACK(*p_dst);
-   b = RGB_565_UNPACKED_BLEND(a, b, alpha);
-   *p_dst = RGB_565_PACK(b);
-}
-
-EFL_ALWAYS_INLINE void
-_soft16_pt_blend_solid_solid_mul_alpha(DATA16 *p_dst, DATA16 src, DATA8 rel_alpha)
-{
-   DATA32 a, b;
-   a = RGB_565_UNPACK(src);
-   b = RGB_565_UNPACK(*p_dst);
-   b = RGB_565_UNPACKED_BLEND_UNMUL(a, b, rel_alpha);
-   *p_dst = RGB_565_PACK(b);
-}
-
-/***********************************************************************
- * Blend operations with extra alpha and multiply color
- */
-
-EFL_ALWAYS_INLINE void
-_soft16_pt_blend_transp_solid_mul_color_transp(DATA16 *p_dst, DATA16 src, DATA8 alpha, DATA8 rel_alpha, DATA16 r, DATA16 g, DATA16 b)
-{
-   DATA32 rgb, d;
-   int r1, g1, b1;
-
-   alpha = (alpha * rel_alpha) >> 5;
-   if (alpha == 0)
-     return;
-
-   alpha++;
-
-   r1 = ((((src) >> 11) & 0x1f) * r) >> 5;
-   g1 = ((((src) >> 5) & 0x3f) * g) >> 6;
-   b1 = (((src) & 0x1f) * b) >> 5;
-   rgb = ((r1 << 11) | (g1 << 21) | b1) & RGB_565_UNPACKED_MASK;
-   d = RGB_565_UNPACK(*p_dst);
-   d = RGB_565_UNPACKED_BLEND(rgb, d, alpha);
-
-   *p_dst = RGB_565_PACK(d);
-}
-
-EFL_ALWAYS_INLINE void
-_soft16_pt_blend_solid_solid_mul_color_transp(DATA16 *p_dst, DATA16 src, DATA8 rel_alpha, DATA16 r, DATA16 g, DATA16 b)
-{
-   int r1, g1, b1;
-   DATA32 rgb, d;
-
-   r1 = ((((src) >> 11) & 0x1f) * r) >> 5;
-   g1 = ((((src) >> 5) & 0x3f) * g) >> 6;
-   b1 = (((src) & 0x1f) * b) >> 5;
-
-   rgb = ((r1 << 11) | (g1 << 21) | b1) & RGB_565_UNPACKED_MASK;
-   d = RGB_565_UNPACK(*p_dst);
-   d = RGB_565_UNPACKED_BLEND(rgb, d, rel_alpha);
-   *p_dst = RGB_565_PACK(d);
-}
-
-/***********************************************************************
- * Blend operations with extra multiply color
- */
-
-EFL_ALWAYS_INLINE void
-_soft16_pt_blend_transp_solid_mul_color_solid(DATA16 *p_dst, DATA16 src, DATA8 alpha, DATA8 r, DATA8 g, DATA8 b)
-{
-   int r1, g1, b1;
-
-   if (alpha == 0) return;
-
-   r1 = ((((src >> 11) & 0x1f) * r) >> 5) & 0x1f;
-   g1 = ((((src >> 5) & 0x3f) * g) >> 6) & 0x3f;
-   b1 = (((src & 0x1f) * b) >> 5) & 0x1f;
-
-   if (alpha == 31) *p_dst = (r1 << 11) | (g1 << 5) | b1;
-   else
-     {
-        DATA32 rgb_unpack, d;
-
-        rgb_unpack = ((r1 << 11) | (g1 << 21) | b1) & RGB_565_UNPACKED_MASK;
-        d = RGB_565_UNPACK(*p_dst);
-        d = RGB_565_UNPACKED_BLEND(rgb_unpack, d, alpha);
-        *p_dst = RGB_565_PACK(d);
-     }
-}
-
-EFL_ALWAYS_INLINE void
-_soft16_pt_blend_solid_solid_mul_color_solid(DATA16 *p_dst, DATA16 src, DATA16 r, DATA16 g, DATA16 b)
-{
-   int r1, g1, b1;
-
-   r1 = ((((src >> 11) & 0x1f) * r) >> 5) & 0x1f;
-   g1 = ((((src >> 5) & 0x3f) * g) >> 6) & 0x3f;
-   b1 = (((src & 0x1f) * b) >> 5) & 0x1f;
-
-   *p_dst = (r1 << 11) | (g1 << 5) | b1;
-}
diff --git a/src/lib/engines/common_16/evas_soft16_polygon.c b/src/lib/engines/common_16/evas_soft16_polygon.c
deleted file mode 100644 (file)
index ca18bef..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-#include <math.h>
-#include <evas_common_soft16.h>
-#include "evas_soft16_scanline_fill.c"
-
-typedef struct _RGBA_Edge RGBA_Edge;
-typedef struct _RGBA_Vertex RGBA_Vertex;
-
-struct _RGBA_Edge
-{
-   float x, dx;
-   int i;
-};
-
-struct _RGBA_Vertex
-{
-   float x, y;
-   int i;
-};
-
-#define POLY_EDGE_DEL(_i)                                               \
-{                                                                       \
-   int _j;                                                              \
-                                                                        \
-   for (_j = 0; (_j < num_active_edges) && (edges[_j].i != _i); _j++);  \
-   if (_j < num_active_edges)                                           \
-     {                                                                  \
-       num_active_edges--;                                             \
-       memmove(&(edges[_j]), &(edges[_j + 1]),                         \
-               (num_active_edges - _j) * sizeof(RGBA_Edge));           \
-     }                                                                  \
-}
-
-#define POLY_EDGE_ADD(_i, _y)                                           \
-{                                                                       \
-   int _j;                                                              \
-   float _dx;                                                           \
-   RGBA_Vertex *_p, *_q;                                                \
-   if (_i < (n - 1)) _j = _i + 1;                                       \
-   else _j = 0;                                                         \
-   if (point[_i].y < point[_j].y)                                       \
-     {                                                                  \
-       _p = &(point[_i]);                                              \
-       _q = &(point[_j]);                                              \
-     }                                                                  \
-   else                                                                 \
-     {                                                                  \
-       _p = &(point[_j]);                                              \
-       _q = &(point[_i]);                                              \
-     }                                                                  \
-   edges[num_active_edges].dx = _dx = (_q->x - _p->x) / (_q->y - _p->y); \
-   edges[num_active_edges].x = (_dx * ((float)_y + 0.5 - _p->y)) + _p->x; \
-   edges[num_active_edges].i = _i;                                      \
-   num_active_edges++;                                                  \
-}
-
-static int
-polygon_point_sorter(const void *a, const void *b)
-{
-   RGBA_Vertex *p, *q;
-
-   p = (RGBA_Vertex *)a;
-   q = (RGBA_Vertex *)b;
-   if (p->y <= q->y) return -1;
-   return 1;
-}
-
-static int
-polygon_edge_sorter(const void *a, const void *b)
-{
-   RGBA_Edge *p, *q;
-
-   p = (RGBA_Edge *)a;
-   q = (RGBA_Edge *)b;
-   if (p->x <= q->x) return -1;
-   return 1;
-}
-
-void
-evas_common_soft16_polygon_draw(Soft16_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points, int x, int y)
-{
-   RGBA_Polygon_Point *pt;
-   RGBA_Vertex       *point;
-   RGBA_Edge         *edges;
-   int                num_active_edges;
-   int                n;
-   int                i, j, k;
-   int                y0, y1, yi;
-   int                ext_x, ext_y, ext_w, ext_h;
-   int               *sorted_index;
-   DATA8 alpha;
-   DATA16 rgb565;
-   DATA32 rgb565_unpack;
-
-   alpha = A_VAL(&dc->col.col) >> 3;
-   if (alpha == 0)
-     return;
-   alpha++;
-
-   rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
-                                   G_VAL(&dc->col.col),
-                                   B_VAL(&dc->col.col));
-   rgb565_unpack = RGB_565_UNPACK(rgb565);
-
-   ext_x = 0;
-   ext_y = 0;
-   ext_w = dst->cache_entry.w;
-   ext_h = dst->cache_entry.h;
-   if (dc->clip.use)
-     RECTS_CLIP_TO_RECT(ext_x, ext_y, ext_w, ext_h,
-                       dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
-
-   if ((ext_w <= 0) || (ext_h <= 0))
-     return;
-
-   n = 0;
-   EINA_INLIST_FOREACH(points, pt) n++;
-
-   if (n < 3)
-     return;
-
-   edges = malloc(sizeof(RGBA_Edge) * n);
-   if (!edges)
-     return;
-
-   point = malloc(sizeof(RGBA_Vertex) * n);
-   if (!point)
-     {
-       free(edges);
-       return;
-     }
-
-   sorted_index = malloc(sizeof(int) * n);
-   if (!sorted_index)
-     {
-       free(edges);
-       free(point);
-       return;
-     }
-
-   k = 0;
-   EINA_INLIST_FOREACH(points, pt)
-     {
-       point[k].x = pt->x + x;
-       point[k].y = pt->y + y;
-       point[k].i = k;
-       k++;
-     }
-   qsort(point, n, sizeof(RGBA_Vertex), polygon_point_sorter);
-
-   for (k = 0; k < n; k++)
-     sorted_index[k] = point[k].i;
-
-   k = 0;
-   EINA_INLIST_FOREACH(points, pt)
-     {
-       point[k].x = pt->x + x;
-       point[k].y = pt->y + y;
-       point[k].i = k;
-       k++;
-     }
-
-   y0 = MAX(ext_y, ceil(point[sorted_index[0]].y - 0.5));
-   y1 = MIN(ext_y + ext_h - 1, floor(point[sorted_index[n - 1]].y - 0.5));
-
-   k = 0;
-   num_active_edges = 0;
-
-   for (yi = y0; yi <= y1; yi++)
-     {
-       for (; (k < n) && (point[sorted_index[k]].y <= ((float)yi + 0.5)); k++)
-         {
-            i = sorted_index[k];
-
-            if (i > 0) j = i - 1;
-            else j = n - 1;
-            if (point[j].y <= ((float)yi - 0.5))
-              {
-                 POLY_EDGE_DEL(j)
-              }
-            else if (point[j].y > ((float)yi + 0.5))
-              {
-                 POLY_EDGE_ADD(j, yi)
-              }
-            if (i < (n - 1)) j = i + 1;
-            else j = 0;
-            if (point[j].y <= ((float)yi - 0.5))
-              {
-                 POLY_EDGE_DEL(i)
-              }
-            else if (point[j].y > ((float)yi + 0.5))
-              {
-                 POLY_EDGE_ADD(i, yi)
-              }
-         }
-
-       qsort(edges, num_active_edges, sizeof(RGBA_Edge), polygon_edge_sorter);
-
-       for (j = 0; j < num_active_edges; j += 2)
-         {
-            int x0, x1;
-
-            x0 = ceil(edges[j].x - 0.5);
-            if (j < (num_active_edges - 1))
-              x1 = floor(edges[j + 1].x - 0.5);
-            else
-              x1 = x0;
-            if ((x1 >= ext_x) && (x0 < (ext_x + ext_w)) && (x0 <= x1))
-              {
-                 DATA16 *dst_itr;
-                 int w;
-
-                 if (x0 < ext_x) x0 = ext_x;
-                 if (x1 >= (ext_x + ext_w)) x1 = ext_x + ext_w - 1;
-
-                 w = (x1 - x0) + 1;
-                 dst_itr = dst->pixels + (yi * dst->stride) + x0;
-
-                 if (alpha == 32)
-                   _soft16_scanline_fill_solid_solid(dst_itr, w, rgb565);
-                 else
-                   _soft16_scanline_fill_transp_solid(dst_itr, w, rgb565_unpack, alpha);
-              }
-            edges[j].x += edges[j].dx;
-            edges[j + 1].x += edges[j + 1].dx;
-         }
-     }
-
-   free(edges);
-   free(point);
-   free(sorted_index);
-}
diff --git a/src/lib/engines/common_16/evas_soft16_rectangle.c b/src/lib/engines/common_16/evas_soft16_rectangle.c
deleted file mode 100644 (file)
index ac6aa46..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-#include "evas_common_soft16.h"
-#include "evas_soft16_scanline_fill.c"
-
-static inline int
-_is_empty_rectangle(const Eina_Rectangle *r)
-{
-   return (r->w < 1) || (r->h < 1);
-}
-
-static inline void
-_soft16_rectangle_draw_solid_solid(Soft16_Image *dst, int offset, int w, int h,
-                                  DATA16 rgb565)
-{
-   DATA16 *dst_itr;
-   int i;
-
-   dst_itr = dst->pixels + offset;
-
-   for (i = 0; i < h; i++, dst_itr += dst->stride)
-      _soft16_scanline_fill_solid_solid(dst_itr, w, rgb565);
-}
-
-static inline void
-_soft16_rectangle_draw_transp_solid(Soft16_Image *dst, int offset, int w, int h,
-                                   DATA16 rgb565, DATA8 alpha)
-{
-   DATA16 *dst_itr;
-   DATA32 rgb565_unpack;
-   int i;
-
-   dst_itr = dst->pixels + offset;
-   rgb565_unpack = RGB_565_UNPACK(rgb565);
-   alpha++;
-
-   for (i = 0; i < h; i++, dst_itr += dst->stride)
-     _soft16_scanline_fill_transp_solid(dst_itr, w, rgb565_unpack, alpha);
-}
-
-static void
-_soft16_rectangle_draw_int(Soft16_Image *dst, RGBA_Draw_Context *dc,
-                           Eina_Rectangle dr)
-{
-   int dst_offset;
-
-   if (_is_empty_rectangle(&dr)) return;
-   RECTS_CLIP_TO_RECT(dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
-   if (_is_empty_rectangle(&dr)) return;
-
-   if (dc->clip.use)
-      RECTS_CLIP_TO_RECT(dr.x, dr.y, dr.w, dr.h, dc->clip.x,
-                         dc->clip.y, dc->clip.w, dc->clip.h);
-   if (_is_empty_rectangle(&dr)) return;
-   if (A_VAL(&dc->col.col) == 0) return;
-
-   dst_offset = dr.x + (dr.y * dst->cache_entry.w);
-
-   if (!dst->cache_entry.flags.alpha)
-      {
-        DATA16 rgb565;
-        DATA8 alpha;
-
-        alpha = A_VAL(&dc->col.col) >> 3;
-        rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
-                                         G_VAL(&dc->col.col),
-                                         B_VAL(&dc->col.col));
-         if (alpha == 31)
-          _soft16_rectangle_draw_solid_solid
-            (dst, dst_offset, dr.w, dr.h, rgb565);
-         else if (alpha > 0)
-          _soft16_rectangle_draw_transp_solid
-            (dst, dst_offset, dr.w, dr.h, rgb565, alpha);
-      }
-   else
-     ERR("Unsupported feature: drawing rectangle to non-opaque destination.");
-}
-
-void
-evas_common_soft16_rectangle_draw(Soft16_Image *dst, RGBA_Draw_Context *dc,
-                      int x, int y, int w, int h)
-{
-   static Cutout_Rects *rects = NULL;
-   Eina_Rectangle dr;
-   Cutout_Rect  *r;
-   struct RGBA_Draw_Context_clip c_bkp;
-   int i;
-
-   /* handle cutouts here! */
-   EINA_RECTANGLE_SET(&dr, x, y, w, h);
-
-   if (_is_empty_rectangle(&dr)) return;
-   if (!(RECTS_INTERSECT(dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
-     return;
-
-   /* no cutouts - cut right to the chase */
-   if (!dc->cutout.rects)
-     {
-        _soft16_rectangle_draw_int(dst, dc, dr);
-       return;
-     }
-
-   c_bkp = dc->clip;
-
-   evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
-   evas_common_draw_context_clip_clip(dc, x, y, w, h);
-   /* our clip is 0 size.. abort */
-   if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
-     {
-       dc->clip = c_bkp;
-       return;
-     }
-   rects = evas_common_draw_context_apply_cutouts(dc, rects);
-   for (i = 0; i < rects->active; ++i)
-     {
-       r = rects->rects + i;
-       evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
-        _soft16_rectangle_draw_int(dst, dc, dr);
-     }
-   dc->clip = c_bkp;
-}
-
diff --git a/src/lib/engines/common_16/evas_soft16_scanline_blend.c b/src/lib/engines/common_16/evas_soft16_scanline_blend.c
deleted file mode 100644 (file)
index c89eeaa..0000000
+++ /dev/null
@@ -1,353 +0,0 @@
-/** NOTE: This file is meant to be included by users **/
-
-/** NOTE2: r, g, b parameters are 16bits, so you can pass 0 to 256 inclusive.
- **        this is due our division by 256 when multiplying the color.
- **/
-
-/*****************************************************************************
- * Scanline processing
- *
- *    _soft16_scanline_<description>_<src>_<dst>[_<modifier>]()
- *
- ****************************************************************************/
-
-#include "evas_soft16_point_blend.c"
-
-/***********************************************************************
- * Regular blend operations
- */
-static void
-_soft16_scanline_blend_transp_solid(DATA16 *src, DATA8 *alpha, DATA16 *dst, int size)
-{
-   DATA16 *start, *end;
-
-   start = dst;
-   end = start + (size & ~7);
-
-   pld(alpha, 0);
-   pld(src, 0);
-
-   /* work on 8 pixels per time, do data preload */
-   while (start < end)
-     {
-       DATA8 alpha1, alpha2;
-
-       alpha1 = alpha[0];
-       alpha += 8;
-
-       /* empirical tests show these give the best performance */
-       pld(alpha, 8);
-       pld(src, 32);
-
-       src += 8;
-       start += 8;
-
-       alpha2 = alpha[-7];
-        _soft16_pt_blend_transp_solid(start - 8, src[-8], alpha1);
-
-       alpha1 = alpha[-6];
-        _soft16_pt_blend_transp_solid(start - 7, src[-7], alpha2);
-
-       alpha2 = alpha[-5];
-       _soft16_pt_blend_transp_solid(start - 6, src[-6], alpha1);
-
-       alpha1 = alpha[-4];
-       _soft16_pt_blend_transp_solid(start - 5, src[-5], alpha2);
-
-       alpha2 = alpha[-3];
-       _soft16_pt_blend_transp_solid(start - 4, src[-4], alpha1);
-
-       alpha1 = alpha[-2];
-       _soft16_pt_blend_transp_solid(start - 3, src[-3], alpha2);
-
-       alpha2 = alpha[-1];
-       _soft16_pt_blend_transp_solid(start - 2, src[-2], alpha1);
-
-       _soft16_pt_blend_transp_solid(start - 1, src[-1], alpha2);
-     }
-
-   /* remaining pixels (up to 7) */
-   end = start + (size & 7);
-   for (; start < end; start++, src++, alpha++)
-      _soft16_pt_blend_transp_solid(start, *src, *alpha);
-}
-
-static inline void
-_soft16_scanline_blend_solid_solid(DATA16 *src, DATA16 *dst, int size)
-{
-   memcpy(dst, src, size * sizeof(DATA16));
-}
-
-/***********************************************************************
- * Blend operations taking an extra alpha (fade in, out)
- */
-
-static void
-_soft16_scanline_blend_transp_solid_mul_alpha(DATA16 *src, DATA8 *alpha, DATA16 *dst, int size, const DATA8 rel_alpha)
-{
-   DATA16 *start, *end;
-
-   start = dst;
-   end = start + (size & ~7);
-
-   pld(alpha, 0);
-   pld(src, 0);
-
-   while (start < end)
-     {
-       DATA8 alpha1, alpha2;
-
-       alpha1 = alpha[0];
-       alpha += 8;
-
-       pld(alpha, 8);
-       pld(src, 32);
-
-       src += 8;
-       start += 8;
-
-       alpha2 = alpha[-7];
-       _soft16_pt_blend_transp_solid_mul_alpha
-           (start - 8, src[-8], alpha1, rel_alpha);
-
-       alpha1 = alpha[-6];
-       _soft16_pt_blend_transp_solid_mul_alpha
-           (start - 7, src[-7], alpha2, rel_alpha);
-
-       alpha2 = alpha[-5];
-       _soft16_pt_blend_transp_solid_mul_alpha
-           (start - 6, src[-6], alpha1, rel_alpha);
-
-       alpha1 = alpha[-4];
-       _soft16_pt_blend_transp_solid_mul_alpha
-           (start - 5, src[-5], alpha2, rel_alpha);
-
-       alpha2 = alpha[-3];
-       _soft16_pt_blend_transp_solid_mul_alpha
-           (start - 4, src[-4], alpha1, rel_alpha);
-
-       alpha1 = alpha[-2];
-       _soft16_pt_blend_transp_solid_mul_alpha
-           (start - 3, src[-3], alpha2, rel_alpha);
-
-       alpha2 = alpha[-1];
-       _soft16_pt_blend_transp_solid_mul_alpha
-           (start - 2, src[-2], alpha1, rel_alpha);
-
-       _soft16_pt_blend_transp_solid_mul_alpha
-           (start - 1, src[-1], alpha2, rel_alpha);
-     }
-
-   end = start + (size & 7);
-   for (; start < end; start++, src++, alpha++)
-      _soft16_pt_blend_transp_solid_mul_alpha(start, *src, *alpha, rel_alpha);
-}
-
-static void
-_soft16_scanline_blend_solid_solid_mul_alpha(DATA16 *src, DATA16 *dst, int size, DATA8 rel_alpha)
-{
-   DATA16 *start, *end;
-
-   start = dst;
-   end = start + (size & ~7);
-
-   pld(src, 0);
-
-   while (start < end)
-     {
-       pld(src, 32);
-        UNROLL8({
-           _soft16_pt_blend_solid_solid_mul_alpha(start, *src, rel_alpha);
-           start++;
-           src++;
-        });
-     }
-
-   end = start + (size & 7);
-   for (; start < end; start++, src++)
-     _soft16_pt_blend_solid_solid_mul_alpha(start, *src, rel_alpha);
-}
-
-/***********************************************************************
- * Blend operations with extra alpha and multiply color
- */
-
-static void
-_soft16_scanline_blend_transp_solid_mul_color_transp(DATA16 *src, DATA8 *alpha, DATA16 *dst, int size, DATA8 rel_alpha, DATA16 r, DATA16 g, DATA16 b)
-{
-   DATA16 *start, *end;
-
-   start = dst;
-   end = start + (size & ~7);
-
-   pld(alpha, 0);
-   pld(src, 0);
-
-   while (start < end)
-     {
-       DATA8 alpha1, alpha2;
-
-       alpha1 = alpha[0];
-       alpha += 8;
-
-        pld(src, 32);
-        pld(start, 32);
-
-       src += 8;
-       start += 8;
-
-       alpha2 = alpha[-7];
-        _soft16_pt_blend_transp_solid_mul_color_transp
-           (start - 8, src[-8], alpha1, rel_alpha, r, g, b);
-
-       alpha1 = alpha[-6];
-        _soft16_pt_blend_transp_solid_mul_color_transp
-           (start - 7, src[-7], alpha2, rel_alpha, r, g, b);
-
-       alpha2 = alpha[-5];
-        _soft16_pt_blend_transp_solid_mul_color_transp
-           (start - 6, src[-6], alpha1, rel_alpha, r, g, b);
-
-       alpha1 = alpha[-4];
-        _soft16_pt_blend_transp_solid_mul_color_transp
-           (start - 5, src[-5], alpha2, rel_alpha, r, g, b);
-
-       alpha2 = alpha[-3];
-        _soft16_pt_blend_transp_solid_mul_color_transp
-           (start - 4, src[-4], alpha1, rel_alpha, r, g, b);
-
-       alpha1 = alpha[-2];
-        _soft16_pt_blend_transp_solid_mul_color_transp
-           (start - 3, src[-3], alpha2, rel_alpha, r, g, b);
-
-       alpha2 = alpha[-1];
-        _soft16_pt_blend_transp_solid_mul_color_transp
-           (start - 2, src[-2], alpha1, rel_alpha, r, g, b);
-
-        _soft16_pt_blend_transp_solid_mul_color_transp
-           (start - 1, src[-1], alpha2, rel_alpha, r, g, b);
-     }
-
-   end = start + (size & 7);
-   for (; start < end; start++, src++, alpha++)
-      _soft16_pt_blend_transp_solid_mul_color_transp
-         (start, *src, *alpha, rel_alpha, r, g, b);
-}
-
-static void
-_soft16_scanline_blend_solid_solid_mul_color_transp(DATA16 *src, DATA16 *dst, int size, DATA8 rel_alpha, DATA16 r, DATA16 g, DATA16 b)
-{
-   DATA16 *start, *end;
-
-   start = dst;
-   end = start + (size & ~7);
-
-   pld(src, 0);
-
-   while (start < end)
-     {
-       pld(src, 32);
-        UNROLL8({
-           _soft16_pt_blend_solid_solid_mul_color_transp
-              (start, *src, rel_alpha, r, g, b);
-           start++;
-           src++;
-        });
-     }
-
-   end = start + (size & 7);
-   for (; start < end; start++, src++)
-      _soft16_pt_blend_solid_solid_mul_color_transp
-         (start, *src, rel_alpha, r, g, b);
-}
-
-/***********************************************************************
- * Blend operations with extra multiply color
- */
-
-static void
-_soft16_scanline_blend_transp_solid_mul_color_solid(DATA16 *src, DATA8 *alpha, DATA16 *dst, int size, DATA16 r, DATA16 g, DATA16 b)
-{
-   DATA16 *start, *end;
-
-   start = dst;
-   end = start + (size & ~7);
-
-   pld(alpha, 0);
-   pld(src, 0);
-
-   while (start < end)
-     {
-       DATA8 alpha1, alpha2;
-
-       alpha1 = alpha[0];
-       alpha += 8;
-
-       pld(alpha, 8);
-       pld(src, 32);
-
-       src += 8;
-       start += 8;
-
-       alpha2 = alpha[-7];
-        _soft16_pt_blend_transp_solid_mul_color_solid
-           (start - 8, src[-8], alpha1, r, g, b);
-
-       alpha1 = alpha[-6];
-        _soft16_pt_blend_transp_solid_mul_color_solid
-           (start - 7, src[-7], alpha2, r, g, b);
-
-       alpha2 = alpha[-5];
-        _soft16_pt_blend_transp_solid_mul_color_solid
-           (start - 6, src[-6], alpha1, r, g, b);
-
-       alpha1 = alpha[-4];
-        _soft16_pt_blend_transp_solid_mul_color_solid
-           (start - 5, src[-5], alpha2, r, g, b);
-
-       alpha2 = alpha[-3];
-        _soft16_pt_blend_transp_solid_mul_color_solid
-           (start - 4, src[-4], alpha1, r, g, b);
-
-       alpha1 = alpha[-2];
-        _soft16_pt_blend_transp_solid_mul_color_solid
-           (start - 3, src[-3], alpha2, r, g, b);
-
-       alpha2 = alpha[-1];
-        _soft16_pt_blend_transp_solid_mul_color_solid
-           (start - 2, src[-2], alpha1, r, g, b);
-
-        _soft16_pt_blend_transp_solid_mul_color_solid
-           (start - 1, src[-1], alpha2, r, g, b);
-     }
-
-   end = start + (size & 7);
-   for (; start < end; start++, src++, alpha++)
-     _soft16_pt_blend_transp_solid_mul_color_solid
-        (start, *src, *alpha, r, g, b);
-}
-
-static void
-_soft16_scanline_blend_solid_solid_mul_color_solid(DATA16 *src, DATA16 *dst, int size, DATA8 r, DATA8 g, DATA8 b)
-{
-   DATA16 *start, *end;
-
-   start = dst;
-   end = start + (size & ~7);
-
-   pld(src, 0);
-
-   while (start < end)
-     {
-       pld(src, 32);
-        UNROLL8({
-           _soft16_pt_blend_solid_solid_mul_color_solid(start, *src, r, g, b);
-           start++;
-           src++;
-        });
-     }
-
-   end = start + (size & 7);
-   for (; start < end; start++, src++)
-     _soft16_pt_blend_solid_solid_mul_color_solid(start, *src, r, g, b);
-}
diff --git a/src/lib/engines/common_16/evas_soft16_scanline_fill.c b/src/lib/engines/common_16/evas_soft16_scanline_fill.c
deleted file mode 100644 (file)
index d31bef8..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/** NOTE: This file is meant to be included by users **/
-
-/*****************************************************************************
- * Point processing
- *
- *    _soft16_pt_<description>_<src>_<dst>[_<modifier>]()
- *
- * Scanline processing
- *
- *    _soft16_scanline_<description>_<src>_<dst>[_<modifier>]()
- *
- ****************************************************************************/
-EFL_ALWAYS_INLINE void
-_soft16_pt_fill_solid_solid(DATA16 *dst, DATA16 rgb565)
-{
-   *dst = rgb565;
-}
-
-static void
-_soft16_scanline_fill_solid_solid(DATA16 *dst, int size, DATA16 rgb565)
-{
-   DATA16 *start, *end;
-   DATA32 rgb565_double;
-
-   start = dst;
-
-   if ((long)start & 0x2)
-     {
-       *start = rgb565;
-       start++;
-       size--;
-     }
-
-   end = start + (size & ~7);
-
-   rgb565_double = (rgb565 << 16) | rgb565;
-
-   while (start < end)
-     {
-        DATA32 *p = (DATA32 *)start;
-
-        p[0] = rgb565_double;
-        p[1] = rgb565_double;
-        p[2] = rgb565_double;
-        p[3] = rgb565_double;
-
-        start += 8;
-     }
-
-   end = start + (size & 7);
-   for (; start < end; start++)
-      *start = rgb565;
-}
-
-EFL_ALWAYS_INLINE void
-_soft16_pt_fill_transp_solid(DATA16 *dst, DATA32 rgb565_unpack, DATA8 alpha)
-{
-   DATA32 d;
-
-   d = RGB_565_UNPACK(*dst);
-   d = RGB_565_UNPACKED_BLEND(rgb565_unpack, d, alpha);
-   *dst = RGB_565_PACK(d);
-}
-
-static void
-_soft16_scanline_fill_transp_solid(DATA16 *dst, int size, DATA32 rgb565_unpack, DATA8 alpha)
-{
-   DATA16 *start, *end;
-
-   start = dst;
-   pld(start, 0);
-   end = start + (size & ~7);
-
-   while (start < end)
-     {
-        pld(start, 32);
-        UNROLL8({
-           _soft16_pt_fill_transp_solid(start, rgb565_unpack, alpha);
-           start++;
-        });
-     }
-
-   end = start + (size & 7);
-   for (; start < end; start++)
-     _soft16_pt_fill_transp_solid(start, rgb565_unpack, alpha);
-}
index 58a1b1f..95a48ae 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @VALGRIND_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @EET_CFLAGS@ \
 @pthread_cflags@
 
index c1c8b66..97970f4 100644 (file)
@@ -9,7 +9,7 @@ AM_CPPFLAGS = \
 -DPACKAGE_LIB_DIR=\"$(libdir)\" \
 -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
 @FREETYPE_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @EVIL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @PIXMAN_CFLAGS@
@@ -21,5 +21,5 @@ evas_module.c \
 evas_module.h \
 evas_path.h
 
-libevas_file_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@
+libevas_file_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@
 
old mode 100644 (file)
new mode 100755 (executable)
index ffef61e..f919b0e
@@ -42,7 +42,7 @@ _evas_module_append(Eina_List *list, char *path)
 void
 evas_module_paths_init(void)
 {
-   char *path;
+   char *libdir, *path;
 
    /* 1. ~/.evas/modules/ */
    path = eina_module_environment_path_get("HOME", "/.evas/modules");
@@ -56,13 +56,24 @@ evas_module_paths_init(void)
      evas_module_paths = _evas_module_append(evas_module_paths, path);
 
    /* 3. libevas.so/../evas/modules/ */
-   path = eina_module_symbol_path_get(evas_module_paths_init, "/evas/modules");
+   libdir = (char *)_evas_module_libdir_get();
+   if (!libdir)
+     path = eina_module_symbol_path_get(evas_module_paths_init, "/evas/modules");
+   else
+     {
+        path = malloc(strlen(libdir) + strlen("/evas/modules") + 1);
+        if (path)
+          {
+             strcpy(path, libdir);
+             strcat(path, "/evas/modules");
+          }
+     }
    if (eina_list_search_unsorted(evas_module_paths, (Eina_Compare_Cb) strcmp, path))
      free(path);
    else
      evas_module_paths = _evas_module_append(evas_module_paths, path);
 
-   /* 4. PREFIX/evas/modules/ */
+   /* 4. PREFIX/lib/evas/modules/ */
 #ifndef _MSC_VER
    path = PACKAGE_LIB_DIR "/evas/modules";
    if (!eina_list_search_unsorted(evas_module_paths, (Eina_Compare_Cb) strcmp, path))
@@ -88,10 +99,6 @@ EVAS_EINA_STATIC_MODULE_DEFINE(engine, fb);
 EVAS_EINA_STATIC_MODULE_DEFINE(engine, gl_x11);
 EVAS_EINA_STATIC_MODULE_DEFINE(engine, gl_sdl);
 EVAS_EINA_STATIC_MODULE_DEFINE(engine, psl1ght);
-EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16);
-EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16_sdl);
-EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16_wince);
-EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16_x11);
 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_8);
 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_8_x11);
 EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_ddraw);
@@ -112,12 +119,16 @@ EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, svg);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, tga);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, tiff);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, wbmp);
+EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, webp);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, xpm);
+EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, tgv);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, edb);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, eet);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, jpeg);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, png);
 EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, tiff);
+EVAS_EINA_STATIC_MODULE_DEFINE(image_saver, tgv);
+
 
 static const struct {
    Eina_Bool (*init)(void);
@@ -144,18 +155,6 @@ static const struct {
 #ifdef EVAS_STATIC_BUILD_PSL1GHT
   EVAS_EINA_STATIC_MODULE_USE(engine, psl1ght),
 #endif
-#ifdef EVAS_STATIC_BUILD_SOFTWARE_16
-  EVAS_EINA_STATIC_MODULE_USE(engine, software_16),
-#endif
-#ifdef EVAS_STATIC_BUILD_SOFTWARE_16_SDL
-  EVAS_EINA_STATIC_MODULE_USE(engine, software_16_sdl),
-#endif
-#ifdef EVAS_STATIC_BUILD_SOFTWARE_16_WINCE
-  EVAS_EINA_STATIC_MODULE_USE(engine, software_16_wince),
-#endif
-#ifdef EVAS_STATIC_BUILD_SOFTWARE_16_X11
-  EVAS_EINA_STATIC_MODULE_USE(engine, software_16_x11),
-#endif
 #ifdef EVAS_STATIC_BUILD_SOFTWARE_GDI
   EVAS_EINA_STATIC_MODULE_USE(engine, software_gdi),
 #endif
@@ -222,9 +221,15 @@ static const struct {
 #ifdef EVAS_STATIC_BUILD_WBMP
   EVAS_EINA_STATIC_MODULE_USE(image_loader, wbmp),
 #endif
+#ifdef EVAS_STATIC_BUILD_WEBP
+  EVAS_EINA_STATIC_MODULE_USE(image_loader, webp),
+#endif
 #ifdef EVAS_STATIC_BUILD_XPM
   EVAS_EINA_STATIC_MODULE_USE(image_loader, xpm),
 #endif
+#ifdef EVAS_STATIC_BUILD_TGV
+  EVAS_EINA_STATIC_MODULE_USE(image_loader, tgv),
+#endif
 #ifdef EVAS_STATIC_BUILD_EDB
   EVAS_EINA_STATIC_MODULE_USE(image_saver, edb),
 #endif
@@ -240,6 +245,9 @@ static const struct {
 #ifdef EVAS_STATIC_BUILD_TIFF
   EVAS_EINA_STATIC_MODULE_USE(image_saver, tiff),
 #endif
+#ifdef EVAS_STATIC_BUILD_TGV
+  EVAS_EINA_STATIC_MODULE_USE(image_saver, tgv),
+#endif
   { NULL, NULL }
 };
 
@@ -282,8 +290,12 @@ evas_module_register(const Evas_Module_Api *module, Evas_Module_Type type)
 
    if (type == EVAS_MODULE_TYPE_ENGINE)
      {
-       eina_array_push(evas_engines, em);
-       em->id_engine = eina_array_count(evas_engines);
+        if (!eina_array_push(evas_engines, em))
+          {
+             free(em);
+             return EINA_FALSE;
+          }
+        em->id_engine = eina_array_count(evas_engines);
      }
 
    eina_hash_direct_add(evas_modules[type], module->name, em);
@@ -356,7 +368,7 @@ evas_module_unregister(const Evas_Module_Api *module, Evas_Module_Type type)
    if (!em || em->definition != module) return EINA_FALSE;
 
    if (type == EVAS_MODULE_TYPE_ENGINE)
-     eina_array_data_set(evas_engines, em->id_engine, NULL);
+     eina_array_data_set(evas_engines, em->id_engine - 1, NULL);
 
    eina_hash_del(evas_modules[type], module->name, em);
    free(em);
@@ -560,6 +572,8 @@ evas_module_clean(void)
 /*      } */
 }
 
+static Eina_Prefix *pfx = NULL;
+
 /* will dlclose all the modules loaded and free all the structs */
 void
 evas_module_shutdown(void)
@@ -588,6 +602,11 @@ evas_module_shutdown(void)
 
    eina_array_free(evas_engines);
    evas_engines = NULL;
+   if (pfx)
+     {
+        eina_prefix_free(pfx);
+        pfx = NULL;
+     }
 }
 
 EAPI int
@@ -610,13 +629,11 @@ _evas_module_engine_inherit(Evas_Func *funcs, char *name)
    return 0;
 }
 
-static Eina_Prefix *pfx = NULL;
-
 EAPI const char *
 _evas_module_libdir_get(void)
 {
    if (!pfx) pfx = eina_prefix_new
-      (NULL, _evas_module_libdir_get, "EVAS", "evas", NULL,
+      (NULL, _evas_module_libdir_get, "EVAS", "evas", "checkme",
        PACKAGE_BIN_DIR, PACKAGE_LIB_DIR, PACKAGE_DATA_DIR, PACKAGE_DATA_DIR);
    if (!pfx) return NULL;
    return eina_prefix_lib_get(pfx);
diff --git a/src/lib/filters/Makefile.am b/src/lib/filters/Makefile.am
new file mode 100644 (file)
index 0000000..df58dff
--- /dev/null
@@ -0,0 +1,45 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/lib/engines/common \
+-DPACKAGE_BIN_DIR=\"$(bindir)\" \
+-DPACKAGE_LIB_DIR=\"$(libdir)\" \
+-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
+@FREETYPE_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
+@EVIL_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
+@PIXMAN_CFLAGS@
+
+noinst_LTLIBRARIES      = libevas_filters.la
+libevas_filters_la_SOURCES  = \
+evas_filter_blend.c \
+evas_filter_blur.c \
+evas_filter_bump.c \
+evas_filter.c \
+evas_filter_curve.c \
+evas_filter_displace.c \
+evas_filter_mask.c \
+evas_filter_parser.c \
+evas_filter_transform.c \
+evas_filter_utils.c \
+evas_filter_private.h
+
+EXTRA_DIST = \
+blur/blur_box_alpha_.c \
+blur/blur_box_alpha_i386.c \
+blur/blur_box_alpha_neon.c \
+blur/blur_box_alpha_sse3.c \
+blur/blur_box_rgba_.c \
+blur/blur_box_rgba_i386.c \
+blur/blur_box_rgba_neon.c \
+blur/blur_box_rgba_sse3.c \
+blur/blur_gaussian_alpha_.c \
+blur/blur_gaussian_rgba_.c
+
+libevas_filters_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@
+
diff --git a/src/lib/filters/blur/blur_box_alpha_.c b/src/lib/filters/blur/blur_box_alpha_.c
new file mode 100644 (file)
index 0000000..c1b8ec1
--- /dev/null
@@ -0,0 +1,248 @@
+/* @file blur_box_alpha_.c
+ * Defines the following functions:
+ * _box_blur_alpha_horiz_step
+ * _box_blur_alpha_vert_step
+ */
+
+#include "../evas_filter_private.h"
+
+static inline void
+_box_blur_alpha_horiz_step(const DATA8* restrict const srcdata,
+                           DATA8* restrict const dstdata,
+                           const int* restrict const radii,
+                           const int len,
+                           const int loops)
+{
+   const DATA8* restrict src;
+   DATA8* restrict dst;
+   DATA8* restrict span1;
+   DATA8* restrict span2;
+
+#if DIV_USING_BITSHIFT
+   int pow2_shifts[6] = {0};
+   int numerators[6] = {0};
+   for (int run = 0; radii[run]; run++)
+     {
+        const int div = radii[run] * 2 + 1;
+        pow2_shifts[run] = evas_filter_smallest_pow2_larger_than(div << 10);
+        numerators[run] = (1 << pow2_shifts[run]) / (div);
+     }
+#endif
+
+   span1 = alloca(len);
+   span2 = alloca(len);
+   memset(span1, 0, len);
+   memset(span2, 0, len);
+
+   // For each line, apply as many blurs as requested
+   for (int l = 0; l < loops; l++)
+     {
+        int run;
+
+        // New line: reset source & destination pointers
+        src = srcdata + len * l;
+        if (!radii[1]) // Only one run
+          dst = dstdata + len * l;
+        else
+          dst = span1;
+
+        // Apply blur with current radius
+        for (run = 0; radii[run]; run++)
+          {
+             const int radius = radii[run];
+             const int left = MIN(radius, len);
+
+#if DIV_USING_BITSHIFT
+             const int pow2 = pow2_shifts[run];
+             const int numerator = numerators[run];
+#else
+             const int divider = 2 * radius + 1;
+#endif
+
+             const DATA8* restrict sl = src;
+             const DATA8* restrict sr = src;
+             const DATA8* restrict sre = src + len;
+             const DATA8* restrict sle = src + len - radius;
+             DATA8* restrict d = dst;
+             int acc = 0, count = 0;
+
+             // Read-ahead & accumulate
+             for (int x = left; x > 0; x--)
+               {
+                  acc += *sr++;
+                  count++;
+               }
+
+             // Left edge
+             for (int x = left; x > 0; x--)
+               {
+                  if (sr < sre)
+                    {
+                       acc += *sr++;
+                       count++;
+                    }
+
+                  *d++ = acc / count;
+               }
+
+             // Middle part, normal blur
+             while (sr < sre)
+               {
+                  acc += *sr++;
+                  *d++ = DIVIDE(acc);
+                  acc -= *sl++;
+               }
+
+             // Right edge
+             count = 2 * radius + 1;
+             while (sl < sle)
+               {
+                  *d++ = acc / (--count);
+                  acc -= *sl++;
+               }
+
+             // More runs to go: swap spans
+             if (radii[run + 1])
+               {
+                  src = dst;
+                  if (radii[run + 2])
+                    {
+                       // Two more runs: swap
+                       DATA8* swap = span1;
+                       span1 = span2;
+                       span2 = swap;
+                       dst = span1;
+                    }
+                  else
+                    {
+                       // Last run: write directly to dstdata
+                       dst = dstdata + len * l;
+                    }
+               }
+          }
+     }
+}
+
+// ATTENTION: Make sure the below code's inner loop is the SAME as above.
+
+static inline void
+_box_blur_alpha_vert_step(const DATA8* restrict const srcdata,
+                          DATA8* restrict const dstdata,
+                          const int* restrict const radii,
+                          const int len,
+                          const int loops)
+{
+   /* Note: This function tries to optimize cache hits by working on
+    * contiguous horizontal spans.
+    */
+
+   const int step = loops;
+   DATA8* restrict src;
+   DATA8* restrict dst;
+   DATA8* restrict span1;
+   DATA8* restrict span2;
+
+#if DIV_USING_BITSHIFT
+   int pow2_shifts[6] = {0};
+   int numerators[6] = {0};
+   for (int run = 0; radii[run]; run++)
+     {
+        const int div = radii[run] * 2 + 1;
+        pow2_shifts[run] = evas_filter_smallest_pow2_larger_than(div << 10);
+        numerators[run] = (1 << pow2_shifts[run]) / (div);
+     }
+#endif
+
+   span1 = alloca(len);
+   span2 = alloca(len);
+
+   // For each line, apply as many blurs as requested
+   for (int l = 0; l < loops; l++)
+     {
+        int run;
+
+        // Rotate input into work span
+        const DATA8* srcptr = srcdata + l;
+        DATA8* s = span1;
+        for (int k = len; k; --k)
+          {
+             *s++ = *srcptr;
+             srcptr += step;
+          }
+
+        src = span1;
+        dst = span2;
+
+        // Apply blur with current radius
+        for (run = 0; radii[run]; run++)
+          {
+             const int radius = radii[run];
+             const int left = MIN(radius, len);
+
+#if DIV_USING_BITSHIFT
+             const int pow2 = pow2_shifts[run];
+             const int numerator = numerators[run];
+#else
+             const int divider = 2 * radius + 1;
+#endif
+
+             const DATA8* restrict sl = src;
+             const DATA8* restrict sr = src;
+             const DATA8* restrict sre = src + len;
+             const DATA8* restrict sle = src + len - radius;
+             DATA8* restrict d = dst;
+             int acc = 0, count = 0;
+
+             // Read-ahead & accumulate
+             for (int x = left; x > 0; x--)
+               {
+                  acc += *sr++;
+                  count++;
+               }
+
+             // Left edge
+             for (int x = left; x > 0; x--)
+               {
+                  if (sr < sre)
+                    {
+                       acc += *sr++;
+                       count++;
+                    }
+
+                  *d++ = acc / count;
+               }
+
+             // Middle part, normal blur
+             while (sr < sre)
+               {
+                  acc += *sr++;
+                  *d++ = DIVIDE(acc);
+                  acc -= *sl++;
+               }
+
+             // Right edge
+             count = 2 * radius + 1;
+             while (sl < sle)
+               {
+                  *d++ = acc / (--count);
+                  acc -= *sl++;
+               }
+
+             // More runs to go: swap spans
+             if (radii[run + 1])
+               {
+                  DATA8* swap = src;
+                  src = dst;
+                  dst = swap;
+               }
+          }
+
+        // Last run: rotate & copy back to destination
+        DATA8* restrict dstptr = dstdata + l;
+        for (int k = len; k; --k)
+          {
+             *dstptr = *dst++;
+             dstptr += step;
+          }
+     }
+}
diff --git a/src/lib/filters/blur/blur_box_alpha_i386.c b/src/lib/filters/blur/blur_box_alpha_i386.c
new file mode 100644 (file)
index 0000000..1664431
--- /dev/null
@@ -0,0 +1,25 @@
+#ifdef BUILD_MMX
+
+static inline void
+_box_blur_alpha_horiz_step_mmx(const DATA8* restrict const srcdata,
+                               DATA8* restrict const dstdata,
+                               const int* restrict const radii,
+                               const int len,
+                               const int loops)
+{
+   // TODO: implement optimized code here and remove the following line:
+   _box_blur_alpha_horiz_step(srcdata, dstdata, radii, len, loops);
+}
+
+static inline void
+_box_blur_alpha_vert_step_mmx(const DATA8* restrict const srcdata,
+                              DATA8* restrict const dstdata,
+                              const int* restrict const radii,
+                              const int len,
+                              const int loops)
+{
+   // TODO: implement optimized code here and remove the following line:
+   _box_blur_alpha_vert_step(srcdata, dstdata, radii, len, loops);
+}
+
+#endif
diff --git a/src/lib/filters/blur/blur_box_alpha_neon.c b/src/lib/filters/blur/blur_box_alpha_neon.c
new file mode 100644 (file)
index 0000000..b8d9524
--- /dev/null
@@ -0,0 +1,25 @@
+#ifdef BUILD_NEON
+
+static inline void
+_box_blur_alpha_horiz_step_neon(const DATA8* restrict const srcdata,
+                                DATA8* restrict const dstdata,
+                                const int* restrict const radii,
+                                const int len,
+                                const int loops)
+{
+   // TODO: implement optimized code here and remove the following line:
+   _box_blur_alpha_horiz_step(srcdata, dstdata, radii, len, loops);
+}
+
+static inline void
+_box_blur_alpha_vert_step_neon(const DATA8* restrict const srcdata,
+                               DATA8* restrict const dstdata,
+                               const int* restrict const radii,
+                               const int len,
+                               const int loops)
+{
+   // TODO: implement optimized code here and remove the following line:
+   _box_blur_alpha_vert_step(srcdata, dstdata, radii, len, loops);
+}
+
+#endif
diff --git a/src/lib/filters/blur/blur_box_alpha_sse3.c b/src/lib/filters/blur/blur_box_alpha_sse3.c
new file mode 100644 (file)
index 0000000..17a19f1
--- /dev/null
@@ -0,0 +1,25 @@
+#ifdef BUILD_SSE3
+
+static inline void
+_box_blur_alpha_horiz_step_sse3(const DATA8* restrict const srcdata,
+                                DATA8* restrict const dstdata,
+                                const int* restrict const radii,
+                                const int len,
+                                const int loops)
+{
+   // TODO: implement optimized code here and remove the following line:
+   _box_blur_alpha_horiz_step(srcdata, dstdata, radii, len, loops);
+}
+
+static inline void
+_box_blur_alpha_vert_step_sse3(const DATA8* restrict const srcdata,
+                               DATA8* restrict const dstdata,
+                               const int* restrict const radii,
+                               const int len,
+                               const int loops)
+{
+   // TODO: implement optimized code here and remove the following line:
+   _box_blur_alpha_vert_step(srcdata, dstdata, radii, len, loops);
+}
+
+#endif
diff --git a/src/lib/filters/blur/blur_box_rgba_.c b/src/lib/filters/blur/blur_box_rgba_.c
new file mode 100644 (file)
index 0000000..033f249
--- /dev/null
@@ -0,0 +1,296 @@
+/* @file blur_box_rgba_.c
+ * Should define the functions:
+ * - _box_blur_horiz_rgba_step
+ * - _box_blur_vert_rgba_step
+ */
+
+#include "../evas_filter_private.h"
+
+static inline void
+_box_blur_rgba_horiz_step(const DATA32* restrict const srcdata,
+                          DATA32* restrict const dstdata,
+                          const int* restrict const radii,
+                          const int len,
+                          const int loops)
+{
+   const DATA32* restrict src;
+   DATA32* restrict dst;
+   DATA32* restrict span1;
+   DATA32* restrict span2;
+
+#if DIV_USING_BITSHIFT
+   int pow2_shifts[6] = {0};
+   int numerators[6] = {0};
+   for (int run = 0; radii[run]; run++)
+     {
+        const int div = radii[run] * 2 + 1;
+        pow2_shifts[run] = evas_filter_smallest_pow2_larger_than(div << 10);
+        numerators[run] = (1 << pow2_shifts[run]) / (div);
+     }
+#endif
+
+   span1 = alloca(len * sizeof(DATA32));
+   span2 = alloca(len * sizeof(DATA32));
+   memset(span1, 0, len * sizeof(DATA32));
+   memset(span2, 0, len * sizeof(DATA32));
+
+   // For each line, apply as many blurs as requested
+   for (int l = 0; l < loops; l++)
+     {
+        int run;
+
+        // New line: reset source & destination pointers
+        src = srcdata + len * l;
+        if (!radii[1]) // Only one run
+          dst = dstdata + len * l;
+        else
+          dst = span1;
+
+        // Apply blur with current radius
+        for (run = 0; radii[run]; run++)
+          {
+             const int radius = radii[run];
+             const int left = MIN(radius, len);
+
+#if DIV_USING_BITSHIFT
+             const int pow2 = pow2_shifts[run];
+             const int numerator = numerators[run];
+#else
+             const int divider = 2 * radius + 1;
+#endif
+
+             const DATA8* restrict sl = (DATA8 *) src;
+             const DATA8* restrict sr = (DATA8 *) src;
+             const DATA8* restrict sre = (DATA8 *) (src + len);
+             const DATA8* restrict sle = (DATA8 *) (src + len - radius);
+             DATA8* restrict d = (DATA8 *) dst;
+             int acc[4] = {0};
+             int count = 0;
+
+             // Read-ahead
+             for (int x = left; x > 0; x--)
+               {
+                  for (int k = 0; k < 4; k++)
+                    acc[k] += sr[k];
+                  sr += sizeof(DATA32);
+                  count++;
+               }
+
+             // Left
+             for (int x = left; x > 0; x--)
+               {
+                  if (sr < sre)
+                    {
+                       for (int k = 0; k < 4; k++)
+                         acc[k] += sr[k];
+                       sr += sizeof(DATA32);
+                       count++;
+                    }
+
+                  d[ALPHA] = acc[ALPHA] / count;
+                  d[RED]   = acc[RED]   / count;
+                  d[GREEN] = acc[GREEN] / count;
+                  d[BLUE]  = acc[BLUE]  / count;
+                  d += sizeof(DATA32);
+               }
+
+             // Main part
+             for (; sr < sre; sr += sizeof(DATA32), sl += sizeof(DATA32))
+               {
+                  for (int k = 0; k < 4; k++)
+                    acc[k] += sr[k];
+
+                  d[ALPHA] = DIVIDE(acc[ALPHA]);
+                  d[RED]   = DIVIDE(acc[RED]);
+                  d[GREEN] = DIVIDE(acc[GREEN]);
+                  d[BLUE]  = DIVIDE(acc[BLUE]);
+                  d += sizeof(DATA32);
+
+                  for (int k = 0; k < 4; k++)
+                    acc[k] -= sl[k];
+               }
+
+             // Right part
+             count = 2 * radius + 1;
+             for (; sl < sle; sl += sizeof(DATA32))
+               {
+                  const int divider = --count;
+                  d[ALPHA] = acc[ALPHA] / divider;
+                  d[RED]   = acc[RED]   / divider;
+                  d[GREEN] = acc[GREEN] / divider;
+                  d[BLUE]  = acc[BLUE]  / divider;
+                  d += sizeof(DATA32);
+
+                  for (int k = 0; k < 4; k++)
+                    acc[k] -= sl[k];
+               }
+
+             // More runs to go: swap spans
+             if (radii[run + 1])
+               {
+                  src = dst;
+                  if (radii[run + 2])
+                    {
+                       // Two more runs: swap
+                       DATA32* swap = span1;
+                       span1 = span2;
+                       span2 = swap;
+                       dst = span1;
+                    }
+                  else
+                    {
+                       // Last run: write directly to dstdata
+                       dst = dstdata + len * l;
+                    }
+               }
+          }
+     }
+}
+
+static inline void
+_box_blur_rgba_vert_step(const DATA32* restrict const srcdata,
+                         DATA32* restrict const dstdata,
+                         const int* restrict const radii,
+                         const int len,
+                         const int loops)
+{
+   /* Note: This function tries to optimize cache hits by working on
+    * contiguous horizontal spans.
+    */
+
+   const int step = loops;
+   DATA32* restrict src;
+   DATA32* restrict dst;
+   DATA32* restrict span1;
+   DATA32* restrict span2;
+
+#if DIV_USING_BITSHIFT
+   int pow2_shifts[6] = {0};
+   int numerators[6] = {0};
+   for (int run = 0; radii[run]; run++)
+     {
+        const int div = radii[run] * 2 + 1;
+        pow2_shifts[run] = evas_filter_smallest_pow2_larger_than(div << 10);
+        numerators[run] = (1 << pow2_shifts[run]) / (div);
+     }
+#endif
+
+   span1 = alloca(len * sizeof(DATA32));
+   span2 = alloca(len * sizeof(DATA32));
+   memset(span1, 0, len * sizeof(DATA32));
+   memset(span2, 0, len * sizeof(DATA32));
+
+   // For each line, apply as many blurs as requested
+   for (int l = 0; l < loops; l++)
+     {
+        int run;
+
+        // Rotate input into work span
+        const DATA32* srcptr = srcdata + l;
+        DATA32* s = span1;
+        for (int k = len; k; --k)
+          {
+             *s++ = *srcptr;
+             srcptr += step;
+          }
+
+        src = span1;
+        dst = span2;
+
+        // Apply blur with current radius
+        for (run = 0; radii[run]; run++)
+          {
+             const int radius = radii[run];
+             const int left = MIN(radius, len);
+
+#if DIV_USING_BITSHIFT
+             const int pow2 = pow2_shifts[run];
+             const int numerator = numerators[run];
+#else
+             const int divider = 2 * radius + 1;
+#endif
+
+             const DATA8* restrict sl = (DATA8 *) src;
+             const DATA8* restrict sr = (DATA8 *) src;
+             const DATA8* restrict sre = (DATA8 *) (src + len);
+             const DATA8* restrict sle = (DATA8 *) (src + len - radius);
+             DATA8* restrict d = (DATA8 *) dst;
+             int acc[4] = {0};
+             int count = 0;
+
+             // Read-ahead
+             for (int x = left; x > 0; x--)
+               {
+                  for (int k = 0; k < 4; k++)
+                    acc[k] += sr[k];
+                  sr += sizeof(DATA32);
+                  count++;
+               }
+
+             // Left
+             for (int x = left; x > 0; x--)
+               {
+                  if (sr < sre)
+                    {
+                       for (int k = 0; k < 4; k++)
+                         acc[k] += sr[k];
+                       sr += sizeof(DATA32);
+                       count++;
+                    }
+
+                  d[ALPHA] = acc[ALPHA] / count;
+                  d[RED]   = acc[RED]   / count;
+                  d[GREEN] = acc[GREEN] / count;
+                  d[BLUE]  = acc[BLUE]  / count;
+                  d += sizeof(DATA32);
+               }
+
+             // Main part
+             for (; sr < sre; sr += sizeof(DATA32), sl += sizeof(DATA32))
+               {
+                  for (int k = 0; k < 4; k++)
+                    acc[k] += sr[k];
+
+                  d[ALPHA] = DIVIDE(acc[ALPHA]);
+                  d[RED]   = DIVIDE(acc[RED]);
+                  d[GREEN] = DIVIDE(acc[GREEN]);
+                  d[BLUE]  = DIVIDE(acc[BLUE]);
+                  d += sizeof(DATA32);
+
+                  for (int k = 0; k < 4; k++)
+                    acc[k] -= sl[k];
+               }
+
+             // Right part
+             count = 2 * radius + 1;
+             for (; sl < sle; sl += sizeof(DATA32))
+               {
+                  const int divider = --count;
+                  d[ALPHA] = acc[ALPHA] / divider;
+                  d[RED]   = acc[RED]   / divider;
+                  d[GREEN] = acc[GREEN] / divider;
+                  d[BLUE]  = acc[BLUE]  / divider;
+                  d += sizeof(DATA32);
+
+                  for (int k = 0; k < 4; k++)
+                    acc[k] -= sl[k];
+               }
+
+             // More runs to go: swap spans
+             if (radii[run + 1])
+               {
+                  DATA32* swap = src;
+                  src = dst;
+                  dst = swap;
+               }
+          }
+
+        // Last run: rotate & copy back to destination
+        DATA32* restrict dstptr = dstdata + l;
+        for (int k = len; k; --k)
+          {
+             *dstptr = *dst++;
+             dstptr += step;
+          }
+     }
+}
diff --git a/src/lib/filters/blur/blur_box_rgba_i386.c b/src/lib/filters/blur/blur_box_rgba_i386.c
new file mode 100644 (file)
index 0000000..7f0f76b
--- /dev/null
@@ -0,0 +1,25 @@
+#ifdef BUILD_MMX
+
+static inline void
+_box_blur_rgba_horiz_step_mmx(const DATA32* restrict const srcdata,
+                              DATA32* restrict const dstdata,
+                              const int* restrict const radii,
+                              const int len,
+                              const int loops)
+{
+   // TODO: implement optimized code here and remove the following line:
+   _box_blur_rgba_horiz_step(srcdata, dstdata, radii, len, loops);
+}
+
+static inline void
+_box_blur_rgba_vert_step_mmx(const DATA32* restrict const srcdata,
+                             DATA32* restrict const dstdata,
+                             const int* restrict const radii,
+                             const int len,
+                             const int loops)
+{
+   // TODO: implement optimized code here and remove the following line:
+   _box_blur_rgba_vert_step(srcdata, dstdata, radii, len, loops);
+}
+
+#endif
diff --git a/src/lib/filters/blur/blur_box_rgba_neon.c b/src/lib/filters/blur/blur_box_rgba_neon.c
new file mode 100644 (file)
index 0000000..9206df5
--- /dev/null
@@ -0,0 +1,25 @@
+#ifdef BUILD_NEON
+
+static inline void
+_box_blur_rgba_horiz_step_neon(const DATA32* restrict const srcdata,
+                               DATA32* restrict const dstdata,
+                               const int* restrict const radii,
+                               const int len,
+                               const int loops)
+{
+   // TODO: implement optimized code here and remove the following line:
+   _box_blur_rgba_horiz_step(srcdata, dstdata, radii, len, loops);
+}
+
+static inline void
+_box_blur_rgba_vert_step_neon(const DATA32* restrict const srcdata,
+                              DATA32* restrict const dstdata,
+                              const int* restrict const radii,
+                              const int len,
+                              const int loops)
+{
+   // TODO: implement optimized code here and remove the following line:
+   _box_blur_rgba_vert_step(srcdata, dstdata, radii, len, loops);
+}
+
+#endif
diff --git a/src/lib/filters/blur/blur_box_rgba_sse3.c b/src/lib/filters/blur/blur_box_rgba_sse3.c
new file mode 100644 (file)
index 0000000..03ae282
--- /dev/null
@@ -0,0 +1,25 @@
+#ifdef BUILD_SSE3
+
+static inline void
+_box_blur_rgba_horiz_step_sse3(const DATA32* restrict const srcdata,
+                               DATA32* restrict const dstdata,
+                               const int* restrict const radii,
+                               const int len,
+                               const int loops)
+{
+   // TODO: implement optimized code here and remove the following line:
+   _box_blur_rgba_horiz_step(srcdata, dstdata, radii, len, loops);
+}
+
+static inline void
+_box_blur_rgba_vert_step_sse3(const DATA32* restrict const srcdata,
+                              DATA32* restrict const dstdata,
+                              const int* restrict const radii,
+                              const int len,
+                              const int loops)
+{
+   // TODO: implement optimized code here and remove the following line:
+   _box_blur_rgba_vert_step(srcdata, dstdata, radii, len, loops);
+}
+
+#endif
diff --git a/src/lib/filters/blur/blur_gaussian_alpha_.c b/src/lib/filters/blur/blur_gaussian_alpha_.c
new file mode 100644 (file)
index 0000000..fad14e2
--- /dev/null
@@ -0,0 +1,84 @@
+/* @file blur_gaussian_alpha_.c
+ * Should define the functions:
+ * - _gaussian_blur_horiz_alpha_step
+ * - _gaussian_blur_vert_alpha_step
+ */
+
+/* Datatypes and MIN macro */
+#include "../evas_filter_private.h"
+
+#if !defined (FUNCTION_NAME) || !defined (STEP)
+# error Must define FUNCTION_NAME and STEP
+#endif
+
+static inline void
+FUNCTION_NAME(const DATA8* restrict srcdata, DATA8* restrict dstdata,
+              const int radius, const int len,
+              const int loops, const int loopstep,
+              const int* restrict weights, const int pow2_divider)
+{
+   int i, j, k, acc, divider;
+   const int diameter = 2 * radius + 1;
+   const int left = MIN(radius, len);
+   const int right = MIN(radius, (len - radius));
+   const DATA8* restrict s;
+   const DATA8* restrict src;
+   DATA8* restrict dst;
+
+   for (i = loops; i; --i)
+     {
+        src = srcdata;
+        dst = dstdata;
+
+        // left
+        for (k = 0; k < left; k++, dst += STEP)
+          {
+             acc = 0;
+             divider = 0;
+             s = src;
+             for (j = 0; j <= k + radius; j++, s += STEP)
+               {
+                  acc += (*s) * weights[j + radius - k];
+                  divider += weights[j + radius - k];
+               }
+             if (!divider) goto error;
+             *dst = acc / divider;
+          }
+
+        // middle
+        for (k = radius; k < (len - radius); k++, src += STEP, dst += STEP)
+          {
+             acc = 0;
+             s = src;
+             for (j = 0; j < diameter; j++, s += STEP)
+               acc += (*s) * weights[j];
+             *dst = acc >> pow2_divider;
+          }
+
+        // right
+        for (k = 0; k < right; k++, dst += STEP, src += STEP)
+          {
+             acc = 0;
+             divider = 0;
+             s = src;
+             for (j = 0; j < 2 * radius - k; j++, s += STEP)
+               {
+                  acc += (*s) * weights[j];
+                  divider += weights[j];
+               }
+             if (!divider) goto error;
+             *dst = acc / divider;
+          }
+
+        dstdata += loopstep;
+        srcdata += loopstep;
+     }
+
+   return;
+
+error:
+   CRI("Avoided division by 0.");
+}
+
+#undef FUNCTION_NAME
+#undef STEP
diff --git a/src/lib/filters/blur/blur_gaussian_rgba_.c b/src/lib/filters/blur/blur_gaussian_rgba_.c
new file mode 100644 (file)
index 0000000..fdbf3da
--- /dev/null
@@ -0,0 +1,103 @@
+/* @file blur_gaussian_rgba_.c
+ * Should define the functions:
+ * - _gaussian_blur_horiz_rgba_step
+ * - _gaussian_blur_vert_rgba_step
+ */
+
+#include "../evas_filter_private.h"
+
+#if !defined (FUNCTION_NAME) || !defined (STEP)
+# error Must define FUNCTION_NAME and STEP
+#endif
+
+static inline void
+FUNCTION_NAME(const DATA32* restrict srcdata, DATA32* restrict dstdata,
+              const int radius, const int len,
+              const int loops, const int loopstep,
+              const int* restrict weights, const int pow2_divider)
+{
+   const int diameter = 2 * radius + 1;
+   const int left = MIN(radius, len);
+   const int right = MIN(radius, (len - radius));
+   const DATA32* restrict src;
+   DATA32* restrict dst;
+   int i, j, k;
+
+   for (i = loops; i; --i)
+     {
+        src = srcdata;
+        dst = dstdata;
+
+        // left
+        for (k = 0; k < left; k++, dst += STEP)
+          {
+             int acc[4] = {0};
+             int divider = 0;
+             const DATA32* restrict s = src;
+             for (j = 0; j <= k + radius; j++, s += STEP)
+               {
+                  const int weightidx = j + radius - k;
+                  acc[ALPHA] += A_VAL(s) * weights[weightidx];
+                  acc[RED]   += R_VAL(s) * weights[weightidx];
+                  acc[GREEN] += G_VAL(s) * weights[weightidx];
+                  acc[BLUE]  += B_VAL(s) * weights[weightidx];
+                  divider += weights[weightidx];
+               }
+             if (!divider) goto error;
+             A_VAL(dst) = acc[ALPHA] / divider;
+             R_VAL(dst) = acc[RED]   / divider;
+             G_VAL(dst) = acc[GREEN] / divider;
+             B_VAL(dst) = acc[BLUE]  / divider;
+          }
+
+        // middle
+        for (k = len - (2 * radius); k > 0; k--, src += STEP, dst += STEP)
+          {
+             int acc[4] = {0};
+             const DATA32* restrict s = src;
+             for (j = 0; j < diameter; j++, s += STEP)
+               {
+                  acc[ALPHA] += A_VAL(s) * weights[j];
+                  acc[RED]   += R_VAL(s) * weights[j];
+                  acc[GREEN] += G_VAL(s) * weights[j];
+                  acc[BLUE]  += B_VAL(s) * weights[j];
+               }
+             A_VAL(dst) = acc[ALPHA] >> pow2_divider;
+             R_VAL(dst) = acc[RED]   >> pow2_divider;
+             G_VAL(dst) = acc[GREEN] >> pow2_divider;
+             B_VAL(dst) = acc[BLUE]  >> pow2_divider;
+          }
+
+        // right
+        for (k = 0; k < right; k++, dst += STEP, src += STEP)
+          {
+             int acc[4] = {0};
+             int divider = 0;
+             const DATA32* restrict s = src;
+             for (j = 0; j < 2 * radius - k; j++, s += STEP)
+               {
+                  acc[ALPHA] += A_VAL(s) * weights[j];
+                  acc[RED]   += R_VAL(s) * weights[j];
+                  acc[GREEN] += G_VAL(s) * weights[j];
+                  acc[BLUE]  += B_VAL(s) * weights[j];
+                  divider += weights[j];
+               }
+             if (!divider) goto error;
+             A_VAL(dst) = acc[ALPHA] / divider;
+             R_VAL(dst) = acc[RED]   / divider;
+             G_VAL(dst) = acc[GREEN] / divider;
+             B_VAL(dst) = acc[BLUE]  / divider;
+          }
+
+        dstdata += loopstep;
+        srcdata += loopstep;
+     }
+
+   return;
+
+error:
+   CRI("Avoided division by 0.");
+}
+
+#undef FUNCTION_NAME
+#undef STEP
diff --git a/src/lib/filters/evas_filter.c b/src/lib/filters/evas_filter.c
new file mode 100644 (file)
index 0000000..2dce870
--- /dev/null
@@ -0,0 +1,2119 @@
+/*
+ * \@file evas_filter.c
+ *
+ * Infrastructure for simple filters applied to RGBA and Alpha buffers.
+ * Originally used by font effects.
+ *
+ * Filters include:
+ * - Blur (Gaussian, Box, Motion) and Shadows
+ * - Bump maps (light effects)
+ * - Displacement maps
+ * - Color curves
+ * - Blending and masking
+ *
+ * The reference documentation can be found in evas_filter_parser.c
+ */
+
+#include "evas_filter.h"
+#include "evas_private.h"
+#include "evas_filter_private.h"
+
+#ifdef EVAS_CSERVE2
+# include "evas_cs2_private.h"
+#endif
+
+static void _buffer_free(Evas_Filter_Buffer *fb);
+static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd);
+static RGBA_Image *_rgba_image_alloc(Evas_Filter_Buffer const *fb, void *data);
+
+#ifdef CLAMP
+# undef CLAMP
+#endif
+#define CLAMP(a,b,c) MIN(MAX((b),(a)),(c))
+
+#define DRAW_COLOR_SET(r, g, b, a) do { cmd->draw.R = r; cmd->draw.G = g; cmd->draw.B = b; cmd->draw.A = a; } while (0)
+#define DRAW_CLIP_SET(_x, _y, _w, _h) do { cmd->draw.clip.x = _x; cmd->draw.clip.y = _y; cmd->draw.clip.w = _w; cmd->draw.clip.h = _h; } while (0)
+#define DRAW_FILL_SET(fmode) do { cmd->draw.fillmode = fmode; } while (0)
+
+typedef struct _Evas_Filter_Thread_Command Evas_Filter_Thread_Command;
+struct _Evas_Filter_Thread_Command
+{
+   Evas_Filter_Context *ctx;
+   RGBA_Image *src, *mask, *dst;
+   Evas_Filter_Apply_Func func;
+};
+
+
+/* Main functions */
+
+Evas_Filter_Context *
+evas_filter_context_new(Evas *_evas, Eina_Bool async)
+{
+   Evas_Filter_Context *ctx;
+
+#if (VMAJ > 1) || (VMIN >= 8)
+   Evas_Public_Data *evas = eo_data_scope_get(_evas, EVAS_CLASS);
+#else
+   Evas *evas = _evas;
+#endif
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(evas, NULL);
+
+   ctx = calloc(1, sizeof(Evas_Filter_Context));
+   if (!ctx) return NULL;
+
+   ctx->evas = evas;
+   ctx->async = async;
+
+   /* Note:
+    * For now, we need to detect whether the engine is full SW or GL.
+    * In case of GL, we will have two buffers in parallel:
+    * RGBA_Image backing and a GL texture (glimage). We can't just leave it
+    * to the engine to handle the image data since it will try to discard the
+    * original buffer as early as possible to save memory, but we still need
+    * it for filtering.
+    * In the future, Evas_Engine functions need to be added to abstract this
+    * better and implement filters direcly with shaders.
+    */
+   ctx->gl_engine = (evas->engine.func->gl_surface_read_pixels != NULL);
+   if (ctx->gl_engine)
+     DBG("Detected GL engine. All filters will still run in software (SLOW).");
+
+   return ctx;
+}
+
+/* Private function to reset the filter context. Used from parser.c */
+void
+evas_filter_context_clear(Evas_Filter_Context *ctx)
+{
+   Evas_Filter_Buffer *fb;
+   Evas_Filter_Command *cmd;
+
+   if (!ctx) return;
+
+   EINA_LIST_FREE(ctx->buffers, fb)
+     _buffer_free(fb);
+   EINA_INLIST_FREE(ctx->commands, cmd)
+     _command_del(ctx, cmd);
+
+   ctx->buffers = NULL;
+   ctx->commands = NULL;
+   ctx->last_buffer_id = 0;
+   ctx->last_command_id = 0;
+
+   // Note: don't reset post_run, as it it set by the client
+}
+
+static void
+_backing_free(Evas_Filter_Context *ctx, RGBA_Image *im)
+{
+   if (!im) return;
+
+   if (!ctx->gl_engine)
+     {
+        if (!ctx->async)
+          ENFN->image_free(ENDT, im);
+     }
+   else
+     {
+#ifdef EVAS_CSERVE2
+        if (evas_cserve2_use_get())
+          evas_cache2_image_close(&im->cache_entry);
+        else
+#endif
+          evas_cache_image_drop(&im->cache_entry);
+     }
+}
+
+static void
+_filter_buffer_backing_free(Evas_Filter_Buffer *fb)
+{
+   if (!fb) return;
+
+   if (!fb->stolen)
+     {
+        if (fb->allocated)
+          _backing_free(fb->ctx, fb->backing);
+        if (fb->glimage && fb->allocated_gl)
+          fb->ENFN->image_free(fb->ENDT, fb->glimage);
+        fb->backing = NULL;
+        fb->glimage = NULL;
+     }
+   else
+     {
+        if (!fb->ctx->gl_engine)
+          {
+             fb->delete_me = fb->allocated;
+          }
+        else if (fb->glimage && fb->allocated)
+          {
+             _backing_free(fb->ctx, fb->backing);
+             fb->backing = NULL;
+          }
+     }
+}
+
+/* GL engine stuff: read-back from texture */
+static Eina_Bool
+_filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb)
+{
+   Eina_Bool ok;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(fb->ctx->gl_engine, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(fb->glimage, EINA_FALSE);
+
+   if (fb->backing)
+     {
+        INF("Backing buffer exists already. %dx%d @ %p (data %p)",
+            fb->backing->cache_entry.w, fb->backing->cache_entry.h,
+            fb->backing, fb->backing->image.data);
+        return EINA_TRUE;
+     }
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_lock, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_read_pixels, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_unlock, EINA_FALSE);
+
+   fb->backing = _rgba_image_alloc(fb, NULL);
+   fb->allocated = EINA_TRUE;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(fb->backing, EINA_FALSE);
+
+   ok = fb->ENFN->gl_surface_lock(fb->ENDT, fb->glimage);
+   if (!ok)
+     {
+        ERR("Failed to lock the image pixels");
+        return EINA_FALSE;
+     }
+
+   ok = fb->ENFN->gl_surface_read_pixels(fb->ENDT, fb->glimage,
+                                         0, 0, fb->w, fb->h, fb->alpha_only
+                                         ? EVAS_COLORSPACE_GRY8
+                                         : EVAS_COLORSPACE_ARGB8888,
+                                         fb->backing->image.data);
+   if (!ok)
+     ERR("Could not read the image pixels!");
+
+   ok &= fb->ENFN->gl_surface_unlock(fb->ENDT, fb->glimage);
+   return ok;
+}
+
+
+#if (VMAJ > 1) || (VMIN >= 8)
+
+/**
+ * @internal
+ * Render the source object when a proxy is set.
+ *
+ * Used to force a draw if necessary, else just makes sure it's available.
+ * @note This comes direcly from evas_object_image.c.
+ * A common function is desirable here :)
+ */
+static void
+_proxy_subrender(Evas *eo_e, Evas_Object *eo_source, Evas_Object *eo_proxy,
+                 Evas_Object_Protected_Data *proxy_obj, Eina_Bool do_async)
+{
+   Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CLASS);
+   Evas_Object_Protected_Data *source;
+   Eina_Bool source_clip = EINA_FALSE;
+   void *ctx;
+   int w, h;
+
+   if (!eo_source) return;
+   source = eo_data_scope_get(eo_source, EVAS_OBJ_CLASS);
+
+   w = source->cur->geometry.w;
+   h = source->cur->geometry.h;
+
+   EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy,
+                        Evas_Object_Proxy_Data, proxy_write)
+     {
+        proxy_write->redraw = EINA_FALSE;
+
+        /* We need to redraw surface then */
+        if ((proxy_write->surface) &&
+            ((proxy_write->w != w) || (proxy_write->h != h)))
+          {
+             e->engine.func->image_map_surface_free(e->engine.data.output,
+                                                    proxy_write->surface);
+             proxy_write->surface = NULL;
+          }
+
+        /* FIXME: Hardcoded alpha 'on' */
+        /* FIXME (cont): Should see if the object has alpha */
+        if (!proxy_write->surface)
+          {
+             proxy_write->surface = e->engine.func->image_map_surface_new
+               (e->engine.data.output, w, h, 1);
+             if (!proxy_write->surface) goto end;
+             proxy_write->w = w;
+             proxy_write->h = h;
+          }
+
+        ctx = e->engine.func->context_new(e->engine.data.output);
+        e->engine.func->context_color_set(e->engine.data.output, ctx, 0, 0,
+                                          0, 0);
+        e->engine.func->context_render_op_set(e->engine.data.output, ctx,
+                                              EVAS_RENDER_COPY);
+        e->engine.func->rectangle_draw(e->engine.data.output, ctx,
+                                       proxy_write->surface, 0, 0, w, h,
+                                       do_async);
+        e->engine.func->context_free(e->engine.data.output, ctx);
+
+        ctx = e->engine.func->context_new(e->engine.data.output);
+
+        if (eo_isa(eo_proxy, EVAS_OBJ_IMAGE_CLASS))
+          eo_do(eo_proxy, evas_obj_image_source_clip_get(&source_clip));
+
+        Evas_Proxy_Render_Data proxy_render_data = {
+             .eo_proxy = eo_proxy,
+             .proxy_obj = proxy_obj,
+             .eo_src = eo_source,
+             .source_clip = source_clip
+        };
+        evas_render_mapped(e, eo_source, source, ctx, proxy_write->surface,
+                           -source->cur->geometry.x,
+                           -source->cur->geometry.y,
+                           1, 0, 0, e->output.w, e->output.h,
+                           &proxy_render_data, 1, do_async, EINA_TRUE);
+
+        e->engine.func->context_free(e->engine.data.output, ctx);
+        proxy_write->surface = e->engine.func->image_dirty_region
+           (e->engine.data.output, proxy_write->surface, 0, 0, w, h);
+     }
+ end:
+   EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, proxy_write);
+}
+
+/** @hidden private render proxy objects */
+void
+evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
+                                     Eina_Bool do_async)
+{
+   Evas_Object_Protected_Data *source;
+   Evas_Object_Protected_Data *obj;
+   Evas_Filter_Buffer *fb;
+   Eina_List *li;
+
+   obj = eo_data_scope_get(eo_obj, EVAS_OBJ_CLASS);
+
+   if (!ctx->has_proxies) return;
+   EINA_LIST_FOREACH(ctx->buffers, li, fb)
+     if (fb->source)
+       {
+          // TODO: Lock current object as proxyrendering (see image obj)
+          source = eo_data_scope_get(fb->source, EVAS_OBJ_CLASS);
+          if (source->proxy->surface && !source->proxy->redraw)
+            {
+               DBG("Source already rendered: '%s' of type '%s'",
+                   fb->source_name, eo_class_name_get(eo_class_get(fb->source)));
+               _filter_buffer_backing_free(fb);
+               fb->w = source->cur->geometry.w;
+               fb->h = source->cur->geometry.h;
+               if (!ctx->gl_engine)
+                 {
+                    fb->backing = source->proxy->surface;
+                    fb->allocated = EINA_FALSE;
+                 }
+               else
+                 {
+                    fb->glimage = source->proxy->surface;
+                    fb->allocated_gl = EINA_FALSE;
+                    _filter_buffer_glimage_pixels_read(fb);
+                 }
+               fb->alpha_only = EINA_FALSE;
+            }
+          else
+            {
+               DBG("Source needs to be rendered: '%s' of type '%s' (%s)",
+                   fb->source_name, eo_class_name_get(eo_class_get(fb->source)),
+                   source->proxy->redraw ? "redraw" : "no surface");
+               _proxy_subrender(ctx->evas->evas, fb->source, eo_obj, obj, do_async);
+               _filter_buffer_backing_free(fb);
+               fb->w = source->cur->geometry.w;
+               fb->h = source->cur->geometry.h;
+               if (!ctx->gl_engine)
+                 {
+                    fb->backing = source->proxy->surface;
+                    fb->allocated = EINA_FALSE;
+                 }
+               else
+                 {
+                    fb->glimage = source->proxy->surface;
+                    fb->allocated_gl = EINA_FALSE;
+                    _filter_buffer_glimage_pixels_read(fb);
+                 }
+               fb->alpha_only = EINA_FALSE;
+            }
+          DBG("Source has dimensions %dx%d (buffer %d)", fb->w, fb->h, fb->id);
+       }
+}
+
+#else // EFL 1.7
+
+static void
+_proxy_subrender(Evas *e, Evas_Object *source, Evas_Object *proxy)
+{
+   void *ctx;
+   int w, h;
+   Evas_Proxy_Render_Data proxy_render_data;
+
+   if (!source) return;
+
+   w = source->cur.geometry.w;
+   h = source->cur.geometry.h;
+
+   source->proxy.redraw = EINA_FALSE;
+
+   /* We need to redraw surface then */
+   if ((source->proxy.surface) &&
+       ((source->proxy.w != w) || (source->proxy.h != h)))
+     {
+        e->engine.func->image_map_surface_free(e->engine.data.output,
+                                               source->proxy.surface);
+        source->proxy.surface = NULL;
+     }
+
+   /* FIXME: Hardcoded alpha 'on' */
+   /* FIXME (cont): Should see if the object has alpha */
+   if (!source->proxy.surface)
+     {
+        source->proxy.surface = e->engine.func->image_map_surface_new
+           (e->engine.data.output, w, h, 1);
+        source->proxy.w = w;
+        source->proxy.h = h;
+     }
+
+   if (!source->proxy.surface) return;
+
+   ctx = e->engine.func->context_new(e->engine.data.output);
+   e->engine.func->context_color_set(e->engine.data.output, ctx, 0, 0, 0, 0);
+   e->engine.func->context_render_op_set(e->engine.data.output, ctx,
+                                         EVAS_RENDER_COPY);
+   e->engine.func->rectangle_draw(e->engine.data.output, ctx,
+                                  source->proxy.surface, 0, 0, w, h);
+   e->engine.func->context_free(e->engine.data.output, ctx);
+
+   ctx = e->engine.func->context_new(e->engine.data.output);
+
+   proxy_render_data.proxy_obj = proxy;
+   proxy_render_data.src_obj = source;
+   proxy_render_data.source_clip = EINA_FALSE;
+
+   evas_render_mapped(e, source, ctx, source->proxy.surface,
+                      -source->cur.geometry.x,
+                      -source->cur.geometry.y,
+                      1, 0, 0, e->output.w, e->output.h,
+                      &proxy_render_data, 1, EINA_TRUE);
+
+   e->engine.func->context_free(e->engine.data.output, ctx);
+
+   source->proxy.surface = e->engine.func->image_dirty_region
+      (e->engine.data.output, source->proxy.surface, 0, 0, w, h);
+}
+
+void
+evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx,
+                                     Evas_Object *obj,
+                                     Eina_Bool do_async EINA_UNUSED)
+{
+   Evas_Filter_Buffer *fb;
+   Eina_List *li;
+
+   EINA_LIST_FOREACH(ctx->buffers, li, fb)
+     {
+        Evas_Object *source = fb->source;
+
+        if (!source) continue;
+        if (source->proxy.surface && !source->proxy.redraw)
+          {
+             INF("Source already rendered");
+             _filter_buffer_backing_free(fb);
+             fb->w = source->cur.geometry.w;
+             fb->h = source->cur.geometry.h;
+             if (!ctx->gl_engine)
+               {
+                  fb->backing = source->proxy.surface;
+                  fb->allocated = EINA_FALSE;
+               }
+             else
+               {
+                  fb->glimage = source->proxy.surface;
+                  fb->allocated_gl = EINA_FALSE;
+                  _filter_buffer_glimage_pixels_read(fb);
+               }
+             fb->alpha_only = EINA_FALSE;
+          }
+        else
+          {
+             INF("Source needs to be rendered");
+             _proxy_subrender(ctx->evas, source, obj);
+             _filter_buffer_backing_free(fb);
+             fb->w = source->cur.geometry.w;
+             fb->h = source->cur.geometry.h;
+             if (!ctx->gl_engine)
+               {
+                  fb->backing = source->proxy.surface;
+                  fb->allocated = EINA_FALSE;
+               }
+             else
+               {
+                  fb->glimage = source->proxy.surface;
+                  fb->allocated_gl = EINA_FALSE;
+                  _filter_buffer_glimage_pixels_read(fb);
+               }
+             fb->alpha_only = EINA_FALSE;
+          }
+     }
+}
+#endif
+
+void
+evas_filter_context_destroy(Evas_Filter_Context *ctx)
+{
+   Evas_Filter_Buffer *fb;
+   Evas_Filter_Command *cmd;
+
+   if (!ctx) return;
+
+   EINA_LIST_FREE(ctx->buffers, fb)
+     _buffer_free(fb);
+   EINA_INLIST_FREE(ctx->commands, cmd)
+     _command_del(ctx, cmd);
+
+   free(ctx);
+}
+
+void
+evas_filter_context_post_run_callback_set(Evas_Filter_Context *ctx,
+                                          Evas_Filter_Cb cb, void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN(ctx);
+   ctx->post_run.cb = cb;
+   ctx->post_run.data = data;
+}
+
+static Evas_Filter_Buffer *
+_buffer_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only)
+{
+   Evas_Filter_Buffer *fb;
+
+   fb = calloc(1, sizeof(Evas_Filter_Buffer));
+   if (!fb) return NULL;
+
+   fb->id = ++(ctx->last_buffer_id);
+   fb->ctx = ctx;
+   fb->alpha_only = alpha_only;
+   fb->transient = EINA_TRUE;
+   fb->w = w;
+   fb->h = h;
+
+   ctx->buffers = eina_list_append(ctx->buffers, fb);
+   return fb;
+}
+
+static RGBA_Image *
+_rgba_image_alloc(Evas_Filter_Buffer const *fb, void *data)
+{
+   Evas_Colorspace cspace;
+   RGBA_Image *image;
+   size_t sz;
+
+   cspace = fb->alpha_only ? EVAS_COLORSPACE_GRY8 : EVAS_COLORSPACE_ARGB8888;
+   if (!fb->ctx->gl_engine)
+     {
+        if (!data)
+          {
+             image = fb->ENFN->image_new_from_copied_data
+                   (fb->ENDT, fb->w, fb->h, NULL, EINA_TRUE, cspace);
+          }
+        else
+          {
+             image = fb->ENFN->image_new_from_data
+                   (fb->ENDT, fb->w, fb->h, data, EINA_TRUE, cspace);
+          }
+     }
+   else
+     {
+        // FIXME: Directly calling the alloc functions since we want to use sw surfaces.
+
+        if (!data)
+          {
+#ifdef EVAS_CSERVE2
+             if (evas_cserve2_use_get())
+               image = (RGBA_Image *) evas_cache2_image_copied_data
+                     (evas_common_image_cache2_get(), fb->w, fb->h, NULL, EINA_TRUE, cspace);
+             else
+#endif
+               image = (RGBA_Image *) evas_cache_image_copied_data
+                     (evas_common_image_cache_get(), fb->w, fb->h, NULL, EINA_TRUE, cspace);
+          }
+        else
+          {
+#ifdef EVAS_CSERVE2
+             if (evas_cserve2_use_get())
+               image = (RGBA_Image *) evas_cache2_image_data
+                     (evas_common_image_cache2_get(), fb->w, fb->h, data, EINA_TRUE, cspace);
+             else
+#endif
+               image = (RGBA_Image *) evas_cache_image_data
+                     (evas_common_image_cache_get(), fb->w, fb->h, data, EINA_TRUE, cspace);
+          }
+     }
+   if (!image) return EINA_FALSE;
+
+   if (fb->alpha_only)
+     sz = image->cache_entry.w * image->cache_entry.h * sizeof(DATA8);
+   else
+     sz = image->cache_entry.w * image->cache_entry.h * sizeof(DATA32);
+   if (!data) memset(image->image.data, 0, sz);
+
+   return image;
+}
+
+Eina_Bool
+evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx,
+                                         unsigned w, unsigned h)
+{
+   Evas_Filter_Command *cmd;
+   Evas_Filter_Buffer *fb;
+   Eina_List *li;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
+   ctx->w = w;
+   ctx->h = h;
+
+   //DBG("Allocating all buffers based on output size %ux%u", w, h);
+
+   EINA_INLIST_FOREACH(ctx->commands, cmd)
+     {
+        Evas_Filter_Fill_Mode fillmode = cmd->draw.fillmode;
+        Evas_Filter_Buffer *in, *out;
+
+        in = cmd->input;
+        if (!in->w && !in->h)
+          {
+             in->w = w;
+             in->h = h;
+          }
+
+        if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY)
+          {
+             unsigned sw = w, sh = h;
+
+             switch (cmd->mode)
+               {
+                case EVAS_FILTER_MODE_BLEND:
+                  in = cmd->input;
+                  break;
+                case EVAS_FILTER_MODE_BUMP:
+                case EVAS_FILTER_MODE_DISPLACE:
+                case EVAS_FILTER_MODE_MASK:
+                  in = cmd->mask;
+                  break;
+                default:
+                  CRI("Invalid fillmode set for command %d", cmd->mode);
+                  return EINA_FALSE;
+               }
+
+             if (in->w) sw = in->w;
+             if (in->h) sh = in->h;
+
+             if ((sw != w) || (sh != h))
+               {
+                  if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
+                    sw = w;
+                  if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
+                    sh = h;
+
+                  //DBG("Allocating temporary buffer of size %ux%u", sw, sh);
+                  fb = evas_filter_buffer_alloc_new(ctx, sw, sh, in->alpha_only);
+                  if (!fb) goto alloc_fail;
+                  fb->transient = EINA_TRUE;
+               }
+          }
+
+        if (cmd->draw.need_temp_buffer)
+          {
+             unsigned sw = w, sh = h;
+
+             in = cmd->input;
+             if (in->w) sw = in->w;
+             if (in->h) sh = in->h;
+
+             //DBG("Allocating temporary buffer of size %ux%u", sw, sh);
+             fb = evas_filter_buffer_alloc_new(ctx, sw, sh, in->alpha_only);
+             if (!fb) goto alloc_fail;
+             fb->transient = EINA_TRUE;
+          }
+
+        out = cmd->output;
+        if (!out->w && !out->h)
+          {
+             out->w = w;
+             out->h = h;
+          }
+     }
+
+   EINA_LIST_FOREACH(ctx->buffers, li, fb)
+     {
+        RGBA_Image *im;
+        im = fb->backing;
+        if (im)
+          {
+#if HAS_DO_ASYNC
+             if (ctx->async)
+               {
+                  im->cache_entry.references++;
+                  evas_unref_queue_image_put(ctx->evas, &im->cache_entry);
+               }
+#endif
+             continue;
+          }
+
+        if (fb->source)
+          continue;
+
+        if (fb->glimage)
+          continue;
+
+        if (!fb->w && !fb->h)
+          {
+             ERR("Size of buffer %d should be known at this point. Is this a dangling buffer?", fb->id);
+             continue;
+          }
+
+        //DBG("Allocating buffer of size %ux%u alpha %d", fb->w, fb->h, fb->alpha_only);
+        im = _rgba_image_alloc(fb, NULL);
+        if (!im) goto alloc_fail;
+
+        fb->backing = im;
+        fb->allocated = (im != NULL);
+#if HAS_DO_ASYNC
+        if (ctx->async && fb->allocated)
+          evas_unref_queue_image_put(ctx->evas, &im->cache_entry);
+#endif
+     }
+
+   return EINA_TRUE;
+
+alloc_fail:
+   ERR("Buffer allocation failed! Context size: %dx%d", w, h);
+   return EINA_FALSE;
+}
+
+int
+evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only)
+{
+   Evas_Filter_Buffer *fb;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
+
+   fb = _buffer_new(ctx, 0, 0, alpha_only);
+   if (!fb) return -1;
+
+   fb->transient = EINA_FALSE;
+
+   return fb->id;
+}
+
+Eina_Bool
+_filter_buffer_data_set(Evas_Filter_Context *ctx, int bufid, void *data,
+                        int w, int h, Eina_Bool alpha_only)
+{
+   Evas_Filter_Buffer *fb;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
+
+   fb = _filter_buffer_get(ctx, bufid);
+   if (!fb) return EINA_FALSE;
+
+   _filter_buffer_backing_free(fb);
+   if (w <= 0 || h <= 0)
+     return EINA_FALSE;
+
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(fb->backing == NULL, EINA_FALSE);
+   // TODO: Check input parameters?
+   fb->alpha_only = alpha_only;
+   fb->w = w;
+   fb->h = h;
+
+   fb->backing = _rgba_image_alloc(fb, data);
+   fb->allocated = (!data && (fb->backing != NULL));
+#if HAS_DO_ASYNC
+   if (ctx->async && fb->allocated)
+     evas_unref_queue_image_put(ctx->evas, fb->backing);
+#endif
+   return fb->allocated;
+}
+
+int
+evas_filter_buffer_image_new(Evas_Filter_Context *ctx, void *image)
+{
+   Evas_Filter_Buffer *fb;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(image, -1);
+
+   fb = calloc(1, sizeof(Evas_Filter_Buffer));
+   if (!fb) return -1;
+
+   fb->id = ++(ctx->last_buffer_id);
+   fb->ctx = ctx;
+   if (!fb->ctx->gl_engine)
+     {
+        fb->backing = image;
+        fb->allocated = EINA_FALSE;
+     }
+   else
+     {
+        fb->glimage = image;
+        fb->allocated_gl = EINA_FALSE;
+     }
+   ENFN->image_size_get(ENDT, image, &fb->w, &fb->h);
+   fb->alpha_only = (ENFN->image_colorspace_get(ENDT, image)
+                     == EVAS_COLORSPACE_GRY8);
+
+   ctx->buffers = eina_list_append(ctx->buffers, fb);
+   return fb->id;
+}
+
+Evas_Filter_Buffer *
+_filter_buffer_data_new(Evas_Filter_Context *ctx, void *data, int w, int h,
+                        Eina_Bool alpha_only)
+{
+   Evas_Filter_Buffer *fb;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(w > 0 && h > 0, NULL);
+
+   fb = calloc(1, sizeof(Evas_Filter_Buffer));
+   if (!fb) return NULL;
+
+   fb->id = ++(ctx->last_buffer_id);
+   fb->ctx = ctx;
+   ctx->buffers = eina_list_append(ctx->buffers, fb);
+
+   if (!_filter_buffer_data_set(ctx, fb->id, data, w, h, alpha_only))
+     {
+        ctx->buffers = eina_list_remove(ctx->buffers, fb);
+        free(fb);
+        return NULL;
+     }
+
+   return fb;
+}
+
+static void
+_buffer_free(Evas_Filter_Buffer *fb)
+{
+   _filter_buffer_backing_free(fb);
+   free(fb);
+}
+
+Evas_Filter_Buffer *
+_filter_buffer_get(Evas_Filter_Context *ctx, int bufid)
+{
+   Evas_Filter_Buffer *buffer;
+   Eina_List *l;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
+
+   EINA_LIST_FOREACH(ctx->buffers, l, buffer)
+     if (buffer->id == bufid) return buffer;
+
+   return NULL;
+}
+
+void *
+evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid)
+{
+   Evas_Filter_Buffer *buffer;
+
+   buffer = _filter_buffer_get(ctx, bufid);
+   if (!buffer) return NULL;
+
+   return buffer->backing;
+}
+
+void *
+evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid)
+{
+   Evas_Filter_Buffer *buffer;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
+
+   buffer = _filter_buffer_get(ctx, bufid);
+   if (!buffer) return NULL;
+
+   buffer->stolen = EINA_TRUE;
+
+   if (ctx->gl_engine)
+     return buffer->glimage;
+
+   if (ctx->async && buffer->backing)
+     buffer->backing->cache_entry.references++;
+
+   return buffer->backing;
+}
+
+Eina_Bool
+evas_filter_buffer_backing_release(Evas_Filter_Context *ctx,
+                                   void *stolen_buffer)
+{
+   Evas_Filter_Buffer *fb;
+   Eina_List *li;
+
+   if (!stolen_buffer) return EINA_FALSE;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
+
+   EINA_LIST_FOREACH(ctx->buffers, li, fb)
+     {
+        if (fb->backing == stolen_buffer)
+          {
+             fb->stolen = EINA_FALSE;
+             if (fb->delete_me)
+               {
+                  ctx->buffers = eina_list_remove_list(ctx->buffers, li);
+                  if (ctx->async)
+                    {
+#if HAS_DO_ASYNC
+                       if (fb->allocated)
+                         evas_unref_queue_image_put(ctx->evas, stolen_buffer);
+#endif
+                       free(fb);
+                    }
+                  else
+                    _buffer_free(fb);
+                  return EINA_TRUE;
+               }
+             return EINA_TRUE;
+          }
+        else if (fb->glimage == stolen_buffer)
+          {
+             fb->stolen = EINA_FALSE;
+             if (fb->delete_me)
+               {
+                  ctx->buffers = eina_list_remove_list(ctx->buffers, li);
+                  _buffer_free(fb);
+               }
+             return EINA_TRUE;
+          }
+     }
+
+#if HAS_DO_ASYNC
+   if (ctx->async)
+     evas_unref_queue_image_put(ctx->evas, stolen_buffer);
+   else
+#endif
+   if (ctx->gl_engine)
+     ctx->post_run.buffers_to_free =
+       eina_list_append(ctx->post_run.buffers_to_free, stolen_buffer);
+   else
+     _backing_free(ctx, stolen_buffer);
+
+   return EINA_TRUE;
+}
+
+static Evas_Filter_Command *
+_command_new(Evas_Filter_Context *ctx, Evas_Filter_Mode mode,
+             Evas_Filter_Buffer *input, Evas_Filter_Buffer *mask,
+             Evas_Filter_Buffer *output)
+{
+   Evas_Filter_Command *cmd;
+
+   cmd = calloc(1, sizeof(Evas_Filter_Command));
+   if (!cmd) return NULL;
+
+   cmd->id = ++(ctx->last_command_id);
+   cmd->ctx = ctx;
+   cmd->mode = mode;
+   cmd->input = input;
+   cmd->mask = mask;
+   cmd->output = output;
+
+   ctx->commands = eina_inlist_append(ctx->commands, EINA_INLIST_GET(cmd));
+   return cmd;
+}
+
+static void
+_command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd)
+{
+   if (!ctx || !cmd) return;
+   ctx->commands = eina_inlist_remove(ctx->commands, EINA_INLIST_GET(cmd));
+   switch (cmd->mode)
+     {
+      case EVAS_FILTER_MODE_CURVE: free(cmd->curve.data); break;
+      default: break;
+     }
+   free(cmd);
+}
+
+Evas_Filter_Command *
+_evas_filter_command_get(Evas_Filter_Context *ctx, int cmdid)
+{
+   Evas_Filter_Command *cmd;
+
+   if (cmdid <= 0) return NULL;
+
+   EINA_INLIST_FOREACH(ctx->commands, cmd)
+     if (cmd->id == cmdid) return cmd;
+
+   return NULL;
+}
+
+Evas_Filter_Buffer *
+evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h,
+                                 Eina_Bool alpha_only)
+{
+   Evas_Filter_Buffer *buf = NULL;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(ctx->buffers, l, buf)
+     {
+        if (buf->transient && !buf->locked && (buf->alpha_only == alpha_only))
+          {
+             if ((!w || (w == buf->w))
+                 && (!h || (h == buf->h)))
+               {
+                  buf->locked = EINA_TRUE;
+                  return buf;
+               }
+          }
+     }
+
+   if (ctx->running) // && ctx->async)
+     {
+        ERR("Can not create a new buffer from this thread!");
+        return NULL;
+     }
+
+   buf = _buffer_new(ctx, w, h, alpha_only);
+   buf->locked = EINA_TRUE;
+   DBG("Created temporary buffer: %d", buf->id);
+   return buf;
+}
+
+static void
+_filter_buffer_unlock_all(Evas_Filter_Context *ctx)
+{
+   Evas_Filter_Buffer *buf = NULL;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(ctx->buffers, l, buf)
+     buf->locked = EINA_FALSE;
+}
+
+int
+evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context,
+                             int bufid)
+{
+   Evas_Filter_Command *cmd;
+   Evas_Filter_Buffer *buf = NULL;
+   int R, G, B, A, cx, cy, cw, ch;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(draw_context, -1);
+
+   buf = _filter_buffer_get(ctx, bufid);
+   if (!buf)
+     {
+        ERR("Buffer %d does not exist.", bufid);
+        return -1;
+     }
+
+   cmd = _command_new(ctx, EVAS_FILTER_MODE_FILL, buf, NULL, buf);
+   if (!cmd) return -1;
+
+   ENFN->context_color_get(ENDT, draw_context, &R, &G, &B, &A);
+   DRAW_COLOR_SET(R, G, B, A);
+
+   ENFN->context_clip_get(ENDT, draw_context, &cx, &cy, &cw, &ch);
+   DRAW_CLIP_SET(cx, cy, cw, ch);
+
+   return cmd->id;
+}
+
+int
+evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
+                             int inbuf, int outbuf, Evas_Filter_Blur_Type type,
+                             int dx, int dy, int ox, int oy, int count)
+{
+   Evas_Filter_Command *cmd = NULL;
+   Evas_Filter_Buffer *in = NULL, *out = NULL, *tmp = NULL, *in_dy = NULL;
+   Evas_Filter_Buffer *out_dy = NULL, *out_dx = NULL;
+   Evas_Filter_Buffer *copybuf = NULL, *blur_out = NULL;
+   Eina_Bool copy_back = EINA_FALSE, convert = EINA_FALSE;
+   int R, G, B, A;
+   int ret = 0, id;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(drawctx, -1);
+
+   if (dx < 0) dx = 0;
+   if (dy < 0) dy = 0;
+   if (!dx && !dy) goto fail;
+
+   in = _filter_buffer_get(ctx, inbuf);
+   if (!in)
+     {
+        ERR("Buffer %d does not exist [input].", inbuf);
+        goto fail;
+     }
+
+   out = _filter_buffer_get(ctx, outbuf);
+   if (!out)
+     {
+        ERR("Buffer %d does not exist [output].", outbuf);
+        goto fail;
+     }
+
+   switch (type)
+     {
+      case EVAS_FILTER_BLUR_GAUSSIAN:
+        count = 1;
+        break;
+
+      case EVAS_FILTER_BLUR_BOX:
+        count = MIN(MAX(1, count), 6);
+        break;
+
+      case EVAS_FILTER_BLUR_DEFAULT:
+
+        /* In DEFAULT mode we cheat, depending on the size of the kernel:
+         * For 1px to 2px, use true Gaussian blur.
+         * For 3px to 6px, use two Box blurs.
+         * For more than 6px, use three Box blurs.
+         * This will give both nicer and MUCH faster results than Gaussian.
+         *
+         * NOTE: When implementing blur with GL shaders, other tricks will be
+         * needed, of course!
+         */
+        {
+           const Eina_Bool alpha = in->alpha_only;
+           int tmp_out = outbuf;
+           int tmp_in = inbuf;
+           int tmp_ox = ox;
+           int tmp_oy = oy;
+
+           id = -1;
+           if (dx && dy)
+             {
+                tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, alpha);
+                if (!tmp) goto fail;
+                tmp_in = tmp_out = tmp->id;
+                tmp_ox = tmp_oy = 0;
+             }
+
+           if (dx)
+             {
+                if (dx <= 2)
+                  type = EVAS_FILTER_BLUR_GAUSSIAN;
+                else
+                  type = EVAS_FILTER_BLUR_BOX;
+
+                id = evas_filter_command_blur_add(ctx, drawctx, inbuf, tmp_out,
+                                                  type, dx, 0, tmp_ox, tmp_oy, 0);
+                if (id < 0) goto fail;
+                cmd = _evas_filter_command_get(ctx, id);
+                cmd->blur.auto_count = EINA_TRUE;
+             }
+
+           if (dy)
+             {
+                if (dy <= 2)
+                  type = EVAS_FILTER_BLUR_GAUSSIAN;
+                else
+                  type = EVAS_FILTER_BLUR_BOX;
+
+                id = evas_filter_command_blur_add(ctx, drawctx, tmp_in, outbuf,
+                                                  type, 0, dy, ox, oy, 0);
+                if (id < 0) goto fail;
+                cmd = _evas_filter_command_get(ctx, id);
+                cmd->blur.auto_count = EINA_TRUE;
+             }
+
+           return id;
+        }
+        break;
+
+      default:
+        CRI("Not implemented yet!");
+        goto fail;
+     }
+
+   if (!in->alpha_only && out->alpha_only)
+     {
+        ERR("Output and input don't have the same format");
+        goto fail;
+     }
+   else if (in->alpha_only && !out->alpha_only)
+     {
+        DBG("Adding extra blending step (Alpha --> RGBA)");
+        blur_out = evas_filter_temporary_buffer_get(ctx, 0, 0, EINA_TRUE);
+        if (!blur_out) goto fail;
+        convert = EINA_TRUE;
+     }
+   else
+     blur_out = out;
+
+   if (dx && dy)
+     {
+        tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only);
+        if (!tmp) goto fail;
+
+        if (!convert && (ox || oy))
+          {
+             copybuf = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only);
+             if (!copybuf) goto fail;
+             copy_back = EINA_TRUE;
+          }
+
+        if (in == blur_out)
+          {
+             // IN = OUT and 2-D blur. IN -blur-> TMP -blur-> IN.
+             out_dx = tmp;
+             in_dy = tmp;
+             out_dy = copybuf ? copybuf : in;
+          }
+        else
+          {
+             // IN != OUT and 2-D blur. IN -blur-> TMP -blur-> OUT.
+             out_dx = tmp;
+             in_dy = tmp;
+             out_dy = copybuf ? copybuf : blur_out;
+          }
+     }
+   else if (dx)
+     {
+        if ((in == blur_out) || ox || oy)
+          {
+             // IN = OUT and 1-D blur. IN -blur-> TMP -copy-> IN.
+             tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only);
+             if (!tmp) goto fail;
+             copy_back = EINA_TRUE;
+             copybuf = tmp;
+             out_dx = tmp;
+          }
+        else
+          {
+             // IN != OUT and 1-D blur. IN -blur-> OUT.
+             out_dx = blur_out;
+          }
+     }
+   else
+     {
+        if ((in == blur_out) || ox || oy)
+          {
+             // IN = OUT and 1-D blur. IN -blur-> TMP -copy-> IN.
+             tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only);
+             if (!tmp) goto fail;
+             copy_back = EINA_TRUE;
+             copybuf = tmp;
+             in_dy = in;
+             out_dy = tmp;
+          }
+        else
+          {
+             // IN != OUT and 1-D blur. IN -blur-> OUT.
+             in_dy = in;
+             out_dy = blur_out;
+          }
+     }
+
+   ENFN->context_color_get(ENDT, drawctx, &R, &G, &B, &A);
+
+   if (dx)
+     {
+        DBG("Add horizontal blur %d -> %d (%dpx)", in->id, out_dx->id, dx);
+        cmd = _command_new(ctx, EVAS_FILTER_MODE_BLUR, in, NULL, out_dx);
+        if (!cmd) goto fail;
+        cmd->blur.type = type;
+        cmd->blur.dx = dx;
+        cmd->blur.dy = 0;
+        cmd->blur.count = count;
+        DRAW_COLOR_SET(R, G, B, A);
+        ret = cmd->id;
+     }
+
+   if (dy)
+     {
+        DBG("Add vertical blur %d -> %d (%dpx)", in_dy->id, out_dy->id, dy);
+        cmd = _command_new(ctx, EVAS_FILTER_MODE_BLUR, in_dy, NULL, out_dy);
+        if (!cmd) goto fail;
+        cmd->blur.type = type;
+        cmd->blur.dx = 0;
+        cmd->blur.dy = dy;
+        cmd->blur.count = count;
+        DRAW_COLOR_SET(R, G, B, A);
+        if (ret <= 0) ret = cmd->id;
+     }
+
+   if (copy_back)
+     {
+        int render_op;
+
+        if (!cmd) goto fail;
+        if (!copybuf) goto fail;
+        DBG("Add copy %d -> %d", copybuf->id, blur_out->id);
+        cmd->ENFN->context_color_set(cmd->ENDT, drawctx, 0, 0, 0, 255);
+        render_op = cmd->ENFN->context_render_op_get(cmd->ENDT, drawctx);
+        cmd->ENFN->context_render_op_set(cmd->ENDT, drawctx, EVAS_RENDER_COPY);
+        id = evas_filter_command_blend_add(ctx, drawctx, copybuf->id, blur_out->id, ox, oy, EVAS_FILTER_FILL_MODE_NONE);
+        cmd->ENFN->context_color_set(cmd->ENDT, drawctx, R, G, B, A);
+        cmd->ENFN->context_render_op_set(cmd->ENDT, drawctx, render_op);
+        if (id < 0) goto fail;
+        ox = oy = 0;
+     }
+
+   if (convert)
+     {
+        DBG("Add convert %d -> %d", blur_out->id, out->id);
+        id = evas_filter_command_blend_add(ctx, drawctx, blur_out->id, out->id, ox, oy, EVAS_FILTER_FILL_MODE_NONE);
+        if (id < 0) goto fail;
+     }
+
+   _filter_buffer_unlock_all(ctx);
+   return ret;
+
+fail:
+   ERR("Failed to add blur");
+   _filter_buffer_unlock_all(ctx);
+   return -1;
+}
+
+int
+evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx,
+                              int inbuf, int outbuf, int ox, int oy,
+                              Evas_Filter_Fill_Mode fillmode)
+{
+   Evas_Filter_Command *cmd;
+   Evas_Filter_Buffer *in, *out;
+   int R, G, B, A;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
+
+   if (inbuf == outbuf)
+     {
+        DBG("Skipping NOP blend operation %d --> %d", inbuf, outbuf);
+        return -1;
+     }
+
+   in = _filter_buffer_get(ctx, inbuf);
+   if (!in)
+     {
+        ERR("Buffer %d does not exist [input].", inbuf);
+        return -1;
+     }
+
+   out = _filter_buffer_get(ctx, outbuf);
+   if (!out)
+     {
+        ERR("Buffer %d does not exist [output].", outbuf);
+        return -1;
+     }
+
+   cmd = _command_new(ctx, EVAS_FILTER_MODE_BLEND, in, NULL, out);
+   if (!cmd) return -1;
+
+   ENFN->context_color_get(ENDT, drawctx, &R, &G, &B, &A);
+   DRAW_COLOR_SET(R, G, B, A);
+   DRAW_FILL_SET(fillmode);
+   cmd->draw.ox = ox;
+   cmd->draw.oy = oy;
+   cmd->draw.render_op = ENFN->context_render_op_get(ENDT, drawctx);
+   cmd->draw.clip_use =
+         ENFN->context_clip_get(ENDT, drawctx,
+                                &cmd->draw.clip.x, &cmd->draw.clip.y,
+                                &cmd->draw.clip.w, &cmd->draw.clip.h);
+
+   if (cmd->draw.clip_use)
+     DBG("Draw clip: %d,%d,%d,%d", cmd->draw.clip.x, cmd->draw.clip.y,
+         cmd->draw.clip.w, cmd->draw.clip.h);
+
+   return cmd->id;
+}
+
+int
+evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
+                             int inbuf, int outbuf, int radius, Eina_Bool smooth)
+{
+   int blurcmd, threshcmd, blendcmd, tmin = 0, growbuf;
+   int diam = abs(radius) * 2 + 1;
+   DATA8 curve[256] = {0};
+   Evas_Filter_Buffer *tmp = NULL, *in;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
+
+   in = _filter_buffer_get(ctx, inbuf);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(in, -1);
+
+   if (inbuf != outbuf)
+     {
+        tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only);
+        EINA_SAFETY_ON_NULL_RETURN_VAL(tmp, -1);
+        growbuf = tmp->id;
+     }
+   else
+     growbuf = outbuf;
+
+   blurcmd = evas_filter_command_blur_add(ctx, draw_context, inbuf, growbuf,
+                                          EVAS_FILTER_BLUR_DEFAULT,
+                                          abs(radius), abs(radius), 0, 0, 0);
+   if (blurcmd < 0) return -1;
+
+   if (diam > 255) diam = 255;
+   if (radius > 0)
+     tmin = 255 / diam;
+   else if (radius < 0)
+     tmin = 256 - (255 / diam);
+
+   if (!smooth)
+     memset(curve + tmin, 255, 256 - tmin);
+   else
+     {
+        int k, start, end, range;
+
+        // This is pretty experimental.
+        range = MAX(2, 12 - radius);
+        start = ((tmin > range) ? (tmin - range) : 0);
+        end = ((tmin < (256 - range)) ? (tmin + range) : 256);
+
+        for (k = start; k < end; k++)
+          curve[k] = ((k - start) * 255) / (end - start);
+        if (end < 256)
+          memset(curve + end, 255, 256 - end);
+     }
+
+   threshcmd = evas_filter_command_curve_add(ctx, draw_context, growbuf, growbuf,
+                                             curve, EVAS_FILTER_CHANNEL_ALPHA);
+   if (threshcmd < 0)
+     {
+        _command_del(ctx, _evas_filter_command_get(ctx, blurcmd));
+        return -1;
+     }
+
+   if (tmp)
+     {
+        blendcmd = evas_filter_command_blend_add(ctx, draw_context, tmp->id,
+                                                 outbuf, 0, 0,
+                                                 EVAS_FILTER_FILL_MODE_NONE);
+        if (blendcmd < 0)
+          {
+             _command_del(ctx, _evas_filter_command_get(ctx, threshcmd));
+             _command_del(ctx, _evas_filter_command_get(ctx, blurcmd));
+             return -1;
+          }
+     }
+
+   return blurcmd;
+}
+
+int
+evas_filter_command_curve_add(Evas_Filter_Context *ctx,
+                              void *draw_context EINA_UNUSED,
+                              int inbuf, int outbuf, DATA8 *curve,
+                              Evas_Filter_Channel channel)
+{
+   Evas_Filter_Command *cmd;
+   Evas_Filter_Buffer *in, *out;
+   DATA8 *copy;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(curve, -1);
+
+   in = _filter_buffer_get(ctx, inbuf);
+   out = _filter_buffer_get(ctx, outbuf);
+   if (!in || !out)
+     {
+        ERR("Invalid buffer id: input %d [%p], output %d [%p]",
+            inbuf, in, outbuf, out);
+        return -1;
+     }
+
+   if (in->alpha_only != out->alpha_only)
+     {
+        ERR("Incompatible formats for color curves");
+        return -1;
+     }
+
+   copy = malloc(256 * sizeof(DATA8));
+   if (!copy) return -1;
+
+   cmd = _command_new(ctx, EVAS_FILTER_MODE_CURVE, in, NULL, out);
+   if (!cmd)
+     {
+        free(copy);
+        return -1;
+     }
+
+   memcpy(copy, curve, 256 * sizeof(DATA8));
+   cmd->curve.data = copy;
+   cmd->curve.channel = channel;
+
+   return cmd->id;
+}
+
+int
+evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx,
+                                         void *draw_context EINA_UNUSED,
+                                         int inbuf, int outbuf, int dispbuf,
+                                         Evas_Filter_Displacement_Flags flags,
+                                         int intensity,
+                                         Evas_Filter_Fill_Mode fillmode)
+{
+   Evas_Filter_Command *cmd;
+   Evas_Filter_Buffer *in, *out, *map, *tmp = NULL, *disp_out;
+   int cmdid = -1;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(intensity >= 0, EINA_FALSE);
+
+   in = _filter_buffer_get(ctx, inbuf);
+   out = _filter_buffer_get(ctx, outbuf);
+   map = _filter_buffer_get(ctx, dispbuf);
+   if (!in || !out || !map)
+     {
+        ERR("Invalid buffer id: input %d [%p], output %d [%p], map %d [%p]",
+            inbuf, in, outbuf, out, dispbuf, map);
+        return -1;
+     }
+
+   if (in->alpha_only != out->alpha_only)
+     {
+        ERR("Incompatible formats for displacement map");
+        return -1;
+     }
+
+   if (in == out)
+     {
+        tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only);
+        if (!tmp) return -1;
+        disp_out = tmp;
+     }
+   else disp_out = out;
+
+   cmd = _command_new(ctx, EVAS_FILTER_MODE_DISPLACE, in, map, disp_out);
+   if (!cmd) goto end;
+
+   DRAW_FILL_SET(fillmode);
+   cmd->displacement.flags = flags & EVAS_FILTER_DISPLACE_BITMASK;
+   cmd->displacement.intensity = intensity;
+   cmd->draw.render_op = ENFN->context_render_op_get(ENDT, draw_context);
+   cmdid = cmd->id;
+
+   if (tmp)
+     {
+        if (evas_filter_command_blend_add(ctx, draw_context, disp_out->id,
+                                          out->id, 0, 0,
+                                          EVAS_FILTER_FILL_MODE_NONE) < 0)
+          {
+             _command_del(ctx, _evas_filter_command_get(ctx, cmdid));
+             cmdid = -1;
+          }
+     }
+
+end:
+   _filter_buffer_unlock_all(ctx);
+   return cmdid;
+}
+
+int
+evas_filter_command_mask_add(Evas_Filter_Context *ctx, void *draw_context,
+                             int inbuf, int maskbuf, int outbuf,
+                             Evas_Filter_Fill_Mode fillmode)
+{
+   Evas_Filter_Command *cmd;
+   Evas_Filter_Buffer *in, *out, *mask;
+   int cmdid = -1, render_op;
+   int R, G, B, A;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
+
+   render_op = ENFN->context_render_op_get(ENDT, draw_context);
+   ENFN->context_color_get(ENDT, draw_context, &R, &G, &B, &A);
+
+   in = _filter_buffer_get(ctx, inbuf);
+   out = _filter_buffer_get(ctx, outbuf);
+   mask = _filter_buffer_get(ctx, maskbuf);
+   if (!in || !out || !mask)
+     {
+        ERR("Invalid buffer id: input %d [%p], output %d [%p], mask %d [%p]",
+            inbuf, in, outbuf, out, maskbuf, mask);
+        return -1;
+     }
+
+   cmd = _command_new(ctx, EVAS_FILTER_MODE_MASK, in, mask, out);
+   if (!cmd) goto end;
+
+   cmd->draw.render_op = render_op;
+   DRAW_COLOR_SET(R, G, B, A);
+   DRAW_FILL_SET(fillmode);
+
+   cmdid = cmd->id;
+
+end:
+   _filter_buffer_unlock_all(ctx);
+   return cmdid;
+}
+
+int
+evas_filter_command_bump_map_add(Evas_Filter_Context *ctx,
+                                 void *draw_context EINA_UNUSED,
+                                 int inbuf, int bumpbuf, int outbuf,
+                                 float xyangle, float zangle, float elevation,
+                                 float sf,
+                                 DATA32 black, DATA32 color, DATA32 white,
+                                 Evas_Filter_Bump_Flags flags,
+                                 Evas_Filter_Fill_Mode fillmode)
+{
+   Evas_Filter_Command *cmd;
+   Evas_Filter_Buffer *in, *out, *bumpmap;
+   int cmdid = -1;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
+
+   in = _filter_buffer_get(ctx, inbuf);
+   out = _filter_buffer_get(ctx, outbuf);
+   bumpmap = _filter_buffer_get(ctx, bumpbuf);
+   if (!in || !out || !bumpmap)
+     {
+        ERR("Invalid buffer id: input %d [%p], output %d [%p], bumpmap %d [%p]",
+            inbuf, in, outbuf, out, bumpbuf, bumpmap);
+        return -1;
+     }
+
+   // FIXME: Must ensure in != out
+   if (in == out) CRI("Not acceptable");
+   if (bumpmap == out) CRI("Not acceptable");
+
+   cmd = _command_new(ctx, EVAS_FILTER_MODE_BUMP, in, bumpmap, out);
+   if (!cmd) goto end;
+
+   DRAW_FILL_SET(fillmode);
+   cmd->bump.xyangle = xyangle;
+   cmd->bump.zangle = zangle;
+   cmd->bump.specular_factor = sf;
+   cmd->bump.dark = black;
+   cmd->bump.color = color;
+   cmd->bump.white = white;
+   cmd->bump.elevation = elevation;
+   cmd->bump.compensate = !!(flags & EVAS_FILTER_BUMP_COMPENSATE);
+   cmdid = cmd->id;
+
+end:
+   _filter_buffer_unlock_all(ctx);
+   return cmdid;
+}
+
+int
+evas_filter_command_transform_add(Evas_Filter_Context *ctx,
+                                  void *draw_context EINA_UNUSED,
+                                  int inbuf, int outbuf,
+                                  Evas_Filter_Transform_Flags flags,
+                                  int ox, int oy)
+{
+   Evas_Filter_Command *cmd;
+   Evas_Filter_Buffer *in, *out;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
+
+   in = _filter_buffer_get(ctx, inbuf);
+   out = _filter_buffer_get(ctx, outbuf);
+   if (!in || !out)
+     {
+        ERR("Invalid buffer id: input %d [%p], output %d [%p]",
+            inbuf, in, outbuf, out);
+        return -1;
+     }
+
+   if (in->alpha_only != out->alpha_only)
+     {
+        CRI("Incompatible buffer formats");
+        return -1;
+     }
+
+   cmd = _command_new(ctx, EVAS_FILTER_MODE_TRANSFORM, in, NULL, out);
+   if (!cmd) return -1;
+
+   cmd->transform.flags = flags;
+   cmd->draw.ox = ox;
+   cmd->draw.oy = oy;
+
+   return cmd->id;
+}
+
+static Eina_Bool
+_fill_cpu(Evas_Filter_Command *cmd)
+{
+   Evas_Filter_Buffer *fb = cmd->output;
+   int step = fb->alpha_only ? sizeof(DATA8) : sizeof(DATA32);
+   int x = MAX(0, cmd->draw.clip.x);
+   int y = MAX(0, cmd->draw.clip.y);
+   DATA8 *ptr = ((RGBA_Image *) fb->backing)->image.data8;
+   int w, h, k, j;
+
+   if (!cmd->draw.clip_mode_lrtb)
+     {
+        if (cmd->draw.clip.w)
+          w = MIN(cmd->draw.clip.w, fb->w - x);
+        else
+          w = fb->w - x;
+        if (cmd->draw.clip.h)
+          h = MIN(cmd->draw.clip.h, fb->h - y);
+        else
+          h = fb->h - y;
+     }
+   else
+     {
+        x = MAX(0, cmd->draw.clip.l);
+        y = MAX(0, cmd->draw.clip.t);
+        w = CLAMP(0, fb->w - x - cmd->draw.clip.r, fb->w - x);
+        h = CLAMP(0, fb->h - y - cmd->draw.clip.b, fb->h - y);
+     }
+
+   ptr += y * step * fb->w;
+   if ((fb->alpha_only)
+       || (!cmd->draw.R && !cmd->draw.G && !cmd->draw.B && !cmd->draw.A)
+       || ((cmd->draw.R == 0xff) && (cmd->draw.G == 0xff)
+           && (cmd->draw.B == 0xff) && (cmd->draw.A == 0xff)))
+     {
+        for (k = 0; k < h; k++)
+          {
+             memset(ptr + (x * step), cmd->draw.A, step * w);
+             ptr += step * fb->w;
+          }
+     }
+   else
+     {
+        DATA32 *dst = ((DATA32 *) ptr) + x;
+        DATA32 color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
+        for (k = 0; k < h; k++)
+          {
+             for (j = 0; j < w; j++)
+               *dst++ = color;
+             dst += fb->w - w;
+          }
+     }
+
+   return EINA_TRUE;
+}
+
+Evas_Filter_Apply_Func
+evas_filter_fill_cpu_func_get(Evas_Filter_Command *cmd)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
+   return _fill_cpu;
+}
+
+
+/* Final target */
+Eina_Bool
+evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
+                       void *surface, int x, int y)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
+
+   ctx->target.bufid = evas_filter_buffer_image_new(ctx, surface);
+   ctx->target.x = x;
+   ctx->target.y = y;
+   ctx->target.clip_use = ENFN->context_clip_get
+         (ENDT, draw_context, &ctx->target.cx, &ctx->target.cy,
+          &ctx->target.cw, &ctx->target.ch);
+   ctx->target.color_use = ENFN->context_multiplier_get
+         (ENDT, draw_context, &ctx->target.r, &ctx->target.g,
+          &ctx->target.b, &ctx->target.a);
+   if (ctx->target.r == 255 && ctx->target.g == 255 &&
+       ctx->target.b == 255 && ctx->target.a == 255)
+     ctx->target.color_use = EINA_FALSE;
+
+   ENFN->context_clip_image_get
+      (ENDT, draw_context, &ctx->target.mask, &ctx->target.mask_x, &ctx->target.mask_y);
+
+   if (ctx->gl_engine)
+     {
+        // Since GL has sync rendering, draw_context is safe to keep around
+        Evas_Filter_Buffer *fb;
+
+        ctx->target.context = draw_context;
+
+        fb = _filter_buffer_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID);
+        EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
+
+        fb->glimage = ENFN->image_new_from_data
+          (ENDT, fb->w, fb->h, fb->backing->image.data, EINA_TRUE,
+           fb->backing->cache_entry.space);
+
+        DBG("Set target as #%d (%p) and output #%d (%p, gl %p)",
+            ctx->target.bufid, surface, fb->id, fb->backing, fb->glimage);
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_filter_target_render(Evas_Filter_Context *ctx)
+{
+   Evas_Filter_Buffer *src, *dst;
+   void *drawctx, *image, *surface;
+   int cx, cy, cw, ch;
+   Eina_Bool use_clip = EINA_FALSE;
+
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(ctx->target.bufid, EINA_FALSE);
+
+   src = _filter_buffer_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID);
+   dst = _filter_buffer_get(ctx, ctx->target.bufid);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+
+   if (!ctx->gl_engine)
+     {
+        drawctx = ENFN->context_new(ENDT);
+        surface = dst->backing;
+        image = src->backing;
+     }
+   else
+     {
+        drawctx = ctx->target.context;
+        surface = dst->glimage;
+        if (src->glimage)
+          {
+             DBG("Using glimage from output buffer.");
+             if (src->backing)
+               ENFN->image_data_put(ENDT, src->glimage, src->backing->image.data);
+          }
+        else
+          {
+             RGBA_Image *im = src->backing;
+
+             DBG("Creating glimage from output buffer.");
+             src->glimage = ENFN->image_new_from_data(ENDT, src->w, src->h,
+                                               im->image.data, EINA_TRUE,
+                                               EVAS_COLORSPACE_ARGB8888);
+          }
+        image = src->glimage;
+     }
+   EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
+
+   if (ctx->target.clip_use)
+     {
+        use_clip = ENFN->context_clip_get(ENDT, drawctx, &cx, &cy, &cw, &ch);
+        ENFN->context_clip_set(ENDT, drawctx, ctx->target.cx, ctx->target.cy,
+                               ctx->target.cw, ctx->target.ch);
+     }
+
+   if (ctx->target.color_use)
+     {
+        ENFN->context_multiplier_set(ENDT, drawctx,
+                                     ctx->target.r, ctx->target.g,
+                                     ctx->target.b, ctx->target.a);
+     }
+   else
+     {
+        ENFN->context_multiplier_unset(ENDT, drawctx);
+     }
+
+   if (ctx->target.mask)
+     ENFN->context_clip_image_set(ENDT, drawctx,
+                                  ctx->target.mask, ctx->target.mask_x, ctx->target.mask_y);
+   else
+     ENFN->context_clip_image_unset(ENDT, drawctx);
+
+#ifdef HAS_DO_ASYNC
+   ENFN->image_draw(ENDT, drawctx, surface, image,
+                    0, 0, src->w, src->h,
+                    ctx->target.x, ctx->target.y, src->w, src->h,
+                    EINA_TRUE, EINA_FALSE);
+#else
+   ENFN->image_draw(ENDT, drawctx, surface, image,
+                    0, 0, src->w, src->h,
+                    ctx->target.x, ctx->target.y, src->w, src->h,
+                    EINA_TRUE);
+#endif
+
+   if (ctx->target.mask)
+     ENFN->context_clip_image_unset(ENDT, drawctx);
+
+   if (!ctx->gl_engine)
+     ENFN->context_free(ENDT, drawctx);
+   else if (use_clip)
+     ENFN->context_clip_set(ENDT, drawctx, cx, cy, cw, ch);
+   else
+     ENFN->context_clip_unset(ENDT, drawctx);
+
+   return EINA_TRUE;
+}
+
+
+/* Font drawing stuff */
+Eina_Bool
+evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
+                      Evas_Font_Set *font, int x, int y,
+                      Evas_Text_Props *text_props, Eina_Bool do_async)
+{
+   Eina_Bool async_unref;
+   Evas_Filter_Buffer *fb;
+   void *surface;
+
+   fb = _filter_buffer_get(ctx, bufid);
+   if (!fb) return EINA_FALSE;
+
+   surface = fb->backing;
+   if (!surface) return EINA_FALSE;
+
+   if (!ctx->gl_engine)
+     {
+        // Copied from evas_font_draw_async_check
+#ifdef HAS_DO_ASYNC
+        async_unref = ENFN->font_draw(ENDT, draw_context, surface,
+                                      font, x, y, fb->w, fb->h, fb->w, fb->h,
+                                      text_props, do_async);
+        if (do_async && async_unref)
+          {
+             evas_common_font_glyphs_ref(text_props->glyphs);
+             evas_unref_queue_glyph_put(ctx->evas, text_props->glyphs);
+          }
+#else
+        ENFN->font_draw(ENDT, draw_context, surface,
+                        font, x, y, fb->w, fb->h, fb->w, fb->h,
+                        text_props);
+#endif
+     }
+   else
+     {
+        // FIXME/GL: Render in software only.
+        // Copied from eng_font_draw in the software engine.
+
+        if (do_async) WRN("Async flag is ignored here!");
+        evas_common_font_draw_prepare(text_props);
+#if (VMAJ == 1) && (VMIN == 7)
+        evas_common_font_draw(surface, draw_context, x, y, text_props);
+#else
+        evas_common_font_draw(surface, draw_context, x, y, text_props->glyphs);
+#endif
+        evas_common_cpu_end_opt();
+     }
+
+   return EINA_TRUE;
+}
+
+
+/* Clip full input rect (0, 0, sw, sh) to target (dx, dy, dw, dh)
+ * and get source's clipped sx, sy as well as destination x, y, cols and rows */
+void
+_clip_to_target(int *sx /* OUT */, int *sy /* OUT */, int sw, int sh,
+                int ox, int oy, int dw, int dh,
+                int *dx /* OUT */, int *dy /* OUT */,
+                int *rows /* OUT */, int *cols /* OUT */)
+{
+   if (ox > 0)
+     {
+        (*sx) = 0;
+        (*dx) = ox;
+        (*cols) = sw;
+        if (((*dx) + (*cols)) > (dw))
+          (*cols) = dw - (*dx);
+     }
+   else if (ox < 0)
+     {
+        (*dx) = 0;
+        (*sx) = (-ox);
+        (*cols) = sw - (*sx);
+        if ((*cols) > dw) (*cols) = dw;
+     }
+   else
+     {
+        (*sx) = 0;
+        (*dx) = 0;
+        (*cols) = sw;
+        if ((*cols) > dw) (*cols) = dw;
+     }
+
+   if (oy > 0)
+     {
+        (*sy) = 0;
+        (*dy) = oy;
+        (*rows) = sh;
+        if (((*dy) + (*rows)) > (dh))
+          (*rows) = dh - (*dy);
+     }
+   else if (oy < 0)
+     {
+        (*dy) = 0;
+        (*sy) = (-oy);
+        (*rows) = sh - (*sy);
+        if ((*rows) > dh) (*rows) = dh;
+     }
+   else
+     {
+        (*sy) = 0;
+        (*dy) = 0;
+        (*rows) = sh;
+        if ((*rows) > dh) (*rows) = dh;
+     }
+}
+
+static const char *
+_filter_name_get(int mode)
+{
+#define FNAME(a) case EVAS_FILTER_MODE_ ## a: return "EVAS_FILTER_MODE_" #a
+   switch (mode)
+     {
+      FNAME(BLEND);
+      FNAME(BLUR);
+      FNAME(CURVE);
+      FNAME(DISPLACE);
+      FNAME(MASK);
+      FNAME(BUMP);
+      FNAME(FILL);
+      default: return "INVALID";
+     }
+#undef FNAME
+}
+
+static Eina_Bool
+_filter_command_run(Evas_Filter_Command *cmd)
+{
+   Evas_Filter_Apply_Func func = NULL;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, EINA_FALSE);
+
+   DBG("Command %d (%s): %d [%d] --> %d",
+       cmd->id, _filter_name_get(cmd->mode),
+       cmd->input->id, cmd->mask ? cmd->mask->id : 0, cmd->output->id);
+
+   if (!cmd->input->w && !cmd->input->h
+       && (cmd->mode != EVAS_FILTER_MODE_FILL))
+     {
+        DBG("Skipping processing of empty input buffer (size 0x0)");
+        return EINA_TRUE;
+     }
+
+   if ((cmd->output->w <= 0) || (cmd->output->h <= 0))
+     {
+        ERR("Output size invalid: %dx%d", cmd->output->w, cmd->output->h);
+        return EINA_FALSE;
+     }
+
+   //func = cmd->ENFN->filter_command_func_get(cmd);
+   // FIXME: Must call engine function, not CPU directly.
+
+   switch (cmd->mode)
+     {
+      case EVAS_FILTER_MODE_BLEND:
+        func = evas_filter_blend_cpu_func_get(cmd);
+        break;
+      case EVAS_FILTER_MODE_BLUR:
+        func = evas_filter_blur_cpu_func_get(cmd);
+        break;
+      case EVAS_FILTER_MODE_CURVE:
+        func = evas_filter_curve_cpu_func_get(cmd);
+        break;
+      case EVAS_FILTER_MODE_DISPLACE:
+        func = evas_filter_displace_cpu_func_get(cmd);
+        break;
+      case EVAS_FILTER_MODE_FILL:
+        func = evas_filter_fill_cpu_func_get(cmd);
+        break;
+      case EVAS_FILTER_MODE_MASK:
+        func = evas_filter_mask_cpu_func_get(cmd);
+        break;
+      case EVAS_FILTER_MODE_BUMP:
+        func = evas_filter_bump_map_cpu_func_get(cmd);
+        break;
+      case EVAS_FILTER_MODE_TRANSFORM:
+        func = evas_filter_transform_cpu_func_get(cmd);
+        break;
+      default:
+        CRI("Invalid filter mode.");
+        break;
+     }
+
+   // END OF FIXME
+
+   if (!func)
+     {
+        CRI("No function to process this filter!");
+        return EINA_FALSE;
+     }
+
+   return func(cmd);
+}
+
+static Eina_Bool
+_filter_chain_run(Evas_Filter_Context *ctx)
+{
+   Evas_Filter_Command *cmd;
+   Eina_Bool ok = EINA_FALSE;
+   void *buffer;
+
+   DEBUG_TIME_BEGIN();
+
+   ctx->running = EINA_TRUE;
+   EINA_INLIST_FOREACH(ctx->commands, cmd)
+     {
+        ok = _filter_command_run(cmd);
+        if (!ok)
+          {
+             ERR("Filter processing failed!");
+             goto end;
+          }
+     }
+
+   ok = _filter_target_render(ctx);
+
+end:
+   ctx->running = EINA_FALSE;
+   DEBUG_TIME_END();
+
+   EINA_LIST_FREE(ctx->post_run.buffers_to_free, buffer)
+     {
+        if (ctx->gl_engine)
+          ENFN->image_free(ENDT, buffer);
+     }
+
+   return ok;
+}
+
+static void
+_filter_thread_run_cb(void *data)
+{
+   Evas_Filter_Context *ctx = data;
+   Eina_Bool success;
+
+   success = _filter_chain_run(ctx);
+
+   if (ctx->post_run.cb)
+     ctx->post_run.cb(ctx, ctx->post_run.data, success);
+}
+
+Eina_Bool
+evas_filter_run(Evas_Filter_Context *ctx)
+{
+   Eina_Bool ret;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
+
+   if (!ctx->commands)
+     return EINA_TRUE;
+
+   if (ctx->gl_engine)
+     INF("EXPERIMENTAL OpenGL support! The text filters will be very slow!");
+
+#ifdef HAS_DO_ASYNC
+   if (ctx->async)
+     {
+        evas_thread_cmd_enqueue(_filter_thread_run_cb, ctx);
+        return EINA_TRUE;
+     }
+#endif
+
+   ret = _filter_chain_run(ctx);
+
+   if (ctx->post_run.cb)
+     ctx->post_run.cb(ctx, ctx->post_run.data, ret);
+   return ret;
+}
diff --git a/src/lib/filters/evas_filter_blend.c b/src/lib/filters/evas_filter_blend.c
new file mode 100644 (file)
index 0000000..49c9479
--- /dev/null
@@ -0,0 +1,518 @@
+#include "evas_filter.h"
+#include "evas_filter_private.h"
+#include "evas_blend_private.h"
+
+// Use a better formula than R+G+B for rgba to alpha conversion (RGB to YCbCr)
+#define RGBA2ALPHA_WEIGHTED 1
+
+static Eina_Bool _mapped_blend(void *data, void *drawctx, void *in, void *out, Evas_Filter_Fill_Mode fillmode, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, image_draw_func image_draw);
+
+struct Filter_Blend_Draw_Context
+{
+   int render_op;
+   DATA32 color;
+};
+
+static Eina_Bool
+_image_draw_cpu_alpha2alpha(void *data EINA_UNUSED, void *context,
+                            void *surface, void *image,
+                            int src_x, int src_y, int src_w, int src_h,
+                            int dst_x, int dst_y, int dst_w, int dst_h,
+                            int smooth EINA_UNUSED ARG_DO_ASYNC)
+{
+   struct Filter_Blend_Draw_Context *dc = context;
+   RGBA_Image *src = image;
+   RGBA_Image *dst = surface;
+   DATA8* srcdata = src->image.data8;
+   DATA8* dstdata = dst->image.data8;
+   Alpha_Gfx_Func func;
+   int y, sw, dw;
+
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
+
+   func = evas_common_alpha_func_get(dc->render_op);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
+
+   sw = src->cache_entry.w;
+   dw = dst->cache_entry.w;
+
+   srcdata += src_y * sw;
+   dstdata += dst_y * dw;
+   for (y = src_h; y; y--)
+     {
+        func(srcdata + src_x, dstdata + dst_x, src_w);
+        srcdata += sw;
+        dstdata += dw;
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_image_draw_cpu_alpha2rgba(void *data EINA_UNUSED, void *context,
+                           void *surface, void *image,
+                           int src_x, int src_y, int src_w, int src_h,
+                           int dst_x, int dst_y, int dst_w, int dst_h,
+                           int smooth EINA_UNUSED ARG_DO_ASYNC)
+{
+   struct Filter_Blend_Draw_Context *dc = context;
+   RGBA_Image *src = image;
+   RGBA_Image *dst = surface;
+   DATA8* srcdata = src->image.data8;
+   DATA32* dstdata = dst->image.data;
+   RGBA_Gfx_Func func;
+   int y, sw, dw;
+
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
+
+   func = evas_common_gfx_func_composite_mask_color_span_get
+     (dc->color, surface, 1, dc->render_op);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
+
+   sw = src->cache_entry.w;
+   dw = dst->cache_entry.w;
+
+   srcdata += src_y * sw;
+   dstdata += dst_y * dw;
+   for (y = src_h; y; y--)
+     {
+        func(NULL, srcdata + src_x, dc->color, dstdata + dst_x, src_w);
+        srcdata += sw;
+        dstdata += dw;
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_filter_blend_cpu_generic_do(Evas_Filter_Command *cmd,
+                             image_draw_func image_draw)
+{
+   RGBA_Image *in, *out;
+   int sw, sh, dx, dy, dw, dh, sx, sy;
+   struct Filter_Blend_Draw_Context dc;
+
+   in = cmd->input->backing;
+   out = cmd->output->backing;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
+
+   sx = 0;
+   sy = 0;
+   sw = in->cache_entry.w;
+   sh = in->cache_entry.h;
+
+   dx = cmd->draw.ox;
+   dy = cmd->draw.oy;
+   dw = out->cache_entry.w;
+   dh = out->cache_entry.h;
+
+   if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0))
+     return EINA_TRUE;
+
+   // Stretch if necessary.
+
+   /* NOTE: As of 2014/03/11, this will happen only with RGBA buffers, since
+    * only proxy sources may be scaled. So, we don't need an alpha scaling
+    * algorithm just now.
+    */
+
+   if ((sw != dw || sh != dh) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
+     {
+        Evas_Filter_Buffer *fb;
+
+        if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
+          sw = dw;
+        if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
+          sh = dh;
+
+        BUFFERS_LOCK();
+        fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->input, sw, sh);
+        BUFFERS_UNLOCK();
+
+        EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
+        fb->locked = EINA_FALSE;
+        in = fb->backing;
+     }
+
+   dc.render_op = cmd->draw.render_op;
+   dc.color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
+   return _mapped_blend(cmd->ENDT, &dc, in, out, cmd->draw.fillmode,
+                        sx, sy, sw, sh, dx, dy, dw, dh, image_draw);
+}
+
+static Eina_Bool
+_image_draw_cpu_rgba2alpha(void *data EINA_UNUSED, void *context EINA_UNUSED,
+                           void *surface, void *image,
+                           int src_x, int src_y, int src_w, int src_h,
+                           int dst_x, int dst_y, int dst_w, int dst_h,
+                           int smooth EINA_UNUSED ARG_DO_ASYNC)
+{
+   RGBA_Image *src = image;
+   RGBA_Image *dst = surface;
+   DATA32* srcdata = src->image.data;
+   DATA8* dstdata = dst->image.data8;
+   int x, y, sw, dw;
+#if RGBA2ALPHA_WEIGHTED
+   const int WR = 299;
+   const int WG = 587;
+   const int WB = 114;
+#else
+   const int WR = 1;
+   const int WG = 1;
+   const int WB = 1;
+#endif
+   DEFINE_DIVIDER(WR + WG + WB);
+
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
+
+   sw = src->cache_entry.w;
+   dw = dst->cache_entry.w;
+
+   srcdata += src_y * sw;
+   dstdata += dst_y * dw;
+   for (y = src_h; y; y--)
+     {
+        DATA32 *s = srcdata + src_x;
+        DATA8 *d = dstdata + dst_x;
+        for (x = src_w; x; x--, d++, s++)
+          *d = DIVIDE((R_VAL(s) * WR) + (G_VAL(s) * WG) + (B_VAL(s) * WB));
+        srcdata += sw;
+        dstdata += dw;
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_image_draw_cpu_rgba2rgba(void *data EINA_UNUSED, void *context,
+                          void *surface, void *image,
+                          int src_x, int src_y, int src_w, int src_h,
+                          int dst_x, int dst_y, int dst_w, int dst_h,
+                          int smooth EINA_UNUSED,
+                          Eina_Bool do_async EINA_UNUSED)
+{
+   struct Filter_Blend_Draw_Context *dc = context;
+   RGBA_Image *src = image;
+   RGBA_Image *dst = surface;
+   DATA32* srcdata = src->image.data;
+   DATA32* dstdata = dst->image.data;
+   RGBA_Gfx_Func func;
+   int y, sw, dw;
+
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
+
+   func = evas_common_gfx_func_composite_pixel_span_get(image, surface, 1, dc->render_op);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
+
+   sw = src->cache_entry.w;
+   dw = dst->cache_entry.w;
+
+   srcdata += src_y * sw;
+   dstdata += dst_y * dw;
+   for (y = src_h; y; y--)
+     {
+        func(srcdata + src_x, NULL, dc->color, dstdata + dst_x, src_w);
+        srcdata += sw;
+        dstdata += dw;
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_filter_blend_cpu_alpha(Evas_Filter_Command *cmd)
+{
+   return _filter_blend_cpu_generic_do(cmd, (image_draw_func) _image_draw_cpu_alpha2alpha);
+}
+
+static Eina_Bool
+_filter_blend_cpu_mask_rgba(Evas_Filter_Command *cmd)
+{
+   return _filter_blend_cpu_generic_do(cmd, (image_draw_func) _image_draw_cpu_alpha2rgba);
+}
+
+static Eina_Bool
+_filter_blend_cpu_rgba2alpha(Evas_Filter_Command *cmd)
+{
+   return _filter_blend_cpu_generic_do(cmd, (image_draw_func) _image_draw_cpu_rgba2alpha);
+}
+
+static Eina_Bool
+_filter_blend_cpu_rgba(Evas_Filter_Command *cmd)
+{
+   RGBA_Image *in, *out;
+   RGBA_Draw_Context *drawctx;
+   int sw, sh, dx, dy, dw, dh, sx, sy;
+   Eina_Bool ret;
+
+   in = cmd->input->backing;
+   out = cmd->output->backing;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
+
+   if (cmd->ctx->gl_engine)
+     return _filter_blend_cpu_generic_do(cmd, (image_draw_func) _image_draw_cpu_rgba2rgba);
+
+   sx = 0;
+   sy = 0;
+   sw = in->cache_entry.w;
+   sh = in->cache_entry.h;
+
+   dx = cmd->draw.ox;
+   dy = cmd->draw.oy;
+   dw = out->cache_entry.w;
+   dh = out->cache_entry.h;
+
+   if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0))
+     return EINA_TRUE;
+
+   drawctx = cmd->ENFN->context_new(cmd->ENDT);
+   cmd->ENFN->context_color_set(cmd->ENDT, drawctx, cmd->draw.R, cmd->draw.G,
+                                cmd->draw.B, cmd->draw.A);
+   cmd->ENFN->context_render_op_set(cmd->ENDT, drawctx, cmd->draw.render_op);
+
+   if (cmd->draw.clip_use)
+     {
+        cmd->ENFN->context_clip_set(cmd->ENDT, drawctx,
+                                    cmd->draw.clip.x, cmd->draw.clip.y,
+                                    cmd->draw.clip.w, cmd->draw.clip.h);
+        cmd->ENFN->context_clip_clip(cmd->ENDT, drawctx, 0, 0,
+                                     out->cache_entry.w, out->cache_entry.h);
+     }
+   else
+     {
+        cmd->ENFN->context_clip_set(cmd->ENDT, drawctx, 0, 0,
+                                    out->cache_entry.w, out->cache_entry.h);
+     }
+
+   ret = _mapped_blend(cmd->ENDT, drawctx, in, out, cmd->draw.fillmode,
+                       sx, sy, sw, sh, dx, dy, dw, dh,
+                       cmd->ENFN->image_draw);
+
+   cmd->ENFN->context_free(cmd->ENDT, drawctx);
+   return ret;
+}
+
+static Eina_Bool
+_mapped_blend(void *data, void *drawctx,
+              void *in, void *out,
+              Evas_Filter_Fill_Mode fillmode,
+              int sx, int sy,
+              int sw, int sh,
+              int dx, int dy,
+              int dw, int dh,
+              image_draw_func image_draw)
+{
+   int right = 0, bottom = 0, left = 0, top = 0;
+   int row, col, rows, cols;
+   Eina_Bool ret = EINA_TRUE;
+
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((sx == 0) && (sy == 0), EINA_FALSE);
+
+   if (fillmode == EVAS_FILTER_FILL_MODE_NONE)
+     {
+        _clip_to_target(&sx, &sy, sw, sh, dx, dy, dw, dh, &dx, &dy, &rows, &cols);
+        DBG("blend: %d,%d,%d,%d --> %d,%d,%d,%d (from %dx%d to %dx%d +%d,%d)",
+            0, 0, sw, sh, dx, dy, cols, rows, sw, sh, dw, dh, dx, dy);
+
+#ifdef HAS_DO_ASYNC
+        ret = image_draw(data, drawctx, out, in,
+                         sx, sy, cols, rows, // src
+                         dx, dy, cols, rows, // dst
+                         EINA_TRUE, // smooth
+                         EINA_FALSE); // Not async
+#else
+        image_draw(data, drawctx, out, in,
+                   sx, sy, cols, rows, // src
+                   dx, dy, cols, rows, // dst
+                   EINA_TRUE); // smooth
+        ret = EINA_TRUE;
+#endif
+        return ret;
+     }
+
+   if (fillmode & EVAS_FILTER_FILL_MODE_REPEAT_X)
+     {
+        if (dx > 0) left = dx % sw;
+        else if (dx < 0) left = sw + (dx % sw);
+        cols = (dw  /*- left*/) / sw;
+        if (left > 0)
+          right = dw - (sw * (cols - 1)) - left;
+        else
+          right = dw - (sw * cols);
+        dx = 0;
+     }
+   else if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
+     {
+        cols = 0;
+        dx = 0;
+     }
+   else
+     {
+        // FIXME: Probably wrong if dx != 0
+        cols = 0;
+        dw -= dx;
+     }
+
+   if (fillmode & EVAS_FILTER_FILL_MODE_REPEAT_Y)
+     {
+        if (dy > 0) top = dy % sh;
+        else if (dy < 0) top = sh + (dy % sh);
+        rows = (dh /*- top*/) / sh;
+        if (top > 0)
+          bottom = dh - (sh * (rows - 1)) - top;
+        else
+          bottom = dh - (sh * rows);
+        dy = 0;
+     }
+   else if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
+     {
+        rows = 0;
+        dy = 0;
+     }
+   else
+     {
+        // FIXME: Probably wrong if dy != 0
+        rows = 0;
+        dh -= dy;
+     }
+
+   if (top > 0) row = -1;
+   else row = 0;
+   for (; row <= rows; row++)
+     {
+        int src_x, src_y, src_w, src_h;
+        int dst_x, dst_y, dst_w, dst_h;
+
+        if (row == -1 && top > 0)
+          {
+             // repeat only
+             src_h = top;
+             src_y = sh - top;
+             dst_y = dy;
+             dst_h = src_h;
+          }
+        else if (row == rows && bottom > 0)
+          {
+             // repeat only
+             src_h = bottom;
+             src_y = 0;
+             dst_y = top + dy + row * sh;
+             dst_h = src_h;
+          }
+        else
+          {
+             src_y = 0;
+             if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
+               {
+                  src_h = sh;
+                  dst_h = dh;
+                  dst_y = 0;
+               }
+             else
+               {
+                  dst_y = top + dy + row * sh;
+                  src_h = MIN(dh - dst_y, sh);
+                  dst_h = src_h;
+               }
+          }
+        if (src_h <= 0 || dst_h <= 0) break;
+
+        if (left > 0) col = -1;
+        else col = 0;
+        for (; col <= cols; col++)
+          {
+             if (col == -1 && left > 0)
+               {
+                  // repeat only
+                  src_w = left;
+                  src_x = sw - left;
+                  dst_x = dx;
+                  dst_w = src_w;
+               }
+             else if (col == cols && right > 0)
+               {
+                  // repeat only
+                  src_w = right;
+                  src_x = 0;
+                  dst_x = left + dx + col * sw;
+                  dst_w = src_w;
+               }
+             else
+               {
+                  src_x = 0;
+                  if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
+                    {
+                       src_w = sw;
+                       dst_w = dw;
+                       dst_x = 0;
+                    }
+                  else
+                    {
+                       dst_x = left + dx + col * sw;
+                       src_w = MIN(dw - dst_x, sw);
+                       dst_w = src_w;
+                    }
+               }
+             if (src_w <= 0 || dst_w <= 0) break;
+
+             DBG("blend: [%d,%d] %d,%d,%dx%d --> %d,%d,%dx%d "
+                 "(src %dx%d, dst %dx%d)",
+                 col, row, src_x, src_y, src_w, src_h,
+                 dst_x, dst_y, dst_w, dst_h,
+                 sw, sh, dw, dh);
+
+#ifdef HAS_DO_ASYNC
+             ret = image_draw(data, drawctx, out, in,
+                              src_x, src_y, src_w, src_h,
+                              dst_x, dst_y, dst_w, dst_h,
+                              EINA_TRUE, EINA_FALSE);
+#else
+             image_draw(data, drawctx, out, in,
+                        src_x, src_y, src_w, src_h,
+                        dst_x, dst_y, dst_w, dst_h,
+                        EINA_TRUE);
+             ret = EINA_TRUE;
+#endif
+             if (!ret) return EINA_FALSE;
+          }
+     }
+   return ret;
+}
+
+Evas_Filter_Apply_Func
+evas_filter_blend_cpu_func_get(Evas_Filter_Command *cmd)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
+
+   if (!cmd->ctx->gl_engine || !cmd->output->glimage || cmd->output->backing)
+     {
+        if (cmd->input->alpha_only)
+          {
+             if (cmd->output->alpha_only)
+               return _filter_blend_cpu_alpha;
+             else
+               return _filter_blend_cpu_mask_rgba;
+          }
+        else
+          {
+             if (cmd->output->alpha_only)
+               return _filter_blend_cpu_rgba2alpha;
+             else
+               return _filter_blend_cpu_rgba;
+          }
+     }
+   else
+     {
+        CRI("Can't render to GL image for the moment!");
+        //return _filter_blend_opengl_generic;
+        return NULL;
+     }
+}
diff --git a/src/lib/filters/evas_filter_blur.c b/src/lib/filters/evas_filter_blur.c
new file mode 100644 (file)
index 0000000..7af357f
--- /dev/null
@@ -0,0 +1,556 @@
+#include "evas_filter.h"
+#include "evas_filter_private.h"
+
+#include <math.h>
+#include <time.h>
+
+static int
+_box_blur_auto_radius(int *radii, int r)
+{
+   if (r <= 2)
+     {
+        radii[0] = r;
+        radii[1] = 0;
+        WRN("Radius is too small for auto box blur: %d", r);
+        return 1;
+     }
+   else if (r <= 6)
+     {
+        radii[0] = r / 2;
+        radii[1] = r - radii[0] - 1;
+        radii[2] = 0;
+        DBG("Using auto radius for %d: %d %d", r, radii[0], radii[1]);
+        return 2;
+     }
+   else
+     {
+        radii[0] = (r + 3) / 3;
+        radii[1] = (r + 2) / 3;
+        radii[2] = r - radii[0] - radii[1];
+        radii[3] = 0;
+        DBG("Using auto radius for %d: %d %d %d", r, radii[0], radii[1], radii[2]);
+        return 3;
+     }
+}
+
+#include "./blur/blur_box_rgba_.c"
+#ifdef BUILD_MMX
+#include "./blur/blur_box_rgba_i386.c"
+#endif
+#ifdef BUILD_SSE3
+#include "./blur/blur_box_rgba_sse3.c"
+#endif
+#ifdef BUILD_NEON
+#include "./blur/blur_box_rgba_neon.c"
+#endif
+
+static void
+_box_blur_horiz_rgba(DATA32 *src, DATA32 *dst, int* radii, int w, int h)
+{
+   DEBUG_TIME_BEGIN();
+
+#ifdef BUILD_SSE3
+   if (evas_common_cpu_has_feature(CPU_FEATURE_SSE3))
+     {
+        _box_blur_rgba_horiz_step_sse3(src, dst, radii, w, h);
+        goto end;
+     }
+#endif
+#ifdef BUILD_MMX
+   if (evas_common_cpu_has_feature(CPU_FEATURE_MMX))
+     {
+        _box_blur_rgba_horiz_step_mmx(src, dst, radii, w, h);
+        goto end;
+     }
+#endif
+#ifdef BUILD_NEON
+   if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+     {
+        _box_blur_rgba_horiz_step_neon(src, dst, radii, w, h);
+        goto end;
+     }
+#endif
+   _box_blur_rgba_horiz_step(src, dst, radii, w, h);
+
+end:
+   DEBUG_TIME_END();
+}
+
+static void
+_box_blur_vert_rgba(DATA32 *src, DATA32 *dst, int* radii, int w, int h)
+{
+   DEBUG_TIME_BEGIN();
+
+#ifdef BUILD_SSE3
+   if (evas_common_cpu_has_feature(CPU_FEATURE_SSE3))
+     {
+        _box_blur_rgba_vert_step_sse3(src, dst, radii, h, w);
+        goto end;
+     }
+#endif
+#ifdef BUILD_MMX
+   if (evas_common_cpu_has_feature(CPU_FEATURE_MMX))
+     {
+        _box_blur_rgba_vert_step_mmx(src, dst, radii, h, w);
+        goto end;
+     }
+#endif
+#ifdef BUILD_NEON
+   if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+     {
+        _box_blur_rgba_vert_step_neon(src, dst, radii, h, w);
+        goto end;
+     }
+#endif
+   _box_blur_rgba_vert_step(src, dst, radii, h, w);
+
+end:
+   DEBUG_TIME_END();
+}
+
+static Eina_Bool
+_box_blur_horiz_apply_rgba(Evas_Filter_Command *cmd)
+{
+   RGBA_Image *in, *out;
+   int radii[7] = {0};
+   unsigned int r;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
+
+   r = abs(cmd->blur.dx);
+   in = cmd->input->backing;
+   out = cmd->output->backing;
+
+   if (cmd->blur.auto_count)
+     _box_blur_auto_radius(radii, r);
+   else for (int k = 0; k < cmd->blur.count; k++)
+     radii[k] = r;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
+
+   _box_blur_horiz_rgba(in->image.data, out->image.data, radii,
+                        in->cache_entry.w, in->cache_entry.h);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_box_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
+{
+   RGBA_Image *in, *out;
+   int radii[7] = {0};
+   unsigned int r;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
+
+   r = abs(cmd->blur.dy);
+   in = cmd->input->backing;
+   out = cmd->output->backing;
+
+   if (cmd->blur.auto_count)
+     _box_blur_auto_radius(radii, r);
+   else for (int k = 0; k < cmd->blur.count; k++)
+     radii[k] = r;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
+
+   _box_blur_vert_rgba(in->image.data, out->image.data, radii,
+                       in->cache_entry.w, in->cache_entry.h);
+
+   return EINA_TRUE;
+}
+
+#include "./blur/blur_box_alpha_.c"
+#ifdef BUILD_MMX
+#include "./blur/blur_box_alpha_i386.c"
+#endif
+#ifdef BUILD_SSE3
+#include "./blur/blur_box_alpha_sse3.c"
+#endif
+#ifdef BUILD_NEON
+#include "./blur/blur_box_alpha_neon.c"
+#endif
+
+static void
+_box_blur_horiz_alpha(DATA8 *src, DATA8 *dst, int* radii, int w, int h)
+{
+   DEBUG_TIME_BEGIN();
+
+#ifdef BUILD_SSE3
+   if (evas_common_cpu_has_feature(CPU_FEATURE_SSE3))
+     {
+        _box_blur_alpha_horiz_step_sse3(src, dst, radii, w, h);
+        goto end;
+     }
+#endif
+#ifdef BUILD_MMX
+   if (evas_common_cpu_has_feature(CPU_FEATURE_MMX))
+     {
+        _box_blur_alpha_horiz_step_mmx(src, dst, radii, w, h);
+        goto end;
+     }
+#endif
+#ifdef BUILD_NEON
+   if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+     {
+        _box_blur_alpha_horiz_step_neon(src, dst, radii, w, h);
+        goto end;
+     }
+#endif
+   _box_blur_alpha_horiz_step(src, dst, radii, w, h);
+
+end:
+   DEBUG_TIME_END();
+}
+
+static void
+_box_blur_vert_alpha(DATA8 *src, DATA8 *dst, int* radii, int w, int h)
+{
+   DEBUG_TIME_BEGIN();
+
+#ifdef BUILD_SSE3
+   if (evas_common_cpu_has_feature(CPU_FEATURE_SSE3))
+     {
+        _box_blur_alpha_vert_step_sse3(src, dst, radii, h, w);
+        goto end;
+     }
+#endif
+#ifdef BUILD_MMX
+   if (evas_common_cpu_has_feature(CPU_FEATURE_MMX))
+     {
+        _box_blur_alpha_vert_step_mmx(src, dst, radii, h, w);
+        goto end;
+     }
+#endif
+#ifdef BUILD_NEON
+   if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+     {
+        _box_blur_alpha_vert_step_neon(src, dst, radii, h, w);
+        goto end;
+     }
+#endif
+   _box_blur_alpha_vert_step(src, dst, radii, h, w);
+
+end:
+   DEBUG_TIME_END();
+}
+
+static Eina_Bool
+_box_blur_horiz_apply_alpha(Evas_Filter_Command *cmd)
+{
+   RGBA_Image *in, *out;
+   int radii[7] = {0};
+   unsigned int r;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
+
+   r = abs(cmd->blur.dx);
+   in = cmd->input->backing;
+   out = cmd->output->backing;
+
+   if (cmd->blur.auto_count)
+     _box_blur_auto_radius(radii, r);
+   else for (int k = 0; k < cmd->blur.count; k++)
+     radii[k] = r;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
+
+   _box_blur_horiz_alpha(in->image.data8, out->image.data8, radii,
+                         in->cache_entry.w, in->cache_entry.h);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_box_blur_vert_apply_alpha(Evas_Filter_Command *cmd)
+{
+   RGBA_Image *in, *out;
+   int radii[7] = {0};
+   unsigned int r;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
+
+   r = abs(cmd->blur.dy);
+   in = cmd->input->backing;
+   out = cmd->output->backing;
+
+   if (cmd->blur.auto_count)
+     _box_blur_auto_radius(radii, r);
+   else for (int k = 0; k < cmd->blur.count; k++)
+     radii[k] = r;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
+
+   _box_blur_vert_alpha(in->image.data8, out->image.data8, radii,
+                        in->cache_entry.w, in->cache_entry.h);
+
+   return EINA_TRUE;
+}
+
+/* Gaussian blur */
+
+static void
+_sin_blur_weights_get(int *weights, int *pow2_divider, int radius)
+{
+   const int diameter = 2 * radius + 1;
+   double x, divider, sum = 0.0;
+   double dweights[diameter];
+   int k, nextpow2, isum = 0;
+   const int FAKE_PI = 3.0;
+
+   /* Base curve:
+    * f(x) = sin(x+pi/2)/2+1/2
+    */
+
+   for (k = 0; k < diameter; k++)
+     {
+        x = ((double) k / (double) (diameter - 1)) * FAKE_PI * 2.0 - FAKE_PI;
+        dweights[k] = ((sin(x + M_PI_2) + 1.0) / 2.0) * 1024.0;
+        sum += dweights[k];
+     }
+
+   // Now we need to normalize to have a 2^N divider.
+   nextpow2 = log2(2 * sum);
+   divider = (double) (1 << nextpow2);
+
+   for (k = 0; k < diameter; k++)
+     {
+        weights[k] = round(dweights[k] * divider / sum);
+        isum += weights[k];
+     }
+
+   // Final correction. The difference SHOULD be small...
+   weights[radius] += (int) divider - isum;
+
+   if (pow2_divider)
+     *pow2_divider = nextpow2;
+}
+
+#define FUNCTION_NAME _gaussian_blur_horiz_alpha_step
+#define STEP 1
+#include "./blur/blur_gaussian_alpha_.c"
+
+static void
+_gaussian_blur_horiz_alpha(const DATA8 *src, DATA8 *dst, int radius, int w, int h)
+{
+   int *weights;
+   int pow2_div = 0;
+
+   weights = alloca((2 * radius + 1) * sizeof(int));
+   _sin_blur_weights_get(weights, &pow2_div, radius);
+
+   DEBUG_TIME_BEGIN();
+   _gaussian_blur_horiz_alpha_step(src, dst, radius, w, h, w, weights, pow2_div);
+   DEBUG_TIME_END();
+}
+
+// Step size is w (row by row), loops = w, so STEP = 'loops'
+#define FUNCTION_NAME _gaussian_blur_vert_alpha_step
+#define STEP loops
+#include "./blur/blur_gaussian_alpha_.c"
+
+static void
+_gaussian_blur_vert_alpha(const DATA8 *src, DATA8 *dst, int radius, int w, int h)
+{
+   int *weights;
+   int pow2_div = 0;
+
+   weights = alloca((2 * radius + 1) * sizeof(int));
+   _sin_blur_weights_get(weights, &pow2_div, radius);
+
+   DEBUG_TIME_BEGIN();
+   _gaussian_blur_vert_alpha_step(src, dst, radius, h, w, 1, weights, pow2_div);
+   DEBUG_TIME_END();
+}
+
+#define FUNCTION_NAME _gaussian_blur_horiz_rgba_step
+#define STEP 1
+#include "./blur/blur_gaussian_rgba_.c"
+
+static void
+_gaussian_blur_horiz_rgba(DATA32 *src, DATA32 *dst, int radius, int w, int h)
+{
+   int *weights;
+   int pow2_div = 0;
+
+   weights = alloca((2 * radius + 1) * sizeof(int));
+   _sin_blur_weights_get(weights, &pow2_div, radius);
+
+   DEBUG_TIME_BEGIN();
+   _gaussian_blur_horiz_rgba_step(src, dst, radius, w, h, w, weights, pow2_div);
+   DEBUG_TIME_END();
+}
+
+#define FUNCTION_NAME _gaussian_blur_vert_rgba_step
+#define STEP loops
+#include "./blur/blur_gaussian_rgba_.c"
+
+static void
+_gaussian_blur_vert_rgba(DATA32 *src, DATA32 *dst, int radius, int w, int h)
+{
+   int *weights;
+   int pow2_div = 0;
+
+   weights = alloca((2 * radius + 1) * sizeof(int));
+   _sin_blur_weights_get(weights, &pow2_div, radius);
+
+   DEBUG_TIME_BEGIN();
+   _gaussian_blur_vert_rgba_step(src, dst, radius, h, w, 1, weights, pow2_div);
+   DEBUG_TIME_END();
+}
+
+static Eina_Bool
+_gaussian_blur_horiz_apply_alpha(Evas_Filter_Command *cmd)
+{
+   RGBA_Image *in, *out;
+   unsigned int r;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
+
+   r = abs(cmd->blur.dx);
+   in = cmd->input->backing;
+   out = cmd->output->backing;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
+
+   _gaussian_blur_horiz_alpha(in->image.data8, out->image.data8, r,
+                              in->cache_entry.w, in->cache_entry.h);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_gaussian_blur_vert_apply_alpha(Evas_Filter_Command *cmd)
+{
+   RGBA_Image *in, *out;
+   unsigned int r;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
+
+   r = abs(cmd->blur.dy);
+   in = cmd->input->backing;
+   out = cmd->output->backing;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
+
+   _gaussian_blur_vert_alpha(in->image.data8, out->image.data8, r,
+                             in->cache_entry.w, in->cache_entry.h);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_gaussian_blur_horiz_apply_rgba(Evas_Filter_Command *cmd)
+{
+   RGBA_Image *in, *out;
+   unsigned int r;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
+
+   r = abs(cmd->blur.dx);
+   in = cmd->input->backing;
+   out = cmd->output->backing;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
+
+   _gaussian_blur_horiz_rgba(in->image.data, out->image.data, r,
+                             in->cache_entry.w, in->cache_entry.h);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_gaussian_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
+{
+   RGBA_Image *in, *out;
+   unsigned int r;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
+
+   r = abs(cmd->blur.dy);
+   in = cmd->input->backing;
+   out = cmd->output->backing;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
+
+   _gaussian_blur_vert_rgba(in->image.data, out->image.data, r,
+                            in->cache_entry.w, in->cache_entry.h);
+
+   return EINA_TRUE;
+}
+
+/* Main entry point */
+
+Evas_Filter_Apply_Func
+evas_filter_blur_cpu_func_get(Evas_Filter_Command *cmd)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->mode == EVAS_FILTER_MODE_BLUR, NULL);
+
+   switch (cmd->blur.type)
+     {
+      case EVAS_FILTER_BLUR_BOX:
+        if (!cmd->input->alpha_only && !cmd->output->alpha_only)
+          {
+             if (cmd->blur.dx)
+               return _box_blur_horiz_apply_rgba;
+             else if (cmd->blur.dy)
+               return _box_blur_vert_apply_rgba;
+          }
+        else if (cmd->input->alpha_only && cmd->output->alpha_only)
+          {
+             if (cmd->blur.dx)
+               return _box_blur_horiz_apply_alpha;
+             else if (cmd->blur.dy)
+               return _box_blur_vert_apply_alpha;
+          }
+        CRI("Unsupported operation: mixing RGBA and Alpha surfaces.");
+        return NULL;
+      case EVAS_FILTER_BLUR_GAUSSIAN:
+        if (!cmd->input->alpha_only && !cmd->output->alpha_only)
+          {
+             if (cmd->blur.dx)
+               return _gaussian_blur_horiz_apply_rgba;
+             else if (cmd->blur.dy)
+               return _gaussian_blur_vert_apply_rgba;
+          }
+        else if (cmd->input->alpha_only && cmd->output->alpha_only)
+          {
+             if (cmd->blur.dx)
+               return _gaussian_blur_horiz_apply_alpha;
+             else if (cmd->blur.dy)
+               return _gaussian_blur_vert_apply_alpha;
+          }
+        CRI("Unsupported operation: mixing RGBA and Alpha surfaces.");
+        return NULL;
+      default:
+        CRI("Unsupported blur type %d", cmd->blur.type);
+        return NULL;
+     }
+}
diff --git a/src/lib/filters/evas_filter_bump.c b/src/lib/filters/evas_filter_bump.c
new file mode 100644 (file)
index 0000000..a269145
--- /dev/null
@@ -0,0 +1,417 @@
+/* Simple bump map algorithms for the software engine */
+
+#include "evas_filter_private.h"
+#include "evas_blend_private.h"
+
+#include <math.h>
+
+
+#ifdef CLAMP
+# undef CLAMP
+#endif
+#define CLAMP(a,b,c) MIN(MAX((b),(a)),(c))
+
+#define DEFAULT_ZANGLE 45.f
+
+static Eina_Bool _bump_map_cpu_alpha_alpha(Evas_Filter_Command *cmd);
+static Eina_Bool _bump_map_cpu_alpha_rgba(Evas_Filter_Command *cmd);
+static Eina_Bool _bump_map_cpu_rgba_rgba(Evas_Filter_Command *cmd);
+
+Evas_Filter_Apply_Func
+evas_filter_bump_map_cpu_func_get(Evas_Filter_Command *cmd)
+{
+   int w, h;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
+
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input != cmd->output, NULL);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->mask->alpha_only, NULL);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((!cmd->output->alpha_only)
+                                   || cmd->input->alpha_only, NULL);
+
+   w = cmd->input->w;
+   h = cmd->input->h;
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->w == w, NULL);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->h == h, NULL);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->mask->w == w, NULL);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->mask->h == h, NULL);
+
+   if (cmd->input->alpha_only)
+     {
+        if (cmd->output->alpha_only)
+          return _bump_map_cpu_alpha_alpha;
+        else
+          return _bump_map_cpu_alpha_rgba;
+     }
+   else
+     return _bump_map_cpu_rgba_rgba;
+}
+
+static void
+_phong_alpha_generate(DATA8 *phong, DATA8 dark, DATA8 color, DATA8 white,
+                      float sf)
+{
+   int x, y;
+
+   // FIXME: Flat surfaces should be of color COLOR when compensate is set
+   // FIXME: Include white in the computation for specular light
+   (void) white;
+   (void) sf;
+
+   /*
+   float3 lightDir = light.position - pos3D; //3D position in space of the surface
+   float distance = length( lightDir );
+   lightDir = lightDir / distance; // = normalize( lightDir );
+   distance = distance * distance; //This line may be optimised using Inverse square root
+
+   //Intensity of the diffuse light. Saturate to keep within the 0-1 range.
+   float NdotL = dot( normal, lightDir );
+   float intensity = saturate( NdotL );
+
+   // Calculate the diffuse light factoring in light color, power and the attenuation
+   OUT.Diffuse = intensity * light.diffuseColor * light.diffusePower / distance;
+
+   //Calculate the half vector between the light vector and the view vector.
+   //This is faster than calculating the actual reflective vector.
+   float3 H = normalize( lightDir + viewDir );
+
+   //Intensity of the specular light
+   float NdotH = dot( normal, H );
+   intensity = pow( saturate( NdotH ), specularHardness );
+
+   //Sum up the specular light factoring
+   OUT.Specular = intensity * light.specularColor * light.specularPower / distance;
+   */
+
+   for (y = 0; y < 256; y++)
+     for (x = 0; x < 256; x++)
+       {
+          float dx = (127.5 - x);
+          float dy = (127.5 - y);
+          float dist = sqrt(dx*dx + dy*dy) * 2.;
+          int diff = dark + MAX(255 - dist, 0) * (color - dark) / 255;
+          int spec = 0; // TODO
+          phong[x + (y << 8)] = MIN(MAX(diff + spec, 0), 255);
+       }
+}
+
+static Eina_Bool
+_bump_map_cpu_alpha_alpha(Evas_Filter_Command *cmd)
+{
+   DATA8 *src, *map, *dst, *map_y1, *map_y2;
+   DATA8 dark, color, white;
+   DATA8 *phong;
+   int x, y, w, h, lx, ly;
+   float xyangle, zangle, sf, lxy;
+
+   w = cmd->input->w;
+   h = cmd->input->h;
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(w > 2 && h > 2, EINA_FALSE);
+
+   src = ((RGBA_Image *) cmd->input->backing)->image.data8;
+   map = ((RGBA_Image *) cmd->mask->backing)->image.data8;
+   dst = ((RGBA_Image *) cmd->output->backing)->image.data8;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(map, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+
+   xyangle = cmd->bump.xyangle;
+   zangle = cmd->bump.zangle;
+   sf = cmd->bump.specular_factor;
+
+   dark = cmd->bump.dark >> 24;
+   white = cmd->bump.white >> 24;
+   color = cmd->bump.color >> 24;
+
+   // Convenience for alpha output only
+   if ((!dark && !white && !color) ||
+       (dark == 0xff && white == 0xff && color == 0xff))
+     {
+        INF("Bump colors are all 0 or 255. Using low byte instead of alpha.");
+        dark = cmd->bump.dark & 0xff;
+        white = cmd->bump.white & 0xff;
+        color = cmd->bump.color & 0xff;
+     }
+
+   // Compute appropriate lx, ly
+   if (abs(zangle) >= 90)
+     {
+        WRN("Z angle was defined as %.0f, out of range. Defaults to %.0f.",
+            zangle, DEFAULT_ZANGLE);
+        zangle = DEFAULT_ZANGLE;
+     }
+
+   lxy = sin(abs(zangle * M_PI / 180.));
+   lx = (int) (40.f * (lxy + 1.0) * cos(xyangle * M_PI / 180.));
+   ly = (int) (40.f * (lxy + 1.0) * sin(xyangle * M_PI / 180.));
+   INF("Using light vector (%d,%d)", lx, ly);
+
+   // Generate light table
+   phong = malloc(256 * 256 * sizeof(*phong));
+   EINA_SAFETY_ON_NULL_RETURN_VAL(phong, EINA_FALSE);
+   _phong_alpha_generate(phong, dark, color, white, sf);
+
+   for (y = 0; y < h; y++)
+     {
+        int gx, gy, vx, vy;
+
+        if (!y)
+          {
+             map_y1 = map;
+             map_y2 = map + w;
+          }
+        else if (y == (h - 1))
+          {
+             map_y1 = map - w;
+             map_y2 = map;
+          }
+        else
+          {
+             map_y1 = map - w;
+             map_y2 = map + w;
+          }
+
+        // x = 0
+        gx = (map[1] - map[0]) / 2;
+        gy = (*map_y2 - *map_y1) / 2;
+        vx = gx + lx + 127;
+        vy = (-gy) + ly + 127;
+
+        //printf("dx,dy: %d,%d, lx,ly: %d,%d, vx,vy: %d,%d\n", gx, gy, lx, ly, vx, vy);
+
+        if ((vx & 0xFF00) || (vy & 0xFF00))
+          *dst = *src * dark;
+        else
+          *dst = (*src * phong[(vy << 8) + vx]) >> 8;
+
+        dst++, src++, map_y1++, map_y2++;
+        for (x = 1; x < (w - 1); x++, map++, map_y1++, map_y2++, src++, dst++)
+          {
+             // note: map is one pixel left of (x,y)
+
+             if (!*src)
+               {
+                  *dst = 0;
+                  continue;
+               }
+
+             // compute gradient (gx, gy). this gives us the normal vector
+             gx = (map[2] - map[0]) / 2;
+             gy = (*map_y2 - *map_y1) / 2;
+
+             // compute halfway vector between light and gradient vectors
+             vx = gx + lx + 127;
+             vy = (-gy) + ly + 127;
+
+             // take light from the phong table
+             if ((vx & 0xFF00) || (vy & 0xFF00))
+               *dst = *src * dark;
+             else
+               *dst = (*src * phong[(vy << 8) + vx]) >> 8;
+          }
+
+        // x = (w - 1)
+        gx = (map[1] - map[0]) / 2;
+        gy = (*map_y2 - *map_y1) / 2;
+        vx = gx + lx + 127;
+        vy = (-gy) + ly + 127;
+
+        if ((vx & 0xFF00) || (vy & 0xFF00))
+          *dst = *src * dark;
+        else
+          *dst = (*src * phong[(vy << 8) + vx]) >> 8;
+
+        map += 2;
+        dst++;
+        src++;
+     }
+
+   free(phong);
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_bump_map_cpu_alpha_rgba(Evas_Filter_Command *cmd)
+{
+   DATA8 *src, *map, *map_y1, *map_y2;
+   DATA32 *dst;
+   DATA32 dark, color, white, col;
+   //DATA32 *phong;
+   Eina_Bool compensate;
+   int x, y, w, h, lx, ly, lz, gz, NL, diffusion, gzlz, gz2;
+   double xyangle, zangle, sf, lxy, elevation;
+
+   w = cmd->input->w;
+   h = cmd->input->h;
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(w > 2 && h > 2, EINA_FALSE);
+
+   src = ((RGBA_Image *) cmd->input->backing)->image.data8;
+   map = ((RGBA_Image *) cmd->mask->backing)->image.data8;
+   dst = ((RGBA_Image *) cmd->output->backing)->image.data;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(map, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+
+   xyangle = cmd->bump.xyangle;
+   zangle = cmd->bump.zangle;
+   sf = cmd->bump.specular_factor;
+   compensate = cmd->bump.compensate;
+   elevation = cmd->bump.elevation;
+
+   dark = cmd->bump.dark;
+   white = cmd->bump.white;
+   color = cmd->bump.color;
+
+   // Compute appropriate lx, ly
+   if (abs(zangle) >= 90)
+     {
+        WRN("Z angle was defined as %.0f, out of range. Defaults to %.0f.",
+            zangle, DEFAULT_ZANGLE);
+        zangle = DEFAULT_ZANGLE;
+     }
+
+   lxy = 255. * cos(zangle * M_PI / 180.);
+   lx = (int) (lxy * cos(xyangle * M_PI / 180.));
+   ly = (int) (lxy * sin(xyangle * M_PI / 180.));
+   lz = (int) (255. * sin(zangle));
+   INF("Using light vector (%d,%d,%d)", lx, ly, lz);
+
+   if (elevation <= 0)
+     {
+        WRN("Invalid elevation value of %.0f, using 10 instead.", elevation);
+        elevation = 10.0;
+     }
+
+   gz = (6*255) / elevation;
+   gzlz = gz * lz;
+   gz2 = gz * gz;
+
+   // Generate light table
+   // FIXME: phong LUT not used (we need two)
+   //phong = malloc(256 * 256 * sizeof(*phong));
+   //EINA_SAFETY_ON_NULL_RETURN_VAL(phong, EINA_FALSE);
+   //_phong_rgba_generate(phong, 1.5, sf, 20, dark, color, white);
+
+   // FIXME: x=0 and x=w-1 are NOT implemented.
+
+   for (y = 0; y < h; y++)
+     {
+        int gx, gy;
+
+        if (!y)
+          {
+             map_y1 = map;
+             map_y2 = map + w;
+          }
+        else if (y == (h - 1))
+          {
+             map_y1 = map - w;
+             map_y2 = map;
+          }
+        else
+          {
+             map_y1 = map - w;
+             map_y2 = map + w;
+          }
+
+        for (x = 0; x < w; x++, dst++, src++, map++, map_y1++, map_y2++)
+          {
+             if (!*src) continue;
+
+             /* Color intensity is defined as:
+              * I = Kd*N.L*Cd + Ks*N.H*Cs
+              * Where Ks and Kd are 1 in this implementation
+              * And Cs is white, Cd is color
+              */
+
+             /* Compute N.L
+              * N = (gx,gy,gz)
+              * L = (lx,ly,lz)   |L| = 255
+              */
+
+             if (EINA_LIKELY(x && (x < (w - 1))))
+               {
+                  gx = map[-1] + map_y1[-1] + map_y2[-1] - map[1] - map_y1[1] - map_y2[1];
+                  gy = map_y2[-1] + map_y2[0] + map_y2[1] - map_y1[-1] - map_y1[0] - map_y1[1];
+               }
+             else if (!x)
+               {
+                  gx = map[0] + map_y1[0] + map_y2[0] - map[1] - map_y1[1] - map_y2[1];
+                  gy = map_y2[0] + map_y2[1] + map_y2[1] - map_y1[0] - map_y1[1] - map_y1[1];
+               }
+             else
+               {
+                  gx = map[-1] + map_y1[-1] + map_y2[-1] - map[0] - map_y1[0] - map_y2[0];
+                  gy = map_y2[-1] + map_y2[0] + map_y2[0] - map_y1[-1] - map_y1[0] - map_y1[0];
+               }
+
+             NL = gx*lx + gy*ly + gzlz;
+
+             if (0 && NL < 0)
+               {
+                  // TODO: Check this
+                  diffusion = lz;
+               }
+             else
+               {
+                  int g2 = gx*gx + gy*gy + gz2;
+                  diffusion = NL / sqrt(MAX(g2, 1));
+                  //diffusion += MAX(0, lz - diffusion);
+               }
+
+             if (compensate)
+               diffusion = diffusion * 255 / lz;
+
+             diffusion = CLAMP(1, diffusion + 1, 256);
+             col = INTERP_256(diffusion, color, dark);
+
+             if (sf > 0)
+               {
+                  /* Compute N.H
+                   * H = (L+V) / |L+V|
+                   * V = (0,0,255)
+                   * L = (lx,ly,lz)   |L| = 255
+                   */
+
+                  // FIXME: All these doubles :)
+
+                  int shine;
+                  const double hnorm = sqrt(lx*lx + ly*ly + (lz+255)*(lz+255));
+                  const double hx = (double) lx / hnorm;
+                  const double hy = (double) ly / hnorm;
+                  const double hz = (double) (lz+255) / hnorm;
+                  double NHx = hx*gx / 255.0;
+                  double NHy = hy*gy / 255.0;
+                  double nz = sqrt(255.0*255.0 - gx*gx - gy*gy);
+                  double NHz = (hz*nz) / 255.0;
+                  double NH = NHx + NHy + NHz;
+                  double specular = NH > 0 ? pow(NH, sf) : 0;
+
+                  if (compensate)
+                    {
+                       const double basespecular = pow(hz, sf);
+                       shine = (specular - basespecular) * 255.0 / (1.0 - basespecular);
+                    }
+                  else shine = specular * 255.0;
+
+                  col = INTERP_256(CLAMP(1, shine + 1, 256), white, col);
+               }
+
+             *dst = INTERP_256(*src + 1, col, *dst);
+          }
+   }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_bump_map_cpu_rgba_rgba(Evas_Filter_Command *cmd)
+{
+   (void) cmd;
+
+   CRI("Not implemented yet.");
+   return EINA_FALSE;
+}
diff --git a/src/lib/filters/evas_filter_curve.c b/src/lib/filters/evas_filter_curve.c
new file mode 100644 (file)
index 0000000..0a9d761
--- /dev/null
@@ -0,0 +1,129 @@
+#include "evas_filter.h"
+#include "evas_filter_private.h"
+
+
+static Eina_Bool
+_filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
+{
+   RGBA_Image *in, *out;
+   DATA32 *src, *dst, *d, *s;
+   DATA8 *curve;
+   int k, offset = -1, len;
+
+#define C_VAL(p) (((DATA8 *)(p))[offset])
+
+   in = cmd->input->backing;
+   out = cmd->output->backing;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
+   src = in->image.data;
+   dst = out->image.data;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+   curve = cmd->curve.data;
+   len = in->cache_entry.w * in->cache_entry.h;
+
+   switch (cmd->curve.channel)
+     {
+#ifndef WORDS_BIGENDIAN
+      case EVAS_FILTER_CHANNEL_RED:   offset = 2; break;
+      case EVAS_FILTER_CHANNEL_GREEN: offset = 1; break;
+      case EVAS_FILTER_CHANNEL_BLUE:  offset = 0; break;
+#else
+      case EVAS_FILTER_CHANNEL_RED:   offset = 1; break;
+      case EVAS_FILTER_CHANNEL_GREEN: offset = 2; break;
+      case EVAS_FILTER_CHANNEL_BLUE:  offset = 3; break;
+#endif
+      case EVAS_FILTER_CHANNEL_ALPHA: break;
+      case EVAS_FILTER_CHANNEL_RGB: break;
+      default:
+        ERR("Invalid color channel %d", (int) cmd->curve.channel);
+        return EINA_FALSE;
+     }
+
+   if (src != dst)
+     memcpy(dst, src, len * sizeof(DATA32));
+   evas_data_argb_unpremul(dst, len);
+
+   // One channel (R, G or B)
+   if (offset >= 0)
+     {
+        for (k = len, s = src, d = dst; k; k--, d++, s++)
+          C_VAL(d) = curve[C_VAL(s)];
+
+        goto premul;
+     }
+
+   // All RGB channels
+   if (cmd->curve.channel == EVAS_FILTER_CHANNEL_RGB)
+     {
+#ifndef WORDS_BIGENDIAN
+        for (offset = 0; offset <= 2; offset++)
+#else
+        for (offset = 1; offset <= 3; offset++)
+#endif
+          {
+             for (k = len, s = src, d = dst; k; k--, d++, s++)
+               C_VAL(d) = curve[C_VAL(s)];
+          }
+
+        goto premul;
+     }
+
+   // Alpha
+#ifndef WORDS_BIGENDIAN
+   offset = 3;
+#else
+   offset = 0;
+#endif
+
+   for (k = len, d = dst; k; k--, d++, src++)
+     C_VAL(d) = curve[C_VAL(src)];
+
+premul:
+   evas_data_argb_premul(dst, len);
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_filter_curve_cpu_alpha(Evas_Filter_Command *cmd)
+{
+   RGBA_Image *in, *out;
+   DATA8 *src, *dst;
+   DATA8 *curve;
+   int k;
+
+   in = cmd->input->backing;
+   out = cmd->output->backing;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
+   src = in->image.data8;
+   dst = out->image.data8;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+   curve = cmd->curve.data;
+
+   for (k = in->cache_entry.w * in->cache_entry.h; k; k--)
+     *dst++ = curve[*src++];
+
+   return EINA_TRUE;
+}
+
+Evas_Filter_Apply_Func
+evas_filter_curve_cpu_func_get(Evas_Filter_Command *cmd)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((cmd->input->w == cmd->output->w)
+                                   && (cmd->input->h == cmd->output->h), 0);
+
+   if (!cmd->input->alpha_only && !cmd->output->alpha_only)
+     return _filter_curve_cpu_rgba;
+
+   if (cmd->input->alpha_only && cmd->output->alpha_only)
+     return _filter_curve_cpu_alpha;
+
+   CRI("Incompatible image formats");
+   return NULL;
+}
diff --git a/src/lib/filters/evas_filter_displace.c b/src/lib/filters/evas_filter_displace.c
new file mode 100644 (file)
index 0000000..0ce30b6
--- /dev/null
@@ -0,0 +1,327 @@
+#include "evas_filter.h"
+#include "evas_filter_private.h"
+
+static void
+_filter_displace_cpu_alpha_do(int w, int h, int map_w, int map_h, int intensity,
+                              DATA8 *src, DATA8 *dst, DATA32 *map_start,
+                              Eina_Bool stretch, Eina_Bool smooth,
+                              Eina_Bool blend)
+{
+   int x, y, map_x, map_y;
+   const int dx = RED;
+   const int dy = GREEN;
+   DATA8 *map;
+
+   for (y = 0, map_y = 0; y < h; y++, map_y++)
+     {
+        if (map_y >= map_h) map_y = 0;
+        map = (DATA8 *) (map_start + map_y * map_w);
+
+        for (x = 0, map_x = 0; x < w;
+             x++, dst++, src++, map_x++, map += sizeof(DATA32))
+          {
+             int offx = 0, offy = 0, offx_dec = 0, offy_dec = 0, val = 0;
+             Eina_Bool out = 0;
+
+             // wrap around (x)
+             if (map_x >= map_w)
+               {
+                  map_x = 0;
+                  map = (DATA8 *) (map_start + map_y * map_w);
+               }
+
+             // x
+             val = ((int) map[dx] - 128) * intensity;
+             offx = val >> 7;
+             offx_dec = val & 0x7f;
+             if ((x + offx) < 0) { offx = -x; out = 1; }
+             if ((x + offx + 1) >= w) { offx = w - x - 2; out = 1; }
+
+             // y
+             val = ((int) map[dy] - 128) * intensity;
+             offy = val >> 7;
+             offy_dec = val & 0x7f;
+             if ((y + offy) < 0) { offy = -y; out = 1; }
+             if ((y + offy + 1) >= h) { offy = h - y - 2; out = 1; }
+
+             // get value
+             if (out && !stretch)
+               val = 0;
+             else
+               {
+                  if (!smooth)
+                    val = src[offx + offy * w];
+                  else
+                    {
+                       val  = src[offx + offy * w] * (128 - offx_dec) * (128 - offy_dec);
+                       val += src[offx + 1 + offy * w] * offx_dec * (128 - offy_dec);
+                       val += src[offx + (offy + 1) * w] * (128 - offx_dec) * offy_dec;
+                       val += src[offx + 1 + (offy + 1) * w] * offx_dec * offy_dec;
+                       val = val >> 14; // <=> *dst = val / (128 * 128)
+                    }
+               }
+
+             // apply alpha
+             if (map[ALPHA] != 255)
+               val = (val * map[ALPHA]) / 255;
+
+             // write to dest
+             if (blend)
+               *dst = (*dst * (255 - val)) / 255 + val;
+             else
+               *dst = val;
+          }
+     }
+}
+
+static void
+_filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
+                             DATA32 *src, DATA32 *dst, DATA32 *map_start,
+                             Eina_Bool stretch, Eina_Bool smooth,
+                             Eina_Bool blend)
+{
+   int x, y, map_x, map_y;
+   const int dx = RED;
+   const int dy = GREEN;
+   Eina_Bool unpremul = EINA_FALSE;
+   DATA8 *map;
+
+   for (y = 0, map_y = 0; y < h; y++, map_y++)
+     {
+        if (map_y >= map_h) map_y = 0;
+        map = (DATA8 *) (map_start + map_y * map_w);
+
+        for (x = 0, map_x = 0; x < w;
+             x++, dst++, src++, map_x++, map += sizeof(DATA32))
+          {
+             int offx = 0, offy = 0, offx_dec = 0, offy_dec = 0, val = 0;
+             DATA32 col = 0;
+             Eina_Bool out = 0;
+
+             // wrap (x)
+             if (map_x >= map_w)
+               {
+                  map_x = 0;
+                  map = (DATA8 *) (map_start + map_y * map_w);
+               }
+
+             if (!map[ALPHA]) continue;
+             if (!unpremul && map[ALPHA] != 0xFF)
+               {
+                  unpremul = EINA_TRUE;
+                  evas_data_argb_unpremul(map_start, map_w * map_h);
+               }
+
+             // x
+             val = ((int) map[dx] - 128) * intensity;
+             offx = val >> 7;
+             offx_dec = val & 0x7f;
+             if ((x + offx) < 0) { offx = -x; out = 1; }
+             if ((x + offx + 1) >= w) { offx = w - x - 2; out = 1; }
+
+             // y
+             val = ((int) map[dy] - 128) * intensity;
+             offy = val >> 7;
+             offy_dec = val & 0x7f;
+             if ((y + offy) < 0) { offy = -y; out = 1; }
+             if ((y + offy + 1) >= h) { offy = h - y - 2; out = 1; }
+
+             // get value
+             if (out && !stretch)
+               col = A_VAL(src + offx + offy * w) << (ALPHA * 8);
+             else if (!smooth)
+               col = src[offx + offy * w];
+             else
+               {
+                  int R, G, B, A;
+                  DATA32 s00, s01, s10, s11; // indexes represent x,y
+                  int mul00, mul01, mul10, mul11;
+
+                  mul00 = (128 - offx_dec) * (128 - offy_dec);
+                  mul01 = (128 - offx_dec) * offy_dec;
+                  mul10 = offx_dec * (128 - offy_dec);
+                  mul11 = offx_dec * offy_dec;
+
+                  s00 = src[offx + offy * w];
+                  s01 = src[offx + (offy + 1) * w];
+                  s10 = src[offx + 1 + offy * w];
+                  s11 = src[offx + 1 + (offy + 1) * w];
+
+                  A = (ALPHA_OF(s00) * mul00) + (ALPHA_OF(s10) * mul10)
+                        + (ALPHA_OF(s01) * mul01) + (ALPHA_OF(s11) * mul11);
+
+                  R = (RED_OF(s00) * mul00) + (RED_OF(s10) * mul10)
+                        + (RED_OF(s01) * mul01) + (RED_OF(s11) * mul11);
+
+                  G = (GREEN_OF(s00) * mul00) + (GREEN_OF(s10) * mul10)
+                        + (GREEN_OF(s01) * mul01) + (GREEN_OF(s11) * mul11);
+
+                  B = (BLUE_OF(s00) * mul00) + (BLUE_OF(s10) * mul10)
+                        + (BLUE_OF(s01) * mul01) + (BLUE_OF(s11) * mul11);
+
+                  A >>= 14;
+                  R >>= 14;
+                  G >>= 14;
+                  B >>= 14;
+
+                  col = ARGB_JOIN(A, R, G, B);
+               }
+
+             if (map[ALPHA] != 0xFF)
+               col = MUL_256(map[ALPHA], col);
+
+             if (blend)
+               {
+                  DATA32 a = 256 - ALPHA_OF(col);
+                  *dst = col + MUL_256(a, *dst);
+               }
+             else
+               *dst = col;
+          }
+     }
+
+   if (unpremul)
+     evas_data_argb_premul(map_start, map_w * map_h);
+}
+
+/**
+ * Apply distortion map on alpha image
+ * input:  alpha
+ * output: alpha
+ * map:    rg+a (rgba)
+ */
+static Eina_Bool
+_filter_displace_cpu_alpha(Evas_Filter_Command *cmd)
+{
+   int w, h, map_w, map_h, intensity;
+   DATA8 *dst, *src;
+   DATA32 *map_start;
+   Eina_Bool stretch, smooth, blend;
+
+   w = cmd->input->w;
+   h = cmd->input->h;
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(w == cmd->output->w, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->backing, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
+
+   src = ((RGBA_Image *) cmd->input->backing)->image.data8;
+   map_start = ((RGBA_Image *) cmd->mask->backing)->image.data;
+   dst = ((RGBA_Image *) cmd->output->backing)->image.data8;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(map_start, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+
+   stretch = cmd->displacement.flags & EVAS_FILTER_DISPLACE_STRETCH;
+   smooth = cmd->displacement.flags & EVAS_FILTER_DISPLACE_LINEAR;
+   map_w = cmd->mask->w;
+   map_h = cmd->mask->h;
+   intensity = cmd->displacement.intensity;
+   blend = (cmd->draw.render_op == EVAS_RENDER_BLEND);
+
+   // Stretch if necessary.
+   if ((map_w != w || map_h != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
+     {
+        Evas_Filter_Buffer *fb;
+
+        if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
+          map_w = w;
+        if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
+          map_h = h;
+
+        BUFFERS_LOCK();
+        fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h);
+        BUFFERS_UNLOCK();
+
+        EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
+        fb->locked = EINA_FALSE;
+        map_start = ((RGBA_Image *) fb->backing)->image.data;
+     }
+
+   _filter_displace_cpu_alpha_do(w, h, map_w, map_h, intensity,
+                                 src, dst, map_start, stretch, smooth, blend);
+
+   return EINA_TRUE;
+}
+
+/**
+ * Apply distortion map on rgba image
+ * input:  rgba
+ * output: rgba
+ * map:    rg+a (rgba)
+ */
+static Eina_Bool
+_filter_displace_cpu_rgba(Evas_Filter_Command *cmd)
+{
+   int w, h, map_w, map_h, intensity;
+   DATA32 *dst, *src, *map_start;
+   Eina_Bool stretch, smooth, blend;
+
+   w = cmd->input->w;
+   h = cmd->input->h;
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(w == cmd->output->w, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->backing, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
+
+   src = ((RGBA_Image *) cmd->input->backing)->image.data;
+   map_start = ((RGBA_Image *) cmd->mask->backing)->image.data;
+   dst = ((RGBA_Image *) cmd->output->backing)->image.data;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(map_start, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+
+   stretch = cmd->displacement.flags & EVAS_FILTER_DISPLACE_STRETCH;
+   smooth = cmd->displacement.flags & EVAS_FILTER_DISPLACE_LINEAR;
+   map_w = cmd->mask->w;
+   map_h = cmd->mask->h;
+   intensity = cmd->displacement.intensity;
+   blend = (cmd->draw.render_op == EVAS_RENDER_BLEND);
+
+   // Stretch if necessary.
+   if ((map_w != w || map_h != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
+     {
+        Evas_Filter_Buffer *fb;
+
+        if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
+          map_w = w;
+        if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
+          map_h = h;
+
+        BUFFERS_LOCK();
+        fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h);
+        BUFFERS_UNLOCK();
+
+        EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
+        fb->locked = EINA_FALSE;
+        map_start = ((RGBA_Image *) fb->backing)->image.data;
+     }
+
+   _filter_displace_cpu_rgba_do(w, h, map_w, map_h, intensity,
+                                src, dst, map_start, stretch, smooth, blend);
+
+   return EINA_TRUE;
+}
+
+Evas_Filter_Apply_Func
+evas_filter_displace_cpu_func_get(Evas_Filter_Command *cmd)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask, NULL);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(!cmd->mask->alpha_only, NULL);
+
+   if (cmd->input->alpha_only != cmd->output->alpha_only)
+     {
+        CRI("Invalid color formats");
+        return NULL;
+     }
+
+   if (cmd->input->alpha_only)
+     return _filter_displace_cpu_alpha;
+   else
+     return _filter_displace_cpu_rgba;
+}
diff --git a/src/lib/filters/evas_filter_mask.c b/src/lib/filters/evas_filter_mask.c
new file mode 100644 (file)
index 0000000..5850071
--- /dev/null
@@ -0,0 +1,397 @@
+/* Implementation of some masking functions for the software engine */
+
+#include "evas_filter_private.h"
+#include "evas_blend_private.h"
+
+
+// Naming convention: _func_engine_incolor_maskcolor_outcolor()
+static Eina_Bool _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd);
+static Eina_Bool _mask_cpu_alpha_rgba_rgba(Evas_Filter_Command *cmd);
+static Eina_Bool _mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd);
+static Eina_Bool _mask_cpu_rgba_alpha_rgba(Evas_Filter_Command *cmd);
+static Eina_Bool _mask_cpu_rgba_rgba_rgba(Evas_Filter_Command *cmd);
+
+Evas_Filter_Apply_Func
+evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask, NULL);
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->backing, NULL);
+
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input->w == cmd->output->w, NULL);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input->h == cmd->output->h, NULL);
+
+   if (cmd->input->alpha_only)
+     {
+        if (cmd->mask->alpha_only && cmd->output->alpha_only)
+          return _mask_cpu_alpha_alpha_alpha;
+        else if (!cmd->mask->alpha_only && !cmd->output->alpha_only)
+          return _mask_cpu_alpha_rgba_rgba;
+        else if (cmd->mask->alpha_only && !cmd->output->alpha_only)
+          return _mask_cpu_alpha_alpha_rgba;
+     }
+   else
+     {
+        if (cmd->mask->alpha_only && !cmd->output->alpha_only)
+          return _mask_cpu_rgba_alpha_rgba;
+        else if (!cmd->mask->alpha_only && !cmd->output->alpha_only)
+          return _mask_cpu_rgba_rgba_rgba;
+     }
+
+   CRI("If input or mask is RGBA, then output must also be RGBA: %s [%s] %s",
+       cmd->input->alpha_only ? "alpha" : "rgba",
+       cmd->mask->alpha_only ? "alpha" : "rgba",
+       cmd->output->alpha_only ? "alpha" : "rgba");
+   return NULL;
+}
+
+static Eina_Bool
+_mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd)
+{
+   Alpha_Gfx_Func func;
+   RGBA_Image *in, *out, *mask;
+   DATA8 *src, *dst, *msk;
+   int render_op = cmd->draw.render_op;
+   int w, h, mw, mh, x, y, my;
+   int stepsize, stepcount, step;
+
+   /* Mechanism:
+    * 1. Stretch mask as requested in fillmode
+    * 2. Copy source to destination
+    * 3. Render mask into destination using alpha function
+    *
+    * FIXME: Could probably be optimized into a single op :)
+    */
+
+   in = (RGBA_Image *) cmd->input->backing;
+   out = (RGBA_Image *) cmd->output->backing;
+   mask = (RGBA_Image *) cmd->mask->backing;
+
+   w = cmd->input->w;
+   h = cmd->input->h;
+   mw = cmd->mask->w;
+   mh = cmd->mask->h;
+   src = in->image.data8;
+   dst = out->image.data8;
+
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
+
+   stepsize  = MIN(mw, w);
+   stepcount = w / stepsize;
+
+   // Stretch if necessary.
+   if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
+     {
+        Evas_Filter_Buffer *fb;
+
+        if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
+          mw = w;
+        if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
+          mh = h;
+
+        BUFFERS_LOCK();
+        fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
+        BUFFERS_UNLOCK();
+
+        EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
+        fb->locked = EINA_FALSE;
+        mask = fb->backing;
+     }
+
+   msk = mask->image.data8;
+
+   // First pass: copy to dest
+   if (src != dst)
+     memcpy(dst, src, w * h * sizeof(DATA8));
+
+   // Second pass: apply render op
+   func = evas_common_alpha_func_get(render_op);
+   for (y = 0, my = 0; y < h; y++, my++, msk += mw)
+     {
+        if (my >= mh)
+          {
+             my = 0;
+             msk = mask->image.data8;
+          }
+
+        for (step = 0; step < stepcount; step++, dst += stepsize)
+          func(msk, dst, stepsize);
+
+        x = stepsize * stepcount;
+        if (x < w)
+          {
+             func(msk, dst, w - x);
+             dst += w - x;
+          }
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_mask_cpu_rgba_alpha_rgba(Evas_Filter_Command *cmd)
+{
+   Evas_Filter_Buffer *fb;
+   Eina_Bool ok;
+
+   /* Mechanism:
+    * 1. Swap input and mask
+    * 2. Apply mask operation for alpha+rgba+rgba
+    * 3. Swap input and mask
+    */
+
+   fb = cmd->input;
+   cmd->input = cmd->mask;
+   cmd->mask = fb;
+
+   ok = _mask_cpu_alpha_rgba_rgba(cmd);
+
+   fb = cmd->input;
+   cmd->input = cmd->mask;
+   cmd->mask = fb;
+
+   return ok;
+}
+
+static Eina_Bool
+_mask_cpu_alpha_rgba_rgba(Evas_Filter_Command *cmd)
+{
+   RGBA_Gfx_Func func1, func2;
+   RGBA_Image *in, *out, *mask;
+   DATA8 *src;
+   DATA32 *dst, *msk, *span;
+   int op = cmd->draw.render_op;
+   int w, h, mw, mh, y, my, r;
+   int stepsize, stepcount, step;
+   DATA32 color2;
+
+   /* Mechanism:
+    * 1. Stretch mask as requested in fillmode
+    * 2. Render mask to span using input as mask
+    * 3. Render span into destination
+    *
+    * FIXME: Could probably be optimized into a single op :)
+    */
+
+   in = (RGBA_Image *) cmd->input->backing;
+   out = (RGBA_Image *) cmd->output->backing;
+   mask = (RGBA_Image *) cmd->mask->backing;
+
+   w = cmd->input->w;
+   h = cmd->input->h;
+   mw = cmd->mask->w;
+   mh = cmd->mask->h;
+   src = in->image.data8;
+   dst = out->image.data;
+
+   // Stretch if necessary.
+   if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
+     {
+        Evas_Filter_Buffer *fb;
+
+        if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
+          mw = w;
+        if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
+          mh = h;
+
+        BUFFERS_LOCK();
+        fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
+        BUFFERS_UNLOCK();
+
+        EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
+        fb->locked = EINA_FALSE;
+        mask = fb->backing;
+     }
+
+   color2 = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
+   msk = mask->image.data;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(msk, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
+
+   stepsize  = MIN(mw, w);
+   stepcount = w / stepsize;
+   span = malloc(stepsize * sizeof(DATA32));
+
+   func1 = evas_common_gfx_func_composite_pixel_mask_span_get(mask, out, 1, EVAS_RENDER_COPY);
+   func2 = evas_common_gfx_func_composite_pixel_color_span_get(mask, color2, out, 1, op);
+
+   // Apply mask using Gfx functions
+   for (y = 0, my = 0; y < h; y++, my++, msk += mw)
+     {
+        if (my >= mh)
+          {
+             my = 0;
+             msk = mask->image.data;
+          }
+
+        for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize)
+          {
+             memset(span, 0, stepsize * sizeof(DATA32));
+             func1(msk, src, 0, span, stepsize);
+             func2(span, NULL, color2, dst, stepsize);
+          }
+
+        r = w - (stepsize * stepcount);
+        if (r > 0)
+          {
+             memset(span, 0, r * sizeof(DATA32));
+             func1(msk, src, 0, span, r);
+             func2(span, NULL, color2, dst, r);
+             dst += r;
+             src += r;
+          }
+     }
+
+   free(span);
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd)
+{
+   RGBA_Gfx_Func func;
+   Alpha_Gfx_Func span_func;
+   RGBA_Image *in, *out, *mask;
+   DATA8 *src, *msk, *span;
+   DATA32 *dst;
+   DATA32 color;
+   int op = cmd->draw.render_op;
+   int w, h, mw, mh, y, my, r;
+   int stepsize, stepcount, step;
+
+   /* Mechanism:
+    * 1. Copy mask to span buffer (1 line)
+    * 2. Multiply source by span (so that: span = mask * source)
+    * 3. Render span to destination using color (blend)
+    *
+    * FIXME: Could probably be optimized into a single op :)
+    */
+
+   in = (RGBA_Image *) cmd->input->backing;
+   out = (RGBA_Image *) cmd->output->backing;
+   mask = (RGBA_Image *) cmd->mask->backing;
+
+   w = cmd->input->w;
+   h = cmd->input->h;
+   mw = cmd->mask->w;
+   mh = cmd->mask->h;
+   src = in->image.data8;
+   dst = out->image.data;
+   color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
+
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
+
+   // Stretch if necessary.
+   if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
+     {
+        Evas_Filter_Buffer *fb;
+
+        if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
+          mw = w;
+        if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
+          mh = h;
+
+        BUFFERS_LOCK();
+        fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
+        BUFFERS_UNLOCK();
+
+        EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
+        fb->locked = EINA_FALSE;
+        mask = fb->backing;
+     }
+
+   msk = mask->image.data8;
+   stepsize  = MIN(mw, w);
+   stepcount = w / stepsize;
+   span = malloc(stepsize * sizeof(DATA8));
+
+   func = evas_common_gfx_func_composite_mask_color_span_get(color, out, 1, op);
+   span_func = evas_common_alpha_func_get(EVAS_RENDER_MASK);
+
+   for (y = 0, my = 0; y < h; y++, my++, msk += mw)
+     {
+        if (my >= mh)
+          {
+             my = 0;
+             msk = mask->image.data8;
+          }
+
+        for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize)
+          {
+             memcpy(span, msk, stepsize * sizeof(DATA8));
+             span_func(src, span, stepsize);
+             func(NULL, span, color, dst, stepsize);
+          }
+
+        r = w - (stepsize * stepcount);
+        if (r > 0)
+          {
+             memcpy(span, msk, r * sizeof(DATA8));
+             span_func(src, span, r);
+             func(NULL, span, color, dst, r);
+             dst += r;
+             src += r;
+          }
+     }
+
+   free(span);
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_mask_cpu_rgba_rgba_rgba(Evas_Filter_Command *cmd)
+{
+   Evas_Filter_Command fake_cmd;
+   Evas_Filter_Apply_Func blend;
+   Evas_Filter_Buffer *fb;
+   Eina_Bool ret;
+   int w, h;
+
+   fake_cmd = *cmd;
+   w = cmd->input->w;
+   h = cmd->input->h;
+
+   /* Blend 2 rgba images into rgba destination.
+    * Mechanism:
+    * 1. Copy input to temp (COPY)
+    * 2. Blend mask to temp (MUL)
+    * 3. Blend temp to output (render_op)
+    */
+
+   // Copy
+   BUFFERS_LOCK();
+   fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->input, w, h);
+   BUFFERS_UNLOCK();
+   EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
+   fb->locked = EINA_TRUE;
+
+   // Mask --> Temp
+   fake_cmd.input = cmd->mask;
+   fake_cmd.mask = NULL;
+   fake_cmd.output = fb;
+   fake_cmd.draw.render_op = EVAS_RENDER_MUL;
+   blend = evas_filter_blend_cpu_func_get(&fake_cmd);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(blend, EINA_FALSE);
+   ret = blend(&fake_cmd);
+   if (!ret) goto finish;
+
+   // Temp --> Output
+   fake_cmd.draw.render_op = EVAS_RENDER_BLEND;
+   fake_cmd.input = fb;
+   fake_cmd.output = cmd->output;
+   blend = evas_filter_blend_cpu_func_get(&fake_cmd);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(blend, EINA_FALSE);
+   ret = blend(&fake_cmd);
+
+finish:
+   fb->locked = EINA_FALSE;
+   return ret;
+}
diff --git a/src/lib/filters/evas_filter_parser.c b/src/lib/filters/evas_filter_parser.c
new file mode 100644 (file)
index 0000000..767b14e
--- /dev/null
@@ -0,0 +1,2529 @@
+#include "evas_filter_private.h"
+#include <stdarg.h>
+
+#define EVAS_FILTER_MODE_GROW   (EVAS_FILTER_MODE_LAST+1)
+
+/* Note on the documentation:
+ * To keep it simple, I'm not using any fancy features, only <ul>/<li> lists
+ * and @a, @b, @c flags from Doxygen.
+ * Let's keep it that way.
+ *
+ * This is a REFERENCE documentation, not supposed to contain tons of examples,
+ * but each filter command should have one simple copy and pasteable example.
+ */
+
+/**
+  @page evasfiltersref Evas filters reference
+
+  The Evas filters are a combination of filters used to apply specific effects
+  to an @ref Evas_Object "Evas Object". For the moment, these effects are
+  specific to the @ref Evas_Object_Text "Text Objects".
+
+  The filters can be applied to an object using a simple script language
+  specifically designed for these effects. A script will contain a series
+  of buffer declarations and filter commands to apply to these buffers.
+
+  Basically, when applying an effect to a @ref Evas_Object_Text "Text Object",
+  an alpha-only @c input buffer is created, where the text is rendered, and
+  an RGBA @c output buffer is created, where the text with effects shall be
+  finally rendered.
+
+  The script language is case insensitive, except for the buffer names.
+  All spaces will be discarded during parsing.
+
+  Here are the available commands:
+  <ul>
+    <li> @ref sec_syntax "Syntax" </li>
+    <li> @ref sec_buffers "Buffer management" </li>
+    <ul>
+      <li> @ref sec_buffers_cspace "Colorspaces" </li>
+      <li> @ref sec_buffers_auto "Automatic buffers" </li>
+      <li> @ref sec_buffers_cmd "BUFFER command" </li>
+    </ul>
+    <li> @ref sec_commands "Commands" </li>
+    <ul>
+      <li> @ref sec_commands_blend "BLEND command"</li>
+      <li> @ref sec_commands_blur "BLUR command"</li>
+      <li> @ref sec_commands_grow "GROW command"</li>
+      <li> @ref sec_commands_curve "CURVE command"</li>
+      <li> @ref sec_commands_fill "FILL command"</li>
+      <li> @ref sec_commands_mask "MASK command"</li>
+      <li> @ref sec_commands_bump "BUMP command"</li>
+      <li> @ref sec_commands_displace "DISPLACE command"</li>
+      <li> @ref sec_commands_transform "TRANSFORM command"</li>
+    </ul>
+  </ul>
+
+  All the examples in this page can (should) be directly used in
+  @ref evas_obj_text_filter_program_set.
+
+  Note that most of the text effects work better with larger font sizes (> 50px),
+  and so do the examples in this page.
+ */
+
+/**
+  @page evasfiltersref
+  @section sec_syntax Syntax
+
+  Here is a simple example illustrating the syntax:
+
+  @include filter_example_1.txt
+
+  This example will display a cyan and dark blue glow surrounding the
+  main text (its color depends on the object's theme).
+
+  <center>
+  @image html filter_example_1.png
+  </center>
+
+  The syntax is pretty simple and follows a small set of rules:
+  <ul>
+    <li>All whitespaces are discarded</li>
+    <li>All commands are case-insensitive, except for the buffer and source names</li>
+    <li>All dimensions are in pixels</li>
+    <li>The commands will be executed in sequential order</li>
+    <li>All commands must be terminated by a semicolon ';'</li>
+    <li>Most commands have default values</li>
+    <li>A command argument can either be set by name, or sequentially omitting the name (similarily to Python)</li>
+    <li>Boolean values can be either 1/0, on/off, yes/no, enabled/disabled, true/false</li>
+  </ul>
+
+  Since the spaces are discarded, the above code is equivalent to:
+  @code
+    buffer:fat(alpha);grow(5,dst=fat);blur(8,src=fat,color=darkblue);blur(4,color=cyan);blend();
+  @endcode
+
+  <h3>Special keywords and their values</h3>
+
+  Some options accept a certain set of values (like enums):
+  <ul>
+    <li>Booleans</li>
+    <ul>
+      <li>1/0, on/off, yes/no, enabled/disabled, true/false</li>
+    </ul>
+    @anchor evasfilters_color
+    <li>Color</li>
+    <ul>
+      <li>Hexademical values: @c #RRGGBB, @c #RRGGBBAA, @c #RGB, @c #RGBA</li>
+      <li>white: @c #FFFFFF</li>
+      <li>black: @c #000000</li>
+      <li>red: @c #FF0000</li>
+      <li>green: @c #008000</li>
+      <li>blue: @c #0000FF</li>
+      <li>darkblue: @c #0000A0</li>
+      <li>yellow: @c #FFFF00</li>
+      <li>magenta: @c #FF00FF</li>
+      <li>cyan: @c #00FFFF</li>
+      <li>orange: @c #FFA500</li>
+      <li>purple: @c #800080</li>
+      <li>brown: @c #A52A2A</li>
+      <li>maroon: @c #800000</li>
+      <li>lime: @c #00FF00</li>
+      <li>gray: @c #808080</li>
+      <li>grey: @c #808080</li>
+      <li>silver: @c #C0C0C0</li>
+      <li>olive: @c #808000</li>
+      <li>invisible, transparent: @c #0000 (alpha is zero)</li>
+    </ul>
+    @anchor evasfilter_fillmode
+    <li>Fillmode</li>
+    <ul>
+      <li>none</li>
+      <li>stretch_x</li>
+      <li>stretch_y</li>
+      <li>repeat_x</li>
+      <li>repeat_y</li>
+      <li>repeat_x_stretch_y, stretch_y_repeat_x</li>
+      <li>repeat_y_stretch_x, stretch_x_repeat_y</li>
+      <li>repeat, repeat_xy</li>
+      <li>stretch, stretch_xy</li>
+    </ul>
+  </ul>
+ */
+
+/**
+  @page evasfiltersref
+  @section sec_buffers Buffer management
+
+  The Evas filters subsystem is based on the concept of using various
+  buffers as image layers and drawing or applying filters to these buffers.
+
+  Most of the buffers are allocated automatically at runtime, depending on the
+  various inputs and commands used (eg. 2-D blur will require a temporary
+  intermediate buffer).
+
+  @subsection sec_buffers_cspace Colorspaces and size
+
+  The buffers' size will be automatically defined at runtime, based on the
+  content of the input and the series of operations to apply (eg. blur adds
+  some necessary margins).
+
+  The buffers can be either ALPHA (1 color channel only) or RGBA (full color).
+  Some operations might require specifically an ALPHA buffer, some others RGBA.
+
+  Most buffers will have the same size, except those specified by an external
+  source.
+
+
+  @subsection sec_buffers_auto Automatic buffers
+
+  The two most important buffers, input and output, are statically defined and
+  always present when running a filter. input is an ALPHA buffer, containing
+  the @ref Evas_Object_Text "Text Object"'s rendered text, and output is the
+  final target on which to render as RGBA.
+
+  Some operations, like 2-D blur might require temporary intermediate buffers,
+  that will be allocated automatically. Those buffers are internal only and
+  can't be used from the script.
+
+  Finally, if a buffer is created using another Evas Object as source (see
+  @ref sec_buffers_cmd "buffer" for more details), its pixel data will be filled
+  by rendering the Evas Object into this buffer. This is how it will be
+  possible to load external images, textures and even animations into a buffer.
+
+
+  @subsection sec_buffers_cmd Buffer command
+
+  @code
+    buffer : name;
+    buffer : name (alpha);
+    buffer : name (rgba);
+    buffer : name (src = partname);
+  @endcode
+
+  The "buffer" instruction is a @a special command used to declare a new buffer
+  in the filters context. This buffer can be either ALPHA, RGBA or based on
+  an other Evas Object (proxy source).
+  If no option is given, an RGBA buffer will be created.
+
+  @param name      An alpha-numerical name, starting with a letter (a-z, A-Z).
+                   Can not be @c input or @c output, as these are reserved names.
+                   Must be unique.
+
+  @param (args)    [alpha] OR [rgba] OR [src = partname] <br>
+    Create a new named buffer, specify its colorspace or source. Possible options:
+    @li @c alpha: Create an alpha-only buffer (1 channel, no color)
+    @li @c rgba: Create an RGBA buffer (4 channels, full color)
+    @li <tt>src = partname</tt>: Use another <tt>Evas Object</tt> as source for this
+      buffer's pixels. The name can either be an Edje part name or the one
+      specified in evas_obj_text_filter_source_set.
+
+  @see evas_obj_text_filter_source_set
+
+  @since 1.9
+ */
+
+// Map of the most common HTML color names
+static struct
+{
+   const char *name;
+   DATA32 value;
+} color_map[] =
+{
+   { "white", 0xFFFFFFFF },
+   { "black", 0xFF000000 },
+   { "red", 0xFFFF0000 },
+   { "green", 0xFF008000 },
+   { "blue", 0xFF0000FF },
+   { "darkblue", 0xFF0000A0 },
+   { "yellow", 0xFFFFFF00 },
+   { "magenta", 0xFFFF00FF },
+   { "cyan", 0xFF00FFFF },
+   { "orange", 0xFFFFA500 },
+   { "purple", 0xFF800080 },
+   { "brown", 0xFFA52A2A },
+   { "maroon", 0xFF800000 },
+   { "lime", 0xFF00FF00 },
+   { "gray", 0xFF808080 },
+   { "grey", 0xFF808080 },
+   { "silver", 0xFFC0C0C0 },
+   { "olive", 0xFF808000 },
+   { "invisible", 0x00000000 },
+   { "transparent", 0x00000000 }
+};
+
+static struct
+{
+   const char *name;
+   Evas_Filter_Fill_Mode value;
+} fill_modes[] =
+{
+   { "none", EVAS_FILTER_FILL_MODE_NONE },
+   { "stretch_x", EVAS_FILTER_FILL_MODE_STRETCH_X },
+   { "stretch_y", EVAS_FILTER_FILL_MODE_STRETCH_Y },
+   { "repeat_x", EVAS_FILTER_FILL_MODE_REPEAT_X },
+   { "repeat_y", EVAS_FILTER_FILL_MODE_REPEAT_Y },
+   { "repeat_x_stretch_y", EVAS_FILTER_FILL_MODE_REPEAT_X_STRETCH_Y },
+   { "repeat_y_stretch_x", EVAS_FILTER_FILL_MODE_REPEAT_Y_STRETCH_X },
+   { "stretch_y_repeat_x", EVAS_FILTER_FILL_MODE_REPEAT_X_STRETCH_Y }, // alias
+   { "stretch_x_repeat_y", EVAS_FILTER_FILL_MODE_REPEAT_Y_STRETCH_X }, // alias
+   { "repeat", EVAS_FILTER_FILL_MODE_REPEAT_XY }, // alias
+   { "repeat_xy", EVAS_FILTER_FILL_MODE_REPEAT_XY },
+   { "stretch", EVAS_FILTER_FILL_MODE_STRETCH_XY }, // alias
+   { "stretch_xy", EVAS_FILTER_FILL_MODE_STRETCH_XY }
+};
+
+typedef enum
+{
+   VT_NONE,
+   VT_BOOL,
+   VT_INT,
+   VT_REAL,
+   VT_STRING,
+   VT_COLOR,
+   VT_BUFFER
+} Value_Type;
+
+typedef struct _Buffer
+{
+   EINA_INLIST;
+   Eina_Stringshare *name;
+   Eina_Stringshare *proxy;
+   int cid; // Transient value
+   struct {
+      int l, r, t, b; // Used for padding calculation. Can change over time.
+   } pad;
+   Eina_Bool alpha : 1;
+} Buffer;
+
+typedef struct _Instruction_Param
+{
+   EINA_INLIST;
+   Eina_Stringshare *name;
+   Value_Type type;
+   Eina_Value *value;
+   Eina_Bool set : 1;
+   Eina_Bool allow_seq : 1;
+   Eina_Bool allow_any_string : 1;
+} Instruction_Param;
+
+struct _Evas_Filter_Instruction
+{
+   EINA_INLIST;
+   Eina_Stringshare *name;
+   int /* Evas_Filter_Mode */ type;
+   Eina_Inlist /* Instruction_Param */ *params;
+   struct
+   {
+      void (* update) (Evas_Filter_Program *, Evas_Filter_Instruction *, int *, int *, int *, int *);
+   } pad;
+   Eina_Bool valid : 1;
+};
+
+struct _Evas_Filter_Program
+{
+   Eina_Stringshare *name; // Optional for now
+   Eina_Hash /* const char * : Evas_Filter_Proxy_Binding */ *proxies;
+   Eina_Inlist /* Evas_Filter_Instruction */ *instructions;
+   Eina_Inlist /* Buffer */ *buffers;
+   struct {
+      int l, r, t, b;
+   } pad;
+   Eina_Bool valid : 1;
+   Eina_Bool padding_calc : 1; // Padding has been calculated
+   Eina_Bool padding_set : 1; // Padding has been forced
+};
+
+/* Instructions */
+static Evas_Filter_Instruction *
+_instruction_new(const char *name)
+{
+   Evas_Filter_Instruction *instr;
+
+   instr = calloc(1, sizeof(Evas_Filter_Instruction));
+   instr->name = eina_stringshare_add(name);
+
+   return instr;
+}
+
+static Eina_Bool
+_instruction_param_addv(Evas_Filter_Instruction *instr, const char *name,
+                        Value_Type format, Eina_Bool sequential, va_list args)
+{
+   const Eina_Value_Type *type = NULL;
+   Instruction_Param *param;
+
+   switch (format)
+     {
+      case VT_BOOL:
+      case VT_INT:
+        type = EINA_VALUE_TYPE_INT;
+        break;
+      case VT_REAL:
+        type = EINA_VALUE_TYPE_DOUBLE;
+        break;
+      case VT_STRING:
+      case VT_BUFFER:
+        type = EINA_VALUE_TYPE_STRING;
+        break;
+      case VT_COLOR:
+        type = EINA_VALUE_TYPE_UINT;
+        break;
+      case VT_NONE:
+      default:
+        return EINA_FALSE;
+     }
+
+   param = calloc(1, sizeof(Instruction_Param));
+   param->name = eina_stringshare_add(name);
+   param->type = format;
+   param->value = eina_value_new(type);
+   param->allow_seq = sequential;
+   eina_value_vset(param->value, args);
+   instr->params = eina_inlist_append(instr->params, EINA_INLIST_GET(param));
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_instruction_param_adda(Evas_Filter_Instruction *instr, const char *name,
+                        Value_Type format, Eina_Bool sequential,
+                        /* default value */ ...)
+{
+   Eina_Bool ok;
+   va_list args;
+
+   va_start(args, sequential);
+   ok = _instruction_param_addv(instr, name, format, sequential, args);
+   va_end(args);
+
+   return ok;
+}
+#define _instruction_param_seq_add(a,b,c,d) _instruction_param_adda((a),(b),(c),1,(d))
+#define _instruction_param_name_add(a,b,c,d) _instruction_param_adda((a),(b),(c),0,(d))
+
+static void
+_instruction_del(Evas_Filter_Instruction *instr)
+{
+   Instruction_Param *param;
+
+   if (!instr) return;
+   EINA_INLIST_FREE(instr->params, param)
+     {
+        eina_value_free(param->value);
+        eina_stringshare_del(param->name);
+        instr->params = eina_inlist_remove(instr->params, EINA_INLIST_GET(param));
+        free(param);
+     }
+   eina_stringshare_del(instr->name);
+   free(instr);
+}
+
+static int
+_instruction_param_geti(Evas_Filter_Instruction *instr, const char *name,
+                        Eina_Bool *isset)
+{
+   Instruction_Param *param;
+   int i = 0;
+
+   EINA_INLIST_FOREACH(instr->params, param)
+     if (!strcasecmp(name, param->name))
+       {
+          if (eina_value_get(param->value, &i))
+            {
+               if (isset) *isset = param->set;
+               return i;
+            }
+          else return -1;
+       }
+
+   if (isset) *isset = EINA_FALSE;
+   return -1;
+}
+
+static double
+_instruction_param_getd(Evas_Filter_Instruction *instr, const char *name,
+                        Eina_Bool *isset)
+{
+   Instruction_Param *param;
+   double i = 0;
+
+   EINA_INLIST_FOREACH(instr->params, param)
+     if (!strcasecmp(name, param->name))
+       {
+          if (eina_value_get(param->value, &i))
+            {
+               if (isset) *isset = param->set;
+               return i;
+            }
+          else return 0.0;
+       }
+
+   if (isset) *isset = EINA_FALSE;
+   return 0.0;
+}
+
+static DATA32
+_instruction_param_getc(Evas_Filter_Instruction *instr, const char *name,
+                        Eina_Bool *isset)
+{
+   Instruction_Param *param;
+   DATA32 i = 0;
+
+   EINA_INLIST_FOREACH(instr->params, param)
+     if (!strcasecmp(name, param->name))
+       {
+          if (eina_value_get(param->value, &i))
+            {
+               if (isset) *isset = param->set;
+               return i;
+            }
+          else return 0;
+       }
+
+   if (isset) *isset = EINA_FALSE;
+   return 0;
+}
+
+static const char *
+_instruction_param_gets(Evas_Filter_Instruction *instr, const char *name,
+                        Eina_Bool *isset)
+{
+   Instruction_Param *param;
+   const char *str = NULL;
+
+   EINA_INLIST_FOREACH(instr->params, param)
+     if (!strcasecmp(name, param->name))
+       {
+          if (eina_value_get(param->value, &str))
+            {
+               if (isset) *isset = param->set;
+               return str;
+            }
+          else return NULL;
+       }
+
+   if (isset) *isset = EINA_FALSE;
+   return NULL;
+}
+
+/* Parsing format: func ( arg , arg2 , argname=val1, argname2 = val2 ) */
+
+#define CHARS_ALPHABET "abcdefghijklmnopqrstuvwxyzABCDEFGHJIKLMNOPQRSTUVWXYZ"
+#define CHARS_NUMS "0123456789"
+#define CHARS_DELIMS "=-(),;#.:_"
+static const char *allowed_chars = CHARS_ALPHABET CHARS_NUMS "_";
+static const char *allowed_delim = CHARS_DELIMS;
+
+static char *
+_whitespace_ignore_strdup(const char *str)
+{
+   Eina_Bool inword = EINA_FALSE, wasword = EINA_FALSE;
+   char *dst, *ptr, *next;
+   int len;
+
+   if (!str) return NULL;
+   len = strlen(str);
+   dst = calloc(len + 1, 1);
+
+   // TODO: Support quoted strings ("string" or 'string')
+
+   ptr = dst;
+   for (; *str; str++)
+     {
+        if (isspace(*str))
+          {
+             wasword = inword;
+             inword = EINA_FALSE;
+          }
+        else if (isalpha(*str) || isdigit(*str))
+          {
+             if (wasword)
+               {
+                  ERR("Invalid space found in program code");
+                  goto invalid;
+               }
+             inword = EINA_TRUE;
+             *ptr++ = *str;
+          }
+        else if (*str == '/')
+          {
+             if (str[1] == '*')
+               {
+                  next = strstr(str + 2, "*/");
+                  if (!next)
+                    {
+                       ERR("Unterminated comment section, \"*/\" was not found");
+                       goto invalid;
+                    }
+                  str = next + 1;
+               }
+             else if (str[1] == '/')
+               {
+                  next = strchr(str + 2, '\n');
+                  if (!next) break;
+                  str = next;
+               }
+             else
+               {
+                  ERR("Character '/' not followed by '/' or '*' is invalid");
+                  goto invalid;
+               }
+          }
+        else
+          {
+             if (!strchr(allowed_delim, *str))
+               {
+                  ERR("Character '%1.1s' is not allowed", str);
+                  goto invalid;
+               }
+             wasword = inword = EINA_FALSE;
+             *ptr++ = *str;
+          }
+     }
+
+   *ptr = 0;
+   return dst;
+
+invalid:
+   free(dst);
+   return NULL;
+}
+
+// "key", alphanumeric chars only, starting with a letter
+static Eina_Bool
+_is_valid_string(const char *str)
+{
+   if (!str)
+     return EINA_FALSE;
+   if (!isalpha(*str++))
+     return EINA_FALSE;
+   for (; *str; str++)
+     if (!isalpha(*str) && !isdigit(*str) && (*str != '_'))
+       return EINA_FALSE;
+   return EINA_TRUE;
+}
+
+// valid number:
+static Eina_Bool
+_is_valid_number(const char *str)
+{
+   Eina_Bool dot = EINA_FALSE;
+   if (!str || !*str) return EINA_FALSE;
+   for (; *str; str++)
+     {
+        if (!isdigit(*str))
+          {
+             if (dot) return EINA_FALSE;
+             if (*str == '.') dot = EINA_TRUE;
+          }
+     }
+   return EINA_TRUE;
+}
+
+// FIXME/TODO: Add support for strings with "" AND/OR ''
+
+// "key=val"
+static Eina_Bool
+_is_valid_keyval(const char *str)
+{
+   char *equal;
+   Eina_Bool ok = EINA_TRUE;
+
+   if (!str) return EINA_FALSE;
+   equal = strchr(str, '=');
+   if (!equal) return EINA_FALSE;
+   *equal = 0;
+   if (!_is_valid_string(str))
+     ok = EINA_FALSE;
+   else if (!_is_valid_string(equal + 1))
+     {
+        if (!_is_valid_number(equal + 1))
+          ok = EINA_FALSE;
+     }
+   *equal = '=';
+   return ok;
+}
+
+static Eina_Bool
+_bool_parse(const char *str, Eina_Bool *b)
+{
+   if (!str || !*str) return EINA_FALSE;
+   if (!strcmp(str, "1") ||
+       !strcasecmp(str, "yes") ||
+       !strcasecmp(str, "on") ||
+       !strcasecmp(str, "enable") ||
+       !strcasecmp(str, "enabled") ||
+       !strcasecmp(str, "true"))
+     {
+        if (b) *b = EINA_TRUE;
+        return EINA_TRUE;
+     }
+   else if (!strcmp(str, "0") ||
+            !strcasecmp(str, "no") ||
+            !strcasecmp(str, "off") ||
+            !strcasecmp(str, "disable") ||
+            !strcasecmp(str, "disabled") ||
+            !strcasecmp(str, "false"))
+     {
+        if (b) *b = EINA_FALSE;
+        return EINA_TRUE;
+     }
+   return EINA_FALSE;
+}
+
+#define PARSE_ABORT() do {} while (0)
+//#define PARSE_ABORT() abort()
+
+#define PARSE_CHECK(a) do { if (!(a)) { ERR("Parsing failed because '%s' is false at %s:%d", #a, __FUNCTION__, __LINE__); PARSE_ABORT(); goto end; } } while (0)
+
+static Eina_Bool
+_color_parse(const char *word, DATA32 *color)
+{
+   DATA32 value;
+   Eina_Bool success = EINA_FALSE;
+
+   PARSE_CHECK(word && *word);
+
+   errno = 0;
+   if (*word == '#')
+     {
+        unsigned char a, r, g, b;
+        int slen = strlen(word);
+        PARSE_CHECK(evas_common_format_color_parse(word, slen, &r, &g, &b, &a));
+        value = ARGB_JOIN(a, r, g, b);
+     }
+   else
+     {
+        unsigned int k;
+        for (k = 0; k < (sizeof(color_map) / sizeof(color_map[0])); k++)
+          {
+             if (!strcasecmp(word, color_map[k].name))
+               {
+                  if (color) *color = color_map[k].value;
+                  return EINA_TRUE;
+               }
+          }
+        PARSE_CHECK(!"color name not found");
+     }
+
+   if ((value & 0xFF000000) == 0 && (value != 0))
+     value |= 0xFF000000;
+
+   if (color) *color = value;
+   success = EINA_TRUE;
+
+end:
+   return success;
+}
+
+static Eina_Bool
+_value_parse(Instruction_Param *param, const char *value)
+{
+   Eina_Bool b;
+   DATA32 color;
+   double d;
+   int i;
+
+   switch (param->type)
+     {
+      case VT_BOOL:
+        PARSE_CHECK(_bool_parse(value, &b));
+        eina_value_set(param->value, b ? 1 : 0);
+        return EINA_TRUE;
+      case VT_INT:
+        PARSE_CHECK(sscanf(value, "%d", &i) == 1);
+        eina_value_set(param->value, i);
+        return EINA_TRUE;
+      case VT_REAL:
+        PARSE_CHECK(sscanf(value, "%lf", &d) == 1);
+        eina_value_set(param->value, d);
+        return EINA_TRUE;
+      case VT_STRING:
+      case VT_BUFFER:
+        if (!param->allow_any_string) PARSE_CHECK(_is_valid_string(value));
+        eina_value_set(param->value, value);
+        return EINA_TRUE;
+      case VT_COLOR:
+        PARSE_CHECK(_color_parse(value, &color));
+        eina_value_set(param->value, color);
+        return EINA_TRUE;
+      case VT_NONE:
+      default:
+        PARSE_CHECK(!"invalid value type");
+     }
+
+end:
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+_instruction_parse(Evas_Filter_Instruction *instr, const char *string)
+{
+   Instruction_Param *param = NULL;
+   char *str = NULL, *token = NULL, *next = NULL, *optval = NULL, *optname = NULL;
+   Eina_Bool last = EINA_FALSE, namedargs = EINA_FALSE, success = EINA_FALSE;
+   int seqorder = 0;
+
+   instr->valid = EINA_FALSE;
+   PARSE_CHECK(string);
+
+   EINA_INLIST_FOREACH(instr->params, param)
+     param->set = EINA_FALSE;
+
+   // Copy and remove whitespaces now
+   str = _whitespace_ignore_strdup(string);
+   PARSE_CHECK(str);
+   token = str;
+
+   // Check instruction matches function name
+   next = strchr(token, '(');
+   PARSE_CHECK(next);
+   *next++ = 0;
+   PARSE_CHECK(!strcasecmp(token, instr->name));
+
+   // Read arguments
+   while (((token = strsep(&next, ",")) != NULL) && (!last))
+     {
+        Eina_Bool found = EINA_FALSE;
+
+        // Last argument
+        if (!next)
+          {
+             // ',' was not found, find ')'
+             next = strchr(token, ')');
+             PARSE_CHECK(next);
+             last = EINA_TRUE;
+             *next++ = 0;
+             PARSE_CHECK(!*next);
+          }
+
+        // Named arguments
+        if (_is_valid_keyval(token))
+          {
+             namedargs = EINA_TRUE;
+
+             optval = strchr(token, '=');
+             PARSE_CHECK(optval); // assert
+             *optval++ = 0;
+
+             optname = token;
+             EINA_INLIST_FOREACH(instr->params, param)
+               {
+                  if (!strcasecmp(param->name, optname))
+                    {
+                       found = EINA_TRUE;
+                       PARSE_CHECK(!param->set);
+                       PARSE_CHECK(_value_parse(param, optval));
+                       param->set = EINA_TRUE;
+                    }
+               }
+             PARSE_CHECK(found);
+          }
+        // Sequential arguments
+        else if (!namedargs &&
+                 (_is_valid_string(token) || _is_valid_number(token)))
+          {
+             int order = 0;
+
+             // Go to the nth argument
+             EINA_INLIST_FOREACH(instr->params, param)
+               {
+                  if (order < seqorder)
+                    order++;
+                  else
+                    {
+                       found = EINA_TRUE;
+                       break;
+                    }
+               }
+
+             PARSE_CHECK(found);
+             PARSE_CHECK(param->allow_seq);
+             PARSE_CHECK(_value_parse(param, token));
+             param->set = EINA_TRUE;
+             seqorder++;
+          }
+        else if (!last)
+          PARSE_CHECK(!"invalid argument list");
+     }
+   PARSE_CHECK(last);
+   success = EINA_TRUE;
+
+end:
+   free(str);
+   instr->valid = success;
+   return success;
+}
+
+/* Buffers */
+static Buffer *
+_buffer_get(Evas_Filter_Program *pgm, const char *name)
+{
+   Buffer *buf;
+   Evas_Object *source;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
+
+   EINA_INLIST_FOREACH(pgm->buffers, buf)
+     if (!strcmp(buf->name, name))
+       return buf;
+
+   // Auto proxies
+   if (pgm->proxies)
+     {
+        source = eina_hash_find(pgm->proxies, name);
+        if (!source) return NULL;
+
+        buf = calloc(1, sizeof(Buffer));
+        if (!buf) return NULL;
+
+        buf->name = eina_stringshare_add(name);
+        buf->proxy = eina_stringshare_add(name);
+        buf->alpha = EINA_FALSE;
+        pgm->buffers = eina_inlist_append(pgm->buffers, EINA_INLIST_GET(buf));
+        return buf;
+     }
+
+   return NULL;
+}
+
+static Eina_Bool
+_buffer_add(Evas_Filter_Program *pgm, const char *name, Eina_Bool alpha,
+            const char *src)
+{
+   Buffer *buf;
+
+   if (_buffer_get(pgm, name))
+     {
+        ERR("Buffer '%s' already exists", name);
+        return EINA_FALSE;
+     }
+
+   if (alpha && src)
+     {
+        ERR("Can not set proxy buffer as alpha!");
+        return EINA_FALSE;
+     }
+
+   buf = calloc(1, sizeof(Buffer));
+   if (!buf) return EINA_FALSE;
+
+   buf->name = eina_stringshare_add(name);
+   buf->proxy = eina_stringshare_add(src);
+   buf->alpha = alpha;
+   pgm->buffers = eina_inlist_append(pgm->buffers, EINA_INLIST_GET(buf));
+
+   return EINA_TRUE;
+}
+
+static void
+_buffer_del(Buffer *buf)
+{
+   if (!buf) return;
+   eina_stringshare_del(buf->name);
+   eina_stringshare_del(buf->proxy);
+   free(buf);
+}
+
+/* Instruction definitions */
+
+static void
+_blend_padding_update(Evas_Filter_Program *pgm, Evas_Filter_Instruction *instr,
+                      int *padl, int *padr, int *padt, int *padb)
+{
+   const char *inbuf, *outbuf;
+   Buffer *in, *out;
+   int ox, oy, l = 0, r = 0, t = 0, b = 0;
+
+   ox = _instruction_param_geti(instr, "ox", NULL);
+   oy = _instruction_param_geti(instr, "oy", NULL);
+
+   inbuf = _instruction_param_gets(instr, "src", NULL);
+   in = _buffer_get(pgm, inbuf);
+   EINA_SAFETY_ON_NULL_RETURN(in);
+
+   outbuf = _instruction_param_gets(instr, "dst", NULL);
+   out = _buffer_get(pgm, outbuf);
+   EINA_SAFETY_ON_NULL_RETURN(out);
+
+   if (ox < 0) l = (-ox) + in->pad.l;
+   else r = ox + in->pad.r;
+
+   if (oy < 0) t = (-oy) + in->pad.t;
+   else b = oy + in->pad.b;
+
+   if (out->pad.l < l) out->pad.l = l;
+   if (out->pad.r < r) out->pad.r = r;
+   if (out->pad.t < t) out->pad.t = t;
+   if (out->pad.b < b) out->pad.b = b;
+
+   if (padl) *padl = l;
+   if (padr) *padr = r;
+   if (padt) *padt = t;
+   if (padb) *padb = b;
+}
+
+/**
+  @page evasfiltersref
+  @section sec_commands Filter commands
+  @page evasfiltersref
+
+  This section will present the various filter instructions, their syntax
+  and their effects.
+ */
+
+/**
+  @page evasfiltersref
+
+  @subsection sec_commands_blend Blend
+
+  Blend a buffer onto another. This is the simplest filter, as it just
+  renders one buffer on another, potentially using a color, an
+  offset and fill options.
+
+  @code
+    blend (src = input, dst = output, ox = 0, oy = 0, color = white, fillmode = none);
+  @endcode
+
+  @param src Source buffer to blend.
+  @param dst Destination buffer for blending.
+  @param ox  X offset. Moves the buffer to the right (ox > 0) or to the left (ox < 0) by N pixels.
+  @param oy  Y offset. Moves the buffer to the bottom (oy > 0) or to the top (oy < 0) by N pixels.
+  @param color A color to use for alpha to RGBA conversion. See @ref evasfilters_color "colors". <br>
+                 If the input is an alpha buffer and the output is RGBA, this will
+                 draw the buffer in this color. If both buffers are RGBA, this will
+                 have no effect.
+  @param fillmode Map the input onto the whole surface of the output by stretching or
+                 repeating it. See @ref evasfilter_fillmode "fillmodes".
+
+  If @a src is an alpha buffer and @a dst is an RGBA buffer, then the @a color option should be set.
+
+  @include filter_blend.txt
+
+  <center>
+  @image html filter_blend.png
+  </center>
+
+  @since 1.9
+ */
+
+static Eina_Bool
+_blend_instruction_prepare(Evas_Filter_Instruction *instr)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr->name, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(!strcasecmp(instr->name, "blend"), EINA_FALSE);
+
+   instr->type = EVAS_FILTER_MODE_BLEND;
+   instr->pad.update = _blend_padding_update;
+   _instruction_param_seq_add(instr, "src", VT_BUFFER, "input");
+   _instruction_param_seq_add(instr, "dst", VT_BUFFER, "output");
+   _instruction_param_seq_add(instr, "ox", VT_INT, 0);
+   _instruction_param_seq_add(instr, "oy", VT_INT, 0);
+   _instruction_param_name_add(instr, "color", VT_COLOR, 0xFFFFFFFF);
+   _instruction_param_name_add(instr, "fillmode", VT_STRING, "none");
+
+   return EINA_TRUE;
+}
+
+static void
+_blur_padding_update(Evas_Filter_Program *pgm, Evas_Filter_Instruction *instr,
+                     int *padl, int *padr, int *padt, int *padb)
+{
+   Eina_Bool yset = EINA_FALSE;
+   int rx, ry, ox, oy, l, r, t, b, count;
+   const char *inbuf, *outbuf, *typestr;
+   Evas_Filter_Blur_Type type = EVAS_FILTER_BLUR_DEFAULT;
+   Buffer *in, *out;
+
+   rx = _instruction_param_geti(instr, "rx", NULL);
+   ry = _instruction_param_geti(instr, "ry", &yset);
+   ox = _instruction_param_geti(instr, "ox", NULL);
+   oy = _instruction_param_geti(instr, "oy", NULL);
+   inbuf = _instruction_param_gets(instr, "src", NULL);
+   outbuf = _instruction_param_gets(instr, "dst", NULL);
+   count = _instruction_param_geti(instr, "count", NULL);
+   typestr = _instruction_param_gets(instr, "type", NULL);
+
+   if (typestr && !strcasecmp(typestr, "box"))
+     type = EVAS_FILTER_BLUR_BOX;
+
+   in = _buffer_get(pgm, inbuf);
+   out = _buffer_get(pgm, outbuf);
+   EINA_SAFETY_ON_NULL_RETURN(in);
+   EINA_SAFETY_ON_NULL_RETURN(out);
+
+   if (!yset) ry = rx;
+   if (rx < 0) rx = 0;
+   if (ry < 0) ry = 0;
+
+   if (type == EVAS_FILTER_BLUR_BOX)
+     {
+        if (count < 1) count = 1;
+        if (count > 6) count = 3;
+     }
+   else
+     count = 1;
+
+   rx *= count;
+   ry *= count;
+
+   l = rx + in->pad.l + ((ox < 0) ? (-ox) : 0);
+   r = rx + in->pad.r + ((ox > 0) ? ox : 0);
+   t = ry + in->pad.t + ((oy < 0) ? (-oy) : 0);
+   b = ry + in->pad.b + ((oy > 0) ? oy : 0);
+
+   if (out->pad.l < l) out->pad.l = l;
+   if (out->pad.r < r) out->pad.r = r;
+   if (out->pad.t < t) out->pad.t = t;
+   if (out->pad.b < b) out->pad.b = b;
+
+   if (padl) *padl = l;
+   if (padr) *padr = r;
+   if (padt) *padt = t;
+   if (padb) *padb = b;
+}
+
+/**
+  @page evasfiltersref
+
+  @subsection sec_commands_blur Blur
+
+  Apply blur effect on a buffer (box or gaussian).
+
+  @code
+    blur (rx = 3, ry = -1, type = default, ox = 0, oy = 0, color = white, src = input, dst = output);
+  @endcode
+
+  @param rx    X radius. Specifies the radius of the blurring kernel (X direction).
+  @param ry    Y radius. Specifies the radius of the blurring kernel (Y direction). If -1 is used, then @a ry = @a rx.
+  @param type  Blur type to apply. One of @c default, @c box or @c gaussian. See below for details about @c default.
+  @param ox    X offset. Moves the buffer to the right (@a ox > 0) or to the left (@a ox < 0) by N pixels.
+  @param oy    Y offset. Moves the buffer to the bottom (@a oy > 0) or to the top (@a oy < 0) by N pixels.
+  @param color A color to use for alpha to RGBA conversion. See @ref evasfilters_color "colors". <br>
+                 If the input is an alpha buffer and the output is RGBA, this will
+                 draw the buffer in this color.
+  @param src   Source buffer to blur.
+  @param dst   Destination buffer for blending.
+  @param count Number of times to repeat the blur. Only valid with @c box blur. Valid range is: 1 to 6.
+
+  The blur type @c default is <b>recommended in all situations</b> as it will select the smoothest
+  and fastest operation possible depending on the kernel size. Instead of running a real
+  gaussian blur, 2 or 3 box blurs may be chained to produce a similar effect at a much
+  higher speed. The value @a count can be set to a value from 1 to 6 if blur type @c box
+  has been specified.
+
+  The speedups of @c box over @c gaussian are of orders of 4x to more than 20x faster.
+
+  If @a src is an alpha buffer and @a dst is an RGBA buffer, then the color option should be set.
+
+  @a ox and @a oy can be used to move the blurry output by a few pixels, like a drop shadow. Example:
+  @include filter_blur.txt
+
+  <center>
+  @image html filter_blur.png
+  </center>
+
+  @since 1.9
+ */
+
+static Eina_Bool
+_blur_instruction_prepare(Evas_Filter_Instruction *instr)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr->name, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(!strcasecmp(instr->name, "blur"), EINA_FALSE);
+
+   instr->type = EVAS_FILTER_MODE_BLUR;
+   instr->pad.update = _blur_padding_update;
+   _instruction_param_seq_add(instr, "rx", VT_INT, 3);
+   _instruction_param_seq_add(instr, "ry", VT_INT, -1);
+   _instruction_param_seq_add(instr, "type", VT_STRING, "default");
+   _instruction_param_seq_add(instr, "ox", VT_INT, 0);
+   _instruction_param_seq_add(instr, "oy", VT_INT, 0);
+   _instruction_param_name_add(instr, "color", VT_COLOR, 0xFFFFFFFF);
+   _instruction_param_name_add(instr, "src", VT_BUFFER, "input");
+   _instruction_param_name_add(instr, "dst", VT_BUFFER, "output");
+   _instruction_param_name_add(instr, "count", VT_INT, 0);
+
+   return EINA_TRUE;
+}
+
+/**
+  @page evasfiltersref
+
+  @subsection sec_commands_bump Bump
+
+  Apply a light effect (ambient light, specular reflection and shadows) based on a bump map.
+
+  This can be used to give a relief effect on the object.
+
+  @code
+    bump (map, azimuth = 135.0, elevation = 45.0, depth = 8.0, specular = 0.0,
+          color = white, compensate = false, src = input, dst = output,
+          black = black, white = white, fillmode = repeat);
+  @endcode
+
+  @param map        An alpha buffer treated like a Z map for the light effect (bump map). Must be specified.
+  @param azimuth    The angle between the light vector and the X axis in the XY plane (Z = 0). 135.0 means 45 degrees from the top-left. Counter-clockwise notation.
+  @param elevation  The angle between the light vector and the Z axis. 45.0 means 45 degrees to the screen's plane. Ranges from 0 to 90 only.
+  @param depth      The depth of the object in an arbitrary unit. More depth means the shadows will be stronger. Default is 8.0.
+  @param specular   An arbitrary unit for the specular light effect. Default is 0.0, but a common value would be 40.0.
+  @param color      The main color of the object if src is an alpha buffer. This represents the light's normal color. See @ref evasfilters_color "colors".
+  @param compensate If set to true, compensate for whitening or darkening on flat surfaces. Default is false but it is recommended if specular light is wanted.
+  @param src        Source buffer. This should be an alpha buffer.
+  @param dst        Destination buffer. This should be an RGBA buffer (although alpha is supported). Must be of the same size as @a src.
+  @param black      The shadows' color. Usually this will be black (@c #000).
+  @param white      The specular light's color. Usually this will be white (@c #FFF).
+  @param fillmode   This specifies how to handle @a map when its dimensions don't match those of @a src and @a dst. Default is to @c repeat. See @ref evasfilter_fillmode "fillmodes".
+
+  @note As of 2014/02/11, the ALPHA to RGBA support is of much better quality than ALPHA only, but @b very slow. RGBA sources are not supported yet.
+
+  Here is a full example of a very simple bevel effect:
+  @include filter_bump.txt
+
+  <center>
+  @image html filter_bump.png
+  </center>
+
+  @since 1.9
+ */
+
+static Eina_Bool
+_bump_instruction_prepare(Evas_Filter_Instruction *instr)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr->name, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(!strcasecmp(instr->name, "bump"), EINA_FALSE);
+
+   instr->type = EVAS_FILTER_MODE_BUMP;
+   _instruction_param_seq_add(instr, "map", VT_BUFFER, NULL);
+   _instruction_param_seq_add(instr, "azimuth", VT_REAL, 135.0);
+   _instruction_param_seq_add(instr, "elevation", VT_REAL, 45.0);
+   _instruction_param_seq_add(instr, "depth", VT_REAL, 8.0);
+   _instruction_param_seq_add(instr, "specular", VT_REAL, 0.0);
+   _instruction_param_name_add(instr, "color", VT_COLOR, 0xFFFFFFFF);
+   _instruction_param_name_add(instr, "compensate", VT_BOOL, EINA_FALSE);
+   _instruction_param_name_add(instr, "src", VT_BUFFER, "input");
+   _instruction_param_name_add(instr, "dst", VT_BUFFER, "output");
+   _instruction_param_name_add(instr, "black", VT_COLOR, 0xFF000000);
+   _instruction_param_name_add(instr, "white", VT_COLOR, 0xFFFFFFFF);
+   _instruction_param_name_add(instr, "fillmode", VT_STRING, "repeat");
+
+   return EINA_TRUE;
+}
+
+/**
+  @page evasfiltersref
+
+  @subsection sec_commands_curve Curve
+
+  Apply a color curve to a specific channel in a buffer.
+
+  @code
+    curve (points, interpolation = linear, channel = rgb, src = input, dst = output);
+  @endcode
+
+  Modify the colors of a buffer. This applies a color curve y = f(x) to every pixel.
+
+  @param points        The color curve to apply. See below for the syntax.
+  @param interpolation How to interpolate between points. One of @c linear (y = ax + b) or @c none (y = Yk).
+  @param channel       Target channel for the color modification. One of @c R(ed), @c G(reen), @c B(lue), @c A(lpha), @c RGB and @c RGBA. If @a src is an alpha buffer, this parameter will be ignored.
+  @param src           Source buffer.
+  @param dst           Destination buffer, must be of same dimensions and color space as @a src.
+
+  The @a points argument contains a list of (X,Y) points in the range 0..255,
+  describing a function <tt>f(x) = y</tt> to apply to all pixel values.
+
+  The syntax of this @a points string is <tt>x1:y1 - x2:y2 - x3:y3 - ... - xn:yn</tt>
+  (remember that all spaces are discarded).
+  The points @c xn are in @a increasing order: <tt>x1 < x2 < x3 < ... < xn</tt>,
+  and all values @c xn or @c yn are within the range 0..255.
+
+  The identity curve is then described as <tt>0:0-255:255</tt>, with linear interpolation:
+  @code
+    curve(points = 0:0 - 255:255, interpolation = linear);
+  @endcode
+  If ignored, y(x = 0) is 0 and y(x = 255) is 255.
+
+  The following example will generate a 4px thick stroke around text letters:
+  @include filter_curve.txt
+
+  <center>
+  @image html filter_curve.png
+  </center>
+
+  The curve command can be used to alter the output of a blur operation.
+
+  @since 1.9
+ */
+
+static Eina_Bool
+_curve_instruction_prepare(Evas_Filter_Instruction *instr)
+{
+   Instruction_Param *param;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr->name, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(!strcasecmp(instr->name, "curve"), EINA_FALSE);
+
+   instr->type = EVAS_FILTER_MODE_CURVE;
+
+   _instruction_param_seq_add(instr, "points", VT_STRING, NULL);
+   param = EINA_INLIST_CONTAINER_GET(eina_inlist_last(instr->params), Instruction_Param);
+   param->allow_any_string = EINA_TRUE;
+
+   _instruction_param_seq_add(instr, "interpolation", VT_STRING, "linear");
+   _instruction_param_seq_add(instr, "channel", VT_STRING, "rgb");
+   _instruction_param_name_add(instr, "src", VT_BUFFER, "input");
+   _instruction_param_name_add(instr, "dst", VT_BUFFER, "output");
+
+   return EINA_TRUE;
+}
+
+static void
+_displace_padding_update(Evas_Filter_Program *pgm,
+                         Evas_Filter_Instruction *instr,
+                         int *padl, int *padr, int *padt, int *padb)
+{
+   int intensity = 0;
+   int l, r, t, b;
+   const char *inbuf, *outbuf;
+   Buffer *in, *out;
+
+   intensity = _instruction_param_geti(instr, "intensity", NULL);
+   inbuf = _instruction_param_gets(instr, "src", NULL);
+   outbuf = _instruction_param_gets(instr, "dst", NULL);
+
+   in = _buffer_get(pgm, inbuf);
+   out = _buffer_get(pgm, outbuf);
+   EINA_SAFETY_ON_NULL_RETURN(in);
+   EINA_SAFETY_ON_NULL_RETURN(out);
+
+   l = intensity + in->pad.l;
+   r = intensity + in->pad.r;
+   t = intensity + in->pad.t;
+   b = intensity + in->pad.b;
+
+   if (out->pad.l < l) out->pad.l = l;
+   if (out->pad.r < r) out->pad.r = r;
+   if (out->pad.t < t) out->pad.t = t;
+   if (out->pad.b < b) out->pad.b = b;
+
+   if (padl) *padl = l;
+   if (padr) *padr = r;
+   if (padt) *padt = t;
+   if (padb) *padb = b;
+}
+
+/**
+  @page evasfiltersref
+
+  @subsection sec_commands_displace Displace
+
+  Apply a displacement map on a buffer.
+
+  @code
+    displace (map, intensity = 10, flags = 0, src = input, dst = output, fillmode = repeat);
+  @endcode
+
+  @param map       An RGBA buffer containing a displacement map. See below for more details.
+  @param intensity Maximum distance for the displacement.
+                   This means 0 and 255 will represent a displacement of @c intensity pixels.
+  @param flags     One of @c default, @c nearest, @c smooth, @c nearest_stretch or @c smooth_stretch.
+                   This defines how pixels should be treated when going out of the @a src image bounds.
+                   @c default is equivalent to @c smooth_stretch.
+  @param src       Source buffer
+  @param dst       Destination buffer. Must be of same color format and size as @a src.
+  @param fillmode  Defines how to handle cases where the map has a different size from @a src and @a dst.
+                   It should be a combination of @c stretch or @c repeat: @c none is not supported.
+                   See @ref evasfilter_fillmode "fillmodes".
+
+  <h3>Displacement map</h3>
+
+  The @a map buffer is an RGBA image containing displacement and alpha values.
+  Its size can be different from @c src or @c dst.
+
+  The @b red channel is used for X displacements while the @b green channel is
+  used for Y displacements. All subpixel values are in the range 0..255.
+  A value of 128 means 0 displacement, lower means displace to the top/left
+  and higher than 128 displace to the bottom/right.
+
+  If <tt>signed char</tt> is used instead of <tt>unsigned char</tt> to represent
+  these R and G values, then < 0 means displace top/left while > 0 means bottom/right.
+
+  The @c alpha channel is used as an alpha multiplier for blending.
+
+  Considering <tt>I(x, y)</tt> represents the pixel at position (x, y) in the
+  image I, then here is how the displacement is applied to @a dst:
+  @code
+    D = map (x, y)
+    dst (x, y) += D.alpha * src (D.red * intensity / 128, D.green * intensity / 128)
+  @endcode
+  Of course, the real algorithm takes into account interpolation between pixels as well.
+
+  @since 1.9
+ */
+
+static Eina_Bool
+_displace_instruction_prepare(Evas_Filter_Instruction *instr)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr->name, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(!strcasecmp(instr->name, "displace"), EINA_FALSE);
+
+   instr->type = EVAS_FILTER_MODE_DISPLACE;
+   instr->pad.update = _displace_padding_update;
+   _instruction_param_seq_add(instr, "map", VT_BUFFER, NULL);
+   _instruction_param_seq_add(instr, "intensity", VT_INT, 10);
+   _instruction_param_seq_add(instr, "flags", VT_STRING, "default");
+   _instruction_param_name_add(instr, "src", VT_BUFFER, "input");
+   _instruction_param_name_add(instr, "dst", VT_BUFFER, "output");
+   _instruction_param_name_add(instr, "fillmode", VT_STRING, "repeat");
+
+   return EINA_TRUE;
+}
+
+/**
+  @page evasfiltersref
+
+  @subsection sec_commands_fill Fill
+
+  Fill a buffer with a specific color.
+  Not blending, can be used to clear a buffer.
+
+  @code
+    fill (dst = output, color = transparent, l = 0, r = 0, t = 0, b = 0);
+  @endcode
+
+  @param dst       Target buffer to fill with @a color.
+  @param color     The color used to fill the buffer. All pixels within the fill area will be reset to this value. See @ref evasfilters_color "colors".
+  @param l         Left padding: skip @a l pixels from the left border of the buffer
+  @param r         Right padding: skip @a r pixels from the right border of the buffer
+  @param t         Top padding: skip @a t pixels from the top border of the buffer
+  @param b         Bottom padding: skip @a b pixels from the bottom border of the buffer
+
+  This function should generally not be used, except for:
+  <ul>
+    <li>@a Testing an effect over a specific background color</li>
+    <li>Clearing out a buffer with either white or transparent color</li>
+  </ul>
+
+  @since 1.9
+ */
+
+static Eina_Bool
+_fill_instruction_prepare(Evas_Filter_Instruction *instr)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr->name, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(!strcasecmp(instr->name, "fill"), EINA_FALSE);
+
+   instr->type = EVAS_FILTER_MODE_FILL;
+   _instruction_param_seq_add(instr, "dst", VT_BUFFER, "output");
+   _instruction_param_seq_add(instr, "color", VT_COLOR, 0x0);
+   _instruction_param_seq_add(instr, "l", VT_INT, 0);
+   _instruction_param_seq_add(instr, "r", VT_INT, 0);
+   _instruction_param_seq_add(instr, "t", VT_INT, 0);
+   _instruction_param_seq_add(instr, "b", VT_INT, 0);
+
+   return EINA_TRUE;
+}
+
+static void
+_grow_padding_update(Evas_Filter_Program *pgm, Evas_Filter_Instruction *instr,
+                     int *padl, int *padr, int *padt, int *padb)
+{
+   const char *inbuf, *outbuf;
+   Buffer *in, *out;
+   int l, r, t, b;
+   int radius;
+
+   radius = _instruction_param_geti(instr, "radius", NULL);
+   inbuf = _instruction_param_gets(instr, "src", NULL);
+   outbuf = _instruction_param_gets(instr, "dst", NULL);
+
+   in = _buffer_get(pgm, inbuf);
+   out = _buffer_get(pgm, outbuf);
+   EINA_SAFETY_ON_NULL_RETURN(in);
+   EINA_SAFETY_ON_NULL_RETURN(out);
+
+   if (radius < 0) radius = 0;
+
+   l = radius + in->pad.l;
+   r = radius + in->pad.r;
+   t = radius + in->pad.t;
+   b = radius + in->pad.b;
+
+   if (padl) *padl = l;
+   if (padr) *padr = r;
+   if (padt) *padt = t;
+   if (padb) *padb = b;
+
+   if (out->pad.l < l) out->pad.l = l;
+   if (out->pad.r < r) out->pad.r = r;
+   if (out->pad.t < t) out->pad.t = t;
+   if (out->pad.b < b) out->pad.b = b;
+}
+
+/**
+  @page evasfiltersref
+
+  @subsection sec_commands_grow Grow
+
+  Grow or shrink a buffer's contents. This is not a zoom effect.
+
+  @code
+    grow (radius, smooth = true, src = input, dst = output);
+  @endcode
+
+  @param radius  The radius of the grow kernel.
+                 If a negative value is specified, the contents will shrink rather than grow.
+  @param smooth  If @c true, use a smooth transitions between black and white (smooth blur and smoother curve).
+  @param src     Source buffer to blur.
+  @param dst     Destination buffer for blending. This must be of same size and colorspace as @a src.
+
+  Example:
+  @include filter_grow.txt
+
+  This will first grow the letters in the buffer @c input by a few pixels, and
+  then draw this buffer in black in the background.
+
+  <center>
+  @image html filter_grow.png
+  </center>
+
+  @since 1.9
+ */
+
+static Eina_Bool
+_grow_instruction_prepare(Evas_Filter_Instruction *instr)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr->name, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(!strcasecmp(instr->name, "grow"), EINA_FALSE);
+
+   instr->type = EVAS_FILTER_MODE_GROW;
+   instr->pad.update = _grow_padding_update;
+   _instruction_param_seq_add(instr, "radius", VT_INT, 0);
+   _instruction_param_name_add(instr, "smooth", VT_BOOL, EINA_TRUE);
+   _instruction_param_name_add(instr, "src", VT_BUFFER, "input");
+   _instruction_param_name_add(instr, "dst", VT_BUFFER, "output");
+
+   return EINA_TRUE;
+}
+
+/**
+  @page evasfiltersref
+
+  @subsection sec_commands_mask Mask
+
+  Blend two input buffers into a third (target).
+
+  @code
+    mask (mask, src = input, dst = output, color = white, fillmode = none);
+  @endcode
+
+  @param mask     A mask or texture to blend with the input @a src into the target @a dst.
+  @param src      Source buffer. This can also be thought of a mask if @a src is alpha and @a mask is RGBA.
+  @param dst      Destination buffer for blending. This must be of same size and colorspace as @a src.
+  @param color    A color to use for alpha to RGBA conversion for the blend operations. White means no change.
+                  See @ref evasfilters_color "colors". This will have no effect on RGBA sources.
+  @param fillmode Defines whether to stretch or repeat the @a mask if its size that of @src. Should be set when masking with external textures. Default is none. See @ref evasfilter_fillmode "fillmodes".
+
+  Note that @a src and @a mask are interchangeable, if they have the same dimensions.
+
+  Example:
+  @include filter_mask.txt
+
+  This will create an inner shadow effect.
+
+  <center>
+  @image html filter_mask.png
+  </center>
+
+  @since 1.9
+ */
+
+static Eina_Bool
+_mask_instruction_prepare(Evas_Filter_Instruction *instr)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr->name, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(!strcasecmp(instr->name, "mask"), EINA_FALSE);
+
+   instr->type = EVAS_FILTER_MODE_MASK;
+   _instruction_param_seq_add(instr, "mask", VT_BUFFER, NULL);
+   _instruction_param_seq_add(instr, "src", VT_BUFFER, "input");
+   _instruction_param_seq_add(instr, "dst", VT_BUFFER, "output");
+   _instruction_param_name_add(instr, "color", VT_COLOR, 0xFFFFFFFF);
+   _instruction_param_name_add(instr, "fillmode", VT_STRING, "none");
+
+   return EINA_TRUE;
+}
+
+static void
+_transform_padding_update(Evas_Filter_Program *pgm,
+                          Evas_Filter_Instruction *instr,
+                          int *padl, int *padr, int *padt, int *padb)
+{
+   const char *outbuf;
+   Buffer *out;
+   int ox, oy, l = 0, r = 0, t = 0, b = 0;
+
+   //ox = _instruction_param_geti(instr, "ox", NULL);
+   ox = 0;
+   oy = _instruction_param_geti(instr, "oy", NULL);
+
+   outbuf = _instruction_param_gets(instr, "dst", NULL);
+   out = _buffer_get(pgm, outbuf);
+   EINA_SAFETY_ON_NULL_RETURN(out);
+
+   if (ox < 0) l = (-ox) * 2;
+   else r = ox * 2;
+
+   if (oy < 0) t = (-oy) * 2;
+   else b = oy * 2;
+
+   if (out->pad.l < l) out->pad.l = l;
+   if (out->pad.r < r) out->pad.r = r;
+   if (out->pad.t < t) out->pad.t = t;
+   if (out->pad.b < b) out->pad.b = b;
+
+   if (padl) *padl = l;
+   if (padr) *padr = r;
+   if (padt) *padt = t;
+   if (padb) *padb = b;
+}
+
+/**
+  @page evasfiltersref
+
+  @subsection sec_commands_transform Transform
+
+  Apply a geometrical transformation to a buffer.
+
+  Right now, only <b>vertical flip</b> is implemented and available.
+  This operation does not blend and assumes the destination buffer is empty.
+
+  @code
+    transform (dst, op = vflip, src = input, oy = 0);
+  @endcode
+
+  @param dst      Destination buffer. Must be of the same colorspace as @a src. Must be specified.
+  @param op       Must be @c vflip. There is no other operation yet.
+  @param src      Source buffer to transform.
+  @param oy       Y offset.
+
+  Example:
+  @include filter_transform.txt
+
+  This will create a mirrored text effect, for a font of 50px.
+
+  <center>
+  @image html filter_transform.png
+  </center>
+
+  @note Because of the meaning of @a oy, this effect probably needs to be
+        customized for a single font size (FIXME).
+
+  @since 1.9
+ */
+
+static Eina_Bool
+_transform_instruction_prepare(Evas_Filter_Instruction *instr)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr->name, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(!strcasecmp(instr->name, "transform"), EINA_FALSE);
+
+   instr->type = EVAS_FILTER_MODE_TRANSFORM;
+   instr->pad.update = _transform_padding_update;
+   _instruction_param_seq_add(instr, "dst", VT_BUFFER, NULL);
+   _instruction_param_seq_add(instr, "op", VT_STRING, "vflip");
+   _instruction_param_seq_add(instr, "src", VT_BUFFER, "input");
+   //_instruction_param_name_add(instr, "ox", VT_INT, 0);
+   _instruction_param_name_add(instr, "oy", VT_INT, 0);
+
+   return EINA_TRUE;
+}
+
+static void
+_padding_set_padding_update(Evas_Filter_Program *pgm,
+                            Evas_Filter_Instruction *instr,
+                            int *padl, int *padr, int *padt, int *padb)
+{
+   int l = 0, r = 0, t = 0, b = 0;
+   Eina_Bool lset = EINA_FALSE;
+   Eina_Bool rset = EINA_FALSE;
+   Eina_Bool tset = EINA_FALSE;
+   Eina_Bool bset = EINA_FALSE;
+
+   l = _instruction_param_geti(instr, "l", &lset);
+   r = _instruction_param_geti(instr, "r", &rset);
+   t = _instruction_param_geti(instr, "t", &tset);
+   b = _instruction_param_geti(instr, "b", &bset);
+
+   if (!lset && !rset && !bset && !tset)
+     DBG("padding_set() called without specifying any of l,r,t,b resets to 0");
+
+   if (l < 0 || r < 0 || t < 0 || b < 0)
+     {
+        WRN("invalid padding values in padding_set(%d, %d, %d, %d), resets to 0", l, r, t, b);
+        l = r = t = b = 0;
+     }
+
+   if (!rset) r = l;
+   if (!tset) t = r;
+   if (!bset) b = t;
+
+   if (padl) *padl = l;
+   if (padr) *padr = r;
+   if (padt) *padt = t;
+   if (padb) *padb = b;
+   pgm->padding_set = EINA_TRUE;
+}
+
+/**
+  @page evasfiltersref
+
+  @subsection sec_commands_padding_set Padding_Set
+
+  Forcily set a specific padding for this filter.
+
+  @code
+  padding_set (l, r = [l], t = [r], b = [t]);
+  @endcode
+
+  @param l        Padding on the left side in pixels.
+  @param r        Padding on the right side in pixels. If unset, defaults to @a l.
+  @param t        Padding on the top in pixels. If unset, defaults to @a r.
+  @param b        Padding on the bottom in pixels. If unset, defaults to @a t.
+
+  All values must be >= 0. When filtering 'filled' images, some values may be too high
+  and would result in completely hiding the image.
+
+  It is not possible to set only one of those without forcing the others as well.
+  A common use case will be when changing a blur size during an animation, or
+  when applying a mask that will hide most of the (blurred) text.
+
+  @since 1.10
+ */
+
+static Eina_Bool
+_padding_set_instruction_prepare(Evas_Filter_Instruction *instr)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr->name, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(!strcasecmp(instr->name, "padding_set"), EINA_FALSE);
+
+   instr->type = EVAS_FILTER_MODE_PADDING_SET;
+   instr->pad.update = _padding_set_padding_update;
+   _instruction_param_seq_add(instr, "l", VT_INT, 0);
+   _instruction_param_seq_add(instr, "r", VT_INT, 0);
+   _instruction_param_seq_add(instr, "t", VT_INT, 0);
+   _instruction_param_seq_add(instr, "b", VT_INT, 0);
+
+   return EINA_TRUE;
+}
+
+static Evas_Filter_Instruction *
+_instruction_create(const char *name)
+{
+   Evas_Filter_Instruction *instr;
+   Eina_Bool (* prepare) (Evas_Filter_Instruction *) = NULL;
+
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(name && *name, NULL);
+
+   if (!strcasecmp(name, "blend"))
+     prepare = _blend_instruction_prepare;
+   else if (!strcasecmp(name, "blur"))
+     prepare = _blur_instruction_prepare;
+   else if (!strcasecmp(name, "bump"))
+     prepare = _bump_instruction_prepare;
+   else if (!strcasecmp(name, "curve"))
+     prepare = _curve_instruction_prepare;
+   else if (!strcasecmp(name, "displace"))
+     prepare = _displace_instruction_prepare;
+   else if (!strcasecmp(name, "fill"))
+     prepare = _fill_instruction_prepare;
+   else if (!strcasecmp(name, "grow"))
+     prepare = _grow_instruction_prepare;
+   else if (!strcasecmp(name, "mask"))
+     prepare = _mask_instruction_prepare;
+   else if (!strcasecmp(name, "transform"))
+     prepare = _transform_instruction_prepare;
+   else if (!strcasecmp(name, "padding_set"))
+     prepare = _padding_set_instruction_prepare;
+
+   if (!prepare)
+     {
+        ERR("Invalid instruction name '%s'", name);
+        return NULL;
+     }
+
+   instr = _instruction_new(name);
+   if (!instr) return NULL;
+
+   if (!prepare(instr))
+     {
+        CRI("Failed to prepare instruction '%s'. Check the code.", name);
+        _instruction_del(instr);
+        return NULL;
+     }
+   return instr;
+}
+
+/* Evas_Filter_Parser entry points */
+
+#undef PARSE_CHECK
+#define PARSE_CHECK(a) do { if (!(a)) { ERR("Parsing failed because '%s' is false at %s:%d", #a, __FUNCTION__, __LINE__); PARSE_ABORT(); goto end; } } while (0)
+
+EAPI void
+evas_filter_program_del(Evas_Filter_Program *pgm)
+{
+   Evas_Filter_Instruction *instr;
+   Buffer *buf;
+
+   if (!pgm) return;
+
+   EINA_INLIST_FREE(pgm->buffers, buf)
+     {
+        pgm->buffers = eina_inlist_remove(pgm->buffers, EINA_INLIST_GET(buf));
+        _buffer_del(buf);
+     }
+
+   EINA_INLIST_FREE(pgm->instructions, instr)
+     {
+        pgm->instructions = eina_inlist_remove(pgm->instructions, EINA_INLIST_GET(instr));
+        _instruction_del(instr);
+     }
+
+   eina_stringshare_del(pgm->name);
+   free(pgm);
+}
+
+static Eina_Bool
+_instruction_buffer_parse(Evas_Filter_Program *pgm, char *command)
+{
+   Eina_Bool success = EINA_FALSE;
+   char *bufname = NULL, *src = NULL, *tok, *tok2;
+   Eina_Bool alpha = EINA_FALSE;
+   size_t sz;
+
+   tok = strchr(command, ':');
+   PARSE_CHECK(tok);
+   PARSE_CHECK(!strncasecmp("buffer:", command, tok - command));
+
+   tok++;
+   tok2 = strchr(tok, '(');
+   if (!tok2)
+     bufname = tok;
+   else
+     {
+        *tok2++ = 0;
+        bufname = tok;
+        tok = strchr(tok2, ')');
+        PARSE_CHECK(tok);
+        *tok = 0;
+        if (!*tok2)
+          alpha = EINA_FALSE;
+        else if (!strcasecmp(tok2, "rgba"))
+          alpha = EINA_FALSE;
+        else if (!strcasecmp(tok2, "alpha"))
+          alpha = EINA_TRUE;
+        else if (!strncasecmp("src=", tok2, 4))
+          {
+             src = tok2 + 4;
+             alpha = EINA_FALSE;
+          }
+        else
+          PARSE_CHECK(!"Invalid buffer type");
+     }
+
+   sz = strspn(bufname, allowed_chars);
+   PARSE_CHECK(sz == strlen(bufname));
+   PARSE_CHECK(_buffer_add(pgm, bufname, (alpha != 0), src));
+   success = EINA_TRUE;
+
+end:
+   return success;
+}
+
+/** Parse a style program */
+
+EAPI Eina_Bool
+evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str)
+{
+   Evas_Filter_Instruction *instr = NULL;
+   Instruction_Param *param;
+   Eina_Bool success = EINA_FALSE, ok;
+   char *token, *next, *code, *instrname;
+   int count = 0;
+   size_t spn;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(str, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(*str != 0, EINA_FALSE);
+
+   code = _whitespace_ignore_strdup(str);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(code, EINA_FALSE);
+
+   // NOTE: '' or "" strings will be broken by strsep if they contain ';'.
+   // But we don't support them anyway :)
+
+   next = code;
+   while ((token = strsep(&next, ";")) != NULL)
+     {
+        if (!next)
+          {
+             // Semicolon is mandatory.
+             DBG("End of processing");
+             PARSE_CHECK(!*token);
+             break;
+          }
+
+        // Empty command
+        if (next == token + 1) continue;
+
+        // Parse "instrname(options)" or "buffer:a(options)"
+        spn = strcspn(token, "(:");
+        PARSE_CHECK(spn);
+        if (token[spn] == ':')
+          PARSE_CHECK(_instruction_buffer_parse(pgm, token));
+        else if (token[spn] == '(')
+          {
+             instrname = token;
+             instrname[spn] = 0;
+
+             instr = _instruction_create(instrname);
+             PARSE_CHECK(instr);
+
+             instrname[spn] = '(';
+             ok = _instruction_parse(instr, token);
+             PARSE_CHECK(ok);
+
+             // Check buffers validity
+             EINA_INLIST_FOREACH(instr->params, param)
+               {
+                  const char *bufname = NULL;
+
+                  if (param->type != VT_BUFFER) continue;
+                  PARSE_CHECK(eina_value_get(param->value, &bufname));
+                  if (!_buffer_get(pgm, bufname))
+                    {
+                       ERR("Buffer '%s' does not exist!", bufname);
+                       goto end;
+                    }
+               }
+
+             // Add to the queue
+             pgm->instructions = eina_inlist_append(pgm->instructions, EINA_INLIST_GET(instr));
+             pgm->padding_calc = EINA_FALSE;
+             instr = NULL;
+             count++;
+          }
+        else PARSE_CHECK(!"invalid command");
+     }
+   success = (count > 0);
+
+   DBG("Program successfully compiled with %d instruction(s)", count);
+
+end:
+   if (!success)
+     {
+        ERR("Failed to parse program");
+        _instruction_del(instr);
+     }
+   free(code);
+
+   pgm->valid = success;
+   return success;
+}
+
+/** Evaluate required padding to correctly apply an effect */
+
+EAPI Eina_Bool
+evas_filter_program_padding_get(Evas_Filter_Program *pgm,
+                                int *l, int *r, int *t, int *b)
+{
+   Evas_Filter_Instruction *instr;
+   int pl = 0, pr = 0, pt = 0, pb = 0;
+   int maxl = 0, maxr = 0, maxt = 0, maxb = 0;
+   Buffer *buf;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, EINA_FALSE);
+
+   if (pgm->padding_calc || pgm->padding_set)
+     {
+        if (l) *l = pgm->pad.l;
+        if (r) *r = pgm->pad.r;
+        if (t) *t = pgm->pad.t;
+        if (b) *b = pgm->pad.b;
+        return EINA_TRUE;
+     }
+
+   // Reset all paddings
+   EINA_INLIST_FOREACH(pgm->buffers, buf)
+     buf->pad.l = buf->pad.r = buf->pad.t = buf->pad.b = 0;
+
+   // Accumulate paddings
+   EINA_INLIST_FOREACH(pgm->instructions, instr)
+     {
+        if (instr->type == EVAS_FILTER_MODE_PADDING_SET)
+          {
+             instr->pad.update(pgm, instr, &maxl, &maxr, &maxt, &maxb);
+             break;
+          }
+        else if (instr->pad.update)
+          {
+             instr->pad.update(pgm, instr, &pl, &pr, &pt, &pb);
+             if (pl > maxl) maxl = pl;
+             if (pr > maxr) maxr = pr;
+             if (pt > maxt) maxt = pt;
+             if (pb > maxb) maxb = pb;
+          }
+     }
+
+   pgm->pad.l = maxl;
+   pgm->pad.r = maxr;
+   pgm->pad.t = maxt;
+   pgm->pad.b = maxb;
+   pgm->padding_calc = EINA_TRUE;
+
+   if (l) *l = maxl;
+   if (r) *r = maxr;
+   if (t) *t = maxt;
+   if (b) *b = maxb;
+
+   return EINA_TRUE;
+}
+
+/** Create an empty filter program for style parsing */
+
+EAPI Evas_Filter_Program *
+evas_filter_program_new(const char *name)
+{
+   Evas_Filter_Program *pgm;
+
+   pgm = calloc(1, sizeof(Evas_Filter_Program));
+   if (!pgm) return NULL;
+   pgm->name = eina_stringshare_add(name);
+   _buffer_add(pgm, "input", EINA_TRUE, NULL);
+   _buffer_add(pgm, "output", EINA_FALSE, NULL);
+
+   return pgm;
+}
+
+/** Bind objects for proxy rendering */
+EAPI void
+evas_filter_program_source_set_all(Evas_Filter_Program *pgm,
+                                   Eina_Hash *proxies)
+{
+   if (!pgm) return;
+   pgm->proxies = proxies;
+}
+
+/** Glue with Evas' filters */
+
+#define CA(color) ((color >> 24) & 0xFF)
+#define CR(color) ((color >> 16) & 0xFF)
+#define CG(color) ((color >> 8) & 0xFF)
+#define CB(color) ((color) & 0xFF)
+
+#define SETCOLOR(c) do { ENFN->context_color_get(ENDT, dc, &R, &G, &B, &A); \
+   ENFN->context_color_set(ENDT, dc, CR(c), CG(c), CB(c), CA(c)); } while (0)
+#define RESETCOLOR() do { ENFN->context_color_set(ENDT, dc, R, G, B, A); } while (0)
+
+#define SETCLIP(l, r, t, b) int _l = 0, _r = 0, _t = 0, _b = 0; \
+   do { ENFN->context_clip_get(ENDT, dc, &_l, &_r, &_t, &_b); \
+   ENFN->context_clip_set(ENDT, dc, l, r, t, b); } while (0)
+#define RESETCLIP() do { ENFN->context_clip_set(ENDT, dc, _l, _r, _t, _b); } while (0)
+
+static Evas_Filter_Fill_Mode
+_fill_mode_get(Evas_Filter_Instruction *instr)
+{
+   const char *fill;
+   unsigned k;
+
+   if (!instr) return EVAS_FILTER_FILL_MODE_NONE;
+   fill = _instruction_param_gets(instr, "fillmode", NULL);
+
+   for (k = 0; k < sizeof(fill_modes) / sizeof(fill_modes[0]); k++)
+     {
+        if (!strcasecmp(fill_modes[k].name, fill))
+          return fill_modes[k].value;
+     }
+
+   return EVAS_FILTER_FILL_MODE_NONE;
+}
+
+static int
+_instr2cmd_blend(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm,
+                 Evas_Filter_Instruction *instr, void *dc)
+{
+   Eina_Bool isset = EINA_FALSE;
+   const char *src, *dst;
+   DATA32 color;
+   Buffer *in, *out;
+   Evas_Filter_Fill_Mode fillmode;
+   int cmdid, ox, oy, A, R, G, B;
+
+   src = _instruction_param_gets(instr, "src", NULL);
+   dst = _instruction_param_gets(instr, "dst", NULL);
+   ox = _instruction_param_geti(instr, "ox", NULL);
+   oy = _instruction_param_geti(instr, "oy", NULL);
+   color = _instruction_param_getc(instr, "color", &isset);
+   fillmode = _fill_mode_get(instr);
+   in = _buffer_get(pgm, src);
+   out = _buffer_get(pgm, dst);
+
+   if (isset) SETCOLOR(color);
+   cmdid = evas_filter_command_blend_add(ctx, dc, in->cid, out->cid, ox, oy,
+                                         fillmode);
+   if (isset) RESETCOLOR();
+   if (cmdid < 0) return cmdid;
+
+   return cmdid;
+}
+
+static int
+_instr2cmd_blur(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm,
+                Evas_Filter_Instruction *instr, void *dc)
+{
+   Eina_Bool colorset = EINA_FALSE, yset = EINA_FALSE, cntset = EINA_FALSE;
+   Evas_Filter_Blur_Type type = EVAS_FILTER_BLUR_DEFAULT;
+   const char *src, *dst, *typestr;
+   DATA32 color;
+   Buffer *in, *out;
+   int cmdid, ox, oy, rx, ry, A, R, G, B, count;
+
+   src = _instruction_param_gets(instr, "src", NULL);
+   dst = _instruction_param_gets(instr, "dst", NULL);
+   ox = _instruction_param_geti(instr, "ox", NULL);
+   oy = _instruction_param_geti(instr, "oy", NULL);
+   rx = _instruction_param_geti(instr, "rx", NULL);
+   ry = _instruction_param_geti(instr, "ry", &yset);
+   color = _instruction_param_getc(instr, "color", &colorset);
+   typestr = _instruction_param_gets(instr, "type", NULL);
+   count = _instruction_param_geti(instr, "count", &cntset);
+   in = _buffer_get(pgm, src);
+   out = _buffer_get(pgm, dst);
+
+   if (typestr)
+     {
+        if (!strcasecmp(typestr, "gaussian"))
+          type = EVAS_FILTER_BLUR_GAUSSIAN;
+        else if (!strcasecmp(typestr, "box"))
+          type = EVAS_FILTER_BLUR_BOX;
+        else if (!strcasecmp(typestr, "default"))
+          type = EVAS_FILTER_BLUR_DEFAULT;
+        else
+          ERR("Unknown blur type '%s'. Using default blur.", typestr);
+     }
+
+   if (type == EVAS_FILTER_BLUR_BOX)
+     {
+        if (count < 1) count = 1;
+        if (count > 6)
+          {
+             WRN("Box blur count should be below 6, defaults to 3.");
+             count = 3;
+          }
+     }
+   else
+     {
+        if (cntset) WRN("Blur count can only be used with BOX blur.");
+        count = 1;
+     }
+
+   if (!yset) ry = rx;
+   if (colorset) SETCOLOR(color);
+   cmdid = evas_filter_command_blur_add(ctx, dc, in->cid, out->cid, type,
+                                        rx, ry, ox, oy, count);
+   if (colorset) RESETCOLOR();
+
+   return cmdid;
+}
+
+static int
+_instr2cmd_bump(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm,
+                Evas_Filter_Instruction *instr, void *dc)
+{
+   Evas_Filter_Bump_Flags flags = EVAS_FILTER_BUMP_NORMAL;
+   Evas_Filter_Fill_Mode fillmode;
+   const char *src, *dst, *map;
+   DATA32 color, black, white;
+   Buffer *in, *out, *bump;
+   double azimuth, elevation, depth, specular;
+   int cmdid, compensate;
+
+   src = _instruction_param_gets(instr, "src", NULL);
+   dst = _instruction_param_gets(instr, "dst", NULL);
+   map = _instruction_param_gets(instr, "map", NULL);
+   color = _instruction_param_getc(instr, "color", NULL);
+   white = _instruction_param_getc(instr, "white", NULL);
+   black = _instruction_param_getc(instr, "black", NULL);
+   azimuth = _instruction_param_getd(instr, "azimuth", NULL);
+   elevation = _instruction_param_getd(instr, "elevation", NULL);
+   depth = _instruction_param_getd(instr, "depth", NULL);
+   specular = _instruction_param_getd(instr, "specular", NULL);
+   compensate = _instruction_param_geti(instr, "compensate", NULL);
+   fillmode = _fill_mode_get(instr);
+   if (compensate) flags |= EVAS_FILTER_BUMP_COMPENSATE;
+
+   in = _buffer_get(pgm, src);
+   out = _buffer_get(pgm, dst);
+   bump = _buffer_get(pgm, map);
+
+   cmdid = evas_filter_command_bump_map_add(ctx, dc, in->cid, bump->cid, out->cid,
+                                            azimuth, elevation, depth, specular,
+                                            black, color, white, flags,
+                                            fillmode);
+
+   return cmdid;
+}
+
+static int
+_instr2cmd_displace(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm,
+                    Evas_Filter_Instruction *instr, void *dc)
+{
+   Evas_Filter_Fill_Mode fillmode;
+   Evas_Filter_Displacement_Flags flags =
+         EVAS_FILTER_DISPLACE_STRETCH | EVAS_FILTER_DISPLACE_LINEAR;
+   const char *src, *dst, *map, *flagsstr;
+   Buffer *in, *out, *mask;
+   int cmdid, intensity;
+   Eina_Bool isset = EINA_FALSE;
+
+   src = _instruction_param_gets(instr, "src", NULL);
+   dst = _instruction_param_gets(instr, "dst", NULL);
+   map = _instruction_param_gets(instr, "map", NULL);
+   intensity = _instruction_param_geti(instr, "intensity", NULL);
+   flagsstr = _instruction_param_gets(instr, "flags", &isset);
+   fillmode = _fill_mode_get(instr);
+
+   if (!flagsstr) flagsstr = "default";
+   if (!strcasecmp(flagsstr, "nearest"))
+     flags = EVAS_FILTER_DISPLACE_NEAREST;
+   else if (!strcasecmp(flagsstr, "smooth"))
+     flags = EVAS_FILTER_DISPLACE_LINEAR;
+   else if (!strcasecmp(flagsstr, "nearest_stretch"))
+     flags = EVAS_FILTER_DISPLACE_NEAREST | EVAS_FILTER_DISPLACE_STRETCH;
+   else if (!strcasecmp(flagsstr, "default") || !strcasecmp(flagsstr, "smooth_stretch"))
+     flags = EVAS_FILTER_DISPLACE_STRETCH | EVAS_FILTER_DISPLACE_LINEAR;
+   else if (isset)
+     WRN("Invalid flags '%s' in displace operation. Using default instead", flagsstr);
+
+   in = _buffer_get(pgm, src);
+   out = _buffer_get(pgm, dst);
+   mask = _buffer_get(pgm, map);
+
+   cmdid = evas_filter_command_displacement_map_add(ctx, dc, in->cid, out->cid,
+                                                    mask->cid, flags, intensity,
+                                                    fillmode);
+
+   return cmdid;
+}
+
+static int
+_instr2cmd_fill(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm,
+                Evas_Filter_Instruction *instr, void *dc)
+{
+   const char *bufname;
+   Buffer *buf;
+   int R, G, B, A, l, r, t, b;
+   Evas_Filter_Command *cmd;
+   Eina_Inlist *il;
+   DATA32 color;
+   int cmdid;
+
+   bufname = _instruction_param_gets(instr, "dst", NULL);
+   color = _instruction_param_getc(instr, "color", NULL);
+   l = _instruction_param_geti(instr, "l", NULL);
+   r = _instruction_param_geti(instr, "r", NULL);
+   t = _instruction_param_geti(instr, "t", NULL);
+   b = _instruction_param_geti(instr, "b", NULL);
+
+   buf = _buffer_get(pgm, bufname);
+
+   SETCOLOR(color);
+   cmdid = evas_filter_command_fill_add(ctx, dc, buf->cid);
+   RESETCOLOR();
+
+   if (cmdid < 0) return -1;
+   il = eina_inlist_last(ctx->commands);
+   if (!il) return -1;
+
+   cmd = EINA_INLIST_CONTAINER_GET(il, Evas_Filter_Command);
+   cmd->draw.clip.l = l;
+   cmd->draw.clip.r = r;
+   cmd->draw.clip.t = t;
+   cmd->draw.clip.b = b;
+   cmd->draw.clip_mode_lrtb = EINA_TRUE;
+
+   return cmdid;
+}
+
+static int
+_instr2cmd_grow(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm,
+                Evas_Filter_Instruction *instr, void *dc)
+{
+   Evas_Filter_Command *cmd;
+   const char *src, *dst;
+   Buffer *in, *out;
+   Eina_Bool smooth;
+   int cmdid, radius;
+
+   src = _instruction_param_gets(instr, "src", NULL);
+   dst = _instruction_param_gets(instr, "dst", NULL);
+   radius = _instruction_param_geti(instr, "radius", NULL);
+   smooth = _instruction_param_geti(instr, "smooth", NULL);
+
+   in = _buffer_get(pgm, src);
+   out = _buffer_get(pgm, dst);
+
+   cmdid = evas_filter_command_grow_add(ctx, dc, in->cid, out->cid,
+                                        radius, smooth);
+
+   cmd = _evas_filter_command_get(ctx, cmdid);
+   if (cmd) cmd->draw.need_temp_buffer = EINA_TRUE;
+
+   return cmdid;
+}
+
+static int
+_instr2cmd_mask(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm,
+                Evas_Filter_Instruction *instr, void *dc)
+{
+   Evas_Filter_Fill_Mode fillmode;
+   const char *src, *dst, *msk;
+   Buffer *in, *out, *mask;
+   DATA32 color;
+   int R, G, B, A, cmdid;
+
+   src = _instruction_param_gets(instr, "src", NULL);
+   dst = _instruction_param_gets(instr, "dst", NULL);
+   msk = _instruction_param_gets(instr, "mask", NULL);
+   color = _instruction_param_getc(instr, "color", NULL);
+   fillmode = _fill_mode_get(instr);
+
+   in = _buffer_get(pgm, src);
+   out = _buffer_get(pgm, dst);
+   mask = _buffer_get(pgm, msk);
+
+   SETCOLOR(color);
+   cmdid = evas_filter_command_mask_add(ctx, dc, in->cid, mask->cid, out->cid, fillmode);
+   RESETCOLOR();
+   if (cmdid < 0) return cmdid;
+
+   if (!in->alpha && !mask->alpha && !out->alpha)
+     {
+        Evas_Filter_Command *cmd;
+
+        cmd = _evas_filter_command_get(ctx, cmdid);
+        cmd->draw.need_temp_buffer = EINA_TRUE;
+     }
+
+   return cmdid;
+}
+
+static int
+_instr2cmd_curve(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm,
+                 Evas_Filter_Instruction *instr, void *dc)
+{
+   Evas_Filter_Interpolation_Mode mode = EVAS_FILTER_INTERPOLATION_MODE_LINEAR;
+   Evas_Filter_Channel channel = EVAS_FILTER_CHANNEL_RGB;
+   const char *src, *dst, *points_str, *interpolation, *channel_name;
+   DATA8 values[256] = {0}, points[512];
+   int cmdid, point_count = 0;
+   char *token, *copy = NULL;
+   Buffer *in, *out;
+   Eina_Bool parse_ok = EINA_FALSE;
+
+   src = _instruction_param_gets(instr, "src", NULL);
+   dst = _instruction_param_gets(instr, "dst", NULL);
+   points_str = _instruction_param_gets(instr, "points", NULL);
+   interpolation = _instruction_param_gets(instr, "interpolation", NULL);
+   channel_name = _instruction_param_gets(instr, "channel", NULL);
+
+   if (channel_name)
+     {
+        if (tolower(*channel_name) == 'r')
+          {
+             if (!strcasecmp(channel_name, "rgb"))
+               channel = EVAS_FILTER_CHANNEL_RGB;
+             else
+               channel = EVAS_FILTER_CHANNEL_RED;
+          }
+        else if (tolower(*channel_name) == 'g')
+          channel = EVAS_FILTER_CHANNEL_GREEN;
+        else if (tolower(*channel_name) == 'b')
+          channel = EVAS_FILTER_CHANNEL_BLUE;
+        else if (tolower(*channel_name) == 'a')
+          channel = EVAS_FILTER_CHANNEL_ALPHA;
+     }
+
+   if (interpolation && !strcasecmp(interpolation, "none"))
+     mode = EVAS_FILTER_INTERPOLATION_MODE_NONE;
+
+   if (!points_str) goto interpolated;
+   copy = strdup(points_str);
+   token = strtok(copy, "-");
+   if (!token) goto interpolated;
+
+   while (token)
+     {
+        int x, y, r, maxx = 0;
+        r = sscanf(token, "%u:%u", &x, &y);
+        if (r != 2) goto interpolated;
+        if (x < maxx || x >= 256) goto interpolated;
+        points[point_count * 2 + 0] = x;
+        points[point_count * 2 + 1] = y;
+        point_count++;
+        token = strtok(NULL, "-");
+     }
+
+   parse_ok = evas_filter_interpolate(values, points, point_count, mode);
+
+interpolated:
+   free(copy);
+   if (!parse_ok)
+     {
+        int x;
+        ERR("Failed to parse the interpolation chain");
+        for (x = 0; x < 256; x++)
+          values[x] = x;
+     }
+
+   in = _buffer_get(pgm, src);
+   out = _buffer_get(pgm, dst);
+   cmdid = evas_filter_command_curve_add(ctx, dc, in->cid, out->cid, values, channel);
+
+   return cmdid;
+}
+
+static int
+_instr2cmd_transform(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm,
+                     Evas_Filter_Instruction *instr, void *dc)
+{
+   Evas_Filter_Transform_Flags flags;
+   const char *src, *dst, *op;
+   Buffer *in, *out;
+   int ox = 0, oy;
+
+   op = _instruction_param_gets(instr, "op", NULL);
+   src = _instruction_param_gets(instr, "src", NULL);
+   dst = _instruction_param_gets(instr, "dst", NULL);
+   // ox = _instruction_param_geti(instr, "ox", NULL);
+   oy = _instruction_param_geti(instr, "oy", NULL);
+
+   if (!strcasecmp(op, "vflip"))
+     flags = EVAS_FILTER_TRANSFORM_VFLIP;
+   else
+     {
+        ERR("Invalid transform '%s'", op);
+        return -1;
+     }
+
+   in = _buffer_get(pgm, src);
+   out = _buffer_get(pgm, dst);
+   return evas_filter_command_transform_add(ctx, dc, in->cid, out->cid, flags, ox, oy);
+}
+
+static int
+_command_from_instruction(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm,
+                          Evas_Filter_Instruction *instr, void *dc)
+{
+   int (* instr2cmd) (Evas_Filter_Context *, Evas_Filter_Program *,
+                      Evas_Filter_Instruction *, void *);
+
+   switch (instr->type)
+     {
+      case EVAS_FILTER_MODE_BLEND:
+        instr2cmd = _instr2cmd_blend;
+        break;
+      case EVAS_FILTER_MODE_BLUR:
+        instr2cmd = _instr2cmd_blur;
+        break;
+      case EVAS_FILTER_MODE_BUMP:
+        instr2cmd = _instr2cmd_bump;
+        break;
+      case EVAS_FILTER_MODE_DISPLACE:
+        instr2cmd = _instr2cmd_displace;
+        break;
+      case EVAS_FILTER_MODE_FILL:
+        instr2cmd = _instr2cmd_fill;
+        break;
+      case EVAS_FILTER_MODE_GROW:
+        instr2cmd = _instr2cmd_grow;
+        break;
+      case EVAS_FILTER_MODE_MASK:
+        instr2cmd = _instr2cmd_mask;
+        break;
+      case EVAS_FILTER_MODE_CURVE:
+        instr2cmd = _instr2cmd_curve;
+        break;
+      case EVAS_FILTER_MODE_TRANSFORM:
+        instr2cmd = _instr2cmd_transform;
+        break;
+      case EVAS_FILTER_MODE_PADDING_SET:
+        return EINA_TRUE;
+      default:
+        CRI("Invalid instruction type: %d", instr->type);
+        return -1;
+     }
+
+   return instr2cmd(ctx, pgm, instr, dc);
+}
+
+Eina_Bool
+evas_filter_context_program_use(Evas_Filter_Context *ctx,
+                                Evas_Filter_Program *pgm)
+{
+   Buffer *buf;
+   Evas_Filter_Instruction *instr;
+   Eina_Bool success = EINA_FALSE;
+   void *dc = NULL;
+   int cmdid;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(pgm->valid, EINA_FALSE);
+
+   DBG("Using program '%s' for context %p", pgm->name, ctx);
+
+   // Create empty context with all required buffers
+   evas_filter_context_clear(ctx);
+   EINA_INLIST_FOREACH(pgm->buffers, buf)
+     {
+        buf->cid = evas_filter_buffer_empty_new(ctx, buf->alpha);
+        if (buf->proxy)
+          {
+             Evas_Filter_Proxy_Binding *pb;
+             Evas_Filter_Buffer *fb;
+
+             pb = eina_hash_find(pgm->proxies, buf->proxy);
+             if (!pb) continue;
+
+             fb = _filter_buffer_get(ctx, buf->cid);
+             fb->proxy = pb->eo_proxy;
+             fb->source = pb->eo_source;
+             fb->source_name = eina_stringshare_ref(pb->name);
+             fb->ctx->has_proxies = EINA_TRUE;
+          }
+     }
+
+   // Compute and save padding info
+   evas_filter_program_padding_get(pgm, &ctx->padl, &ctx->padr, &ctx->padt, &ctx->padb);
+
+   dc = ENFN->context_new(ENDT);
+   ENFN->context_color_set(ENDT, dc, 255, 255, 255, 255);
+
+   // Apply all commands
+   EINA_INLIST_FOREACH(pgm->instructions, instr)
+     {
+        cmdid = _command_from_instruction(ctx, pgm, instr, dc);
+        if (cmdid <= 0)
+          goto end;
+     }
+
+   success = EINA_TRUE;
+
+end:
+   if (!success) evas_filter_context_clear(ctx);
+   if (dc) ENFN->context_free(ENDT, dc);
+   return success;
+}
diff --git a/src/lib/filters/evas_filter_private.h b/src/lib/filters/evas_filter_private.h
new file mode 100644 (file)
index 0000000..1ef69a9
--- /dev/null
@@ -0,0 +1,266 @@
+#ifndef EVAS_FILTER_PRIVATE_H
+#define EVAS_FILTER_PRIVATE_H
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#if (VMAJ == 1) && (VMIN == 7)
+#include "evas_filter_tizen_compat.h"
+#endif
+
+#include "evas_filter.h"
+#include "evas_private.h"
+
+// This is a potential optimization.
+#define DIV_USING_BITSHIFT 1
+
+#ifdef LITTLE_ENDIAN
+#define ALPHA 3
+#define RGB0 0
+#define RGB3 3
+#define RED 2
+#define GREEN 1
+#define BLUE 0
+#else
+#define ALPHA 0
+#define RGB0 1
+#define RGB3 4
+#define RED 0
+#define GREEN 1
+#define BLUE 2
+#endif
+
+// RGBA = (((a) << 24) + ((r) << 16) + ((g) << 8) + (b))
+#define ALPHA_OF(a) ((a) >> 24)
+#define RED_OF(a)   (((a) >> 16) & 0xff)
+#define GREEN_OF(a) (((a) >> 8) & 0xff)
+#define BLUE_OF(a)  ((a) & 0xff)
+
+// Enable debug if you're working on optimizations
+#define DEBUG_TIME 1
+
+// Windows build will break if CLOCK_MONOTONIC is used
+#if !defined(_POSIX_MONOTONIC_CLOCK) || (_POSIX_MONOTONIC_CLOCK < 0)
+# undef DEBUG_TIME
+# define DEBUG_TIME 0
+#endif
+
+// The 'restrict' keyword is part of C99
+#if __STDC_VERSION__ < 199901L
+# define restrict
+#endif
+
+// Helpers
+#define ENFN ctx->evas->engine.func
+#define ENDT ctx->evas->engine.data.output
+
+#define BUFFERS_LOCK() do { if (cmd->input) cmd->input->locked = 1; if (cmd->output) cmd->output->locked = 1; if (cmd->mask) cmd->mask->locked = 1; } while (0)
+#define BUFFERS_UNLOCK() do { if (cmd->input) cmd->input->locked = 0; if (cmd->output) cmd->output->locked = 0; if (cmd->mask) cmd->mask->locked = 0; } while (0)
+
+#if DEBUG_TIME
+# define DEBUG_TIME_BEGIN() \
+   struct timespec ts1, ts2; \
+   clock_gettime(CLOCK_MONOTONIC, &ts1);
+# define DEBUG_TIME_END() \
+   clock_gettime(CLOCK_MONOTONIC, &ts2); \
+   long long int t = 1000000LL * (ts2.tv_sec - ts1.tv_sec) \
+   + (ts2.tv_nsec - ts1.tv_nsec) / 1000LL; \
+   INF("TIME SPENT: %lldus", t);
+#else
+# define DEBUG_TIME_BEGIN() do {} while(0)
+# define DEBUG_TIME_END() do {} while(0)
+#endif
+
+#if DIV_USING_BITSHIFT
+# define DEFINE_DIVIDER(div) const int pow2 = evas_filter_smallest_pow2_larger_than((div) << 10); const int numerator = (1 << pow2) / (div);
+# define DIVIDE(val) (((val) * numerator) >> pow2)
+#else
+# define DEFINE_DIVIDER(div) const int divider = (div);
+# define DIVIDE(val) ((val) / divider)
+#endif
+
+#if (VMAJ == 1) && (VMIN == 7)
+typedef void (*image_draw_func) (void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth);
+#define ARG_DO_ASYNC
+#else
+typedef Eina_Bool (*image_draw_func) (void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async);
+#define HAS_DO_ASYNC 1
+#define ARG_DO_ASYNC , Eina_Bool do_async EINA_UNUSED
+#endif
+
+typedef enum _Evas_Filter_Interpolation_Mode Evas_Filter_Interpolation_Mode;
+
+struct _Evas_Filter_Context
+{
+#if (VMAJ > 1) || (VMIN >= 8)
+   Evas_Public_Data *evas;
+#else
+   Evas *evas;
+#endif
+   Eina_Inlist *commands;
+   Eina_List *buffers; // Evas_Filter_Buffer *
+   int last_buffer_id;
+   int last_command_id;
+
+   // Variables changing at each run
+   int w, h; // Dimensions of the input/output buffers
+   int padl, padt, padr, padb; // Padding in the current input/output buffers
+
+   struct
+   {
+      /** Post-processing callback. The context can be safely destroyed here. */
+      Evas_Filter_Cb cb;
+      void *data;
+      Eina_List *buffers_to_free; // Some buffers should be queued for deletion
+   } post_run;
+
+   struct
+   {
+      int bufid;
+      void *context;
+      int x, y;
+      int cx, cy, cw, ch; // clip
+      int r, g, b, a; // clip color
+      void *mask; // mask
+      int mask_x, mask_y; // mask offset
+      Eina_Bool clip_use : 1;
+      Eina_Bool color_use : 1;
+   } target;
+
+   Eina_Bool async : 1;
+   Eina_Bool gl_engine : 1;
+   Eina_Bool running : 1;
+   Eina_Bool has_proxies : 1;
+};
+
+struct _Evas_Filter_Command
+{
+   EINA_INLIST;
+
+   int id;
+   Evas_Filter_Mode mode;
+   Evas_Filter_Context *ctx;
+
+   Evas_Filter_Buffer *input;
+   Evas_Filter_Buffer *mask;
+   Evas_Filter_Buffer *output;
+
+   union
+   {
+      struct
+      {
+         int dx, dy;
+         int count;
+         Evas_Filter_Blur_Type type;
+         Eina_Bool auto_count : 1; // If true, BOX blur will be smooth using
+      } blur;
+
+      struct
+      {
+         DATA8 *data; // Pointer to 256 char array
+         Evas_Filter_Channel channel;
+      } curve;
+
+      struct
+      {
+         // mask contains the map data
+         Evas_Filter_Displacement_Flags flags;
+         int intensity; // Max displacement in pixels
+      } displacement;
+
+      struct
+      {
+         float xyangle; // in degrees: 0-360 (modulo)
+         float zangle;  // degrees: 0-90 (defaults to 0)
+         float specular_factor; // range TBD: 0-...
+         float elevation;
+         DATA32 dark;
+         DATA32 color;
+         DATA32 white;
+         Eina_Bool compensate : 1; // Compensate for darkening
+         //Eina_Bool specular : 1; // Use specular light as well (needs specular_factor > 0)
+      } bump;
+
+      struct
+      {
+         Evas_Filter_Transform_Flags flags;
+      } transform;
+   };
+
+   struct {
+      int render_op;
+      int R, G, B, A;
+      int ox, oy;
+      union {
+         struct {
+            int x, y, w, h;
+         };
+         struct {
+            int l, r, t, b;
+         };
+      } clip;
+      Evas_Filter_Fill_Mode fillmode;
+      Eina_Bool clip_use : 1;
+      Eina_Bool clip_mode_lrtb : 1;
+      Eina_Bool need_temp_buffer : 1;
+   } draw;
+};
+
+struct _Evas_Filter_Buffer
+{
+   EINA_REFCOUNT;
+
+   int id;
+   Evas_Filter_Context *ctx;
+
+   Evas_Object *source;
+   Eina_Stringshare *source_name;
+   RGBA_Image *backing;
+   void *glimage;
+   int w, h;
+
+   Evas_Object *proxy;
+
+   Eina_Bool alpha_only : 1;  // 1 channel (A) instead of 4 (RGBA)
+   Eina_Bool allocated : 1;   // allocated on demand, belongs to this context
+   Eina_Bool allocated_gl : 1; // allocated on demand the glimage
+   Eina_Bool transient : 1;   // temporary buffer (automatic allocation)
+   Eina_Bool locked : 1;      // internal flag
+   Eina_Bool stolen : 1;      // stolen by the client
+   Eina_Bool delete_me : 1;   // request delete asap (after released by client)
+};
+
+enum _Evas_Filter_Interpolation_Mode
+{
+   EVAS_FILTER_INTERPOLATION_MODE_NONE,
+   EVAS_FILTER_INTERPOLATION_MODE_LINEAR
+};
+
+void                     evas_filter_context_clear(Evas_Filter_Context *ctx);
+void                     evas_filter_context_source_set(Evas_Filter_Context *ctx, Evas_Object *eo_proxy, Evas_Object *eo_source, int bufid, Eina_Stringshare *name);
+
+/* FIXME: CPU filters entry points. Move these to the Evas Engine itself. */
+Evas_Filter_Apply_Func   evas_filter_blend_cpu_func_get(Evas_Filter_Command *cmd);
+Evas_Filter_Apply_Func   evas_filter_blur_cpu_func_get(Evas_Filter_Command *cmd);
+Evas_Filter_Apply_Func   evas_filter_bump_map_cpu_func_get(Evas_Filter_Command *cmd);
+Evas_Filter_Apply_Func   evas_filter_curve_cpu_func_get(Evas_Filter_Command *cmd);
+Evas_Filter_Apply_Func   evas_filter_displace_cpu_func_get(Evas_Filter_Command *cmd);
+Evas_Filter_Apply_Func   evas_filter_fill_cpu_func_get(Evas_Filter_Command *cmd);
+Evas_Filter_Apply_Func   evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd);
+Evas_Filter_Apply_Func   evas_filter_transform_cpu_func_get(Evas_Filter_Command *cmd);
+
+/* Utility functions */
+void _clip_to_target(int *sx, int *sy, int sw, int sh, int ox, int oy, int dw, int dh, int *dx, int *dy, int *rows, int *cols);
+Eina_Bool evas_filter_buffer_alloc(Evas_Filter_Buffer *fb, int w, int h);
+Evas_Filter_Buffer *_filter_buffer_get(Evas_Filter_Context *ctx, int bufid);
+Eina_Bool           _filter_buffer_data_set(Evas_Filter_Context *ctx, int bufid, void *data, int w, int h, Eina_Bool alpha_only);
+Evas_Filter_Buffer *_filter_buffer_data_new(Evas_Filter_Context *ctx, void *data, int w, int h, Eina_Bool alpha_only);
+#define             evas_filter_buffer_alloc_new(ctx, w, h, a) _filter_buffer_data_new(ctx, NULL, w, h, a)
+Evas_Filter_Buffer *evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only);
+Evas_Filter_Buffer *evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx, Evas_Filter_Buffer *src, unsigned w, unsigned h);
+Eina_Bool evas_filter_interpolate(DATA8* output /* 256 values */, DATA8* points /* pairs x + y */, int point_count, Evas_Filter_Interpolation_Mode mode);
+Evas_Filter_Command *_evas_filter_command_get(Evas_Filter_Context *ctx, int cmdid);
+int evas_filter_smallest_pow2_larger_than(int val);
+
+#endif // EVAS_FILTER_PRIVATE_H
diff --git a/src/lib/filters/evas_filter_tizen_compat.h b/src/lib/filters/evas_filter_tizen_compat.h
new file mode 100644 (file)
index 0000000..b76f112
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef EVAS_FILTERS_TIZEN_COMPAT_H
+#define EVAS_FILTERS_TIZEN_COMPAT_H
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#if (VMAJ == 1) && (VMIN == 7)
+
+/* This file will contain a few Tizen compilation fixups */
+
+#define EVAS_TIZEN_FIXUPS 1
+
+#include "evas_common.h"
+
+// EFL 1.8
+
+#define CRI(...) CRIT(__VA_ARGS__)
+
+// Eina 1.8
+
+/**
+ * @def EINA_INLIST_FREE
+ * @param list The list to free.
+ * @param it The pointer to the list item, i.e. a pointer to each item
+ * that is part of the list.
+ *
+ * NOTE: it is the duty of the body loop to properly remove the item from the
+ * inlist and free it. This function will turn into a infinite loop if you
+ * don't remove all items from the list.
+ * @since 1.8
+ */
+#define EINA_INLIST_FREE(list, it)                              \
+  for (it = (__typeof__(it)) list; list; it = (__typeof__(it)) list)
+
+static inline Eina_Inlist *eina_inlist_last(Eina_Inlist *i)
+{
+   return i->last;
+}
+
+#endif // Evas 1.7
+
+#endif // EVAS_FILTERS_TIZEN_COMPAT_H
diff --git a/src/lib/filters/evas_filter_transform.c b/src/lib/filters/evas_filter_transform.c
new file mode 100644 (file)
index 0000000..3deda12
--- /dev/null
@@ -0,0 +1,93 @@
+#include "evas_filter_private.h"
+
+/* Apply geomeetrical transformations to a buffer.
+ * This filter is a bit simplistic at the moment.
+ *
+ * It also assumes the destination is empty, as it does not use blend
+ * operations. This should probably be fixed later on (use evas_map?).
+ */
+
+static Eina_Bool
+_vflip_cpu(Evas_Filter_Command *cmd)
+{
+   size_t datasize, stride;
+   DATA8 *in, *out, *span = NULL;
+   int w, h, sy, dy, oy, center, t, b, objh;
+   int s0, s1, d0, d1;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
+
+   w = cmd->input->w;
+   h = cmd->input->h;
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->w == w, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->h == h, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->alpha_only == cmd->input->alpha_only, EINA_FALSE);
+
+   in = ((RGBA_Image *) cmd->input->backing)->image.data8;
+   out = ((RGBA_Image *) cmd->output->backing)->image.data8;
+   datasize = cmd->input->alpha_only ? sizeof(DATA8) : sizeof(DATA32);
+   stride = w * datasize;
+
+   oy = cmd->draw.oy;
+   t = cmd->ctx->padt;
+   b = cmd->ctx->padb;
+   objh = h - t - b;
+   center = t + objh / 2 + oy;
+
+   s0 = t;
+   s1 = h - b - 1;
+   if (oy >= 0)
+     {
+        d0 = center + (objh / 2) + oy;
+        d1 = center - (objh / 2) - oy;
+     }
+   else
+     {
+        d0 = center + (objh / 2) - oy;
+        d1 = center - (objh / 2) + oy;
+     }
+
+   if (in == out)
+     {
+        span = malloc(stride);
+        if (!span) return EINA_FALSE;
+     }
+
+   for (sy = s0, dy = d0; (dy >= d1) && (sy <= s1); sy++, dy--)
+     {
+        DATA8* src = in + stride * sy;
+        DATA8* dst = out + stride * dy;
+
+        if (in == out)
+          {
+             if (src == dst) break;
+             memcpy(span, dst, stride);
+             memcpy(dst, src, stride);
+             memcpy(src, span, stride);
+             if (sy >= center) break;
+          }
+        else
+          memcpy(dst, src, stride);
+     }
+   free(span);
+   return EINA_TRUE;
+}
+
+Evas_Filter_Apply_Func
+evas_filter_transform_cpu_func_get(Evas_Filter_Command *cmd)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
+
+   switch (cmd->transform.flags)
+     {
+      case EVAS_FILTER_TRANSFORM_VFLIP:
+        return _vflip_cpu;
+      default:
+        CRI("Unknown transform flag %d", (int) cmd->transform.flags);
+        return NULL;
+     }
+}
diff --git a/src/lib/filters/evas_filter_utils.c b/src/lib/filters/evas_filter_utils.c
new file mode 100644 (file)
index 0000000..ef72eeb
--- /dev/null
@@ -0,0 +1,166 @@
+/* Utility functions for the filters.  */
+
+#include "evas_filter_private.h"
+
+Evas_Filter_Buffer *
+evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx,
+                              Evas_Filter_Buffer *src,
+                              unsigned w, unsigned h)
+{
+   Evas_Filter_Buffer *fb;
+   Image_Entry *dstdata = NULL;
+   Image_Entry *srcdata;
+   void *drawctx;
+
+   srcdata = evas_filter_buffer_backing_get(ctx, src->id);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(srcdata, NULL);
+
+   if (src->alpha_only)
+     {
+        // There is no supporting function in Evas for alpha scaling...
+        // but guess what? There is also no use case in the filters :)
+        CRI("Alpha buffer scaling is not supported");
+        return NULL;
+     }
+
+   fb = evas_filter_temporary_buffer_get(ctx, w, h, src->alpha_only);
+   if (!fb) return NULL;
+
+   dstdata = evas_filter_buffer_backing_get(ctx, fb->id);
+   if (!dstdata)
+     {
+        CRI("No backing found for buffer %d", fb->id);
+        return NULL;
+     }
+
+   if ((dstdata->w != w) || (dstdata->h != h))
+     {
+        CRI("Buffer size mismatch: got %dx%d requested %dx%d",
+            dstdata->w, dstdata->h, w, h);
+        return NULL;
+     }
+
+   if (ctx->gl_engine)
+     {
+        RGBA_Image *s = (RGBA_Image *) srcdata;
+        RGBA_Image *d = (RGBA_Image *) dstdata;
+        EINA_SAFETY_ON_NULL_RETURN_VAL(s->image.data, NULL);
+        EINA_SAFETY_ON_NULL_RETURN_VAL(d->image.data, NULL);
+
+        if (src->w == (int) w && src->h == (int) h)
+          memcpy(d->image.data, s->image.data, w * h * 4);
+        else
+          {
+             Eina_Bool ok;
+             RGBA_Draw_Context dc;
+
+             memset(&dc, 0, sizeof(dc));
+             dc.sli.h = 1;
+             dc.render_op = EVAS_RENDER_COPY;
+
+#if !defined(EVAS_TIZEN_FIXUPS)
+             ok = evas_common_scale_rgba_in_to_out_clip_sample
+                   (s, d, &dc, 0, 0, src->w, src->h, 0, 0, w, h);
+             if (!ok)
+               {
+                  ERR("RGBA Image scaling failed.");
+                  return NULL;
+               }
+#else
+             evas_common_scale_rgba_in_to_out_clip_sample
+                   (s, d, &dc, 0, 0, src->w, src->h, 0, 0, w, h);
+#endif
+          }
+     }
+   else
+     {
+        drawctx = ENFN->context_new(ENDT);
+        ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255);
+        ENFN->context_render_op_set(ENDT, drawctx, EVAS_RENDER_COPY);
+#ifdef HAS_DO_ASYNC
+        ENFN->image_draw(ENDT, drawctx, dstdata, srcdata,
+                         0, 0, src->w, src->h, // src
+                         0, 0, w, h, // dst
+                         EINA_TRUE, // smooth
+                         EINA_FALSE); // Not async
+#else
+        ENFN->image_draw(ENDT, drawctx, dstdata, srcdata,
+                         0, 0, src->w, src->h, // src
+                         0, 0, w, h, // dst
+                         EINA_TRUE); // smooth
+#endif
+        ENFN->context_free(ENDT, drawctx);
+     }
+
+   return fb;
+}
+
+static Eina_Bool
+_interpolate_none(DATA8 *output, DATA8 *points, int point_count)
+{
+   int j, k, val, x1, x2;
+   for (j = 0; j < point_count; j++)
+     {
+        x1 = points[j * 2];
+        val = points[j * 2 + 1];
+        if (j < (point_count - 1))
+          x2 = points[(j + 1) * 2];
+        else
+          x2 = 256;
+        if (x2 < x1) return EINA_FALSE;
+        for (k = x1; k < x2; k++)
+          output[k] = val;
+     }
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_interpolate_linear(DATA8 *output, DATA8 *points, int point_count)
+{
+   int j, k, val1, val2, x1, x2;
+   for (j = 0; j < point_count; j++)
+     {
+        x1 = points[j * 2];
+        val1 = points[j * 2 + 1];
+        if (j < (point_count - 1))
+          {
+             x2 = points[(j + 1) * 2];
+             val2 = points[(j + 1) * 2 + 1];
+          }
+        else
+          {
+             x2 = 256;
+             val2 = val1;
+          }
+        if (x2 < x1) return EINA_FALSE;
+        for (k = x1; k < x2; k++)
+          output[k] = val1 + ((val2 - val1) * (k - x1)) / (x2 - x1);
+     }
+   return EINA_TRUE;
+}
+
+Eina_Bool
+evas_filter_interpolate(DATA8 *output, DATA8 *points, int point_count,
+                        Evas_Filter_Interpolation_Mode mode)
+{
+   switch (mode)
+     {
+      case EVAS_FILTER_INTERPOLATION_MODE_NONE:
+        return _interpolate_none(output, points, point_count);
+      case EVAS_FILTER_INTERPOLATION_MODE_LINEAR:
+      default:
+        return _interpolate_linear(output, points, point_count);
+     }
+}
+
+int
+evas_filter_smallest_pow2_larger_than(int val)
+{
+   int n;
+
+   for (n = 0; n < 32; n++)
+     if (val <= (1 << n)) return n;
+
+   ERR("Value %d is too damn high!", val);
+   return 32;
+}
index 5c986c2..638172d 100644 (file)
@@ -10,4 +10,5 @@ evas_mmx.h \
 evas_common.h \
 evas_common_soft8.h \
 evas_common_soft16.h \
-evas_blend_ops.h
+evas_blend_ops.h \
+evas_filters.h
index 6bd1f16..cd2928b 100644 (file)
@@ -106,12 +106,12 @@ extern const DATA32 ALPHA_256;
 #define MUL4_SYM(x, y) \
  ( ((((((x) >> 16) & 0xff00) * (((y) >> 16) & 0xff00)) + 0xff0000) & 0xff000000) + \
    ((((((x) >> 8) & 0xff00) * (((y) >> 16) & 0xff)) + 0xff00) & 0xff0000) + \
-   ((((((x) & 0xff00) * ((y) & 0xff00)) + 0xff00) >> 16) & 0xff00) + \
+   ((((((x) & 0xff00) * ((y) & 0xff00)) + 0xff0000) >> 16) & 0xff00) + \
    (((((x) & 0xff) * ((y) & 0xff)) + 0xff) >> 8) )
 
 #define MUL3_SYM(x, y) \
  ( ((((((x) >> 8) & 0xff00) * (((y) >> 16) & 0xff)) + 0xff00) & 0xff0000) + \
-   ((((((x) & 0xff00) * ((y) & 0xff00)) + 0xff00) >> 16) & 0xff00) + \
+   ((((((x) & 0xff00) * ((y) & 0xff00)) + 0xff0000) >> 16) & 0xff00) + \
    (((((x) & 0xff) * ((y) & 0xff)) + 0xff) >> 8) )
 
 #define MUL_SYM(a, x) \
@@ -186,6 +186,64 @@ extern const DATA32 ALPHA_256;
 
 #endif
 
+/* some useful NEON macros */
+
+#ifdef BUILD_NEON
+#define FPU_NEON \
+       __asm__ __volatile__(".fpu neon \n\t");
+
+/* copy reg1 to reg2 */
+#define VMOV_R2R_NEON(reg1, reg2) \
+       __asm__ __volatile__("vmov " #reg1 ", " #reg2 " \n\t" ::: #reg1);
+
+/* copy 32bit value to lower bits of register reg */
+#define VMOV_M2R_NEON(reg, value) \
+       __asm__ __volatile__("vmov.32 " #reg "[0], %[val] \n\t" :: [val] "r" (value) : #reg);
+
+/* save 32bit value from lower 64 bits of register regq to memory location */
+/* pointed to by pointer, using 64bit register regd as temporary location */
+#define VMOV_R2M_NEON(regq, regd, pointer) \
+       __asm__ __volatile__("vqmovn.u16 " #regd ", " #regq " \n\t" \
+                            "vst1.32 {" #regd "[0]}, [%[p]] \n\t" :: [p] "r" (pointer) : #regd, "memory");
+
+/* spread constant imm in register reg */
+#define VMOV_I2R_NEON(reg, imm) \
+       __asm__ __volatile__("vmov.i16 " #reg ", " #imm " \n\t" ::: #reg);
+
+/* spread value in register reg */
+#define VDUP_NEON(reg, value) \
+       __asm__ __volatile__("vdup.16 " #reg ", %[val] \n\t" :: [val] "r" (value) : #reg);
+
+/* interleave contents of reg1 and reg2 */
+#define VZIP_NEON(reg1, reg2) \
+       __asm__ __volatile__("vzip.8 " #reg1 ", " #reg2 " \n\t" ::: #reg1 , #reg2);
+
+/* swap contents of two registers */
+#define VSWP_NEON(reg1, reg2) \
+       __asm__ __volatile__("vswp " #reg1 ", " #reg2 " \n\t" ::: #reg1 , #reg2);
+
+/* set register to zero */
+#define VEOR_NEON(reg) \
+       __asm__ __volatile__("veor " #reg ", " #reg ", " #reg " \n\t" ::: #reg);
+
+/* do interpolation of every channel RGBA, result is contained in regy */
+#define INTERP_256_NEON(rega, regx, regy, reg255) \
+       __asm__ __volatile__("vsub.i16 " #regx ", " #regx ", " #regy " \n\t" \
+                            "vmul.u16 " #regx ", " #regx ", " #rega " \n\t" \
+                            "vsri.16 " #regx ", " #regx ", #8 \n\t" \
+                            "vadd.i16 " #regx ", " #regx ", " #regy " \n\t" \
+                            "vand " #regy ", " #regx ", " #reg255 " \n\t" \
+                            ::: #regx, #regy );
+
+/* multiply every channel of regx and regy */
+#define MUL4_SYM_NEON(regx, regy, reg255) \
+       __asm__ __volatile__("vmul.u16 " #regx ", " #regx ", " #regy " \n\t" \
+                            "vadd.i16 " #regx ", " #regx ", " #reg255 " \n\t" \
+                            "vsri.16 " #regx ", " #regx ", #8 \n\t" \
+                            "vand " #regx ", " #regx ", " #reg255 " \n\t" \
+                            ::: #regx );
+
+#endif
 
 /* some useful SSE3 inline functions */
 
index 838870f..77f74ef 100644 (file)
@@ -435,6 +435,8 @@ typedef void (*RGBA_Gfx_Pt_Func) (DATA32 src, DATA8 mask, DATA32 col, DATA32 *ds
 typedef void (*Gfx_Func_Copy)    (DATA32 *src, DATA32 *dst, int len);
 
 typedef void (*Gfx_Func_Convert) (DATA32 *src, DATA8 *dst, int src_jump, int dst_jump, int w, int h, int dith_x, int dith_y, DATA8 *pal);
+typedef void (*Alpha_Gfx_Func)   (DATA8 *src, DATA8 *dst, int len);
+
 
 #include "../cache/evas_cache.h"
 #ifdef EVAS_CSERVE2
@@ -449,7 +451,7 @@ typedef enum _RGBA_Image_Flags
 /*    RGBA_IMAGE_HAS_ALPHA     = (1 << 0), */
    RGBA_IMAGE_IS_DIRTY      = (1 << 1),
    RGBA_IMAGE_INDEXED       = (1 << 2),
-   RGBA_IMAGE_ALPHA_ONLY    = (1 << 3),
+/*   RGBA_IMAGE_ALPHA_ONLY    = (1 << 3), */
    RGBA_IMAGE_ALPHA_TILES   = (1 << 4),
 /*    RGBA_IMAGE_ALPHA_SPARSE  = (1 << 5), */
 /*    RGBA_IMAGE_LOADED        = (1 << 6), */
@@ -542,6 +544,7 @@ struct _Image_Entry_Flags
 #endif
    Eina_Bool animated     : 1;
    Eina_Bool rotated      : 1;
+   Eina_Bool flipped      : 1;
 };
 
 struct _Image_Entry_Frame
@@ -597,7 +600,9 @@ struct _Image_Entry
    unsigned char          scale;
 
    RGBA_Image_Loadopts    load_opts;
-   int                    space;
+   Evas_Colorspace        space;
+   const Evas_Colorspace *cspaces; // owned by the loader, live as long as the loader
+
    unsigned int           w;
    unsigned int           h;
 
@@ -696,12 +701,10 @@ struct _RGBA_Draw_Context
    } col;
    struct RGBA_Draw_Context_clip {
       int    x, y, w, h;
+      void  *mask;
+      int    mask_x, mask_y;
       Eina_Bool use : 1;
    } clip;
-   struct {
-      int x, y, w, h;
-      RGBA_Image *mask;
-   } mask;
    Cutout_Rects cutout;
    struct {
       struct {
@@ -811,7 +814,10 @@ struct _RGBA_Image
 
    /* RGBA stuff */
    struct {
-      DATA32            *data;
+      union {
+         DATA32         *data;
+         DATA8          *data8;
+      };
       Eina_Bool          no_free : 1;
    } image;
 
@@ -839,6 +845,13 @@ struct _RGBA_Image
       pixman_image_t *im;
    } pixman;
 #endif
+   struct {
+      void   *data; //Evas_Native_Surface ns;
+      struct {
+        void (*free) (void *data, void *image);
+        void *data;
+      } func;
+   } native;
 };
 
 struct _RGBA_Polygon_Point
@@ -994,14 +1007,16 @@ struct _RGBA_Font_Source
  */
 struct _RGBA_Font_Glyph_Out
 {
+   unsigned char *rle;
    struct {
-      int rows;
-      int width;
-      int pitch;
       unsigned char *buffer;
-      short num_grays;
-      char pixel_mode;
+      unsigned short rows;
+      unsigned short width;
+      unsigned short pitch;
+      unsigned short rle_alloc : 1;
+      unsigned short no_free_glout : 1;
    } bitmap;
+   int rle_size;
 };
 
 struct _RGBA_Font_Glyph
@@ -1077,16 +1092,10 @@ struct rect_node
 
 struct _Tilebuf
 {
-   int outbuf_w;
-   int outbuf_h;
-
+   int outbuf_w, outbuf_h;
    struct {
-      int           w, h;
+      short w, h;
    } tile_size;
-
-   struct {
-      int x, y, w, h;
-   } prev_add, prev_del;
 #ifdef RECTUPDATE
 /*
    Regionbuf *rb;
@@ -1102,6 +1111,10 @@ struct _Tilebuf
    } tiles;
  */
 #endif
+   struct {
+      int x, y, w, h;
+   } prev_add, prev_del;
+   Eina_Bool strict_tiles : 1;
 };
 
 struct _Tilebuf_Tile
@@ -1218,7 +1231,7 @@ void evas_common_shutdown                               (void);
 EAPI void evas_common_cpu_init                          (void);
 
 int  evas_common_cpu_have_cpuid                         (void);
-int  evas_common_cpu_has_feature                        (unsigned int feature);
+EAPI int  evas_common_cpu_has_feature                   (unsigned int feature);
 EAPI void evas_common_cpu_can_do                        (int *mmx, int *sse, int *sse2);
 EAPI void evas_common_cpu_end_opt                       (void);
 
@@ -1259,6 +1272,7 @@ EAPI Tilebuf      *evas_common_tilebuf_new               (int w, int h);
 EAPI void          evas_common_tilebuf_free              (Tilebuf *tb);
 EAPI void          evas_common_tilebuf_set_tile_size     (Tilebuf *tb, int tw, int th);
 EAPI void          evas_common_tilebuf_get_tile_size     (Tilebuf *tb, int *tw, int *th);
+EAPI void          evas_common_tilebuf_tile_strict_set   (Tilebuf *tb, Eina_Bool strict);
 EAPI int           evas_common_tilebuf_add_redraw        (Tilebuf *tb, int x, int y, int w, int h);
 EAPI int           evas_common_tilebuf_del_redraw        (Tilebuf *tb, int x, int y, int w, int h);
 EAPI int           evas_common_tilebuf_add_motion_vector (Tilebuf *tb, int x, int y, int w, int h, int dx, int dy, int alpha);
diff --git a/src/lib/include/evas_filter.h b/src/lib/include/evas_filter.h
new file mode 100644 (file)
index 0000000..829af76
--- /dev/null
@@ -0,0 +1,257 @@
+#ifndef _EVAS_FILTER_H
+#define _EVAS_FILTER_H
+
+#if (VMAJ > 1) || (VMIN >= 8)
+#include "evas_common_private.h"
+#else
+#include "evas_common.h"
+#endif
+#include "evas_private.h"
+
+typedef struct _Evas_Filter_Context Evas_Filter_Context;
+typedef struct _Evas_Filter_Command Evas_Filter_Command;
+typedef struct _Evas_Filter_Program Evas_Filter_Program;
+typedef struct _Evas_Filter_Instruction Evas_Filter_Instruction;
+typedef struct _Evas_Filter_Buffer Evas_Filter_Buffer;
+typedef struct _Evas_Filter_Proxy_Binding Evas_Filter_Proxy_Binding;
+typedef enum _Evas_Filter_Mode Evas_Filter_Mode;
+typedef enum _Evas_Filter_Blur_Type Evas_Filter_Blur_Type;
+typedef enum _Evas_Filter_Channel Evas_Filter_Channel;
+typedef enum _Evas_Filter_Displacement_Flags Evas_Filter_Displacement_Flags;
+typedef enum _Evas_Filter_Bump_Flags Evas_Filter_Bump_Flags;
+typedef enum _Evas_Filter_Fill_Mode Evas_Filter_Fill_Mode;
+typedef enum _Evas_Filter_Transform_Flags Evas_Filter_Transform_Flags;
+
+typedef Eina_Bool (* Evas_Filter_Apply_Func) (Evas_Filter_Command *cmd);
+typedef void (* Evas_Filter_Cb) (Evas_Filter_Context *ctx, void *data, Eina_Bool success);
+
+#define EVAS_FILTER_BUFFER_RGBA  EINA_FALSE
+#define EVAS_FILTER_BUFFER_ALPHA EINA_TRUE
+
+#define EVAS_FILTER_BUFFER_INPUT_ID  1
+#define EVAS_FILTER_BUFFER_OUTPUT_ID 2
+
+enum _Evas_Filter_Mode
+{
+   EVAS_FILTER_MODE_BLEND,        /**< Blend with current context render_op */
+   EVAS_FILTER_MODE_BLUR,         /**< @see Evas_Filter_Blur_Type */
+   EVAS_FILTER_MODE_CURVE,        /**< Apply color curve */
+   EVAS_FILTER_MODE_DISPLACE,     /**< Apply XY displacement based on RG mask */
+   EVAS_FILTER_MODE_FILL,         /**< Fill a buffer with a solid color */
+   EVAS_FILTER_MODE_MASK,         /**< Apply Alpha or RGBA texture on image */
+   EVAS_FILTER_MODE_BUMP,         /**< Apply bump mapping (light effect) */
+   EVAS_FILTER_MODE_TRANSFORM,    /**< Apply a simple geometrical transformation */
+   EVAS_FILTER_MODE_PADDING_SET,  /**< Special padding_set instruction to force a specific padding value */
+   EVAS_FILTER_MODE_LAST
+};
+
+enum _Evas_Filter_Blur_Type
+{
+   EVAS_FILTER_BLUR_DEFAULT  = 0x0, // Default blur (GAUSSIAN or series of BOX)
+   EVAS_FILTER_BLUR_BOX      = 0x1, // Optimizable on CPU. But, UGLY. O(n)
+   EVAS_FILTER_BLUR_GAUSSIAN = 0x2, // Gaussian blur (using sine curve)
+   EVAS_FILTER_BLUR_LAST,
+};
+
+enum _Evas_Filter_Channel
+{
+   EVAS_FILTER_CHANNEL_ALPHA = 0,
+   EVAS_FILTER_CHANNEL_RED   = 1,
+   EVAS_FILTER_CHANNEL_GREEN = 2,
+   EVAS_FILTER_CHANNEL_BLUE  = 3,
+   EVAS_FILTER_CHANNEL_RGB   = 4
+};
+
+enum _Evas_Filter_Displacement_Flags
+{
+   EVAS_FILTER_DISPLACE_NEAREST  = 0x0,   /**< Interpolate between pixels (linear interpolation) */
+   EVAS_FILTER_DISPLACE_LINEAR   = 0x1,   /**< Interpolate between pixels (linear interpolation) */
+   EVAS_FILTER_DISPLACE_BLACK    = 0x0,   /**< Use black (or transparent) when going out of bounds) */
+   EVAS_FILTER_DISPLACE_STRETCH  = 0x2,   /**< Stretch border pixels when going out of bounds */
+   EVAS_FILTER_DISPLACE_BITMASK  = 0x3
+};
+
+enum _Evas_Filter_Bump_Flags
+{
+   EVAS_FILTER_BUMP_NORMAL       = 0x0,
+   EVAS_FILTER_BUMP_COMPENSATE   = 0x1    /**< Compensate for darkening (diffuse light) or brightening (specular light) of zero gradient surfaces */
+};
+
+enum _Evas_Filter_Fill_Mode
+{
+   EVAS_FILTER_FILL_MODE_NONE               = 0x0,
+   EVAS_FILTER_FILL_MODE_STRETCH_X          = 0x1,
+   EVAS_FILTER_FILL_MODE_STRETCH_Y          = 0x2,
+   EVAS_FILTER_FILL_MODE_REPEAT_X           = 0x4,
+   EVAS_FILTER_FILL_MODE_REPEAT_Y           = 0x8,
+   EVAS_FILTER_FILL_MODE_REPEAT_X_STRETCH_Y = EVAS_FILTER_FILL_MODE_REPEAT_X | EVAS_FILTER_FILL_MODE_STRETCH_Y,
+   EVAS_FILTER_FILL_MODE_REPEAT_Y_STRETCH_X = EVAS_FILTER_FILL_MODE_REPEAT_Y | EVAS_FILTER_FILL_MODE_STRETCH_X,
+   EVAS_FILTER_FILL_MODE_REPEAT_XY          = EVAS_FILTER_FILL_MODE_REPEAT_X | EVAS_FILTER_FILL_MODE_REPEAT_Y,
+   EVAS_FILTER_FILL_MODE_STRETCH_XY         = EVAS_FILTER_FILL_MODE_STRETCH_X | EVAS_FILTER_FILL_MODE_STRETCH_Y
+};
+
+enum _Evas_Filter_Transform_Flags
+{
+   EVAS_FILTER_TRANSFORM_VFLIP = 1
+};
+
+/* Parser stuff (high level API) */
+EAPI Evas_Filter_Program *evas_filter_program_new(const char *name);
+EAPI Eina_Bool           evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str);
+EAPI void                evas_filter_program_del(Evas_Filter_Program *pgm);
+Eina_Bool                evas_filter_context_program_use(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm);
+EAPI Eina_Bool           evas_filter_program_padding_get(Evas_Filter_Program *pgm, int *l, int *r, int *t, int *b);
+EAPI void                evas_filter_program_source_set_all(Evas_Filter_Program *pgm, Eina_Hash *sources);
+void                     evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Evas_Object *eo_obj, Eina_Bool do_async);
+
+/* Filter context (low level) */
+Evas_Filter_Context     *evas_filter_context_new(Evas *evas, Eina_Bool async);
+void                     evas_filter_context_destroy(Evas_Filter_Context *ctx);
+void                     evas_filter_context_post_run_callback_set(Evas_Filter_Context *ctx, Evas_Filter_Cb cb, void *data);
+#define                  evas_filter_context_autodestroy(ctx) evas_filter_context_post_run_callback_set(ctx, ((Evas_Filter_Cb) evas_filter_context_destroy), ctx)
+Eina_Bool                evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx, unsigned w, unsigned h);
+
+int                      evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only);
+int                      evas_filter_buffer_image_new(Evas_Filter_Context *ctx, void *image);
+void                    *evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid);
+void                    *evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid);
+Eina_Bool                evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, void *stolen_buffer);
+
+Eina_Bool                evas_filter_run(Evas_Filter_Context *ctx);
+
+Eina_Bool                evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid, Evas_Font_Set *font, int x, int y, Evas_Text_Props *text_props, Eina_Bool do_async);
+Eina_Bool                evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context, void *surface, int x, int y);
+
+/**
+ * @brief Blend a source buffer into a destination buffer, allowing X,Y offsets, Alpha to RGBA conversion with color
+ * @param ctx            Current filter chain
+ * @param draw_context   Current Evas draw context. Current color is used when inbuf is ALPHA and outbuf is RGBA.
+ * @param inbuf          Source buffer: ALPHA or RGBA
+ * @param outbuf         Destination buffer: ALPHA or RGBA (note: must be RGBA if inbuf is RGBA)
+ * @param ox             X offset in the destination buffer
+ * @param oy             Y offset in the destination buffer
+ * @param fillmode       Specifies whether to repeat or stretch the input onto its destination, and on which axes
+ * @return               Filter command ID or -1 in case of error
+ */
+int                      evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int ox, int oy, Evas_Filter_Fill_Mode fillmode);
+
+/**
+ * @brief Apply a blur effect on a buffer
+ * @param ctx            Current filter chain
+ * @param draw_context   Current Evas draw context. Current color is used when inbuf is ALPHA and outbuf is RGBA.
+ * @param inbuf          Source buffer: ALPHA or RGBA
+ * @param outbuf         Destination buffer: ALPHA or RGBA (note: must be RGBA if inbuf is RGBA)
+ * @param type           Type of blur: BOX, GAUSSIAN or MOTION
+ * @param dx             X radius of blur. Can be negative ONLY for MOTION blur
+ * @param dy             Y radius of blur. Can be negative ONLY for MOTION blur
+ * @param ox             X offset in the destination buffer
+ * @param oy             Y offset in the destination buffer
+ * @param count          Number of times to repeat the operation (used for smooth fast blurs with box blur)
+ * @return               Filter command ID or -1 in case of error
+ */
+int                      evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Blur_Type type, int dx, int dy, int ox, int oy, int count);
+
+/**
+ * @brief Fill a buffer with the current color
+ * @param ctx            Current filter chain
+ * @param draw_context   Current Evas draw context. Current color is used when buf is RGBA, and clip is used to specify the fill area.
+ * @param buf            Buffer: ALPHA or RGBA
+ * @return               Filter command ID or -1 in case of error
+ * @note The current draw context's render operation is ignored (always uses COPY mode).
+ */
+int                      evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context, int buf);
+
+/**
+ * @brief evas_filter_command_curve_add
+ * @param ctx            Current filter chain
+ * @param draw_context   Current Evas draw context. Current color is used when buf is RGBA, and clip is used to specify the fill area.
+ * @param inbuf          Input buffer, ALPHA or RGBA.
+ * @param outbuf         Output buffer, must have same colorspace as inbuf.
+ * @param curve          The data points to use, must contain 256 values.
+ * @param channel        Which channel to apply the curve (red, green, blue, alpha or RGB)
+ * @return               Filter command ID or -1 in case of error
+ */
+int                      evas_filter_command_curve_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, DATA8 *curve /* 256 elements */, Evas_Filter_Channel channel);
+
+/**
+ * @brief Grow/Shrink an image, as defined in image processing (this is not a scale algorithm!)
+ * @param ctx            Current filter chain
+ * @param draw_context   Current Evas draw context. Current color is used when inbuf is ALPHA and outbuf is RGBA.
+ * @param inbuf          Source buffer: ALPHA or RGBA
+ * @param outbuf         Destination buffer: ALPHA or RGBA (note: must be RGBA if inbuf is RGBA)
+ * @param radius         Number of pixels to grow by. If negative, shrink instead of grow
+ * @param smooth         Use smooth blur and curve for grow (default: true)
+ * @return               Filter command ID or -1 in case of error
+ */
+int                      evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int radius, Eina_Bool smooth);
+
+/**
+ * @brief Apply a displacement map to a buffer. This will move pixels from the source to the destination based on pixel per pixel offset, as defined in the displacement map
+ * @param ctx            Current filter chain
+ * @param draw_context   Current Evas draw context (ignored)
+ * @param inbuf          Input buffer (Alpha or RGBA)
+ * @param outbuf         Output buffer (Alpha or RGBA), same size as inbuf
+ * @param dispbuf        Displacement map. Should be an RGBA buffer, where the Red and Green channels are the displacement maps for X and Y. Can be also ALPHA buffer, in which case only one dimension can be specified (X or Y).
+ * @param flags          Alters how the map is interpreted, @see Evas_Filter_Displacement_Flags
+ * @param intensity      Maximum offset possible, if the map's value is maximal at this point (ie. 0 or 255)
+ * @param fillmode       Specifies how to repeat and stretch the map to fit the target size
+ * @return               Filter command ID or -1 in case of error
+ */
+int                      evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int dispbuf, Evas_Filter_Displacement_Flags flags, int intensity, Evas_Filter_Fill_Mode fillmode);
+
+/**
+ * @brief Apply a texture to a buffer
+ * @param ctx            Current filter chain
+ * @param draw_context   Current Evas draw context (ignored)
+ * @param inbuf          Input buffer (Alpha or RGBA)
+ * @param maskbuf        Texture buffer (Alpha or RGBA)
+ * @param outbuf         Output buffer (Alpha or RGBA)
+ * @param fillmode       Specifies how to repeat and stretch the mask to fit the target size
+ * @return               Filter command ID or -1 in case of error
+ * @note For the moment, inbuf can only be ALPHA, and output must be RGBA if mask is RGBA as well
+ */
+int                      evas_filter_command_mask_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int maskbuf, int outbuf, Evas_Filter_Fill_Mode fillmode);
+
+/**
+ * @brief Apply a relief effect based on a bump map (Z map)
+ * @param ctx              Current filter chain
+ * @param draw_context     Current Evas draw context (ignored)
+ * @param inbuf            Input buffer (Alpha or RGBA)
+ * @param bumpbuf          Bump map (Alpha only), same size as inbuf. By definition, lows are black (alpha 0) and highs are white (alpha 255).
+ * @param outbuf           Output buffer (Alpha or RGBA), same size as inbuf
+ * @param azimuth          CCW angle in degrees from the X axis of the light direction. 0 is light from the right, 90 from the top, 180 from the left, 270 from the bottom. All values are valid.
+ * @param elevation        Angle in degrees between the XY plane and the light. Only values from 0 (light is perfectly horizontal) to 90 (light comes from the viewer herself) are acceptable.
+ * @param depth            Max depth in the bump map. Default value is 10.
+ * @param specular_factor  Factor for the specular light effect (shininess). Ranges from 1.0 to 1000+ with logarithmic effects
+ * @param black            Darkest color, defines the ambiant light
+ * @param color            Light's normal color
+ * @param white            Brightest color, used in the shininess effect
+ * @param flags            Optional flags: compensation for darkening
+ * @param fillmode         Specifies how to repeat and stretch the map to fit the target size
+ * @return                 Filter command ID or -1 in case of error
+ */
+int                      evas_filter_command_bump_map_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int bumpbuf, int outbuf, float azimuth, float elevation, float depth, float specular_factor, DATA32 black, DATA32 color, DATA32 white, Evas_Filter_Bump_Flags flags, Evas_Filter_Fill_Mode fillmode);
+
+/**
+ * @brief Apply a geometrical transformation to the buffer
+ * @param ctx            Current filter chain
+ * @param draw_context   Current Evas draw context (ignored)
+ * @param inbuf          Input buffer (Alpha or RGBA)
+ * @param outbuf         Output buffer (Alpha or RGBA), same size as inbuf
+ * @param flags          Specifies the operation to apply (eg. vflip)
+ * @param ox             X offset
+ * @param oy             Y offset
+ * @return               Filter command ID or -1 in case of error
+ */
+int                      evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Transform_Flags flags, int ox, int oy);
+
+/* Simple binding between a filter object and its sources */
+struct _Evas_Filter_Proxy_Binding
+{
+   Evas_Object *eo_proxy;
+   Evas_Object *eo_source;
+   Eina_Stringshare *name;
+};
+
+#endif
+
index 44e24ce..9657355 100644 (file)
@@ -1,12 +1,14 @@
 #ifndef EVAS_INLINE_H
 #define EVAS_INLINE_H
 
+#include "evas_private.h"
+
 static inline Eina_Bool
 _evas_render_has_map(Evas_Object *obj)
 {
-   return ((!((obj->func->can_map) && (obj->func->can_map(obj)))) &&
-           ((obj->cur.map) && (obj->cur.usemap)));
-   //   return ((obj->cur.map) && (obj->cur.usemap));
+   return (((obj->cur.map) && (obj->cur.usemap)) &&
+           !((obj->func->can_map) && (obj->func->can_map(obj))));
+      //   return ((obj->cur.map) && (obj->cur.usemap));
 }
 
 static inline void
@@ -66,9 +68,12 @@ evas_object_is_opaque(Evas_Object *obj)
 {
    if (obj->smart.smart) return 0;
    /* If a mask: Assume alpha */
-   if (obj->cur.mask) return 0;
    if (obj->cur.cache.clip.a == 255)
      {
+        /* If has mask image: Always assume non opaque */
+        if ((obj->cur.clipper && obj->cur.clipper->mask.is_mask) ||
+            (obj->clip.mask))
+          return 0;
         if (obj->func->is_opaque)
           return obj->func->is_opaque(obj);
         return 1;
@@ -105,6 +110,19 @@ evas_event_passes_through(Evas_Object *obj)
 }
 
 static inline int
+evas_object_is_source_invisible(Evas_Object *obj)
+{
+   if (obj->parent_cache.src_invisible_valid)
+     return obj->parent_cache.src_invisible;
+   if (obj->proxy.proxies && obj->proxy.src_invisible) return 1;
+   if (!obj->smart.parent) return 0;
+   obj->parent_cache.src_invisible =
+      evas_object_is_source_invisible(obj->smart.parent);
+   obj->parent_cache.src_invisible_valid = EINA_TRUE;
+   return obj->parent_cache.src_invisible;
+}
+
+static inline int
 evas_object_is_visible(Evas_Object *obj)
 {                        /* post 1.0 -> enable? */
    if ((obj->cur.visible)/* && (obj->cur.color.a > 0)*/ &&
@@ -120,6 +138,22 @@ evas_object_is_visible(Evas_Object *obj)
 }
 
 static inline int
+evas_object_is_proxy_visible(Evas_Object *obj)
+{
+   if ((obj->cur.visible) &&
+       //FIXME: Check the cached clipper visible properly.
+       (obj->smart.smart || !obj->cur.clipper || obj->cur.clipper->cur.visible) &&
+       ((obj->cur.cache.clip.a > 0 && obj->cur.render_op == EVAS_RENDER_BLEND)
+       || (obj->cur.render_op != EVAS_RENDER_BLEND)))
+     {
+        if (obj->func->is_visible)
+          return obj->func->is_visible(obj);
+        return 1;
+     }
+   return 0;
+}
+
+static inline int
 evas_object_clippers_is_visible(Evas_Object *obj)
 {
    if (obj->cur.visible)
@@ -200,6 +234,7 @@ evas_object_clip_recalc(Evas_Object *obj)
 {
    int cx, cy, cw, ch, cr, cg, cb, ca;
    int nx, ny, nw, nh, nr, ng, nb, na;
+   Evas_Object *mask = NULL, *prev_mask = NULL;
    Eina_Bool cvis, nvis;
 
    if ((!obj->cur.cache.clip.dirty) &&
@@ -249,6 +284,28 @@ evas_object_clip_recalc(Evas_Object *obj)
              RECTS_CLIP_TO_RECT(cx, cy, cw, ch, nx, ny, nw, nh);
           }
 
+        if (obj->cur.clipper->mask.is_mask)
+          {
+             // Set complex masks the object being clipped (parent)
+             mask = obj->cur.clipper;
+
+             // Forward any mask from the parents
+             if (obj->smart.parent != NULL)
+               {
+                  Evas_Object *parent = obj->smart.parent;
+                  if (parent->clip.mask)
+                    {
+                       if (parent->clip.mask != mask)
+                         prev_mask = parent->clip.mask;
+                    }
+               }
+          }
+        else if (obj->cur.clipper->clip.mask)
+          {
+             // Pass complex masks to children
+             mask = obj->cur.clipper->clip.mask;
+          }
+
         nvis = obj->cur.clipper->cur.cache.clip.visible;
         nr = obj->cur.clipper->cur.cache.clip.r;
         ng = obj->cur.clipper->cur.cache.clip.g;
@@ -272,6 +329,8 @@ evas_object_clip_recalc(Evas_Object *obj)
    obj->cur.cache.clip.b = cb;
    obj->cur.cache.clip.a = ca;
    obj->cur.cache.clip.dirty = EINA_FALSE;
+   obj->clip.mask = mask;
+   obj->clip.prev_mask = prev_mask;
 }
 
 #endif
old mode 100644 (file)
new mode 100755 (executable)
index fc3033f..71d3b7b
@@ -22,6 +22,8 @@
 
 #define RENDER_METHOD_INVALID            0x00000000
 
+/* #define REND_DBG 1 */
+
 typedef struct _Evas_Layer                  Evas_Layer;
 typedef struct _Evas_Size                   Evas_Size;
 typedef struct _Evas_Aspect                 Evas_Aspect;
@@ -48,6 +50,8 @@ typedef struct _Evas_Smart_Cb_Description_Array Evas_Smart_Cb_Description_Array;
 typedef struct _Evas_Smart_Interfaces_Array Evas_Smart_Interfaces_Array;
 typedef struct _Evas_Post_Callback          Evas_Post_Callback;
 typedef struct _Evas_Coord_Touch_Point      Evas_Coord_Touch_Point;
+typedef struct _Evas_Proxy_Render_Data      Evas_Proxy_Render_Data;
+typedef struct _Evas_GL_Ext                 Evas_GL_Ext;
 
 enum _Evas_Font_Style
 {
@@ -105,21 +109,22 @@ OPAQUE_TYPE(Evas_Font_Instance); /* General type for RGBA_Font_Int */
 /* End of general types */
 
 #define MAGIC_EVAS                 0x70777770
-#define MAGIC_OBJ                  0x71777770
-#define MAGIC_OBJ_RECTANGLE        0x71777771
-#define MAGIC_OBJ_LINE             0x71777772
-#define MAGIC_OBJ_POLYGON          0x71777774
-#define MAGIC_OBJ_IMAGE            0x71777775
-#define MAGIC_OBJ_TEXT             0x71777776
-#define MAGIC_OBJ_SMART            0x71777777
-#define MAGIC_OBJ_TEXTBLOCK        0x71777778
-#define MAGIC_OBJ_TEXTGRID         0x7177777A
-#define MAGIC_SMART                0x72777770
-#define MAGIC_OBJ_SHAPE            0x72777773
-#define MAGIC_OBJ_CONTAINER        0x72777774
-#define MAGIC_OBJ_CUSTOM           0x72777775
-#define MAGIC_EVAS_GL              0x72777776
-#define MAGIC_MAP                  0x72777777
+#define MAGIC_OBJ                  0x71737723
+#define MAGIC_OBJ_RECTANGLE        0x76748772
+#define MAGIC_OBJ_LINE             0x7a27f839
+#define MAGIC_OBJ_POLYGON          0x7bb7577e
+#define MAGIC_OBJ_IMAGE            0x747ad76c
+#define MAGIC_OBJ_TEXT             0x77757721
+#define MAGIC_OBJ_SMART            0x78c7c73f
+#define MAGIC_OBJ_TEXTBLOCK        0x71737744
+#define MAGIC_OBJ_TEXTGRID         0x7377a7ca
+#define MAGIC_SMART                0x7c6977c5
+#define MAGIC_OBJ_SHAPE            0x747297f7
+#define MAGIC_OBJ_CONTAINER        0x71877776
+#define MAGIC_OBJ_CUSTOM           0x7b7857ab
+#define MAGIC_EVAS_GL              0x77976718
+#define MAGIC_MAP                  0x7575177d
+#define MAGIC_DEV                  0x7d773738
 
 #ifdef MAGIC_DEBUG
 # define MAGIC_CHECK_FAILED(o, t, m) \
@@ -129,7 +134,7 @@ OPAQUE_TYPE(Evas_Font_Instance); /* General type for RGBA_Font_Int */
  else evas_debug_magic_wrong((m), ((t *)o)->magic); \
 }
 # define MAGIC_CHECK(o, t, m) \
-{if ((!o) || (!(((t *)o)->magic == (m)))) { \
+{if (EINA_UNLIKELY((!o) || (!(((t *)o)->magic == (m))))) { \
 MAGIC_CHECK_FAILED(o, t, m)
 # define MAGIC_CHECK_END() }}
 #else
@@ -330,7 +335,7 @@ struct _Evas
       unsigned char  changed : 1;
    } output;
 
-   struct 
+   struct
      {
         Evas_Coord x, y, w, h;
         Eina_Bool changed : 1;
@@ -363,6 +368,9 @@ struct _Evas
       int   info_magic;
    } engine;
 
+   // TIZEN_ONLY(20140822): Added evas_bidi_direction_hint_set, get APIs and applied to textblock, text.
+   Evas_BiDi_Direction bidi_direction_hint;
+   //
    Eina_Array     delete_objects;
    Eina_Array     active_objects;
    Eina_Array     restack_objects;
@@ -406,6 +414,8 @@ struct _Evas
    unsigned char  focus : 1;
 
    Eina_List     *touch_points;
+   Eina_List     *devices;
+   Eina_Array    *cur_device;
 };
 
 struct _Evas_Layer
@@ -449,6 +459,7 @@ struct _Evas_Size_Hints
    Evas_Aspect aspect;
    Evas_Double_Pair align, weight;
    Evas_Border padding;
+   Evas_Display_Mode dispmode;
 };
 
 struct _Evas_Map_Point
@@ -463,14 +474,18 @@ struct _Evas_Map
    DATA32                magic;
    int                   count; // num of points
    Evas_Coord_Rectangle  normal_geometry; // bounding box of map geom actually
-   void                 *surface; // surface holding map if needed
-   int                   surface_w, surface_h; // current surface w & h alloc
+//   void                 *surface; // surface holding map if needed
+//   int                   surface_w, surface_h; // current surface w & h alloc
    Evas_Coord            mx, my; // mouse x, y after conversion to map space
    struct {
       Evas_Coord         px, py, z0, foc;
    } persp;
    Eina_Bool             alpha : 1;
    Eina_Bool             smooth : 1;
+   struct {
+      Eina_Bool          enabled : 1;
+      Evas_Coord         diff_x, diff_y;
+   } move_sync;
    Evas_Map_Point        points[]; // actual points
 };
 
@@ -515,7 +530,6 @@ struct _Evas_Object
    struct {
       Evas_Map             *map;
       Evas_Object          *clipper;
-      Evas_Object          *mask;
       Evas_Object          *map_parent;
       double                scale;
       Evas_Coord_Rectangle  geometry;
@@ -544,6 +558,11 @@ struct _Evas_Object
       Eina_Bool             parent_cached_surface : 1;
    } cur, prev;
 
+   struct {
+      void                 *surface; // surface holding map if needed
+      int                   surface_w, surface_h; // current surface w & h alloc
+   } map;
+
    Evas_Map                   *cache_map;
    char                       *name;
 
@@ -560,6 +579,7 @@ struct _Evas_Object
    struct {
       Eina_List               *clipees;
       Eina_List               *changes;
+      Evas_Object             *mask, *prev_mask;
    } clip;
 
    const Evas_Object_Func     *func;
@@ -576,8 +596,18 @@ struct _Evas_Object
       void                    *surface;
       int                      w,h;
       Eina_Bool                redraw;
+      Eina_Bool                src_invisible : 1;
    } proxy;
 
+   struct {
+      void                    *surface;
+      int                      w, h;
+      Eina_Bool                is_mask : 1;
+      Eina_Bool                redraw : 1;
+      Eina_Bool                is_alpha : 1;
+      Eina_Bool                is_scaled : 1;
+   } mask;
+
 #if 0 // filtering disabled
    Evas_Filter_Info           *filter;
 #endif
@@ -619,6 +649,8 @@ struct _Evas_Object
       Eina_Bool                pass_events_valid : 1;
       Eina_Bool                freeze_events : 1;
       Eina_Bool                freeze_events_valid : 1;
+      Eina_Bool                src_invisible : 1;
+      Eina_Bool                src_invisible_valid : 1;
    } parent_cache;
    Eina_Bool                   restack : 1;
    Eina_Bool                   is_active : 1;
@@ -639,10 +671,12 @@ struct _Evas_Object
    Eina_Bool                   changed_color : 1;
    Eina_Bool                   changed_map : 1;
    Eina_Bool                   changed_pchange : 1;
+   Eina_Bool                   changed_src_visible : 1;
    Eina_Bool                   del_ref : 1;
 
    Eina_Bool                   is_frame : 1;
    Eina_Bool                   child_has_map : 1;
+   Eina_Bool                   on_deletion : 1;
 };
 
 struct _Evas_Func_Node
@@ -704,6 +738,19 @@ struct _Evas_Font_Description
    Eina_Bool is_new : 1;
 };
 
+struct _Evas_Device
+{
+   DATA32 magic;
+   Evas *evas;
+   Evas_Device *parent;
+   Evas_Device *src;
+   Eina_List *children;
+   const char *name;
+   const char *desc;
+   int ref;
+   Evas_Device_Class clas;
+};
+
 struct _Evas_Object_Func
 {
    void (*free) (Evas_Object *obj);
@@ -759,6 +806,9 @@ struct _Evas_Func
    Eina_Bool (*canvas_alpha_get)           (void *data, void *context);
    void (*context_free)                    (void *data, void *context);
    void (*context_clip_set)                (void *data, void *context, int x, int y, int w, int h);
+   void (*context_clip_image_set)          (void *data, void *context, void *surface, int x, int y);
+   void (*context_clip_image_unset)        (void *data, void *context);
+   void (*context_clip_image_get)          (void *data, void *context, void **surface, int *x, int *y);
    void (*context_clip_clip)               (void *data, void *context, int x, int y, int w, int h);
    void (*context_clip_unset)              (void *data, void *context);
    int  (*context_clip_get)                (void *data, void *context, int *x, int *y, int *w, int *h);
@@ -852,6 +902,7 @@ struct _Evas_Func
    void *(*image_map_surface_new)          (void *data, int w, int h, int alpha);
    void (*image_map_surface_free)          (void *data, void *surface);
    void (*image_map_clean)                 (void *data, RGBA_Map *m);
+   void *(*image_scaled_update)            (void *data, void *scaled, void *image, int dst_w, int dst_h, Eina_Bool smooth, Eina_Bool alpha, Evas_Colorspace cspace);
 
    void (*image_content_hint_set)          (void *data, void *surface, int hint);
    int  (*image_content_hint_get)          (void *data, void *surface);
@@ -868,15 +919,26 @@ struct _Evas_Func
 
    /* EFL-GL Glue Layer */
    void *(*gl_surface_create)            (void *data, void *config, int w, int h);
+   void *(*gl_pbuffer_surface_create)    (void *data, void *config, int w, int h, int const *attrib_list);
    int  (*gl_surface_destroy)            (void *data, void *surface);
-   void *(*gl_context_create)            (void *data, void *share_context);
+   void *(*gl_context_create)            (void *data, void *share_context, int version);
    int  (*gl_context_destroy)            (void *data, void *context);
    int  (*gl_make_current)               (void *data, void *surface, void *context);
-   void *(*gl_string_query)              (void *data, int name);
-   void *(*gl_proc_address_get)          (void *data, const char *name);
+   const char *(*gl_string_query)        (void *data, int name);
+   void *(*gl_proc_address_get)          (void *data, Evas_GL_Ext *exts, const char *name);
    int  (*gl_native_surface_get)         (void *data, void *surface, void *native_surface);
-   void *(*gl_api_get)                   (void *data);
-   void (*gl_img_obj_set)                (void *data, void *image, int has_alpha);
+   void *(*gl_api_get)                   (void *data, int version);
+   void  (*gl_direct_override_get)       (void *data, int *override, int *force_off);
+   void (*gl_get_pixels_set)             (void *data, void *get_pixels, void *get_pixels_data, void *obj);
+   Eina_Bool (*gl_surface_lock)          (void *data, void *surface);
+   Eina_Bool (*gl_surface_read_pixels)   (void *data, void *surface, int x, int y, int w, int h, Evas_Colorspace cspace, void *pixels);
+   Eina_Bool (*gl_surface_unlock)        (void *data, void *surface);
+   int  (*gl_error_get)                  (void *data);
+   void *(*gl_current_context_get)       (void *data);
+   void *(*gl_current_surface_get)       (void *data);
+   int  (*gl_rotation_angle_get)         (void *data);
+   Eina_Bool (*gl_surface_query)         (void *data, void *surface, int attr, void *value);
+   Eina_Bool (*gl_surface_direct_renderable_get) (void *data, Evas_Native_Surface *ns, Eina_Bool *direct_override);
 
    int  (*image_load_error_get)          (void *data, void *image);
    int  (*font_run_end_get)              (void *data, Evas_Font_Set *font, Evas_Font_Instance **script_fi, Evas_Font_Instance **cur_fi, Evas_Script_Type script, const Eina_Unicode *text, int run_len);
@@ -891,6 +953,25 @@ struct _Evas_Func
 
    /* max size query */
    void (*image_max_size_get)            (void *data, int *maxw, int *maxh);
+
+   void (*context_flush)                 (void *data);
+
+   /* evas_gl Extensions */
+   int (*gl_ext_buffer_age_get)          (void *data);
+   int (*gl_ext_update_region_get)       (void *data, int *x, int *y, int *w, int *h);
+   void *(*gl_ext_surface_from_native_create) (void *data, void *config, int target, void *native);
+   int (*gl_ext_surface_is_texture)      (void *data, void *surface);
+
+   /* post on_pixel callback's rendering */
+   void (*get_pixels_render_post)        (void *data);
+
+   void (*gl_engine_init)                (void *data);
+   void (*gl_engine_shutdown)            (void *data);
+
+   void (*image_direct_set)              (void *data, void *image, int direct);
+   Eina_Bool (*image_direct_get)         (void *data, void *image);
+
+   Eina_Bool (*pixel_alpha_get)          (void *image, int x, int y, DATA8 *alpha, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h);
 };
 
 struct _Evas_Image_Load_Func
@@ -904,7 +985,13 @@ struct _Evas_Image_Load_Func
 
 struct _Evas_Image_Save_Func
 {
-  int (*image_save) (RGBA_Image *im, const char *file, const char *key, int quality, int compress);
+  int (*image_save) (RGBA_Image *im, const char *file, const char *key, int quality, int compress, const char *encoding);
+};
+
+struct _Evas_GL_Ext
+{
+   const char *name;
+   void       *func;
 };
 
 #ifdef __cplusplus
@@ -942,6 +1029,7 @@ int evas_object_was_opaque(Evas_Object *obj);
 int evas_object_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
 int evas_object_was_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
 int evas_object_clippers_was_visible(Evas_Object *obj);
+void evas_object_mapped_across_change(Evas_Object *obj);
 void evas_object_clip_across_check(Evas_Object *obj);
 void evas_object_clip_across_clippees_check(Evas_Object *obj);
 void evas_object_mapped_clip_across_mark(Evas_Object *obj);
@@ -979,6 +1067,7 @@ void _evas_object_smart_members_all_del(Evas_Object *obj);
 void evas_call_smarts_calculate(Evas *e);
 void evas_object_smart_bouding_box_update(Evas_Object *obj);
 void evas_object_smart_need_bounding_box_update(Evas_Object *obj);
+Eina_Bool evas_object_smart_changed_get(Evas_Object *obj);
 void *evas_mem_calloc(int size);
 void _evas_post_event_callback_call(Evas *e);
 void _evas_post_event_callback_free(Evas *e);
@@ -995,6 +1084,7 @@ void evas_object_inform_call_restack(Evas_Object *obj);
 void evas_object_inform_call_changed_size_hints(Evas_Object *obj);
 void evas_object_inform_call_image_preloaded(Evas_Object *obj);
 void evas_object_inform_call_image_unloaded(Evas_Object *obj);
+void evas_object_inform_call_image_resize(Evas_Object *obj);
 void evas_object_intercept_cleanup(Evas_Object *obj);
 int evas_object_intercept_call_show(Evas_Object *obj);
 int evas_object_intercept_call_hide(Evas_Object *obj);
@@ -1026,10 +1116,12 @@ int evas_font_desc_cmp(const Evas_Font_Description *a, const Evas_Font_Descripti
 Evas_Font_Description *evas_font_desc_ref(Evas_Font_Description *fdesc);
 void * evas_font_load(Evas *evas, Evas_Font_Description *fdesc, const char *source, Evas_Font_Size size);
 void evas_font_load_hinting_set(Evas *evas, void *font, int hinting);
-void evas_object_smart_member_cache_invalidate(Evas_Object *obj, Eina_Bool pass_events, Eina_Bool freeze_events);
+void evas_object_smart_member_cache_invalidate(Evas_Object *obj, Eina_Bool pass_events, Eina_Bool freeze_events, Eina_Bool sourve_invisible);
 void evas_text_style_pad_get(Evas_Text_Style_Type style, int *l, int *r, int *t, int *b);
 void _evas_object_text_rehint(Evas_Object *obj);
 void _evas_object_textblock_rehint(Evas_Object *obj);
+void evas_object_inform_call_render_pre(Evas_Object *obj);
+void evas_object_inform_call_render_post(Evas_Object *obj);
 
 extern int _evas_alloc_error;
 extern int _evas_event_counter;
@@ -1044,6 +1136,13 @@ struct _Evas_Imaging_Font
    RGBA_Font *font;
 };
 
+struct _Evas_Proxy_Render_Data
+{
+   Evas_Object *proxy_obj;
+   Evas_Object *src_obj;
+   Eina_Bool source_clip : 1;
+};
+
 int evas_async_events_init(void);
 int evas_async_events_shutdown(void);
 int evas_async_target_del(const void *target);
@@ -1062,17 +1161,21 @@ void _evas_unwalk(Evas *e);
 // expose for use in engines
 EAPI int _evas_module_engine_inherit(Evas_Func *funcs, char *name);
 EAPI const char *_evas_module_libdir_get(void);
-         
-Eina_Bool evas_render_mapped(Evas *e, Evas_Object *obj, 
+
+Eina_Bool evas_render_mapped(Evas *e, Evas_Object *obj,
                              void *context, void *surface,
                              int off_x, int off_y, int mapped,
-                             int ecx, int ecy, int ecw, int ech);
+                             int ecx, int ecy, int ecw, int ech,
+                             Evas_Proxy_Render_Data *proxy_render_data,
+                             int level, Eina_Bool use_mapped_ctx);
 void evas_render_invalidate(Evas *e);
 void evas_render_object_recalc(Evas_Object *obj);
 
 Eina_Bool evas_map_inside_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y);
 Eina_Bool evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y, Evas_Coord *mx, Evas_Coord *my, int grab);
-void evas_object_map_update(Evas_Object *obj, int x, int y, int imagew, int imageh, int uvw, int uvh);
+Eina_Bool evas_object_map_update(Evas_Object *obj, int x, int y, int imagew, int imageh, int uvw, int uvh);
+void evas_map_object_move_diff_set(Evas_Map *m, Evas_Coord diff_x, Evas_Coord diff_y);
+void evas_object_map_move_sync(Evas_Object *obj);
 
 Eina_List *evas_module_engine_list(void);
 
@@ -1081,12 +1184,17 @@ void _evas_touch_point_append(Evas *e, int id, Evas_Coord x, Evas_Coord y);
 void _evas_touch_point_update(Evas *e, int id, Evas_Coord x, Evas_Coord y, Evas_Touch_Point_State state);
 void _evas_touch_point_remove(Evas *e, int id);
 
+void _evas_device_cleanup(Evas *e);
+Evas_Device *_evas_device_top_get(const Evas *e);
+void _evas_device_ref(Evas_Device *dev);
+void _evas_device_unref(Evas_Device *dev);
+
 /****************************************************************************/
 /*****************************************/
 /********************/
 #define MPOOL 1
 
-#ifdef MPOOL 
+#ifdef MPOOL
 typedef struct _Evas_Mempool Evas_Mempool;
 
 struct _Evas_Mempool
index 0431977..72ce2c4 100644 (file)
@@ -82,7 +82,11 @@ evas_debug_input_null(void)
      }
    if (_evas_debug_show == _EVAS_DEBUG_SHOW)
      CRIT("Input object pointer is NULL!");
+
+   /* disable temporarily*/
+   /*
    if (_evas_debug_abort) abort();
+   */
 }
 
 void
@@ -95,7 +99,11 @@ evas_debug_magic_null(void)
    if ((_evas_debug_show == _EVAS_DEBUG_SHOW) ||
          (_evas_debug_show == _EVAS_DEBUG_DEFAULT))
      CRIT("Input object is zero'ed out (maybe a freed object or zero-filled RAM)!");
-   if (_evas_debug_abort) abort();
+   if (_evas_debug_abort)
+     {
+        ERR("### EFL abort on errors ###\n");
+        abort();
+     }
 }
 
 void
@@ -112,7 +120,11 @@ evas_debug_magic_wrong(DATA32 expected, DATA32 supplied)
          "    Supplied: %08x - %s",
          expected, evas_debug_magic_string_get(expected),
          supplied, evas_debug_magic_string_get(supplied));
-   if (_evas_debug_abort) abort();
+   if (_evas_debug_abort)
+     {
+        ERR("### EFL abort on errors ###\n");
+        abort();
+     }
 }
 
 void
@@ -125,7 +137,11 @@ evas_debug_generic(const char *str)
    if ((_evas_debug_show == _EVAS_DEBUG_SHOW) ||
          (_evas_debug_show == _EVAS_DEBUG_DEFAULT))
      CRIT("%s", str);
-   if (_evas_debug_abort) abort();
+   if (_evas_debug_abort)
+     {
+        ERR("### EFL abort on errors ###\n");
+        abort();
+     }
 }
 
 const char *
index 3ee22df..b6498f1 100644 (file)
@@ -41,18 +41,6 @@ endif
 if !EVAS_STATIC_BUILD_SOFTWARE_8_X11
 SUBDIRS += software_8_x11
 endif
-if !EVAS_STATIC_BUILD_SOFTWARE_16
-SUBDIRS += software_16
-endif
-if !EVAS_STATIC_BUILD_SOFTWARE_16_WINCE
-SUBDIRS += software_16_wince
-endif
-if !EVAS_STATIC_BUILD_SOFTWARE_16_X11
-SUBDIRS += software_16_x11
-endif
-if !EVAS_STATIC_BUILD_SOFTWARE_16_SDL
-SUBDIRS += software_16_sdl
-endif
 if !EVAS_STATIC_BUILD_SOFTWARE_DDRAW
 SUBDIRS += software_ddraw
 endif
index a9cbbfb..d35a7af 100644 (file)
@@ -29,7 +29,7 @@ struct _Evas_Engine_Info_Buffer
       struct {
         void * (*new_update_region) (int x, int y, int w, int h, int *row_bytes);
         void   (*free_update_region) (int x, int y, int w, int h, void *data);
-        void * (*switch_buffer) (void *data, void *dest_buffer);
+        void * (*switch_buffer) (void *data, void *dest_buffer);
       } func;
 
       void *switch_data;
index 27f4912..de9c401 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 -I$(top_srcdir)/src/lib/cserve2 \
 -I$(top_srcdir)/src/modules/engines \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@
@@ -28,7 +28,7 @@ pkgdir = $(libdir)/evas/modules/engines/buffer/$(MODULE_ARCH)
 pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = $(BUFFER_SOURCES)
-module_la_LIBADD = $(top_builddir)/src/lib/libevas.la @EINA_LIBS@
+module_la_LIBADD = $(top_builddir)/src/lib/libevas.la @EVAS_GENERAL_LIBS@
 module_la_LDFLAGS =  -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index fc1ffba..dd06d69 100644 (file)
@@ -121,13 +121,13 @@ evas_buffer_outbuf_buf_new_region_for_update(Outbuf *buf, int x, int y, int w, i
                 ((buf->depth == OUTBUF_DEPTH_BGRA_32BPP_8888_8888)))
               {
                  im->cache_entry.flags.alpha = 1;
+               }
 #ifdef EVAS_CSERVE2
-                  if (evas_cserve2_use_get())
-                    evas_cache2_image_size_set(&im->cache_entry, w, h);
-                  else
+               if (evas_cserve2_use_get())
+                 evas_cache2_image_size_set(&im->cache_entry, w, h);
+               else
 #endif
-                  im = (RGBA_Image *) evas_cache_image_size_set(&im->cache_entry, w, h);
-               }
+                 im = (RGBA_Image *) evas_cache_image_size_set(&im->cache_entry, w, h);
           }
      }
    return im;
@@ -331,19 +331,30 @@ evas_buffer_outbuf_buf_push_updated_region(Outbuf *buf, RGBA_Image *update, int
             if (!buf->priv.back_buf)
               {
                  Gfx_Func_Copy func;
-                 
+
                  func = evas_common_draw_func_copy_get(w, 0);
                  if (func)
                    {
-                      for (yy = 0; yy < h; yy++)
-                        {
-                           src = update->image.data + (yy * update->cache_entry.w);
-                           dst = (DATA32 *)((DATA8 *)(buf->dest) + ((y + yy) * row_bytes));
-                           func(src, dst, w);
-                        }
-                      
-                   }
-              }
+                    if (buf->dest_row_bytes != (buf->w * sizeof(DATA32)))
+                      {
+                         for (yy = 0; yy < h; yy++)
+                           {
+                              src = update->image.data + (yy * update->cache_entry.w);
+                              dst = (DATA32 *)((DATA8 *)(buf->dest) + ((y + yy) * row_bytes) + (x * 4));
+                              func(src, dst, w);
+                           }
+                      }
+                    else
+                      {
+                       for (yy = 0; yy < h; yy++)
+                         {
+                            src = update->image.data + (yy * update->cache_entry.w);
+                            dst = (DATA32 *)((DATA8 *)(buf->dest) + ((y + yy) * row_bytes));
+                            func(src, dst, w);
+                         }
+                    }
+                 }
+            }
             if (buf->func.free_update_region)
               {
                  buf->func.free_update_region(x, y, w, h, dest);
index 1ff43a7..e8f0292 100644 (file)
@@ -6,7 +6,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib \
 -I$(top_srcdir)/src/lib/include \
 -I$(top_srcdir)/src/modules/engines \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
@@ -41,7 +41,7 @@ pkgdir = $(libdir)/evas/modules/engines/direct3d/$(MODULE_ARCH)
 pkg_LTLIBRARIES = module.la
 module_la_SOURCES = $(DIRECT3D_SOURCES)
 module_la_CXXFLAGS = -fno-exceptions
-module_la_LIBADD = $(top_builddir)/src/lib/libevas.la $(DIRECT3D_LIBADD) @EINA_LIBS@
+module_la_LIBADD = $(top_builddir)/src/lib/libevas.la $(DIRECT3D_LIBADD) @EVAS_GENERAL_LIBS@
 module_la_LDFLAGS = @lt_enable_auto_import@ -no-undefined -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index c7ce8ff..3d3ea20 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/modules/engines \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_engine_directfb_cflags@
 
@@ -28,7 +28,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES  = $(DIRECTFB_SOURCES)
 
-module_la_LIBADD = @EINA_LIBS@ $(DIRECTFB_LIBADD) $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ $(DIRECTFB_LIBADD) $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 3046db9..1aa1acb 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/modules/engines \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_engine_fb_cflags@
 
@@ -30,7 +30,7 @@ if !EVAS_STATIC_BUILD_FB
 pkgdir = $(libdir)/evas/modules/engines/fb/$(MODULE_ARCH)
 pkg_LTLIBRARIES = module.la
 module_la_SOURCES = $(FB_SOURCES)
-module_la_LIBADD = @EINA_LIBS@ $(FB_LIBADD) $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ $(FB_LIBADD) $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index e15c02b..804c408 100644 (file)
@@ -99,6 +99,7 @@ eng_setup(Evas *e, void *in)
    Evas_Engine_Info_FB *info;
 
    info = (Evas_Engine_Info_FB *)in;
+   EINA_LOG_DBG("[ evasgl_dbg ]: Evas_Engine Info -> FB");
    re = _output_setup(e->output.w,
                      e->output.h,
                      info->info.rotation,
index 1d61f1a..236ae9b 100644 (file)
@@ -322,6 +322,7 @@ fb_getmode(void)
    if (ioctl(fb, FBIOGET_VSCREENINFO, &mode->fb_var) == -1)
      {
         perror("ioctl FBIOGET_VSCREENINFO");
+        free(mode);
         return NULL;
      }
    
index 1db05cc..02a213d 100644 (file)
@@ -6,7 +6,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib \
 -I$(top_srcdir)/src/lib/include \
 -I$(top_srcdir)/src/modules/engines/gl_common \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @GL_EET_CFLAGS@ \
 @FREETYPE_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
@@ -30,7 +30,7 @@ pkgdir = $(libdir)/evas/modules/engines/gl_cocoa/$(MODULE_ARCH)
 pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = $(GL_COCOA_SOURCES)
-module_la_LIBADD = @EINA_LIBS@ @GL_EET_LIBS@ $(GL_COCOA_LIBADD) $(top_builddir)/src/lib/libevas.la @dlopen_libs@
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @GL_EET_LIBS@ $(GL_COCOA_LIBADD) $(top_builddir)/src/lib/libevas.la @dlopen_libs@
 module_la_LDFLAGS = -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
old mode 100644 (file)
new mode 100755 (executable)
index 245de0f..8d3b29c
@@ -446,6 +446,9 @@ eng_image_alpha_set(void *data, void *image, int has_alpha)
      {
         Evas_GL_Image *im_new;
         
+        if (!im->im->image.data)
+          evas_cache_image_load_data(&im->im->cache_entry);
+        evas_gl_common_image_alloc_ensure(im);
         im_new = evas_gl_common_image_new_from_copied_data
            (im->gc, im->im->cache_entry.w, im->im->cache_entry.h, 
                im->im->image.data,
@@ -516,6 +519,7 @@ eng_image_colorspace_set(void *data, void *image, int cspace)
    /* FIXME: can move to gl_common */
    if (im->cs.space == cspace) return;
    eng_window_use(re->win);
+   evas_gl_common_image_alloc_ensure(im);
    evas_cache_image_colorspace(&im->im->cache_entry, cspace);
    switch (cspace)
      {
@@ -684,6 +688,7 @@ eng_image_size_set(void *data, void *image, int w, int h)
    if ((eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422P601_PL) ||
        (eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422P709_PL))
      w &= ~0x1;
+   evas_gl_common_image_alloc_ensure(im);
    if ((im_old) &&
        ((int)im_old->im->cache_entry.w == w) &&
        ((int)im_old->im->cache_entry.h == h))
@@ -751,6 +756,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
      }
    eng_window_use(re->win);
    error = evas_cache_image_load_data(&im->im->cache_entry);
+   evas_gl_common_image_alloc_ensure(im);
    switch (im->cs.space)
      {
       case EVAS_COLORSPACE_ARGB8888:
@@ -802,6 +808,7 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
    im = image;
    if (im->native.data) return image;
    eng_window_use(re->win);
+   evas_gl_common_image_alloc_ensure(im);
    if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data))
      {
         if (im->tex->pt->dyn.data == image_data)
@@ -984,8 +991,12 @@ eng_image_map_surface_free(void *data __UNUSED__, void *surface)
 }
 
 static void
-eng_image_content_hint_set(void *data __UNUSED__, void *image, int hint)
+eng_image_content_hint_set(void *data, void *image, int hint)
 {
+   Render_Engine *re;
+   re = (Render_Engine *)data;
+
+   if (re) eng_window_use(re->win);
    if (image) evas_gl_common_image_content_hint_set(image, hint);
 }
 
@@ -1104,7 +1115,7 @@ evgl_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
 static void
 evgl_glClearDepthf(GLclampf depth)
 {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
    glClearDepthf(depth);
 #else
    glClearDepth(depth);
@@ -1114,7 +1125,7 @@ evgl_glClearDepthf(GLclampf depth)
 static void
 evgl_glDepthRangef(GLclampf zNear, GLclampf zFar)
 {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
    glDepthRangef(zNear, zFar);
 #else
    glDepthRange(zNear, zFar);
@@ -1124,7 +1135,7 @@ evgl_glDepthRangef(GLclampf zNear, GLclampf zFar)
 static void
 evgl_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
 {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
    glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
 #else
    if (range)
@@ -1144,7 +1155,7 @@ evgl_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint*
 static void
 evgl_glReleaseShaderCompiler(void)
 {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
    glReleaseShaderCompiler();
 #else
 #endif
@@ -1153,7 +1164,7 @@ evgl_glReleaseShaderCompiler(void)
 static void
 evgl_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length)
 {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
    glShaderBinary(n, shaders, binaryformat, binary, length);
 #else
 // FIXME: need to dlsym/getprocaddress for this
index b2ebc5b..b83ee6c 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @GL_EET_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@
 
 if BUILD_ENGINE_GL_COMMON
@@ -18,6 +18,7 @@ libevas_engine_gl_common_la_SOURCES  = \
 evas_gl_private.h \
 evas_gl_common.h \
 evas_gl_context.c \
+evas_gl_file_cache.c \
 evas_gl_shader.c \
 evas_gl_rectangle.c \
 evas_gl_texture.c \
@@ -26,52 +27,124 @@ evas_gl_font.c \
 evas_gl_polygon.c \
 evas_gl_line.c \
 evas_gl_filter.c \
-shader/rect_frag.h \
-shader/rect_frag_bin_s3c6410.h \
-shader/rect_vert.h \
-shader/rect_vert_bin_s3c6410.h \
+evas_gl_core.c \
+evas_gl_api_ext.h \
+evas_gl_api_ext_def.h \
+evas_gl_core.h \
+evas_gl_core_private.h \
+evas_gl_api.c \
+evas_gl_api_ext.c \
+evas_gl_api_gles1.c \
 shader/font_frag.h \
-shader/font_frag_bin_s3c6410.h \
 shader/font_vert.h \
-shader/font_vert_bin_s3c6410.h \
-shader/img_frag.h \
-shader/img_frag_bin_s3c6410.h \
-shader/img_vert.h \
-shader/img_vert_bin_s3c6410.h \
-shader/img_nomul_frag.h \
-shader/img_nomul_frag_bin_s3c6410.h \
-shader/img_nomul_vert.h \
-shader/img_nomul_vert_bin_s3c6410.h \
+shader/img_12_bgra_frag.h \
+shader/img_12_bgra_nomul_frag.h \
+shader/img_12_bgra_nomul_vert.h \
+shader/img_12_bgra_vert.h \
+shader/img_12_bgra_afill_frag.h \
+shader/img_12_bgra_nomul_afill_frag.h \
+shader/img_12_bgra_nomul_afill_vert.h \
+shader/img_12_bgra_afill_vert.h \
+shader/img_12_frag.h \
+shader/img_12_nomul_frag.h \
+shader/img_12_nomul_vert.h \
+shader/img_12_vert.h \
+shader/img_12_afill_frag.h \
+shader/img_12_nomul_afill_frag.h \
+shader/img_12_nomul_afill_vert.h \
+shader/img_12_afill_vert.h \
+shader/img_21_bgra_frag.h \
+shader/img_21_bgra_nomul_frag.h \
+shader/img_21_bgra_nomul_vert.h \
+shader/img_21_bgra_vert.h \
+shader/img_21_bgra_afill_frag.h \
+shader/img_21_bgra_nomul_afill_frag.h \
+shader/img_21_bgra_nomul_afill_vert.h \
+shader/img_21_bgra_afill_vert.h \
+shader/img_21_frag.h \
+shader/img_21_nomul_frag.h \
+shader/img_21_nomul_vert.h \
+shader/img_21_vert.h \
+shader/img_21_afill_frag.h \
+shader/img_21_nomul_afill_frag.h \
+shader/img_21_nomul_afill_vert.h \
+shader/img_21_afill_vert.h \
+shader/img_22_bgra_frag.h \
+shader/img_22_bgra_nomul_frag.h \
+shader/img_22_bgra_nomul_vert.h \
+shader/img_22_bgra_vert.h \
+shader/img_22_bgra_afill_frag.h \
+shader/img_22_bgra_nomul_afill_frag.h \
+shader/img_22_bgra_nomul_afill_vert.h \
+shader/img_22_bgra_afill_vert.h \
+shader/img_22_frag.h \
+shader/img_22_nomul_frag.h \
+shader/img_22_nomul_vert.h \
+shader/img_22_vert.h \
+shader/img_22_afill_frag.h \
+shader/img_22_nomul_afill_frag.h \
+shader/img_22_nomul_afill_vert.h \
+shader/img_22_afill_vert.h \
 shader/img_bgra_frag.h \
-shader/img_bgra_frag_bin_s3c6410.h \
-shader/img_bgra_vert.h \
-shader/img_bgra_vert_bin_s3c6410.h \
 shader/img_bgra_nomul_frag.h \
-shader/img_bgra_nomul_frag_bin_s3c6410.h \
 shader/img_bgra_nomul_vert.h \
-shader/img_bgra_nomul_vert_bin_s3c6410.h \
+shader/img_bgra_vert.h \
+shader/img_bgra_afill_frag.h \
+shader/img_bgra_nomul_afill_frag.h \
+shader/img_bgra_nomul_afill_vert.h \
+shader/img_bgra_afill_vert.h \
+shader/img_frag.h \
 shader/img_mask_frag.h \
 shader/img_mask_vert.h \
+shader/img_nomul_frag.h \
+shader/img_nomul_vert.h \
+shader/img_vert.h \
+shader/img_afill_frag.h \
+shader/img_nomul_afill_frag.h \
+shader/img_nomul_afill_vert.h \
+shader/img_afill_vert.h \
+shader/nv12_frag.h \
+shader/nv12_nomul_frag.h \
 shader/nv12_nomul_vert.h \
 shader/nv12_vert.h \
-shader/nv12_nomul_frag.h \
-shader/nv12_frag.h \
-shader/yuv_frag.h \
-shader/yuv_frag_bin_s3c6410.h \
-shader/yuv_vert.h \
-shader/yuv_vert_bin_s3c6410.h \
-shader/yuv_nomul_frag.h \
-shader/yuv_nomul_frag_bin_s3c6410.h \
-shader/yuv_nomul_vert.h \
-shader/yuv_nomul_vert_bin_s3c6410.h \
+shader/rect_frag.h \
+shader/rect_vert.h \
+shader/tex_12_frag.h \
+shader/tex_12_nomul_frag.h \
+shader/tex_12_nomul_vert.h \
+shader/tex_12_vert.h \
+shader/tex_21_frag.h \
+shader/tex_21_nomul_frag.h \
+shader/tex_21_nomul_vert.h \
+shader/tex_21_vert.h \
+shader/tex_22_frag.h \
+shader/tex_22_nomul_frag.h \
+shader/tex_22_nomul_vert.h \
+shader/tex_22_vert.h \
 shader/tex_frag.h \
-shader/tex_frag_bin_s3c6410.h \
-shader/tex_vert.h \
-shader/tex_vert_bin_s3c6410.h \
 shader/tex_nomul_frag.h \
-shader/tex_nomul_frag_bin_s3c6410.h \
 shader/tex_nomul_vert.h \
-shader/tex_nomul_vert_bin_s3c6410.h \
+shader/tex_vert.h \
+shader/tex_12_afill_frag.h \
+shader/tex_12_nomul_afill_frag.h \
+shader/tex_12_nomul_afill_vert.h \
+shader/tex_12_afill_vert.h \
+shader/tex_21_afill_frag.h \
+shader/tex_21_nomul_afill_frag.h \
+shader/tex_21_nomul_afill_vert.h \
+shader/tex_21_afill_vert.h \
+shader/tex_22_afill_frag.h \
+shader/tex_22_nomul_afill_frag.h \
+shader/tex_22_nomul_afill_vert.h \
+shader/tex_22_afill_vert.h \
+shader/tex_afill_frag.h \
+shader/tex_nomul_afill_frag.h \
+shader/tex_nomul_afill_vert.h \
+shader/tex_afill_vert.h \
+shader/yuv_frag.h \
+shader/yuv_nomul_frag.h \
+shader/yuv_nomul_vert.h \
+shader/yuv_vert.h \
 shader/filter_invert.h \
 shader/filter_invert_nomul.h \
 shader/filter_invert_bgra.h \
@@ -93,42 +166,74 @@ shader/yuy2_vert.h \
 shader/yuy2_nomul_frag.h \
 shader/yuy2_nomul_vert.h
 
-libevas_engine_gl_common_la_LIBADD = @EINA_LIBS@ @GL_EET_LIBS@ @evas_engine_gl_common_libs@ @dlopen_libs@
+libevas_engine_gl_common_la_LIBADD = @EVAS_GENERAL_LIBS@ @GL_EET_LIBS@ @evas_engine_gl_common_libs@ @dlopen_libs@
 endif
 
 EXTRA_DIST = \
-shader/compile-s3c6410.sh \
-shader/compile-sgx.sh \
-shader/make-c-bin.sh \
+shader/compile.sh \
 shader/make-c-str.sh \
-shader/rect_frag.shd \
-shader/rect_frag_s3c6410.asm \
-shader/rect_vert.shd \
 shader/font_frag.shd \
-shader/font_frag_s3c6410.asm \
 shader/font_vert.shd \
-shader/img_frag.shd \
-shader/img_frag_s3c6410.asm \
-shader/img_vert.shd \
-shader/img_nomul_frag.shd \
-shader/img_nomul_vert.shd \
-shader/img_bgra_vert.shd \
+shader/img_12_bgra_frag.shd \
+shader/img_12_bgra_nomul_frag.shd \
+shader/img_12_bgra_nomul_vert.shd \
+shader/img_12_bgra_vert.shd \
+shader/img_12_frag.shd \
+shader/img_12_nomul_frag.shd \
+shader/img_12_nomul_vert.shd \
+shader/img_12_vert.shd \
+shader/img_21_bgra_frag.shd \
+shader/img_21_bgra_nomul_frag.shd \
+shader/img_21_bgra_nomul_vert.shd \
+shader/img_21_bgra_vert.shd \
+shader/img_21_frag.shd \
+shader/img_21_nomul_frag.shd \
+shader/img_21_nomul_vert.shd \
+shader/img_21_vert.shd \
+shader/img_22_bgra_frag.shd \
+shader/img_22_bgra_nomul_frag.shd \
+shader/img_22_bgra_nomul_vert.shd \
+shader/img_22_bgra_vert.shd \
+shader/img_22_frag.shd \
+shader/img_22_nomul_frag.shd \
+shader/img_22_nomul_vert.shd \
+shader/img_22_vert.shd \
 shader/img_bgra_frag.shd \
-shader/img_bgra_vert.shd \
 shader/img_bgra_nomul_frag.shd \
 shader/img_bgra_nomul_vert.shd \
+shader/img_bgra_vert.shd \
+shader/img_frag.shd \
 shader/img_mask_frag.h \
 shader/img_mask_vert.h \
-shader/yuv_frag.shd \
-shader/yuv_frag_s3c6410.asm \
-shader/yuv_vert.shd \
-shader/yuv_nomul_frag.shd \
-shader/yuv_nomul_vert.shd \
+shader/img_nomul_frag.shd \
+shader/img_nomul_vert.shd \
+shader/img_vert.shd \
+shader/nv12_frag.shd \
+shader/nv12_nomul_frag.shd \
+shader/nv12_nomul_vert.shd \
+shader/nv12_vert.shd \
+shader/rect_frag.shd \
+shader/rect_vert.shd \
+shader/tex_12_frag.shd \
+shader/tex_12_nomul_frag.shd \
+shader/tex_12_nomul_vert.shd \
+shader/tex_12_vert.shd \
+shader/tex_21_frag.shd \
+shader/tex_21_nomul_frag.shd \
+shader/tex_21_nomul_vert.shd \
+shader/tex_21_vert.shd \
+shader/tex_22_frag.shd \
+shader/tex_22_nomul_frag.shd \
+shader/tex_22_nomul_vert.shd \
+shader/tex_22_vert.shd \
 shader/tex_frag.shd \
-shader/tex_frag_s3c6410.asm \
-shader/tex_vert.shd \
 shader/tex_nomul_frag.shd \
 shader/tex_nomul_vert.shd \
+shader/tex_vert.shd \
+shader/yuv_frag.shd \
+shader/yuv_nomul_frag.shd \
+shader/yuv_nomul_vert.shd \
+shader/yuv_vert.shd \
 shader/filter_invert.shd \
 shader/filter_invert_nomul.shd \
 shader/filter_invert_bgra.shd \
@@ -145,21 +250,9 @@ shader/filter_blur.shd \
 shader/filter_blur_nomul.shd \
 shader/filter_blur_bgra.shd \
 shader/filter_blur_bgra_nomul.shd \
-shader/nv12_frag.h \
-shader/nv12_frag.shd \
-shader/nv12_nomul_frag.h \
-shader/nv12_nomul_frag.shd \
-shader/nv12_nomul_vert.h \
-shader/nv12_nomul_vert.shd \
-shader/nv12_vert.h \
-shader/nv12_vert.shd \
-shader/yuy2_frag.h \
 shader/yuy2_frag.shd \
-shader/yuy2_nomul_frag.h \
 shader/yuy2_nomul_frag.shd \
-shader/yuy2_nomul_vert.h \
 shader/yuy2_nomul_vert.shd \
-shader/yuy2_vert.h \
 shader/yuy2_vert.shd
 
 
diff --git a/src/modules/engines/gl_common/evas_gl_api.c b/src/modules/engines/gl_common/evas_gl_api.c
new file mode 100755 (executable)
index 0000000..0c7a065
--- /dev/null
@@ -0,0 +1,2844 @@
+#include "evas_gl_core_private.h"
+#include "evas_gl_api_ext.h"
+
+#define EVGL_FUNC_BEGIN() \
+{ \
+   _func_begin_debug(__FUNCTION__); \
+}
+
+#define EVGL_FUNC_END()
+#define _EVGL_INT_INIT_VALUE -3
+
+extern int _evas_gl_log_level;
+
+//---------------------------------------//
+// API Debug Error Checking Code
+static
+void _make_current_check(const char* api)
+{
+   EVGL_Context *ctx = NULL;
+
+   ctx = _evgl_current_context_get();
+
+   if (!ctx)
+     {
+        CRIT("\e[1;33m%s\e[m: Current Context NOT SET: GL Call Should NOT Be Called without MakeCurrent!!!", api);
+     }
+}
+
+static
+void _direct_rendering_check(const char *api)
+{
+   EVGL_Context *ctx = NULL;
+
+   ctx = _evgl_current_context_get();
+   if (!ctx)
+     {
+        ERR("Current Context Not Set");
+        return;
+     }
+
+   if (_evgl_not_in_pixel_get())
+     {
+        CRIT("\e[1;33m%s\e[m: This API is being called outside Pixel Get Callback Function.", api);
+     }
+}
+
+static
+void _func_begin_debug(const char *api)
+{
+   _make_current_check(api);
+   _direct_rendering_check(api);
+
+   if (_evas_gl_log_level >= 6)
+     DBG("GL CALL: %s", api);
+}
+
+
+//-------------------------------------------------------------//
+// GL to GLES Compatibility Functions
+//-------------------------------------------------------------//
+void
+_evgl_glBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+   EVGL_Context *ctx = NULL;
+   EVGL_Resource *rsc;
+
+   rsc = _evgl_tls_resource_get();
+   ctx = _evgl_current_context_get();
+
+   if (!ctx)
+     {
+        ERR("No current context set.");
+        return;
+     }
+   if (!rsc)
+     {
+        ERR("No current TLS resource.");
+        return;
+     }
+
+   // Take care of BindFramebuffer 0 issue
+   if (framebuffer==0)
+     {
+        if (_evgl_direct_enabled())
+          {
+             if (ctx->map_tex)
+                glBindFramebuffer(target, ctx->current_fbo);
+             else
+                glBindFramebuffer(target, 0);
+
+             if (rsc->direct.partial.enabled)
+               {
+                  if (!ctx->partial_render)
+                    {
+                       evgl_direct_partial_render_start();
+                       ctx->partial_render = 1;
+                    }
+               }
+          }
+        else
+          {
+             glBindFramebuffer(target, ctx->surface_fbo);
+          }
+        ctx->current_fbo = 0;
+     }
+   else
+     {
+        if (_evgl_direct_enabled())
+          {
+             if (ctx->current_fbo == 0)
+               {
+                  if (rsc->direct.partial.enabled)
+                     evgl_direct_partial_render_end();
+               }
+          }
+
+        glBindFramebuffer(target, framebuffer);
+
+        // Save this for restore when doing make current
+        ctx->current_fbo = framebuffer;
+     }
+}
+
+void
+_evgl_glClearDepthf(GLclampf depth)
+{
+#ifdef GL_GLES
+   glClearDepthf(depth);
+#else
+   glClearDepth(depth);
+#endif
+}
+
+void
+_evgl_glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+#ifdef GL_GLES
+   glDepthRangef(zNear, zFar);
+#else
+   glDepthRange(zNear, zFar);
+#endif
+}
+
+void
+_evgl_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+#ifdef GL_GLES
+   glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
+#else
+   if (range)
+     {
+        range[0] = -126; // floor(log2(FLT_MIN))
+        range[1] = 127; // floor(log2(FLT_MAX))
+     }
+   if (precision)
+     {
+        precision[0] = 24; // floor(-log2((1.0/16777218.0)));
+     }
+   return;
+   if (shadertype) shadertype = precisiontype = 0;
+#endif
+}
+
+void
+_evgl_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length)
+{
+#ifdef GL_GLES
+   glShaderBinary(n, shaders, binaryformat, binary, length);
+#else
+   // FIXME: need to dlsym/getprocaddress for this
+   ERR("Binary Shader is not supported here yet.");
+   (void)n;
+   (void)shaders;
+   (void)binaryformat;
+   (void)binary;
+   (void)length;
+#endif
+}
+
+void
+_evgl_glReleaseShaderCompiler(void)
+{
+#ifdef GL_GLES
+   glReleaseShaderCompiler();
+#else
+#endif
+}
+
+
+//-------------------------------------------------------------//
+// Calls related to Evas GL Direct Rendering
+//-------------------------------------------------------------//
+// Transform from Evas Coordinat to GL Coordinate
+// returns: imgc[4] (oc[4]) original image object dimension in gl coord
+// returns: objc[4] (nc[4]) tranformed  (x, y, width, heigth) in gl coord
+// returns: cc[4] cliped coordinate in original coordinate
+void
+compute_gl_coordinates(int win_w, int win_h, int rot, int clip_image,
+                       int x, int y, int width, int height,
+                       int img_x, int img_y, int img_w, int img_h,
+                       int clip_x, int clip_y, int clip_w, int clip_h,
+                       int imgc[4], int objc[4], int cc[4])
+{
+   if (rot == 0)
+     {
+        // oringinal image object coordinate in gl coordinate
+        imgc[0] = img_x;
+        imgc[1] = win_h - img_y - img_h;
+        imgc[2] = imgc[0] + img_w;
+        imgc[3] = imgc[1] + img_h;
+
+        // clip coordinates in gl coordinate
+        cc[0] = clip_x;
+        cc[1] = win_h - clip_y - clip_h;
+        cc[2] = cc[0] + clip_w;
+        cc[3] = cc[1] + clip_h;
+
+        // transformed (x,y,width,height) in gl coordinate
+        objc[0] = imgc[0] + x;
+        objc[1] = imgc[1] + y;
+        objc[2] = objc[0] + width;
+        objc[3] = objc[1] + height;
+     }
+   else if (rot == 180)
+     {
+        // oringinal image object coordinate in gl coordinate
+        imgc[0] = win_w - img_x - img_w;
+        imgc[1] = img_y;
+        imgc[2] = imgc[0] + img_w;
+        imgc[3] = imgc[1] + img_h;
+
+        // clip coordinates in gl coordinate
+        cc[0] = win_w - clip_x - clip_w;
+        cc[1] = clip_y;
+        cc[2] = cc[0] + clip_w;
+        cc[3] = cc[1] + clip_h;
+
+        // transformed (x,y,width,height) in gl coordinate
+        objc[0] = imgc[0] + img_w - x - width;
+        objc[1] = imgc[1] + img_h - y - height;
+        objc[2] = objc[0] + width;
+        objc[3] = objc[1] + height;
+
+     }
+   else if (rot == 90)
+     {
+        // oringinal image object coordinate in gl coordinate
+        imgc[0] = img_y;
+        imgc[1] = img_x;
+        imgc[2] = imgc[0] + img_h;
+        imgc[3] = imgc[1] + img_w;
+
+        // clip coordinates in gl coordinate
+        cc[0] = clip_y;
+        cc[1] = clip_x;
+        cc[2] = cc[0] + clip_h;
+        cc[3] = cc[1] + clip_w;
+
+        // transformed (x,y,width,height) in gl coordinate
+        objc[0] = imgc[0] + img_h - y - height;
+        objc[1] = imgc[1] + x;
+        objc[2] = objc[0] + height;
+        objc[3] = objc[1] + width;
+     }
+   else if (rot == 270)
+     {
+        // oringinal image object coordinate in gl coordinate
+        imgc[0] = win_h - img_y - img_h;
+        imgc[1] = win_w - img_x - img_w;
+        imgc[2] = imgc[0] + img_h;
+        imgc[3] = imgc[1] + img_w;
+
+        // clip coordinates in gl coordinate
+        cc[0] = win_h - clip_y - clip_h;
+        cc[1] = win_w - clip_x - clip_w;
+        cc[2] = cc[0] + clip_h;
+        cc[3] = cc[1] + clip_w;
+
+        // transformed (x,y,width,height) in gl coordinate
+        objc[0] = imgc[0] + y;
+        objc[1] = imgc[1] + img_w - x - width;
+        objc[2] = objc[0] + height;
+        objc[3] = objc[1] + width;
+     }
+   else
+     {
+        ERR("Invalid rotation angle %d.", rot);
+        return;
+     }
+
+   if (clip_image)
+     {
+        // Clip against original image object
+        if (objc[0] < imgc[0]) objc[0] = imgc[0];
+        if (objc[0] > imgc[2]) objc[0] = imgc[2];
+
+        if (objc[1] < imgc[1]) objc[1] = imgc[1];
+        if (objc[1] > imgc[3]) objc[1] = imgc[3];
+
+        if (objc[2] < imgc[0]) objc[2] = imgc[0];
+        if (objc[2] > imgc[2]) objc[2] = imgc[2];
+
+        if (objc[3] < imgc[1]) objc[3] = imgc[1];
+        if (objc[3] > imgc[3]) objc[3] = imgc[3];
+     }
+
+   imgc[2] = imgc[2]-imgc[0];     // width
+   imgc[3] = imgc[3]-imgc[1];     // height
+
+   objc[2] = objc[2]-objc[0];     // width
+   objc[3] = objc[3]-objc[1];     // height
+
+   cc[2] = cc[2]-cc[0]; // width
+   cc[3] = cc[3]-cc[1]; // height
+
+   //DBG( "\e[1;32m     Img[%d %d %d %d] Original [%d %d %d %d]  Transformed[%d %d %d %d]  Clip[%d %d %d %d] Clipped[%d %d %d %d] \e[m", img_x, img_y, img_w, img_h, imgc[0], imgc[1], imgc[2], imgc[3], objc[0], objc[1], objc[2], objc[3], clip[0], clip[1], clip[2], clip[3], cc[0], cc[1], cc[2], cc[3]);
+}
+
+static void
+_evgl_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+   EVGL_Resource *rsc;
+
+   if (!(rsc=_evgl_tls_resource_get()))
+     {
+        ERR("Unable to execute GL command. Error retrieving tls");
+        return;
+     }
+
+   if (_evgl_direct_enabled())
+     {
+        rsc->clear_color.a = alpha;
+        rsc->clear_color.r = red;
+        rsc->clear_color.g = green;
+        rsc->clear_color.b = blue;
+     }
+   glClearColor(red, green, blue, alpha);
+}
+
+static void
+_evgl_glClear(GLbitfield mask)
+{
+   EVGL_Resource *rsc;
+   EVGL_Context *ctx;
+   int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0};
+   int cc[4] = {0,0,0,0};
+
+   if (!(rsc=_evgl_tls_resource_get()))
+     {
+        ERR("Unable to execute GL command. Error retrieving tls");
+        return;
+     }
+
+   if (!rsc->current_eng)
+     {
+        ERR("Unable to retrive Current Engine");
+        return;
+     }
+
+   ctx = rsc->current_ctx;
+   if (!ctx)
+     {
+        ERR("Unable to retrive Current Context");
+        return;
+     }
+
+   if (_evgl_direct_enabled())
+     {
+        if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex)
+          {
+             /* Skip glClear() if clearing with transparent color
+              * Note: There will be side effects if the object itself is not
+              * marked as having an alpha channel!
+              */
+             if (ctx->current_sfc->alpha && (mask & GL_COLOR_BUFFER_BIT))
+               {
+                  if ((rsc->clear_color.a == 0) &&
+                      (rsc->clear_color.r == 0) &&
+                      (rsc->clear_color.g == 0) &&
+                      (rsc->clear_color.b == 0))
+                    {
+                       // Skip clear color as we don't want to write black
+                       mask &= ~GL_COLOR_BUFFER_BIT;
+                    }
+                  else if (rsc->clear_color.a != 1.0)
+                    {
+                       // TODO: Draw a rectangle? This will never be the perfect solution though.
+                       WRN("glClear() used with a semi-transparent color and direct rendering. "
+                           "This will erase the previous contents of the evas!");
+                    }
+                  if (!mask) return;
+               }
+
+             if ((!ctx->direct_scissor))
+               {
+                  glEnable(GL_SCISSOR_TEST);
+                  ctx->direct_scissor = 1;
+               }
+
+             if ((ctx->scissor_updated) && (ctx->scissor_enabled))
+               {
+                  compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h,
+                                         rsc->direct.rot, 1,
+                                         ctx->scissor_coord[0], ctx->scissor_coord[1],
+                                         ctx->scissor_coord[2], ctx->scissor_coord[3],
+                                         rsc->direct.img.x, rsc->direct.img.y,
+                                         rsc->direct.img.w, rsc->direct.img.h,
+                                         rsc->direct.clip.x, rsc->direct.clip.y,
+                                         rsc->direct.clip.w, rsc->direct.clip.h,
+                                         oc, nc, cc);
+
+                  RECTS_CLIP_TO_RECT(nc[0], nc[1], nc[2], nc[3], cc[0], cc[1], cc[2], cc[3]);
+                  glScissor(nc[0], nc[1], nc[2], nc[3]);
+                  ctx->direct_scissor = 0;
+               }
+             else
+               {
+                  compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h,
+                                         rsc->direct.rot, 0,
+                                         0, 0, 0, 0,
+                                         rsc->direct.img.x, rsc->direct.img.y,
+                                         rsc->direct.img.w, rsc->direct.img.h,
+                                         rsc->direct.clip.x, rsc->direct.clip.y,
+                                         rsc->direct.clip.w, rsc->direct.clip.h,
+                                         oc, nc, cc);
+
+                  glScissor(cc[0], cc[1], cc[2], cc[3]);
+               }
+
+             glClear(mask);
+
+             // TODO/FIXME: Restore previous client-side scissors.
+          }
+        else
+          {
+             if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+               {
+                  glDisable(GL_SCISSOR_TEST);
+                  ctx->direct_scissor = 0;
+               }
+
+             glClear(mask);
+          }
+     }
+   else
+     {
+        if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+          {
+             glDisable(GL_SCISSOR_TEST);
+             ctx->direct_scissor = 0;
+          }
+
+        glClear(mask);
+     }
+}
+
+static void
+_evgl_glEnable(GLenum cap)
+{
+   EVGL_Context *ctx;
+
+   ctx = _evgl_current_context_get();
+
+   if (cap == GL_SCISSOR_TEST)
+      if (ctx) ctx->scissor_enabled = 1;
+   glEnable(cap);
+}
+
+static void
+_evgl_glDisable(GLenum cap)
+{
+   EVGL_Context *ctx;
+
+   ctx = _evgl_current_context_get();
+
+   if (cap == GL_SCISSOR_TEST)
+      if (ctx) ctx->scissor_enabled = 0;
+   glDisable(cap);
+}
+
+void
+_evgl_glGetIntegerv(GLenum pname, GLint* params)
+{
+   EVGL_Resource *rsc;
+   EVGL_Context *ctx;
+
+   if (_evgl_direct_enabled())
+     {
+        if (!params)
+          {
+             ERR("Inavlid Parameter");
+             return;
+          }
+
+        if (!(rsc=_evgl_tls_resource_get()))
+          {
+             ERR("Unable to execute GL command. Error retrieving tls");
+             return;
+          }
+
+        ctx = rsc->current_ctx;
+        if (!ctx)
+          {
+             ERR("Unable to retrive Current Context");
+             return;
+          }
+
+        // Only need to handle it if it's directly rendering to the window
+        if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex)
+          {
+             if (pname == GL_SCISSOR_BOX)
+               {
+                  if (ctx->scissor_updated)
+                    {
+                       memcpy(params, ctx->scissor_coord, sizeof(int)*4);
+                       return;
+                    }
+               }
+             /*!!! Temporary Fixes to avoid Webkit issue
+             if (pname == GL_VIEWPORT)
+               {
+                  if (ctx->viewport_updated)
+                    {
+                       memcpy(params, ctx->viewport_coord, sizeof(int)*4);
+                       return;
+                    }
+               }
+               */
+
+             // If it hasn't been initialized yet, return img object size
+             if ((pname == GL_SCISSOR_BOX)) //|| (pname == GL_VIEWPORT))
+               {
+                  params[0] = 0;
+                  params[1] = 0;
+                  params[2] = (GLint)rsc->direct.img.w;
+                  params[3] = (GLint)rsc->direct.img.h;
+                  return;
+               }
+          }
+     }
+
+   glGetIntegerv(pname, params);
+}
+
+const GLubyte *
+_evgl_glGetString(GLenum name)
+{
+   static char _version[128] = {0};
+   EVGL_Resource *rsc;
+   const GLubyte *ret;
+
+   if (!name)
+     {
+        ERR("Invalid parameter");
+        return NULL;
+     }
+
+   if (!(rsc=_evgl_tls_resource_get()))
+     {
+        ERR("Unable to execute GL command. Error retrieving tls");
+        return NULL;
+     }
+
+   if (!rsc->current_ctx)
+     {
+        ERR("Unable to retrive Current Context");
+        return NULL;
+     }
+
+   switch (name)
+     {
+      case GL_VENDOR:
+      case GL_RENDERER:
+      case GL_SHADING_LANGUAGE_VERSION:
+        break;
+
+      case GL_VERSION:
+        ret = glGetString(GL_VERSION);
+        if (!ret) return NULL;
+#ifdef GL_GLES
+        if (ret[10] != (GLubyte) '2')
+          {
+             // We try not to remove the vendor fluff
+             snprintf(_version, sizeof(_version), "OpenGL ES 2.0 Evas GL (%s)", ((char *) ret) + 10);
+             _version[sizeof(_version) - 1] = '\0';
+             return (const GLubyte *) _version;
+          }
+        return ret;
+#else
+        // Desktop GL, we still keep the official name
+        snprintf(_version, sizeof(_version), "OpenGL ES 2.0 Evas GL (%s)", (char *) ret);
+        _version[sizeof(_version) - 1] = '\0';
+        return (const GLubyte *) _version;
+#endif
+
+      case GL_EXTENSIONS:
+        return (GLubyte *) evgl_api_ext_string_get(EINA_TRUE, EINA_FALSE);
+
+      default:
+        WRN("Unknown string requested: %x", (unsigned int) name);
+        break;
+     }
+
+   return glGetString(name);
+}
+
+static void
+_evgl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
+{
+   EVGL_Resource *rsc;
+   EVGL_Context *ctx;
+   int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0};
+   int cc[4] = {0,0,0,0};
+
+
+   if (!(rsc=_evgl_tls_resource_get()))
+     {
+        ERR("Unable to execute GL command. Error retrieving tls");
+        return;
+     }
+
+   if (!rsc->current_eng)
+     {
+        ERR("Unable to retrive Current Engine");
+        return;
+     }
+
+   ctx = rsc->current_ctx;
+   if (!ctx)
+     {
+        ERR("Unable to retrive Current Context");
+        return;
+     }
+
+   if (_evgl_direct_enabled())
+     {
+
+        if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex)
+          {
+             compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h,
+                                    rsc->direct.rot, 1,
+                                    x, y, width, height,
+                                    rsc->direct.img.x, rsc->direct.img.y,
+                                    rsc->direct.img.w, rsc->direct.img.h,
+                                    rsc->direct.clip.x, rsc->direct.clip.y,
+                                    rsc->direct.clip.w, rsc->direct.clip.h,
+                                    oc, nc, cc);
+             glReadPixels(nc[0], nc[1], nc[2], nc[3], format, type, pixels);
+          }
+        else
+          {
+             glReadPixels(x, y, width, height, format, type, pixels);
+          }
+     }
+   else
+     {
+        glReadPixels(x, y, width, height, format, type, pixels);
+     }
+}
+
+static void
+_evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+   EVGL_Resource *rsc;
+   EVGL_Context *ctx;
+   int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0};
+   int cc[4] = {0,0,0,0};
+
+   if (!(rsc=_evgl_tls_resource_get()))
+     {
+        ERR("Unable to execute GL command. Error retrieving tls");
+        return;
+     }
+
+   if (!rsc->current_eng)
+     {
+        ERR("Unable to retrive Current Engine");
+        return;
+     }
+
+   ctx = rsc->current_ctx;
+   if (!ctx)
+     {
+        ERR("Unable to retrive Current Context");
+        return;
+     }
+
+   if (_evgl_direct_enabled())
+     {
+        if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex)
+          {
+             if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+               {
+                  glDisable(GL_SCISSOR_TEST);
+               }
+
+             compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h,
+                                    rsc->direct.rot, 1,
+                                    x, y, width, height,
+                                    rsc->direct.img.x, rsc->direct.img.y,
+                                    rsc->direct.img.w, rsc->direct.img.h,
+                                    rsc->direct.clip.x, rsc->direct.clip.y,
+                                    rsc->direct.clip.w, rsc->direct.clip.h,
+                                    oc, nc, cc);
+
+             // Keep a copy of the original coordinates
+             ctx->scissor_coord[0] = x;
+             ctx->scissor_coord[1] = y;
+             ctx->scissor_coord[2] = width;
+             ctx->scissor_coord[3] = height;
+
+             RECTS_CLIP_TO_RECT(nc[0], nc[1], nc[2], nc[3], cc[0], cc[1], cc[2], cc[3]);
+             glScissor(nc[0], nc[1], nc[2], nc[3]);
+
+             ctx->direct_scissor = 0;
+
+             // Check....!!!!
+             ctx->scissor_updated = 1;
+          }
+        else
+          {
+             if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+               {
+                  glDisable(GL_SCISSOR_TEST);
+                  ctx->direct_scissor = 0;
+               }
+
+             glScissor(x, y, width, height);
+
+             ctx->scissor_updated = 0;
+          }
+     }
+   else
+     {
+        if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+          {
+             glDisable(GL_SCISSOR_TEST);
+             ctx->direct_scissor = 0;
+          }
+
+        glScissor(x, y, width, height);
+     }
+}
+
+static void
+_evgl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+   EVGL_Resource *rsc;
+   EVGL_Context *ctx;
+   int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0};
+   int cc[4] = {0,0,0,0};
+
+   if (!(rsc=_evgl_tls_resource_get()))
+     {
+        ERR("Unable to execute GL command. Error retrieving tls");
+        return;
+     }
+
+   if (!rsc->current_eng)
+     {
+        ERR("Unable to retrive Current Engine");
+        return;
+     }
+
+   ctx = rsc->current_ctx;
+   if (!ctx)
+     {
+        ERR("Unable to retrive Current Context");
+        return;
+     }
+
+   if (_evgl_direct_enabled())
+     {
+        if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex)
+          {
+             if ((!ctx->direct_scissor))
+               {
+                  glEnable(GL_SCISSOR_TEST);
+                  ctx->direct_scissor = 1;
+               }
+
+             if ((ctx->scissor_updated) && (ctx->scissor_enabled))
+               {
+                  // Recompute the scissor coordinates
+                  compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h,
+                                         rsc->direct.rot, 1,
+                                         ctx->scissor_coord[0], ctx->scissor_coord[1],
+                                         ctx->scissor_coord[2], ctx->scissor_coord[3],
+                                         rsc->direct.img.x, rsc->direct.img.y,
+                                         rsc->direct.img.w, rsc->direct.img.h,
+                                         rsc->direct.clip.x, rsc->direct.clip.y,
+                                         rsc->direct.clip.w, rsc->direct.clip.h,
+                                         oc, nc, cc);
+
+                  RECTS_CLIP_TO_RECT(nc[0], nc[1], nc[2], nc[3], cc[0], cc[1], cc[2], cc[3]);
+                  glScissor(nc[0], nc[1], nc[2], nc[3]);
+
+                  ctx->direct_scissor = 0;
+
+                  // Compute the viewport coordinate
+                  compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h,
+                                         rsc->direct.rot, 0,
+                                         x, y, width, height,
+                                         rsc->direct.img.x, rsc->direct.img.y,
+                                         rsc->direct.img.w, rsc->direct.img.h,
+                                         rsc->direct.clip.x, rsc->direct.clip.y,
+                                         rsc->direct.clip.w, rsc->direct.clip.h,
+                                         oc, nc, cc);
+                  glViewport(nc[0], nc[1], nc[2], nc[3]);
+               }
+             else
+               {
+
+                  compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h,
+                                         rsc->direct.rot, 0,
+                                         x, y, width, height,
+                                         rsc->direct.img.x, rsc->direct.img.y,
+                                         rsc->direct.img.w, rsc->direct.img.h,
+                                         rsc->direct.clip.x, rsc->direct.clip.y,
+                                         rsc->direct.clip.w, rsc->direct.clip.h,
+                                         oc, nc, cc);
+                  glScissor(cc[0], cc[1], cc[2], cc[3]);
+
+                  glViewport(nc[0], nc[1], nc[2], nc[3]);
+               }
+
+             // Keep a copy of the original coordinates
+             ctx->viewport_coord[0] = x;
+             ctx->viewport_coord[1] = y;
+             ctx->viewport_coord[2] = width;
+             ctx->viewport_coord[3] = height;
+
+             ctx->viewport_updated   = 1;
+          }
+        else
+          {
+             if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+               {
+                  glDisable(GL_SCISSOR_TEST);
+                  ctx->direct_scissor = 0;
+               }
+
+             glViewport(x, y, width, height);
+          }
+     }
+   else
+     {
+        if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+          {
+             glDisable(GL_SCISSOR_TEST);
+             ctx->direct_scissor = 0;
+          }
+
+        glViewport(x, y, width, height);
+     }
+}
+//-------------------------------------------------------------//
+
+
+
+//-------------------------------------------------------------//
+// Debug Evas GL APIs
+//  - GL APIs Overriden for debugging purposes
+//-------------------------------------------------------------//
+
+void
+_evgld_glActiveTexture(GLenum texture)
+{
+   EVGL_FUNC_BEGIN();
+   glActiveTexture(texture);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glAttachShader(GLuint program, GLuint shader)
+{
+   EVGL_FUNC_BEGIN();
+   glAttachShader(program, shader);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glBindAttribLocation(GLuint program, GLuint idx, const char* name)
+{
+   EVGL_FUNC_BEGIN();
+   glBindAttribLocation(program, idx, name);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glBindBuffer(GLenum target, GLuint buffer)
+{
+   EVGL_FUNC_BEGIN();
+   glBindBuffer(target, buffer);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+   EVGL_FUNC_BEGIN();
+
+   _evgl_glBindFramebuffer(target, framebuffer);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+   EVGL_FUNC_BEGIN();
+   glBindRenderbuffer(target, renderbuffer);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glBindTexture(GLenum target, GLuint texture)
+{
+   EVGL_FUNC_BEGIN();
+   glBindTexture(target, texture);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+   EVGL_FUNC_BEGIN();
+   glBlendColor(red, green, blue, alpha);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glBlendEquation(GLenum mode)
+{
+   EVGL_FUNC_BEGIN();
+   glBlendEquation(mode);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+   EVGL_FUNC_BEGIN();
+   glBlendEquationSeparate(modeRGB, modeAlpha);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+   EVGL_FUNC_BEGIN();
+   glBlendFunc(sfactor, dfactor);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+   EVGL_FUNC_BEGIN();
+   glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glBufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage)
+{
+   EVGL_FUNC_BEGIN();
+   glBufferData(target, size, data, usage);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data)
+{
+   EVGL_FUNC_BEGIN();
+   glBufferSubData(target, offset, size, data);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+GLenum
+_evgld_glCheckFramebufferStatus(GLenum target)
+{
+   GLenum ret = GL_NONE;
+
+   EVGL_FUNC_BEGIN();
+   ret = glCheckFramebufferStatus(target);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+void
+_evgld_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+   EVGL_FUNC_BEGIN();
+   _evgl_glClearColor(red, green, blue, alpha);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glClearDepthf(GLclampf depth)
+{
+   EVGL_FUNC_BEGIN();
+
+   _evgl_glClearDepthf(depth);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glClearStencil(GLint s)
+{
+   EVGL_FUNC_BEGIN();
+   glClearStencil(s);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+   EVGL_FUNC_BEGIN();
+   glColorMask(red, green, blue, alpha);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glCompileShader(GLuint shader)
+{
+   EVGL_FUNC_BEGIN();
+   glCompileShader(shader);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
+{
+   EVGL_FUNC_BEGIN();
+   glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
+{
+   EVGL_FUNC_BEGIN();
+   glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+   EVGL_FUNC_BEGIN();
+   glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+   EVGL_FUNC_BEGIN();
+   glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+GLuint
+_evgld_glCreateProgram(void)
+{
+   GLuint ret = _EVGL_INT_INIT_VALUE;
+
+   EVGL_FUNC_BEGIN();
+   ret = glCreateProgram();
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+GLuint
+_evgld_glCreateShader(GLenum type)
+{
+   GLuint ret = _EVGL_INT_INIT_VALUE;
+   EVGL_FUNC_BEGIN();
+   ret = glCreateShader(type);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+void
+_evgld_glCullFace(GLenum mode)
+{
+   EVGL_FUNC_BEGIN();
+   glCullFace(mode);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+   EVGL_FUNC_BEGIN();
+   glDeleteBuffers(n, buffers);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+{
+   EVGL_FUNC_BEGIN();
+   glDeleteFramebuffers(n, framebuffers);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glDeleteProgram(GLuint program)
+{
+   EVGL_FUNC_BEGIN();
+   glDeleteProgram(program);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+{
+   EVGL_FUNC_BEGIN();
+   glDeleteRenderbuffers(n, renderbuffers);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glDeleteShader(GLuint shader)
+{
+   EVGL_FUNC_BEGIN();
+   glDeleteShader(shader);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glDeleteTextures(GLsizei n, const GLuint* textures)
+{
+   EVGL_FUNC_BEGIN();
+   glDeleteTextures(n, textures);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glDepthFunc(GLenum func)
+{
+   EVGL_FUNC_BEGIN();
+   glDepthFunc(func);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glDepthMask(GLboolean flag)
+{
+   EVGL_FUNC_BEGIN();
+   glDepthMask(flag);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+   EVGL_FUNC_BEGIN();
+
+   _evgl_glDepthRangef(zNear, zFar);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glDetachShader(GLuint program, GLuint shader)
+{
+   EVGL_FUNC_BEGIN();
+   glDetachShader(program, shader);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glDisableVertexAttribArray(GLuint idx)
+{
+   EVGL_FUNC_BEGIN();
+   glDisableVertexAttribArray(idx);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+   EVGL_FUNC_BEGIN();
+   glDrawArrays(mode, first, count);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices)
+{
+   EVGL_FUNC_BEGIN();
+   glDrawElements(mode, count, type, indices);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glEnableVertexAttribArray(GLuint idx)
+{
+   EVGL_FUNC_BEGIN();
+   glEnableVertexAttribArray(idx);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glFinish(void)
+{
+   EVGL_FUNC_BEGIN();
+   glFinish();
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glFlush(void)
+{
+   EVGL_FUNC_BEGIN();
+   glFlush();
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+   EVGL_FUNC_BEGIN();
+   glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+   EVGL_FUNC_BEGIN();
+   glFramebufferTexture2D(target, attachment, textarget, texture, level);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glFrontFace(GLenum mode)
+{
+   EVGL_FUNC_BEGIN();
+   glFrontFace(mode);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetVertexAttribfv(GLuint idx, GLenum pname, GLfloat* params)
+{
+   EVGL_FUNC_BEGIN();
+   glGetVertexAttribfv(idx, pname, params);
+
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetVertexAttribiv(GLuint idx, GLenum pname, GLint* params)
+{
+   EVGL_FUNC_BEGIN();
+   glGetVertexAttribiv(idx, pname, params);
+
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetVertexAttribPointerv(GLuint idx, GLenum pname, void** pointer)
+{
+   EVGL_FUNC_BEGIN();
+   glGetVertexAttribPointerv(idx, pname, pointer);
+
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glHint(GLenum target, GLenum mode)
+{
+   EVGL_FUNC_BEGIN();
+   glHint(target, mode);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGenBuffers(GLsizei n, GLuint* buffers)
+{
+   EVGL_FUNC_BEGIN();
+   glGenBuffers(n, buffers);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGenerateMipmap(GLenum target)
+{
+   EVGL_FUNC_BEGIN();
+   glGenerateMipmap(target);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGenFramebuffers(GLsizei n, GLuint* framebuffers)
+{
+   EVGL_FUNC_BEGIN();
+   glGenFramebuffers(n, framebuffers);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+{
+   EVGL_FUNC_BEGIN();
+   glGenRenderbuffers(n, renderbuffers);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGenTextures(GLsizei n, GLuint* textures)
+{
+   EVGL_FUNC_BEGIN();
+   glGenTextures(n, textures);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetActiveAttrib(GLuint program, GLuint idx, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+{
+   EVGL_FUNC_BEGIN();
+   glGetActiveAttrib(program, idx, bufsize, length, size, type, name);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetActiveUniform(GLuint program, GLuint idx, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+{
+   EVGL_FUNC_BEGIN();
+   glGetActiveUniform(program, idx, bufsize, length, size, type, name);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+{
+   EVGL_FUNC_BEGIN();
+   glGetAttachedShaders(program, maxcount, count, shaders);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+int
+_evgld_glGetAttribLocation(GLuint program, const char* name)
+{
+   int ret = _EVGL_INT_INIT_VALUE;
+   EVGL_FUNC_BEGIN();
+   ret = glGetAttribLocation(program, name);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+void
+_evgld_glGetBooleanv(GLenum pname, GLboolean* params)
+{
+   EVGL_FUNC_BEGIN();
+   glGetBooleanv(pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+   EVGL_FUNC_BEGIN();
+   glGetBufferParameteriv(target, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+GLenum
+_evgld_glGetError(void)
+{
+   GLenum ret = GL_NONE;
+
+   EVGL_FUNC_BEGIN();
+   ret = glGetError();
+   EVGL_FUNC_END();
+   return ret;
+}
+
+void
+_evgld_glGetFloatv(GLenum pname, GLfloat* params)
+{
+   EVGL_FUNC_BEGIN();
+   glGetFloatv(pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+   EVGL_FUNC_BEGIN();
+   glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetProgramiv(GLuint program, GLenum pname, GLint* params)
+{
+   EVGL_FUNC_BEGIN();
+   glGetProgramiv(program, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog)
+{
+   EVGL_FUNC_BEGIN();
+   glGetProgramInfoLog(program, bufsize, length, infolog);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+   EVGL_FUNC_BEGIN();
+   glGetRenderbufferParameteriv(target, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+{
+   EVGL_FUNC_BEGIN();
+   glGetShaderiv(shader, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog)
+{
+   EVGL_FUNC_BEGIN();
+   glGetShaderInfoLog(shader, bufsize, length, infolog);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+   EVGL_FUNC_BEGIN();
+
+   _evgl_glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source)
+{
+   EVGL_FUNC_BEGIN();
+   glGetShaderSource(shader, bufsize, length, source);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+const GLubyte *
+_evgld_glGetString(GLenum name)
+{
+   const GLubyte *ret = NULL;
+
+   EVGL_FUNC_BEGIN();
+#if 0
+   if (name == GL_EXTENSIONS)
+      return (GLubyte *)_gl_ext_string; //glGetString(GL_EXTENSIONS);
+   else
+      return glGetString(name);
+#endif
+   ret = _evgl_glGetString(name);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+void
+_evgld_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
+{
+   EVGL_FUNC_BEGIN();
+   glGetTexParameterfv(target, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+   EVGL_FUNC_BEGIN();
+   glGetTexParameteriv(target, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetUniformfv(GLuint program, GLint location, GLfloat* params)
+{
+   EVGL_FUNC_BEGIN();
+   glGetUniformfv(program, location, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetUniformiv(GLuint program, GLint location, GLint* params)
+{
+   EVGL_FUNC_BEGIN();
+   glGetUniformiv(program, location, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+int
+_evgld_glGetUniformLocation(GLuint program, const char* name)
+{
+   int ret = _EVGL_INT_INIT_VALUE;
+
+   EVGL_FUNC_BEGIN();
+   ret = glGetUniformLocation(program, name);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+GLboolean
+_evgld_glIsBuffer(GLuint buffer)
+{
+   GLboolean ret = GL_FALSE;
+
+   EVGL_FUNC_BEGIN();
+   ret = glIsBuffer(buffer);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+GLboolean
+_evgld_glIsEnabled(GLenum cap)
+{
+   GLboolean ret = GL_FALSE;
+
+   EVGL_FUNC_BEGIN();
+   ret = glIsEnabled(cap);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+GLboolean
+_evgld_glIsFramebuffer(GLuint framebuffer)
+{
+   GLboolean ret = GL_FALSE;
+
+   EVGL_FUNC_BEGIN();
+   ret = glIsFramebuffer(framebuffer);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+GLboolean
+_evgld_glIsProgram(GLuint program)
+{
+   GLboolean ret;
+   EVGL_FUNC_BEGIN();
+   ret = glIsProgram(program);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+GLboolean
+_evgld_glIsRenderbuffer(GLuint renderbuffer)
+{
+   GLboolean ret;
+   EVGL_FUNC_BEGIN();
+   ret = glIsRenderbuffer(renderbuffer);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+GLboolean
+_evgld_glIsShader(GLuint shader)
+{
+   GLboolean ret;
+   EVGL_FUNC_BEGIN();
+   ret = glIsShader(shader);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+GLboolean
+_evgld_glIsTexture(GLuint texture)
+{
+   GLboolean ret;
+   EVGL_FUNC_BEGIN();
+   ret = glIsTexture(texture);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+void
+_evgld_glLineWidth(GLfloat width)
+{
+   EVGL_FUNC_BEGIN();
+   glLineWidth(width);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glLinkProgram(GLuint program)
+{
+   EVGL_FUNC_BEGIN();
+   glLinkProgram(program);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glPixelStorei(GLenum pname, GLint param)
+{
+   EVGL_FUNC_BEGIN();
+   glPixelStorei(pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glPolygonOffset(GLfloat factor, GLfloat units)
+{
+   EVGL_FUNC_BEGIN();
+   glPolygonOffset(factor, units);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glReleaseShaderCompiler(void)
+{
+   EVGL_FUNC_BEGIN();
+
+   _evgl_glReleaseShaderCompiler();
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+   EVGL_FUNC_BEGIN();
+   glRenderbufferStorage(target, internalformat, width, height);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glSampleCoverage(GLclampf value, GLboolean invert)
+{
+   EVGL_FUNC_BEGIN();
+   glSampleCoverage(value, invert);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length)
+{
+   EVGL_FUNC_BEGIN();
+
+   _evgl_glShaderBinary(n, shaders, binaryformat, binary, length);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length)
+{
+   EVGL_FUNC_BEGIN();
+#ifdef GL_GLES
+   glShaderSource(shader, count, (const GLchar * const *) string, length);
+#else
+   glShaderSource(shader, count, (const GLchar **) string, length);
+#endif
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+   EVGL_FUNC_BEGIN();
+   glStencilFunc(func, ref, mask);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+   EVGL_FUNC_BEGIN();
+   glStencilFuncSeparate(face, func, ref, mask);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glStencilMask(GLuint mask)
+{
+   EVGL_FUNC_BEGIN();
+   glStencilMask(mask);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glStencilMaskSeparate(GLenum face, GLuint mask)
+{
+   EVGL_FUNC_BEGIN();
+   glStencilMaskSeparate(face, mask);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+   EVGL_FUNC_BEGIN();
+   glStencilOp(fail, zfail, zpass);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+   EVGL_FUNC_BEGIN();
+   glStencilOpSeparate(face, fail, zfail, zpass);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels)
+{
+   EVGL_FUNC_BEGIN();
+   glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+   EVGL_FUNC_BEGIN();
+   glTexParameterf(target, pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
+{
+   EVGL_FUNC_BEGIN();
+   glTexParameterfv(target, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+   EVGL_FUNC_BEGIN();
+   glTexParameteri(target, pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
+{
+   EVGL_FUNC_BEGIN();
+   glTexParameteriv(target, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels)
+{
+   EVGL_FUNC_BEGIN();
+   glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniform1f(GLint location, GLfloat x)
+{
+   EVGL_FUNC_BEGIN();
+   glUniform1f(location, x);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+   EVGL_FUNC_BEGIN();
+   glUniform1fv(location, count, v);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniform1i(GLint location, GLint x)
+{
+   EVGL_FUNC_BEGIN();
+   glUniform1i(location, x);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniform1iv(GLint location, GLsizei count, const GLint* v)
+{
+   EVGL_FUNC_BEGIN();
+   glUniform1iv(location, count, v);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniform2f(GLint location, GLfloat x, GLfloat y)
+{
+   EVGL_FUNC_BEGIN();
+   glUniform2f(location, x, y);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
+{
+   EVGL_FUNC_BEGIN();
+   glUniform2fv(location, count, v);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniform2i(GLint location, GLint x, GLint y)
+{
+   EVGL_FUNC_BEGIN();
+   glUniform2i(location, x, y);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniform2iv(GLint location, GLsizei count, const GLint* v)
+{
+   EVGL_FUNC_BEGIN();
+   glUniform2iv(location, count, v);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+   EVGL_FUNC_BEGIN();
+   glUniform3f(location, x, y, z);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
+{
+   EVGL_FUNC_BEGIN();
+   glUniform3fv(location, count, v);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniform3i(GLint location, GLint x, GLint y, GLint z)
+{
+   EVGL_FUNC_BEGIN();
+   glUniform3i(location, x, y, z);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniform3iv(GLint location, GLsizei count, const GLint* v)
+{
+   EVGL_FUNC_BEGIN();
+   glUniform3iv(location, count, v);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+   EVGL_FUNC_BEGIN();
+   glUniform4f(location, x, y, z, w);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
+{
+   EVGL_FUNC_BEGIN();
+   glUniform4fv(location, count, v);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+   EVGL_FUNC_BEGIN();
+   glUniform4i(location, x, y, z, w);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniform4iv(GLint location, GLsizei count, const GLint* v)
+{
+   EVGL_FUNC_BEGIN();
+   glUniform4iv(location, count, v);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+   EVGL_FUNC_BEGIN();
+   glUniformMatrix2fv(location, count, transpose, value);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+   EVGL_FUNC_BEGIN();
+   glUniformMatrix3fv(location, count, transpose, value);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+   EVGL_FUNC_BEGIN();
+   glUniformMatrix4fv(location, count, transpose, value);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glUseProgram(GLuint program)
+{
+   EVGL_FUNC_BEGIN();
+   glUseProgram(program);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glValidateProgram(GLuint program)
+{
+   EVGL_FUNC_BEGIN();
+   glValidateProgram(program);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glVertexAttrib1f(GLuint indx, GLfloat x)
+{
+   EVGL_FUNC_BEGIN();
+   glVertexAttrib1f(indx, x);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glVertexAttrib1fv(GLuint indx, const GLfloat* values)
+{
+   EVGL_FUNC_BEGIN();
+   glVertexAttrib1fv(indx, values);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
+{
+   EVGL_FUNC_BEGIN();
+   glVertexAttrib2f(indx, x, y);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glVertexAttrib2fv(GLuint indx, const GLfloat* values)
+{
+   EVGL_FUNC_BEGIN();
+   glVertexAttrib2fv(indx, values);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+{
+   EVGL_FUNC_BEGIN();
+   glVertexAttrib3f(indx, x, y, z);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glVertexAttrib3fv(GLuint indx, const GLfloat* values)
+{
+   EVGL_FUNC_BEGIN();
+   glVertexAttrib3fv(indx, values);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+   EVGL_FUNC_BEGIN();
+   glVertexAttrib4f(indx, x, y, z, w);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glVertexAttrib4fv(GLuint indx, const GLfloat* values)
+{
+   EVGL_FUNC_BEGIN();
+   glVertexAttrib4fv(indx, values);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
+{
+   EVGL_FUNC_BEGIN();
+   glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+//-------------------------------------------------------------//
+// Calls for stripping precision string in the shader
+#if 0
+
+static const char *
+opengl_strtok(const char *s, int *n, char **saveptr, char *prevbuf)
+{
+   char *start;
+   char *ret;
+   char *p;
+   int retlen;
+   static const char *delim = " \t\n\r/";
+
+   if (prevbuf)
+      free(prevbuf);
+
+   if (s)
+     {
+        *saveptr = s;
+     }
+   else
+     {
+        if (!(*saveptr) || !(*n))
+           return NULL;
+        s = *saveptr;
+     }
+
+   for (; *n && strchr(delim, *s); s++, (*n)--)
+     {
+        if (*s == '/' && *n > 1)
+          {
+             if (s[1] == '/')
+               {
+                  do {
+                       s++, (*n)--;
+                  } while (*n > 1 && s[1] != '\n' && s[1] != '\r');
+               }
+             else if (s[1] == '*')
+               {
+                  do {
+                       s++, (*n)--;
+                  } while (*n > 2 && (s[1] != '*' || s[2] != '/'));
+                  s++, (*n)--;
+                  s++, (*n)--;
+                  if (*n == 0)
+                    {
+                       break;
+                    }
+               }
+             else
+               {
+                  break;
+               }
+          }
+     }
+
+   start = s;
+   for (; *n && *s && !strchr(delim, *s); s++, (*n)--);
+   if (*n > 0)
+      s++, (*n)--;
+
+   *saveptr = s;
+
+   retlen = s - start;
+   ret = malloc(retlen + 1);
+   p = ret;
+
+   if (retlen == 0)
+     {
+        *p = 0;
+        return;
+     }
+
+   while (retlen > 0)
+     {
+        if (*start == '/' && retlen > 1)
+          {
+             if (start[1] == '/')
+               {
+                  do {
+                       start++, retlen--;
+                  } while (retlen > 1 && start[1] != '\n' && start[1] != '\r');
+                  start++, retlen--;
+                  continue;
+               } else if (start[1] == '*')
+                 {
+                    do {
+                         start++, retlen--;
+                    } while (retlen > 2 && (start[1] != '*' || start[2] != '/'));
+                    start += 3, retlen -= 3;
+                    continue;
+                 }
+          }
+        *(p++) = *(start++), retlen--;
+     }
+
+   *p = 0;
+   return ret;
+}
+
+static char *
+do_eglShaderPatch(const char *source, int length, int *patched_len)
+{
+   char *saveptr = NULL;
+   char *sp;
+   char *p = NULL;
+
+   if (!length) length = strlen(source);
+
+   *patched_len = 0;
+   int patched_size = length;
+   char *patched = malloc(patched_size + 1);
+
+   if (!patched) return NULL;
+
+   p = opengl_strtok(source, &length, &saveptr, NULL);
+
+   for (; p; p = opengl_strtok(0, &length, &saveptr, p))
+     {
+        if (!strncmp(p, "lowp", 4) || !strncmp(p, "mediump", 7) || !strncmp(p, "highp", 5))
+          {
+             continue;
+          }
+        else if (!strncmp(p, "precision", 9))
+          {
+             while ((p = opengl_strtok(0, &length, &saveptr, p)) && !strchr(p, ';'));
+          }
+        else
+          {
+             if (!strncmp(p, "gl_MaxVertexUniformVectors", 26))
+               {
+                  p = "(gl_MaxVertexUniformComponents / 4)";
+               }
+             else if (!strncmp(p, "gl_MaxFragmentUniformVectors", 28))
+               {
+                  p = "(gl_MaxFragmentUniformComponents / 4)";
+               }
+             else if (!strncmp(p, "gl_MaxVaryingVectors", 20))
+               {
+                  p = "(gl_MaxVaryingFloats / 4)";
+               }
+
+             int new_len = strlen(p);
+             if (*patched_len + new_len > patched_size)
+               {
+                  patched_size *= 2;
+                  patched = realloc(patched, patched_size + 1);
+
+                  if (!patched) return NULL;
+               }
+
+             memcpy(patched + *patched_len, p, new_len);
+             *patched_len += new_len;
+          }
+     }
+
+   patched[*patched_len] = 0;
+   /* check that we don't leave dummy preprocessor lines */
+   for (sp = patched; *sp;)
+     {
+        for (; *sp == ' ' || *sp == '\t'; sp++);
+        if (!strncmp(sp, "#define", 7))
+          {
+             for (p = sp + 7; *p == ' ' || *p == '\t'; p++);
+             if (*p == '\n' || *p == '\r' || *p == '/')
+               {
+                  memset(sp, 0x20, 7);
+               }
+          }
+        for (; *sp && *sp != '\n' && *sp != '\r'; sp++);
+        for (; *sp == '\n' || *sp == '\r'; sp++);
+     }
+   return patched;
+}
+
+static int
+shadersrc_gles_to_gl(GLsizei count, const char** string, char **s, const GLint* length, GLint *l)
+{
+   int i;
+
+   for(i = 0; i < count; ++i) {
+        GLint len;
+        if(length) {
+             len = length[i];
+             if (len < 0)
+                len = string[i] ? strlen(string[i]) : 0;
+        } else
+           len = string[i] ? strlen(string[i]) : 0;
+
+        if(string[i]) {
+             s[i] = do_eglShaderPatch(string[i], len, &l[i]);
+             if(!s[i]) {
+                  while(i)
+                     free(s[--i]);
+
+                  free(l);
+                  free(s);
+                  return -1;
+             }
+        } else {
+             s[i] = NULL;
+             l[i] = 0;
+        }
+   }
+
+   return 0;
+}
+
+
+void
+_evgld_glShaderSource(GLuint shader, GLsizei count, const char* const* string, const GLint* length)
+{
+   EVGL_FUNC_BEGIN();
+
+#ifdef GL_GLES
+   glShaderSource(shader, count, string, length);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   goto finish;
+#else
+   //GET_EXT_PTR(void, glShaderSource, (int, int, char **, void *));
+   int size = count;
+   int i;
+   int acc_length = 0;
+   GLchar **tab_prog = malloc(size * sizeof(GLchar *));
+   int *tab_length = (int *) length;
+
+   char **tab_prog_new;
+   GLint *tab_length_new;
+
+   tab_prog_new = malloc(count* sizeof(char*));
+   tab_length_new = malloc(count* sizeof(GLint));
+
+   memset(tab_prog_new, 0, count * sizeof(char*));
+   memset(tab_length_new, 0, count * sizeof(GLint));
+
+   for (i = 0; i < size; i++) {
+        tab_prog[i] = ((GLchar *) string) + acc_length;
+        acc_length += tab_length[i];
+   }
+
+   shadersrc_gles_to_gl(count, tab_prog, tab_prog_new, tab_length, tab_length_new);
+
+   if (!tab_prog_new || !tab_length_new)
+      ERR("Error allocating memory for shader string manipulation.");
+
+   glShaderSource(shader, count, tab_prog_new, tab_length_new);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+   for (i = 0; i < count; i++)
+      free(tab_prog_new[i]);
+   free(tab_prog_new);
+   free(tab_length_new);
+
+   free(tab_prog);
+#endif
+
+finish:
+   EVGL_FUNC_END();
+}
+#endif
+
+//-------------------------------------------------------------//
+
+
+//-------------------------------------------------------------//
+// Calls related to Evas GL Direct Rendering
+//-------------------------------------------------------------//
+static void
+_evgld_glClear(GLbitfield mask)
+{
+   EVGL_FUNC_BEGIN();
+
+   _evgl_glClear(mask);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_glEnable(GLenum cap)
+{
+   EVGL_FUNC_BEGIN();
+
+   _evgl_glEnable(cap);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_glDisable(GLenum cap)
+{
+   EVGL_FUNC_BEGIN();
+
+   _evgl_glDisable(cap);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+void
+_evgld_glGetIntegerv(GLenum pname, GLint* params)
+{
+   EVGL_FUNC_BEGIN();
+   _evgl_glGetIntegerv(pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
+{
+   EVGL_FUNC_BEGIN();
+
+   _evgl_glReadPixels(x, y, width, height, format, type, pixels);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+   EVGL_FUNC_BEGIN();
+
+   _evgl_glScissor(x, y, width, height);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+   EVGL_FUNC_BEGIN();
+
+   _evgl_glViewport(x, y, width, height);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+//-------------------------------------------------------------//
+
+static void
+_normal_gl_api_get(Evas_GL_API *funcs)
+{
+   funcs->version = EVAS_GL_API_VERSION;
+
+#define ORD(f) EVAS_API_OVERRIDE(f, funcs,)
+   // GLES 2.0
+   ORD(glActiveTexture);
+   ORD(glAttachShader);
+   ORD(glBindAttribLocation);
+   ORD(glBindBuffer);
+   ORD(glBindTexture);
+   ORD(glBlendColor);
+   ORD(glBlendEquation);
+   ORD(glBlendEquationSeparate);
+   ORD(glBlendFunc);
+   ORD(glBlendFuncSeparate);
+   ORD(glBufferData);
+   ORD(glBufferSubData);
+   ORD(glCheckFramebufferStatus);
+//   ORD(glClear);
+//   ORD(glClearColor);
+//   ORD(glClearDepthf);
+   ORD(glClearStencil);
+   ORD(glColorMask);
+   ORD(glCompileShader);
+   ORD(glCompressedTexImage2D);
+   ORD(glCompressedTexSubImage2D);
+   ORD(glCopyTexImage2D);
+   ORD(glCopyTexSubImage2D);
+   ORD(glCreateProgram);
+   ORD(glCreateShader);
+   ORD(glCullFace);
+   ORD(glDeleteBuffers);
+   ORD(glDeleteFramebuffers);
+   ORD(glDeleteProgram);
+   ORD(glDeleteRenderbuffers);
+   ORD(glDeleteShader);
+   ORD(glDeleteTextures);
+   ORD(glDepthFunc);
+   ORD(glDepthMask);
+//   ORD(glDepthRangef);
+   ORD(glDetachShader);
+//   ORD(glDisable);
+   ORD(glDisableVertexAttribArray);
+   ORD(glDrawArrays);
+   ORD(glDrawElements);
+//   ORD(glEnable);
+   ORD(glEnableVertexAttribArray);
+   ORD(glFinish);
+   ORD(glFlush);
+   ORD(glFramebufferRenderbuffer);
+   ORD(glFramebufferTexture2D);
+   ORD(glFrontFace);
+   ORD(glGenBuffers);
+   ORD(glGenerateMipmap);
+   ORD(glGenFramebuffers);
+   ORD(glGenRenderbuffers);
+   ORD(glGenTextures);
+   ORD(glGetActiveAttrib);
+   ORD(glGetActiveUniform);
+   ORD(glGetAttachedShaders);
+   ORD(glGetAttribLocation);
+   ORD(glGetBooleanv);
+   ORD(glGetBufferParameteriv);
+   ORD(glGetError);
+   ORD(glGetFloatv);
+   ORD(glGetFramebufferAttachmentParameteriv);
+//   ORD(glGetIntegerv);
+   ORD(glGetProgramiv);
+   ORD(glGetProgramInfoLog);
+   ORD(glGetRenderbufferParameteriv);
+   ORD(glGetShaderiv);
+   ORD(glGetShaderInfoLog);
+//   ORD(glGetShaderPrecisionFormat);
+   ORD(glGetShaderSource);
+//   ORD(glGetString);
+   ORD(glGetTexParameterfv);
+   ORD(glGetTexParameteriv);
+   ORD(glGetUniformfv);
+   ORD(glGetUniformiv);
+   ORD(glGetUniformLocation);
+   ORD(glGetVertexAttribfv);
+   ORD(glGetVertexAttribiv);
+   ORD(glGetVertexAttribPointerv);
+   ORD(glHint);
+   ORD(glIsBuffer);
+   ORD(glIsEnabled);
+   ORD(glIsFramebuffer);
+   ORD(glIsProgram);
+   ORD(glIsRenderbuffer);
+   ORD(glIsShader);
+   ORD(glIsTexture);
+   ORD(glLineWidth);
+   ORD(glLinkProgram);
+   ORD(glPixelStorei);
+   ORD(glPolygonOffset);
+//   ORD(glReadPixels);
+//   ORD(glReleaseShaderCompiler);
+   ORD(glRenderbufferStorage);
+   ORD(glSampleCoverage);
+//   ORD(glScissor);
+//   ORD(glShaderBinary);
+// Deal with double glShaderSource signature
+   funcs->glShaderSource = (void (*)(GLuint, GLsizei, const char **, const GLint *))glShaderSource;
+   ORD(glStencilFunc);
+   ORD(glStencilFuncSeparate);
+   ORD(glStencilMask);
+   ORD(glStencilMaskSeparate);
+   ORD(glStencilOp);
+   ORD(glStencilOpSeparate);
+   ORD(glTexImage2D);
+   ORD(glTexParameterf);
+   ORD(glTexParameterfv);
+   ORD(glTexParameteri);
+   ORD(glTexParameteriv);
+   ORD(glTexSubImage2D);
+   ORD(glUniform1f);
+   ORD(glUniform1fv);
+   ORD(glUniform1i);
+   ORD(glUniform1iv);
+   ORD(glUniform2f);
+   ORD(glUniform2fv);
+   ORD(glUniform2i);
+   ORD(glUniform2iv);
+   ORD(glUniform3f);
+   ORD(glUniform3fv);
+   ORD(glUniform3i);
+   ORD(glUniform3iv);
+   ORD(glUniform4f);
+   ORD(glUniform4fv);
+   ORD(glUniform4i);
+   ORD(glUniform4iv);
+   ORD(glUniformMatrix2fv);
+   ORD(glUniformMatrix3fv);
+   ORD(glUniformMatrix4fv);
+   ORD(glUseProgram);
+   ORD(glValidateProgram);
+   ORD(glVertexAttrib1f);
+   ORD(glVertexAttrib1fv);
+   ORD(glVertexAttrib2f);
+   ORD(glVertexAttrib2fv);
+   ORD(glVertexAttrib3f);
+   ORD(glVertexAttrib3fv);
+   ORD(glVertexAttrib4f);
+   ORD(glVertexAttrib4fv);
+   ORD(glVertexAttribPointer);
+//   ORD(glViewport);
+
+//   ORD(glBindFramebuffer);
+   ORD(glBindRenderbuffer);
+#undef ORD
+
+
+#define ORD(f) EVAS_API_OVERRIDE(f, funcs, _evgl_)
+
+   // General purpose wrapper
+   ORD(glGetString);
+
+   // For Surface FBO
+   ORD(glBindFramebuffer);
+
+   // For Direct Rendering
+   ORD(glClear);
+   ORD(glClearColor);
+   ORD(glDisable);
+   ORD(glEnable);
+   ORD(glGetIntegerv);
+   ORD(glReadPixels);
+   ORD(glScissor);
+   ORD(glViewport);
+
+   // GLES 2 Compat for Desktop
+   ORD(glClearDepthf);
+   ORD(glDepthRangef);
+   ORD(glGetShaderPrecisionFormat);
+   ORD(glShaderBinary);
+   ORD(glReleaseShaderCompiler);
+
+#undef ORD
+
+   evgl_api_ext_get(funcs);
+}
+
+static void
+_direct_scissor_off_api_get(Evas_GL_API *funcs)
+{
+
+#define ORD(f) EVAS_API_OVERRIDE(f, funcs,)
+   // For Direct Rendering
+   ORD(glClear);
+   ORD(glClearColor);
+   ORD(glDisable);
+   ORD(glEnable);
+   ORD(glGetIntegerv);
+   ORD(glReadPixels);
+   ORD(glScissor);
+   ORD(glViewport);
+#undef ORD
+}
+
+
+static void
+_debug_gl_api_get(Evas_GL_API *funcs)
+{
+   funcs->version = EVAS_GL_API_VERSION;
+
+#define ORD(f) EVAS_API_OVERRIDE(f, funcs, _evgld_)
+   // GLES 2.0
+   ORD(glActiveTexture);
+   ORD(glAttachShader);
+   ORD(glBindAttribLocation);
+   ORD(glBindBuffer);
+   ORD(glBindTexture);
+   ORD(glBlendColor);
+   ORD(glBlendEquation);
+   ORD(glBlendEquationSeparate);
+   ORD(glBlendFunc);
+   ORD(glBlendFuncSeparate);
+   ORD(glBufferData);
+   ORD(glBufferSubData);
+   ORD(glCheckFramebufferStatus);
+   ORD(glClear);
+   ORD(glClearColor);
+   ORD(glClearDepthf);
+   ORD(glClearStencil);
+   ORD(glColorMask);
+   ORD(glCompileShader);
+   ORD(glCompressedTexImage2D);
+   ORD(glCompressedTexSubImage2D);
+   ORD(glCopyTexImage2D);
+   ORD(glCopyTexSubImage2D);
+   ORD(glCreateProgram);
+   ORD(glCreateShader);
+   ORD(glCullFace);
+   ORD(glDeleteBuffers);
+   ORD(glDeleteFramebuffers);
+   ORD(glDeleteProgram);
+   ORD(glDeleteRenderbuffers);
+   ORD(glDeleteShader);
+   ORD(glDeleteTextures);
+   ORD(glDepthFunc);
+   ORD(glDepthMask);
+   ORD(glDepthRangef);
+   ORD(glDetachShader);
+   ORD(glDisable);
+   ORD(glDisableVertexAttribArray);
+   ORD(glDrawArrays);
+   ORD(glDrawElements);
+   ORD(glEnable);
+   ORD(glEnableVertexAttribArray);
+   ORD(glFinish);
+   ORD(glFlush);
+   ORD(glFramebufferRenderbuffer);
+   ORD(glFramebufferTexture2D);
+   ORD(glFrontFace);
+   ORD(glGenBuffers);
+   ORD(glGenerateMipmap);
+   ORD(glGenFramebuffers);
+   ORD(glGenRenderbuffers);
+   ORD(glGenTextures);
+   ORD(glGetActiveAttrib);
+   ORD(glGetActiveUniform);
+   ORD(glGetAttachedShaders);
+   ORD(glGetAttribLocation);
+   ORD(glGetBooleanv);
+   ORD(glGetBufferParameteriv);
+   ORD(glGetError);
+   ORD(glGetFloatv);
+   ORD(glGetFramebufferAttachmentParameteriv);
+   ORD(glGetIntegerv);
+   ORD(glGetProgramiv);
+   ORD(glGetProgramInfoLog);
+   ORD(glGetRenderbufferParameteriv);
+   ORD(glGetShaderiv);
+   ORD(glGetShaderInfoLog);
+   ORD(glGetShaderPrecisionFormat);
+   ORD(glGetShaderSource);
+   ORD(glGetString);
+   ORD(glGetTexParameterfv);
+   ORD(glGetTexParameteriv);
+   ORD(glGetUniformfv);
+   ORD(glGetUniformiv);
+   ORD(glGetUniformLocation);
+   ORD(glGetVertexAttribfv);
+   ORD(glGetVertexAttribiv);
+   ORD(glGetVertexAttribPointerv);
+   ORD(glHint);
+   ORD(glIsBuffer);
+   ORD(glIsEnabled);
+   ORD(glIsFramebuffer);
+   ORD(glIsProgram);
+   ORD(glIsRenderbuffer);
+   ORD(glIsShader);
+   ORD(glIsTexture);
+   ORD(glLineWidth);
+   ORD(glLinkProgram);
+   ORD(glPixelStorei);
+   ORD(glPolygonOffset);
+   ORD(glReadPixels);
+   ORD(glReleaseShaderCompiler);
+   ORD(glRenderbufferStorage);
+   ORD(glSampleCoverage);
+   ORD(glScissor);
+   ORD(glShaderBinary);
+   ORD(glShaderSource);
+   ORD(glStencilFunc);
+   ORD(glStencilFuncSeparate);
+   ORD(glStencilMask);
+   ORD(glStencilMaskSeparate);
+   ORD(glStencilOp);
+   ORD(glStencilOpSeparate);
+   ORD(glTexImage2D);
+   ORD(glTexParameterf);
+   ORD(glTexParameterfv);
+   ORD(glTexParameteri);
+   ORD(glTexParameteriv);
+   ORD(glTexSubImage2D);
+   ORD(glUniform1f);
+   ORD(glUniform1fv);
+   ORD(glUniform1i);
+   ORD(glUniform1iv);
+   ORD(glUniform2f);
+   ORD(glUniform2fv);
+   ORD(glUniform2i);
+   ORD(glUniform2iv);
+   ORD(glUniform3f);
+   ORD(glUniform3fv);
+   ORD(glUniform3i);
+   ORD(glUniform3iv);
+   ORD(glUniform4f);
+   ORD(glUniform4fv);
+   ORD(glUniform4i);
+   ORD(glUniform4iv);
+   ORD(glUniformMatrix2fv);
+   ORD(glUniformMatrix3fv);
+   ORD(glUniformMatrix4fv);
+   ORD(glUseProgram);
+   ORD(glValidateProgram);
+   ORD(glVertexAttrib1f);
+   ORD(glVertexAttrib1fv);
+   ORD(glVertexAttrib2f);
+   ORD(glVertexAttrib2fv);
+   ORD(glVertexAttrib3f);
+   ORD(glVertexAttrib3fv);
+   ORD(glVertexAttrib4f);
+   ORD(glVertexAttrib4fv);
+   ORD(glVertexAttribPointer);
+   ORD(glViewport);
+
+   ORD(glBindFramebuffer);
+   ORD(glBindRenderbuffer);
+#undef ORD
+
+   evgl_api_ext_get(funcs);
+}
+
+void
+_evgl_api_get(Evas_GL_API *funcs, Eina_Bool debug)
+{
+   if (debug)
+     _debug_gl_api_get(funcs);
+   else
+      _normal_gl_api_get(funcs);
+
+   if (evgl_engine->direct_scissor_off)
+     _direct_scissor_off_api_get(funcs);
+}
diff --git a/src/modules/engines/gl_common/evas_gl_api_ext.c b/src/modules/engines/gl_common/evas_gl_api_ext.c
new file mode 100755 (executable)
index 0000000..88be480
--- /dev/null
@@ -0,0 +1,764 @@
+
+#include "evas_gl_api_ext.h"
+
+#include <dlfcn.h>
+
+
+#define MAX_EXTENSION_STRING_BUFFER 10240
+
+// list of exts like "discard_framebuffer GL_EXT_discard_framebuffer multi_draw_arrays GL_EXT_multi_draw_arrays"
+char _gl_ext_string[MAX_EXTENSION_STRING_BUFFER] = { 0 };
+// list of exts by official name only like "GL_EXT_discard_framebuffer GL_EXT_multi_draw_arrays"
+char _gl_ext_string_official[MAX_EXTENSION_STRING_BUFFER] = { 0 };
+// list of gles 1.1 exts by official name
+static char *_gles1_ext_string = NULL;
+
+typedef void (*_getproc_fn) (void);
+typedef _getproc_fn (*fp_getproc)(const char *);
+
+#ifndef EGL_NATIVE_PIXMAP_KHR
+# define EGL_NATIVE_PIXMAP_KHR 0x30b0
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Extension HEADER
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+#define _EVASGL_EXT_CHECK_SUPPORT(name)
+#define _EVASGL_EXT_DISCARD_SUPPORT()
+#define _EVASGL_EXT_BEGIN(name)
+#define _EVASGL_EXT_END()
+#define _EVASGL_EXT_DRVNAME(name)
+#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param) \
+   ret (*gl_ext_sym_##name) param = NULL; \
+   ret (*gles1_ext_sym_##name) param = NULL;
+#define _EVASGL_EXT_FUNCTION_END()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
+#define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
+#define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
+
+#include "evas_gl_api_ext_def.h"
+
+#undef _EVASGL_EXT_CHECK_SUPPORT
+#undef _EVASGL_EXT_DISCARD_SUPPORT
+#undef _EVASGL_EXT_BEGIN
+#undef _EVASGL_EXT_END
+#undef _EVASGL_EXT_DRVNAME
+#undef _EVASGL_EXT_FUNCTION_BEGIN
+#undef _EVASGL_EXT_FUNCTION_END
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Extension HEADER
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+#define _EVASGL_EXT_CHECK_SUPPORT(name)
+#define _EVASGL_EXT_DISCARD_SUPPORT()
+#define _EVASGL_EXT_BEGIN(name) \
+   int _gl_ext_support_##name = 0; \
+   int _gles1_ext_support_##name = 0;
+#define _EVASGL_EXT_END()
+#define _EVASGL_EXT_DRVNAME(name)
+#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param)
+#define _EVASGL_EXT_FUNCTION_END()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
+#define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
+#define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
+
+#include "evas_gl_api_ext_def.h"
+
+#undef _EVASGL_EXT_CHECK_SUPPORT
+#undef _EVASGL_EXT_DISCARD_SUPPORT
+#undef _EVASGL_EXT_BEGIN
+#undef _EVASGL_EXT_END
+#undef _EVASGL_EXT_DRVNAME
+#undef _EVASGL_EXT_FUNCTION_BEGIN
+#undef _EVASGL_EXT_FUNCTION_END
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+// Evas extensions from EGL extensions
+#ifdef GL_GLES
+#define EGLDISPLAY_GET() _evgl_egl_display_get(__FUNCTION__)
+static EGLDisplay
+_evgl_egl_display_get(const char *function)
+{
+   EGLDisplay dpy = EGL_NO_DISPLAY;
+   EVGL_Resource *rsc;
+
+   if (!(rsc=_evgl_tls_resource_get()))
+     {
+        ERR("%s: Unable to execute GL command. Error retrieving tls", function);
+        _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+        return EGL_NO_DISPLAY;
+     }
+
+   if (!rsc->current_eng)
+     {
+        ERR("%s: Unable to retrive Current Engine", function);
+        _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+        return EGL_NO_DISPLAY;
+     }
+
+   if ((evgl_engine) && (evgl_engine->funcs->display_get))
+     {
+        dpy = (EGLDisplay)evgl_engine->funcs->display_get(rsc->current_eng);
+        return dpy;
+     }
+   else
+     {
+        ERR("%s: Invalid Engine... (Can't acccess EGL Display)\n", function);
+        _evgl_error_set(EVAS_GL_BAD_DISPLAY);
+        return EGL_NO_DISPLAY;
+     }
+}
+
+static void *
+_evgl_eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx,
+                        int target, void* buffer, const int *attrib_list)
+{
+   int *attribs = NULL;
+
+   /* Convert 0 terminator into a EGL_NONE terminator */
+   if (attrib_list)
+     {
+        int cnt = 0;
+        int *a;
+
+        for (a = (int *) attrib_list; (*a) && (*a != EGL_NONE); a += 2)
+          {
+             /* TODO: Verify supported attributes */
+             cnt += 2;
+          }
+
+        attribs = alloca(sizeof(int) * (cnt + 1));
+        for (a = attribs; (*attrib_list) && (*attrib_list != EGL_NONE);
+             a += 2, attrib_list += 2)
+          {
+             a[0] = attrib_list[0];
+             a[1] = attrib_list[1];
+          }
+        *a = EGL_NONE;
+     }
+
+   return EXT_FUNC(eglCreateImage)(dpy, ctx, target, buffer, attribs);
+}
+
+static void *
+evgl_evasglCreateImage(int target, void* buffer, const int *attrib_list)
+{
+   EGLDisplay dpy = EGLDISPLAY_GET();
+   EGLContext ctx = EGL_NO_CONTEXT;
+
+   if (!dpy) return NULL;
+
+   /* EGL_NO_CONTEXT will always fail for TEXTURE_2D */
+   if (target == EVAS_GL_TEXTURE_2D)
+     {
+        ctx = eglGetCurrentContext();
+        INF("Creating EGL image based on the current context: %p", ctx);
+     }
+
+   return _evgl_eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
+}
+
+static void *
+evgl_evasglCreateImageForContext(Evas_GL *evasgl EINA_UNUSED, Evas_GL_Context *evasctx,
+                                 int target, void* buffer, const int *attrib_list)
+{
+   EGLDisplay dpy = EGLDISPLAY_GET();
+   EGLContext ctx = EGL_NO_CONTEXT;
+
+   if (!evasgl || !dpy) return NULL;
+
+   ctx = evgl_context_native_get(evasctx);
+   return _evgl_eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
+}
+
+static void
+evgl_evasglDestroyImage(EvasGLImage image)
+{
+   EGLDisplay dpy = EGLDISPLAY_GET();
+   if (!dpy) return;
+   EXT_FUNC(eglDestroyImage)(dpy, image);
+}
+
+static void
+evgl_glEvasGLImageTargetTexture2D(GLenum target, EvasGLImage image)
+{
+   EXT_FUNC(glEGLImageTargetTexture2DOES)(target, image);
+}
+
+static void
+evgl_glEvasGLImageTargetRenderbufferStorage(GLenum target, EvasGLImage image)
+{
+   EXT_FUNC(glEGLImageTargetRenderbufferStorageOES)(target, image);
+}
+
+static EvasGLSync
+evgl_evasglCreateSync(Evas_GL *evas_gl EINA_UNUSED,
+                      unsigned int type, const int *attrib_list)
+{
+   EGLDisplay dpy = EGLDISPLAY_GET();
+   if (!dpy) return NULL;
+   return EXT_FUNC(eglCreateSyncKHR)(dpy, type, attrib_list);
+}
+
+static Eina_Bool
+evgl_evasglDestroySync(Evas_GL *evas_gl EINA_UNUSED, EvasGLSync sync)
+{
+   EGLDisplay dpy = EGLDISPLAY_GET();
+   if (!dpy) return EINA_FALSE;
+   return EXT_FUNC(eglDestroySyncKHR)(dpy, sync);
+}
+
+static int
+evgl_evasglClientWaitSync(Evas_GL *evas_gl EINA_UNUSED,
+                          EvasGLSync sync, int flags, EvasGLTime timeout)
+{
+   EGLDisplay dpy = EGLDISPLAY_GET();
+   if (!dpy) return EINA_FALSE;
+   return EXT_FUNC(eglClientWaitSyncKHR)(dpy, sync, flags, timeout);
+}
+
+static Eina_Bool
+evgl_evasglSignalSync(Evas_GL *evas_gl EINA_UNUSED,
+                      EvasGLSync sync, unsigned mode)
+{
+   EGLDisplay dpy = EGLDISPLAY_GET();
+   if (!dpy) return EINA_FALSE;
+   return EXT_FUNC(eglSignalSyncKHR)(dpy, sync, mode);
+}
+
+static Eina_Bool
+evgl_evasglGetSyncAttrib(Evas_GL *evas_gl EINA_UNUSED,
+                         EvasGLSync sync, int attribute, int *value)
+{
+   EGLDisplay dpy = EGLDISPLAY_GET();
+   if (!dpy) return EINA_FALSE;
+   return EXT_FUNC(eglGetSyncAttribKHR)(dpy, sync, attribute, value);
+}
+
+static int
+evgl_evasglWaitSync(Evas_GL *evas_gl EINA_UNUSED,
+                    EvasGLSync sync, int flags)
+{
+   EGLDisplay dpy = EGLDISPLAY_GET();
+   if (!dpy) return EINA_FALSE;
+   return EXT_FUNC(eglWaitSyncKHR)(dpy, sync, flags);
+}
+
+
+#else
+#endif
+
+// 0: not initialized, 1: GLESv2 initialized, 2: GLESv1 also initialized
+static int _evgl_api_ext_status = 0;
+
+Eina_Bool
+evgl_api_ext_init(void *getproc, const char *glueexts)
+{
+   const char *glexts;
+
+   fp_getproc gp = (fp_getproc)getproc;
+   int _curext_supported = 0;
+
+   memset(_gl_ext_string, 0x00, MAX_EXTENSION_STRING_BUFFER);
+   memset(_gl_ext_string_official, 0x00, MAX_EXTENSION_STRING_BUFFER);
+
+   // GLES Extensions
+   glexts = (const char*)glGetString(GL_EXTENSIONS);
+   if (!glexts)
+     {
+        ERR("glGetString returned NULL! Something is very wrong...");
+        return EINA_FALSE;
+     }
+
+   /*
+   // GLUE Extensions
+#ifdef GL_GLES
+getproc = &eglGetProcAddress;
+glueexts = eglQueryString(re->win->egl_disp, EGL_EXTENSIONS);
+#else
+getproc = &glXGetProcAddress;
+glueexts = glXQueryExtensionsString(re->info->info.display,
+re->info->info.screen);
+#endif
+    */
+
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Extension HEADER
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+#define GETPROCADDR(sym) \
+   (((!(*drvfunc)) && (gp)) ? (__typeof__((*drvfunc)))gp(sym) : (__typeof__((*drvfunc)))dlsym(RTLD_DEFAULT, sym))
+
+#define _EVASGL_EXT_BEGIN(name) \
+     { \
+        int *ext_support = &_gl_ext_support_##name; \
+        *ext_support = 0;
+
+#define _EVASGL_EXT_END() \
+     }
+
+#define _EVASGL_EXT_CHECK_SUPPORT(name) \
+   (strstr(glexts, name) != NULL || strstr(glueexts, name) != NULL)
+
+#define _EVASGL_EXT_DISCARD_SUPPORT() \
+   *ext_support = 0;
+
+#define _EVASGL_EXT_DRVNAME(name) \
+   if (_EVASGL_EXT_CHECK_SUPPORT(#name)) *ext_support = 1;
+
+#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param) \
+     { \
+        ret (**drvfunc)param = &gl_ext_sym_##name; \
+        if (*ext_support == 1) \
+          {
+
+#define _EVASGL_EXT_FUNCTION_END() \
+          } \
+        if ((*drvfunc) == NULL) _EVASGL_EXT_DISCARD_SUPPORT(); \
+     }
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
+#define _EVASGL_EXT_FUNCTION_DRVFUNC(name) \
+   if ((*drvfunc) == NULL) *drvfunc = name;
+
+// This adds all the function names to the "safe" list but only one pointer
+// will be stored in the hash table.
+#define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name) \
+   if ((*drvfunc) == NULL) \
+     { \
+        *drvfunc = GETPROCADDR(name); \
+        evgl_safe_extension_add(name, (void *) (*drvfunc)); \
+     } \
+   else evgl_safe_extension_add(name, NULL);
+
+#ifdef _EVASGL_EXT_FUNCTION_WHITELIST
+# undef _EVASGL_EXT_FUNCTION_WHITELIST
+#endif
+#define _EVASGL_EXT_FUNCTION_WHITELIST(name) evgl_safe_extension_add(name, NULL);
+//#define _EVASGL_EXT_VERIFY
+
+#include "evas_gl_api_ext_def.h"
+
+//#undef _EVASGL_EXT_VERIFY
+#undef _EVASGL_EXT_FUNCTION_WHITELIST
+#undef _EVASGL_EXT_CHECK_SUPPORT
+#undef _EVASGL_EXT_DISCARD_SUPPORT
+#undef _EVASGL_EXT_BEGIN
+#undef _EVASGL_EXT_END
+#undef _EVASGL_EXT_DRVNAME
+#undef _EVASGL_EXT_FUNCTION_BEGIN
+#undef _EVASGL_EXT_FUNCTION_END
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
+
+#undef GETPROCADDR
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+       _gl_ext_string[0] = 0x00; //NULL;
+       _gl_ext_string_official[0] = 0x00;
+
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Extension HEADER
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+#define _EVASGL_EXT_BEGIN(name) \
+     if (_gl_ext_support_##name != 0) \
+       { \
+          strncat(_gl_ext_string, #name" ", MAX_EXTENSION_STRING_BUFFER); \
+          _curext_supported = 1; \
+       } \
+     else _curext_supported = 0;
+#define _EVASGL_EXT_END()
+#define _EVASGL_EXT_CHECK_SUPPORT(name)
+#define _EVASGL_EXT_DISCARD_SUPPORT()
+#define _EVASGL_EXT_DRVNAME_PRINT(name) \
+       { \
+          strncat(_gl_ext_string, name" ", MAX_EXTENSION_STRING_BUFFER); \
+          if ((strncmp(name, "GL", 2) == 0) && (strstr(_gl_ext_string_official, name) == NULL)) \
+            strncat(_gl_ext_string_official, name" ", MAX_EXTENSION_STRING_BUFFER); \
+       }
+#define _EVASGL_EXT_DRVNAME(name) \
+     if (_curext_supported) \
+       _EVASGL_EXT_DRVNAME_PRINT(#name)
+#define _EVASGL_EXT_DRVNAME_PRIVATE(name) \
+     if (_curext_supported && _gl_ext_support_func_##name) \
+       _EVASGL_EXT_DRVNAME_PRINT(#name)
+#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param)
+#define _EVASGL_EXT_FUNCTION_END()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
+#define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
+#define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
+
+#include "evas_gl_api_ext_def.h"
+
+#undef _EVASGL_EXT_CHECK_SUPPORT
+#undef _EVASGL_EXT_DISCARD_SUPPORT
+#undef _EVASGL_EXT_BEGIN
+#undef _EVASGL_EXT_END
+#undef _EVASGL_EXT_DRVNAME_PRINT
+#undef _EVASGL_EXT_DRVNAME
+#undef _EVASGL_EXT_FUNCTION_BEGIN
+#undef _EVASGL_EXT_FUNCTION_END
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+   _gl_ext_string[MAX_EXTENSION_STRING_BUFFER - 1] = '\0';
+   _gl_ext_string_official[MAX_EXTENSION_STRING_BUFFER - 1] = '\0';
+
+
+   _evgl_api_ext_status = 1;
+   return EINA_TRUE;
+}
+
+void
+evgl_api_ext_get(Evas_GL_API *gl_funcs)
+{
+   if (_evgl_api_ext_status < 1)
+     {
+        ERR("EVGL extension is not yet initialized.");
+        return;
+     }
+
+#define ORD(f) EVAS_API_OVERRIDE(f, gl_funcs, gl_ext_sym_)
+
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Extension HEADER
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+#define _EVASGL_EXT_CHECK_SUPPORT(name)
+#define _EVASGL_EXT_DISCARD_SUPPORT()
+#define _EVASGL_EXT_BEGIN(name) \
+   if (_gl_ext_support_##name != 0) \
+     {
+#define _EVASGL_EXT_END() \
+     }
+#define _EVASGL_EXT_DRVNAME(name)
+#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param) \
+   ORD(name);
+#define _EVASGL_EXT_FUNCTION_END()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
+#define _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(ret, name, param)
+#define _EVASGL_EXT_FUNCTION_PRIVATE_END()
+#define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
+#define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
+
+#undef _EVASGL_EXT_WHITELIST_ONLY
+#define _EVASGL_EXT_WHITELIST_ONLY 0
+
+#include "evas_gl_api_ext_def.h"
+
+#undef _EVASGL_EXT_WHITELIST_ONLY
+#undef _EVASGL_EXT_CHECK_SUPPORT
+#undef _EVASGL_EXT_DISCARD_SUPPORT
+#undef _EVASGL_EXT_BEGIN
+#undef _EVASGL_EXT_END
+#undef _EVASGL_EXT_DRVNAME
+#undef _EVASGL_EXT_FUNCTION_BEGIN
+#undef _EVASGL_EXT_FUNCTION_END
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
+#undef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN
+#undef _EVASGL_EXT_FUNCTION_PRIVATE_END
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+#undef ORD
+
+}
+
+Eina_Bool
+_evgl_api_gles1_ext_init(void)
+{
+   if (_evgl_api_ext_status >= 2)
+     return EINA_TRUE;
+
+#ifdef GL_GLES
+   int _curext_supported = 0;
+   Evas_GL_API *gles1_funcs;
+   const char *gles1_exts;
+   EVGL_Resource *rsc;
+   EGLint context_version;
+   EGLDisplay dpy = EGL_NO_DISPLAY;
+
+   /* glGetString returns the information for the currently bound context
+    * So, update gles1_exts only if GLES1 context is currently bound.
+    * Check here if GLESv1 is current
+    */
+   if (!(rsc=_evgl_tls_resource_get()))
+     {
+        ERR("Unable to initialize GLES1 extensions. Error retrieving tls");
+        return EINA_FALSE;
+     }
+
+   if (rsc->current_eng)
+      dpy = EGLDISPLAY_GET();
+
+   if ((dpy == EGL_NO_DISPLAY) || !rsc->current_ctx)
+     {
+        DBG("Unable to initialize GLES1 extensions. Engine not initialised");
+        return EINA_FALSE;
+     }
+
+   if (!eglQueryContext(dpy, rsc->current_ctx->context, EGL_CONTEXT_CLIENT_VERSION, &context_version))
+     {
+        ERR("Unable to initialize GLES1 extensions. eglQueryContext failed 0x%x", eglGetError());
+        return EINA_FALSE;
+     }
+
+   if (context_version != EVAS_GL_GLES_1_X)
+     {
+        DBG("GLESv1 context not bound");
+        return EINA_FALSE;
+     }
+
+   gles1_funcs = _evgl_api_gles1_internal_get();
+   if (!gles1_funcs || !gles1_funcs->glGetString)
+     {
+        ERR("Could not get address of glGetString in GLESv1 library!");
+        return EINA_FALSE;
+     }
+
+   gles1_exts = (const char *) gles1_funcs->glGetString(GL_EXTENSIONS);
+   if (!gles1_exts)
+     {
+        ERR("GLESv1:glGetString(GL_EXTENSIONS) returned NULL!");
+        return EINA_FALSE;
+     }
+
+   if (!_gles1_ext_string)
+     {
+        _gles1_ext_string = calloc(MAX_EXTENSION_STRING_BUFFER, 1);
+        if (!_gles1_ext_string) return EINA_FALSE;
+     }
+
+   _gles1_ext_string[0] = '\0';
+
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Scanning supported extensions, sets the variables
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+   // Preparing all the magic macros
+#define GETPROCADDR(sym) \
+   ((__typeof__((*drvfunc))) (eglGetProcAddress(sym)))
+
+#define _EVASGL_EXT_BEGIN(name) \
+   { \
+      int *ext_support = &_gles1_ext_support_##name; \
+      *ext_support = 0;
+
+#define _EVASGL_EXT_END() \
+   }
+
+#define _EVASGL_EXT_CHECK_SUPPORT(name) \
+   (strstr(gles1_exts, name) != NULL)
+
+#define _EVASGL_EXT_DISCARD_SUPPORT() \
+   *ext_support = 0;
+
+#define _EVASGL_EXT_DRVNAME(name) \
+   if (_EVASGL_EXT_CHECK_SUPPORT(#name)) *ext_support = 1;
+
+#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param) \
+     { \
+        ret (**drvfunc)param = &gles1_ext_sym_##name; \
+        if (*ext_support == 1) \
+          {
+
+#define _EVASGL_EXT_FUNCTION_END() \
+          } \
+        if ((*drvfunc) == NULL) _EVASGL_EXT_DISCARD_SUPPORT(); \
+     }
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN() \
+   if (EINA_FALSE) \
+     {
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END() \
+     }
+#define _EVASGL_EXT_FUNCTION_DRVFUNC(name) \
+   if ((*drvfunc) == NULL) *drvfunc = name;
+
+#define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name) \
+   if ((*drvfunc) == NULL) \
+     { \
+        *drvfunc = GETPROCADDR(name); \
+        evgl_safe_extension_add(name, (void *) (*drvfunc)); \
+     } \
+   else evgl_safe_extension_add(name, NULL);
+
+#ifdef _EVASGL_EXT_FUNCTION_WHITELIST
+# undef _EVASGL_EXT_FUNCTION_WHITELIST
+#endif
+#define _EVASGL_EXT_FUNCTION_WHITELIST(name) evgl_safe_extension_add(name, NULL);
+
+#define _EVASGL_EXT_GLES1_ONLY 1
+
+   // Okay, now we are ready to scan.
+#include "evas_gl_api_ext_def.h"
+
+#undef _EVASGL_EXT_GLES1_ONLY
+#undef _EVASGL_EXT_FUNCTION_WHITELIST
+#undef _EVASGL_EXT_CHECK_SUPPORT
+#undef _EVASGL_EXT_DISCARD_SUPPORT
+#undef _EVASGL_EXT_BEGIN
+#undef _EVASGL_EXT_END
+#undef _EVASGL_EXT_DRVNAME
+#undef _EVASGL_EXT_FUNCTION_BEGIN
+#undef _EVASGL_EXT_FUNCTION_END
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
+#undef GETPROCADDR
+
+#define _EVASGL_EXT_BEGIN(name) \
+     _curext_supported = (_gles1_ext_support_##name != 0);
+
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Scanning again to add to the gles1 ext string list
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define _EVASGL_EXT_END()
+#define _EVASGL_EXT_CHECK_SUPPORT(name)
+#define _EVASGL_EXT_DISCARD_SUPPORT()
+#define _EVASGL_EXT_DRVNAME_PRINT(name) \
+     { \
+        if ((strncmp(name, "GL", 2) == 0) && (strstr(_gles1_ext_string, name) == NULL)) \
+          strcat(_gles1_ext_string, name" "); \
+     }
+#define _EVASGL_EXT_DRVNAME(name) \
+   if (_curext_supported) \
+      _EVASGL_EXT_DRVNAME_PRINT(#name)
+#define _EVASGL_EXT_DRVNAME_PRIVATE(name) \
+   if (_curext_supported && _gles1_ext_support_func_##name) \
+      _EVASGL_EXT_DRVNAME_PRINT(#name)
+#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param)
+#define _EVASGL_EXT_FUNCTION_END()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
+#define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
+#define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
+
+#include "evas_gl_api_ext_def.h"
+
+#undef _EVASGL_EXT_CHECK_SUPPORT
+#undef _EVASGL_EXT_DISCARD_SUPPORT
+#undef _EVASGL_EXT_BEGIN
+#undef _EVASGL_EXT_END
+#undef _EVASGL_EXT_DRVNAME_PRINT
+#undef _EVASGL_EXT_DRVNAME
+#undef _EVASGL_EXT_FUNCTION_BEGIN
+#undef _EVASGL_EXT_FUNCTION_END
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
+
+   if (evgl_engine->api_debug_mode)
+     DBG("GLES1: List of supported extensions:\n%s", _gles1_ext_string);
+
+   // Both GLES versions have been initialized!
+   _evgl_api_ext_status = 2;
+   return EINA_TRUE;
+#else
+   ERR("GLESv1 support is not implemented for GLX");
+   return EINA_FALSE;
+#endif
+}
+
+void
+evgl_api_gles1_ext_get(Evas_GL_API *gl_funcs)
+{
+   if (_evgl_api_ext_status < 1)
+     {
+        ERR("EVGL extension is not yet initialized.");
+        return;
+     }
+
+   if (_evgl_api_ext_status < 2)
+     {
+        DBG("Initializing GLESv1 extensions...");
+        if (!_evgl_api_gles1_ext_init())
+          {
+             ERR("GLESv1 extensions initialization failed");
+             return;
+          }
+     }
+
+#define ORD(f) EVAS_API_OVERRIDE(f, gl_funcs, gles1_ext_sym_)
+
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Extension HEADER
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+#define _EVASGL_EXT_CHECK_SUPPORT(name)
+#define _EVASGL_EXT_DISCARD_SUPPORT()
+#define _EVASGL_EXT_BEGIN(name) \
+   if (_gles1_ext_support_##name != 0) \
+     {
+#define _EVASGL_EXT_END() \
+     }
+#define _EVASGL_EXT_DRVNAME(name)
+#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param) \
+   ORD(name);
+#define _EVASGL_EXT_FUNCTION_END()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
+#define _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(ret, name, param)
+#define _EVASGL_EXT_FUNCTION_PRIVATE_END()
+#define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
+#define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
+
+#undef _EVASGL_EXT_WHITELIST_ONLY
+#define _EVASGL_EXT_WHITELIST_ONLY 0
+
+#include "evas_gl_api_ext_def.h"
+
+#undef _EVASGL_EXT_CHECK_SUPPORT
+#undef _EVASGL_EXT_DISCARD_SUPPORT
+#undef _EVASGL_EXT_BEGIN
+#undef _EVASGL_EXT_END
+#undef _EVASGL_EXT_DRVNAME
+#undef _EVASGL_EXT_FUNCTION_BEGIN
+#undef _EVASGL_EXT_FUNCTION_END
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
+#undef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN
+#undef _EVASGL_EXT_FUNCTION_PRIVATE_END
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+#undef ORD
+
+}
+const char *
+evgl_api_ext_string_get(Eina_Bool official, Eina_Bool gles1)
+{
+   if (_evgl_api_ext_status < 1)
+     {
+        ERR("EVGL extension is not yet initialized.");
+        return NULL;
+     }
+
+   if (gles1) // only official.
+     return _gles1_ext_string;
+
+   if (official)
+     return _gl_ext_string_official;
+
+   return _gl_ext_string;
+}
diff --git a/src/modules/engines/gl_common/evas_gl_api_ext.h b/src/modules/engines/gl_common/evas_gl_api_ext.h
new file mode 100644 (file)
index 0000000..53394ee
--- /dev/null
@@ -0,0 +1,88 @@
+#ifndef _EVAS_GL_API_EXT_H
+#define _EVAS_GL_API_EXT_H
+
+#include "evas_gl_core_private.h"
+
+#ifdef GL_GLES
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+typedef char GLchar;           //!!!Temporary measure for Emulator
+#else
+# include <GL/glext.h>
+# include <GL/glx.h>
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Extension HEADER
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+#define _EVASGL_EXT_CHECK_SUPPORT(name)
+#define _EVASGL_EXT_DISCARD_SUPPORT()
+#define _EVASGL_EXT_BEGIN(name)
+#define _EVASGL_EXT_END()
+#define _EVASGL_EXT_DRVNAME(name)
+#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param) extern ret (*gl_ext_sym_##name) param;
+#define _EVASGL_EXT_FUNCTION_END()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
+#define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
+#define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
+
+#include "evas_gl_api_ext_def.h"
+
+#undef _EVASGL_EXT_CHECK_SUPPORT
+#undef _EVASGL_EXT_DISCARD_SUPPORT
+#undef _EVASGL_EXT_BEGIN
+#undef _EVASGL_EXT_END
+#undef _EVASGL_EXT_DRVNAME
+#undef _EVASGL_EXT_FUNCTION_BEGIN
+#undef _EVASGL_EXT_FUNCTION_END
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+#define EXT_FUNC(fname) gl_ext_sym_##fname
+#define EXT_FUNC_GLES1(fname) gles1_ext_sym_##fname
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Extension HEADER
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+#define _EVASGL_EXT_CHECK_SUPPORT(name)
+#define _EVASGL_EXT_DISCARD_SUPPORT()
+#define _EVASGL_EXT_BEGIN(name) \
+   extern int _gl_ext_support_##name; \
+   extern int _gles1_ext_support_##name;
+#define _EVASGL_EXT_END()
+#define _EVASGL_EXT_DRVNAME(name)
+#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param)
+#define _EVASGL_EXT_FUNCTION_END()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
+#define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
+#define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
+
+#include "evas_gl_api_ext_def.h"
+
+#undef _EVASGL_EXT_CHECK_SUPPORT
+#undef _EVASGL_EXT_DISCARD_SUPPORT
+#undef _EVASGL_EXT_BEGIN
+#undef _EVASGL_EXT_END
+#undef _EVASGL_EXT_DRVNAME
+#undef _EVASGL_EXT_FUNCTION_BEGIN
+#undef _EVASGL_EXT_FUNCTION_END
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
+#undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+#define EXTENSION_SUPPORT(name) (_gl_ext_support_##name == 1)
+#define EXTENSION_SUPPORT_GLES1(name) (_gles1_ext_support_##name == 1)
+
+extern Eina_Bool evgl_api_ext_init(void *getproc, const char *glueexts);
+extern void evgl_api_ext_get(Evas_GL_API *gl_funcs);
+extern void evgl_api_gles1_ext_get(Evas_GL_API *gl_funcs);
+extern const char *
+   evgl_api_ext_string_get(Eina_Bool official, Eina_Bool gles1);
+
+#endif //_EVAS_GL_API_EXT_H
+
diff --git a/src/modules/engines/gl_common/evas_gl_api_ext_def.h b/src/modules/engines/gl_common/evas_gl_api_ext_def.h
new file mode 100644 (file)
index 0000000..a1696ac
--- /dev/null
@@ -0,0 +1,1731 @@
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+#ifndef _EVASGL_EXT_BEGIN
+
+#define _EVASGL_EXT_USE_DEFAULT_DEFINE
+
+#define _EVASGL_EXT_CHECK_SUPPORT(name)
+#define _EVASGL_EXT_DISCARD_SUPPORT()
+
+// Begin of the extension block (name : EVAS extension name)
+#define _EVASGL_EXT_BEGIN(name)
+// End of the extension block
+#define _EVASGL_EXT_END()
+
+// Driver extensions to wrap (name : SPEC extension name)
+#define _EVASGL_EXT_DRVNAME(name)
+
+// These functions will be exported to 'EVAS extension function'.
+// The functions of this block must correspond with the functions list in Evas_GL.h.
+// Begin of the extension function block (ret : return value, name : function name, param : parameters with bracket)
+#define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param) ret (*name) param;
+// End of the extension function block
+#define _EVASGL_EXT_FUNCTION_END()
+
+// These functions will not be exported. Only be used in engines privately.
+// Begin of the extension function block (ret : return value, name : function name, param : parameters with bracket)
+#define _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(ret, name, param)
+// End of the extension function block
+#define _EVASGL_EXT_FUNCTION_PRIVATE_END()
+
+// These functions will not be considered for export for GLESv1
+// Begin of the glesv1 bypass function block
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
+// End of the glesv1 bypass function block
+#define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
+
+// Driver extension functions to wrap (name : SPEC extension function name)
+#define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
+
+// Driver extension functions that need no wrapping
+#define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
+
+#endif
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN
+#define _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(ret, name, param) _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param)
+#define _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN_DEFINED
+#endif
+
+#ifndef _EVASGL_EXT_FUNCTION_PRIVATE_END
+#define _EVASGL_EXT_FUNCTION_PRIVATE_END() _EVASGL_EXT_FUNCTION_END()
+#define _EVASGL_EXT_FUNCTION_PRIVATE_END_DEFINED
+#endif
+
+#ifndef _EVASGL_EXT_WHITELIST_ONLY
+# define _EVASGL_EXT_WHITELIST_ONLY 1
+#endif
+
+#ifndef _EVASGL_EXT_FUNCTION_WHITELIST
+# define _EVASGL_EXT_FUNCTION_WHITELIST(name)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// GL/GLES EXTENSIONS
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+_EVASGL_EXT_BEGIN(get_program_binary)
+       _EVASGL_EXT_DRVNAME(GL_OES_get_program_binary)
+
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glGetProgramBinaryOES, (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetProgramBinary")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetProgramBinaryOES")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glProgramBinaryOES, (GLuint program, GLenum binaryFormat, const void *binary, GLint length))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glProgramBinary")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glProgramBinaryOES")
+       _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(mapbuffer)
+       _EVASGL_EXT_DRVNAME(GL_OES_mapbuffer)
+
+       _EVASGL_EXT_FUNCTION_BEGIN(void *, glMapBufferOES, (GLenum target, GLenum access))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMapBuffer")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMapBufferOES")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(GLboolean, glUnmapBufferOES, (GLenum target))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glUnmapBuffer")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glUnmapBufferOES")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glGetBufferPointervOES, (GLenum target, GLenum pname, void** params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetBufferPointerv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetBufferPointervOES")
+       _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(texture_3D)
+       _EVASGL_EXT_DRVNAME(GL_OES_texture_3D)
+
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glTexImage3DOES, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexImage3D")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexImage3DOES")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexSubImage3D")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexSubImage3DOES")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glCopyTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glCopyTexSubImage3D")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glCopyTexSubImage3DOES")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glCompressedTexImage3DOES, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glCompressedTexImage3D")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glCompressedTexImage3DOES")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glCompressedTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glCompressedTexSubImage3D")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glCompressedTexSubImage3DOES")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glFramebufferTexture3DOES, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFramebufferTexture3D")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFramebufferTexture3DOES")
+       _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(AMD_performance_monitor)
+       _EVASGL_EXT_DRVNAME(GL_AMD_performance_monitor)
+
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glGetPerfMonitorGroupsAMD, (GLint* numGroups, GLsizei groupsSize, GLuint* groups))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetPerfMonitorGroupsAMD")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glGetPerfMonitorCountersAMD, (GLuint group, GLint* numCounters, GLint* maxActiveCounters, GLsizei counterSize, GLuint* counters))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetPerfMonitorCountersAMD")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glGetPerfMonitorGroupStringAMD, (GLuint group, GLsizei bufSize, GLsizei* length, char* groupString))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetPerfMonitorGroupStringAMD")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glGetPerfMonitorCounterStringAMD, (GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, char* counterString))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetPerfMonitorCounterStringAMD")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glGetPerfMonitorCounterInfoAMD, (GLuint group, GLuint counter, GLenum pname, void* data))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetPerfMonitorCounterInfoAMD")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glGenPerfMonitorsAMD, (GLsizei n, GLuint* monitors))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGenPerfMonitorsAMD")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glDeletePerfMonitorsAMD, (GLsizei n, GLuint* monitors))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDeletePerfMonitorsAMD")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glSelectPerfMonitorCountersAMD, (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* countersList))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glSelectPerfMonitorCountersAMD")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glBeginPerfMonitorAMD, (GLuint monitor))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glBeginPerfMonitorAMD")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glEndPerfMonitorAMD, (GLuint monitor))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glEndPerfMonitorAMD")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glGetPerfMonitorCounterDataAMD, (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint* bytesWritten))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetPerfMonitorCounterDataAMD")
+       _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(discard_framebuffer)
+       _EVASGL_EXT_DRVNAME(GL_EXT_discard_framebuffer)
+
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glDiscardFramebufferEXT, (GLenum target, GLsizei numAttachments, const GLenum* attachments))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDiscardFramebuffer")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDiscardFramebufferEXT")
+       _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(multi_draw_arrays)
+       _EVASGL_EXT_DRVNAME(GL_EXT_multi_draw_arrays)
+
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glMultiDrawArraysEXT, (GLenum mode, GLint* first, GLsizei* count, GLsizei primcount))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMultiDrawArrays")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMultiDrawArraysEXT")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glMultiDrawElementsEXT, (GLenum mode, const GLsizei* count, GLenum type, const GLvoid** indices, GLsizei primcount))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMultiDrawElements")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMultiDrawElementsEXT")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMultiDrawElementsARB")
+       _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(NV_fence)
+       _EVASGL_EXT_DRVNAME(GL_NV_fence)
+
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glDeleteFencesNV, (GLsizei n, const GLuint* fences))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDeleteFencesNV")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glGenFencesNV, (GLsizei n, GLuint* fences))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGenFencesNV")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(unsigned char, glIsFenceNV, (GLuint fence))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glIsFenceNV")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(unsigned char, glTestFenceNV, (GLuint fence))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTestFenceNV")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glGetFenceivNV, (GLuint fence, GLenum pname, GLint* params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetFenceivNV")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glFinishFenceNV, (GLuint fence))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFinishFenceNV")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glSetFenceNV, (GLuint, GLenum))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glSetFenceNV")
+       _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(QCOM_driver_control)
+       _EVASGL_EXT_DRVNAME(GL_QCOM_driver_control)
+
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glGetDriverControlsQCOM, (GLint* num, GLsizei size, GLuint* driverControls))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetDriverControlsQCOM")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glGetDriverControlStringQCOM, (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetDriverControlStringQCOM")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glEnableDriverControlQCOM, (GLuint driverControl))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glEnableDriverControlQCOM")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glDisableDriverControlQCOM, (GLuint driverControl))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDisableDriverControlQCOM")
+       _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(QCOM_extended_get)
+       _EVASGL_EXT_DRVNAME(GL_QCOM_extended_get)
+
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetTexturesQCOM, (GLuint* textures, GLint maxTextures, GLint* numTextures))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glExtGetTexturesQCOM")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetBuffersQCOM, (GLuint* buffers, GLint maxBuffers, GLint* numBuffers))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glExtGetBuffersQCOM")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetRenderbuffersQCOM, (GLuint* renderbuffers, GLint maxRenderbuffers, GLint* numRenderbuffers))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glExtGetRenderbuffersQCOM")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetFramebuffersQCOM, (GLuint* framebuffers, GLint maxFramebuffers, GLint* numFramebuffers))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glExtGetFramebuffersQCOM")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetTexLevelParameterivQCOM, (GLuint texture, GLenum face, GLint level, GLenum pname, GLint* params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glExtGetTexLevelParameterivQCOM")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glExtTexObjectStateOverrideiQCOM, (GLenum target, GLenum pname, GLint param))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glExtTexObjectStateOverrideiQCOM")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetTexSubImageQCOM, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void* texels))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glExtGetTexSubImageQCOM")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetBufferPointervQCOM, (GLenum target, void** params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glExtGetBufferPointervQCOM")
+       _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(QCOM_extended_get2)
+       _EVASGL_EXT_DRVNAME(GL_QCOM_extended_get2)
+
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetShadersQCOM, (GLuint* shaders, GLint maxShaders, GLint* numShaders))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glExtGetShadersQCOM")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetProgramsQCOM, (GLuint* programs, GLint maxPrograms, GLint* numPrograms))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glExtGetProgramsQCOM")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(unsigned char, glExtIsProgramBinaryQCOM, (GLuint program))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glExtIsProgramBinaryQCOM")
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glExtGetProgramBinarySourceQCOM, (GLuint program, GLenum shadertype, char* source, GLint* length))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glExtGetProgramBinarySourceQCOM")
+       _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(IMG_multisampled_render_to_texture)
+       _EVASGL_EXT_DRVNAME(GL_IMG_multisampled_render_to_texture)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(EXT_multisampled_render_to_texture)
+       _EVASGL_EXT_DRVNAME(GL_EXT_multisampled_render_to_texture)
+
+        /* GLES 1.x extension */
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glRenderbufferStorageMultisampleEXT, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glRenderbufferStorageMultisample")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glRenderbufferStorageMultisampleEXT")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glFramebufferTexture2DMultisampleEXT, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFramebufferTexture2DMultisample")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFramebufferTexture2DMultisampleEXT")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(multisampled_render_to_texture)
+       _EVASGL_EXT_DRVNAME(GL_IMG_multisampled_render_to_texture)
+       _EVASGL_EXT_DRVNAME(GL_EXT_multisampled_render_to_texture)
+
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void, glRenderbufferStorageMultisample, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glRenderbufferStorageMultisample")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glRenderbufferStorageMultisampleIMG")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glRenderbufferStorageMultisampleEXT")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void, glFramebufferTexture2DMultisample, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFramebufferTexture2DMultisample")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFramebufferTexture2DMultisampleIMG")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFramebufferTexture2DMultisampleEXT")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+_EVASGL_EXT_END()
+
+/* ETC1 compressed texture format support */
+_EVASGL_EXT_BEGIN(compressed_ETC1_RGB8_texture)
+        _EVASGL_EXT_DRVNAME(GL_OES_compressed_ETC1_RGB8_texture)
+_EVASGL_EXT_END()
+
+/* SubImage texture upload support for ETC1*/
+_EVASGL_EXT_BEGIN(compressed_ETC1_RGB8_sub_texture)
+        _EVASGL_EXT_DRVNAME(GL_EXT_compressed_ETC1_RGB8_sub_texture)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(compressed_ETC2_RGB8_texture)
+        _EVASGL_EXT_DRVNAME(GL_OES_compressed_ETC2_RGB8_texture)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(compressed_paletted_texture)
+       _EVASGL_EXT_DRVNAME(GL_OES_compressed_paletted_texture)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(depth24)
+       _EVASGL_EXT_DRVNAME(GL_OES_depth24)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(depth32)
+       _EVASGL_EXT_DRVNAME(GL_OES_depth32)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(EGL_image)
+       _EVASGL_EXT_DRVNAME(GL_OES_EvasGL_image)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(packed_depth_stencil)
+       _EVASGL_EXT_DRVNAME(GL_OES_packed_depth_stencil)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(rgb8_rgba8)
+       _EVASGL_EXT_DRVNAME(GL_OES_rgb8_rgba8)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(standard_derivatives)
+       _EVASGL_EXT_DRVNAME(GL_OES_standard_derivatives)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(stencil1)
+       _EVASGL_EXT_DRVNAME(GL_OES_stencil1)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(stencil4)
+       _EVASGL_EXT_DRVNAME(GL_OES_stencil4)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(texture_float)
+       _EVASGL_EXT_DRVNAME(GL_OES_texture_float)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(texture_half_float)
+       _EVASGL_EXT_DRVNAME(GL_OES_texture_half_float)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(texture_float_linear)
+        _EVASGL_EXT_DRVNAME(GL_OES_texture_float_linear)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(texture_half_float_linear)
+       _EVASGL_EXT_DRVNAME(GL_OES_texture_half_float_linear)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(texture_npot)     // Desktop differs
+       _EVASGL_EXT_DRVNAME(GL_OES_texture_npot)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(texture_npot_DESKTOP)     // Desktop differs
+       _EVASGL_EXT_DRVNAME(GL_OES_texture_npot)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(vertex_half_float)     // Desktop differs
+       _EVASGL_EXT_DRVNAME(GL_OES_vertex_half_float)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(vertex_half_float_DESKTOP)     // Desktop differs
+       _EVASGL_EXT_DRVNAME(GL_OES_vertex_half_float)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(vertex_type_10_10_10_2)
+       _EVASGL_EXT_DRVNAME(GL_OES_vertex_type_10_10_10_2)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(compressed_3DC_texture)
+       _EVASGL_EXT_DRVNAME(GL_AMD_compressed_3DC_texture)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(compressed_ATC_texture)
+       _EVASGL_EXT_DRVNAME(GL_AMD_compressed_ATC_texture)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(program_binary_Z400)
+       _EVASGL_EXT_DRVNAME(GL_AMD_program_binary_Z400)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(blend_minmax)
+       _EVASGL_EXT_DRVNAME(GL_EXT_blend_minmax)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(read_format_bgra) // Desktop differs
+       _EVASGL_EXT_DRVNAME(GL_EXT_read_format_bgra)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(read_format_bgra_DESKTOP) // Desktop differs
+       _EVASGL_EXT_DRVNAME(GL_EXT_read_format_bgra)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(texture_filter_anisotropic)
+       _EVASGL_EXT_DRVNAME(GL_EXT_texture_filter_anisotropic)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(texture_format_BGRA8888) // Desktop differs
+       _EVASGL_EXT_DRVNAME(GL_EXT_texture_format_BGRA8888)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(texture_format_BGRA8888_DESKTOP) // Desktop differs
+       _EVASGL_EXT_DRVNAME(GL_EXT_texture_format_BGRA8888)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(texture_type_2_10_10_10_rev) // Desktop differs
+       _EVASGL_EXT_DRVNAME(GL_EXT_texture_type_2_10_10_10_REV)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(texture_type_2_10_10_10_rev_DESKTOP) // Desktop differs
+       _EVASGL_EXT_DRVNAME(GL_EXT_texture_type_2_10_10_10_REV)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(IMG_program_binary)
+       _EVASGL_EXT_DRVNAME(GL_IMG_program_binary)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(IMG_read_format)
+       _EVASGL_EXT_DRVNAME(GL_IMG_read_format)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(IMG_shader_binary)
+       _EVASGL_EXT_DRVNAME(GL_IMG_shader_binary)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(IMG_texture_compression_pvrtc)
+       _EVASGL_EXT_DRVNAME(GL_IMG_texture_compression_pvrtc)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(QCOM_perfmon_global_mode)
+       _EVASGL_EXT_DRVNAME(GL_QCOM_perfmon_global_mode)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(QCOM_writeonly_rendering)
+       _EVASGL_EXT_DRVNAME(GL_QCOM_writeonly_rendering)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(OES_read_format)
+       _EVASGL_EXT_DRVNAME(GL_OES_read_format)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(EXT_color_buffer_float)
+       _EVASGL_EXT_DRVNAME(GL_EXT_color_buffer_float)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(EXT_color_buffer_half_float)
+       _EVASGL_EXT_DRVNAME(GL_EXT_color_buffer_half_float)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(sRGB)
+       _EVASGL_EXT_DRVNAME(GL_EXT_sRGB)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(EXT_sRGB_write_control)
+       _EVASGL_EXT_DRVNAME(GL_EXT_sRGB_write_control)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(EXT_texture_sRGB_decode)
+       _EVASGL_EXT_DRVNAME(GL_EXT_texture_sRGB_decode)
+_EVASGL_EXT_END()
+
+/* GL_OES_fragment_precision_high:
+    This extension has been withdrawn. See the specification of
+    GetShaderPrecisionFormat in section 6.1.8 of the OpenGL ES 2.0
+    Specification to determine within the API if high-precision fragment
+    shader varyings are supported by the implementation.
+ */
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// GLES 1.1 ONLY EXTENSIONS
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+_EVASGL_EXT_BEGIN(blend_equation_separate)
+        _EVASGL_EXT_DRVNAME(GL_OES_blend_equation_separate)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glBlendEquationSeparateOES, (GLenum modeRGB, GLenum modeAlpha))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glBlendEquationSeparate")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glBlendEquationSeparateOES")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(blend_func_separate)
+        _EVASGL_EXT_DRVNAME(GL_OES_blend_func_separate)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glBlendFuncSeparateOES, (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glBlendFuncSeparate")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glBlendFuncSeparateOES")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(blend_subtract)
+        _EVASGL_EXT_DRVNAME(GL_OES_blend_subtract)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glBlendEquationOES, (GLenum mode))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glBlendEquation")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glBlendEquationOES")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(byte_coordinates)
+        _EVASGL_EXT_DRVNAME(GL_OES_byte_coordinates)
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(draw_texture)
+        _EVASGL_EXT_DRVNAME(GL_OES_draw_texture)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glDrawTexsOES, (GLshort x, GLshort y, GLshort z, GLshort width, GLshort height))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDrawTexs")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDrawTexsOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glDrawTexiOES, (GLint x, GLint y, GLint z, GLint width, GLint height))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDrawTexi")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDrawTexiOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glDrawTexxOES, (GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDrawTexx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDrawTexxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glDrawTexsvOES, (const GLshort *coords))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDrawTexsv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDrawTexsvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glDrawTexivOES, (const GLint *coords))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDrawTexiv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDrawTexivOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glDrawTexxvOES, (const GLfixed *coords))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDrawTexxv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDrawTexxvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glDrawTexfOES, (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDrawTexf")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDrawTexfOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glDrawTexfvOES, (const GLfloat *coords))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDrawTexfv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDrawTexfvOES")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(extended_matrix_palette)
+        _EVASGL_EXT_DRVNAME(GL_OES_extended_matrix_palette)
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(fixed_point)
+        _EVASGL_EXT_DRVNAME(GL_OES_fixed_point)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glAlphaFuncxOES, (GLenum func, GLclampx ref))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glAlphaFuncx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glAlphaFuncxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glClearColorxOES, (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glClearColorx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glClearColorxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glClearDepthxOES, (GLclampx depth))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glClearDepthx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glClearDepthxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glClipPlanexOES, (GLenum plane, const GLfixed *equation))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glClipPlanex")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glClipPlanexOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glColor4xOES, (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glColor4x")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glColor4xOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glDepthRangexOES, (GLclampx zNear, GLclampx zFar))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDepthRangex")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDepthRangexOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glFogxOES, (GLenum pname, GLfixed param))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFogx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFogxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glFogxvOES, (GLenum pname, const GLfixed *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFogxv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFogxvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glFrustumxOES, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFrustumx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFrustumxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGetClipPlanexOES, (GLenum pname, GLfixed eqn[4]))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetClipPlanex")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetClipPlanexOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGetFixedvOES, (GLenum pname, GLfixed *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetFixedv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetFixedvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGetLightxvOES, (GLenum light, GLenum pname, GLfixed *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetLightxv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetLightxvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGetMaterialxvOES, (GLenum face, GLenum pname, GLfixed *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetMaterialxv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetMaterialxvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGetTexEnvxvOES, (GLenum env, GLenum pname, GLfixed *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetTexEnvxv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetTexEnvxvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGetTexParameterxvOES, (GLenum target, GLenum pname, GLfixed *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetTexParameterxv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetTexParameterxvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glLightModelxOES, (GLenum pname, GLfixed param))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glLightModelx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glLightModelxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glLightModelxvOES, (GLenum pname, const GLfixed *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glLightModelxv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glLightModelxvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glLightxOES, (GLenum light, GLenum pname, GLfixed param))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glLightx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glLightxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glLightxvOES, (GLenum light, GLenum pname, const GLfixed *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glLightxv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glLightxvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glLineWidthxOES, (GLfixed width))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glLineWidthx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glLineWidthxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glLoadMatrixxOES, (const GLfixed *m))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glLoadMatrixx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glLoadMatrixxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glMaterialxOES, (GLenum face, GLenum pname, GLfixed param))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMaterialx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMaterialxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glMaterialxvOES, (GLenum face, GLenum pname, const GLfixed *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMaterialxv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMaterialxvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glMultMatrixxOES, (const GLfixed *m))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMultMatrixx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMultMatrixxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glMultiTexCoord4xOES, (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMultiTexCoord4x")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMultiTexCoord4xOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glNormal3xOES, (GLfixed nx, GLfixed ny, GLfixed nz))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glNormal3x")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glNormal3xOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glOrthoxOES, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glOrthox")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glOrthoxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glPointParameterxOES, (GLenum pname, GLfixed param))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glPointParameterx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glPointParameterxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glPointParameterxvOES, (GLenum pname, const GLfixed *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glPointParameterxv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glPointParameterxvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glPointSizexOES, (GLfixed size))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glPointSizex")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glPointSizexOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glPolygonOffsetxOES, (GLfixed factor, GLfixed units))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glPolygonOffsetx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glPolygonOffsetxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glRotatexOES, (GLfixed angle, GLfixed x, GLfixed y, GLfixed z))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glRotatex")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glRotatexOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glSampleCoveragexOES, (GLclampx value, GLboolean invert))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glSampleCoveragex")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glSampleCoveragexOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glScalexOES, (GLfixed x, GLfixed y, GLfixed z))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glScalex")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glScalexOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTexEnvxOES, (GLenum target, GLenum pname, GLfixed param))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexEnvx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexEnvxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTexEnvxvOES, (GLenum target, GLenum pname, const GLfixed *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexEnvxv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexEnvxvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTexParameterxOES, (GLenum target, GLenum pname, GLfixed param))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexParameterx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexParameterxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTexParameterxvOES, (GLenum target, GLenum pname, const GLfixed *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexParameterxv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexParameterxvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTranslatexOES, (GLfixed x, GLfixed y, GLfixed z))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTranslatex")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTranslatexOES")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(framebuffer_object)
+        _EVASGL_EXT_DRVNAME(GL_OES_framebuffer_object)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(GLboolean, glIsRenderbufferOES, (GLuint renderbuffer))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glIsRenderbuffer")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glIsRenderbufferOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glBindRenderbufferOES, (GLenum target, GLuint renderbuffer))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glBindRenderbuffer")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glBindRenderbufferOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glDeleteRenderbuffersOES, (GLsizei n, const GLuint* renderbuffers))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDeleteRenderbuffers")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDeleteRenderbuffersOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGenRenderbuffersOES, (GLsizei n, GLuint* renderbuffers))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGenRenderbuffers")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGenRenderbuffersOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glRenderbufferStorageOES, (GLenum target, GLenum internalformat, GLsizei width, GLsizei height))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glRenderbufferStorage")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glRenderbufferStorageOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGetRenderbufferParameterivOES, (GLenum target, GLenum pname, GLint* params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetRenderbufferParameteriv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetRenderbufferParameterivOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(GLboolean, glIsFramebufferOES, (GLuint framebuffer))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glIsFramebuffer")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glIsFramebufferOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glBindFramebufferOES, (GLenum target, GLuint framebuffer))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glBindFramebuffer")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glBindFramebufferOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glDeleteFramebuffersOES, (GLsizei n, const GLuint* framebuffers))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDeleteFramebuffers")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDeleteFramebuffersOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGenFramebuffersOES, (GLsizei n, GLuint* framebuffers))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGenFramebuffers")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGenFramebuffersOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(GLenum, glCheckFramebufferStatusOES, (GLenum target))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glCheckFramebufferStatus")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glCheckFramebufferStatusOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glFramebufferRenderbufferOES, (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFramebufferRenderbuffer")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFramebufferRenderbufferOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glFramebufferTexture2DOES, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFramebufferTexture2D")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFramebufferTexture2DOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGetFramebufferAttachmentParameterivOES, (GLenum target, GLenum attachment, GLenum pname, GLint* params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetFramebufferAttachmentParameteriv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetFramebufferAttachmentParameterivOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGenerateMipmapOES, (GLenum target))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGenerateMipmap")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGenerateMipmapOES")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(matrix_get)
+        _EVASGL_EXT_DRVNAME(GL_OES_matrix_get)
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(matrix_palette)
+        _EVASGL_EXT_DRVNAME(GL_OES_matrix_palette)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glCurrentPaletteMatrixOES, (GLuint matrixpaletteindex))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glCurrentPaletteMatrix")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glCurrentPaletteMatrixOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glLoadPaletteFromModelViewMatrixOES, (void))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glLoadPaletteFromModelViewMatrix")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glLoadPaletteFromModelViewMatrixOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glMatrixIndexPointerOES, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMatrixIndexPointer")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMatrixIndexPointerOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glWeightPointerOES, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glWeightPointer")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glWeightPointerOES")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(required_internalformat)
+        _EVASGL_EXT_DRVNAME(GL_OES_required_internalformat)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(query_matrix)
+        _EVASGL_EXT_DRVNAME(GL_OES_query_matrix)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(GLbitfield, glQueryMatrixxOES, (GLfixed mantissa[16], GLint exponent[16]))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glQueryMatrixx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glQueryMatrixxOES")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(single_precision)
+        _EVASGL_EXT_DRVNAME(GL_OES_single_precision)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glDepthRangefOES, (GLclampf zNear, GLclampf zFar))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDepthRangef")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDepthRangefOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glFrustumfOES, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFrustumf")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFrustumfOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glOrthofOES, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glOrthof")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glOrthofOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glClipPlanefOES, (GLenum plane, const GLfloat *equation))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glClipPlanef")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glClipPlanefOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGetClipPlanefOES, (GLenum pname, GLfloat eqn[4]))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetClipPlanef")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetClipPlanefOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glClearDepthfOES, (GLclampf depth))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glClearDepthf")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glClearDepthfOES")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(stencil8)
+        _EVASGL_EXT_DRVNAME(GL_OES_stencil8)
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(stencil_wrap)
+        _EVASGL_EXT_DRVNAME(GL_OES_stencil_wrap)
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(texture_cube_map)
+        _EVASGL_EXT_DRVNAME(GL_OES_texture_cube_map)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTexGenfOES, (GLenum coord, GLenum pname, GLfloat param))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexGenf")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexGenfOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTexGenfvOES, (GLenum coord, GLenum pname, const GLfloat *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexGenfv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexGenfvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTexGeniOES, (GLenum coord, GLenum pname, GLint param))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexGeni")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexGeniOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTexGenivOES, (GLenum coord, GLenum pname, const GLint *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexGeniv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexGenivOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTexGenxOES, (GLenum coord, GLenum pname, GLfixed param))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexGenx")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexGenxOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTexGenxvOES, (GLenum coord, GLenum pname, const GLfixed *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexGenxv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexGenxvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGetTexGenfvOES, (GLenum coord, GLenum pname, GLfloat *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetTexGenfv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetTexGenfvOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGetTexGenivOES, (GLenum coord, GLenum pname, GLint *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetTexGeniv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetTexGenivOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGetTexGenxvOES, (GLenum coord, GLenum pname, GLfixed *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetTexGenxv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetTexGenxvOES")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(texture_env_crossbar)
+        _EVASGL_EXT_DRVNAME(GL_OES_texture_env_crossbar)
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(texture_mirrored_repeat)
+        _EVASGL_EXT_DRVNAME(GL_OES_texture_mirrored_repeat)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(vertex_array_object)
+        _EVASGL_EXT_DRVNAME(GL_OES_vertex_array_object)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glBindVertexArrayOES, (GLuint array))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glBindVertexArray")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glBindVertexArrayOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glDeleteVertexArraysOES, (GLsizei n, const GLuint *arrays))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDeleteVertexArrays")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDeleteVertexArraysOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGenVertexArraysOES, (GLsizei n, GLuint *arrays))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGenVertexArrays")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGenVertexArraysOES")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(GLboolean, glIsVertexArrayOES, (GLuint array))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glIsVertexArray")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glIsVertexArrayOES")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+/* APPLE extension functions */
+_EVASGL_EXT_BEGIN(APPLE_copy_texture_levels)
+        _EVASGL_EXT_DRVNAME(GL_APPLE_copy_texture_levels)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glCopyTextureLevelsAPPLE, (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glCopyTextureLevels")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glCopyTextureLevelsAPPLE")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(APPLE_framebuffer_multisample)
+        _EVASGL_EXT_DRVNAME(GL_APPLE_framebuffer_multisample)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glRenderbufferStorageMultisampleAPPLE, (GLenum, GLsizei, GLenum, GLsizei, GLsizei))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glRenderbufferStorageMultisample")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glRenderbufferStorageMultisampleAPPLE")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glResolveMultisampleFramebufferAPPLE, (void))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glResolveMultisampleFramebuffer")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glResolveMultisampleFramebufferAPPLE")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(APPLE_sync)
+        _EVASGL_EXT_DRVNAME(GL_APPLE_sync)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(GLsync, glFenceSyncAPPLE, (GLenum condition, GLbitfield flags))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFenceSyncAPPLE")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(GLboolean, glIsSyncAPPLE, (GLsync sync))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glIsSyncAPPLE")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glDeleteSyncAPPLE, (GLsync sync))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glDeleteSyncAPPLE")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(GLenum, glClientWaitSyncAPPLE, (GLsync sync, GLbitfield flags, EvasGLuint64 timeout))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glClientWaitSyncAPPLE")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glWaitSyncAPPLE, (GLsync sync, GLbitfield flags, EvasGLuint64 timeout))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glWaitSyncAPPLE")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGetInteger64vAPPLE, (GLenum pname, EvasGLint64 *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetInteger64vAPPLE")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glGetSyncivAPPLE, (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetSyncivAPPLE")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(APPLE_texture_2D_limited_npot)
+        _EVASGL_EXT_DRVNAME(GL_APPLE_texture_2D_limited_npot)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(APPLE_texture_format_BGRA8888)
+        _EVASGL_EXT_DRVNAME(GL_APPLE_texture_format_BGRA8888)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(APPLE_texture_max_level)
+        _EVASGL_EXT_DRVNAME(GL_APPLE_texture_max_level)
+_EVASGL_EXT_END()
+
+/* ARM extension */
+_EVASGL_EXT_BEGIN(ARM_rgba8)
+        _EVASGL_EXT_DRVNAME(GL_ARM_rgba8)
+_EVASGL_EXT_END()
+
+/* EXT extension functions */
+_EVASGL_EXT_BEGIN(map_buffer_range)
+        _EVASGL_EXT_DRVNAME(GL_EXT_map_buffer_range)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(void *, glMapBufferRangeEXT, (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMapBufferRange")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glMapBufferRangeEXT")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glFlushMappedBufferRangeEXT, (GLenum target, GLintptr offset, GLsizeiptr length))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFlushMappedBufferRange")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glFlushMappedBufferRangeEXT")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(robustness)
+        _EVASGL_EXT_DRVNAME(GL_EXT_robustness)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(GLenum, glGetGraphicsResetStatusEXT, (void))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetGraphicsResetStatus")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetGraphicsResetStatusEXT")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glReadnPixelsEXT, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glReadnPixels")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glReadnPixelsEXT")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
+           _EVASGL_EXT_FUNCTION_BEGIN(void, glGetnUniformfvEXT, (GLuint program, GLint location, GLsizei bufSize, float *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetnUniformfv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetnUniformfvEXT")
+           _EVASGL_EXT_FUNCTION_END()
+           _EVASGL_EXT_FUNCTION_BEGIN(void, glGetnUniformivEXT, (GLuint program, GLint location, GLsizei bufSize, GLint *params))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetnUniformiv")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glGetnUniformivEXT")
+           _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(texture_compression_dxt1)
+        _EVASGL_EXT_DRVNAME(GL_EXT_texture_compression_dxt1)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(texture_lod_bias)
+        _EVASGL_EXT_DRVNAME(GL_EXT_texture_lod_bias)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(texture_storage)
+        _EVASGL_EXT_DRVNAME(GL_EXT_texture_storage)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTexStorage1DEXT, (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexStorage1D")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexStorage1DEXT")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTexStorage2DEXT, (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexStorage2D")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexStorage2DEXT")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTexStorage3DEXT, (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexStorage3D")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTexStorage3DEXT")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTextureStorage1DEXT, (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTextureStorage1D")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTextureStorage1DEXT")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTextureStorage2DEXT, (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTextureStorage2D")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTextureStorage2DEXT")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glTextureStorage3DEXT, (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTextureStorage3D")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glTextureStorage3DEXT")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(IMG_texture_env_enhanced_fixed_function)
+        _EVASGL_EXT_DRVNAME(GL_IMG_texture_env_enhanced_fixed_function)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(IMG_user_clip_plane)
+        _EVASGL_EXT_DRVNAME(GL_IMG_user_clip_plane)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glClipPlanefIMG, (GLenum, const GLfloat *))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glClipPlanef")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glClipPlanefIMG")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glClipPlanexIMG, (GLenum, const GLfixed *))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glClipPlanex")
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glClipPlanexIMG")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(QCOM_tiled_rendering)
+        _EVASGL_EXT_DRVNAME(GL_QCOM_tiled_rendering)
+
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glStartTilingQCOM, (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glStartTilingQCOM")
+        _EVASGL_EXT_FUNCTION_END()
+        _EVASGL_EXT_FUNCTION_BEGIN(void, glEndTilingQCOM, (GLbitfield preserveMask))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glEndTilingQCOM")
+        _EVASGL_EXT_FUNCTION_END()
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(element_index_uint)
+        _EVASGL_EXT_DRVNAME(GL_OES_element_index_uint)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(fbo_render_mipmap)
+        _EVASGL_EXT_DRVNAME(GL_OES_fbo_render_mipmap)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(mali_program_binary)
+        _EVASGL_EXT_DRVNAME(GL_ARM_mali_program_binary)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(mali_shader_binary)
+        _EVASGL_EXT_DRVNAME(GL_ARM_mali_shader_binary)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(depth_texture)
+        _EVASGL_EXT_DRVNAME(GL_OES_depth_texture)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(depth_texture_cube_map)
+        _EVASGL_EXT_DRVNAME(GL_OES_depth_texture_cube_map)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(shader_texture_lod)
+        _EVASGL_EXT_DRVNAME(GL_EXT_shader_texture_lod)
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(QCOM_binning_control)
+        _EVASGL_EXT_DRVNAME(GL_QCOM_binning_control)
+_EVASGL_EXT_END()
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Other "safe" extensions that are not in Evas_GL_API
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/*
+ * IMPORTANT NOTE:
+ *
+ * Before adding any extension & function to the list below, it is very
+ * important to check that the extension does not modify the state in a way
+ * that would break direct rendering (eg. Scissors) or indirect rendering
+ * (eg. changes the target FBO).
+ *
+ * If any of the following applies, the extension must be wrapped before
+ * being exposed to client apps:
+ * - The target FBO is changed (this could break indirect rendering)
+ * - The scissors geometry is changed (breaks direct rendering)
+ * - Shared contexts can also be affected (breaks everything since all contexts
+ *   are shared with the main Evas GL context)
+ *
+ * There can be a number of other reasons for functions to need wrapping, so
+ * please read carefully the specifications of all extensions and check that
+ * they are safe to use. The goal is to contain as much as possible the effects
+ * of an API call to the surface & context bound to the Evas_GL.
+ */
+
+#if _EVASGL_EXT_WHITELIST_ONLY
+
+// ----------------------------------------------------------
+_EVASGL_EXT_BEGIN(debug)
+_EVASGL_EXT_DRVNAME(GL_KHR_debug)
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glDebugMessageControl")
+_EVASGL_EXT_FUNCTION_WHITELIST("glDebugMessageControlKHR")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glDebugMessageInsert")
+_EVASGL_EXT_FUNCTION_WHITELIST("glDebugMessageInsertKHR")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glDebugMessageCallback")
+_EVASGL_EXT_FUNCTION_WHITELIST("glDebugMessageCallbackKHR")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetDebugMessageLog")
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetDebugMessageLogKHR")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetPointerv")
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetPointervKHR")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glPushDebugGroup")
+_EVASGL_EXT_FUNCTION_WHITELIST("glPushDebugGroupKHR")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glPopDebugGroup")
+_EVASGL_EXT_FUNCTION_WHITELIST("glPopDebugGroupKHR")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glObjectLabel")
+_EVASGL_EXT_FUNCTION_WHITELIST("glObjectLabelKHR")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetObjectLabel")
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetObjectLabelKHR")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glObjectPtrLabel")
+_EVASGL_EXT_FUNCTION_WHITELIST("glObjectPtrLabelKHR")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetObjectPtrLabel")
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetObjectPtrLabelKHR")
+
+_EVASGL_EXT_END()
+
+
+// ----------------------------------------------------------
+_EVASGL_EXT_BEGIN(debug_label)
+_EVASGL_EXT_DRVNAME(GL_EXT_debug_label)
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glLabelObject")
+_EVASGL_EXT_FUNCTION_WHITELIST("glLabelObjectEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetObjectLabel")
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetObjectLabelEXT")
+
+_EVASGL_EXT_END()
+
+
+// ----------------------------------------------------------
+_EVASGL_EXT_BEGIN(debug_marker)
+_EVASGL_EXT_DRVNAME(GL_EXT_debug_marker)
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glInsertEventMarker")
+_EVASGL_EXT_FUNCTION_WHITELIST("glInsertEventMarkerEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glPushGroupMarker")
+_EVASGL_EXT_FUNCTION_WHITELIST("glPushGroupMarkerEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glPopGroupMarker")
+_EVASGL_EXT_FUNCTION_WHITELIST("glPopGroupMarkerEXT")
+
+_EVASGL_EXT_END()
+
+
+// ----------------------------------------------------------
+_EVASGL_EXT_BEGIN(disjoint_timer_query)
+_EVASGL_EXT_DRVNAME(GL_EXT_disjoint_timer_query)
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glGenQueries")
+_EVASGL_EXT_FUNCTION_WHITELIST("glGenQueriesEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glDeleteQueries")
+_EVASGL_EXT_FUNCTION_WHITELIST("glDeleteQueriesEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glIsQuery")
+_EVASGL_EXT_FUNCTION_WHITELIST("glIsQueryEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glBeginQuery")
+_EVASGL_EXT_FUNCTION_WHITELIST("glBeginQueryEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glEndQuery")
+_EVASGL_EXT_FUNCTION_WHITELIST("glEndQueryEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glQueryCounter")
+_EVASGL_EXT_FUNCTION_WHITELIST("glQueryCounterEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetQueryiv")
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetQueryivEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetQueryObjectiv")
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetQueryObjectivEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetQueryObjectuiv")
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetQueryObjectuivEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetQueryObjecti64v")
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetQueryObjecti64vEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetQueryObjectui64v")
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetQueryObjectui64vEXT")
+
+_EVASGL_EXT_END()
+
+
+// ----------------------------------------------------------
+_EVASGL_EXT_BEGIN(occlusion_query_boolean)
+_EVASGL_EXT_DRVNAME(GL_EXT_occlusion_query_boolean)
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glGenQueries")
+_EVASGL_EXT_FUNCTION_WHITELIST("glGenQueriesEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glDeleteQueries")
+_EVASGL_EXT_FUNCTION_WHITELIST("glDeleteQueriesEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glIsQuery")
+_EVASGL_EXT_FUNCTION_WHITELIST("glIsQueryEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glBeginQuery")
+_EVASGL_EXT_FUNCTION_WHITELIST("glBeginQueryEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glEndQuery")
+_EVASGL_EXT_FUNCTION_WHITELIST("glEndQueryEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetQueryiv")
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetQueryivEXT")
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetQueryObjectuiv")
+_EVASGL_EXT_FUNCTION_WHITELIST("glGetQueryObjectuivEXT")
+
+_EVASGL_EXT_END()
+
+
+// ----------------------------------------------------------
+// NOTE: This extension changes state
+_EVASGL_EXT_BEGIN(alpha_test)
+_EVASGL_EXT_DRVNAME(GL_QCOM_alpha_test)
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glAlphaFunc")
+_EVASGL_EXT_FUNCTION_WHITELIST("glAlphaFuncQCOM")
+
+_EVASGL_EXT_END()
+
+
+// ----------------------------------------------------------
+// NOTE: This extension changes state
+/* Also, to be perfectly correct, we would need to wrap the extension:
+ * << DrawBuffersNV may only be called when the GL is bound to a framebuffer
+ *    object. If called when the GL is bound to the default framebuffer, an
+ *    INVALID_OPERATION error is generated. >>
+ * This means the function should generate INVALID_OPERATION when indirect
+ * rendering is active and the default FBO is currently bound.
+ */
+_EVASGL_EXT_BEGIN(draw_buffers)
+_EVASGL_EXT_DRVNAME(GL_NV_draw_buffers)
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glDrawBuffers")
+_EVASGL_EXT_FUNCTION_WHITELIST("glDrawBuffersNV")
+
+_EVASGL_EXT_END()
+
+
+// ----------------------------------------------------------
+// NOTE: This extension changes state
+_EVASGL_EXT_BEGIN(read_buffer)
+_EVASGL_EXT_DRVNAME(GL_NV_read_buffer)
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glReadBuffer")
+_EVASGL_EXT_FUNCTION_WHITELIST("glReadBufferNV")
+
+_EVASGL_EXT_END()
+
+
+// Another version of the extension (that allows reading from the FRONT color buf)
+_EVASGL_EXT_BEGIN(read_buffer_front)
+_EVASGL_EXT_DRVNAME(GL_NV_read_buffer_front)
+_EVASGL_EXT_END()
+
+
+// ----------------------------------------------------------
+_EVASGL_EXT_BEGIN(framebuffer_blit)
+_EVASGL_EXT_DRVNAME(GL_NV_framebuffer_blit)
+_EVASGL_EXT_DRVNAME(GL_ANGLE_framebuffer_blit)
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glBlitFramebuffer")
+_EVASGL_EXT_FUNCTION_WHITELIST("glBlitFramebufferNV")
+_EVASGL_EXT_FUNCTION_WHITELIST("glBlitFramebufferANGLE")
+
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(framebuffer_multisample)
+_EVASGL_EXT_DRVNAME(GL_ANGLE_framebuffer_multisample)
+
+_EVASGL_EXT_FUNCTION_WHITELIST("glRenderbufferStorageMultisampleANGLE")
+
+_EVASGL_EXT_END()
+
+
+// ----------------------------------------------------------
+_EVASGL_EXT_BEGIN(point_sprite)
+  _EVASGL_EXT_DRVNAME(GL_OES_point_sprite)
+_EVASGL_EXT_END()
+
+
+// ----------------------------------------------------------
+// This "extension" is already listed in the base GLES1 API
+// Provided here as convenience for evas_gl_proc_address_get
+_EVASGL_EXT_BEGIN(point_size_array)
+  _EVASGL_EXT_DRVNAME(GL_OES_point_size_array)
+
+  _EVASGL_EXT_FUNCTION_WHITELIST("glPointSizePointer")
+  _EVASGL_EXT_FUNCTION_WHITELIST("glPointSizePointerOES")
+_EVASGL_EXT_END()
+
+
+
+
+#endif // _EVASGL_EXT_WHITELIST_ONLY ("safe" extensions)
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// EGL EXTENSIONS
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#ifdef GL_GLES
+
+_EVASGL_EXT_BEGIN(EGL_KHR_image_base)
+
+       _EVASGL_EXT_DRVNAME(EGL_KHR_image_base)
+
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void *, eglCreateImage, (EGLDisplay a, EGLContext b, EGLenum c, EGLClientBuffer d, const int *e))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("eglCreateImageKHR")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void, eglDestroyImage, (EGLDisplay a, void *b))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("eglDestroyImageKHR")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+
+       _EVASGL_EXT_FUNCTION_BEGIN(EvasGLImage, evasglCreateImage, (int target, void* buffer, const int *attrib_list))
+               _EVASGL_EXT_FUNCTION_DRVFUNC(evgl_evasglCreateImage)
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, evasglDestroyImage, (EvasGLImage image))
+               _EVASGL_EXT_FUNCTION_DRVFUNC(evgl_evasglDestroyImage)
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(EvasGLImage, evasglCreateImageForContext, (Evas_GL *evas_gl, Evas_GL_Context *ctx, int target, void* buffer, const int *attrib_list))
+               _EVASGL_EXT_FUNCTION_DRVFUNC(evgl_evasglCreateImageForContext)
+       _EVASGL_EXT_FUNCTION_END()
+
+       #ifdef _EVASGL_EXT_VERIFY
+       {
+               // Add special function pointers
+               //evgl_evasglCreateImage_ptr = GETPROCADDR("eglCreateImageKHR");
+               //evgl_evasglDestroyImage_ptr = GETPROCADDR("eglDestroyImageKHR");
+       }
+       #endif
+
+_EVASGL_EXT_END()
+
+
+
+_EVASGL_EXT_BEGIN(GL_OES_EGL_image)
+
+       _EVASGL_EXT_DRVNAME(GL_OES_EGL_image)
+
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void, glEGLImageTargetTexture2DOES, (GLenum target, GLeglImageOES image))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glEGLImageTargetTexture2DOES")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void, glEGLImageTargetRenderbufferStorageOES, (GLenum target, GLeglImageOES image))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glEGLImageTargetRenderbufferStorageOES")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glEvasGLImageTargetTexture2DOES, (GLenum target, EvasGLImage image))
+               _EVASGL_EXT_FUNCTION_DRVFUNC(evgl_glEvasGLImageTargetTexture2D)
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(void, glEvasGLImageTargetRenderbufferStorageOES, (GLenum target, EvasGLImage image))
+               _EVASGL_EXT_FUNCTION_DRVFUNC(evgl_glEvasGLImageTargetRenderbufferStorage)
+       _EVASGL_EXT_FUNCTION_END()
+
+       #ifdef _EVASGL_EXT_VERIFY
+       {
+                if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT();
+       }
+       #endif
+
+_EVASGL_EXT_END()
+
+
+
+_EVASGL_EXT_BEGIN(EGL_KHR_image_pixmap)
+       _EVASGL_EXT_DRVNAME(EGL_KHR_image_pixmap)
+       #ifdef _EVASGL_EXT_VERIFY
+       {
+                if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT();
+       }
+       #endif
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(EGL_KHR_image)
+       _EVASGL_EXT_DRVNAME(EGL_KHR_image)
+       #ifdef _EVASGL_EXT_VERIFY
+       {
+                if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT();
+       }
+       #endif
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(EGL_KHR_vg_parent_image)
+       _EVASGL_EXT_DRVNAME(EGL_KHR_vg_parent_image)
+       #ifdef _EVASGL_EXT_VERIFY
+       {
+                if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT();
+       }
+       #endif
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(EGL_KHR_gl_texture_2D_image)
+       _EVASGL_EXT_DRVNAME(EGL_KHR_gl_texture_2D_image)
+       #ifdef _EVASGL_EXT_VERIFY
+       {
+                if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT();
+       }
+       #endif
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(EGL_KHR_gl_texture_cubemap_image)
+       _EVASGL_EXT_DRVNAME(EGL_KHR_gl_texture_cubemap_image)
+       #ifdef _EVASGL_EXT_VERIFY
+       {
+                if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT();
+       }
+       #endif
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(EGL_KHR_gl_texture_3D_image)
+       _EVASGL_EXT_DRVNAME(EGL_KHR_gl_texture_3D_image)
+       #ifdef _EVASGL_EXT_VERIFY
+       {
+                if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT();
+       }
+       #endif
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(EGL_KHR_gl_renderbuffer_image)
+       _EVASGL_EXT_DRVNAME(EGL_KHR_gl_renderbuffer_image)
+       #ifdef _EVASGL_EXT_VERIFY
+       {
+                if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT();
+       }
+       #endif
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(GL_OES_EGL_image_external)
+        _EVASGL_EXT_DRVNAME(GL_OES_EGL_image_external)
+       #ifdef _EVASGL_EXT_VERIFY
+       {
+                if (!_EVASGL_EXT_CHECK_SUPPORT("EGL_KHR_image_base")) _EVASGL_EXT_DISCARD_SUPPORT();
+       }
+       #endif
+_EVASGL_EXT_END()
+
+
+_EVASGL_EXT_BEGIN(EGL_KHR_fence_sync)
+
+        /* 3 aliasses for EGL_KHR_fence_sync */
+       _EVASGL_EXT_DRVNAME(EGL_KHR_fence_sync)
+        _EVASGL_EXT_DRVNAME(GL_OES_EGL_sync)
+        _EVASGL_EXT_DRVNAME(VG_KHR_EGL_sync)
+
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void *, eglCreateSyncKHR, (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("eglCreateSyncKHR")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(EGLBoolean, eglDestroySyncKHR, (EGLDisplay dpy, EGLSyncKHR sync))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("eglDestroySyncKHR")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(EGLint, eglClientWaitSyncKHR, (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("eglClientWaitSyncKHR")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(EGLBoolean, eglGetSyncAttribKHR, (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("eglGetSyncAttribKHR")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+
+       _EVASGL_EXT_FUNCTION_BEGIN(EvasGLSync, evasglCreateSync, (Evas_GL *evas_gl, unsigned int type, const int *attrib_list))
+               _EVASGL_EXT_FUNCTION_DRVFUNC(evgl_evasglCreateSync)
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(Eina_Bool, evasglDestroySync, (Evas_GL *evas_gl, EvasGLSync sync))
+               _EVASGL_EXT_FUNCTION_DRVFUNC(evgl_evasglDestroySync)
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(int, evasglClientWaitSync, (Evas_GL *evas_gl, EvasGLSync sync, int flags, EvasGLTime timeout))
+               _EVASGL_EXT_FUNCTION_DRVFUNC(evgl_evasglClientWaitSync)
+       _EVASGL_EXT_FUNCTION_END()
+       _EVASGL_EXT_FUNCTION_BEGIN(Eina_Bool, evasglGetSyncAttrib, (Evas_GL *evas_gl, EvasGLSync sync, int attribute, int *value))
+               _EVASGL_EXT_FUNCTION_DRVFUNC(evgl_evasglGetSyncAttrib)
+       _EVASGL_EXT_FUNCTION_END()
+
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(EGL_KHR_reusable_sync)
+
+       _EVASGL_EXT_DRVNAME(EGL_KHR_reusable_sync)
+
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(EGLBoolean, eglSignalSyncKHR, (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("eglSignalSyncKHR")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+
+       _EVASGL_EXT_FUNCTION_BEGIN(Eina_Bool, evasglSignalSync, (Evas_GL *evas_gl, EvasGLSync sync, unsigned mode))
+               _EVASGL_EXT_FUNCTION_DRVFUNC(evgl_evasglSignalSync)
+       _EVASGL_EXT_FUNCTION_END()
+
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(EGL_KHR_wait_sync)
+
+       _EVASGL_EXT_DRVNAME(EGL_KHR_wait_sync)
+
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(EGLint, eglWaitSyncKHR, (EGLDisplay dpy, EGLSyncKHR sync, int flags))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("eglWaitSyncKHR")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+
+       _EVASGL_EXT_FUNCTION_BEGIN(int, evasglWaitSync, (Evas_GL *evas_gl, EvasGLSync sync, int flags))
+               _EVASGL_EXT_FUNCTION_DRVFUNC(evgl_evasglWaitSync)
+       _EVASGL_EXT_FUNCTION_END()
+
+_EVASGL_EXT_END()
+
+
+#if 0
+_EVASGL_EXT_BEGIN(EGL_SEC_map_image)
+       _EVASGL_EXT_DRVNAME(EGL_SEC_map_image)
+
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void *, eglMapImageSEC, void *a, void *b, int c, int d))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("eglMapImageSEC")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(unsigned int, eglUnmapImageSEC, void *a, void *b, int c))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("eglUnmapImageSEC")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+_EVASGL_EXT_END()
+#endif
+
+
+#endif
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// GLX EXTENSIONS
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#if 0
+#ifdef GL_GLES
+#else
+
+_EVASGL_EXT_BEGIN(GLX_EXT_swap_control)
+       _EVASGL_EXT_DRVNAME(GLX_EXT_swap_control)
+
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void, glXSwapIntervalEXT, (Display *dpy, GLXDrawable drawable, int interval))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glXSwapIntervalEXT")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(GLX_SGI_swap_control)
+       _EVASGL_EXT_DRVNAME(GLX_SGI_swap_control)
+
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(int, glXSwapIntervalSGI, (int interval))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glXSwapIntervalSGI")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(GLX_SGI_video_sync)
+       _EVASGL_EXT_DRVNAME(GLX_SGI_video_sync)
+
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(int, glXGetVideoSyncSGI, (uint *count))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glXGetVideoSyncSGI")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(int, glXWaitVideoSyncSGI, (int divisor, int remainder, unsigned int *count))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glXWaitVideoSyncSGI")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+
+_EVASGL_EXT_END()
+
+_EVASGL_EXT_BEGIN(GLX_EXT_texture_from_pixmap)
+       _EVASGL_EXT_DRVNAME(GLX_EXT_texture_from_pixmap)
+
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void, glXBindTexImageEXT, (Display *display, GLXDrawable drawable, int buffer, const int *attrib_list))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glXBindTexImageEXT")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+       _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void, glXReleaseTexImageEXT, (Display *display, GLXDrawable drawable, int buffer))
+                _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR("glXReleaseTexImageEXT")
+       _EVASGL_EXT_FUNCTION_PRIVATE_END()
+
+_EVASGL_EXT_END()
+
+#endif
+#endif
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN_DEFINED
+#undef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN
+#undef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN_DEFINED
+#endif
+
+#ifdef _EVASGL_EXT_FUNCTION_PRIVATE_END_DEFINED
+#undef _EVASGL_EXT_FUNCTION_PRIVATE_END
+#undef _EVASGL_EXT_FUNCTION_PRIVATE_END_DEFINED
+#endif
+
+#ifdef _EVASGL_EXT_USE_DEFAULT_DEFINE
+#undef _EVASGL_EXT_CHECK_SUPPORT
+#undef _EVASGL_EXT_DISCARD_SUPPORT
+#undef _EVASGL_EXT_BEGIN
+#undef _EVASGL_EXT_END
+#undef _EVASGL_EXT_DRVNAME
+#undef _EVASGL_EXT_FUNCTION_BEGIN
+#undef _EVASGL_EXT_FUNCTION_END
+#undef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN
+#undef _EVASGL_EXT_FUNCTION_PRIVATE_END
+#undef _EVASGL_EXT_FUNCTION_DRVFUNC
+#endif
+
+
diff --git a/src/modules/engines/gl_common/evas_gl_api_gles1.c b/src/modules/engines/gl_common/evas_gl_api_gles1.c
new file mode 100644 (file)
index 0000000..3d402e5
--- /dev/null
@@ -0,0 +1,4326 @@
+#include "evas_gl_core_private.h"
+
+#include <dlfcn.h>
+
+#define EVGL_FUNC_BEGIN() \
+{ \
+   _func_begin_debug(__FUNCTION__); \
+}
+
+#define EVGL_FUNC_END()
+
+static void *_gles1_handle = NULL;
+static Evas_GL_API _gles1_api;
+
+void
+compute_gl_coordinates(int win_w, int win_h, int rot, int clip_image,
+                       int x, int y, int width, int height,
+                       int img_x, int img_y, int img_w, int img_h,
+                       int clip_x, int clip_y, int clip_w, int clip_h,
+                       int imgc[4], int objc[4], int cc[4]);
+
+//---------------------------------------//
+// API Debug Error Checking Code
+
+static
+void _make_current_check(const char* api)
+{
+   EVGL_Context *ctx = NULL;
+
+   ctx = _evgl_current_context_get();
+
+   if (!ctx)
+     CRIT("\e[1;33m%s\e[m: Current Context NOT SET: GL Call Should NOT Be Called without MakeCurrent!!!", api);
+   else if (ctx->version != EVAS_GL_GLES_1_X)
+     CRIT("\e[1;33m%s\e[m: This API is being called with the wrong context (invalid version).", api);
+}
+
+static
+void _direct_rendering_check(const char *api)
+{
+   EVGL_Context *ctx = NULL;
+
+   ctx = _evgl_current_context_get();
+   if (!ctx)
+     {
+        ERR("Current Context Not Set");
+        return;
+     }
+
+   if (_evgl_not_in_pixel_get())
+     CRIT("\e[1;33m%s\e[m: This API is being called outside Pixel Get Callback Function.", api);
+   else if (ctx->version != EVAS_GL_GLES_1_X)
+     CRIT("\e[1;33m%s\e[m: This API is being called with the wrong context (invalid version).", api);
+}
+
+static
+void _func_begin_debug(const char *api)
+{
+   _make_current_check(api);
+   _direct_rendering_check(api);
+}
+
+
+static void
+_evgl_gles1_glAlphaFunc(GLenum func, GLclampf ref)
+{
+   if (!_gles1_api.glAlphaFunc)
+     return;
+   _gles1_api.glAlphaFunc(func, ref);
+}
+
+static void
+_evgl_gles1_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+   EVGL_Resource *rsc;
+
+   if (!_gles1_api.glClearColor)
+     return;
+
+   if (!(rsc=_evgl_tls_resource_get()))
+     {
+        ERR("Unable to execute GL command. Error retrieving tls");
+        return;
+     }
+
+   if (_evgl_direct_enabled())
+     {
+        rsc->clear_color.a = alpha;
+        rsc->clear_color.r = red;
+        rsc->clear_color.g = green;
+        rsc->clear_color.b = blue;
+     }
+   _gles1_api.glClearColor(red, green, blue, alpha);
+}
+
+static void
+_evgl_gles1_glClearDepthf(GLclampf depth)
+{
+   if (!_gles1_api.glClearDepthf)
+     return;
+   _gles1_api.glClearDepthf(depth);
+}
+
+static void
+_evgl_gles1_glClipPlanef(GLenum plane, const GLfloat *equation)
+{
+   if (!_gles1_api.glClipPlanef)
+     return;
+   _gles1_api.glClipPlanef(plane, equation);
+}
+
+static void
+_evgl_gles1_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+   if (!_gles1_api.glColor4f)
+     return;
+   _gles1_api.glColor4f(red, green, blue, alpha);
+}
+
+static void
+_evgl_gles1_glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+   if (!_gles1_api.glDepthRangef)
+     return;
+   _gles1_api.glDepthRangef(zNear, zFar);
+}
+
+static void
+_evgl_gles1_glFogf(GLenum pname, GLfloat param)
+{
+   if (!_gles1_api.glFogf)
+     return;
+   _gles1_api.glFogf(pname, param);
+}
+
+static void
+_evgl_gles1_glFogfv(GLenum pname, const GLfloat *params)
+{
+   if (!_gles1_api.glFogfv)
+     return;
+   _gles1_api.glFogfv(pname, params);
+}
+
+static void
+_evgl_gles1_glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+   if (!_gles1_api.glFrustumf)
+     return;
+   _gles1_api.glFrustumf(left, right, bottom, top, zNear, zFar);
+}
+
+static void
+_evgl_gles1_glGetClipPlanef(GLenum pname, GLfloat eqn[4])
+{
+   if (!_gles1_api.glGetClipPlanef)
+     return;
+   _gles1_api.glGetClipPlanef(pname, eqn);
+}
+
+static void
+_evgl_gles1_glGetFloatv(GLenum pname, GLfloat *params)
+{
+   if (!_gles1_api.glGetFloatv)
+     return;
+   _gles1_api.glGetFloatv(pname, params);
+}
+
+static void
+_evgl_gles1_glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
+{
+   if (!_gles1_api.glGetLightfv)
+     return;
+   _gles1_api.glGetLightfv(light, pname, params);
+}
+
+static void
+_evgl_gles1_glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
+{
+   if (!_gles1_api.glGetMaterialfv)
+     return;
+   _gles1_api.glGetMaterialfv(face, pname, params);
+}
+
+static void
+_evgl_gles1_glGetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)
+{
+   if (!_gles1_api.glGetTexEnvfv)
+     return;
+   _gles1_api.glGetTexEnvfv(env, pname, params);
+}
+
+static void
+_evgl_gles1_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+   if (!_gles1_api.glGetTexParameterfv)
+     return;
+   _gles1_api.glGetTexParameterfv(target, pname, params);
+}
+
+static void
+_evgl_gles1_glLightModelf(GLenum pname, GLfloat param)
+{
+   if (!_gles1_api.glLightModelf)
+     return;
+   _gles1_api.glLightModelf(pname, param);
+}
+
+static void
+_evgl_gles1_glLightModelfv(GLenum pname, const GLfloat *params)
+{
+   if (!_gles1_api.glLightModelfv)
+     return;
+   _gles1_api.glLightModelfv(pname, params);
+}
+
+static void
+_evgl_gles1_glLightf(GLenum light, GLenum pname, GLfloat param)
+{
+   if (!_gles1_api.glLightf)
+     return;
+   _gles1_api.glLightf(light, pname, param);
+}
+
+static void
+_evgl_gles1_glLightfv(GLenum light, GLenum pname, const GLfloat *params)
+{
+   if (!_gles1_api.glLightfv)
+     return;
+   _gles1_api.glLightfv(light, pname, params);
+}
+
+static void
+_evgl_gles1_glLineWidth(GLfloat width)
+{
+   if (!_gles1_api.glLineWidth)
+     return;
+   _gles1_api.glLineWidth(width);
+}
+
+static void
+_evgl_gles1_glLoadMatrixf(const GLfloat *m)
+{
+   if (!_gles1_api.glLoadMatrixf)
+     return;
+   _gles1_api.glLoadMatrixf(m);
+}
+
+static void
+_evgl_gles1_glMaterialf(GLenum face, GLenum pname, GLfloat param)
+{
+   if (!_gles1_api.glMaterialf)
+     return;
+   _gles1_api.glMaterialf(face, pname, param);
+}
+
+static void
+_evgl_gles1_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+   if (!_gles1_api.glMaterialfv)
+     return;
+   _gles1_api.glMaterialfv(face, pname, params);
+}
+
+static void
+_evgl_gles1_glMultMatrixf(const GLfloat *m)
+{
+   if (!_gles1_api.glMultMatrixf)
+     return;
+   _gles1_api.glMultMatrixf(m);
+}
+
+static void
+_evgl_gles1_glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+   if (!_gles1_api.glMultiTexCoord4f)
+     return;
+   _gles1_api.glMultiTexCoord4f(target, s, t, r, q);
+}
+
+static void
+_evgl_gles1_glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+   if (!_gles1_api.glNormal3f)
+     return;
+   _gles1_api.glNormal3f(nx, ny, nz);
+}
+
+static void
+_evgl_gles1_glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+   if (!_gles1_api.glOrthof)
+     return;
+   _gles1_api.glOrthof(left, right, bottom, top, zNear, zFar);
+}
+
+static void
+_evgl_gles1_glPointParameterf(GLenum pname, GLfloat param)
+{
+   if (!_gles1_api.glPointParameterf)
+     return;
+   _gles1_api.glPointParameterf(pname, param);
+}
+
+static void
+_evgl_gles1_glPointParameterfv(GLenum pname, const GLfloat *params)
+{
+   if (!_gles1_api.glPointParameterfv)
+     return;
+   _gles1_api.glPointParameterfv(pname, params);
+}
+
+static void
+_evgl_gles1_glPointSize(GLfloat size)
+{
+   if (!_gles1_api.glPointSize)
+     return;
+   _gles1_api.glPointSize(size);
+}
+
+static void
+_evgl_gles1_glPointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+   if (!_gles1_api.glPointSizePointerOES)
+     return;
+   _gles1_api.glPointSizePointerOES(type, stride, pointer);
+}
+
+static void
+_evgl_gles1_glPolygonOffset(GLfloat factor, GLfloat units)
+{
+   if (!_gles1_api.glPolygonOffset)
+     return;
+   _gles1_api.glPolygonOffset(factor, units);
+}
+
+static void
+_evgl_gles1_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+   if (!_gles1_api.glRotatef)
+     return;
+   _gles1_api.glRotatef(angle, x, y, z);
+}
+
+static void
+_evgl_gles1_glScalef(GLfloat x, GLfloat y, GLfloat z)
+{
+   if (!_gles1_api.glScalef)
+     return;
+   _gles1_api.glScalef(x, y, z);
+}
+
+static void
+_evgl_gles1_glTexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+   if (!_gles1_api.glTexEnvf)
+     return;
+   _gles1_api.glTexEnvf(target, pname, param);
+}
+
+static void
+_evgl_gles1_glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+   if (!_gles1_api.glTexEnvfv)
+     return;
+   _gles1_api.glTexEnvfv(target, pname, params);
+}
+
+static void
+_evgl_gles1_glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+   if (!_gles1_api.glTexParameterf)
+     return;
+   _gles1_api.glTexParameterf(target, pname, param);
+}
+
+static void
+_evgl_gles1_glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+   if (!_gles1_api.glTexParameterfv)
+     return;
+   _gles1_api.glTexParameterfv(target, pname, params);
+}
+
+static void
+_evgl_gles1_glTranslatef(GLfloat x, GLfloat y, GLfloat z)
+{
+   if (!_gles1_api.glTranslatef)
+     return;
+   _gles1_api.glTranslatef(x, y, z);
+}
+
+static void
+_evgl_gles1_glActiveTexture(GLenum texture)
+{
+   if (!_gles1_api.glActiveTexture)
+     return;
+   _gles1_api.glActiveTexture(texture);
+}
+
+static void
+_evgl_gles1_glAlphaFuncx(GLenum func, GLclampx ref)
+{
+   if (!_gles1_api.glAlphaFuncx)
+     return;
+   _gles1_api.glAlphaFuncx(func, ref);
+}
+
+static void
+_evgl_gles1_glBindBuffer(GLenum target, GLuint buffer)
+{
+   if (!_gles1_api.glBindBuffer)
+     return;
+   _gles1_api.glBindBuffer(target, buffer);
+}
+
+static void
+_evgl_gles1_glBindTexture(GLenum target, GLuint texture)
+{
+   if (!_gles1_api.glBindTexture)
+     return;
+   _gles1_api.glBindTexture(target, texture);
+}
+
+static void
+_evgl_gles1_glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+   if (!_gles1_api.glBlendFunc)
+     return;
+   _gles1_api.glBlendFunc(sfactor, dfactor);
+}
+
+static void
+_evgl_gles1_glBufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
+{
+   if (!_gles1_api.glBufferData)
+     return;
+   _gles1_api.glBufferData(target, size, data, usage);
+}
+
+static void
+_evgl_gles1_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
+{
+   if (!_gles1_api.glBufferSubData)
+     return;
+   _gles1_api.glBufferSubData(target, offset, size, data);
+}
+
+static void
+_evgl_gles1_glClear(GLbitfield mask)
+{
+   EVGL_Resource *rsc;
+   EVGL_Context *ctx;
+   int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0};
+   int cc[4] = {0,0,0,0};
+
+   if (!_gles1_api.glClear)
+     return;
+
+   if (!(rsc=_evgl_tls_resource_get()))
+     {
+        ERR("Unable to execute GL command. Error retrieving tls");
+        return;
+     }
+
+   if (!rsc->current_eng)
+     {
+        ERR("Unable to retrive Current Engine");
+        return;
+     }
+
+   ctx = rsc->current_ctx;
+   if (!ctx)
+     {
+        ERR("Unable to retrive Current Context");
+        return;
+     }
+
+   if (ctx->version != EVAS_GL_GLES_1_X)
+     {
+        ERR("Invalid context version %d", (int) ctx->version);
+        return;
+     }
+
+   if (_evgl_direct_enabled())
+     {
+        if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex)
+          {
+             /* Skip glClear() if clearing with transparent color
+              * Note: There will be side effects if the object itself is not
+              * marked as having an alpha channel!
+              */
+             if (ctx->current_sfc->alpha && (mask & GL_COLOR_BUFFER_BIT))
+               {
+                  if ((rsc->clear_color.a == 0) &&
+                      (rsc->clear_color.r == 0) &&
+                      (rsc->clear_color.g == 0) &&
+                      (rsc->clear_color.b == 0))
+                    {
+                       // Skip clear color as we don't want to write black
+                       mask &= ~GL_COLOR_BUFFER_BIT;
+                    }
+                  else if (rsc->clear_color.a != 1.0)
+                    {
+                       // TODO: Draw a rectangle? This will never be the perfect solution though.
+                       WRN("glClear() used with a semi-transparent color and direct rendering. "
+                           "This will erase the previous contents of the evas!");
+                    }
+                  if (!mask) return;
+               }
+
+             if ((!ctx->direct_scissor))
+               {
+                  _gles1_api.glEnable(GL_SCISSOR_TEST);
+                  ctx->direct_scissor = 1;
+               }
+
+             if ((ctx->scissor_updated) && (ctx->scissor_enabled))
+               {
+                  compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h,
+                                         rsc->direct.rot, 1,
+                                         ctx->scissor_coord[0], ctx->scissor_coord[1],
+                                         ctx->scissor_coord[2], ctx->scissor_coord[3],
+                                         rsc->direct.img.x, rsc->direct.img.y,
+                                         rsc->direct.img.w, rsc->direct.img.h,
+                                         rsc->direct.clip.x, rsc->direct.clip.y,
+                                         rsc->direct.clip.w, rsc->direct.clip.h,
+                                         oc, nc, cc);
+
+                  RECTS_CLIP_TO_RECT(nc[0], nc[1], nc[2], nc[3], cc[0], cc[1], cc[2], cc[3]);
+                  _gles1_api.glScissor(nc[0], nc[1], nc[2], nc[3]);
+                  ctx->direct_scissor = 0;
+               }
+             else
+               {
+                  compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h,
+                                         rsc->direct.rot, 0,
+                                         0, 0, 0, 0,
+                                         rsc->direct.img.x, rsc->direct.img.y,
+                                         rsc->direct.img.w, rsc->direct.img.h,
+                                         rsc->direct.clip.x, rsc->direct.clip.y,
+                                         rsc->direct.clip.w, rsc->direct.clip.h,
+                                         oc, nc, cc);
+
+                  _gles1_api.glScissor(cc[0], cc[1], cc[2], cc[3]);
+               }
+
+             _gles1_api.glClear(mask);
+
+             // TODO/FIXME: Restore previous client-side scissors.
+          }
+        else
+          {
+             if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+               {
+                  _gles1_api.glDisable(GL_SCISSOR_TEST);
+                  ctx->direct_scissor = 0;
+               }
+
+             _gles1_api.glClear(mask);
+          }
+     }
+   else
+     {
+        if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+          {
+             _gles1_api.glDisable(GL_SCISSOR_TEST);
+             ctx->direct_scissor = 0;
+          }
+
+        _gles1_api.glClear(mask);
+     }
+}
+
+static void
+_evgl_gles1_glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+{
+   if (!_gles1_api.glClearColorx)
+     return;
+   _gles1_api.glClearColorx(red, green, blue, alpha);
+}
+
+static void
+_evgl_gles1_glClearDepthx(GLclampx depth)
+{
+   if (!_gles1_api.glClearDepthx)
+     return;
+   _gles1_api.glClearDepthx(depth);
+}
+
+static void
+_evgl_gles1_glClearStencil(GLint s)
+{
+   if (!_gles1_api.glClearStencil)
+     return;
+   _gles1_api.glClearStencil(s);
+}
+
+static void
+_evgl_gles1_glClientActiveTexture(GLenum texture)
+{
+   if (!_gles1_api.glClientActiveTexture)
+     return;
+   _gles1_api.glClientActiveTexture(texture);
+}
+
+static void
+_evgl_gles1_glClipPlanex(GLenum plane, const GLfixed *equation)
+{
+   if (!_gles1_api.glClipPlanex)
+     return;
+   _gles1_api.glClipPlanex(plane, equation);
+}
+
+static void
+_evgl_gles1_glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+   if (!_gles1_api.glColor4ub)
+     return;
+   _gles1_api.glColor4ub(red, green, blue, alpha);
+}
+
+static void
+_evgl_gles1_glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+   if (!_gles1_api.glColor4x)
+     return;
+   _gles1_api.glColor4x(red, green, blue, alpha);
+}
+
+static void
+_evgl_gles1_glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+   if (!_gles1_api.glColorMask)
+     return;
+   _gles1_api.glColorMask(red, green, blue, alpha);
+}
+
+static void
+_evgl_gles1_glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+   if (!_gles1_api.glColorPointer)
+     return;
+   _gles1_api.glColorPointer(size, type, stride, pointer);
+}
+
+static void
+_evgl_gles1_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data)
+{
+   if (!_gles1_api.glCompressedTexImage2D)
+     return;
+   _gles1_api.glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+}
+
+static void
+_evgl_gles1_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data)
+{
+   if (!_gles1_api.glCompressedTexSubImage2D)
+     return;
+   _gles1_api.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+
+static void
+_evgl_gles1_glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+   if (!_gles1_api.glCopyTexImage2D)
+     return;
+   _gles1_api.glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+}
+
+static void
+_evgl_gles1_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+   if (!_gles1_api.glCopyTexSubImage2D)
+     return;
+   _gles1_api.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+}
+
+static void
+_evgl_gles1_glCullFace(GLenum mode)
+{
+   if (!_gles1_api.glCullFace)
+     return;
+   _gles1_api.glCullFace(mode);
+}
+
+static void
+_evgl_gles1_glDeleteBuffers(GLsizei n, const GLuint *buffers)
+{
+   if (!_gles1_api.glDeleteBuffers)
+     return;
+   _gles1_api.glDeleteBuffers(n, buffers);
+}
+
+static void
+_evgl_gles1_glDeleteTextures(GLsizei n, const GLuint *textures)
+{
+   if (!_gles1_api.glDeleteTextures)
+     return;
+   _gles1_api.glDeleteTextures(n, textures);
+}
+
+static void
+_evgl_gles1_glDepthFunc(GLenum func)
+{
+   if (!_gles1_api.glDepthFunc)
+     return;
+   _gles1_api.glDepthFunc(func);
+}
+
+static void
+_evgl_gles1_glDepthMask(GLboolean flag)
+{
+   if (!_gles1_api.glDepthMask)
+     return;
+   _gles1_api.glDepthMask(flag);
+}
+
+static void
+_evgl_gles1_glDepthRangex(GLclampx zNear, GLclampx zFar)
+{
+   if (!_gles1_api.glDepthRangex)
+     return;
+   _gles1_api.glDepthRangex(zNear, zFar);
+}
+
+static void
+_evgl_gles1_glDisable(GLenum cap)
+{
+   EVGL_Context *ctx;
+
+   if (!_gles1_api.glDisable)
+     return;
+
+   ctx = _evgl_current_context_get();
+   if (!ctx)
+     {
+        ERR("Unable to retrive Current Context");
+        return;
+     }
+
+   if (ctx->version != EVAS_GL_GLES_1_X)
+     {
+        ERR("Invalid context version %d", (int) ctx->version);
+        return;
+     }
+
+   if (cap == GL_SCISSOR_TEST)
+      ctx->scissor_enabled = 0;
+   _gles1_api.glDisable(cap);
+}
+
+static void
+_evgl_gles1_glDisableClientState(GLenum array)
+{
+   if (!_gles1_api.glDisableClientState)
+     return;
+   _gles1_api.glDisableClientState(array);
+}
+
+static void
+_evgl_gles1_glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+   if (!_gles1_api.glDrawArrays)
+     return;
+   _gles1_api.glDrawArrays(mode, first, count);
+}
+
+static void
+_evgl_gles1_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
+{
+   if (!_gles1_api.glDrawElements)
+     return;
+   _gles1_api.glDrawElements(mode, count, type, indices);
+}
+
+static void
+_evgl_gles1_glEnable(GLenum cap)
+{
+   EVGL_Context *ctx;
+
+   if (!_gles1_api.glEnable)
+     return;
+
+   ctx = _evgl_current_context_get();
+   if (!ctx)
+     {
+        ERR("Unable to retrive Current Context");
+        return;
+     }
+
+   if (ctx->version != EVAS_GL_GLES_1_X)
+     {
+        ERR("Invalid context version %d", (int) ctx->version);
+        return;
+     }
+
+   if (cap == GL_SCISSOR_TEST)
+      ctx->scissor_enabled = 1;
+   _gles1_api.glEnable(cap);
+}
+
+static void
+_evgl_gles1_glEnableClientState(GLenum array)
+{
+   if (!_gles1_api.glEnableClientState)
+     return;
+   _gles1_api.glEnableClientState(array);
+}
+
+static void
+_evgl_gles1_glFinish(void)
+{
+   if (!_gles1_api.glFinish)
+     return;
+   _gles1_api.glFinish();
+}
+
+static void
+_evgl_gles1_glFlush(void)
+{
+   if (!_gles1_api.glFlush)
+     return;
+   _gles1_api.glFlush();
+}
+
+static void
+_evgl_gles1_glFogx(GLenum pname, GLfixed param)
+{
+   if (!_gles1_api.glFogx)
+     return;
+   _gles1_api.glFogx(pname, param);
+}
+
+static void
+_evgl_gles1_glFogxv(GLenum pname, const GLfixed *params)
+{
+   if (!_gles1_api.glFogxv)
+     return;
+   _gles1_api.glFogxv(pname, params);
+}
+
+static void
+_evgl_gles1_glFrontFace(GLenum mode)
+{
+   if (!_gles1_api.glFrontFace)
+     return;
+   _gles1_api.glFrontFace(mode);
+}
+
+static void
+_evgl_gles1_glFrustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+   if (!_gles1_api.glFrustumx)
+     return;
+   _gles1_api.glFrustumx(left, right, bottom, top, zNear, zFar);
+}
+
+static void
+_evgl_gles1_glGetBooleanv(GLenum pname, GLboolean *params)
+{
+   if (!_gles1_api.glGetBooleanv)
+     return;
+   _gles1_api.glGetBooleanv(pname, params);
+}
+
+static void
+_evgl_gles1_glGetBufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+   if (!_gles1_api.glGetBufferParameteriv)
+     return;
+   _gles1_api.glGetBufferParameteriv(target, pname, params);
+}
+
+static void
+_evgl_gles1_glGetClipPlanex(GLenum pname, GLfixed eqn[4])
+{
+   if (!_gles1_api.glGetClipPlanex)
+     return;
+   _gles1_api.glGetClipPlanex(pname, eqn);
+}
+
+static void
+_evgl_gles1_glGenBuffers(GLsizei n, GLuint *buffers)
+{
+   if (!_gles1_api.glGenBuffers)
+     return;
+   _gles1_api.glGenBuffers(n, buffers);
+}
+
+static void
+_evgl_gles1_glGenTextures(GLsizei n, GLuint *textures)
+{
+   if (!_gles1_api.glGenTextures)
+     return;
+   _gles1_api.glGenTextures(n, textures);
+}
+
+static GLenum
+_evgl_gles1_glGetError(void)
+{
+   GLenum ret;
+   if (!_gles1_api.glGetError)
+     return EVAS_GL_NOT_INITIALIZED;
+   ret = _gles1_api.glGetError();
+   return ret;
+}
+
+static void
+_evgl_gles1_glGetFixedv(GLenum pname, GLfixed *params)
+{
+   if (!_gles1_api.glGetFixedv)
+     return;
+   _gles1_api.glGetFixedv(pname, params);
+}
+
+static void
+_evgl_gles1_glGetIntegerv(GLenum pname, GLint *params)
+{
+   EVGL_Resource *rsc;
+   EVGL_Context *ctx;
+
+   if (!_gles1_api.glGetIntegerv)
+     return;
+
+   if (_evgl_direct_enabled())
+     {
+        if (!params)
+          {
+             ERR("Inavlid Parameter");
+             return;
+          }
+
+        if (!(rsc=_evgl_tls_resource_get()))
+          {
+             ERR("Unable to execute GL command. Error retrieving tls");
+             return;
+          }
+
+        ctx = rsc->current_ctx;
+        if (!ctx)
+          {
+             ERR("Unable to retrive Current Context");
+             return;
+          }
+
+        if (ctx->version != EVAS_GL_GLES_1_X)
+          {
+             ERR("Invalid context version %d", (int) ctx->version);
+             return;
+          }
+
+        // Only need to handle it if it's directly rendering to the window
+        if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex)
+          {
+             if (pname == GL_SCISSOR_BOX)
+               {
+                  if (ctx->scissor_updated)
+                    {
+                       memcpy(params, ctx->scissor_coord, sizeof(int)*4);
+                       return;
+                    }
+               }
+             /*!!! Temporary Fixes to avoid Webkit issue
+             if (pname == GL_VIEWPORT)
+               {
+                  if (ctx->viewport_updated)
+                    {
+                       memcpy(params, ctx->viewport_coord, sizeof(int)*4);
+                       return;
+                    }
+               }
+               */
+
+             // If it hasn't been initialized yet, return img object size
+             if ((pname == GL_SCISSOR_BOX)) //|| (pname == GL_VIEWPORT))
+               {
+                  params[0] = 0;
+                  params[1] = 0;
+                  params[2] = (GLint)rsc->direct.img.w;
+                  params[3] = (GLint)rsc->direct.img.h;
+                  return;
+               }
+          }
+     }
+
+   _gles1_api.glGetIntegerv(pname, params);
+}
+
+static void
+_evgl_gles1_glGetLightxv(GLenum light, GLenum pname, GLfixed *params)
+{
+   if (!_gles1_api.glGetLightxv)
+     return;
+   _gles1_api.glGetLightxv(light, pname, params);
+}
+
+static void
+_evgl_gles1_glGetMaterialxv(GLenum face, GLenum pname, GLfixed *params)
+{
+   if (!_gles1_api.glGetMaterialxv)
+     return;
+   _gles1_api.glGetMaterialxv(face, pname, params);
+}
+
+static void
+_evgl_gles1_glGetPointerv(GLenum pname, GLvoid **params)
+{
+   if (!_gles1_api.glGetPointerv)
+     return;
+   _gles1_api.glGetPointerv(pname, params);
+}
+
+static const GLubyte *
+_evgl_gles1_glGetString(GLenum name)
+{
+   EVGL_Resource *rsc;
+
+   if (!_gles1_api.glGetString)
+     return NULL;
+
+   if (!name)
+     {
+        ERR("Invalid parameter");
+        return NULL;
+     }
+
+   if (!(rsc=_evgl_tls_resource_get()))
+     {
+        ERR("Unable to execute GL command. Error retrieving tls");
+        return NULL;
+     }
+
+   if (!rsc->current_ctx)
+     {
+        ERR("Unable to retrive Current Context");
+        return NULL;
+     }
+
+   if (rsc->current_ctx->version != EVAS_GL_GLES_1_X)
+     {
+        ERR("Invalid context version %d", (int) rsc->current_ctx->version);
+        return NULL;
+     }
+
+   switch (name)
+     {
+      case GL_VENDOR:
+      case GL_RENDERER:
+      case GL_SHADING_LANGUAGE_VERSION:
+      case GL_VERSION:
+        break;
+
+      case GL_EXTENSIONS:
+        return (GLubyte *) evgl_api_ext_string_get(EINA_TRUE, EINA_TRUE);
+
+      default:
+        WRN("Unknown string requested: %x", (unsigned int) name);
+        break;
+     }
+
+   return _gles1_api.glGetString(name);
+}
+
+static void
+_evgl_gles1_glGetTexEnviv(GLenum env, GLenum pname, GLint *params)
+{
+   if (!_gles1_api.glGetTexEnviv)
+     return;
+   _gles1_api.glGetTexEnviv(env, pname, params);
+}
+
+static void
+_evgl_gles1_glGetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)
+{
+   if (!_gles1_api.glGetTexEnvxv)
+     return;
+   _gles1_api.glGetTexEnvxv(env, pname, params);
+}
+
+static void
+_evgl_gles1_glGetTexParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+   if (!_gles1_api.glGetTexParameteriv)
+     return;
+   _gles1_api.glGetTexParameteriv(target, pname, params);
+}
+
+static void
+_evgl_gles1_glGetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
+{
+   if (!_gles1_api.glGetTexParameterxv)
+     return;
+   _gles1_api.glGetTexParameterxv(target, pname, params);
+}
+
+static void
+_evgl_gles1_glHint(GLenum target, GLenum mode)
+{
+   if (!_gles1_api.glHint)
+     return;
+   _gles1_api.glHint(target, mode);
+}
+
+static GLboolean
+_evgl_gles1_glIsBuffer(GLuint buffer)
+{
+   GLboolean ret;
+   if (!_gles1_api.glIsBuffer)
+     return EINA_FALSE;
+   ret = _gles1_api.glIsBuffer(buffer);
+   return ret;
+}
+
+static GLboolean
+_evgl_gles1_glIsEnabled(GLenum cap)
+{
+   GLboolean ret;
+   if (!_gles1_api.glIsEnabled)
+     return EINA_FALSE;
+   ret = _gles1_api.glIsEnabled(cap);
+   return ret;
+}
+
+static GLboolean
+_evgl_gles1_glIsTexture(GLuint texture)
+{
+   GLboolean ret;
+   if (!_gles1_api.glIsTexture)
+     return EINA_FALSE;
+   ret = _gles1_api.glIsTexture(texture);
+   return ret;
+}
+
+static void
+_evgl_gles1_glLightModelx(GLenum pname, GLfixed param)
+{
+   if (!_gles1_api.glLightModelx)
+     return;
+   _gles1_api.glLightModelx(pname, param);
+}
+
+static void
+_evgl_gles1_glLightModelxv(GLenum pname, const GLfixed *params)
+{
+   if (!_gles1_api.glLightModelxv)
+     return;
+   _gles1_api.glLightModelxv(pname, params);
+}
+
+static void
+_evgl_gles1_glLightx(GLenum light, GLenum pname, GLfixed param)
+{
+   if (!_gles1_api.glLightx)
+     return;
+   _gles1_api.glLightx(light, pname, param);
+}
+
+static void
+_evgl_gles1_glLightxv(GLenum light, GLenum pname, const GLfixed *params)
+{
+   if (!_gles1_api.glLightxv)
+     return;
+   _gles1_api.glLightxv(light, pname, params);
+}
+
+static void
+_evgl_gles1_glLineWidthx(GLfixed width)
+{
+   if (!_gles1_api.glLineWidthx)
+     return;
+   _gles1_api.glLineWidthx(width);
+}
+
+static void
+_evgl_gles1_glLoadIdentity(void)
+{
+   if (!_gles1_api.glLoadIdentity)
+     return;
+   _gles1_api.glLoadIdentity();
+}
+
+static void
+_evgl_gles1_glLoadMatrixx(const GLfixed *m)
+{
+   if (!_gles1_api.glLoadMatrixx)
+     return;
+   _gles1_api.glLoadMatrixx(m);
+}
+
+static void
+_evgl_gles1_glLogicOp(GLenum opcode)
+{
+   if (!_gles1_api.glLogicOp)
+     return;
+   _gles1_api.glLogicOp(opcode);
+}
+
+static void
+_evgl_gles1_glMaterialx(GLenum face, GLenum pname, GLfixed param)
+{
+   if (!_gles1_api.glMaterialx)
+     return;
+   _gles1_api.glMaterialx(face, pname, param);
+}
+
+static void
+_evgl_gles1_glMaterialxv(GLenum face, GLenum pname, const GLfixed *params)
+{
+   if (!_gles1_api.glMaterialxv)
+     return;
+   _gles1_api.glMaterialxv(face, pname, params);
+}
+
+static void
+_evgl_gles1_glMatrixMode(GLenum mode)
+{
+   if (!_gles1_api.glMatrixMode)
+     return;
+   _gles1_api.glMatrixMode(mode);
+}
+
+static void
+_evgl_gles1_glMultMatrixx(const GLfixed *m)
+{
+   if (!_gles1_api.glMultMatrixx)
+     return;
+   _gles1_api.glMultMatrixx(m);
+}
+
+static void
+_evgl_gles1_glMultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+   if (!_gles1_api.glMultiTexCoord4x)
+     return;
+   _gles1_api.glMultiTexCoord4x(target, s, t, r, q);
+}
+
+static void
+_evgl_gles1_glNormal3x(GLfixed nx, GLfixed ny, GLfixed nz)
+{
+   if (!_gles1_api.glNormal3x)
+     return;
+   _gles1_api.glNormal3x(nx, ny, nz);
+}
+
+static void
+_evgl_gles1_glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+   if (!_gles1_api.glNormalPointer)
+     return;
+   _gles1_api.glNormalPointer(type, stride, pointer);
+}
+
+static void
+_evgl_gles1_glOrthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+   if (!_gles1_api.glOrthox)
+     return;
+   _gles1_api.glOrthox(left, right, bottom, top, zNear, zFar);
+}
+
+static void
+_evgl_gles1_glPixelStorei(GLenum pname, GLint param)
+{
+   if (!_gles1_api.glPixelStorei)
+     return;
+   _gles1_api.glPixelStorei(pname, param);
+}
+
+static void
+_evgl_gles1_glPointParameterx(GLenum pname, GLfixed param)
+{
+   if (!_gles1_api.glPointParameterx)
+     return;
+   _gles1_api.glPointParameterx(pname, param);
+}
+
+static void
+_evgl_gles1_glPointParameterxv(GLenum pname, const GLfixed *params)
+{
+   if (!_gles1_api.glPointParameterxv)
+     return;
+   _gles1_api.glPointParameterxv(pname, params);
+}
+
+static void
+_evgl_gles1_glPointSizex(GLfixed size)
+{
+   if (!_gles1_api.glPointSizex)
+     return;
+   _gles1_api.glPointSizex(size);
+}
+
+static void
+_evgl_gles1_glPolygonOffsetx(GLfixed factor, GLfixed units)
+{
+   if (!_gles1_api.glPolygonOffsetx)
+     return;
+   _gles1_api.glPolygonOffsetx(factor, units);
+}
+
+static void
+_evgl_gles1_glPopMatrix(void)
+{
+   if (!_gles1_api.glPopMatrix)
+     return;
+   _gles1_api.glPopMatrix();
+}
+
+static void
+_evgl_gles1_glPushMatrix(void)
+{
+   if (!_gles1_api.glPushMatrix)
+     return;
+   _gles1_api.glPushMatrix();
+}
+
+static void
+_evgl_gles1_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
+{
+   EVGL_Resource *rsc;
+   EVGL_Context *ctx;
+   int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0};
+   int cc[4] = {0,0,0,0};
+
+   if (!_gles1_api.glReadPixels)
+     return;
+
+   if (!(rsc=_evgl_tls_resource_get()))
+     {
+        ERR("Unable to execute GL command. Error retrieving tls");
+        return;
+     }
+
+   if (!rsc->current_eng)
+     {
+        ERR("Unable to retrive Current Engine");
+        return;
+     }
+
+   ctx = rsc->current_ctx;
+   if (!ctx)
+     {
+        ERR("Unable to retrive Current Context");
+        return;
+     }
+
+   if (ctx->version != EVAS_GL_GLES_1_X)
+     {
+        ERR("Invalid context version %d", (int) ctx->version);
+        return;
+     }
+
+   if (_evgl_direct_enabled())
+     {
+        if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex)
+          {
+             compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h,
+                                    rsc->direct.rot, 1,
+                                    x, y, width, height,
+                                    rsc->direct.img.x, rsc->direct.img.y,
+                                    rsc->direct.img.w, rsc->direct.img.h,
+                                    rsc->direct.clip.x, rsc->direct.clip.y,
+                                    rsc->direct.clip.w, rsc->direct.clip.h,
+                                    oc, nc, cc);
+             _gles1_api.glReadPixels(nc[0], nc[1], nc[2], nc[3], format, type, pixels);
+          }
+        else
+          {
+             _gles1_api.glReadPixels(x, y, width, height, format, type, pixels);
+          }
+     }
+   else
+     {
+        _gles1_api.glReadPixels(x, y, width, height, format, type, pixels);
+     }
+}
+
+static void
+_evgl_gles1_glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+   if (!_gles1_api.glRotatex)
+     return;
+   _gles1_api.glRotatex(angle, x, y, z);
+}
+
+static void
+_evgl_gles1_glSampleCoverage(GLclampf value, GLboolean invert)
+{
+   if (!_gles1_api.glSampleCoverage)
+     return;
+   _gles1_api.glSampleCoverage(value, invert);
+}
+
+static void
+_evgl_gles1_glSampleCoveragex(GLclampx value, GLboolean invert)
+{
+   if (!_gles1_api.glSampleCoveragex)
+     return;
+   _gles1_api.glSampleCoveragex(value, invert);
+}
+
+static void
+_evgl_gles1_glScalex(GLfixed x, GLfixed y, GLfixed z)
+{
+   if (!_gles1_api.glScalex)
+     return;
+   _gles1_api.glScalex(x, y, z);
+}
+
+static void
+_evgl_gles1_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+   EVGL_Resource *rsc;
+   EVGL_Context *ctx;
+   int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0};
+   int cc[4] = {0,0,0,0};
+
+   if (!_gles1_api.glScissor)
+     return;
+
+   if (!(rsc=_evgl_tls_resource_get()))
+     {
+        ERR("Unable to execute GL command. Error retrieving tls");
+        return;
+     }
+
+   if (!rsc->current_eng)
+     {
+        ERR("Unable to retrive Current Engine");
+        return;
+     }
+
+   ctx = rsc->current_ctx;
+   if (!ctx)
+     {
+        ERR("Unable to retrive Current Context");
+        return;
+     }
+
+   if (ctx->version != EVAS_GL_GLES_1_X)
+     {
+        ERR("Invalid context version %d", (int) ctx->version);
+        return;
+     }
+
+   if (_evgl_direct_enabled())
+     {
+        if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex)
+          {
+             if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+               {
+                  _gles1_api.glDisable(GL_SCISSOR_TEST);
+               }
+
+             compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h,
+                                    rsc->direct.rot, 1,
+                                    x, y, width, height,
+                                    rsc->direct.img.x, rsc->direct.img.y,
+                                    rsc->direct.img.w, rsc->direct.img.h,
+                                    rsc->direct.clip.x, rsc->direct.clip.y,
+                                    rsc->direct.clip.w, rsc->direct.clip.h,
+                                    oc, nc, cc);
+
+             // Keep a copy of the original coordinates
+             ctx->scissor_coord[0] = x;
+             ctx->scissor_coord[1] = y;
+             ctx->scissor_coord[2] = width;
+             ctx->scissor_coord[3] = height;
+
+             RECTS_CLIP_TO_RECT(nc[0], nc[1], nc[2], nc[3], cc[0], cc[1], cc[2], cc[3]);
+             _gles1_api.glScissor(nc[0], nc[1], nc[2], nc[3]);
+
+             ctx->direct_scissor = 0;
+
+             // Check....!!!!
+             ctx->scissor_updated = 1;
+          }
+        else
+          {
+             if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+               {
+                  _gles1_api.glDisable(GL_SCISSOR_TEST);
+                  ctx->direct_scissor = 0;
+               }
+
+             _gles1_api.glScissor(x, y, width, height);
+
+             ctx->scissor_updated = 0;
+          }
+     }
+   else
+     {
+        if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+          {
+             _gles1_api.glDisable(GL_SCISSOR_TEST);
+             ctx->direct_scissor = 0;
+          }
+
+        _gles1_api.glScissor(x, y, width, height);
+     }
+}
+
+static void
+_evgl_gles1_glShadeModel(GLenum mode)
+{
+   if (!_gles1_api.glShadeModel)
+     return;
+   _gles1_api.glShadeModel(mode);
+}
+
+static void
+_evgl_gles1_glStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+   if (!_gles1_api.glStencilFunc)
+     return;
+   _gles1_api.glStencilFunc(func, ref, mask);
+}
+
+static void
+_evgl_gles1_glStencilMask(GLuint mask)
+{
+   if (!_gles1_api.glStencilMask)
+     return;
+   _gles1_api.glStencilMask(mask);
+}
+
+static void
+_evgl_gles1_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+   if (!_gles1_api.glStencilOp)
+     return;
+   _gles1_api.glStencilOp(fail, zfail, zpass);
+}
+
+static void
+_evgl_gles1_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+   if (!_gles1_api.glTexCoordPointer)
+     return;
+   _gles1_api.glTexCoordPointer(size, type, stride, pointer);
+}
+
+static void
+_evgl_gles1_glTexEnvi(GLenum target, GLenum pname, GLint param)
+{
+   if (!_gles1_api.glTexEnvi)
+     return;
+   _gles1_api.glTexEnvi(target, pname, param);
+}
+
+static void
+_evgl_gles1_glTexEnvx(GLenum target, GLenum pname, GLfixed param)
+{
+   if (!_gles1_api.glTexEnvx)
+     return;
+   _gles1_api.glTexEnvx(target, pname, param);
+}
+
+static void
+_evgl_gles1_glTexEnviv(GLenum target, GLenum pname, const GLint *params)
+{
+   if (!_gles1_api.glTexEnviv)
+     return;
+   _gles1_api.glTexEnviv(target, pname, params);
+}
+
+static void
+_evgl_gles1_glTexEnvxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+   if (!_gles1_api.glTexEnvxv)
+     return;
+   _gles1_api.glTexEnvxv(target, pname, params);
+}
+
+static void
+_evgl_gles1_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+   if (!_gles1_api.glTexImage2D)
+     return;
+   _gles1_api.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+}
+
+static void
+_evgl_gles1_glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+   if (!_gles1_api.glTexParameteri)
+     return;
+   _gles1_api.glTexParameteri(target, pname, param);
+}
+
+static void
+_evgl_gles1_glTexParameterx(GLenum target, GLenum pname, GLfixed param)
+{
+   if (!_gles1_api.glTexParameterx)
+     return;
+   _gles1_api.glTexParameterx(target, pname, param);
+}
+
+static void
+_evgl_gles1_glTexParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+   if (!_gles1_api.glTexParameteriv)
+     return;
+   _gles1_api.glTexParameteriv(target, pname, params);
+}
+
+static void
+_evgl_gles1_glTexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+   if (!_gles1_api.glTexParameterxv)
+     return;
+   _gles1_api.glTexParameterxv(target, pname, params);
+}
+
+static void
+_evgl_gles1_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+{
+   if (!_gles1_api.glTexSubImage2D)
+     return;
+   _gles1_api.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+static void
+_evgl_gles1_glTranslatex(GLfixed x, GLfixed y, GLfixed z)
+{
+   if (!_gles1_api.glTranslatex)
+     return;
+   _gles1_api.glTranslatex(x, y, z);
+}
+
+static void
+_evgl_gles1_glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+   if (!_gles1_api.glVertexPointer)
+     return;
+   _gles1_api.glVertexPointer(size, type, stride, pointer);
+}
+
+static void
+_evgl_gles1_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+   EVGL_Resource *rsc;
+   EVGL_Context *ctx;
+   int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0};
+   int cc[4] = {0,0,0,0};
+
+   if (!_gles1_api.glViewport)
+     return;
+
+   if (!(rsc=_evgl_tls_resource_get()))
+     {
+        ERR("Unable to execute GL command. Error retrieving tls");
+        return;
+     }
+
+   if (!rsc->current_eng)
+     {
+        ERR("Unable to retrive Current Engine");
+        return;
+     }
+
+   ctx = rsc->current_ctx;
+   if (!ctx)
+     {
+        ERR("Unable to retrive Current Context");
+        return;
+     }
+
+   if (ctx->version != EVAS_GL_GLES_1_X)
+     {
+        ERR("Invalid context version %d", (int) ctx->version);
+        return;
+     }
+
+   if (_evgl_direct_enabled())
+     {
+        if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex)
+          {
+             if ((!ctx->direct_scissor))
+               {
+                  _gles1_api.glEnable(GL_SCISSOR_TEST);
+                  ctx->direct_scissor = 1;
+               }
+
+             if ((ctx->scissor_updated) && (ctx->scissor_enabled))
+               {
+                  // Recompute the scissor coordinates
+                  compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h,
+                                         rsc->direct.rot, 1,
+                                         ctx->scissor_coord[0], ctx->scissor_coord[1],
+                                         ctx->scissor_coord[2], ctx->scissor_coord[3],
+                                         rsc->direct.img.x, rsc->direct.img.y,
+                                         rsc->direct.img.w, rsc->direct.img.h,
+                                         rsc->direct.clip.x, rsc->direct.clip.y,
+                                         rsc->direct.clip.w, rsc->direct.clip.h,
+                                         oc, nc, cc);
+
+                  RECTS_CLIP_TO_RECT(nc[0], nc[1], nc[2], nc[3], cc[0], cc[1], cc[2], cc[3]);
+                  _gles1_api.glScissor(nc[0], nc[1], nc[2], nc[3]);
+
+                  ctx->direct_scissor = 0;
+
+                  // Compute the viewport coordinate
+                  compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h,
+                                         rsc->direct.rot, 0,
+                                         x, y, width, height,
+                                         rsc->direct.img.x, rsc->direct.img.y,
+                                         rsc->direct.img.w, rsc->direct.img.h,
+                                         rsc->direct.clip.x, rsc->direct.clip.y,
+                                         rsc->direct.clip.w, rsc->direct.clip.h,
+                                         oc, nc, cc);
+                  _gles1_api.glViewport(nc[0], nc[1], nc[2], nc[3]);
+               }
+             else
+               {
+
+                  compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h,
+                                         rsc->direct.rot, 0,
+                                         x, y, width, height,
+                                         rsc->direct.img.x, rsc->direct.img.y,
+                                         rsc->direct.img.w, rsc->direct.img.h,
+                                         rsc->direct.clip.x, rsc->direct.clip.y,
+                                         rsc->direct.clip.w, rsc->direct.clip.h,
+                                         oc, nc, cc);
+                  _gles1_api.glScissor(cc[0], cc[1], cc[2], cc[3]);
+
+                  _gles1_api.glViewport(nc[0], nc[1], nc[2], nc[3]);
+               }
+
+             ctx->viewport_direct[0] = nc[0];
+             ctx->viewport_direct[1] = nc[1];
+             ctx->viewport_direct[2] = nc[2];
+             ctx->viewport_direct[3] = nc[3];
+
+             // Keep a copy of the original coordinates
+             ctx->viewport_coord[0] = x;
+             ctx->viewport_coord[1] = y;
+             ctx->viewport_coord[2] = width;
+             ctx->viewport_coord[3] = height;
+
+             ctx->viewport_updated   = 1;
+          }
+        else
+          {
+             if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+               {
+                  _gles1_api.glDisable(GL_SCISSOR_TEST);
+                  ctx->direct_scissor = 0;
+               }
+
+             _gles1_api.glViewport(x, y, width, height);
+          }
+     }
+   else
+     {
+        if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+          {
+             _gles1_api.glDisable(GL_SCISSOR_TEST);
+             ctx->direct_scissor = 0;
+          }
+
+        _gles1_api.glViewport(x, y, width, height);
+     }
+}
+
+static void
+_evgld_gles1_glAlphaFunc(GLenum func, GLclampf ref)
+{
+   if (!_gles1_api.glAlphaFunc)
+     {
+        ERR("Can not call glAlphaFunc() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glAlphaFunc(func, ref);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+   if (!_gles1_api.glClearColor)
+     {
+        ERR("Can not call glClearColor() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glClearColor(red, green, blue, alpha);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glClearDepthf(GLclampf depth)
+{
+   if (!_gles1_api.glClearDepthf)
+     {
+        ERR("Can not call glClearDepthf() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glClearDepthf(depth);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glClipPlanef(GLenum plane, const GLfloat *equation)
+{
+   if (!_gles1_api.glClipPlanef)
+     {
+        ERR("Can not call glClipPlanef() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glClipPlanef(plane, equation);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+   if (!_gles1_api.glColor4f)
+     {
+        ERR("Can not call glColor4f() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glColor4f(red, green, blue, alpha);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+   if (!_gles1_api.glDepthRangef)
+     {
+        ERR("Can not call glDepthRangef() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glDepthRangef(zNear, zFar);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glFogf(GLenum pname, GLfloat param)
+{
+   if (!_gles1_api.glFogf)
+     {
+        ERR("Can not call glFogf() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glFogf(pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glFogfv(GLenum pname, const GLfloat *params)
+{
+   if (!_gles1_api.glFogfv)
+     {
+        ERR("Can not call glFogfv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glFogfv(pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+   if (!_gles1_api.glFrustumf)
+     {
+        ERR("Can not call glFrustumf() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glFrustumf(left, right, bottom, top, zNear, zFar);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGetClipPlanef(GLenum pname, GLfloat eqn[4])
+{
+   if (!_gles1_api.glGetClipPlanef)
+     {
+        ERR("Can not call glGetClipPlanef() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetClipPlanef(pname, eqn);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGetFloatv(GLenum pname, GLfloat *params)
+{
+   if (!_gles1_api.glGetFloatv)
+     {
+        ERR("Can not call glGetFloatv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetFloatv(pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
+{
+   if (!_gles1_api.glGetLightfv)
+     {
+        ERR("Can not call glGetLightfv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetLightfv(light, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
+{
+   if (!_gles1_api.glGetMaterialfv)
+     {
+        ERR("Can not call glGetMaterialfv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetMaterialfv(face, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)
+{
+   if (!_gles1_api.glGetTexEnvfv)
+     {
+        ERR("Can not call glGetTexEnvfv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetTexEnvfv(env, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+   if (!_gles1_api.glGetTexParameterfv)
+     {
+        ERR("Can not call glGetTexParameterfv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetTexParameterfv(target, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glLightModelf(GLenum pname, GLfloat param)
+{
+   if (!_gles1_api.glLightModelf)
+     {
+        ERR("Can not call glLightModelf() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glLightModelf(pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glLightModelfv(GLenum pname, const GLfloat *params)
+{
+   if (!_gles1_api.glLightModelfv)
+     {
+        ERR("Can not call glLightModelfv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glLightModelfv(pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glLightf(GLenum light, GLenum pname, GLfloat param)
+{
+   if (!_gles1_api.glLightf)
+     {
+        ERR("Can not call glLightf() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glLightf(light, pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glLightfv(GLenum light, GLenum pname, const GLfloat *params)
+{
+   if (!_gles1_api.glLightfv)
+     {
+        ERR("Can not call glLightfv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glLightfv(light, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glLineWidth(GLfloat width)
+{
+   if (!_gles1_api.glLineWidth)
+     {
+        ERR("Can not call glLineWidth() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glLineWidth(width);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glLoadMatrixf(const GLfloat *m)
+{
+   if (!_gles1_api.glLoadMatrixf)
+     {
+        ERR("Can not call glLoadMatrixf() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glLoadMatrixf(m);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glMaterialf(GLenum face, GLenum pname, GLfloat param)
+{
+   if (!_gles1_api.glMaterialf)
+     {
+        ERR("Can not call glMaterialf() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glMaterialf(face, pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+   if (!_gles1_api.glMaterialfv)
+     {
+        ERR("Can not call glMaterialfv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glMaterialfv(face, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glMultMatrixf(const GLfloat *m)
+{
+   if (!_gles1_api.glMultMatrixf)
+     {
+        ERR("Can not call glMultMatrixf() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glMultMatrixf(m);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+   if (!_gles1_api.glMultiTexCoord4f)
+     {
+        ERR("Can not call glMultiTexCoord4f() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glMultiTexCoord4f(target, s, t, r, q);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+   if (!_gles1_api.glNormal3f)
+     {
+        ERR("Can not call glNormal3f() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glNormal3f(nx, ny, nz);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+   if (!_gles1_api.glOrthof)
+     {
+        ERR("Can not call glOrthof() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glOrthof(left, right, bottom, top, zNear, zFar);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glPointParameterf(GLenum pname, GLfloat param)
+{
+   if (!_gles1_api.glPointParameterf)
+     {
+        ERR("Can not call glPointParameterf() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glPointParameterf(pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glPointParameterfv(GLenum pname, const GLfloat *params)
+{
+   if (!_gles1_api.glPointParameterfv)
+     {
+        ERR("Can not call glPointParameterfv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glPointParameterfv(pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glPointSize(GLfloat size)
+{
+   if (!_gles1_api.glPointSize)
+     {
+        ERR("Can not call glPointSize() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glPointSize(size);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glPointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+   if (!_gles1_api.glPointSizePointerOES)
+     {
+        ERR("Can not call glPointSizePointerOES() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glPointSizePointerOES(type, stride, pointer);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glPolygonOffset(GLfloat factor, GLfloat units)
+{
+   if (!_gles1_api.glPolygonOffset)
+     {
+        ERR("Can not call glPolygonOffset() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glPolygonOffset(factor, units);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+   if (!_gles1_api.glRotatef)
+     {
+        ERR("Can not call glRotatef() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glRotatef(angle, x, y, z);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glScalef(GLfloat x, GLfloat y, GLfloat z)
+{
+   if (!_gles1_api.glScalef)
+     {
+        ERR("Can not call glScalef() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glScalef(x, y, z);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+   if (!_gles1_api.glTexEnvf)
+     {
+        ERR("Can not call glTexEnvf() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTexEnvf(target, pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+   if (!_gles1_api.glTexEnvfv)
+     {
+        ERR("Can not call glTexEnvfv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTexEnvfv(target, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+   if (!_gles1_api.glTexParameterf)
+     {
+        ERR("Can not call glTexParameterf() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTexParameterf(target, pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+   if (!_gles1_api.glTexParameterfv)
+     {
+        ERR("Can not call glTexParameterfv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTexParameterfv(target, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTranslatef(GLfloat x, GLfloat y, GLfloat z)
+{
+   if (!_gles1_api.glTranslatef)
+     {
+        ERR("Can not call glTranslatef() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTranslatef(x, y, z);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glActiveTexture(GLenum texture)
+{
+   if (!_gles1_api.glActiveTexture)
+     {
+        ERR("Can not call glActiveTexture() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glActiveTexture(texture);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glAlphaFuncx(GLenum func, GLclampx ref)
+{
+   if (!_gles1_api.glAlphaFuncx)
+     {
+        ERR("Can not call glAlphaFuncx() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glAlphaFuncx(func, ref);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glBindBuffer(GLenum target, GLuint buffer)
+{
+   if (!_gles1_api.glBindBuffer)
+     {
+        ERR("Can not call glBindBuffer() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glBindBuffer(target, buffer);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glBindTexture(GLenum target, GLuint texture)
+{
+   if (!_gles1_api.glBindTexture)
+     {
+        ERR("Can not call glBindTexture() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glBindTexture(target, texture);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+   if (!_gles1_api.glBlendFunc)
+     {
+        ERR("Can not call glBlendFunc() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glBlendFunc(sfactor, dfactor);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glBufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
+{
+   if (!_gles1_api.glBufferData)
+     {
+        ERR("Can not call glBufferData() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glBufferData(target, size, data, usage);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
+{
+   if (!_gles1_api.glBufferSubData)
+     {
+        ERR("Can not call glBufferSubData() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glBufferSubData(target, offset, size, data);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glClear(GLbitfield mask)
+{
+   if (!_gles1_api.glClear)
+     {
+        ERR("Can not call glClear() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glClear(mask);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+{
+   if (!_gles1_api.glClearColorx)
+     {
+        ERR("Can not call glClearColorx() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glClearColorx(red, green, blue, alpha);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glClearDepthx(GLclampx depth)
+{
+   if (!_gles1_api.glClearDepthx)
+     {
+        ERR("Can not call glClearDepthx() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glClearDepthx(depth);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glClearStencil(GLint s)
+{
+   if (!_gles1_api.glClearStencil)
+     {
+        ERR("Can not call glClearStencil() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glClearStencil(s);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glClientActiveTexture(GLenum texture)
+{
+   if (!_gles1_api.glClientActiveTexture)
+     {
+        ERR("Can not call glClientActiveTexture() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glClientActiveTexture(texture);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glClipPlanex(GLenum plane, const GLfixed *equation)
+{
+   if (!_gles1_api.glClipPlanex)
+     {
+        ERR("Can not call glClipPlanex() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glClipPlanex(plane, equation);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+   if (!_gles1_api.glColor4ub)
+     {
+        ERR("Can not call glColor4ub() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glColor4ub(red, green, blue, alpha);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+   if (!_gles1_api.glColor4x)
+     {
+        ERR("Can not call glColor4x() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glColor4x(red, green, blue, alpha);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+   if (!_gles1_api.glColorMask)
+     {
+        ERR("Can not call glColorMask() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glColorMask(red, green, blue, alpha);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+   if (!_gles1_api.glColorPointer)
+     {
+        ERR("Can not call glColorPointer() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glColorPointer(size, type, stride, pointer);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data)
+{
+   if (!_gles1_api.glCompressedTexImage2D)
+     {
+        ERR("Can not call glCompressedTexImage2D() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data)
+{
+   if (!_gles1_api.glCompressedTexSubImage2D)
+     {
+        ERR("Can not call glCompressedTexSubImage2D() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+   if (!_gles1_api.glCopyTexImage2D)
+     {
+        ERR("Can not call glCopyTexImage2D() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+   if (!_gles1_api.glCopyTexSubImage2D)
+     {
+        ERR("Can not call glCopyTexSubImage2D() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glCullFace(GLenum mode)
+{
+   if (!_gles1_api.glCullFace)
+     {
+        ERR("Can not call glCullFace() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glCullFace(mode);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glDeleteBuffers(GLsizei n, const GLuint *buffers)
+{
+   if (!_gles1_api.glDeleteBuffers)
+     {
+        ERR("Can not call glDeleteBuffers() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glDeleteBuffers(n, buffers);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glDeleteTextures(GLsizei n, const GLuint *textures)
+{
+   if (!_gles1_api.glDeleteTextures)
+     {
+        ERR("Can not call glDeleteTextures() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glDeleteTextures(n, textures);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glDepthFunc(GLenum func)
+{
+   if (!_gles1_api.glDepthFunc)
+     {
+        ERR("Can not call glDepthFunc() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glDepthFunc(func);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glDepthMask(GLboolean flag)
+{
+   if (!_gles1_api.glDepthMask)
+     {
+        ERR("Can not call glDepthMask() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glDepthMask(flag);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glDepthRangex(GLclampx zNear, GLclampx zFar)
+{
+   if (!_gles1_api.glDepthRangex)
+     {
+        ERR("Can not call glDepthRangex() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glDepthRangex(zNear, zFar);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glDisable(GLenum cap)
+{
+   if (!_gles1_api.glDisable)
+     {
+        ERR("Can not call glDisable() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glDisable(cap);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glDisableClientState(GLenum array)
+{
+   if (!_gles1_api.glDisableClientState)
+     {
+        ERR("Can not call glDisableClientState() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glDisableClientState(array);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+   if (!_gles1_api.glDrawArrays)
+     {
+        ERR("Can not call glDrawArrays() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glDrawArrays(mode, first, count);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
+{
+   if (!_gles1_api.glDrawElements)
+     {
+        ERR("Can not call glDrawElements() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glDrawElements(mode, count, type, indices);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glEnable(GLenum cap)
+{
+   if (!_gles1_api.glEnable)
+     {
+        ERR("Can not call glEnable() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glEnable(cap);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glEnableClientState(GLenum array)
+{
+   if (!_gles1_api.glEnableClientState)
+     {
+        ERR("Can not call glEnableClientState() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glEnableClientState(array);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glFinish(void)
+{
+   if (!_gles1_api.glFinish)
+     {
+        ERR("Can not call glFinish() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glFinish();
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glFlush(void)
+{
+   if (!_gles1_api.glFlush)
+     {
+        ERR("Can not call glFlush() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glFlush();
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glFogx(GLenum pname, GLfixed param)
+{
+   if (!_gles1_api.glFogx)
+     {
+        ERR("Can not call glFogx() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glFogx(pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glFogxv(GLenum pname, const GLfixed *params)
+{
+   if (!_gles1_api.glFogxv)
+     {
+        ERR("Can not call glFogxv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glFogxv(pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glFrontFace(GLenum mode)
+{
+   if (!_gles1_api.glFrontFace)
+     {
+        ERR("Can not call glFrontFace() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glFrontFace(mode);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glFrustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+   if (!_gles1_api.glFrustumx)
+     {
+        ERR("Can not call glFrustumx() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glFrustumx(left, right, bottom, top, zNear, zFar);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGetBooleanv(GLenum pname, GLboolean *params)
+{
+   if (!_gles1_api.glGetBooleanv)
+     {
+        ERR("Can not call glGetBooleanv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetBooleanv(pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGetBufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+   if (!_gles1_api.glGetBufferParameteriv)
+     {
+        ERR("Can not call glGetBufferParameteriv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetBufferParameteriv(target, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGetClipPlanex(GLenum pname, GLfixed eqn[4])
+{
+   if (!_gles1_api.glGetClipPlanex)
+     {
+        ERR("Can not call glGetClipPlanex() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetClipPlanex(pname, eqn);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGenBuffers(GLsizei n, GLuint *buffers)
+{
+   if (!_gles1_api.glGenBuffers)
+     {
+        ERR("Can not call glGenBuffers() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGenBuffers(n, buffers);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGenTextures(GLsizei n, GLuint *textures)
+{
+   if (!_gles1_api.glGenTextures)
+     {
+        ERR("Can not call glGenTextures() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGenTextures(n, textures);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static GLenum
+_evgld_gles1_glGetError(void)
+{
+   GLenum ret;
+   if (!_gles1_api.glGetError)
+     {
+        ERR("Can not call glGetError() in this context!");
+        return EVAS_GL_NOT_INITIALIZED;
+     }
+   EVGL_FUNC_BEGIN();
+   ret = _evgl_gles1_glGetError();
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+static void
+_evgld_gles1_glGetFixedv(GLenum pname, GLfixed *params)
+{
+   if (!_gles1_api.glGetFixedv)
+     {
+        ERR("Can not call glGetFixedv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetFixedv(pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGetIntegerv(GLenum pname, GLint *params)
+{
+   if (!_gles1_api.glGetIntegerv)
+     {
+        ERR("Can not call glGetIntegerv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetIntegerv(pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGetLightxv(GLenum light, GLenum pname, GLfixed *params)
+{
+   if (!_gles1_api.glGetLightxv)
+     {
+        ERR("Can not call glGetLightxv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetLightxv(light, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGetMaterialxv(GLenum face, GLenum pname, GLfixed *params)
+{
+   if (!_gles1_api.glGetMaterialxv)
+     {
+        ERR("Can not call glGetMaterialxv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetMaterialxv(face, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGetPointerv(GLenum pname, GLvoid **params)
+{
+   if (!_gles1_api.glGetPointerv)
+     {
+        ERR("Can not call glGetPointerv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetPointerv(pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static const GLubyte *
+_evgld_gles1_glGetString(GLenum name)
+{
+   const GLubyte * ret;
+   if (!_gles1_api.glGetString)
+     {
+        ERR("Can not call glGetString() in this context!");
+        return NULL;
+     }
+   EVGL_FUNC_BEGIN();
+   ret = _evgl_gles1_glGetString(name);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+static void
+_evgld_gles1_glGetTexEnviv(GLenum env, GLenum pname, GLint *params)
+{
+   if (!_gles1_api.glGetTexEnviv)
+     {
+        ERR("Can not call glGetTexEnviv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetTexEnviv(env, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)
+{
+   if (!_gles1_api.glGetTexEnvxv)
+     {
+        ERR("Can not call glGetTexEnvxv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetTexEnvxv(env, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGetTexParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+   if (!_gles1_api.glGetTexParameteriv)
+     {
+        ERR("Can not call glGetTexParameteriv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetTexParameteriv(target, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glGetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
+{
+   if (!_gles1_api.glGetTexParameterxv)
+     {
+        ERR("Can not call glGetTexParameterxv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glGetTexParameterxv(target, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glHint(GLenum target, GLenum mode)
+{
+   if (!_gles1_api.glHint)
+     {
+        ERR("Can not call glHint() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glHint(target, mode);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static GLboolean
+_evgld_gles1_glIsBuffer(GLuint buffer)
+{
+   GLboolean ret;
+   if (!_gles1_api.glIsBuffer)
+     {
+        ERR("Can not call glIsBuffer() in this context!");
+        return EINA_FALSE;
+     }
+   EVGL_FUNC_BEGIN();
+   ret = _evgl_gles1_glIsBuffer(buffer);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+static GLboolean
+_evgld_gles1_glIsEnabled(GLenum cap)
+{
+   GLboolean ret;
+   if (!_gles1_api.glIsEnabled)
+     {
+        ERR("Can not call glIsEnabled() in this context!");
+        return EINA_FALSE;
+     }
+   EVGL_FUNC_BEGIN();
+   ret = _evgl_gles1_glIsEnabled(cap);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+static GLboolean
+_evgld_gles1_glIsTexture(GLuint texture)
+{
+   GLboolean ret;
+   if (!_gles1_api.glIsTexture)
+     {
+        ERR("Can not call glIsTexture() in this context!");
+        return EINA_FALSE;
+     }
+   EVGL_FUNC_BEGIN();
+   ret = _evgl_gles1_glIsTexture(texture);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+   return ret;
+}
+
+static void
+_evgld_gles1_glLightModelx(GLenum pname, GLfixed param)
+{
+   if (!_gles1_api.glLightModelx)
+     {
+        ERR("Can not call glLightModelx() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glLightModelx(pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glLightModelxv(GLenum pname, const GLfixed *params)
+{
+   if (!_gles1_api.glLightModelxv)
+     {
+        ERR("Can not call glLightModelxv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glLightModelxv(pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glLightx(GLenum light, GLenum pname, GLfixed param)
+{
+   if (!_gles1_api.glLightx)
+     {
+        ERR("Can not call glLightx() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glLightx(light, pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glLightxv(GLenum light, GLenum pname, const GLfixed *params)
+{
+   if (!_gles1_api.glLightxv)
+     {
+        ERR("Can not call glLightxv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glLightxv(light, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glLineWidthx(GLfixed width)
+{
+   if (!_gles1_api.glLineWidthx)
+     {
+        ERR("Can not call glLineWidthx() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glLineWidthx(width);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glLoadIdentity(void)
+{
+   if (!_gles1_api.glLoadIdentity)
+     {
+        ERR("Can not call glLoadIdentity() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glLoadIdentity();
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glLoadMatrixx(const GLfixed *m)
+{
+   if (!_gles1_api.glLoadMatrixx)
+     {
+        ERR("Can not call glLoadMatrixx() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glLoadMatrixx(m);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glLogicOp(GLenum opcode)
+{
+   if (!_gles1_api.glLogicOp)
+     {
+        ERR("Can not call glLogicOp() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glLogicOp(opcode);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glMaterialx(GLenum face, GLenum pname, GLfixed param)
+{
+   if (!_gles1_api.glMaterialx)
+     {
+        ERR("Can not call glMaterialx() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glMaterialx(face, pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glMaterialxv(GLenum face, GLenum pname, const GLfixed *params)
+{
+   if (!_gles1_api.glMaterialxv)
+     {
+        ERR("Can not call glMaterialxv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glMaterialxv(face, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glMatrixMode(GLenum mode)
+{
+   if (!_gles1_api.glMatrixMode)
+     {
+        ERR("Can not call glMatrixMode() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glMatrixMode(mode);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glMultMatrixx(const GLfixed *m)
+{
+   if (!_gles1_api.glMultMatrixx)
+     {
+        ERR("Can not call glMultMatrixx() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glMultMatrixx(m);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glMultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+   if (!_gles1_api.glMultiTexCoord4x)
+     {
+        ERR("Can not call glMultiTexCoord4x() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glMultiTexCoord4x(target, s, t, r, q);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glNormal3x(GLfixed nx, GLfixed ny, GLfixed nz)
+{
+   if (!_gles1_api.glNormal3x)
+     {
+        ERR("Can not call glNormal3x() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glNormal3x(nx, ny, nz);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+   if (!_gles1_api.glNormalPointer)
+     {
+        ERR("Can not call glNormalPointer() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glNormalPointer(type, stride, pointer);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glOrthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+   if (!_gles1_api.glOrthox)
+     {
+        ERR("Can not call glOrthox() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glOrthox(left, right, bottom, top, zNear, zFar);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glPixelStorei(GLenum pname, GLint param)
+{
+   if (!_gles1_api.glPixelStorei)
+     {
+        ERR("Can not call glPixelStorei() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glPixelStorei(pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glPointParameterx(GLenum pname, GLfixed param)
+{
+   if (!_gles1_api.glPointParameterx)
+     {
+        ERR("Can not call glPointParameterx() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glPointParameterx(pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glPointParameterxv(GLenum pname, const GLfixed *params)
+{
+   if (!_gles1_api.glPointParameterxv)
+     {
+        ERR("Can not call glPointParameterxv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glPointParameterxv(pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glPointSizex(GLfixed size)
+{
+   if (!_gles1_api.glPointSizex)
+     {
+        ERR("Can not call glPointSizex() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glPointSizex(size);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glPolygonOffsetx(GLfixed factor, GLfixed units)
+{
+   if (!_gles1_api.glPolygonOffsetx)
+     {
+        ERR("Can not call glPolygonOffsetx() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glPolygonOffsetx(factor, units);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glPopMatrix(void)
+{
+   if (!_gles1_api.glPopMatrix)
+     {
+        ERR("Can not call glPopMatrix() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glPopMatrix();
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glPushMatrix(void)
+{
+   if (!_gles1_api.glPushMatrix)
+     {
+        ERR("Can not call glPushMatrix() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glPushMatrix();
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
+{
+   if (!_gles1_api.glReadPixels)
+     {
+        ERR("Can not call glReadPixels() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glReadPixels(x, y, width, height, format, type, pixels);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+   if (!_gles1_api.glRotatex)
+     {
+        ERR("Can not call glRotatex() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glRotatex(angle, x, y, z);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glSampleCoverage(GLclampf value, GLboolean invert)
+{
+   if (!_gles1_api.glSampleCoverage)
+     {
+        ERR("Can not call glSampleCoverage() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glSampleCoverage(value, invert);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glSampleCoveragex(GLclampx value, GLboolean invert)
+{
+   if (!_gles1_api.glSampleCoveragex)
+     {
+        ERR("Can not call glSampleCoveragex() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glSampleCoveragex(value, invert);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glScalex(GLfixed x, GLfixed y, GLfixed z)
+{
+   if (!_gles1_api.glScalex)
+     {
+        ERR("Can not call glScalex() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glScalex(x, y, z);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+   if (!_gles1_api.glScissor)
+     {
+        ERR("Can not call glScissor() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glScissor(x, y, width, height);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glShadeModel(GLenum mode)
+{
+   if (!_gles1_api.glShadeModel)
+     {
+        ERR("Can not call glShadeModel() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glShadeModel(mode);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+   if (!_gles1_api.glStencilFunc)
+     {
+        ERR("Can not call glStencilFunc() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glStencilFunc(func, ref, mask);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glStencilMask(GLuint mask)
+{
+   if (!_gles1_api.glStencilMask)
+     {
+        ERR("Can not call glStencilMask() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glStencilMask(mask);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+   if (!_gles1_api.glStencilOp)
+     {
+        ERR("Can not call glStencilOp() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glStencilOp(fail, zfail, zpass);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+   if (!_gles1_api.glTexCoordPointer)
+     {
+        ERR("Can not call glTexCoordPointer() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTexCoordPointer(size, type, stride, pointer);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTexEnvi(GLenum target, GLenum pname, GLint param)
+{
+   if (!_gles1_api.glTexEnvi)
+     {
+        ERR("Can not call glTexEnvi() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTexEnvi(target, pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTexEnvx(GLenum target, GLenum pname, GLfixed param)
+{
+   if (!_gles1_api.glTexEnvx)
+     {
+        ERR("Can not call glTexEnvx() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTexEnvx(target, pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTexEnviv(GLenum target, GLenum pname, const GLint *params)
+{
+   if (!_gles1_api.glTexEnviv)
+     {
+        ERR("Can not call glTexEnviv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTexEnviv(target, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTexEnvxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+   if (!_gles1_api.glTexEnvxv)
+     {
+        ERR("Can not call glTexEnvxv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTexEnvxv(target, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+   if (!_gles1_api.glTexImage2D)
+     {
+        ERR("Can not call glTexImage2D() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+   if (!_gles1_api.glTexParameteri)
+     {
+        ERR("Can not call glTexParameteri() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTexParameteri(target, pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTexParameterx(GLenum target, GLenum pname, GLfixed param)
+{
+   if (!_gles1_api.glTexParameterx)
+     {
+        ERR("Can not call glTexParameterx() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTexParameterx(target, pname, param);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTexParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+   if (!_gles1_api.glTexParameteriv)
+     {
+        ERR("Can not call glTexParameteriv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTexParameteriv(target, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+   if (!_gles1_api.glTexParameterxv)
+     {
+        ERR("Can not call glTexParameterxv() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTexParameterxv(target, pname, params);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+{
+   if (!_gles1_api.glTexSubImage2D)
+     {
+        ERR("Can not call glTexSubImage2D() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glTranslatex(GLfixed x, GLfixed y, GLfixed z)
+{
+   if (!_gles1_api.glTranslatex)
+     {
+        ERR("Can not call glTranslatex() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glTranslatex(x, y, z);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+   if (!_gles1_api.glVertexPointer)
+     {
+        ERR("Can not call glVertexPointer() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glVertexPointer(size, type, stride, pointer);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+static void
+_evgld_gles1_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+   if (!_gles1_api.glViewport)
+     {
+        ERR("Can not call glViewport() in this context!");
+        return;
+     }
+   EVGL_FUNC_BEGIN();
+   _evgl_gles1_glViewport(x, y, width, height);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   EVGL_FUNC_END();
+}
+
+
+
+static void
+_evgl_load_gles1_apis(void *dl_handle, Evas_GL_API *funcs)
+{
+   if (!dl_handle) return;
+
+#define ORD(name) funcs->name = dlsym(dl_handle, #name)
+   /* Available only in Common profile */
+   ORD(glAlphaFunc);
+   ORD(glClearColor);
+   ORD(glClearDepthf);
+   ORD(glClipPlanef);
+   ORD(glColor4f);
+   ORD(glDepthRangef);
+   ORD(glFogf);
+   ORD(glFogfv);
+   ORD(glFrustumf);
+   ORD(glGetClipPlanef);
+   ORD(glGetFloatv);
+   ORD(glGetLightfv);
+   ORD(glGetMaterialfv);
+   ORD(glGetTexEnvfv);
+   ORD(glGetTexParameterfv);
+   ORD(glLightModelf);
+   ORD(glLightModelfv);
+   ORD(glLightf);
+   ORD(glLightfv);
+   ORD(glLineWidth);
+   ORD(glLoadMatrixf);
+   ORD(glMaterialf);
+   ORD(glMaterialfv);
+   ORD(glMultMatrixf);
+   ORD(glMultiTexCoord4f);
+   ORD(glNormal3f);
+   ORD(glOrthof);
+   ORD(glPointParameterf);
+   ORD(glPointParameterfv);
+   ORD(glPointSize);
+   ORD(glPointSizePointerOES);
+   ORD(glPolygonOffset);
+   ORD(glRotatef);
+   ORD(glScalef);
+   ORD(glTexEnvf);
+   ORD(glTexEnvfv);
+   ORD(glTexParameterf);
+   ORD(glTexParameterfv);
+   ORD(glTranslatef);
+   /* Available in both Common and Common-Lite profiles */
+   ORD(glActiveTexture);
+   ORD(glAlphaFuncx);
+   ORD(glBindBuffer);
+   ORD(glBindTexture);
+   ORD(glBlendFunc);
+   ORD(glBufferData);
+   ORD(glBufferSubData);
+   ORD(glClear);
+   ORD(glClearColorx);
+   ORD(glClearDepthx);
+   ORD(glClearStencil);
+   ORD(glClientActiveTexture);
+   ORD(glClipPlanex);
+   ORD(glColor4ub);
+   ORD(glColor4x);
+   ORD(glColorMask);
+   ORD(glColorPointer);
+   ORD(glCompressedTexImage2D);
+   ORD(glCompressedTexSubImage2D);
+   ORD(glCopyTexImage2D);
+   ORD(glCopyTexSubImage2D);
+   ORD(glCullFace);
+   ORD(glDeleteBuffers);
+   ORD(glDeleteTextures);
+   ORD(glDepthFunc);
+   ORD(glDepthMask);
+   ORD(glDepthRangex);
+   ORD(glDisable);
+   ORD(glDisableClientState);
+   ORD(glDrawArrays);
+   ORD(glDrawElements);
+   ORD(glEnable);
+   ORD(glEnableClientState);
+   ORD(glFinish);
+   ORD(glFlush);
+   ORD(glFogx);
+   ORD(glFogxv);
+   ORD(glFrontFace);
+   ORD(glFrustumx);
+   ORD(glGetBooleanv);
+   ORD(glGetBufferParameteriv);
+   ORD(glGetClipPlanex);
+   ORD(glGenBuffers);
+   ORD(glGenTextures);
+   ORD(glGetError);
+   ORD(glGetFixedv);
+   ORD(glGetIntegerv);
+   ORD(glGetLightxv);
+   ORD(glGetMaterialxv);
+   ORD(glGetPointerv);
+   ORD(glGetString);
+   ORD(glGetTexEnviv);
+   ORD(glGetTexEnvxv);
+   ORD(glGetTexParameteriv);
+   ORD(glGetTexParameterxv);
+   ORD(glHint);
+   ORD(glIsBuffer);
+   ORD(glIsEnabled);
+   ORD(glIsTexture);
+   ORD(glLightModelx);
+   ORD(glLightModelxv);
+   ORD(glLightx);
+   ORD(glLightxv);
+   ORD(glLineWidthx);
+   ORD(glLoadIdentity);
+   ORD(glLoadMatrixx);
+   ORD(glLogicOp);
+   ORD(glMaterialx);
+   ORD(glMaterialxv);
+   ORD(glMatrixMode);
+   ORD(glMultMatrixx);
+   ORD(glMultiTexCoord4x);
+   ORD(glNormal3x);
+   ORD(glNormalPointer);
+   ORD(glOrthox);
+   ORD(glPixelStorei);
+   ORD(glPointParameterx);
+   ORD(glPointParameterxv);
+   ORD(glPointSizex);
+   ORD(glPolygonOffsetx);
+   ORD(glPopMatrix);
+   ORD(glPushMatrix);
+   ORD(glReadPixels);
+   ORD(glRotatex);
+   ORD(glSampleCoverage);
+   ORD(glSampleCoveragex);
+   ORD(glScalex);
+   ORD(glScissor);
+   ORD(glShadeModel);
+   ORD(glStencilFunc);
+   ORD(glStencilMask);
+   ORD(glStencilOp);
+   ORD(glTexCoordPointer);
+   ORD(glTexEnvi);
+   ORD(glTexEnvx);
+   ORD(glTexEnviv);
+   ORD(glTexEnvxv);
+   ORD(glTexImage2D);
+   ORD(glTexParameteri);
+   ORD(glTexParameterx);
+   ORD(glTexParameteriv);
+   ORD(glTexParameterxv);
+   ORD(glTexSubImage2D);
+   ORD(glTranslatex);
+   ORD(glVertexPointer);
+   ORD(glViewport);
+#undef ORD
+}
+
+static Eina_Bool
+_evgl_gles1_api_init(void)
+{
+   static Eina_Bool _initialized = EINA_FALSE;
+   if (_initialized) return EINA_TRUE;
+
+   memset(&_gles1_api, 0, sizeof(_gles1_api));
+   _gles1_handle = dlopen("libGLES_CM.so", RTLD_NOW);
+   if (!_gles1_handle) _gles1_handle = dlopen("libGLES_CM.so.1", RTLD_NOW);
+   if (!_gles1_handle) _gles1_handle = dlopen("libGLES_CM.so.1.1", RTLD_NOW);
+   if (!_gles1_handle) _gles1_handle = dlopen("libGLESv1_CM.so", RTLD_NOW);
+   if (!_gles1_handle) _gles1_handle = dlopen("libGLESv1_CM.so.1", RTLD_NOW);
+   if (!_gles1_handle)
+     {
+        WRN("OpenGL ES 1 was not found on this system. Evas GL will not support GLES 1 contexts.");
+        return EINA_FALSE;
+     }
+
+   _evgl_load_gles1_apis(_gles1_handle, &_gles1_api);
+   if (!_evgl_api_gles1_ext_init())
+     WRN("Could not initialize OpenGL ES 1 extensions yet.");
+
+   _initialized = EINA_TRUE;
+   return EINA_TRUE;
+}
+
+static void
+_debug_gles1_api_get(Evas_GL_API *funcs)
+{
+   if (!funcs) return;
+
+#define ORD(name) EVAS_API_OVERRIDE(name, funcs, _evgld_gles1_)
+   /* Available only in Common profile */
+   ORD(glAlphaFunc);
+   ORD(glClearColor);
+   ORD(glClearDepthf);
+   ORD(glClipPlanef);
+   ORD(glColor4f);
+   ORD(glDepthRangef);
+   ORD(glFogf);
+   ORD(glFogfv);
+   ORD(glFrustumf);
+   ORD(glGetClipPlanef);
+   ORD(glGetFloatv);
+   ORD(glGetLightfv);
+   ORD(glGetMaterialfv);
+   ORD(glGetTexEnvfv);
+   ORD(glGetTexParameterfv);
+   ORD(glLightModelf);
+   ORD(glLightModelfv);
+   ORD(glLightf);
+   ORD(glLightfv);
+   ORD(glLineWidth);
+   ORD(glLoadMatrixf);
+   ORD(glMaterialf);
+   ORD(glMaterialfv);
+   ORD(glMultMatrixf);
+   ORD(glMultiTexCoord4f);
+   ORD(glNormal3f);
+   ORD(glOrthof);
+   ORD(glPointParameterf);
+   ORD(glPointParameterfv);
+   ORD(glPointSize);
+   ORD(glPointSizePointerOES);
+   ORD(glPolygonOffset);
+   ORD(glRotatef);
+   ORD(glScalef);
+   ORD(glTexEnvf);
+   ORD(glTexEnvfv);
+   ORD(glTexParameterf);
+   ORD(glTexParameterfv);
+   ORD(glTranslatef);
+   /* Available in both Common and Common-Lite profiles */
+   ORD(glActiveTexture);
+   ORD(glAlphaFuncx);
+   ORD(glBindBuffer);
+   ORD(glBindTexture);
+   ORD(glBlendFunc);
+   ORD(glBufferData);
+   ORD(glBufferSubData);
+   ORD(glClear);
+   ORD(glClearColorx);
+   ORD(glClearDepthx);
+   ORD(glClearStencil);
+   ORD(glClientActiveTexture);
+   ORD(glClipPlanex);
+   ORD(glColor4ub);
+   ORD(glColor4x);
+   ORD(glColorMask);
+   ORD(glColorPointer);
+   ORD(glCompressedTexImage2D);
+   ORD(glCompressedTexSubImage2D);
+   ORD(glCopyTexImage2D);
+   ORD(glCopyTexSubImage2D);
+   ORD(glCullFace);
+   ORD(glDeleteBuffers);
+   ORD(glDeleteTextures);
+   ORD(glDepthFunc);
+   ORD(glDepthMask);
+   ORD(glDepthRangex);
+   ORD(glDisable);
+   ORD(glDisableClientState);
+   ORD(glDrawArrays);
+   ORD(glDrawElements);
+   ORD(glEnable);
+   ORD(glEnableClientState);
+   ORD(glFinish);
+   ORD(glFlush);
+   ORD(glFogx);
+   ORD(glFogxv);
+   ORD(glFrontFace);
+   ORD(glFrustumx);
+   ORD(glGetBooleanv);
+   ORD(glGetBufferParameteriv);
+   ORD(glGetClipPlanex);
+   ORD(glGenBuffers);
+   ORD(glGenTextures);
+   ORD(glGetError);
+   ORD(glGetFixedv);
+   ORD(glGetIntegerv);
+   ORD(glGetLightxv);
+   ORD(glGetMaterialxv);
+   ORD(glGetPointerv);
+   ORD(glGetString);
+   ORD(glGetTexEnviv);
+   ORD(glGetTexEnvxv);
+   ORD(glGetTexParameteriv);
+   ORD(glGetTexParameterxv);
+   ORD(glHint);
+   ORD(glIsBuffer);
+   ORD(glIsEnabled);
+   ORD(glIsTexture);
+   ORD(glLightModelx);
+   ORD(glLightModelxv);
+   ORD(glLightx);
+   ORD(glLightxv);
+   ORD(glLineWidthx);
+   ORD(glLoadIdentity);
+   ORD(glLoadMatrixx);
+   ORD(glLogicOp);
+   ORD(glMaterialx);
+   ORD(glMaterialxv);
+   ORD(glMatrixMode);
+   ORD(glMultMatrixx);
+   ORD(glMultiTexCoord4x);
+   ORD(glNormal3x);
+   ORD(glNormalPointer);
+   ORD(glOrthox);
+   ORD(glPixelStorei);
+   ORD(glPointParameterx);
+   ORD(glPointParameterxv);
+   ORD(glPointSizex);
+   ORD(glPolygonOffsetx);
+   ORD(glPopMatrix);
+   ORD(glPushMatrix);
+   ORD(glReadPixels);
+   ORD(glRotatex);
+   ORD(glSampleCoverage);
+   ORD(glSampleCoveragex);
+   ORD(glScalex);
+   ORD(glScissor);
+   ORD(glShadeModel);
+   ORD(glStencilFunc);
+   ORD(glStencilMask);
+   ORD(glStencilOp);
+   ORD(glTexCoordPointer);
+   ORD(glTexEnvi);
+   ORD(glTexEnvx);
+   ORD(glTexEnviv);
+   ORD(glTexEnvxv);
+   ORD(glTexImage2D);
+   ORD(glTexParameteri);
+   ORD(glTexParameterx);
+   ORD(glTexParameteriv);
+   ORD(glTexParameterxv);
+   ORD(glTexSubImage2D);
+   ORD(glTranslatex);
+   ORD(glVertexPointer);
+   ORD(glViewport);
+#undef ORD
+   evgl_api_gles1_ext_get(funcs);
+}
+
+static void
+_normal_gles1_api_get(Evas_GL_API *funcs)
+{
+   if (!funcs) return;
+
+#define ORD(name) EVAS_API_OVERRIDE(name, funcs, _evgl_gles1_)
+   /* Available only in Common profile */
+   ORD(glAlphaFunc);
+   ORD(glClearColor);
+   ORD(glClearDepthf);
+   ORD(glClipPlanef);
+   ORD(glColor4f);
+   ORD(glDepthRangef);
+   ORD(glFogf);
+   ORD(glFogfv);
+   ORD(glFrustumf);
+   ORD(glGetClipPlanef);
+   ORD(glGetFloatv);
+   ORD(glGetLightfv);
+   ORD(glGetMaterialfv);
+   ORD(glGetTexEnvfv);
+   ORD(glGetTexParameterfv);
+   ORD(glLightModelf);
+   ORD(glLightModelfv);
+   ORD(glLightf);
+   ORD(glLightfv);
+   ORD(glLineWidth);
+   ORD(glLoadMatrixf);
+   ORD(glMaterialf);
+   ORD(glMaterialfv);
+   ORD(glMultMatrixf);
+   ORD(glMultiTexCoord4f);
+   ORD(glNormal3f);
+   ORD(glOrthof);
+   ORD(glPointParameterf);
+   ORD(glPointParameterfv);
+   ORD(glPointSize);
+   ORD(glPointSizePointerOES);
+   ORD(glPolygonOffset);
+   ORD(glRotatef);
+   ORD(glScalef);
+   ORD(glTexEnvf);
+   ORD(glTexEnvfv);
+   ORD(glTexParameterf);
+   ORD(glTexParameterfv);
+   ORD(glTranslatef);
+   /* Available in both Common and Common-Lite profiles */
+   ORD(glActiveTexture);
+   ORD(glAlphaFuncx);
+   ORD(glBindBuffer);
+   ORD(glBindTexture);
+   ORD(glBlendFunc);
+   ORD(glBufferData);
+   ORD(glBufferSubData);
+   ORD(glClear);
+   ORD(glClearColorx);
+   ORD(glClearDepthx);
+   ORD(glClearStencil);
+   ORD(glClientActiveTexture);
+   ORD(glClipPlanex);
+   ORD(glColor4ub);
+   ORD(glColor4x);
+   ORD(glColorMask);
+   ORD(glColorPointer);
+   ORD(glCompressedTexImage2D);
+   ORD(glCompressedTexSubImage2D);
+   ORD(glCopyTexImage2D);
+   ORD(glCopyTexSubImage2D);
+   ORD(glCullFace);
+   ORD(glDeleteBuffers);
+   ORD(glDeleteTextures);
+   ORD(glDepthFunc);
+   ORD(glDepthMask);
+   ORD(glDepthRangex);
+   ORD(glDisable);
+   ORD(glDisableClientState);
+   ORD(glDrawArrays);
+   ORD(glDrawElements);
+   ORD(glEnable);
+   ORD(glEnableClientState);
+   ORD(glFinish);
+   ORD(glFlush);
+   ORD(glFogx);
+   ORD(glFogxv);
+   ORD(glFrontFace);
+   ORD(glFrustumx);
+   ORD(glGetBooleanv);
+   ORD(glGetBufferParameteriv);
+   ORD(glGetClipPlanex);
+   ORD(glGenBuffers);
+   ORD(glGenTextures);
+   ORD(glGetError);
+   ORD(glGetFixedv);
+   ORD(glGetIntegerv);
+   ORD(glGetLightxv);
+   ORD(glGetMaterialxv);
+   ORD(glGetPointerv);
+   ORD(glGetString);
+   ORD(glGetTexEnviv);
+   ORD(glGetTexEnvxv);
+   ORD(glGetTexParameteriv);
+   ORD(glGetTexParameterxv);
+   ORD(glHint);
+   ORD(glIsBuffer);
+   ORD(glIsEnabled);
+   ORD(glIsTexture);
+   ORD(glLightModelx);
+   ORD(glLightModelxv);
+   ORD(glLightx);
+   ORD(glLightxv);
+   ORD(glLineWidthx);
+   ORD(glLoadIdentity);
+   ORD(glLoadMatrixx);
+   ORD(glLogicOp);
+   ORD(glMaterialx);
+   ORD(glMaterialxv);
+   ORD(glMatrixMode);
+   ORD(glMultMatrixx);
+   ORD(glMultiTexCoord4x);
+   ORD(glNormal3x);
+   ORD(glNormalPointer);
+   ORD(glOrthox);
+   ORD(glPixelStorei);
+   ORD(glPointParameterx);
+   ORD(glPointParameterxv);
+   ORD(glPointSizex);
+   ORD(glPolygonOffsetx);
+   ORD(glPopMatrix);
+   ORD(glPushMatrix);
+   ORD(glReadPixels);
+   ORD(glRotatex);
+   ORD(glSampleCoverage);
+   ORD(glSampleCoveragex);
+   ORD(glScalex);
+   ORD(glScissor);
+   ORD(glShadeModel);
+   ORD(glStencilFunc);
+   ORD(glStencilMask);
+   ORD(glStencilOp);
+   ORD(glTexCoordPointer);
+   ORD(glTexEnvi);
+   ORD(glTexEnvx);
+   ORD(glTexEnviv);
+   ORD(glTexEnvxv);
+   ORD(glTexImage2D);
+   ORD(glTexParameteri);
+   ORD(glTexParameterx);
+   ORD(glTexParameteriv);
+   ORD(glTexParameterxv);
+   ORD(glTexSubImage2D);
+   ORD(glTranslatex);
+   ORD(glVertexPointer);
+   ORD(glViewport);
+#undef ORD
+   evgl_api_gles1_ext_get(funcs);
+}
+
+void
+_evgl_api_gles1_get(Evas_GL_API *funcs, Eina_Bool debug)
+{
+   if (!_evgl_gles1_api_init())
+     return;
+
+   if (debug)
+     _debug_gles1_api_get(funcs);
+   else
+     _normal_gles1_api_get(funcs);
+
+   // FIXME: This looks wrong, we should be calling the gles1 API
+   // TODO: Implement these wrappers first
+   //if (evgl_engine->direct_scissor_off)
+     //_direct_scissor_off_api_get(funcs);
+}
+
+Evas_GL_API *
+_evgl_api_gles1_internal_get(void)
+{
+   return &_gles1_api;
+}
old mode 100644 (file)
new mode 100755 (executable)
index 4197746..df04a87
 # include <OpenGL/glext.h>
 #else
 # ifdef _EVAS_ENGINE_SDL_H
-#  if defined(GLES_VARIETY_S3C6410) || defined(GLES_VARIETY_SGX)
+#  ifdef GL_GLES
 #   include <SDL/SDL_opengles.h>
 #  else
 #   include <SDL/SDL_opengl.h>
 #  endif
 # else
-#  if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-#   if defined(GLES_VARIETY_S3C6410)
-#    include <GLES2/gl2.h>
-#   elif defined(GLES_VARIETY_SGX)
-#    include <GLES2/gl2.h>
-#    include <GLES2/gl2ext.h>
-#   endif
+#  ifdef GL_GLES
+#   include <GLES2/gl2.h>
+#   include <GLES2/gl2ext.h>
 #  else
 #   include <GL/gl.h>
 #   include <GL/glext.h>
 #ifndef GL_BGRA
 # define GL_BGRA 0x80E1
 #endif
+#ifndef GL_RGBA4
+# define GL_RGBA4 0x8056
+#endif
+#ifndef GL_RGBA8
+# define GL_RGBA8 0x8058
+#endif
+#ifndef GL_RGBA12
+# define GL_RGBA12 0x805A
+#endif
+#ifndef GL_RGBA16
+# define GL_RGBA16 0x805B
+#endif
+#ifndef GL_R3_G3_B2
+# define GL_R3_G3_B2 0x2A10
+#endif
+#ifndef GL_RGB4
+# define GL_RGB4 0x804F
+#endif
+#ifndef GL_RGB5
+# define GL_RGB5 0x8050
+#endif
+#ifndef GL_RGB8
+# define GL_RGB8 0x8051
+#endif
+#ifndef GL_RGB10
+# define GL_RGB10 0x8052
+#endif
+#ifndef GL_RGB12
+# define GL_RGB12 0x8053
+#endif
+#ifndef GL_RGB16
+# define GL_RGB16 0x8054
+#endif
+#ifndef GL_ALPHA4
+# define GL_ALPHA4 0x803B
+#endif
+#ifndef GL_ALPHA8
+# define GL_ALPHA8 0x803C
+#endif
+#ifndef GL_ALPHA12
+# define GL_ALPHA12 0x803D
+#endif
+#ifndef GL_ALPHA16
+# define GL_ALPHA16 0x803E
+#endif
+#ifndef GL_LUMINANCE4
+# define GL_LUMINANCE4 0x803F
+#endif
+#ifndef GL_LUMINANCE8
+# define GL_LUMINANCE8 0x8040
+#endif
+#ifndef GL_LUMINANCE12
+# define GL_LUMINANCE12 0x8041
+#endif
+#ifndef GL_LUMINANCE16
+# define GL_LUMINANCE16 0x8042
+#endif
+#ifndef GL_LUMINANCE4_ALPHA4
+# define GL_LUMINANCE4_ALPHA4 0x8043
+#endif
+#ifndef GL_LUMINANCE8_ALPHA8
+# define GL_LUMINANCE8_ALPHA8 0x8045
+#endif
+#ifndef GL_LUMINANCE12_ALPHA12
+# define GL_LUMINANCE12_ALPHA12 0x8047
+#endif
+#ifndef GL_LUMINANCE16_ALPHA16
+# define GL_LUMINANCE16_ALPHA16 0x8048
+#endif
+#ifndef GL_ETC1_RGB8_OES
+# define GL_ETC1_RGB8_OES 0x8D64
+#endif
+#ifndef GL_COMPRESSED_RGB8_ETC2
+# define GL_COMPRESSED_RGB8_ETC2 0x9274
+#endif
+#ifndef GL_COMPRESSED_RGBA8_ETC2_EAC
+# define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#endif
+
+#ifndef GL_UNPACK_ROW_LENGTH_EXT
+# define GL_UNPACK_ROW_LENGTH_EXT 0x0cf2
+#endif
+
+#ifndef EGL_NO_DISPLAY
+# define EGL_NO_DISPLAY 0
+#endif
 
 #ifndef EGL_NO_CONTEXT
 # define EGL_NO_CONTEXT 0
 # define EGL_FALSE 0
 #endif
 
+#ifndef EGL_IMAGE_PRESERVED_KHR
+# define EGL_IMAGE_PRESERVED_KHR 0x30D2
+#endif
+#ifndef EGL_NATIVE_BUFFER_TIZEN
+# define EGL_NATIVE_BUFFER_TIZEN 0x32A0
+#endif
+#ifndef EGL_NATIVE_SURFACE_TIZEN
+# define EGL_NATIVE_SURFACE_TIZEN 0x32A1
+#endif
 #ifndef EGL_MAP_GL_TEXTURE_2D_SEC
 # define EGL_MAP_GL_TEXTURE_2D_SEC 0x3201
 #endif
 #ifndef GL_MAX_SAMPLES_IMG
 #define GL_MAX_SAMPLES_IMG 0x9135
 #endif
+#ifndef GL_MAX_SAMPLES_EXT
+#define GL_MAX_SAMPLES_EXT 0x8D57
+#endif
+#ifndef GL_WRITE_ONLY
+#define GL_WRITE_ONLY 0x88B9
+#endif
+#ifndef EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC
+#define EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC 1
+#endif
+#ifndef EGL_MAP_GL_TEXTURE_DEVICE_G2D_SEC
+#define EGL_MAP_GL_TEXTURE_DEVICE_G2D_SEC 2
+#endif
+#ifndef EGL_MAP_GL_TEXTURE_OPTION_READ_SEC
+#define EGL_MAP_GL_TEXTURE_OPTION_READ_SEC (1<<0)
+#endif
+#ifndef EGL_MAP_GL_TEXTURE_OPTION_WRITE_SEC
+#define EGL_MAP_GL_TEXTURE_OPTION_WRITE_SEC (1<<1)
+#endif
+#ifndef EGL_GL_TEXTURE_2D_KHR
+#define EGL_GL_TEXTURE_2D_KHR 0x30B1
+#endif
+#ifndef EGL_GL_TEXTURE_LEVEL_KHR
+#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC
+#endif
+#ifndef EGL_IMAGE_PRESERVED_KHR
+#define EGL_IMAGE_PRESERVED_KHR 0x30D2
+#endif
+
+#ifndef GL_COLOR_BUFFER_BIT0_QCOM
+// if GL_COLOR_BUFFER_BIT0_QCOM  just assume the rest arent... saves fluff
+#define GL_COLOR_BUFFER_BIT0_QCOM                     0x00000001
+#define GL_COLOR_BUFFER_BIT1_QCOM                     0x00000002
+#define GL_COLOR_BUFFER_BIT2_QCOM                     0x00000004
+#define GL_COLOR_BUFFER_BIT3_QCOM                     0x00000008
+#define GL_COLOR_BUFFER_BIT4_QCOM                     0x00000010
+#define GL_COLOR_BUFFER_BIT5_QCOM                     0x00000020
+#define GL_COLOR_BUFFER_BIT6_QCOM                     0x00000040
+#define GL_COLOR_BUFFER_BIT7_QCOM                     0x00000080
+#define GL_DEPTH_BUFFER_BIT0_QCOM                     0x00000100
+#define GL_DEPTH_BUFFER_BIT1_QCOM                     0x00000200
+#define GL_DEPTH_BUFFER_BIT2_QCOM                     0x00000400
+#define GL_DEPTH_BUFFER_BIT3_QCOM                     0x00000800
+#define GL_DEPTH_BUFFER_BIT4_QCOM                     0x00001000
+#define GL_DEPTH_BUFFER_BIT5_QCOM                     0x00002000
+#define GL_DEPTH_BUFFER_BIT6_QCOM                     0x00004000
+#define GL_DEPTH_BUFFER_BIT7_QCOM                     0x00008000
+#define GL_STENCIL_BUFFER_BIT0_QCOM                   0x00010000
+#define GL_STENCIL_BUFFER_BIT1_QCOM                   0x00020000
+#define GL_STENCIL_BUFFER_BIT2_QCOM                   0x00040000
+#define GL_STENCIL_BUFFER_BIT3_QCOM                   0x00080000
+#define GL_STENCIL_BUFFER_BIT4_QCOM                   0x00100000
+#define GL_STENCIL_BUFFER_BIT5_QCOM                   0x00200000
+#define GL_STENCIL_BUFFER_BIT6_QCOM                   0x00400000
+#define GL_STENCIL_BUFFER_BIT7_QCOM                   0x00800000
+#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM               0x01000000
+#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM               0x02000000
+#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM               0x04000000
+#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM               0x08000000
+#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM               0x10000000
+#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM               0x20000000
+#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM               0x40000000
+#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM               0x80000000
+#endif
 
 #define SHAD_VERTEX 0
 #define SHAD_COLOR  1
 #define SHAD_TEXUV2 3
 #define SHAD_TEXUV3 4
 #define SHAD_TEXM   5
+#define SHAD_TEXSAM 6
 
 typedef struct _Evas_GL_Program                      Evas_GL_Program;
 typedef struct _Evas_GL_Program_Source               Evas_GL_Program_Source;
@@ -133,19 +288,68 @@ typedef struct _Evas_GL_Polygon_Point                Evas_GL_Polygon_Point;
 typedef enum {
   SHADER_RECT,
   SHADER_FONT,
+
+  SHADER_IMG_MASK,
+
   SHADER_IMG,
   SHADER_IMG_NOMUL,
+  SHADER_IMG_AFILL,
+  SHADER_IMG_NOMUL_AFILL,
   SHADER_IMG_BGRA,
   SHADER_IMG_BGRA_NOMUL,
-  SHADER_IMG_MASK,
+  SHADER_IMG_BGRA_AFILL,
+  SHADER_IMG_BGRA_NOMUL_AFILL,
+  SHADER_TEX,
+  SHADER_TEX_NOMUL,
+  SHADER_TEX_AFILL,
+  SHADER_TEX_NOMUL_AFILL,
+
+  SHADER_IMG_21,
+  SHADER_IMG_21_NOMUL,
+  SHADER_IMG_21_AFILL,
+  SHADER_IMG_21_NOMUL_AFILL,
+  SHADER_IMG_21_BGRA,
+  SHADER_IMG_21_BGRA_NOMUL,
+  SHADER_IMG_21_BGRA_AFILL,
+  SHADER_IMG_21_BGRA_NOMUL_AFILL,
+  SHADER_TEX_21,
+  SHADER_TEX_21_NOMUL,
+  SHADER_TEX_21_AFILL,
+  SHADER_TEX_21_NOMUL_AFILL,
+
+  SHADER_IMG_12,
+  SHADER_IMG_12_NOMUL,
+  SHADER_IMG_12_AFILL,
+  SHADER_IMG_12_NOMUL_AFILL,
+  SHADER_IMG_12_BGRA,
+  SHADER_IMG_12_BGRA_NOMUL,
+  SHADER_IMG_12_BGRA_AFILL,
+  SHADER_IMG_12_BGRA_NOMUL_AFILL,
+  SHADER_TEX_12,
+  SHADER_TEX_12_NOMUL,
+  SHADER_TEX_12_AFILL,
+  SHADER_TEX_12_NOMUL_AFILL,
+
+  SHADER_IMG_22,
+  SHADER_IMG_22_NOMUL,
+  SHADER_IMG_22_AFILL,
+  SHADER_IMG_22_NOMUL_AFILL,
+  SHADER_IMG_22_BGRA,
+  SHADER_IMG_22_BGRA_NOMUL,
+  SHADER_IMG_22_BGRA_AFILL,
+  SHADER_IMG_22_BGRA_NOMUL_AFILL,
+  SHADER_TEX_22,
+  SHADER_TEX_22_NOMUL,
+  SHADER_TEX_22_AFILL,
+  SHADER_TEX_22_NOMUL_AFILL,
+
   SHADER_YUV,
   SHADER_YUV_NOMUL,
   SHADER_YUY2,
   SHADER_YUY2_NOMUL,
   SHADER_NV12,
   SHADER_NV12_NOMUL,
-  SHADER_TEX,
-  SHADER_TEX_NOMUL,
+
   SHADER_FILTER_INVERT,
   SHADER_FILTER_INVERT_NOMUL,
   SHADER_FILTER_INVERT_BGRA,
@@ -158,10 +362,32 @@ typedef enum {
   SHADER_FILTER_SEPIA_NOMUL,
   SHADER_FILTER_SEPIA_BGRA,
   SHADER_FILTER_SEPIA_BGRA_NOMUL,
+
   /* SHADER_FILTER_BLUR, */
   /* SHADER_FILTER_BLUR_NOMUL, */
   /* SHADER_FILTER_BLUR_BGRA, */
   /* SHADER_FILTER_BLUR_BGRA_NOMUL, */
+  SHADER_TIZEN,
+  SHADER_TIZEN_MASK,
+  SHADER_TIZEN_NOMUL,
+  SHADER_TIZEN_MASK_NOMUL,
+  SHADER_RGB_A_PAIR,
+  SHADER_RGB_A_PAIR_NOMUL,
+
+  SHADER_FONT_MASK,
+  SHADER_IMG_MASK_BGRA,
+  SHADER_IMG_MASK_BGRA_NOMUL,
+  SHADER_IMG_MASK_NOMUL,
+  SHADER_NV12_MASK,
+  SHADER_RECT_MASK,
+  /* SHADER_RGB_A_PAIR_MASK, */
+  SHADER_YUV_MASK,
+  SHADER_YUY2_MASK,
+  SHADER_MAP_MASK,
+  SHADER_MAP_MASK_BGRA,
+  SHADER_MAP_MASK_BGRA_NOMUL,
+  SHADER_MAP_MASK_NOMUL,
+
   SHADER_LAST
 } Evas_GL_Shader;
 
@@ -170,6 +396,8 @@ struct _Evas_GL_Program
    GLuint vert, frag, prog;
 
    int tex_count;
+
+   Eina_Bool init;
 };
 
 struct _Evas_GL_Program_Source
@@ -195,7 +423,12 @@ struct _Evas_GL_Shared
       Eina_Bool tex_npo2 : 1;
       Eina_Bool tex_rect : 1;
       Eina_Bool sec_image_map : 1;
+      Eina_Bool sec_tbm_surface : 1;
       Eina_Bool bin_program : 1;
+      Eina_Bool unpack_row_length : 1;
+      Eina_Bool etc1 : 1;
+      Eina_Bool etc2 : 1;
+      Eina_Bool etc1_subimage : 1; // may be set to false at runtime if op fails
       // tuning params - per gpu/cpu combo?
 #define MAX_CUTOUT             512
 #define DEF_CUTOUT                  512
@@ -208,11 +441,13 @@ struct _Evas_GL_Shared
 
 #define MIN_ATLAS_ALLOC         16
 #define MAX_ATLAS_ALLOC       1024
-#define DEF_ATLAS_ALLOC            1024
+#define DEF_ATLAS_ALLOC       1024
+#define DEF_ATLAS_RECT_ALLOC   256
 
 #define MIN_ATLAS_ALLOC_ALPHA   16
 #define MAX_ATLAS_ALLOC_ALPHA 4096
-#define DEF_ATLAS_ALLOC_ALPHA      4096
+#define DEF_ATLAS_ALLOC_ALPHA 4096
+#define DEF_ATLAS_RECT_ALLOC_ALPHA 512
 
 #define MAX_ATLAS_W            512
 #define DEF_ATLAS_W                 512
@@ -220,10 +455,13 @@ struct _Evas_GL_Shared
 #define MAX_ATLAS_H            512
 #define DEF_ATLAS_H                 512
 
+#define ATLAS_FORMATS_COUNT    7
 #define MIN_ATLAS_SLOT          16
 #define MAX_ATLAS_SLOT         512
 #define DEF_ATLAS_SLOT               16
 
+      Eina_List *cspaces; // depend on the values of etc1, etc2
+
       struct {
          struct {
             int max;
@@ -243,11 +481,14 @@ struct _Evas_GL_Shared
 
    struct {
       Eina_List       *whole;
-      Eina_List       *atlas[33][3];
+      Eina_List       *atlas[33][ATLAS_FORMATS_COUNT];
    } tex;
 
    Eina_Hash          *native_pm_hash;
    Eina_Hash          *native_tex_hash;
+   Eina_Hash          *native_buffer_hash;
+   Eina_Hash          *native_tbm_hash;
+   Eina_Hash          *native_evasgl_hash;
 
    Evas_GL_Program     shader[SHADER_LAST];
 
@@ -268,6 +509,8 @@ struct _Evas_GL_Shared
 #define RTYPE_IMASK 6
 #define RTYPE_YUY2  7
 #define RTYPE_NV12  8
+#define ARRAY_BUFFER_USE 500
+#define ARRAY_BUFFER_USE_SHIFT 100
 
 struct _Evas_Engine_GL_Context
 {
@@ -295,6 +538,12 @@ struct _Evas_Engine_GL_Context
    } state;
 
    struct {
+      int                x, y, w, h;
+      Eina_Bool          enabled : 1;
+      Eina_Bool          used : 1;
+   } master_clip;
+
+   struct {
       struct {
          int             x, y, w, h;
          int             type;
@@ -322,6 +571,7 @@ struct _Evas_Engine_GL_Context
          GLfloat *texuv2;
          GLfloat *texuv3;
          GLfloat *texm;
+         GLfloat *texsam;
          Eina_Bool line: 1;
          Eina_Bool use_vertex : 1;
          Eina_Bool use_color : 1;
@@ -329,7 +579,12 @@ struct _Evas_Engine_GL_Context
          Eina_Bool use_texuv2 : 1;
          Eina_Bool use_texuv3 : 1;
          Eina_Bool use_texm : 1;
+         Eina_Bool use_texsam : 1;
+         Eina_Bool mask_smooth : 1;
          Evas_GL_Image *im;
+         GLuint buffer;
+         int buffer_alloc;
+         int buffer_use;
       } array;
    } pipe[MAX_PIPES];
 
@@ -337,17 +592,26 @@ struct _Evas_Engine_GL_Context
       Eina_Bool size : 1;
    } change;
 
-   Eina_Bool havestuff : 1;
+   Eina_List *font_glyph_textures;
 
    Evas_GL_Image *def_surface;
 
-   /* If this is set: Force drawing with a particular filter */
-   GLuint filter_prog;
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
 // FIXME: hack. expose egl display to gl core for egl image sec extn.
    void *egldisp;
 #endif
+
+   GLuint preserve_bit;
+   int gles_version;
+
+   int depth;
+
+   /* ----- Bitfields come here ----- */
+
+   Eina_Bool havestuff : 1;
+
+   /* If set, the driver will rotate the buffer itself based on an X Window property */
+   Eina_Bool pre_rotated : 1;
 };
 
 struct _Evas_GL_Texture_Pool
@@ -360,12 +624,15 @@ struct _Evas_GL_Texture_Pool
    int              slot, fslot;
    struct {
       void         *img;
+      void         *buffer;
       unsigned int *data;
       int           w, h;
       int           stride;
       int           checked_out;
    } dyn;
+
    Eina_List       *allocations;
+   Eina_Rectangle_Pool *eina_pool;
    Eina_Bool        whole : 1;
    Eina_Bool        render : 1;
    Eina_Bool        native : 1;
@@ -376,7 +643,12 @@ struct _Evas_GL_Texture
 {
    Evas_Engine_GL_Context *gc;
    Evas_GL_Image   *im;
-   Evas_GL_Texture_Pool *pt, *ptu, *ptv, *ptuv;
+   Evas_GL_Texture_Pool *pt, *ptu, *ptv, *ptt;
+   union {
+      Evas_GL_Texture_Pool *ptuv;
+      Evas_GL_Texture_Pool *pta;
+   };
+   RGBA_Font_Glyph *fglyph;
    int              x, y, w, h;
    double           sx1, sy1, sx2, sy2;
    int              references;
@@ -389,6 +661,7 @@ struct _Evas_GL_Texture
 
    Eina_Bool        alpha : 1;
    Eina_Bool        dyn : 1;
+   Eina_Rectangle   *rect;
 };
 
 struct _Evas_GL_Image
@@ -401,7 +674,7 @@ struct _Evas_GL_Image
    // if im->im == NULL, it's a render-surface so these here are used
    int              w, h;
    struct {
-      int           space;
+      Evas_Colorspace space;
       void         *data;
       unsigned char no_free : 1;
    } cs;
@@ -412,14 +685,24 @@ struct _Evas_GL_Image
          void     (*bind)   (void *data, void *image);
          void     (*unbind) (void *data, void *image);
          void     (*free)   (void *data, void *image);
+         int      (*yinvert)(void *data, void *image);
          void      *data;
       } func;
       int           yinvert;
       int           target;
       int           mipmap;
+      int           rot;
+      float         ratio;
+      int           flip;
       unsigned char loose : 1;
    } native;
 
+   struct {
+      Evas_GL_Image *origin;
+      int            w, h;
+      Eina_Bool      smooth : 1;
+   } scaled;
+
    int scale_hint, content_hint;
    int csize;
 
@@ -429,6 +712,8 @@ struct _Evas_GL_Image
    unsigned char    cached : 1;
    unsigned char    alpha : 1;
    unsigned char    tex_only : 1;
+   unsigned char    locked : 1; // gl_surface_lock/unlock
+   unsigned char    direct : 1; // evas gl direct renderable
 };
 
 struct _Evas_GL_Font_Texture
@@ -506,6 +791,12 @@ void              evas_gl_common_context_free(Evas_Engine_GL_Context *gc);
 void              evas_gl_common_context_use(Evas_Engine_GL_Context *gc);
 void              evas_gl_common_context_newframe(Evas_Engine_GL_Context *gc);
 void              evas_gl_common_context_resize(Evas_Engine_GL_Context *gc, int w, int h, int rot);
+void              evas_gl_common_tiling_start(Evas_Engine_GL_Context *gc,
+                                              int rot, int gw, int gh,
+                                              int cx, int cy, int cw, int ch,
+                                              int bitmask);
+void              evas_gl_common_context_done(Evas_Engine_GL_Context *gc);
+void              evas_gl_common_tiling_done(Evas_Engine_GL_Context *gc);
 void              evas_gl_common_context_target_surface_set(Evas_Engine_GL_Context *gc, Evas_GL_Image *surface);
 
 void              evas_gl_common_context_line_push(Evas_Engine_GL_Context *gc,
@@ -514,51 +805,54 @@ void              evas_gl_common_context_line_push(Evas_Engine_GL_Context *gc,
                                                    int r, int g, int b, int a);
 void              evas_gl_common_context_rectangle_push(Evas_Engine_GL_Context *gc,
                                                         int x, int y, int w, int h,
-                                                        int r, int g, int b, int a);
+                                                        int r, int g, int b, int a,
+                                                        Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth);
 void              evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
                                                     Evas_GL_Texture *tex,
                                                     double sx, double sy, double sw, double sh,
                                                     int x, int y, int w, int h,
+                                                    Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
                                                     int r, int g, int b, int a,
                                                     Eina_Bool smooth, Eina_Bool tex_only);
-void              evas_gl_common_context_image_mask_push(Evas_Engine_GL_Context *gc,
-                                                    Evas_GL_Texture *tex,
-                                                    Evas_GL_Texture *texm,
-                                                    double sx, double sy, double sw, double sh,
-                                                    double sxm, double sym, double swm, double shm,
-                                                    int x, int y, int w, int h,
-                                                    int r, int g, int b, int a,
-                                                    Eina_Bool smooth);
-
-
 void              evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
                                                    Evas_GL_Texture *tex,
                                                    double sx, double sy, double sw, double sh,
                                                    int x, int y, int w, int h,
+                                                   Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
                                                    int r, int g, int b, int a);
 void             evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
                                                  Evas_GL_Texture *tex,
                                                  double sx, double sy, double sw, double sh,
                                                  int x, int y, int w, int h,
+                                                 Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
                                                  int r, int g, int b, int a,
                                                  Eina_Bool smooth);
 void             evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
                                                   Evas_GL_Texture *tex,
                                                   double sx, double sy, double sw, double sh,
                                                   int x, int y, int w, int h,
+                                                  Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
                                                   int r, int g, int b, int a,
                                                   Eina_Bool smooth);
 void             evas_gl_common_context_nv12_push(Evas_Engine_GL_Context *gc,
                                                   Evas_GL_Texture *tex,
                                                   double sx, double sy, double sw, double sh,
                                                   int x, int y, int w, int h,
+                                                  Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
                                                   int r, int g, int b, int a,
                                                   Eina_Bool smooth);
+void             evas_gl_common_context_rgb_a_pair_push(Evas_Engine_GL_Context *gc,
+                                                        Evas_GL_Texture *tex,
+                                                        double sx, double sy, double sw, double sh,
+                                                        int x, int y, int w, int h,
+                                                        int r, int g, int b, int a,
+                                                        Eina_Bool smooth);
 void             evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
                                                        Evas_GL_Texture *tex,
                                                        int npoints,
                                                        RGBA_Map_Point *p,
                                                        int clip, int cx, int cy, int cw, int ch,
+                                                       Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
                                                        int r, int g, int b, int a,
                                                        Eina_Bool smooth,
                                                        Eina_Bool tex_only,
@@ -569,6 +863,15 @@ int               evas_gl_common_shader_program_init(Evas_GL_Shared *shared);
 void              evas_gl_common_shader_program_init_done(void);
 void              evas_gl_common_shader_program_shutdown(Evas_GL_Program *p);
 
+Eina_Bool         evas_gl_common_file_cache_is_dir(const char *file);
+Eina_Bool         evas_gl_common_file_cache_mkdir(const char *dir);
+Eina_Bool         evas_gl_common_file_cache_file_exists(const char *file);
+Eina_Bool         evas_gl_common_file_cache_mkpath_if_not_exists(const char *path);
+Eina_Bool         evas_gl_common_file_cache_mkpath(const char *path);
+int               evas_gl_common_file_cache_dir_check(char *cache_dir, int num);
+int               evas_gl_common_file_cache_file_check(const char *cache_dir, const char *cache_name, char *cache_file, int dir_num);
+int               evas_gl_common_file_cache_save(Evas_GL_Shared *shared);
+
 void              evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h);
 
 void              evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt);
@@ -588,7 +891,10 @@ Evas_GL_Texture  *evas_gl_common_texture_nv12_new(Evas_Engine_GL_Context *gc, DA
 void              evas_gl_common_texture_nv12_update(Evas_GL_Texture *tex, DATA8 **row, unsigned int w, unsigned int h);
 Evas_GL_Texture  *evas_gl_common_texture_nv12tiled_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h);
 void              evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **row, unsigned int w, unsigned int h);
+Evas_GL_Texture  *evas_gl_common_texture_rgb_a_pair_new(Evas_Engine_GL_Context *gc, RGBA_Image *im);
+void              evas_gl_common_texture_rgb_a_pair_update(Evas_GL_Texture *tex, RGBA_Image *im);
 
+void              evas_gl_common_image_alloc_ensure(Evas_GL_Image *im);
 void              evas_gl_common_image_all_unload(Evas_Engine_GL_Context *gc);
 
 void              evas_gl_common_image_ref(Evas_GL_Image *im);
@@ -620,6 +926,11 @@ void              evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_P
 
 void              evas_gl_common_line_draw(Evas_Engine_GL_Context *gc, int x1, int y1, int x2, int y2);
 
+int               evas_gl_common_buffer_dump(Evas_Engine_GL_Context *gc, const char* dname, const char* fname, int frame, const char* suffix);
+
+void evas_gl_common_texture_shared_specific(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt, int i);
+void evas_gl_common_texture_shared_back(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt);
+
 #if 0 // filtering disabled
 void              evas_gl_common_filter_draw(Evas_Engine_GL_Context *context, Evas_GL_Image *im, Evas_Filter_Info *filter);
 Filtered_Image   *evas_gl_common_image_filtered_get(Evas_GL_Image *im, uint8_t *key, size_t keylen);
@@ -627,22 +938,76 @@ Filtered_Image   *evas_gl_common_image_filtered_save(Evas_GL_Image *im, Evas_GL_
 void              evas_gl_common_image_filtered_free(Evas_GL_Image *im, Filtered_Image *);
 #endif
 
-extern void (*glsym_glGenFramebuffers)      (GLsizei a, GLuint *b);
-extern void (*glsym_glBindFramebuffer)      (GLenum a, GLuint b);
-extern void (*glsym_glFramebufferTexture2D) (GLenum a, GLenum b, GLenum c, GLuint d, GLint e);
-extern void (*glsym_glDeleteFramebuffers)   (GLsizei a, const GLuint *b);
-extern void (*glsym_glGetProgramBinary)     (GLuint a, GLsizei b, GLsizei *c, GLenum *d, void *e);
-extern void (*glsym_glProgramBinary)        (GLuint a, GLenum b, const void *c, GLint d);
-extern void (*glsym_glProgramParameteri)    (GLuint a, GLuint b, GLint d);
-extern void (*glsym_glReleaseShaderCompiler)(void);
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+extern void       (*glsym_glGenFramebuffers)      (GLsizei a, GLuint *b);
+extern void       (*glsym_glBindFramebuffer)      (GLenum a, GLuint b);
+extern void       (*glsym_glFramebufferTexture2D) (GLenum a, GLenum b, GLenum c, GLuint d, GLint e);
+extern void       (*glsym_glDeleteFramebuffers)   (GLsizei a, const GLuint *b);
+extern void       (*glsym_glGetProgramBinary)     (GLuint a, GLsizei b, GLsizei *c, GLenum *d, void *e);
+extern void       (*glsym_glProgramBinary)        (GLuint a, GLenum b, const void *c, GLint d);
+extern void       (*glsym_glProgramParameteri)    (GLuint a, GLuint b, GLint d);
+extern void       (*glsym_glReleaseShaderCompiler)(void);
+extern void      *(*glsym_glMapBuffer)            (GLenum a, GLenum b);
+extern GLboolean  (*glsym_glUnmapBuffer)          (GLenum a);
+
+#ifdef GL_GLES
 extern void          *(*secsym_eglCreateImage)               (void *a, void *b, GLenum c, void *d, const int *e);
 extern unsigned int   (*secsym_eglDestroyImage)              (void *a, void *b);
 extern void           (*secsym_glEGLImageTargetTexture2DOES) (int a, void *b);
-extern void          *(*secsym_eglMapImageSEC)               (void *a, void *b);
-extern unsigned int   (*secsym_eglUnmapImageSEC)             (void *a, void *b);
+extern void          *(*secsym_eglMapImageSEC)               (void *a, void *b, int c, int d);
+extern unsigned int   (*secsym_eglUnmapImageSEC)             (void *a, void *b, int c);
 extern unsigned int   (*secsym_eglGetImageAttribSEC)         (void *a, void *b, int c, int *d);
+
+
+#define TBM_SURF_PLANE_MAX 4 /**< maximum number of the planes  */
+
+/* option to map the tbm_surface */
+#define TBM_SURF_OPTION_READ      (1 << 0) /**< access option to read  */
+#define TBM_SURF_OPTION_WRITE     (1 << 1) /**< access option to write */
+
+#define __tbm_fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
+                             ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+
+#define TBM_FORMAT_C8       __tbm_fourcc_code('C', '8', ' ', ' ')
+#define TBM_FORMAT_RGBA8888 __tbm_fourcc_code('R', 'A', '2', '4')
+#define TBM_FORMAT_BGRA8888 __tbm_fourcc_code('B', 'A', '2', '4')
+#define TBM_FORMAT_RGB888   __tbm_fourcc_code('R', 'G', '2', '4')
+
+typedef struct _tbm_surface * tbm_surface_h;
+typedef uint32_t tbm_format;
+typedef struct _tbm_surface_plane
+{
+    unsigned char *ptr;   /**< Plane pointer */
+    uint32_t size;        /**< Plane size */
+    uint32_t offset;      /**< Plane offset */
+    uint32_t stride;      /**< Plane stride */
+
+    void *reserved1;      /**< Reserved pointer1 */
+    void *reserved2;      /**< Reserved pointer2 */
+    void *reserved3;      /**< Reserved pointer3 */
+} tbm_surface_plane_s;
+
+typedef struct _tbm_surface_info
+{
+    uint32_t width;      /**< TBM surface width */
+    uint32_t height;     /**< TBM surface height */
+    tbm_format format;   /**< TBM surface format*/
+    uint32_t bpp;        /**< TBM surface bbp */
+    uint32_t size;       /**< TBM surface size */
+
+    uint32_t num_planes;                            /**< The number of planes */
+    tbm_surface_plane_s planes[TBM_SURF_PLANE_MAX]; /**< Array of planes */
+
+    void *reserved4;   /**< Reserved pointer4 */
+    void *reserved5;   /**< Reserved pointer5 */
+    void *reserved6;   /**< Reserved pointer6 */
+} tbm_surface_info_s;
+
+
+extern void *(*secsym_tbm_surface_create) (int width, int height, unsigned int format);
+extern int   (*secsym_tbm_surface_destroy) (void *surface);
+extern int   (*secsym_tbm_surface_map) (void *surface, int opt, void *info);
+extern int   (*secsym_tbm_surface_unmap) (void *surface);
+extern int   (*secsym_tbm_surface_get_info) (void *surface, void *info);
 #endif
 
 //#define GL_ERRORS 1
@@ -653,8 +1018,10 @@ extern unsigned int   (*secsym_eglGetImageAttribSEC)         (void *a, void *b,
       int __gl_err = glGetError(); \
       if (__gl_err != GL_NO_ERROR) glerr(__gl_err, fl, fn, ln, op); \
    }
+# define GLERRLOG() GLERR(__FUNCTION__, __FILE__, __LINE__, "")
 #else
 # define GLERR(fn, fl, ln, op)
+# define GLERRLOG()
 #endif
 
 Eina_Bool evas_gl_common_module_open(void);
old mode 100644 (file)
new mode 100755 (executable)
index 189506c..48c55d5
 static int sym_done = 0;
 int _evas_engine_GL_common_log_dom = -1;
 
-typedef void    (*glsym_func_void) ();
-
-void (*glsym_glGenFramebuffers)      (GLsizei a, GLuint *b) = NULL;
-void (*glsym_glBindFramebuffer)      (GLenum a, GLuint b) = NULL;
-void (*glsym_glFramebufferTexture2D) (GLenum a, GLenum b, GLenum c, GLuint d, GLint e) = NULL;
-void (*glsym_glDeleteFramebuffers)   (GLsizei a, const GLuint *b) = NULL;
-void (*glsym_glGetProgramBinary)     (GLuint a, GLsizei b, GLsizei *c, GLenum *d, void *e) = NULL;
-void (*glsym_glProgramBinary)        (GLuint a, GLenum b, const void *c, GLint d) = NULL;
-void (*glsym_glProgramParameteri)    (GLuint a, GLuint b, GLint d) = NULL;
-void (*glsym_glReleaseShaderCompiler)(void) = NULL;
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+typedef void       (*glsym_func_void) ();
+typedef void      *(*glsym_func_void_ptr) ();
+typedef GLboolean  (*glsym_func_boolean) ();
+typedef const char *(*glsym_func_const_char_ptr) ();
+
+void       (*glsym_glGenFramebuffers)      (GLsizei a, GLuint *b) = NULL;
+void       (*glsym_glBindFramebuffer)      (GLenum a, GLuint b) = NULL;
+void       (*glsym_glFramebufferTexture2D) (GLenum a, GLenum b, GLenum c, GLuint d, GLint e) = NULL;
+void       (*glsym_glDeleteFramebuffers)   (GLsizei a, const GLuint *b) = NULL;
+void       (*glsym_glGetProgramBinary)     (GLuint a, GLsizei b, GLsizei *c, GLenum *d, void *e) = NULL;
+void       (*glsym_glProgramBinary)        (GLuint a, GLenum b, const void *c, GLint d) = NULL;
+void       (*glsym_glProgramParameteri)    (GLuint a, GLuint b, GLint d) = NULL;
+void       (*glsym_glReleaseShaderCompiler)(void) = NULL;
+void      *(*glsym_glMapBuffer)            (GLenum a, GLenum b) = NULL;
+GLboolean  (*glsym_glUnmapBuffer)          (GLenum a) = NULL;
+void       (*glsym_glStartTiling)          (GLuint a, GLuint b, GLuint c, GLuint d, GLuint e) = NULL;
+void       (*glsym_glEndTiling)            (GLuint a) = NULL;
+
+#ifdef GL_GLES
 // just used for finding symbols :)
 typedef void (*_eng_fn) (void);
 
-typedef _eng_fn       (*secsym_func_eng_fn) ();
+typedef _eng_fn (*glsym_func_eng_fn) ();
+typedef int  (*secsym_func_int) ();
 typedef unsigned int  (*secsym_func_uint) ();
 typedef void         *(*secsym_func_void_ptr) ();
 
-static _eng_fn  (*secsym_eglGetProcAddress)          (const char *a) = NULL;
+static _eng_fn  (*glsym_eglGetProcAddress)           (const char *a) = NULL;
 
 void          *(*secsym_eglCreateImage)               (void *a, void *b, GLenum c, void *d, const int *e) = NULL;
 unsigned int   (*secsym_eglDestroyImage)              (void *a, void *b) = NULL;
 void           (*secsym_glEGLImageTargetTexture2DOES) (int a, void *b) = NULL;
-void          *(*secsym_eglMapImageSEC)               (void *a, void *b) = NULL;
-unsigned int   (*secsym_eglUnmapImageSEC)             (void *a, void *b) = NULL;
+void          *(*secsym_eglMapImageSEC)               (void *a, void *b, int c, int d) = NULL;
+unsigned int   (*secsym_eglUnmapImageSEC)             (void *a, void *b, int c) = NULL;
 unsigned int   (*secsym_eglGetImageAttribSEC)         (void *a, void *b, int c, int *d) = NULL;
+
+////////////////////////////////////
+//libtbm.so.1
+static void *tbm_lib_handle;
+static int tbm_sym_done = 0;
+
+void *(*secsym_tbm_surface_create) (int width, int height, unsigned int format) = NULL;
+int  (*secsym_tbm_surface_destroy) (void *surface) = NULL;
+int  (*secsym_tbm_surface_map) (void *surface, int opt, void *info) = NULL;
+int  (*secsym_tbm_surface_unmap) (void *surface) = NULL;
+int  (*secsym_tbm_surface_get_info) (void *surface, void *info) = NULL;
+////////////////////////////////////
+#else
+typedef void (*_eng_fn) (void);
+
+typedef _eng_fn (*glsym_func_eng_fn) ();
+static _eng_fn  (*glsym_glXGetProcAddress)  (const char *a) = NULL;
 #endif
 
 static int dbgflushnum = -1;
@@ -59,89 +84,125 @@ gl_symbols(void)
     * instead of dlsym
     * if (!dst) dst = (typ)SDL_GL_GetProcAddress(sym)
     */
-#define FINDSYM(dst, sym, typ) if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym)
+#ifdef GL_GLES
+#define FINDSYM(dst, sym, typ) \
+   if (glsym_eglGetProcAddress) { \
+      if (!dst) dst = (typ)glsym_eglGetProcAddress(sym); \
+   } else { \
+      if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym); \
+   }
+   FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressKHR", glsym_func_eng_fn);
+   FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressEXT", glsym_func_eng_fn);
+   FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressARB", glsym_func_eng_fn);
+   FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddress", glsym_func_eng_fn);
+#else
+#define FINDSYM(dst, sym, typ) \
+   if (glsym_glXGetProcAddress) { \
+      if (!dst) dst = (typ)glsym_glXGetProcAddress(sym); \
+   } else { \
+      if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym); \
+   }
+   FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddressEXT", glsym_func_eng_fn);
+   FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddressARB", glsym_func_eng_fn);
+   FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddress", glsym_func_eng_fn);
+#endif
+#define FINDSYM2(dst, sym, typ) if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym)
 #define FALLBAK(dst, typ) if (!dst) dst = (typ)sym_missing;
 
-   FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffers", glsym_func_void);
    FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffersEXT", glsym_func_void);
    FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffersARB", glsym_func_void);
+   FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffers", glsym_func_void);
+   // nvidia tegra3 drivers seem to not expose via getprocaddress, but dlsym finds it
+   FINDSYM2(glsym_glGenFramebuffers, "glGenFramebuffers", glsym_func_void);
    FALLBAK(glsym_glGenFramebuffers, glsym_func_void);
 
-   FINDSYM(glsym_glBindFramebuffer, "glBindFramebuffer", glsym_func_void);
    FINDSYM(glsym_glBindFramebuffer, "glBindFramebufferEXT", glsym_func_void);
    FINDSYM(glsym_glBindFramebuffer, "glBindFramebufferARB", glsym_func_void);
+   FINDSYM(glsym_glBindFramebuffer, "glBindFramebuffer", glsym_func_void);
+   // nvidia tegra3 drivers seem to not expose via getprocaddress, but dlsym finds it
+   FINDSYM2(glsym_glBindFramebuffer, "glBindFramebuffer", glsym_func_void);
    FALLBAK(glsym_glBindFramebuffer, glsym_func_void);
 
-   FINDSYM(glsym_glFramebufferTexture2D, "glFramebufferTexture2D", glsym_func_void);
    FINDSYM(glsym_glFramebufferTexture2D, "glFramebufferTexture2DEXT", glsym_func_void);
    FINDSYM(glsym_glFramebufferTexture2D, "glFramebufferTexture2DARB", glsym_func_void);
+   FINDSYM(glsym_glFramebufferTexture2D, "glFramebufferTexture2D", glsym_func_void);
+   // nvidia tegra3 drivers seem to not expose via getprocaddress, but dlsym finds it
+   FINDSYM2(glsym_glFramebufferTexture2D, "glFramebufferTexture2D", glsym_func_void);
    FALLBAK(glsym_glFramebufferTexture2D, glsym_func_void);
 
-   FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffers", glsym_func_void);
    FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffersEXT", glsym_func_void);
    FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffersARB", glsym_func_void);
+   FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffers", glsym_func_void);
+   // nvidia tegra3 drivers seem to not expose via getprocaddress, but dlsym finds it
+   FINDSYM2(glsym_glDeleteFramebuffers, "glDeleteFramebuffers", glsym_func_void);
    FALLBAK(glsym_glDeleteFramebuffers, glsym_func_void);
 
-   FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinary", glsym_func_void);
+   FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryOES", glsym_func_void);
+   FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryKHR", glsym_func_void);
    FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryEXT", glsym_func_void);
    FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryARB", glsym_func_void);
-   FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryOES", glsym_func_void);
+   FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinary", glsym_func_void);
 
-   FINDSYM(glsym_glProgramBinary, "glProgramBinary", glsym_func_void);
+   FINDSYM(glsym_glProgramBinary, "glProgramBinaryOES", glsym_func_void);
+   FINDSYM(glsym_glProgramBinary, "glProgramBinaryKHR", glsym_func_void);
    FINDSYM(glsym_glProgramBinary, "glProgramBinaryEXT", glsym_func_void);
    FINDSYM(glsym_glProgramBinary, "glProgramBinaryARB", glsym_func_void);
+   FINDSYM(glsym_glProgramBinary, "glProgramBinary", glsym_func_void);
 
-   FINDSYM(glsym_glProgramParameteri, "glProgramParameteri", glsym_func_void);
    FINDSYM(glsym_glProgramParameteri, "glProgramParameteriEXT", glsym_func_void);
    FINDSYM(glsym_glProgramParameteri, "glProgramParameteriARB", glsym_func_void);
+   FINDSYM(glsym_glProgramParameteri, "glProgramParameteri", glsym_func_void);
 
-   FINDSYM(glsym_glReleaseShaderCompiler, "glReleaseShaderCompiler", glsym_func_void);
    FINDSYM(glsym_glReleaseShaderCompiler, "glReleaseShaderCompilerEXT", glsym_func_void);
    FINDSYM(glsym_glReleaseShaderCompiler, "glReleaseShaderCompilerARB", glsym_func_void);
+   FINDSYM(glsym_glReleaseShaderCompiler, "glReleaseShaderCompiler", glsym_func_void);
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-#undef FINDSYM
-#define FINDSYM(dst, sym, typ) \
-   if ((!dst) && (secsym_eglGetProcAddress)) dst = (typ)secsym_eglGetProcAddress(sym); \
-   if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym)
+   FINDSYM(glsym_glStartTiling, "glStartTilingQCOM", glsym_func_void);
+   FINDSYM(glsym_glStartTiling, "glStartTiling", glsym_func_void);
+   FINDSYM(glsym_glStartTiling, "glActivateTileQCOM", glsym_func_void);
+
+   FINDSYM(glsym_glEndTiling, "glEndTilingQCOM", glsym_func_void);
+   FINDSYM(glsym_glEndTiling, "glEndTiling", glsym_func_void);
+
+   if (!getenv("EVAS_GL_MAPBUFFER_DISABLE"))
+     {
+        FINDSYM(glsym_glMapBuffer, "glMapBufferOES", glsym_func_void_ptr);
+        FINDSYM(glsym_glMapBuffer, "glMapBufferEXT", glsym_func_void_ptr);
+        FINDSYM(glsym_glMapBuffer, "glMapBufferARB", glsym_func_void_ptr);
+        FINDSYM(glsym_glMapBuffer, "glMapBufferKHR", glsym_func_void_ptr);
+        FINDSYM(glsym_glMapBuffer, "glMapBuffer", glsym_func_void_ptr);
+
+        FINDSYM(glsym_glUnmapBuffer, "glUnmapBufferOES", glsym_func_boolean);
+        FINDSYM(glsym_glUnmapBuffer, "glUnmapBufferEXT", glsym_func_boolean);
+        FINDSYM(glsym_glUnmapBuffer, "glUnmapBufferARB", glsym_func_boolean);
+        FINDSYM(glsym_glUnmapBuffer, "glUnmapBufferKHR", glsym_func_boolean);
+        FINDSYM(glsym_glUnmapBuffer, "glUnmapBuffer", glsym_func_boolean);
+     }
+
+#ifdef GL_GLES
 // yes - gl core looking for egl stuff. i know it's odd. a reverse-layer thing
 // but it will work as the egl/glx layer calls gl core common stuff and thus
 // these symbols will work. making the glx/egl + x11 layer do this kind-of is
 // wrong as this is not x11 (output) layer specific like the native surface
 // stuff. this is generic zero-copy textures for gl
 
-   FINDSYM(secsym_eglGetProcAddress, "eglGetProcAddress", secsym_func_eng_fn);
-   FINDSYM(secsym_eglGetProcAddress, "eglGetProcAddressEXT", secsym_func_eng_fn);
-   FINDSYM(secsym_eglGetProcAddress, "eglGetProcAddressARB", secsym_func_eng_fn);
-   FINDSYM(secsym_eglGetProcAddress, "eglGetProcAddressKHR", secsym_func_eng_fn);
-
-   FINDSYM(secsym_eglCreateImage, "eglCreateImage", secsym_func_void_ptr);
+   FINDSYM(secsym_eglCreateImage, "eglCreateImageOES", secsym_func_void_ptr);
+   FINDSYM(secsym_eglCreateImage, "eglCreateImageKHR", secsym_func_void_ptr);
    FINDSYM(secsym_eglCreateImage, "eglCreateImageEXT", secsym_func_void_ptr);
    FINDSYM(secsym_eglCreateImage, "eglCreateImageARB", secsym_func_void_ptr);
-   FINDSYM(secsym_eglCreateImage, "eglCreateImageKHR", secsym_func_void_ptr);
+   FINDSYM(secsym_eglCreateImage, "eglCreateImage", secsym_func_void_ptr);
 
-   FINDSYM(secsym_eglDestroyImage, "eglDestroyImage", secsym_func_uint);
+   FINDSYM(secsym_eglDestroyImage, "eglDestroyImageOES", secsym_func_uint);
+   FINDSYM(secsym_eglDestroyImage, "eglDestroyImageKHR", secsym_func_uint);
    FINDSYM(secsym_eglDestroyImage, "eglDestroyImageEXT", secsym_func_uint);
    FINDSYM(secsym_eglDestroyImage, "eglDestroyImageARB", secsym_func_uint);
-   FINDSYM(secsym_eglDestroyImage, "eglDestroyImageKHR", secsym_func_uint);
-
-   FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinary", glsym_func_void);
-   FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryEXT", glsym_func_void);
-   FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryARB", glsym_func_void);
-   FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryOES", glsym_func_void);
-   FINDSYM(glsym_glGetProgramBinary, "glGetProgramBinaryKHR", glsym_func_void);
-
-   FINDSYM(glsym_glProgramBinary, "glProgramBinary", glsym_func_void);
-   FINDSYM(glsym_glProgramBinary, "glProgramBinaryEXT", glsym_func_void);
-   FINDSYM(glsym_glProgramBinary, "glProgramBinaryARB", glsym_func_void);
-   FINDSYM(glsym_glProgramBinary, "glProgramBinaryOES", glsym_func_void);
-   FINDSYM(glsym_glProgramBinary, "glProgramBinaryKHR", glsym_func_void);
+   FINDSYM(secsym_eglDestroyImage, "eglDestroyImage", secsym_func_uint);
 
-   FINDSYM(glsym_glProgramParameteri, "glProgramParameteri", glsym_func_void);
-   FINDSYM(glsym_glProgramParameteri, "glProgramParameteriEXT", glsym_func_void);
-   FINDSYM(glsym_glProgramParameteri, "glProgramParameteriARB", glsym_func_void);
    FINDSYM(glsym_glProgramParameteri, "glProgramParameteriOES", glsym_func_void);
    FINDSYM(glsym_glProgramParameteri, "glProgramParameteriKHR", glsym_func_void);
+   FINDSYM(glsym_glProgramParameteri, "glProgramParameteriEXT", glsym_func_void);
+   FINDSYM(glsym_glProgramParameteri, "glProgramParameteriARB", glsym_func_void);
+   FINDSYM(glsym_glProgramParameteri, "glProgramParameteri", glsym_func_void);
 
    FINDSYM(secsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", glsym_func_void);
 
@@ -153,6 +214,38 @@ gl_symbols(void)
 #endif
 }
 
+static void
+tbm_symbols(void)
+{
+   if (tbm_sym_done) return;
+   tbm_sym_done = 1;
+
+#ifdef GL_GLES
+   tbm_lib_handle = dlopen("libtbm.so.1", RTLD_NOW);
+   if (!tbm_lib_handle)
+     {
+        DBG("Unable to open libtbm:  %s", dlerror());
+        return;
+     }
+
+#define FINDSYM(dst, sym, typ) \
+   if (!dst) dst = (typeof(dst))dlsym(tbm_lib_handle, sym); \
+   if (!dst)  \
+     { \
+        ERR("Symbol not found %s\n", sym); \
+        return; \
+     }
+
+   FINDSYM(secsym_tbm_surface_create, "tbm_surface_create", secsym_func_void_ptr);
+   FINDSYM(secsym_tbm_surface_destroy, "tbm_surface_destroy", secsym_func_int);
+   FINDSYM(secsym_tbm_surface_map, "tbm_surface_map", secsym_func_int);
+   FINDSYM(secsym_tbm_surface_unmap, "tbm_surface_unmap", secsym_func_int);
+   FINDSYM(secsym_tbm_surface_get_info, "tbm_surface_get_info", secsym_func_int);
+
+#undef FINDSYM
+#endif
+}
+
 static void shader_array_flush(Evas_Engine_GL_Context *gc);
 
 static Evas_Engine_GL_Context *_evas_gl_common_context = NULL;
@@ -245,13 +338,14 @@ matrix_ortho(GLfloat *m,
 }
 
 static int
-_evas_gl_common_version_check()
+_evas_gl_common_version_check(int *gles_ver)
 {
    char *version;
    char *tmp;
    char *tmp2;
    int major;
    int minor;
+   *gles_ver = 0;
 
   /*
    * glGetString returns a string describing the current GL connection.
@@ -259,6 +353,11 @@ _evas_gl_common_version_check()
    */
 
    version = (char *)glGetString(GL_VERSION);
+   if (!version)
+     {
+        /* Something is wrong! */
+        return 0;
+     }
 
   /*
    * OpengL ES
@@ -288,6 +387,7 @@ _evas_gl_common_version_check()
    if ((tmp = strstr(version, "OpenGL ES ")))
      {
         /* Supported */
+        *gles_ver = 2;
         return 1;
      }
 
@@ -327,7 +427,16 @@ _evas_gl_common_version_check()
    free(version);
 
    if (((major == 1) && (minor >= 4)) || (major >= 2))
+   {
+
+     /* Map GL to GLES version: Refer http://en.wikipedia.org/wiki/OpenGL_ES */
+     if ((major >=4 ) && (minor >= 3))
+       *gles_ver = 3;
+     else
+       *gles_ver = 2;
+
      return 1;
+   }
 
    return 0;
 }
@@ -376,10 +485,11 @@ _evas_gl_common_viewport_set(Evas_Engine_GL_Context *gc)
    if (foc == 0)
      {
         if ((rot == 0) || (rot == 180))
-           glViewport(0, 0, w, h);
+          glViewport(0, 0, w, h);
         else
-           glViewport(0, 0, h, w);
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+          glViewport(0, 0, h, w);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "glViewport");
+
         // std matrix
         if (m == 1)
            matrix_ortho(proj,
@@ -399,6 +509,8 @@ _evas_gl_common_viewport_set(Evas_Engine_GL_Context *gc)
      {
         int px, py, vx, vy, vw = 0, vh = 0, ax = 0, ay = 0, ppx = 0, ppy = 0;
 
+        // TODO: Should pre-rotation be handled in this case?
+
         px = gc->shared->px;
         py = gc->shared->py;
 
@@ -478,27 +590,42 @@ evas_gl_common_context_new(void)
    Evas_Engine_GL_Context *gc;
    const char *s;
    int i;
+   int gles_version;
 
 #if 1
    if (_evas_gl_common_context)
      {
+        _evas_gl_common_context->change.size = 1;
+        _evas_gl_common_context->foc = 0;
+        if(_evas_gl_common_context->shared) _evas_gl_common_context->shared->foc = 1;
+        _evas_gl_common_viewport_set(_evas_gl_common_context);
         _evas_gl_common_context->references++;
         return _evas_gl_common_context;
      }
 #endif
-   if (!_evas_gl_common_version_check())
+   if (!_evas_gl_common_version_check(&gles_version))
      return NULL;
    gc = calloc(1, sizeof(Evas_Engine_GL_Context));
    if (!gc) return NULL;
+   gc->gles_version = gles_version;
 
    gl_symbols();
+   tbm_symbols();
 
    gc->references = 1;
 
    _evas_gl_common_context = gc;
 
    for (i = 0; i < MAX_PIPES; i++)
-      gc->pipe[i].shader.render_op = EVAS_RENDER_BLEND;
+     {
+        gc->pipe[i].shader.render_op = EVAS_RENDER_BLEND;
+        if (glsym_glMapBuffer && glsym_glUnmapBuffer)
+          {
+             glGenBuffers(1, &gc->pipe[i].array.buffer);
+             gc->pipe[i].array.buffer_alloc = 0;
+             gc->pipe[i].array.buffer_use = 0;
+          }
+     }
 
    if (!shared)
      {
@@ -521,6 +648,16 @@ evas_gl_common_context_new(void)
              if ((strstr((char *)ext, "GL_ARB_get_program_binary")) ||
                  (strstr((char *)ext, "GL_OES_get_program_binary")))
                shared->info.bin_program = 1;
+             else
+                  glsym_glGetProgramBinary = NULL;
+#ifdef GL_UNPACK_ROW_LENGTH
+             shared->info.unpack_row_length = 1;
+# ifdef GL_GLES
+             if (!strstr((char *)ext, "_unpack_subimage"))
+               shared->info.unpack_row_length = 0;
+# endif
+#endif
+
 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
              if ((strstr((char *)ext, "GL_EXT_texture_filter_anisotropic")))
                 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,
@@ -531,7 +668,9 @@ evas_gl_common_context_new(void)
                  (strstr((char *)ext, "GL_EXT_texture_format_BGRA8888")))
                shared->info.bgra = 1;
 #endif
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+             if (strstr((char *)ext, "OES_compressed_ETC1_RGB8_texture"))
+               shared->info.etc1 = 1;
+#ifdef GL_GLES
              // FIXME: there should be an extension name/string to check for
              // not just symbols in the lib
              i = 0;
@@ -541,20 +680,40 @@ evas_gl_common_context_new(void)
                {
                   // test for all needed symbols - be "conservative" and
                   // need all of it
-                  if ((secsym_eglCreateImage) &&
-                      (secsym_eglDestroyImage) &&
-                      (secsym_glEGLImageTargetTexture2DOES) &&
-                      (secsym_eglMapImageSEC) &&
-                      (secsym_eglUnmapImageSEC) &&
-                      (secsym_eglGetImageAttribSEC))
+                  if ((secsym_eglCreateImage)
+                      && (secsym_eglDestroyImage)
+                      && (secsym_glEGLImageTargetTexture2DOES)
+                      && (secsym_eglMapImageSEC)
+                      && (secsym_eglUnmapImageSEC)
+                      && (secsym_eglGetImageAttribSEC)
+                     )
                      shared->info.sec_image_map = 1;
                }
+
+             if ((secsym_tbm_surface_create)
+                  && (secsym_tbm_surface_destroy)
+                  && (secsym_tbm_surface_map)
+                  && (secsym_tbm_surface_unmap)
+                  && (secsym_tbm_surface_get_info))
+                  shared->info.sec_tbm_surface = 1;
 #endif
+
+             if (!strstr((char *)ext, "GL_QCOM_tiled_rendering"))
+               {
+                  glsym_glStartTiling = NULL;
+                  glsym_glEndTiling = NULL;
+               }
           }
         glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,
                       &(shared->info.max_texture_units));
         glGetIntegerv(GL_MAX_TEXTURE_SIZE,
                       &(shared->info.max_texture_size));
+
+#ifndef TEX_BORDER_SIZE
+#define TEX_BORDER_SIZE 4  // value of TEX_BORDER_SIZE should be synched with TEX_VREP, TEX_HREP and EXTRA_HREP in gl_texture implementation
+#endif
+        shared->info.max_texture_size = shared->info.max_texture_size - TEX_BORDER_SIZE; // TEX_VREP(1) + TEX_HREP(1) + EXTRA_HREP(1/2 -in case of alpha in evas 1.7)
+
         shared->info.max_vertex_elements = 6 * 100000;
 #ifdef GL_MAX_ELEMENTS_VERTICES
 /* only applies to glDrawRangeElements. don't really need to get it.
@@ -567,14 +726,50 @@ evas_gl_common_context_new(void)
         if (shared->info.max_vertex_elements < 6)
            shared->info.max_vertex_elements = 6;
 
+#define GETENVOPT(name, tune_param, min, max) \
+        do { \
+           const char *__v = getenv(name); \
+           if (__v) { \
+              shared->info.tune.tune_param = atoi(__v); \
+              if (shared->info.tune.tune_param > max) \
+                 shared->info.tune.tune_param = max; \
+              else if (shared->info.tune.tune_param < min) \
+                 shared->info.tune.tune_param = min; \
+           } \
+        } while (0)
+
         // magic numbers that are a result of imperical testing and getting
         // "best case" performance across a range of systems
         shared->info.tune.cutout.max                 = DEF_CUTOUT;
         shared->info.tune.pipes.max                  = DEF_PIPES;
-        shared->info.tune.atlas.max_alloc_size       = DEF_ATLAS_ALLOC;
-        shared->info.tune.atlas.max_alloc_alpha_size = DEF_ATLAS_ALLOC_ALPHA;
-        shared->info.tune.atlas.max_w                = DEF_ATLAS_W;
-        shared->info.tune.atlas.max_h                = DEF_ATLAS_H;
+
+        if (getenv("EVAS_GL_TEXTURE_RECT_POOL_DISABLE"))
+        {
+            shared->info.tune.atlas.max_alloc_size       = DEF_ATLAS_ALLOC;
+            shared->info.tune.atlas.max_alloc_alpha_size = DEF_ATLAS_ALLOC_ALPHA;
+
+            shared->info.tune.atlas.max_w                = DEF_ATLAS_W;
+            shared->info.tune.atlas.max_h                = DEF_ATLAS_H;
+
+            GETENVOPT("EVAS_GL_ATLAS_ALLOC_SIZE", atlas.max_alloc_size, MIN_ATLAS_ALLOC, MAX_ATLAS_ALLOC);
+            GETENVOPT("EVAS_GL_ATLAS_ALLOC_ALPHA_SIZE", atlas.max_alloc_alpha_size, MIN_ATLAS_ALLOC_ALPHA, MAX_ATLAS_ALLOC_ALPHA);
+            GETENVOPT("EVAS_GL_ATLAS_MAX_W", atlas.max_w, 0, MAX_ATLAS_W);
+            GETENVOPT("EVAS_GL_ATLAS_MAX_H", atlas.max_h, 0, MAX_ATLAS_H);
+        }
+        else
+        {
+            shared->info.tune.atlas.max_alloc_size       = DEF_ATLAS_RECT_ALLOC;
+            shared->info.tune.atlas.max_alloc_alpha_size = DEF_ATLAS_RECT_ALLOC_ALPHA;
+
+            shared->info.tune.atlas.max_w                = DEF_ATLAS_RECT_ALLOC;
+            shared->info.tune.atlas.max_h                = DEF_ATLAS_RECT_ALLOC;
+
+            GETENVOPT("EVAS_GL_ATLAS_ALLOC_SIZE", atlas.max_alloc_size, MIN_ATLAS_ALLOC, DEF_ATLAS_RECT_ALLOC);
+            GETENVOPT("EVAS_GL_ATLAS_ALLOC_ALPHA_SIZE", atlas.max_alloc_alpha_size, MIN_ATLAS_ALLOC_ALPHA, DEF_ATLAS_RECT_ALLOC_ALPHA);
+            GETENVOPT("EVAS_GL_ATLAS_MAX_W", atlas.max_w, 0, DEF_ATLAS_RECT_ALLOC);
+            GETENVOPT("EVAS_GL_ATLAS_MAX_H", atlas.max_h, 0, DEF_ATLAS_RECT_ALLOC);
+        }
+
         shared->info.tune.atlas.slot_size            = DEF_ATLAS_SLOT;
 
         // per gpu hacks. based on impirical measurement of some known gpu's
@@ -587,24 +782,8 @@ evas_gl_common_context_new(void)
                 shared->info.tune.pipes.max = DEF_PIPES_TEGRA_2;
           }
 
-#define GETENVOPT(name, tune_param, min, max) \
-        do { \
-           const char *__v = getenv(name); \
-           if (__v) { \
-              shared->info.tune.tune_param = atoi(__v); \
-              if (shared->info.tune.tune_param > max) \
-                 shared->info.tune.tune_param = max; \
-              else if (shared->info.tune.tune_param < min) \
-                 shared->info.tune.tune_param = min; \
-           } \
-        } while (0)
-
         GETENVOPT("EVAS_GL_CUTOUT_MAX", cutout.max, -1, 0x7fffffff);
         GETENVOPT("EVAS_GL_PIPES_MAX", pipes.max, 1, MAX_PIPES);
-        GETENVOPT("EVAS_GL_ATLAS_ALLOC_SIZE", atlas.max_alloc_size, MIN_ATLAS_ALLOC, MAX_ATLAS_ALLOC);
-        GETENVOPT("EVAS_GL_ATLAS_ALLOC_ALPHA_SIZE", atlas.max_alloc_alpha_size, MIN_ATLAS_ALLOC_ALPHA, MAX_ATLAS_ALLOC_ALPHA);
-        GETENVOPT("EVAS_GL_ATLAS_MAX_W", atlas.max_w, 0, MAX_ATLAS_W);
-        GETENVOPT("EVAS_GL_ATLAS_MAX_H", atlas.max_h, 0, MAX_ATLAS_H);
         GETENVOPT("EVAS_GL_ATLAS_SLOT_SIZE", atlas.slot_size, MIN_ATLAS_SLOT, MAX_ATLAS_SLOT);
         s = (const char *)getenv("EVAS_GL_GET_PROGRAM_BINARY");
         if (s)
@@ -612,6 +791,42 @@ evas_gl_common_context_new(void)
              if (atoi(s) == 0) shared->info.bin_program = 0;
           }
 
+#ifdef GL_GLES
+        // Detect ECT2 support. We need both RGB and RGBA formats.
+          {
+             GLint texFormatCnt = 0;
+             glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &texFormatCnt);
+             if (texFormatCnt > 0)
+               {
+                  GLenum *texFormats = malloc(texFormatCnt * sizeof(GLenum));
+                  if (texFormats)
+                    {
+                       int k, cnt = 0;
+                       glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, (GLint *) texFormats);
+                       for (k = 0; k < texFormatCnt && cnt < 2; k++)
+                         {
+                            if (texFormats[k] == GL_COMPRESSED_RGB8_ETC2)
+                              cnt++;
+                            else if (texFormats[k] == GL_COMPRESSED_RGBA8_ETC2_EAC)
+                              cnt++;
+                         }
+                       shared->info.etc2 = (cnt == 2);
+                       free(texFormats);
+
+                       // Note: If we support ETC2 we'll try to always use ETC2 even when the
+                       // image has colorspace ETC1 (backwards compatibility).
+                       shared->info.etc1_subimage = shared->info.etc2;
+
+                       // FIXME: My NVIDIA driver advertises ETC2 texture formats
+                       // but does not support them. Driver bug? Logic bug?
+                       // This is in #ifdef GL_GLES because Khronos recommends
+                       // use of GL_COMPRESSED_TEXTURE_FORMATS but OpenGL 4.x
+                       // does not.
+                    }
+               }
+          }
+#endif
+
         if (getenv("EVAS_GL_INFO"))
            fprintf(stderr,
                    "max tex size %ix%i\n"
@@ -619,6 +834,8 @@ evas_gl_common_context_new(void)
                    "non-power-2 tex %i\n"
                    "rect tex %i\n"
                    "bgra : %i\n"
+                   "etc1 : %i\n"
+                   "etc2 : %i%s\n"
                    "max ansiotropic filtering: %3.3f\n"
                    "egl sec map image: %i\n"
                    "max vertex count: %i\n"
@@ -638,6 +855,8 @@ evas_gl_common_context_new(void)
                    (int)shared->info.tex_npo2,
                    (int)shared->info.tex_rect,
                    (int)shared->info.bgra,
+                   (int)shared->info.etc1,
+                   (int)shared->info.etc2, shared->info.etc2 ? " (GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGBA8_ETC2_EAC)" : "",
                    (double)shared->info.anisotropic,
                    (int)shared->info.sec_image_map,
                    (int)shared->info.max_vertex_elements,
@@ -698,12 +917,25 @@ evas_gl_common_context_new(void)
         SHADER_TEXTURE_ADD(shared, YUV, texu);
         SHADER_TEXTURE_ADD(shared, YUV, texv);
 
+        SHADER_TEXTURE_ADD(shared, YUV_MASK, tex);
+        SHADER_TEXTURE_ADD(shared, YUV_MASK, texu);
+        SHADER_TEXTURE_ADD(shared, YUV_MASK, texv);
+        SHADER_TEXTURE_ADD(shared, YUV_MASK, texm);
+
         SHADER_TEXTURE_ADD(shared, YUY2, tex);
         SHADER_TEXTURE_ADD(shared, YUY2, texuv);
 
+        SHADER_TEXTURE_ADD(shared, YUY2_MASK, tex);
+        SHADER_TEXTURE_ADD(shared, YUY2_MASK, texuv);
+        SHADER_TEXTURE_ADD(shared, YUY2_MASK, texm);
+
         SHADER_TEXTURE_ADD(shared, NV12, tex);
         SHADER_TEXTURE_ADD(shared, NV12, texuv);
 
+        SHADER_TEXTURE_ADD(shared, NV12_MASK, tex);
+        SHADER_TEXTURE_ADD(shared, NV12_MASK, texuv);
+        SHADER_TEXTURE_ADD(shared, NV12_MASK, texm);
+
         SHADER_TEXTURE_ADD(shared, YUV_NOMUL, tex);
         SHADER_TEXTURE_ADD(shared, YUV_NOMUL, texu);
         SHADER_TEXTURE_ADD(shared, YUV_NOMUL, texv);
@@ -714,11 +946,43 @@ evas_gl_common_context_new(void)
         SHADER_TEXTURE_ADD(shared, NV12_NOMUL, tex);
         SHADER_TEXTURE_ADD(shared, NV12_NOMUL, texuv);
 
+        SHADER_TEXTURE_ADD(shared, RGB_A_PAIR, tex);
+        SHADER_TEXTURE_ADD(shared, RGB_A_PAIR, texm);
+        SHADER_TEXTURE_ADD(shared, RGB_A_PAIR_NOMUL, tex);
+        SHADER_TEXTURE_ADD(shared, RGB_A_PAIR_NOMUL, texm);
+
+        SHADER_TEXTURE_ADD(shared, TIZEN_MASK, tex);
+        SHADER_TEXTURE_ADD(shared, TIZEN_MASK, texm);
+        SHADER_TEXTURE_ADD(shared, TIZEN_MASK_NOMUL, tex);
+        SHADER_TEXTURE_ADD(shared, TIZEN_MASK_NOMUL, texm);
+
         SHADER_TEXTURE_ADD(shared, IMG_MASK, tex);
         SHADER_TEXTURE_ADD(shared, IMG_MASK, texm);
+        SHADER_TEXTURE_ADD(shared, IMG_MASK_NOMUL, tex);
+        SHADER_TEXTURE_ADD(shared, IMG_MASK_NOMUL, texm);
+
+        SHADER_TEXTURE_ADD(shared, IMG_MASK_BGRA, tex);
+        SHADER_TEXTURE_ADD(shared, IMG_MASK_BGRA, texm);
+        SHADER_TEXTURE_ADD(shared, IMG_MASK_BGRA_NOMUL, tex);
+        SHADER_TEXTURE_ADD(shared, IMG_MASK_BGRA_NOMUL, texm);
+
+        SHADER_TEXTURE_ADD(shared, MAP_MASK, tex);
+        SHADER_TEXTURE_ADD(shared, MAP_MASK, texm);
+        SHADER_TEXTURE_ADD(shared, MAP_MASK_NOMUL, tex);
+        SHADER_TEXTURE_ADD(shared, MAP_MASK_NOMUL, texm);
+
+        SHADER_TEXTURE_ADD(shared, MAP_MASK_BGRA, tex);
+        SHADER_TEXTURE_ADD(shared, MAP_MASK_BGRA, texm);
+        SHADER_TEXTURE_ADD(shared, MAP_MASK_BGRA_NOMUL, tex);
+        SHADER_TEXTURE_ADD(shared, MAP_MASK_BGRA_NOMUL, texm);
+
+        SHADER_TEXTURE_ADD(shared, FONT_MASK, tex);
+        SHADER_TEXTURE_ADD(shared, FONT_MASK, texm);
+
+        SHADER_TEXTURE_ADD(shared, RECT_MASK, texm);
 
         if (gc->state.current.cur_prog == PRG_INVALID)
-           glUseProgram(gc->shared->shader[0].prog);
+           glUseProgram(shared->shader[0].prog);
         else glUseProgram(gc->state.current.cur_prog);
         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
 
@@ -733,6 +997,9 @@ evas_gl_common_context_new(void)
 
         shared->native_pm_hash  = eina_hash_int32_new(NULL);
         shared->native_tex_hash = eina_hash_int32_new(NULL);
+        shared->native_buffer_hash = eina_hash_pointer_new(NULL);
+        shared->native_tbm_hash = eina_hash_pointer_new(NULL);
+        shared->native_evasgl_hash = eina_hash_pointer_new(NULL);
      }
    gc->shared = shared;
    gc->shared->references++;
@@ -758,6 +1025,12 @@ evas_gl_common_context_free(Evas_Engine_GL_Context *gc)
 
    if (gc->def_surface) evas_gl_common_image_free(gc->def_surface);
 
+   if (glsym_glMapBuffer && glsym_glUnmapBuffer)
+     {
+        for (i = 0; i < MAX_PIPES; i++)
+          glDeleteBuffers(1, &gc->pipe[i].array.buffer);
+     }
+
    if (gc->shared)
      {
         for (i = 0; i < gc->shared->info.tune.pipes.max; i++)
@@ -768,9 +1041,13 @@ evas_gl_common_context_free(Evas_Engine_GL_Context *gc)
              if (gc->pipe[i].array.texm) free(gc->pipe[i].array.texm);
              if (gc->pipe[i].array.texuv2) free(gc->pipe[i].array.texuv2);
              if (gc->pipe[i].array.texuv3) free(gc->pipe[i].array.texuv3);
+             if (gc->pipe[i].array.texsam) free(gc->pipe[i].array.texsam);
           }
      }
 
+   while (gc->font_glyph_textures)
+     evas_gl_common_texture_free(gc->font_glyph_textures->data);
+
    if ((gc->shared) && (gc->shared->references == 0))
      {
         Evas_GL_Texture_Pool *pt;
@@ -783,18 +1060,24 @@ evas_gl_common_context_free(Evas_Engine_GL_Context *gc)
              evas_gl_common_image_free(gc->shared->images->data);
           }
 
-        EINA_LIST_FOREACH(gc->shared->tex.whole, l, pt)
-           evas_gl_texture_pool_empty(pt);
         for (i = 0; i < 33; i++)
           {
              for (j = 0; j < 3; j++)
                {
                   EINA_LIST_FOREACH(gc->shared->tex.atlas[i][j], l, pt)
                      evas_gl_texture_pool_empty(pt);
+                  eina_list_free(gc->shared->tex.atlas[i][j]);
                }
           }
+        EINA_LIST_FOREACH(gc->shared->tex.whole, l, pt)
+           evas_gl_texture_pool_empty(pt);
+        eina_list_free(gc->shared->info.cspaces);
+        eina_list_free(gc->shared->tex.whole);
         eina_hash_free(gc->shared->native_pm_hash);
         eina_hash_free(gc->shared->native_tex_hash);
+        eina_hash_free(gc->shared->native_buffer_hash);
+        eina_hash_free(gc->shared->native_tbm_hash);
+        eina_hash_free(gc->shared->native_evasgl_hash);
         free(gc->shared);
         shared = NULL;
      }
@@ -914,8 +1197,8 @@ evas_gl_common_context_newframe(Evas_Engine_GL_Context *gc)
 
    glActiveTexture(GL_TEXTURE0);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+   evas_gl_common_texture_shared_back(gc, NULL);
 
    _evas_gl_common_viewport_set(gc);
 }
@@ -933,6 +1216,56 @@ evas_gl_common_context_resize(Evas_Engine_GL_Context *gc, int w, int h, int rot)
 }
 
 void
+evas_gl_common_tiling_start(Evas_Engine_GL_Context *gc,
+                            int rot, int gw, int gh,
+                            int cx, int cy, int cw, int ch,
+                            int bitmask)
+{
+   if (!glsym_glStartTiling) return;
+   switch (rot)
+     {
+      case 0: // UP this way: ^
+        glsym_glStartTiling(cx, cy, cw, ch, bitmask);
+        break;
+      case 90: // UP this way: <
+        glsym_glStartTiling(gh - (cy + ch), cx, ch, cw, bitmask);
+        break;
+      case 180: // UP this way: v
+        glsym_glStartTiling(gw - (cx + cw), gh - (cy + ch), cw, ch, bitmask);
+        break;
+      case 270: // UP this way: >
+        glsym_glStartTiling(cy, gw - (cx + cw), ch, cw, bitmask);
+        break;
+      default: // assume up is up
+        glsym_glStartTiling(cx, cy, cw, ch, bitmask);
+        break;
+     }
+}
+
+void
+evas_gl_common_tiling_done(Evas_Engine_GL_Context *gc)
+{
+   if (glsym_glEndTiling)
+     {
+        glsym_glEndTiling(GL_COLOR_BUFFER_BIT0_QCOM);
+     }
+}
+
+
+void
+evas_gl_common_context_done(Evas_Engine_GL_Context *gc)
+{
+   if (gc->master_clip.used)
+     {
+        if (glsym_glEndTiling)
+          {
+             glsym_glEndTiling(GL_COLOR_BUFFER_BIT0_QCOM);
+          }
+        gc->master_clip.used = EINA_FALSE;
+     }
+}
+
+void
 evas_gl_common_context_target_surface_set(Evas_Engine_GL_Context *gc,
                                           Evas_GL_Image *surface)
 {
@@ -940,6 +1273,8 @@ evas_gl_common_context_target_surface_set(Evas_Engine_GL_Context *gc,
 
    evas_gl_common_context_flush(gc);
 
+   evas_gl_common_context_done(gc);
+
    gc->state.current.cur_prog = PRG_INVALID;
    gc->state.current.cur_tex = -1;
    gc->state.current.cur_texu = -1;
@@ -955,7 +1290,7 @@ evas_gl_common_context_target_surface_set(Evas_Engine_GL_Context *gc,
 
    gc->pipe[0].shader.surface = surface;
    gc->change.size = 1;
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
 # ifndef GL_FRAMEBUFFER
 #  define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
 # endif
@@ -977,53 +1312,92 @@ evas_gl_common_context_target_surface_set(Evas_Engine_GL_Context *gc,
    _evas_gl_common_viewport_set(gc);
 }
 
-#define PUSH_VERTEX(n, x, y, z) \
+#define PUSH_VERTEX(n, x, y, z) do { \
    gc->pipe[n].array.vertex[nv++] = x; \
    gc->pipe[n].array.vertex[nv++] = y; \
-   gc->pipe[n].array.vertex[nv++] = z
-#define PUSH_COLOR(n, r, g, b, a) \
+   gc->pipe[n].array.vertex[nv++] = z; } while(0)
+#define PUSH_COLOR(n, r, g, b, a) do { \
    gc->pipe[n].array.color[nc++] = r; \
    gc->pipe[n].array.color[nc++] = g; \
    gc->pipe[n].array.color[nc++] = b; \
-   gc->pipe[n].array.color[nc++] = a
-#define PUSH_TEXUV(n, u, v) \
+   gc->pipe[n].array.color[nc++] = a; } while(0)
+#define PUSH_TEXUV(n, u, v) do { \
    gc->pipe[n].array.texuv[nu++] = u; \
-   gc->pipe[n].array.texuv[nu++] = v
-#define PUSH_TEXUV2(n, u, v) \
+   gc->pipe[n].array.texuv[nu++] = v; } while(0)
+#define PUSH_TEXUV2(n, u, v) do { \
    gc->pipe[n].array.texuv2[nu2++] = u; \
-   gc->pipe[n].array.texuv2[nu2++] = v
-#define PUSH_TEXUV3(n, u, v) \
+   gc->pipe[n].array.texuv2[nu2++] = v; } while(0)
+#define PUSH_TEXUV3(n, u, v) do { \
    gc->pipe[n].array.texuv3[nu3++] = u; \
-   gc->pipe[n].array.texuv3[nu3++] = v
-#define PUSH_TEXM(n, u, v) \
+   gc->pipe[n].array.texuv3[nu3++] = v; } while(0)
+#define PUSH_TEXM(n, u, v) do { \
    gc->pipe[n].array.texm[nm++] = u; \
-   gc->pipe[n].array.texm[nm++] = v
-
+   gc->pipe[n].array.texm[nm++] = v; } while(0)
+#define PUSH_TEXSAM(n, x, y) do { \
+   gc->pipe[n].array.texsam[ns++] = x; \
+   gc->pipe[n].array.texsam[ns++] = y; } while(0)
+
+#define PUSH_6_COLORS(pn, r, g, b, a) \
+   do { int i; for (i = 0; i < 6; i++) PUSH_COLOR(pn, r, g, b, a); } while(0)
+
+#define PUSH_MASK(pn, mtex, mx, my, mw, mh) if (mtex) do { \
+   GLfloat tmx1, tmx2, tmy1, tmy2; \
+   tmx1 = mx; \
+   tmy1 = my; \
+   tmx2 = mx + mw; \
+   tmy2 = my + mh; \
+   PUSH_TEXM(pn, tmx1, tmy1); \
+   PUSH_TEXM(pn, tmx2, tmy1); \
+   PUSH_TEXM(pn, tmx1, tmy2); \
+   PUSH_TEXM(pn, tmx2, tmy1); \
+   PUSH_TEXM(pn, tmx2, tmy2); \
+   PUSH_TEXM(pn, tmx1, tmy2); \
+  } while(0)
+
+#define PIPE_GROW(gc, pn, inc) \
+   int nv = gc->pipe[pn].array.num * 3; (void) nv; \
+   int nc = gc->pipe[pn].array.num * 4; (void) nc; \
+   int nu = gc->pipe[pn].array.num * 2; (void) nu; \
+   int nu2 = gc->pipe[pn].array.num * 2; (void) nu2; \
+   int nu3 = gc->pipe[pn].array.num * 2; (void) nu3; \
+   int na = gc->pipe[pn].array.num * 2; (void) na; \
+   int ns = gc->pipe[pn].array.num * 2; (void) ns; \
+   int nm = gc->pipe[pn].array.num * 2; (void) nm; \
+   gc->pipe[pn].array.num += inc; \
+   array_alloc(gc, pn);
 
 static inline void
 array_alloc(Evas_Engine_GL_Context *gc, int n)
 {
    gc->havestuff = EINA_TRUE;
-   if (gc->pipe[n].array.num <= gc->pipe[n].array.alloc) return;
+   if (gc->pipe[n].array.num <= gc->pipe[n].array.alloc)
+     {
+#define ALOC(field, type, size) \
+   if ((gc->pipe[n].array.use_##field) && (!gc->pipe[n].array.field)) \
+       gc->pipe[n].array.field = \
+     malloc(gc->pipe[n].array.alloc * sizeof(type) * size)
+        ALOC(vertex, GLshort, 3);
+        ALOC(color,  GLubyte, 4);
+        ALOC(texuv,  GLfloat, 2);
+        ALOC(texm,   GLfloat, 2);
+        ALOC(texuv2, GLfloat, 2);
+        ALOC(texuv3, GLfloat, 2);
+        ALOC(texsam, GLfloat, 2);
+        return;
+     }
    gc->pipe[n].array.alloc += 6 * 1024;
-   if (gc->pipe[n].array.use_vertex)
-     gc->pipe[n].array.vertex = realloc(gc->pipe[n].array.vertex,
-                                gc->pipe[n].array.alloc * sizeof(GLshort) * 3);
-   if (gc->pipe[n].array.use_color)
-     gc->pipe[n].array.color  = realloc(gc->pipe[n].array.color,
-                                gc->pipe[n].array.alloc * sizeof(GLubyte) * 4);
-   if (gc->pipe[n].array.use_texuv)
-     gc->pipe[n].array.texuv  = realloc(gc->pipe[n].array.texuv,
-                                gc->pipe[n].array.alloc * sizeof(GLfloat) * 2);
-   if (gc->pipe[n].array.use_texm)
-     gc->pipe[n].array.texm  = realloc(gc->pipe[n].array.texm,
-                                gc->pipe[n].array.alloc * sizeof(GLfloat) * 2);
-   if (gc->pipe[n].array.use_texuv2)
-     gc->pipe[n].array.texuv2  = realloc(gc->pipe[n].array.texuv2,
-                               gc->pipe[n].array.alloc * sizeof(GLfloat) * 2);
-   if (gc->pipe[n].array.use_texuv3)
-     gc->pipe[n].array.texuv3  = realloc(gc->pipe[n].array.texuv3,
-                                 gc->pipe[n].array.alloc * sizeof(GLfloat) * 2);
+#define RALOC(field, type, size) \
+   if (gc->pipe[n].array.use_##field) \
+       gc->pipe[n].array.field = realloc \
+     (gc->pipe[n].array.field, \
+         gc->pipe[n].array.alloc * sizeof(type) * size)
+   RALOC(vertex, GLshort, 3);
+   RALOC(color,  GLubyte, 4);
+   RALOC(texuv,  GLfloat, 2);
+   RALOC(texm,   GLfloat, 2);
+   RALOC(texuv2, GLfloat, 2);
+   RALOC(texuv3, GLfloat, 2);
+   RALOC(texsam, GLfloat, 2);
 }
 
 #ifdef GLPIPES
@@ -1109,21 +1483,24 @@ vertex_array_size_check(Evas_Engine_GL_Context *gc, int pn, int n)
 }
 
 static inline Evas_GL_Shader
-evas_gl_common_shader_choice(int npoints __UNUSED__,
-                            RGBA_Map_Point *p,
-                            int r, int g, int b, int a,
-                            Evas_GL_Shader nomul,
-                            Evas_GL_Shader mul)
+evas_gl_common_shader_choice(int npoints EINA_UNUSED,
+                             RGBA_Map_Point *p,
+                             int r, int g, int b, int a,
+                             Eina_Bool has_mask,
+                             Evas_GL_Shader nomul,
+                             Evas_GL_Shader mul,
+                             Evas_GL_Shader mask_nomul,
+                             Evas_GL_Shader mask_mul)
 {
   if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
     {
-       if (!p) return nomul;
+       if (!p) return (has_mask ? mask_nomul : nomul);
 
        if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
            (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
-         return nomul;
+         return (has_mask ? mask_nomul : nomul);
     }
-  return mul;
+  return (has_mask ? mask_mul : mul);
 }
 
 static int
@@ -1255,6 +1632,8 @@ evas_gl_common_context_line_push(Evas_Engine_GL_Context *gc,
    gc->pipe[pn].array.use_texuv = 0;
    gc->pipe[pn].array.use_texuv2 = 0;
    gc->pipe[pn].array.use_texuv3 = 0;
+   gc->pipe[pn].array.use_texm = 0;
+   gc->pipe[pn].array.use_texsam = 0;
 
    pnum = gc->pipe[pn].array.num;
    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nt = pnum * 4;
@@ -1276,36 +1655,34 @@ evas_gl_common_context_line_push(Evas_Engine_GL_Context *gc,
    gc->pipe[pn].array.use_texuv = 0;
    gc->pipe[pn].array.use_texuv2 = 0;
    gc->pipe[pn].array.use_texuv3 = 0;
+   gc->pipe[pn].array.use_texm = 0;
+   gc->pipe[pn].array.use_texsam = 0;
 }
 
 void
 evas_gl_common_context_rectangle_push(Evas_Engine_GL_Context *gc,
                                       int x, int y, int w, int h,
-                                      int r, int g, int b, int a)
+                                      int r, int g, int b, int a,
+                                      Evas_GL_Texture *mtex,
+                                      double mx, double my, double mw, double mh,
+                                      Eina_Bool mask_smooth)
 {
-   int pnum, nv, nc, nu, nt, i;
-   Eina_Bool blend = 0;
+   Eina_Bool blend = EINA_FALSE;
    GLuint prog = gc->shared->shader[SHADER_RECT].prog;
+   GLuint mtexid = 0;
    int pn = 0;
 
-   if (gc->dc->mask.mask)
+   if (!(gc->dc->render_op == EVAS_RENDER_COPY) && (a < 255))
+     blend = EINA_TRUE;
+
+   // note: old code reused the font shader
+   if (mtex)
      {
-       RGBA_Draw_Context *dc;
-       dc = gc->dc;
-       Evas_GL_Image *im;
-       im = (void *)dc->mask.mask;
-       evas_gl_common_context_font_push(gc, im->tex,
-                                         x - dc->mask.x,
-                                         y - dc->mask.y,
-                                         dc->mask.w, dc->mask.h,
-                                         x, y, w, h,
-                                         r, g, b, a);
-       return;
+        blend = EINA_TRUE;
+        mtexid = mtex->pt->texture;
+        prog = gc->shared->shader[SHADER_RECT_MASK].prog;
      }
 
-   if (a < 255) blend = 1;
-   if (gc->dc->render_op == EVAS_RENDER_COPY) blend = 0;
-
 again:
    vertex_array_size_check(gc, gc->state.top_pipe, 6);
    pn = gc->state.top_pipe;
@@ -1314,6 +1691,7 @@ again:
      {
         gc->pipe[pn].region.type = RTYPE_RECT;
         gc->pipe[pn].shader.cur_tex = 0;
+        gc->pipe[pn].shader.cur_texm = mtexid;
         gc->pipe[pn].shader.cur_prog = prog;
         gc->pipe[pn].shader.blend = blend;
         gc->pipe[pn].shader.render_op = gc->dc->render_op;
@@ -1328,15 +1706,19 @@ again:
         gc->pipe[pn].array.use_texuv = 0;
         gc->pipe[pn].array.use_texuv2 = 0;
         gc->pipe[pn].array.use_texuv3 = 0;
+        gc->pipe[pn].array.use_texsam = 0;
+        gc->pipe[pn].array.use_texm = !!mtex;
+        gc->pipe[pn].array.mask_smooth = mask_smooth;
      }
    else
      {
-        int found = 0;
+        int found = 0, i;
 
         for (i = pn; i >= 0; i--)
           {
              if ((gc->pipe[i].region.type == RTYPE_RECT)
                  && (gc->pipe[i].shader.cur_tex == 0)
+                 && (gc->pipe[i].shader.cur_texm == mtexid)
                  && (gc->pipe[i].shader.cur_prog == prog)
                  && (gc->pipe[i].shader.blend == blend)
                  && (gc->pipe[i].shader.render_op == gc->dc->render_op)
@@ -1360,6 +1742,7 @@ again:
              gc->state.top_pipe = pn;
              gc->pipe[pn].region.type = RTYPE_RECT;
              gc->pipe[pn].shader.cur_tex = 0;
+             gc->pipe[pn].shader.cur_texm = mtexid;
              gc->pipe[pn].shader.cur_prog = prog;
              gc->pipe[pn].shader.blend = blend;
              gc->pipe[pn].shader.render_op = gc->dc->render_op;
@@ -1374,10 +1757,14 @@ again:
              gc->pipe[pn].array.use_texuv = 0;
              gc->pipe[pn].array.use_texuv2 = 0;
              gc->pipe[pn].array.use_texuv3 = 0;
+             gc->pipe[pn].array.use_texsam = 0;
+             gc->pipe[pn].array.use_texm = !!mtex;
+             gc->pipe[pn].array.mask_smooth = mask_smooth;
          }
      }
 #else
    if ((gc->pipe[pn].shader.cur_tex != 0)
+       || (gc->pipe[pn].shader.cur_texm != mtexid)
        || (gc->pipe[pn].shader.cur_prog != prog)
        || (gc->pipe[pn].shader.blend != blend)
        || (gc->pipe[pn].shader.render_op != gc->dc->render_op)
@@ -1387,6 +1774,7 @@ again:
         shader_array_flush(gc);
         pn = gc->state.top_pipe;
         gc->pipe[pn].shader.cur_tex = 0;
+        gc->pipe[pn].shader.cur_texm = mtexid;
         gc->pipe[pn].shader.cur_prog = prog;
         gc->pipe[pn].shader.blend = blend;
         gc->pipe[pn].shader.render_op = gc->dc->render_op;
@@ -1404,14 +1792,13 @@ again:
    gc->pipe[pn].array.use_texuv = 0;
    gc->pipe[pn].array.use_texuv2 = 0;
    gc->pipe[pn].array.use_texuv3 = 0;
+   gc->pipe[pn].array.use_texsam = 0;
+   gc->pipe[pn].array.use_texm = !!mtex;
+   gc->pipe[pn].array.mask_smooth = mask_smooth;
 #endif
 
    pipe_region_expand(gc, pn, x, y, w, h);
-
-   pnum = gc->pipe[pn].array.num;
-   nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nt = pnum * 4;
-   gc->pipe[pn].array.num += 6;
-   array_alloc(gc, pn);
+   PIPE_GROW(gc, pn, 6);
 
    PUSH_VERTEX(pn, x    , y    , 0);
    PUSH_VERTEX(pn, x + w, y    , 0);
@@ -1421,10 +1808,9 @@ again:
    PUSH_VERTEX(pn, x + w, y + h, 0);
    PUSH_VERTEX(pn, x    , y + h, 0);
 
-   for (i = 0; i < 6; i++)
-     {
-        PUSH_COLOR(pn, r, g, b, a);
-     }
+   PUSH_MASK(pn, mtex, mx, my, mw, mh);
+
+   PUSH_6_COLORS(pn, r, g, b, a);
 }
 
 void
@@ -1432,167 +1818,276 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
                                   Evas_GL_Texture *tex,
                                   double sx, double sy, double sw, double sh,
                                   int x, int y, int w, int h,
+                                  Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
                                   int r, int g, int b, int a,
                                   Eina_Bool smooth, Eina_Bool tex_only)
 {
-   int pnum, nv, nc, nu, nu2, nt, i;
    GLfloat tx1, tx2, ty1, ty2;
-   Eina_Bool blend = 1;
+   GLfloat tx3, tx4, ty3, ty4;
+   Eina_Bool blend = EINA_TRUE;
+   Eina_Bool afill_img = EINA_FALSE, afill_tex = EINA_FALSE;
    GLuint prog = gc->shared->shader[SHADER_IMG].prog;
-   int pn = 0;
-
-   if (!tex->alpha) blend = 0;
-   if (a < 255) blend = 1;
+   int pn = 0, sam = 0, yinvert = 0, render_op = gc->dc->render_op;
 
-   if (gc->filter_prog)
-     {
-        prog = gc->filter_prog;
-     }
-   else if (tex_only)
+   if (!mtex)
      {
-        if (tex->pt->dyn.img)
-          {
-             prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
-                                                                    SHADER_IMG_BGRA_NOMUL, SHADER_IMG_BGRA)].prog;
-          }
-        else
+        if ((gc->dc->render_op == EVAS_RENDER_COPY) ||
+            ((a == 255) && (!tex->alpha)))
+          blend = EINA_FALSE;
+        if (gc->depth == 32)
           {
-             prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
-                                                                    SHADER_TEX_NOMUL, SHADER_TEX)].prog;
+             if ((!tex->im->alpha) && (gc->dc->render_op == EVAS_RENDER_COPY))
+               afill_img = EINA_TRUE;
+             if ((!tex->alpha) && (tex->pt->native))
+               afill_tex = EINA_TRUE;
           }
      }
    else
      {
-        if (tex->gc->shared->info.bgra)
-          {
-             prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
-                                                                    SHADER_IMG_BGRA_NOMUL, SHADER_IMG_BGRA)].prog;
-          }
-        else
-          {
-             prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
-                                                                    SHADER_IMG_NOMUL, SHADER_IMG)].prog;
-          }
+        // masking forces BLEND mode (mask with COPY does not make sense)
+        render_op = EVAS_RENDER_BLEND;
+        blend = EINA_TRUE;
      }
 
-   pn = _evas_gl_common_context_push(RTYPE_IMAGE,
-                                     gc, tex, NULL,
-                                     prog,
-                                     x, y, w, h,
-                                     blend,
-                                     smooth,
-                                     0, 0, 0, 0, 0);
-
-   gc->pipe[pn].region.type = RTYPE_IMAGE;
-   gc->pipe[pn].shader.cur_tex = tex->pt->texture;
-   gc->pipe[pn].shader.cur_prog = prog;
-   gc->pipe[pn].shader.smooth = smooth;
-   gc->pipe[pn].shader.blend = blend;
-   gc->pipe[pn].shader.render_op = gc->dc->render_op;
-   gc->pipe[pn].shader.clip = 0;
-   gc->pipe[pn].shader.cx = 0;
-   gc->pipe[pn].shader.cy = 0;
-   gc->pipe[pn].shader.cw = 0;
-   gc->pipe[pn].shader.ch = 0;
-   gc->pipe[pn].array.line = 0;
-   gc->pipe[pn].array.use_vertex = 1;
-   // if nomul... dont need this
-   gc->pipe[pn].array.use_color = 1;
-   gc->pipe[pn].array.use_texuv = 1;
-   gc->pipe[pn].array.use_texuv2 = 0;
-   gc->pipe[pn].array.use_texuv3 = 0;
-
-   pipe_region_expand(gc, pn, x, y, w, h);
-
-   pnum = gc->pipe[pn].array.num;
-   nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nu2 = pnum * 2;
-   nt = pnum * 4;
-   gc->pipe[pn].array.num += 6;
-   array_alloc(gc, pn);
-
-   if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert))
+#ifdef HAVE_NATIVE_BUFFER
+   if (tex->im && tex->im->native.target == GL_TEXTURE_EXTERNAL_OES)
      {
-        tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
-        ty1 = 1.0 - ((double)(tex->y) + sy) / (double)tex->pt->h;
-        tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
-        ty2 = 1.0 - ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
+        prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                               SHADER_TIZEN_NOMUL, SHADER_TIZEN,
+                                                               SHADER_TIZEN_MASK_NOMUL, SHADER_TIZEN_MASK)].prog;
      }
    else
      {
-        tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
-        ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h;
-        tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
-        ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
-     }
-
-   PUSH_VERTEX(pn, x    , y    , 0);
-   PUSH_VERTEX(pn, x + w, y    , 0);
-   PUSH_VERTEX(pn, x    , y + h, 0);
-
-   PUSH_TEXUV(pn, tx1, ty1);
-   PUSH_TEXUV(pn, tx2, ty1);
-   PUSH_TEXUV(pn, tx1, ty2);
-
-   PUSH_VERTEX(pn, x + w, y    , 0);
-   PUSH_VERTEX(pn, x + w, y + h, 0);
-   PUSH_VERTEX(pn, x    , y + h, 0);
-
-   PUSH_TEXUV(pn, tx2, ty1);
-   PUSH_TEXUV(pn, tx2, ty2);
-   PUSH_TEXUV(pn, tx1, ty2);
+#endif
+        if (tex_only)
+          {
+             if (tex->pt->dyn.img)
+               {
+                  if ((smooth) && ((sw >= (w * 2)) && (sh >= (h * 2))))
+                    {
+                      if (afill_img)
+                         prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                SHADER_IMG_22_BGRA_NOMUL_AFILL, SHADER_IMG_22_BGRA_AFILL,
+                                                                                SHADER_IMG_22_BGRA_NOMUL_AFILL, SHADER_IMG_22_BGRA_AFILL)].prog;
+                      else
+                         prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                SHADER_IMG_22_BGRA_NOMUL, SHADER_IMG_22_BGRA,
+                                                                                SHADER_IMG_MASK_BGRA_NOMUL, SHADER_IMG_MASK_BGRA)].prog;
+                      sam = 1;
+                    }
+                  else if ((smooth) && (sw >= (w * 2)))
+                    {
+                      if (afill_img)
+                         prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                SHADER_IMG_21_BGRA_NOMUL_AFILL, SHADER_IMG_21_BGRA_AFILL,
+                                                                                SHADER_IMG_21_BGRA_NOMUL_AFILL, SHADER_IMG_21_BGRA_AFILL)].prog;
+                      else
+                         prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                SHADER_IMG_21_BGRA_NOMUL, SHADER_IMG_21_BGRA,
+                                                                                SHADER_IMG_MASK_BGRA_NOMUL, SHADER_IMG_MASK_BGRA)].prog;
+                      sam = 1;
+                    }
+                  else if ((smooth) && (sh >= (h * 2)))
+                    {
+                      if (afill_img)
+                         prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                SHADER_IMG_12_BGRA_NOMUL_AFILL, SHADER_IMG_12_BGRA_AFILL,
+                                                                                SHADER_IMG_12_BGRA_NOMUL_AFILL, SHADER_IMG_12_BGRA_AFILL)].prog;
+                      else
+                         prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                SHADER_IMG_12_BGRA_NOMUL, SHADER_IMG_12_BGRA,
+                                                                                SHADER_IMG_MASK_BGRA_NOMUL, SHADER_IMG_MASK_BGRA)].prog;
+                      sam = 1;
+                    }
+                  else
+                    {
+                      if (afill_img)
+                         prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                SHADER_IMG_BGRA_NOMUL_AFILL, SHADER_IMG_BGRA_AFILL,
+                                                                                SHADER_IMG_BGRA_NOMUL_AFILL, SHADER_IMG_BGRA_AFILL)].prog;
+                      else
+                         prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                SHADER_IMG_BGRA_NOMUL, SHADER_IMG_BGRA,
+                                                                                SHADER_IMG_MASK_BGRA_NOMUL, SHADER_IMG_MASK_BGRA)].prog;
+                    }
+               }
+             else
+               {
+                  if ((smooth) && ((sw >= (w * 2)) && (sh >= (h * 2))))
+                    {
+                      if (afill_tex)
+                        prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                               SHADER_TEX_22_NOMUL_AFILL, SHADER_TEX_22_AFILL,
+                                                                               SHADER_TEX_22_NOMUL_AFILL, SHADER_TEX_22_AFILL)].prog;
+                      else
+                        prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                               SHADER_TEX_22_NOMUL, SHADER_TEX_22,
+                                                                               SHADER_IMG_MASK_BGRA_NOMUL, SHADER_IMG_MASK_BGRA)].prog;
+                      sam = 1;
+                    }
+                  else if ((smooth) && (sw >= (w * 2)))
+                    {
+                      if (afill_tex)
+                        prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                               SHADER_TEX_21_NOMUL_AFILL, SHADER_TEX_21_AFILL,
+                                                                               SHADER_TEX_21_NOMUL_AFILL, SHADER_TEX_21_AFILL)].prog;
+                      else
+                        prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                               SHADER_TEX_21_NOMUL, SHADER_TEX_21,
+                                                                               SHADER_IMG_MASK_BGRA_NOMUL, SHADER_IMG_MASK_BGRA)].prog;
+                      sam = 1;
+                    }
+                  else if ((smooth) && (sh >= (h * 2)))
+                    {
+                      if (afill_tex)
+                        prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                               SHADER_TEX_12_NOMUL_AFILL, SHADER_TEX_12_AFILL,
+                                                                               SHADER_TEX_12_NOMUL_AFILL, SHADER_TEX_12_AFILL)].prog;
+                      else
+                        prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                               SHADER_TEX_12_NOMUL, SHADER_TEX_12,
+                                                                               SHADER_IMG_MASK_BGRA_NOMUL, SHADER_IMG_MASK_BGRA)].prog;
+                      sam = 1;
+                    }
+                  else
+                    {
+                      if (afill_tex)
+                        prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                               SHADER_TEX_NOMUL_AFILL, SHADER_TEX_AFILL,
+                                                                               SHADER_TEX_NOMUL_AFILL, SHADER_TEX_AFILL)].prog;
+                      else
+                        prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                               SHADER_TEX_NOMUL, SHADER_TEX,
+                                                                               SHADER_IMG_MASK_BGRA_NOMUL, SHADER_IMG_MASK_BGRA)].prog;
+                    }
+               }
+          }
+        else
+          {
+             if (tex->gc->shared->info.bgra)
+               {
+                  if ((smooth) && ((sw >= (w * 2)) && (sh >= (h * 2))))
+                    {
+                      if (afill_img)
+                         prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                SHADER_IMG_22_BGRA_NOMUL_AFILL, SHADER_IMG_22_BGRA_AFILL,
+                                                                                SHADER_IMG_22_BGRA_NOMUL_AFILL, SHADER_IMG_22_BGRA_AFILL)].prog;
+                      else
+                         prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                SHADER_IMG_22_BGRA_NOMUL, SHADER_IMG_22_BGRA,
+                                                                                SHADER_IMG_MASK_BGRA_NOMUL, SHADER_IMG_MASK_BGRA)].prog;
+                      sam = 1;
+                    }
+                  else if ((smooth) && (sw >= (w * 2)))
+                    {
+                      if (afill_img)
+                         prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                SHADER_IMG_21_BGRA_NOMUL_AFILL, SHADER_IMG_21_BGRA_AFILL,
+                                                                                SHADER_IMG_21_BGRA_NOMUL_AFILL, SHADER_IMG_21_BGRA_AFILL)].prog;
+                      else
+                         prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                SHADER_IMG_21_BGRA_NOMUL, SHADER_IMG_21_BGRA,
+                                                                                SHADER_IMG_MASK_BGRA_NOMUL, SHADER_IMG_MASK_BGRA)].prog;
+                      sam = 1;
+                    }
+                  else if ((smooth) && (sh >= (h * 2)))
+                    {
+                      if (afill_img)
+                         prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                SHADER_IMG_12_BGRA_NOMUL_AFILL, SHADER_IMG_12_BGRA_AFILL,
+                                                                                SHADER_IMG_12_BGRA_NOMUL_AFILL, SHADER_IMG_12_BGRA_AFILL)].prog;
+                      else
+                         prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                SHADER_IMG_12_BGRA_NOMUL, SHADER_IMG_12_BGRA,
+                                                                                SHADER_IMG_MASK_BGRA_NOMUL, SHADER_IMG_MASK_BGRA)].prog;
+                      sam = 1;
+                    }
+                  else
+                    {
+                      if (afill_img)
+                        prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                               SHADER_IMG_BGRA_NOMUL_AFILL, SHADER_IMG_BGRA_AFILL,
+                                                                               SHADER_IMG_BGRA_NOMUL_AFILL, SHADER_IMG_BGRA_AFILL)].prog;
+                      else
+                        prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                               SHADER_IMG_BGRA_NOMUL, SHADER_IMG_BGRA,
+                                                                               SHADER_IMG_MASK_BGRA_NOMUL, SHADER_IMG_MASK_BGRA)].prog;
+                    }
+               }
+             else
+               {
+                  if ((smooth) && ((sw >= (w * 2)) && (sh >= (h * 2))))
+                    {
+                      if (afill_img)
+                         prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                SHADER_IMG_22_NOMUL_AFILL, SHADER_IMG_22_AFILL,
+                                                                                SHADER_IMG_22_NOMUL_AFILL, SHADER_IMG_22_AFILL)].prog;
+                      else
+                         prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                SHADER_IMG_22_NOMUL, SHADER_IMG_22,
+                                                                                SHADER_IMG_MASK_NOMUL, SHADER_IMG_MASK)].prog;
+                      sam = 1;
+                    }
+                  else if ((smooth) && (sw >= (w * 2)))
+                    {
+                       if (afill_img)
+                          prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                 SHADER_IMG_21_NOMUL_AFILL, SHADER_IMG_21_AFILL,
+                                                                                 SHADER_IMG_21_NOMUL_AFILL, SHADER_IMG_21_AFILL)].prog;
+                       else
+                          prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                 SHADER_IMG_21_NOMUL, SHADER_IMG_21,
+                                                                                 SHADER_IMG_MASK_NOMUL, SHADER_IMG_MASK)].prog;
+                       sam = 1;
+                    }
+                  else if ((smooth) && (sh >= (h * 2)))
+                    {
+                       if (afill_img)
+                          prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                 SHADER_IMG_12_NOMUL_AFILL, SHADER_IMG_12_AFILL,
+                                                                                 SHADER_IMG_12_NOMUL_AFILL, SHADER_IMG_12_AFILL)].prog;
+                       else
+                          prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                 SHADER_IMG_12_NOMUL, SHADER_IMG_12,
+                                                                                 SHADER_IMG_MASK_NOMUL, SHADER_IMG_MASK)].prog;
+                       sam = 1;
+                    }
+                  else
+                    {
+                       if (afill_img)
+                          prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                 SHADER_IMG_NOMUL_AFILL, SHADER_IMG_AFILL,
+                                                                                 SHADER_IMG_NOMUL_AFILL, SHADER_IMG_AFILL)].prog;
+                       else
+                          prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                                                 SHADER_IMG_NOMUL, SHADER_IMG,
+                                                                                 SHADER_IMG_MASK_NOMUL, SHADER_IMG_MASK)].prog;
+                    }
+               }
+          }
 
-   // if nomul... dont need this
-   for (i = 0; i < 6; i++)
-     {
-        PUSH_COLOR(pn, r, g, b, a);
+#ifdef HAVE_NATIVE_BUFFER
      }
-}
-
-void
-evas_gl_common_context_image_mask_push(Evas_Engine_GL_Context *gc,
-                                  Evas_GL_Texture *tex,
-                                  Evas_GL_Texture *texm,
-                                  double sx, double sy, double sw, double sh,
-                                  double sxm, double sym, double swm,double shm,
-                                  int x, int y, int w, int h,
-                                  int r, int g, int b, int a,
-                                  Eina_Bool smooth)
-{
-   int pnum, nv, nc, nu, nm, nt, i;
-   GLfloat tx1, tx2, ty1, ty2;
-   GLfloat txm1, txm2, tym1, tym2;
-   Eina_Bool blend = 1;
-   GLuint prog = gc->shared->shader[SHADER_IMG_MASK].prog;
-   int pn = 0;
-
-#if 0
-   if (tex->gc->shared->info.bgra)
-   {
-      prog = gc->shared->shader[SHADER_IMG_MASK].prog;
-   }
-   else
-   {
-#warning Nash: FIXME: Need two shaders?
-          printf("Not good: Need other texture\n");
-          prog = gc->shared->shader[SHADER_IMG].prog;
-   }
 #endif
 
-   pn = _evas_gl_common_context_push(RTYPE_IMASK,
-                                     gc, tex, texm,
+   // extra sampling disabled for masking (shaders not implememented yet)
+   if (mtex) sam = 0;
+
+   pn = _evas_gl_common_context_push(RTYPE_IMAGE,
+                                     gc, tex, mtex,
                                      prog,
                                      x, y, w, h,
                                      blend,
                                      smooth,
                                      0, 0, 0, 0, 0);
 
-   gc->pipe[pn].region.type = RTYPE_IMASK;
+   gc->pipe[pn].region.type = RTYPE_IMAGE;
    gc->pipe[pn].shader.cur_tex = tex->pt->texture;
-   gc->pipe[pn].shader.cur_texm = texm->pt->texture;
+   gc->pipe[pn].shader.cur_texm = mtex ? mtex->pt->texture : 0;
    gc->pipe[pn].shader.cur_prog = prog;
    gc->pipe[pn].shader.smooth = smooth;
    gc->pipe[pn].shader.blend = blend;
-   gc->pipe[pn].shader.render_op = gc->dc->render_op;
+   gc->pipe[pn].shader.render_op = render_op;
    gc->pipe[pn].shader.clip = 0;
    gc->pipe[pn].shader.cx = 0;
    gc->pipe[pn].shader.cy = 0;
@@ -1605,99 +2100,205 @@ evas_gl_common_context_image_mask_push(Evas_Engine_GL_Context *gc,
    gc->pipe[pn].array.use_texuv = 1;
    gc->pipe[pn].array.use_texuv2 = 0;
    gc->pipe[pn].array.use_texuv3 = 0;
-   gc->pipe[pn].array.use_texm = 1;
+   gc->pipe[pn].array.use_texm = !!mtex;
+   gc->pipe[pn].array.use_texsam = sam;
+   gc->pipe[pn].array.mask_smooth = mask_smooth;
 
    pipe_region_expand(gc, pn, x, y, w, h);
+   PIPE_GROW(gc, pn, 6);
 
-   pnum = gc->pipe[pn].array.num;
-   nv = pnum * 3; nc = pnum * 4; nm = pnum * 2; nu = pnum * 2;
-   nt = pnum * 4;
-   gc->pipe[pn].array.num += 6;
-   array_alloc(gc, pn);
-
-   if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert))
+   if ((tex->im) && (tex->im->native.data))
      {
-        tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
-        ty1 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
-        tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
-        ty2 = ((double)(tex->y) + sy) / (double)tex->pt->h;
+        if (tex->im->native.func.yinvert)
+          yinvert = tex->im->native.func.yinvert(tex->im->native.func.data, tex->im);
+        else
+          yinvert = tex->im->native.yinvert;
 
-       txm1 = ((double)(texm->x) + sxm) / (double)texm->pt->w;
-        tym1 = ((double)(texm->y) + sym + shm) / (double)texm->pt->h;
-        txm2 = ((double)(texm->x) + sxm + swm) / (double)texm->pt->w;
-        tym2 = ((double)(texm->y) + sym) / (double)texm->pt->h;
+        if (!yinvert)
+          {
+             tx3 = tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
+             ty4 = ty1 = 1.0 - ((double)(tex->y) + sy) / (double)tex->pt->h;
+             tx4 = tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
+             ty3 = ty2 = 1.0 - ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
+          }
+        else
+          {
+             double tmp;
+             switch (tex->im->native.rot)
+               {
+                case 90:
+                   tmp = sx; sx = (tex->h - sy - sh) * tex->w / (double)tex->h;
+                   sy = tmp * tex->h / (double)tex->w;
+                   tmp = sw; sw = sh * tex->w / (double)tex->h;
+                   sh = tmp * tex->h / (double)tex->w;
+                   if (tex->im->native.flip == 2 || tex->im->native.flip == 3)
+                     {
+                        tx2 = tx3 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
+                        tx1 = tx4 = ((double)(tex->x) + sx) / (double)tex->pt->w;
+                     }
+                   else
+                     {
+                        tx1 = tx4 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
+                        tx2 = tx3 = ((double)(tex->x) + sx) / (double)tex->pt->w;
+                     }
+                   if (tex->im->native.flip == 1 || tex->im->native.flip == 3)
+                     {
+                        ty1 = ty3 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
+                        ty2 = ty4 = ((double)(tex->y) + sy) / (double)tex->pt->h;
+                     }
+                   else
+                     {
+                        ty2 = ty4 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
+                        ty1 = ty3 = ((double)(tex->y) + sy) / (double)tex->pt->h;
+                     }
+                   break;
+                case 180:
+                   sx = tex->w - sx - sw; sy = tex->h - sy - sh;
+                   if (tex->im->native.flip == 2 || tex->im->native.flip == 3)
+                     {
+                        tx4 = tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
+                        tx3 = tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
+                     }
+                   else
+                     {
+                        tx3 = tx1 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
+                        tx4 = tx2 = ((double)(tex->x) + sx) / (double)tex->pt->w;
+                     }
+                   if (tex->im->native.flip == 1 || tex->im->native.flip == 3)
+                     {
+                        ty3 = ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
+                        ty4 = ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h;
+                     }
+                   else
+                     {
+                        ty4 = ty1 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
+                        ty3 = ty2 = ((double)(tex->y) + sy) / (double)tex->pt->h;
+                     }
+                   break;
+                case 270:
+                   tmp = sy; sy = (tex->w - sx - sw) * tex->h / (double)tex->w;
+                   sx = tmp * tex->w / (double)tex->h;
+                   tmp = sw; sw = sh * tex->w / (double)tex->h;
+                   sh = tmp * tex->h / (double)tex->w;
+                   if (tex->im->native.flip == 2 || tex->im->native.flip == 3)
+                     {
+                        tx1 = tx4 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
+                        tx2 = tx3 = ((double)(tex->x) + sx) / (double)tex->pt->w;
+                     }
+                   else
+                     {
+                        tx2 = tx3 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
+                        tx1 = tx4 = ((double)(tex->x) + sx) / (double)tex->pt->w;
+                     }
+                   if (tex->im->native.flip == 1 || tex->im->native.flip == 3)
+                     {
+                        ty2 = ty4 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
+                        ty1 = ty3 = ((double)(tex->y) + sy) / (double)tex->pt->h;
+                     }
+                   else
+                     {
+                        ty1 = ty3 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
+                        ty2 = ty4 = ((double)(tex->y) + sy) / (double)tex->pt->h;
+                     }
+                   break;
+                case 0:
+                default:
+                   if (tex->im->native.flip == 2 || tex->im->native.flip == 3)
+                     {
+                        tx4 = tx2 = ((double)(tex->x) + sx) / (double)tex->pt->w;
+                        tx3 = tx1 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
+                     }
+                   else
+                     {
+                        tx3 = tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
+                        tx4 = tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
+                     }
+                   if (tex->im->native.flip == 1 || tex->im->native.flip == 3)
+                     {
+                        ty3 = ty2 = ((double)(tex->y) + sy) / (double)tex->pt->h;
+                        ty4 = ty1 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
+                     }
+                   else
+                     {
+                        ty4 = ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h;
+                        ty3 = ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
+                     }
+                   break;
+               }
+          }
      }
    else
      {
-        tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
-        ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h;
-        tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
-        ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
-
-        txm1 = (texm->x + sxm) / (double)texm->pt->w;
-        tym1 = (texm->y + sym) / (double)texm->pt->h;
-        txm2 = (texm->x + sxm + swm) / (double)texm->pt->w;
-        tym2 = (texm->y + sym + shm) / (double)texm->pt->h;
+        tx3 = tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
+        ty4 = ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h;
+        tx4 = tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
+        ty3 = ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
      }
- // printf(" %3.6lf %3.6lf %3.6lf %3.6lf\n",sx,sy,sw,sh);
- //  printf("m%3.6lf %3.6lf %3.6lf %3.6lf\n",sxm,sym,swm,shm);
- // printf(" %3f %3f %3f %3f\n",tx1,ty1,tx2,ty2);
- // printf("m%3f %3f %3f %3f\n",txm1,tym1,txm2,tym2);
 
    PUSH_VERTEX(pn, x    , y    , 0);
    PUSH_VERTEX(pn, x + w, y    , 0);
    PUSH_VERTEX(pn, x    , y + h, 0);
 
    PUSH_TEXUV(pn, tx1, ty1);
-   PUSH_TEXUV(pn, tx2, ty1);
-   PUSH_TEXUV(pn, tx1, ty2);
-
-   PUSH_TEXM(pn, txm1, tym1);
-   PUSH_TEXM(pn, txm2, tym1);
-   PUSH_TEXM(pn, txm1, tym2);
+   PUSH_TEXUV(pn, tx4, ty4);
+   PUSH_TEXUV(pn, tx3, ty3);
 
    PUSH_VERTEX(pn, x + w, y    , 0);
    PUSH_VERTEX(pn, x + w, y + h, 0);
    PUSH_VERTEX(pn, x    , y + h, 0);
 
-   PUSH_TEXUV(pn, tx2, ty1);
+   PUSH_TEXUV(pn, tx4, ty4);
    PUSH_TEXUV(pn, tx2, ty2);
-   PUSH_TEXUV(pn, tx1, ty2);
-
-   PUSH_TEXM(pn, txm2, tym1);
-   PUSH_TEXM(pn, txm2, tym2);
-   PUSH_TEXM(pn, txm1, tym2);
+   PUSH_TEXUV(pn, tx3, ty3);
 
-   // if nomul... dont need this
-   for (i = 0; i < 6; i++)
+   if (sam)
      {
-        PUSH_COLOR(pn, r, g, b, a);
+        double samx = (double)(sw) / (double)(tex->pt->w * w * 4);
+        double samy = (double)(sh) / (double)(tex->pt->h * h * 4);
+
+        PUSH_TEXSAM(pn, samx, samy);
+        PUSH_TEXSAM(pn, samx, samy);
+        PUSH_TEXSAM(pn, samx, samy);
+
+        PUSH_TEXSAM(pn, samx, samy);
+        PUSH_TEXSAM(pn, samx, samy);
+        PUSH_TEXSAM(pn, samx, samy);
      }
-}
 
+   PUSH_MASK(pn, mtex, mx, my, mw, mh);
+
+   // if nomul... dont need this
+   PUSH_6_COLORS(pn, r, g, b, a);
+}
 
 void
 evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
                                  Evas_GL_Texture *tex,
                                  double sx, double sy, double sw, double sh,
                                  int x, int y, int w, int h,
+                                 Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
                                  int r, int g, int b, int a)
 {
-   int pnum, nv, nc, nu, nt, i;
    GLfloat tx1, tx2, ty1, ty2;
-   GLuint prog = gc->shared->shader[SHADER_FONT].prog;
+   GLuint prog;
    int pn = 0;
 
+   if (!mtex)
+     prog = gc->shared->shader[SHADER_FONT].prog;
+   else
+     prog = gc->shared->shader[SHADER_FONT_MASK].prog;
+
    pn = _evas_gl_common_context_push(RTYPE_FONT,
-                                    gc, tex, NULL,
-                                    prog,
-                                    x, y, w, h,
-                                    1,
-                                    0,
-                                    0, 0, 0, 0, 0);
+                                     gc, tex, mtex,
+                                     prog,
+                                     x, y, w, h,
+                                     1,
+                                     0,
+                                     0, 0, 0, 0, 0);
 
    gc->pipe[pn].region.type = RTYPE_FONT;
    gc->pipe[pn].shader.cur_tex = tex->pt->texture;
+   gc->pipe[pn].shader.cur_texm = mtex ? mtex->pt->texture : 0;
    gc->pipe[pn].shader.cur_prog = prog;
    gc->pipe[pn].shader.smooth = 0;
    gc->pipe[pn].shader.blend = 1;
@@ -1713,13 +2314,12 @@ evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
    gc->pipe[pn].array.use_texuv = 1;
    gc->pipe[pn].array.use_texuv2 = 0;
    gc->pipe[pn].array.use_texuv3 = 0;
+   gc->pipe[pn].array.use_texm = !!mtex;
+   gc->pipe[pn].array.use_texsam = 0;
+   gc->pipe[pn].array.mask_smooth = mask_smooth;
 
    pipe_region_expand(gc, pn, x, y, w, h);
-
-   pnum = gc->pipe[pn].array.num;
-   nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nt = pnum * 4;
-   gc->pipe[pn].array.num += 6;
-   array_alloc(gc, pn);
+   PIPE_GROW(gc, pn, 6);
 
    if (sw == 0.0)
      {
@@ -1752,10 +2352,9 @@ evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
    PUSH_TEXUV(pn, tx2, ty2);
    PUSH_TEXUV(pn, tx1, ty2);
 
-   for (i = 0; i < 6; i++)
-     {
-        PUSH_COLOR(pn, r, g, b, a);
-     }
+   PUSH_MASK(pn, mtex, mx, my, mw, mh);
+
+   PUSH_6_COLORS(pn, r, g, b, a);
 }
 
 void
@@ -1763,32 +2362,35 @@ evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
                                 Evas_GL_Texture *tex,
                                 double sx, double sy, double sw, double sh,
                                 int x, int y, int w, int h,
+                                Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
                                 int r, int g, int b, int a,
                                 Eina_Bool smooth)
 {
-   int pnum, nv, nc, nu, nu2, nu3, nt, i;
    GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
    Eina_Bool blend = 0;
    GLuint prog;
    int pn = 0;
 
-   if (a < 255) blend = 1;
+   if ((a < 255) || (!!mtex))
+     blend = 1;
 
-   prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
-                                                          SHADER_YUV_NOMUL, SHADER_YUV)].prog;
+   prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                          SHADER_YUV_NOMUL, SHADER_YUV,
+                                                          SHADER_YUV_MASK, SHADER_YUV_MASK)].prog;
 
    pn = _evas_gl_common_context_push(RTYPE_YUV,
-                                    gc, tex, NULL,
-                                    prog,
-                                    x, y, w, h,
-                                    blend,
-                                    smooth,
-                                    0, 0, 0, 0, 0);
+                                     gc, tex, mtex,
+                                     prog,
+                                     x, y, w, h,
+                                     blend,
+                                     smooth,
+                                     0, 0, 0, 0, 0);
 
    gc->pipe[pn].region.type = RTYPE_YUV;
    gc->pipe[pn].shader.cur_tex = tex->pt->texture;
    gc->pipe[pn].shader.cur_texu = tex->ptu->texture;
    gc->pipe[pn].shader.cur_texv = tex->ptv->texture;
+   gc->pipe[pn].shader.cur_texm = mtex ? mtex->pt->texture : 0;
    gc->pipe[pn].shader.cur_prog = prog;
    gc->pipe[pn].shader.smooth = smooth;
    gc->pipe[pn].shader.blend = blend;
@@ -1804,14 +2406,12 @@ evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
    gc->pipe[pn].array.use_texuv = 1;
    gc->pipe[pn].array.use_texuv2 = 1;
    gc->pipe[pn].array.use_texuv3 = 1;
+   gc->pipe[pn].array.use_texm = !!mtex;
+   gc->pipe[pn].array.use_texsam = 0;
+   gc->pipe[pn].array.mask_smooth = mask_smooth;
 
    pipe_region_expand(gc, pn, x, y, w, h);
-
-   pnum = gc->pipe[pn].array.num;
-   nv = pnum * 3; nc = pnum * 4; nu = pnum * 2;
-   nu2 = pnum * 2; nu3 = pnum * 2; nt = pnum * 4;
-   gc->pipe[pn].array.num += 6;
-   array_alloc(gc, pn);
+   PIPE_GROW(gc, pn, 6);
 
    tx1 = (sx) / (double)tex->pt->w;
    ty1 = (sy) / (double)tex->pt->h;
@@ -1855,42 +2455,44 @@ evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
    PUSH_TEXUV3(pn, t2x2, t2y2);
    PUSH_TEXUV3(pn, t2x1, t2y2);
 
-   for (i = 0; i < 6; i++)
-     {
-        PUSH_COLOR(pn, r, g, b, a);
-     }
+   PUSH_MASK(pn, mtex, mx, my, mw, mh);
+
+   PUSH_6_COLORS(pn, r, g, b, a);
 }
 
 void
 evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
-                                Evas_GL_Texture *tex,
-                                double sx, double sy, double sw, double sh,
-                                int x, int y, int w, int h,
-                                int r, int g, int b, int a,
-                                Eina_Bool smooth)
+                                 Evas_GL_Texture *tex,
+                                 double sx, double sy, double sw, double sh,
+                                 int x, int y, int w, int h,
+                                 Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
+                                 int r, int g, int b, int a,
+                                 Eina_Bool smooth)
 {
-   int pnum, nv, nc, nu, nu2, nu3, nt, i;
    GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
    Eina_Bool blend = 0;
    GLuint prog;
    int pn = 0;
 
-   if (a < 255) blend = 1;
+   if ((a < 255) || (!!mtex))
+     blend = 1;
 
-   prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
-                                                          SHADER_YUY2_NOMUL, SHADER_YUY2)].prog;
+   prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                          SHADER_YUY2_NOMUL, SHADER_YUY2,
+                                                          SHADER_YUY2_MASK, SHADER_YUY2_MASK)].prog;
 
    pn = _evas_gl_common_context_push(RTYPE_YUY2,
-                                    gc, tex, NULL,
-                                    prog,
-                                    x, y, w, h,
-                                    blend,
-                                    smooth,
-                                    0, 0, 0, 0, 0);
+                                     gc, tex, mtex,
+                                     prog,
+                                     x, y, w, h,
+                                     blend,
+                                     smooth,
+                                     0, 0, 0, 0, 0);
 
    gc->pipe[pn].region.type = RTYPE_YUY2;
    gc->pipe[pn].shader.cur_tex = tex->pt->texture;
    gc->pipe[pn].shader.cur_texu = tex->ptuv->texture;
+   gc->pipe[pn].shader.cur_texm = mtex ? mtex->pt->texture : 0;
    gc->pipe[pn].shader.cur_prog = prog;
    gc->pipe[pn].shader.smooth = smooth;
    gc->pipe[pn].shader.blend = blend;
@@ -1906,14 +2508,12 @@ evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
    gc->pipe[pn].array.use_texuv = 1;
    gc->pipe[pn].array.use_texuv2 = 1;
    gc->pipe[pn].array.use_texuv3 = 0;
+   gc->pipe[pn].array.use_texm = !!mtex;
+   gc->pipe[pn].array.use_texsam = 0;
+   gc->pipe[pn].array.mask_smooth = mask_smooth;
 
    pipe_region_expand(gc, pn, x, y, w, h);
-
-   pnum = gc->pipe[pn].array.num;
-   nv = pnum * 3; nc = pnum * 4; nu = pnum * 2;
-   nu2 = pnum * 2; nu3 = pnum * 2; nt = pnum * 4;
-   gc->pipe[pn].array.num += 6;
-   array_alloc(gc, pn);
+   PIPE_GROW(gc, pn, 6);
 
    tx1 = (sx) / (double)tex->pt->w;
    ty1 = (sy) / (double)tex->pt->h;
@@ -1949,44 +2549,46 @@ evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
    PUSH_TEXUV2(pn, t2x2, t2y2);
    PUSH_TEXUV2(pn, t2x1, t2y2);
 
-   for (i = 0; i < 6; i++)
-     {
-        PUSH_COLOR(pn, r, g, b, a);
-     }
+   PUSH_MASK(pn, mtex, mx, my, mw, mh);
+
+   PUSH_6_COLORS(pn, r, g, b, a);
 }
 
 void
 evas_gl_common_context_nv12_push(Evas_Engine_GL_Context *gc,
-                                Evas_GL_Texture *tex,
-                                double sx, double sy, double sw, double sh,
-                                int x, int y, int w, int h,
-                                int r, int g, int b, int a,
-                                Eina_Bool smooth)
+                                 Evas_GL_Texture *tex,
+                                 double sx, double sy, double sw, double sh,
+                                 int x, int y, int w, int h,
+                                 Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
+                                 int r, int g, int b, int a,
+                                 Eina_Bool smooth)
 {
-   int pnum, nv, nc, nu, nu2, nu3, nt, i;
    GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
    Eina_Bool blend = 0;
    GLuint prog;
    int pn = 0;
 
-   if (a < 255) blend = 1;
+   if ((a < 255) || (!!mtex))
+     blend = 1;
 
-   prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a,
-                                                          SHADER_NV12_NOMUL, SHADER_NV12)].prog;
+   prog = gc->shared->shader[evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                          SHADER_NV12_NOMUL, SHADER_NV12,
+                                                          SHADER_NV12_MASK, SHADER_NV12_MASK)].prog;
 
    pn = _evas_gl_common_context_push(RTYPE_NV12,
-                                    gc, tex, NULL,
-                                    prog,
-                                    x, y, w, h,
-                                    blend,
-                                    smooth,
-                                    0, 0, 0, 0, 0);
+                                     gc, tex, mtex,
+                                     prog,
+                                     x, y, w, h,
+                                     blend,
+                                     smooth,
+                                     0, 0, 0, 0, 0);
 
    gc->pipe[pn].region.type = RTYPE_NV12;
    gc->pipe[pn].shader.cur_tex = tex->pt->texture;
    gc->pipe[pn].shader.cur_tex_dyn = tex->pt->dyn.img;
    gc->pipe[pn].shader.cur_texu = tex->ptuv->texture;
    gc->pipe[pn].shader.cur_texu_dyn = tex->ptuv->dyn.img;
+   gc->pipe[pn].shader.cur_texm = mtex ? mtex->pt->texture : 0;
    gc->pipe[pn].shader.cur_prog = prog;
    gc->pipe[pn].shader.smooth = smooth;
    gc->pipe[pn].shader.blend = blend;
@@ -2002,14 +2604,12 @@ evas_gl_common_context_nv12_push(Evas_Engine_GL_Context *gc,
    gc->pipe[pn].array.use_texuv = 1;
    gc->pipe[pn].array.use_texuv2 = 1;
    gc->pipe[pn].array.use_texuv3 = 0;
+   gc->pipe[pn].array.use_texm = !!mtex;
+   gc->pipe[pn].array.use_texsam = 0;
+   gc->pipe[pn].array.mask_smooth = mask_smooth;
 
    pipe_region_expand(gc, pn, x, y, w, h);
-
-   pnum = gc->pipe[pn].array.num;
-   nv = pnum * 3; nc = pnum * 4; nu = pnum * 2;
-   nu2 = pnum * 2; nu3 = pnum * 2; nt = pnum * 4;
-   gc->pipe[pn].array.num += 6;
-   array_alloc(gc, pn);
+   PIPE_GROW(gc, pn, 6);
 
    tx1 = (sx) / (double)tex->pt->w;
    ty1 = (sy) / (double)tex->pt->h;
@@ -2045,6 +2645,107 @@ evas_gl_common_context_nv12_push(Evas_Engine_GL_Context *gc,
    PUSH_TEXUV2(pn, t2x2, t2y2);
    PUSH_TEXUV2(pn, t2x1, t2y2);
 
+   PUSH_MASK(pn, mtex, mx, my, mw, mh);
+
+   PUSH_6_COLORS(pn, r, g, b, a);
+}
+
+void
+evas_gl_common_context_rgb_a_pair_push(Evas_Engine_GL_Context *gc,
+                                       Evas_GL_Texture *tex,
+                                       double sx, double sy,
+                                       double sw, double sh,
+                                       int x, int y, int w, int h,
+                                       int r, int g, int b, int a,
+                                       Eina_Bool smooth)
+
+{
+   /* This RGB+Alpha mode is used for ETC1+Alpha textures, where the shader
+    * will multiply RGB by alpha. Two textures are created: tex->{pt,pta}.
+    * Since the exact encoding doesn't matter here (decoding is transparent
+    * from the shader point of view), this method could be used for other
+    * colorspaces as well (eg. RGB565+Alpha4, ...).
+    */
+
+   // NOTE: RGB+A does not support masking
+
+   GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
+   GLuint prog;
+   int pn, i;
+
+   prog = gc->shared->shader[evas_gl_common_shader_choice
+     (0, NULL, r, g, b, a, EINA_FALSE,
+      SHADER_RGB_A_PAIR_NOMUL, SHADER_RGB_A_PAIR,
+      SHADER_RGB_A_PAIR_NOMUL, SHADER_RGB_A_PAIR)].prog;
+
+   pn = _evas_gl_common_context_push(RTYPE_IMAGE,
+                                     gc, tex, NULL,
+                                     prog,
+                                     x, y, w, h,
+                                     EINA_TRUE,
+                                     smooth,
+                                     EINA_FALSE, 0, 0, 0, 0);
+
+   gc->pipe[pn].region.type = RTYPE_IMAGE;
+   gc->pipe[pn].shader.cur_tex = tex->pt->texture;
+   gc->pipe[pn].shader.cur_texm = tex->pta->texture;
+   gc->pipe[pn].shader.cur_prog = prog;
+   gc->pipe[pn].shader.smooth = smooth;
+   gc->pipe[pn].shader.blend = EINA_TRUE;
+   gc->pipe[pn].shader.render_op = gc->dc->render_op;
+   gc->pipe[pn].shader.clip = 0;
+   gc->pipe[pn].shader.cx = 0;
+   gc->pipe[pn].shader.cy = 0;
+   gc->pipe[pn].shader.cw = 0;
+   gc->pipe[pn].shader.ch = 0;
+   gc->pipe[pn].array.line = 0;
+   gc->pipe[pn].array.use_vertex = EINA_TRUE;
+   // if nomul... dont need this
+   gc->pipe[pn].array.use_color = EINA_TRUE;
+   gc->pipe[pn].array.use_texuv = EINA_TRUE;
+   gc->pipe[pn].array.use_texuv2 = EINA_FALSE;
+   gc->pipe[pn].array.use_texuv3 = EINA_FALSE;
+   gc->pipe[pn].array.use_texm = EINA_TRUE;
+   gc->pipe[pn].array.mask_smooth = EINA_TRUE;
+
+   pipe_region_expand(gc, pn, x, y, w, h);
+   PIPE_GROW(gc, pn, 6);
+
+   // FIXME: pt and pta could have different x,y
+   tx1 = (tex->x + sx) / (double)tex->pt->w;
+   ty1 = (tex->y + sy) / (double)tex->pt->h;
+   tx2 = (tex->x + sx + sw) / (double)tex->pt->w;
+   ty2 = (tex->y + sy + sh) / (double)tex->pt->h;
+
+   t2x1 = (tex->x + sx) / (double)tex->pta->w;
+   t2y1 = (tex->y + sy) / (double)tex->pta->h;
+   t2x2 = (tex->x + sx + sw) / (double)tex->pta->w;
+   t2y2 = (tex->y + sy + sh) / (double)tex->pta->h;
+
+   PUSH_VERTEX(pn, x    , y    , 0);
+   PUSH_VERTEX(pn, x + w, y    , 0);
+   PUSH_VERTEX(pn, x    , y + h, 0);
+
+   PUSH_TEXUV(pn, tx1, ty1);
+   PUSH_TEXUV(pn, tx2, ty1);
+   PUSH_TEXUV(pn, tx1, ty2);
+
+   PUSH_TEXM(pn, t2x1, t2y1);
+   PUSH_TEXM(pn, t2x2, t2y1);
+   PUSH_TEXM(pn, t2x1, t2y2);
+
+   PUSH_VERTEX(pn, x + w, y    , 0);
+   PUSH_VERTEX(pn, x + w, y + h, 0);
+   PUSH_VERTEX(pn, x    , y + h, 0);
+
+   PUSH_TEXUV(pn, tx2, ty1);
+   PUSH_TEXUV(pn, tx2, ty2);
+   PUSH_TEXUV(pn, tx1, ty2);
+
+   PUSH_TEXM(pn, t2x2, t2y1);
+   PUSH_TEXM(pn, t2x2, t2y2);
+   PUSH_TEXM(pn, t2x1, t2y2);
+
    for (i = 0; i < 6; i++)
      {
         PUSH_COLOR(pn, r, g, b, a);
@@ -2057,24 +2758,26 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
                                       int npoints,
                                       RGBA_Map_Point *p,
                                       int clip, int cx, int cy, int cw, int ch,
+                                      Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
                                       int r, int g, int b, int a,
                                       Eina_Bool smooth, Eina_Bool tex_only,
                                       Evas_Colorspace cspace)
 {
-   int pnum, nv, nc, nu, nu2, nu3, nt, i;
    const int points[6] = { 0, 1, 2, 0, 2, 3 };
    int x = 0, y = 0, w = 0, h = 0, px = 0, py = 0;
    GLfloat tx[4], ty[4], t2x[4], t2y[4];
-   Eina_Bool blend = 1;
+   Eina_Bool blend = EINA_TRUE;
    DATA32 cmul;
-   GLuint prog = gc->shared->shader[SHADER_IMG].prog;
+   Evas_GL_Shader shader = SHADER_IMG;
    Eina_Bool utexture = EINA_FALSE;
    Eina_Bool uvtexture = EINA_FALSE;
-   int pn = 0;
-   int flat = 0;
+   int pn = 0, i;
+   int flat = 0, yinvert = 0;
+   GLuint prog;
+
+   if ((gc->dc->render_op == EVAS_RENDER_COPY) ||
+       ((a == 255) && (!tex->alpha) && (!mtex))) blend = EINA_FALSE;
 
-   if (!tex->alpha) blend = 0;
-   if (a < 255) blend = 1;
    if (npoints != 4)
      {
         // FIXME: nash - you didn't fix this for n points. its still all
@@ -2099,52 +2802,65 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
      {
       case EVAS_COLORSPACE_YCBCR422P601_PL:
       case EVAS_COLORSPACE_YCBCR422P709_PL:
-         prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
-                                                                SHADER_YUV_NOMUL, SHADER_YUV)].prog;
-         utexture = EINA_TRUE;
-         break;
+        shader = evas_gl_common_shader_choice(npoints, p, r, g, b, a, !!mtex,
+                                              SHADER_YUV_NOMUL, SHADER_YUV,
+                                              SHADER_YUV_MASK, SHADER_YUV_MASK);
+        utexture = EINA_TRUE;
+        break;
       case EVAS_COLORSPACE_YCBCR422601_PL:
-         prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
-                                                                SHADER_YUY2_NOMUL, SHADER_YUY2)].prog;
-         uvtexture = EINA_TRUE;
-         break;
+        shader = evas_gl_common_shader_choice(npoints, p, r, g, b, a, !!mtex,
+                                              SHADER_YUY2_NOMUL, SHADER_YUY2,
+                                              SHADER_YUY2_MASK, SHADER_YUY2_MASK);
+        uvtexture = EINA_TRUE;
+        break;
       case EVAS_COLORSPACE_YCBCR420NV12601_PL:
       case EVAS_COLORSPACE_YCBCR420TM12601_PL:
-         prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
-                                                                SHADER_NV12_NOMUL, SHADER_NV12)].prog;
-         uvtexture = EINA_TRUE;
-         break;
+        shader = evas_gl_common_shader_choice(npoints, p, r, g, b, a, !!mtex,
+                                              SHADER_NV12_NOMUL, SHADER_NV12,
+                                              SHADER_NV12_MASK, SHADER_NV12_MASK);
+        uvtexture = EINA_TRUE;
+        break;
 
       default:
-         if (tex_only)
-           {
-              if (tex->pt->dyn.img)
-                {
-                   prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
-                                                                          SHADER_IMG_BGRA_NOMUL, SHADER_IMG_BGRA)].prog;
-                }
-              else
-                {
-                   prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
-                                                                          SHADER_TEX_NOMUL, SHADER_TEX)].prog;
-                }
-           }
-         else
-           {
-              if (tex->gc->shared->info.bgra)
-                {
-                   prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
-                                                                          SHADER_IMG_BGRA_NOMUL,
-                                                                          SHADER_IMG_BGRA)].prog;
-                }
+        if (tex_only)
+          {
+             if (tex->pt->dyn.img)
+               {
+                  shader = evas_gl_common_shader_choice(npoints, p, r, g, b, a, !!mtex,
+                                                        SHADER_IMG_BGRA_NOMUL, SHADER_IMG_BGRA,
+                                                        SHADER_MAP_MASK_BGRA_NOMUL, SHADER_MAP_MASK_BGRA);
+               }
              else
                {
-                  prog = gc->shared->shader[evas_gl_common_shader_choice(npoints, p, r, g, b, a,
-                                                                         SHADER_IMG_NOMUL,
-                                                                         SHADER_IMG)].prog;
+                  shader = evas_gl_common_shader_choice(npoints, p, r, g, b, a, !!mtex,
+                                                        SHADER_TEX_NOMUL, SHADER_TEX,
+                                                        SHADER_MAP_MASK_BGRA_NOMUL, SHADER_MAP_MASK_BGRA);
+               }
+          }
+        else
+          {
+             if (tex->gc->shared->info.bgra)
+               {
+                  shader = evas_gl_common_shader_choice(npoints, p, r, g, b, a, !!mtex,
+                                                        SHADER_IMG_BGRA_NOMUL, SHADER_IMG_BGRA,
+                                                        SHADER_MAP_MASK_BGRA_NOMUL, SHADER_MAP_MASK_BGRA);
+               }
+             else
+               {
+                  shader = evas_gl_common_shader_choice(npoints, p, r, g, b, a, !!mtex,
+                                                        SHADER_IMG_NOMUL, SHADER_IMG,
+                                                        SHADER_MAP_MASK_NOMUL, SHADER_MAP_MASK);
                }
            }
      }
+   prog = gc->shared->shader[shader].prog;
+
+   /* FIXME: Add RGB+A support, as well as YUV map masking
+    * Print error messages for easier debugging... */
+   if (cspace == EVAS_COLORSPACE_ETC1_ALPHA)
+     ERR("Proper support for ETC1+Alpha maps is not implemented!");
+   else if (mtex && (utexture || uvtexture))
+     ERR("Support for YUV or ETC1+Alpha map masking is not implemented!");
 
    x = w = (p[0].x >> FP);
    y = h = (p[0].y >> FP);
@@ -2174,16 +2890,27 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
    w = w - x;
    h = h - y;
 
+   if (!flat)
+     {
+        // FUZZZZ!
+        x -= 3;
+        y -= 3;
+        w += 6;
+        h += 6;
+     }
    if (clip)
      {
-        int nx = x, ny = y, nw = w, nh = h;
-
-        RECTS_CLIP_TO_RECT(nx, ny, nw, nh, cx, cy, cw, ch);
-        if ((nx == x) && (ny == y) && (nw == w) && (nh == h))
+        if (flat)
           {
-             clip = 0; cx = 0; cy = 0; cw = 0; ch = 0;
+             int nx = x, ny = y, nw = w, nh = h;
+
+             RECTS_CLIP_TO_RECT(nx, ny, nw, nh, cx, cy, cw, ch);
+             if ((nx == x) && (ny == y) && (nw == w) && (nh == h))
+               {
+                  clip = 0; cx = 0; cy = 0; cw = 0; ch = 0;
+               }
+             x = nx; y = ny; w = nw; h = nh;
           }
-        x = nx; y = ny; w = nw; h = nh;
      }
 
    if (!flat)
@@ -2198,7 +2925,7 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
      }
 
    pn = _evas_gl_common_context_push(RTYPE_MAP,
-                                     gc, tex, NULL,
+                                     gc, tex, mtex,
                                      prog,
                                      x, y, w, h,
                                      blend,
@@ -2218,6 +2945,7 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
        gc->pipe[pn].shader.cur_texu = tex->ptuv->texture;
        gc->pipe[pn].shader.cur_texu_dyn = tex->ptuv->dyn.img;
      }
+   gc->pipe[pn].shader.cur_texm = mtex ? mtex->pt->texture : 0;
    gc->pipe[pn].shader.cur_prog = prog;
    gc->pipe[pn].shader.smooth = smooth;
    gc->pipe[pn].shader.blend = blend;
@@ -2233,16 +2961,22 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
    gc->pipe[pn].array.use_texuv = 1;
    gc->pipe[pn].array.use_texuv2 = (utexture || uvtexture) ? 1 : 0;
    gc->pipe[pn].array.use_texuv3 = (utexture) ? 1 : 0;
+   gc->pipe[pn].array.use_texm = !!mtex;
+   gc->pipe[pn].array.use_texsam = gc->pipe[pn].array.use_texm;
+   gc->pipe[pn].array.mask_smooth = mask_smooth;
 
    pipe_region_expand(gc, pn, x, y, w, h);
+   PIPE_GROW(gc, pn, 6);
 
-   pnum = gc->pipe[pn].array.num;
-   nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nu2 = pnum * 2;
-   nu2 = pnum * 2; nu3 = pnum * 2; nt = pnum * 4;
-   gc->pipe[pn].array.num += 6;
-   array_alloc(gc, pn);
+   if ((tex->im) && (tex->im->native.data))
+     {
+        if (tex->im->native.func.yinvert)
+          yinvert = tex->im->native.func.yinvert(tex->im->native.func.data, tex->im);
+        else
+          yinvert = tex->im->native.yinvert;
+     }
 
-   if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert))
+   if ((tex->im) && (tex->im->native.data) && (!yinvert))
      {
         for (i = 0; i < 4; i++)
           {
@@ -2296,6 +3030,60 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
                    B_VAL(&cl),
                    A_VAL(&cl));
      }
+
+   if (mtex)
+     {
+        double glmx, glmy, glmw, glmh, yinv = -1.f;
+        double gw = gc->w, gh = gc->h;
+
+        if (!((gc->pipe[0].shader.surface == gc->def_surface) ||
+              (!gc->pipe[0].shader.surface)))
+          {
+             gw = gc->pipe[0].shader.surface->w;
+             gh = gc->pipe[0].shader.surface->h;
+             yinv = 1.f;
+          }
+        if (!gw || !gh || !mw || !mh || !mtex->pt->w || !mtex->pt->h)
+          goto mask_error;
+
+        // vertex shader: tex_m = (X,Y) * abs(tex_coordm) + tex_sample
+        // tex_coordm
+        glmx = (double)((mtex->x * mw) - (mtex->w * mx)) / (double)(mw * mtex->pt->w);
+        glmy = (double)((mtex->y * mh) - (mtex->h * my)) / (double)(mh * mtex->pt->h);
+        PUSH_TEXM(pn, glmx, glmy);
+        PUSH_TEXM(pn, glmx, glmy);
+        PUSH_TEXM(pn, glmx, glmy);
+        PUSH_TEXM(pn, glmx, glmy);
+        PUSH_TEXM(pn, glmx, glmy);
+        PUSH_TEXM(pn, glmx, glmy);
+
+        // tex_sample: also contains sign for Y-invert
+        glmw = (double)(gw * mtex->w) / (double)(mw * mtex->pt->w);
+        glmh = yinv * ((double)(gh * mtex->h) / (double)(mh * mtex->pt->h));
+        PUSH_TEXSAM(pn, glmw, glmh);
+        PUSH_TEXSAM(pn, glmw, glmh);
+        PUSH_TEXSAM(pn, glmw, glmh);
+        PUSH_TEXSAM(pn, glmw, glmh);
+        PUSH_TEXSAM(pn, glmw, glmh);
+        PUSH_TEXSAM(pn, glmw, glmh);
+
+        // tex_coorda: Y-invert flag
+        //PUSH_TEXA(pn, 1.0, yinv);
+        //PUSH_TEXA(pn, 1.0, yinv);
+        //PUSH_TEXA(pn, 1.0, yinv);
+        //PUSH_TEXA(pn, 1.0, yinv);
+        //PUSH_TEXA(pn, 1.0, yinv);
+        //PUSH_TEXA(pn, 1.0, yinv);
+
+        /*
+        DBG("Map mask: %d,%d %dx%d --> %f , %f - %f x %f @ %f %f [gc %dx%d, tex %d,%d %dx%d, pt %dx%d]",
+            mx, my, mw, mh,
+            glmx, glmy, glmw, glmh, 1.0, yinv,
+            gc->w, gc->h, mtex->x, mtex->y, mtex->w, mtex->h, mtex->pt->w, mtex->pt->h);
+        */
+     }
+
+mask_error:
    if (!flat)
      {
         shader_array_flush(gc);
@@ -2321,19 +3109,45 @@ scissor_rot(Evas_Engine_GL_Context *gc __UNUSED__,
    switch (rot)
      {
       case 0: // UP this way: ^
-        glScissor(cx, cy, cw, ch);
+         glScissor(cx, cy, cw, ch);
+         break;
+      case 90: // UP this way: <
+         glScissor(gh - (cy + ch), cx, ch, cw);
+         break;
+      case 180: // UP this way: v
+         glScissor(gw - (cx + cw), gh - (cy + ch), cw, ch);
+         break;
+      case 270: // UP this way: >
+         glScissor(cy, gw - (cx + cw), ch, cw);
+         break;
+      default: // assume up is up
+         glScissor(cx, cy, cw, ch);
+         break;
+     }
+}
+
+static void
+start_tiling(Evas_Engine_GL_Context *gc EINA_UNUSED,
+             int rot, int gw, int gh, int cx, int cy, int cw, int ch,
+             int bitmask)
+{
+   if (!glsym_glStartTiling) return;
+   switch (rot)
+     {
+      case 0: // UP this way: ^
+        glsym_glStartTiling(cx, cy, cw, ch, bitmask);
         break;
       case 90: // UP this way: <
-        glScissor(gh - (cy + ch), cx, ch, cw);
+        glsym_glStartTiling(gh - (cy + ch), cx, ch, cw, bitmask);
         break;
       case 180: // UP this way: v
-        glScissor(gw - (cx + cw), gh - (cy + ch), cw, ch);
+        glsym_glStartTiling(gw - (cx + cw), gh - (cy + ch), cw, ch, bitmask);
         break;
       case 270: // UP this way: >
-        glScissor(cy, gw - (cx + cw), ch, cw);
+        glsym_glStartTiling(cy, gw - (cx + cw), ch, cw, bitmask);
         break;
       default: // assume up is up
-        glScissor(cx, cy, cw, ch);
+        glsym_glStartTiling(cx, cy, cw, ch, bitmask);
         break;
      }
 }
@@ -2341,7 +3155,7 @@ scissor_rot(Evas_Engine_GL_Context *gc __UNUSED__,
 static void
 shader_array_flush(Evas_Engine_GL_Context *gc)
 {
-   int i, gw, gh, setclip, cy, fbo = 0, done = 0;
+   int i, gw, gh, setclip, fbo = 0, done = 0;
 
    if (!gc->havestuff) return;
    gw = gc->w;
@@ -2382,12 +3196,12 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
 #endif
              glActiveTexture(GL_TEXTURE0);
              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-             glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_tex);
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+             evas_gl_common_texture_shared_specific(gc, NULL, i);
           }
         if (gc->pipe[i].array.im)
           {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
              if (gc->pipe[i].array.im->tex->pt->dyn.img)
                {
                   secsym_glEGLImageTargetTexture2DOES
@@ -2489,60 +3303,190 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
           }
         if (gc->pipe[i].shader.clip != gc->state.current.clip)
           {
+             int cx, cy, cw, ch;
 
-             if (gc->pipe[i].shader.clip)
+             cx = gc->pipe[i].shader.cx;
+             cy = gc->pipe[i].shader.cy;
+             cw = gc->pipe[i].shader.cw;
+             ch = gc->pipe[i].shader.ch;
+             if ((gc->master_clip.enabled) && (!fbo))
+               {
+                  if (gc->pipe[i].shader.clip)
+                    {
+                       RECTS_CLIP_TO_RECT(cx, cy, cw, ch,
+                                          gc->master_clip.x, gc->master_clip.y,
+                                          gc->master_clip.w, gc->master_clip.h);
+                    }
+                  else
+                    {
+                       cx = gc->master_clip.x;
+                       cy = gc->master_clip.y;
+                       cw = gc->master_clip.w;
+                       ch = gc->master_clip.h;
+                    }
+               }
+             if ((glsym_glStartTiling) && (glsym_glEndTiling) &&
+                 (gc->master_clip.enabled) &&
+                 (gc->master_clip.w > 0) && (gc->master_clip.h > 0))
+               {
+                  if (!gc->master_clip.used)
+                    {
+                       if (!fbo)
+                         {
+                            start_tiling(gc, gc->rot, gw, gh,
+                                         gc->master_clip.x,
+                                         gh - gc->master_clip.y - gc->master_clip.h,
+                                         gc->master_clip.w, gc->master_clip.h,
+                                         gc->preserve_bit);
+
+                            if (!gc->preserve_bit)
+                               gc->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM;
+                            gc->master_clip.used = EINA_TRUE;
+                         }
+                    }
+               }
+             if ((gc->pipe[i].shader.clip) ||
+                 ((gc->master_clip.enabled) && (!fbo)))
                {
-                  cy = gh - gc->pipe[i].shader.cy - gc->pipe[i].shader.ch;
-                  if (fbo) cy = gc->pipe[i].shader.cy;
                   glEnable(GL_SCISSOR_TEST);
                   if (!fbo)
-                     scissor_rot(gc, gc->rot, gw, gh,
-                                 gc->pipe[i].shader.cx,
-                                 cy,
-                                 gc->pipe[i].shader.cw,
-                                 gc->pipe[i].shader.ch);
+                     scissor_rot(gc, gc->rot, gw, gh, cx, gh - cy - ch, cw, ch);
                   else
-                     glScissor(gc->pipe[i].shader.cx, cy,
-                               gc->pipe[i].shader.cw, gc->pipe[i].shader.ch);
+                     glScissor(cx, cy, cw, ch);
                   setclip = 1;
+                  gc->state.current.cx = cx;
+                  gc->state.current.cy = cy;
+                  gc->state.current.cw = cw;
+                  gc->state.current.ch = ch;
                }
              else
                {
                   glDisable(GL_SCISSOR_TEST);
                   glScissor(0, 0, 0, 0);
+                  gc->state.current.cx = 0;
+                  gc->state.current.cy = 0;
+                  gc->state.current.cw = 0;
+                  gc->state.current.ch = 0;
                }
           }
-        if ((gc->pipe[i].shader.clip) && (!setclip))
+        if (((gc->pipe[i].shader.clip) && (!setclip)) ||
+            ((gc->master_clip.enabled) && (!fbo)))
           {
-             if ((gc->pipe[i].shader.cx != gc->state.current.cx) ||
-                 (gc->pipe[i].shader.cy != gc->state.current.cy) ||
-                 (gc->pipe[i].shader.cw != gc->state.current.cw) ||
-                 (gc->pipe[i].shader.ch != gc->state.current.ch))
+             int cx, cy, cw, ch;
+
+             cx = gc->pipe[i].shader.cx;
+             cy = gc->pipe[i].shader.cy;
+             cw = gc->pipe[i].shader.cw;
+             ch = gc->pipe[i].shader.ch;
+             if ((gc->master_clip.enabled) && (!fbo))
+               {
+                  if (gc->pipe[i].shader.clip)
+                    {
+                       RECTS_CLIP_TO_RECT(cx, cy, cw, ch,
+                                          gc->master_clip.x, gc->master_clip.y,
+                                          gc->master_clip.w, gc->master_clip.h);
+                    }
+                  else
+                    {
+                       cx = gc->master_clip.x;
+                       cy = gc->master_clip.y;
+                       cw = gc->master_clip.w;
+                       ch = gc->master_clip.h;
+                    }
+               }
+             if ((cx != gc->state.current.cx) ||
+                 (cy != gc->state.current.cy) ||
+                 (cw != gc->state.current.cw) ||
+                 (ch != gc->state.current.ch))
                {
-                  cy = gh - gc->pipe[i].shader.cy - gc->pipe[i].shader.ch;
-                  if (fbo) cy = gc->pipe[i].shader.cy;
                   if (!fbo)
-                     scissor_rot(gc, gc->rot, gw, gh,
-                                 gc->pipe[i].shader.cx,
-                                 cy,
-                                 gc->pipe[i].shader.cw,
-                                 gc->pipe[i].shader.ch);
+                     scissor_rot(gc, gc->rot, gw, gh, cx, gh - cy - ch, cw, ch);
                   else
-                     glScissor(gc->pipe[i].shader.cx, cy,
-                               gc->pipe[i].shader.cw, gc->pipe[i].shader.ch);
+                       glScissor(cx, cy, cw, ch);
+                  gc->state.current.cx = cx;
+                  gc->state.current.cy = cy;
+                  gc->state.current.cw = cw;
+                  gc->state.current.ch = ch;
                }
           }
 
-        glVertexAttribPointer(SHAD_VERTEX, 3, GL_SHORT, GL_FALSE, 0, gc->pipe[i].array.vertex);
+        unsigned char *vertex_ptr = NULL;
+        unsigned char *color_ptr = NULL;
+        unsigned char *texuv_ptr = NULL;
+        unsigned char *texuv2_ptr = NULL;
+        unsigned char *texuv3_ptr = NULL;
+        unsigned char *texm_ptr = NULL;
+        unsigned char *texsam_ptr = NULL;
+        GLint MASK_TEXTURE = GL_TEXTURE0;
+
+        if (glsym_glMapBuffer && glsym_glUnmapBuffer)
+          {
+             unsigned char *x;
+
+# define VERTEX_SIZE (gc->pipe[i].array.num * sizeof(GLshort) * 3)
+# define COLOR_SIZE (gc->pipe[i].array.num * sizeof(GLubyte) * 4)
+# define TEX_SIZE (gc->pipe[i].array.num * sizeof(GLfloat) * 2)
+             vertex_ptr = NULL;
+             color_ptr = vertex_ptr + VERTEX_SIZE;
+             texuv_ptr = color_ptr + COLOR_SIZE;
+             texuv2_ptr = texuv_ptr + TEX_SIZE;
+             texuv3_ptr = texuv2_ptr + TEX_SIZE;
+             texm_ptr = texuv3_ptr + TEX_SIZE;
+             texsam_ptr = texm_ptr + TEX_SIZE;
+# define END_POINTER (texsam_ptr + TEX_SIZE)
+
+             glBindBuffer(GL_ARRAY_BUFFER, gc->pipe[i].array.buffer);
+             if ((gc->pipe[i].array.buffer_alloc < (long)END_POINTER) ||
+                 (gc->pipe[i].array.buffer_use >= (ARRAY_BUFFER_USE + ARRAY_BUFFER_USE_SHIFT * i)))
+               {
+                  glBufferData(GL_ARRAY_BUFFER, (long)END_POINTER, NULL, GL_STATIC_DRAW);
+                  gc->pipe[i].array.buffer_alloc = (long)END_POINTER;
+                  gc->pipe[i].array.buffer_use = 0;
+               }
+             gc->pipe[i].array.buffer_use++;
+
+             x = glsym_glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+             if (x)
+               {
+                  if (gc->pipe[i].array.use_vertex)
+                    memcpy(x + (unsigned long)vertex_ptr, gc->pipe[i].array.vertex, VERTEX_SIZE);
+                  if (gc->pipe[i].array.use_color)
+                    memcpy(x + (unsigned long)color_ptr, gc->pipe[i].array.color, COLOR_SIZE);
+                  if (gc->pipe[i].array.use_texuv)
+                    memcpy(x + (unsigned long)texuv_ptr, gc->pipe[i].array.texuv, TEX_SIZE);
+                  if (gc->pipe[i].array.use_texuv2)
+                    memcpy(x + (unsigned long)texuv2_ptr, gc->pipe[i].array.texuv2, TEX_SIZE);
+                  if (gc->pipe[i].array.use_texuv3)
+                    memcpy(x + (unsigned long)texuv3_ptr, gc->pipe[i].array.texuv3, TEX_SIZE);
+                  if (gc->pipe[i].array.use_texm)
+                    memcpy(x + (unsigned long)texm_ptr, gc->pipe[i].array.texm, TEX_SIZE);
+                  if (gc->pipe[i].array.use_texsam)
+                    memcpy(x + (unsigned long)texsam_ptr, gc->pipe[i].array.texsam, TEX_SIZE);
+                  glsym_glUnmapBuffer(GL_ARRAY_BUFFER);
+               }
+          }
+        else
+          {
+             vertex_ptr = (unsigned char *)gc->pipe[i].array.vertex;
+             color_ptr = (unsigned char *)gc->pipe[i].array.color;
+             texuv_ptr = (unsigned char *)gc->pipe[i].array.texuv;
+             texuv2_ptr = (unsigned char *)gc->pipe[i].array.texuv2;
+             texuv3_ptr = (unsigned char *)gc->pipe[i].array.texuv3;
+             texm_ptr = (unsigned char *)gc->pipe[i].array.texm;
+             texsam_ptr = (unsigned char *)gc->pipe[i].array.texsam;
+          }
+        glVertexAttribPointer(SHAD_VERTEX, 3, GL_SHORT, GL_FALSE, 0, (void *)vertex_ptr);
         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-        glVertexAttribPointer(SHAD_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, gc->pipe[i].array.color);
+        glVertexAttribPointer(SHAD_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, (void *)color_ptr);
         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
         if (gc->pipe[i].array.use_texuv)
           {
              glEnableVertexAttribArray(SHAD_TEXUV);
              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-             glVertexAttribPointer(SHAD_TEXUV, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texuv);
+             glVertexAttribPointer(SHAD_TEXUV, 2, GL_FLOAT, GL_FALSE, 0, (void *)texuv_ptr);
              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+             MASK_TEXTURE += 1;
           }
         else
           {
@@ -2563,68 +3507,65 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
           }
         else
           {
-            if (gc->pipe[i].array.use_texm)
-              {
-                 glEnableVertexAttribArray(SHAD_TEXM);
-                  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-                  glVertexAttribPointer(SHAD_TEXM, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texm);
-                  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-                  glActiveTexture(GL_TEXTURE1);
+             if (gc->pipe[i].array.use_texsam)
+               {
+                  glEnableVertexAttribArray(SHAD_TEXSAM);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-                  glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texm);
+                  glVertexAttribPointer(SHAD_TEXSAM, 2, GL_FLOAT, GL_FALSE, 0, (void *)texsam_ptr);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-                  glActiveTexture(GL_TEXTURE0);
-                  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-              }
-            else
-              {
-                  glDisableVertexAttribArray(SHAD_TEXM);
-              }
+               }
+             else
+               {
+                  glDisableVertexAttribArray(SHAD_TEXSAM);
+               }
              if ((gc->pipe[i].array.use_texuv2) && (gc->pipe[i].array.use_texuv3))
                {
                   glEnableVertexAttribArray(SHAD_TEXUV2);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
                   glEnableVertexAttribArray(SHAD_TEXUV3);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-                  glVertexAttribPointer(SHAD_TEXUV2, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texuv2);
+                  glVertexAttribPointer(SHAD_TEXUV2, 2, GL_FLOAT, GL_FALSE, 0, (void *)texuv2_ptr);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-                  glVertexAttribPointer(SHAD_TEXUV3, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texuv3);
+                  glVertexAttribPointer(SHAD_TEXUV3, 2, GL_FLOAT, GL_FALSE, 0, (void *)texuv3_ptr);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
 
                   glActiveTexture(GL_TEXTURE1);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
                   glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texu);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
                   if (gc->pipe[i].shader.cur_texu_dyn)
                    secsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texu_dyn);
 #endif
-                  
+
                   glActiveTexture(GL_TEXTURE2);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
                   glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texv);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
                  if (gc->pipe[i].shader.cur_texv_dyn)
                    secsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texv_dyn);
 #endif
                   glActiveTexture(GL_TEXTURE0);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+                  MASK_TEXTURE += 2;
                }
              else if (gc->pipe[i].array.use_texuv2)
                {
                   glEnableVertexAttribArray(SHAD_TEXUV2);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-                  glVertexAttribPointer(SHAD_TEXUV2, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texuv2);
+                  glVertexAttribPointer(SHAD_TEXUV2, 2, GL_FLOAT, GL_FALSE, 0, (void *)texuv2_ptr);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
 
                   glActiveTexture(GL_TEXTURE1);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
                   glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texu);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
                  if (gc->pipe[i].shader.cur_texu_dyn)
-                   secsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texu_dyn);
+                   secsym_glEGLImageTargetTexture2DOES
+                    (GL_TEXTURE_2D, gc->pipe[i].shader.cur_texu_dyn);
 #endif
                   glActiveTexture(GL_TEXTURE0);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
@@ -2636,6 +3577,52 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
                   glDisableVertexAttribArray(SHAD_TEXUV3);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
                }
+
+             /* Mask surface */
+             if (gc->pipe[i].array.use_texm)
+                {
+                   glEnableVertexAttribArray(SHAD_TEXM);
+                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                   glVertexAttribPointer(SHAD_TEXM, 2, GL_FLOAT, GL_FALSE, 0, (void *)texm_ptr);
+                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                   glActiveTexture(MASK_TEXTURE);
+                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                   glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texm);
+                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+#ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
+                  if (shared->info.anisotropic > 0.0)
+                    {
+                       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, shared->info.anisotropic);
+                       GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                    }
+#endif
+                   if (gc->pipe[i].array.mask_smooth)
+                      {
+                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+                         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+                         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                      }
+                   else
+                      {
+                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+                         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+                         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                      }
+                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                   glActiveTexture(GL_TEXTURE0);
+                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+               }
+             else
+               {
+                  glDisableVertexAttribArray(SHAD_TEXM);
+                  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+               }
+
              if (dbgflushnum)
                {
                   const char *types[6] =
@@ -2667,11 +3654,12 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
 
         gc->state.current.cur_prog  = gc->pipe[i].shader.cur_prog;
         gc->state.current.cur_tex   = gc->pipe[i].shader.cur_tex;
+        gc->state.current.cur_texm  = gc->pipe[i].shader.cur_texm;
         gc->state.current.render_op = gc->pipe[i].shader.render_op;
-        gc->state.current.cx        = gc->pipe[i].shader.cx;
-        gc->state.current.cy        = gc->pipe[i].shader.cy;
-        gc->state.current.cw        = gc->pipe[i].shader.cw;
-        gc->state.current.ch        = gc->pipe[i].shader.ch;
+//        gc->state.current.cx        = gc->pipe[i].shader.cx;
+//        gc->state.current.cy        = gc->pipe[i].shader.cy;
+//        gc->state.current.cw        = gc->pipe[i].shader.cw;
+//        gc->state.current.ch        = gc->pipe[i].shader.ch;
         gc->state.current.smooth    = gc->pipe[i].shader.smooth;
         gc->state.current.blend     = gc->pipe[i].shader.blend;
         gc->state.current.clip      = gc->pipe[i].shader.clip;
@@ -2682,17 +3670,33 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
         if (gc->pipe[i].array.texm) free(gc->pipe[i].array.texm);
         if (gc->pipe[i].array.texuv2) free(gc->pipe[i].array.texuv2);
         if (gc->pipe[i].array.texuv3) free(gc->pipe[i].array.texuv3);
-
+        if (gc->pipe[i].array.texsam) free(gc->pipe[i].array.texsam);
+
+        gc->pipe[i].array.line = 0;
+        gc->pipe[i].array.use_vertex = 0;
+        gc->pipe[i].array.use_color = 0;
+        gc->pipe[i].array.use_texuv = 0;
+        gc->pipe[i].array.use_texuv2 = 0;
+        gc->pipe[i].array.use_texuv3 = 0;
+        gc->pipe[i].array.use_texm = 0;
+        gc->pipe[i].array.use_texsam = 0;
+        gc->pipe[i].array.mask_smooth = 0;
         gc->pipe[i].array.vertex = NULL;
         gc->pipe[i].array.color = NULL;
         gc->pipe[i].array.texuv = NULL;
         gc->pipe[i].array.texm = NULL;
         gc->pipe[i].array.texuv2 = NULL;
         gc->pipe[i].array.texuv3 = NULL;
+        gc->pipe[i].array.texsam = NULL;
 
         gc->pipe[i].array.num = 0;
         gc->pipe[i].array.alloc = 0;
 
+        if (glsym_glMapBuffer && glsym_glUnmapBuffer)
+          {
+             glBindBuffer(GL_ARRAY_BUFFER, 0);
+          }
+
         gc->pipe[i].region.x = 0;
         gc->pipe[i].region.y = 0;
         gc->pipe[i].region.w = 0;
@@ -2707,6 +3711,69 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
    gc->havestuff = EINA_FALSE;
 }
 
+int
+evas_gl_common_buffer_dump(Evas_Engine_GL_Context *gc, const char* dname, const char* buf_name, int frame, const char *suffix)
+{
+   RGBA_Image *im = NULL;
+   DATA32 *data1, *data2;
+   char fname[100];
+   int ok = 0;
+
+   sprintf(fname, "./%s/win_%s-fc_%03d_%s.png", dname, buf_name, frame, suffix);
+
+   data1 = (DATA32 *)malloc(gc->w * gc->h * sizeof(DATA32));
+   data2 = (DATA32 *)malloc(gc->w * gc->h * sizeof(DATA32));
+
+   if ((!data1) || (!data2)) goto finish;
+
+   glReadPixels(0, 0, gc->w, gc->h, GL_RGBA,
+                GL_UNSIGNED_BYTE, (unsigned char*)data1);
+
+   // Flip the Y and change from RGBA TO BGRA
+   int i, j;
+   for (j = 0; j < gc->h; j++)
+      for (i = 0; i < gc->w; i++)
+        {
+           DATA32 d;
+           int idx1 = (j * gc->w) + i;
+           int idx2 = ((gc->h - 1) - j) * gc->w + i;
+
+           d = data1[idx1];
+           data2[idx2] = ((d & 0x000000ff) << 16) +
+              ((d & 0x00ff0000) >> 16)  +
+              ((d & 0xff00ff00));
+        }
+
+   evas_common_convert_argb_premul(data2, gc->w * gc->h);
+
+   im = (RGBA_Image*) evas_cache_image_data(evas_common_image_cache_get(),
+                                            gc->w,
+                                            gc->h,
+                                            (DATA32 *)data2,
+                                            1,
+                                            EVAS_COLORSPACE_ARGB8888);
+   if (im)
+     {
+        im->image.data = data2;
+        if (im->image.data)
+          {
+             ok = evas_common_save_image_to_file(im, fname, NULL, 0, 0, NULL);
+
+             if (!ok) ERR("Error Saving file.");
+          }
+
+        evas_cache_image_drop(&im->cache_entry);
+     }
+
+finish:
+   if (data1) free(data1);
+   if (data2) free(data2);
+   if (im)  evas_cache_image_drop(&im->cache_entry);
+
+   if (ok) return 1;
+   else return 0;
+}
+
 Eina_Bool
 evas_gl_common_module_open(void)
 {
old mode 100644 (file)
new mode 100755 (executable)
index a5061bb..24c13e8
-#include <stdlib.h>
-#include <stdio.h>
+#include "evas_gl_core_private.h"
 #include <dlfcn.h>
-#include <string.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-#include "evas_gl_core.h"
-
-
-#define FLAG_BIT_0      0x01
-#define FLAG_BIT_1      0x02
-#define FLAG_BIT_2      0x04
-#define FLAG_BIT_3      0x08
-#define FLAG_BIT_4      0x10
-#define FLAG_BIT_5      0x20
-#define FLAG_BIT_6      0x40
-#define FLAG_BIT_7      0x80
-
-//#define EVAS_GL_DEBUG 1
-//#define EVAS_GL_PROFILE_LOG
-
-#define EVAS_GL_DEBUG_ASSERT(x)  \
-   do { \
-        if (!(x)) { ERR("Assert(%s) failed..", #x); exit(0); } \
-   } while (0)
-
-#ifdef EVAS_GL_DEBUG
-   #define COMPARE_OPT_SKIP  (1) ||
-   #define THREAD_CHECK_DEBUG() thread_check()
-#else
-   #define COMPARE_OPT_SKIP
-   #define THREAD_CHECK_DEBUG()
-#endif
 
-
-typedef struct _Call_Log
+// EVGL GL Format Pair
+typedef struct _GL_Format
 {
-   int count;
-   struct timeval start;
-   struct timeval end;
-   struct timeval total;
-} Call_Log;
-
-static Call_Log mc_log;
-static int frame_count = 0;
-
-
-#ifdef EVAS_GL_PROFILE_LOG
-#  define EVAS_GL_INIT_LOG(a) \
-   do { \
-        (a).count = 0; \
-        (a).total.tv_sec = 0; \
-        (a).total.tv_usec = 0; \
-   } while(0)
-
-#  define EVAS_GL_START_LOG(a) \
-   do { \
-        if (gettimeofday(&(a.start), NULL) != 0) \
-        fprintf(stderr, "Error Getting Time of Day \n"); \
-   } while(0)\
-
-
-#  define EVAS_GL_END_LOG(a) \
-   do { \
-        gettimeofday(&(a.end), NULL); \
-        a.count++; \
-        a.total.tv_sec = (a.end.tv_sec - a.start.tv_sec); \
-        a.total.tv_usec = (a.end.tv_usec - a.start.tv_usec); \
-        print_log("GLProfile", &a); \
-   } while(0)
-#else
-#  define EVAS_GL_INIT_LOG(a)
+   int    bit;
+   GLenum fmt;
+} GL_Format;
 
-#  define EVAS_GL_START_LOG(a)
+// Extended struct size based on the 314 functions found in gl31.h
+#define EVAS_GL_API_STRUCT_SIZE (sizeof(Evas_GL_API) + 300 * sizeof(void*))
+static Evas_GL_API *gl_funcs = NULL;
+static Evas_GL_API *gles1_funcs = NULL;
 
-#  define EVAS_GL_END_LOG(a)
-#endif
+EVGL_Engine *evgl_engine = NULL;
+int _evas_gl_log_dom   = -1;
+int _evas_gl_log_level = -1;
 
+static void _surface_cap_print(int error);
+static void _surface_context_list_print();
+static void _internal_resources_destroy(void *eng_data, EVGL_Resource *rsc);
 
-static void
-print_log(const char * name, Call_Log *log)
+// FIXME: This is a hidden option for Webkit-EFL on Tizen.
+// They were setting env vars, which have a global impact on the whole application,
+// including other Evas GL surfaces. Instead, they should request the DR and
+// memory option only on a per-surface basis.
+#define EVAS_GL_OPTIONS_DIRECT_MEMORY_OPTIMIZE 0x1000
+#define EVAS_GL_OPTIONS_DIRECT_OVERRIDE        0x2000
+
+
+//---------------------------------------------------------------//
+// Internal Resources:
+//  - Surface and Context used for internal buffer creation
+//---------------------------------------------------------------//
+static void *
+_internal_resources_create(void *eng_data)
 {
-    static double total_time = 0;
-    static int total_count = 0;
-    double seconds = log->total.tv_sec + log->total.tv_usec / 1000000.0;
-    total_count++;
-    total_time += seconds;
-
-    //if (!(log->count % 100))
-    if (!(total_count % 100))
-      {
-         fprintf(stderr, "\t[%s] Count: %d in %6.3f seconds : %d total count %6.3f total second ---- FRAMECOUNT: %d\n",
-                 name, log->count, seconds, total_count, total_time, frame_count);
-      }
-
-    EVAS_GL_INIT_LOG(*log);
-}
+   EVGL_Resource *rsc = NULL;
 
-#define EVAS_GL_PRINT_LOG(a, b) print_log(#a, &b)
+   // Check if engine is valid
+   if (!evgl_engine)
+     {
+        ERR("EVGL Engine not initialized!");
+        return NULL;
+     }
 
+   // Allocate resource
+   rsc = calloc(1, sizeof(EVGL_Resource));
+   if (!rsc)
+     {
+        ERR("Error allocating EVGL_Resource");
+        return NULL;
+     }
 
+   // Get display
+   rsc->display = evgl_engine->funcs->display_get(eng_data);
+   if (!rsc->display)
+     {
+        ERR("Error getting display");
+        goto error;
+     }
 
-//------------------------------------------------------//
-typedef _eng_fn                (*glsym_func_eng_fn) ();
-typedef void                   (*glsym_func_void) ();
-typedef XID                    (*glsym_func_xid) ();
-typedef XVisualInfo           *(*glsym_func_xvisinfo_ptr) ();
-typedef Bool                   (*glsym_func_bool) ();
-typedef unsigned int           (*glsym_func_uint) ();
-typedef int                    (*glsym_func_int) ();
-typedef unsigned char          (*glsym_func_uchar) ();
-typedef unsigned char         *(*glsym_func_uchar_ptr) ();
-typedef const unsigned char   *(*glsym_func_const_uchar_ptr) ();
-typedef char const            *(*glsym_func_char_const_ptr) ();
+   // Create resource surface
+   rsc->window = evgl_engine->funcs->native_window_create(eng_data);
+   if (!rsc->window)
+     {
+        ERR("Error creating native window");
+        goto error;
+     }
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-typedef EGLDisplay             (*glsym_func_egldpy) ();
-typedef EGLContext             (*glsym_func_eglctx) ();
-typedef EGLSurface             (*glsym_func_eglsfc) ();
-typedef EGLBoolean             (*glsym_func_eglbool) ();
-#else
-typedef GLXContext             (*glsym_func_glxctx) ();
-typedef GLXDrawable            (*glsym_func_glxdraw) ();
-typedef GLXFBConfig           *(*glsym_func_glxfbcfg_ptr) ();
-#endif
-//------------------------------------------------------//
+   rsc->surface = evgl_engine->funcs->surface_create(eng_data, rsc->window);
+   if (!rsc->surface)
+     {
+        ERR("Error creating native surface");
+        goto error;
+     }
 
-static void                *gl_lib_handle;
+   // Create a resource context
+   rsc->context = evgl_engine->funcs->context_create(eng_data, NULL, EVAS_GL_GLES_2_X);
+   if (!rsc->context)
+     {
+        ERR("Internal resource context creation failed.");
+        goto error;
+     }
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-static void                *egl_lib_handle;
-static EGLDisplay           global_dpy         = EGL_DEFAULT_DISPLAY;
-static EGLSurface           current_surf       = EGL_NO_SURFACE;
-static EGLContext           global_ctx         = NULL;
-#else
-static Display             *global_dpy         = NULL;
-static GLXDrawable          current_surf       = None;
-static GLXContext           global_ctx         = NULL;
-#endif
-static int                  global_ctx_initted = 0;
-static EvasGlueContext      current_ctx        = NULL;
-static EvasGlueContext      real_current_ctx   = NULL;
-static int                  ctx_ref_count      = 0;
-static int                  current_tid        = 0;
-
-
-static int                  log_opt            = 0;
-
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-
-//------------------------------------------------------//
-// EGL APIs... Only ones that are being used.
-//--------//
-_eng_fn      (*GL(eglGetProcAddress))            (const char *procname) = NULL;
-
-//--------//
-// Standard EGL APIs
-EGLint       (*GL(eglGetError))                  (void) = NULL;
-EGLDisplay   (*GL(eglGetDisplay))                (EGLNativeDisplayType display_id) = NULL;
-EGLBoolean   (*GL(eglInitialize))                (EGLDisplay dpy, EGLint* major, EGLint* minor) = NULL;
-EGLBoolean   (*GL(eglTerminate))                 (EGLDisplay dpy) = NULL;
-EGLBoolean   (*GL(eglChooseConfig))              (EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config) = NULL;
-EGLSurface   (*GL(eglCreateWindowSurface)  )     (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint* attrib_list) = NULL;
-EGLSurface   (*GL(eglCreatePixmapSurface)  )     (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint* attrib_list) = NULL;
-EGLBoolean   (*GL(eglDestroySurface))            (EGLDisplay dpy, EGLSurface surface) = NULL;
-EGLBoolean   (*GL(eglBindAPI))                   (EGLenum api) = NULL;
-EGLBoolean   (*GL(eglWaitClient))                (void) = NULL;
-EGLBoolean   (*GL(eglSurfaceAttrib))             (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) = NULL;
-void         (*GL(eglBindTexImage))              (EGLDisplay dpy, EGLSurface surface, EGLint buffer) = NULL;
-EGLBoolean   (*GL(eglReleaseTexImage))           (EGLDisplay dpy, EGLSurface surface, EGLint buffer) = NULL;
-EGLBoolean   (*GL(eglSwapInterval))              (EGLDisplay dpy, EGLint interval) = NULL;
-EGLContext   (*GL(eglCreateContext))             (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint* attrib_list) = NULL;
-EGLBoolean   (*GL(eglDestroyContext))            (EGLDisplay dpy, EGLContext ctx) = NULL;
-EGLBoolean   (*GL(eglMakeCurrent))               (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) = NULL;
-EGLContext   (*GL(eglGetCurrentContext))         (void) = NULL;
-EGLSurface   (*GL(eglGetCurrentSurface))         (EGLint readdraw) = NULL;
-EGLDisplay   (*GL(eglGetCurrentDisplay))         (void) = NULL;
-EGLBoolean   (*GL(eglWaitGL))                    (void) = NULL;
-EGLBoolean   (*GL(eglWaitNative))                (EGLint engine) = NULL;
-EGLBoolean   (*GL(eglSwapBuffers))               (EGLDisplay dpy, EGLSurface surface) = NULL;
-EGLBoolean   (*GL(eglCopyBuffers))               (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) = NULL;
-char const  *(*GL(eglQueryString))               (EGLDisplay dpy, EGLint name) = NULL;
-
-// Extensions
-void         *(*GL(eglCreateImage))               (void *a, void *b, GLenum c, void *d, const int *e) = NULL;
-unsigned int  (*GL(eglDestroyImage))              (void *a, void *b) = NULL;
-void          (*GL(glEGLImageTargetTexture2DOES)) (int a, void *b) = NULL;
-void          (*GL(glEGLImageTargetRenderbufferStorageOES)) (int a, void *b) = NULL;
-void         *(*GL(eglMapImageSEC))               (void *a, void *b) = NULL;
-unsigned int  (*GL(eglUnmapImageSEC))             (void *a, void *b) = NULL;
-unsigned int  (*GL(eglGetImageAttribSEC))         (void *a, void *b, int c, int *d) = NULL;
-
-
-//--------//
-
-//------------------------------------------------------//
-// Internal EGL APIs... Only ones that are being used.
-//--------//
-static _eng_fn      (*_sym_eglGetProcAddress)            (const char* procname) = NULL;
-// Standard EGL funtions
-static EGLint       (*_sym_eglGetError)                  (void) = NULL;
-static EGLDisplay   (*_sym_eglGetDisplay)                (EGLNativeDisplayType display_id) = NULL;
-static EGLBoolean   (*_sym_eglInitialize)                (EGLDisplay dpy, EGLint* major, EGLint* minor) = NULL;
-static EGLBoolean   (*_sym_eglTerminate)                 (EGLDisplay dpy) = NULL;
-static EGLBoolean   (*_sym_eglChooseConfig)              (EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config) = NULL;
-static EGLSurface   (*_sym_eglCreateWindowSurface  )     (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint* attrib_list) = NULL;
-static EGLSurface   (*_sym_eglCreatePixmapSurface  )     (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint* attrib_list) = NULL;
-static EGLBoolean   (*_sym_eglDestroySurface)            (EGLDisplay dpy, EGLSurface surface) = NULL;
-static EGLBoolean   (*_sym_eglBindAPI)                   (EGLenum api) = NULL;
-static EGLBoolean   (*_sym_eglWaitClient)                (void) = NULL;
-static EGLBoolean   (*_sym_eglSurfaceAttrib)             (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) = NULL;
-static void         (*_sym_eglBindTexImage)              (EGLDisplay dpy, EGLSurface surface, EGLint buffer) = NULL;
-static EGLBoolean   (*_sym_eglReleaseTexImage)           (EGLDisplay dpy, EGLSurface surface, EGLint buffer) = NULL;
-static EGLBoolean   (*_sym_eglSwapInterval)              (EGLDisplay dpy, EGLint interval) = NULL;
-static EGLContext   (*_sym_eglCreateContext)             (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint* attrib_list) = NULL;
-static EGLBoolean   (*_sym_eglDestroyContext)            (EGLDisplay dpy, EGLContext ctx) = NULL;
-static EGLBoolean   (*_sym_eglMakeCurrent)               (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) = NULL;
-static EGLContext   (*_sym_eglGetCurrentContext)         (void) = NULL;
-static EGLSurface   (*_sym_eglGetCurrentSurface)         (EGLint readdraw) = NULL;
-static EGLDisplay   (*_sym_eglGetCurrentDisplay)         (void) = NULL;
-static EGLBoolean   (*_sym_eglWaitGL)                    (void) = NULL;
-static EGLBoolean   (*_sym_eglWaitNative)                (EGLint engine) = NULL;
-static EGLBoolean   (*_sym_eglSwapBuffers)               (EGLDisplay dpy, EGLSurface surface) = NULL;
-static EGLBoolean   (*_sym_eglCopyBuffers)               (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) = NULL;
-static char const  *(*_sym_eglQueryString)               (EGLDisplay dpy, EGLint name) = NULL;
-
-// Extensions
-static void         *(*_sym_eglCreateImage)               (void *a, void *b, GLenum c, void *d, const int *e) = NULL;
-static unsigned int  (*_sym_eglDestroyImage)              (void *a, void *b) = NULL;
-static void          (*_sym_glEGLImageTargetTexture2DOES) (int a, void *b) = NULL;
-static void          (*_sym_glEGLImageTargetRenderbufferStorageOES) (int a, void *b) = NULL;
-static void         *(*_sym_eglMapImageSEC)               (void *a, void *b) = NULL;
-static unsigned int  (*_sym_eglUnmapImageSEC)             (void *a, void *b) = NULL;
-static unsigned int  (*_sym_eglGetImageAttribSEC)         (void *a, void *b, int c, int *d) = NULL;
+   rsc->error_state = EVAS_GL_SUCCESS;
 
+   return rsc;
 
-#else
-//------------------------------------------------------//
-// GLX APIs... Only ones that are being used.
-//--------//
-_eng_fn      (*GL(glXGetProcAddress))            (const char* procName) = NULL;
-
-// Standard glX functions
-XVisualInfo* (*GL(glXChooseVisual))              (Display* dpy, int screen, int* attribList) = NULL;
-GLXContext   (*GL(glXCreateContext))             (Display* dpy, XVisualInfo* vis, GLXContext shareList, Bool direct) = NULL;
-void         (*GL(glXDestroyContext))            (Display* dpy, GLXContext ctx) = NULL;
-GLXContext   (*GL(glXGetCurrentContext))         (void) = NULL;
-GLXDrawable  (*GL(glXGetCurrentDrawable))        (void) = NULL;
-Bool         (*GL(glXMakeCurrent))               (Display* dpy, GLXDrawable draw, GLXContext ctx) = NULL;
-void         (*GL(glXSwapBuffers))               (Display* dpy, GLXDrawable draw) = NULL;
-void         (*GL(glXWaitX))                     (void) = NULL;
-void         (*GL(glXWaitGL))                    (void) = NULL;
-Bool         (*GL(glXQueryExtension))            (Display* dpy, int* errorb, int *event) = NULL;
-const char  *(*GL(glXQueryExtensionsString))     (Display *dpy, int screen) = NULL;
-
-//--------//
-GLXFBConfig* (*GL(glXChooseFBConfig))            (Display* dpy, int screen, const int* attribList, int* nitems) = NULL;
-GLXFBConfig* (*GL(glXGetFBConfigs))              (Display* dpy, int screen, int* nelements) = NULL;
-int          (*GL(glXGetFBConfigAttrib))         (Display* dpy, GLXFBConfig config, int attribute, int* value) = NULL;
-XVisualInfo* (*GL(glXGetVisualFromFBConfig))     (Display* dpy, GLXFBConfig config) = NULL;
-void         (*GL(glXDestroyWindow))             (Display* dpy, GLXWindow window) = NULL;
-Bool         (*GL(glXMakeContextCurrent))        (Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) = NULL;
-//--------//
-
-void         (*GL(glXBindTexImage))              (Display* dpy, GLXDrawable draw, int buffer, int* attribList) = NULL;
-void         (*GL(glXReleaseTexImage))           (Display* dpy, GLXDrawable draw, int buffer) = NULL;
-int          (*GL(glXGetVideoSync))              (unsigned int* count) = NULL;
-int          (*GL(glXWaitVideoSync))             (int divisor, int remainder, unsigned int *count) = NULL;
-XID          (*GL(glXCreatePixmap))              (Display* dpy, void* config, Pixmap pixmap, const int* attribList) = NULL;
-void         (*GL(glXDestroyPixmap))             (Display* dpy, XID pixmap) = NULL;
-void         (*GL(glXQueryDrawable))             (Display* dpy, XID draw, int attribute, unsigned int* value) = NULL;
-int          (*GL(glXSwapIntervalSGI))           (int interval) = NULL;
-void         (*GL(glXSwapIntervalEXT))           (Display* dpy, GLXDrawable draw, int interval) = NULL;
-
-//------------------//
-
-
-//------------------------------------------------------//
-// Internal GLX APIs... Only ones that are being used.
-//--------//
-static _eng_fn      (*_sym_glXGetProcAddress)            (const char* procName) = NULL;
-
-// Standard glX functions
-static XVisualInfo* (*_sym_glXChooseVisual)              (Display* dpy, int screen, int* attribList) = NULL;
-static GLXContext   (*_sym_glXCreateContext)             (Display* dpy, XVisualInfo* vis, GLXContext shareList, Bool direct) = NULL;
-static void         (*_sym_glXDestroyContext)            (Display* dpy, GLXContext ctx) = NULL;
-static GLXContext   (*_sym_glXGetCurrentContext)         (void) = NULL;
-static GLXDrawable  (*_sym_glXGetCurrentDrawable)        (void) = NULL;
-static Bool         (*_sym_glXMakeCurrent)               (Display* dpy, GLXDrawable draw, GLXContext ctx) = NULL;
-static void         (*_sym_glXSwapBuffers)               (Display* dpy, GLXDrawable draw) = NULL;
-static void         (*_sym_glXWaitX)                     (void) = NULL;
-static void         (*_sym_glXWaitGL)                    (void) = NULL;
-static Bool         (*_sym_glXQueryExtension)            (Display* dpy, int* errorb, int* event) = NULL;
-static const char  *(*_sym_glXQueryExtensionsString)     (Display* dpy, int screen);
-
-//--------//
-static GLXFBConfig* (*_sym_glXChooseFBConfig)            (Display* dpy, int screen, const int* attribList, int* nitems) = NULL;
-static GLXFBConfig* (*_sym_glXGetFBConfigs)              (Display* dpy, int screen, int* nelements) = NULL;
-static int          (*_sym_glXGetFBConfigAttrib)         (Display* dpy, GLXFBConfig config, int attribute, int* value) = NULL;
-static XVisualInfo* (*_sym_glXGetVisualFromFBConfig)     (Display* dpy, GLXFBConfig config) = NULL;
-static void         (*_sym_glXDestroyWindow)             (Display* dpy, GLXWindow window) = NULL;
-static Bool         (*_sym_glXMakeContextCurrent)        (Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) = NULL;
-//--------//
-
-static void         (*_sym_glXBindTexImage)              (Display* dpy, GLXDrawable draw, int buffer, int* attribList) = NULL;
-static void         (*_sym_glXReleaseTexImage)           (Display* dpy, GLXDrawable draw, int buffer) = NULL;
-static int          (*_sym_glXGetVideoSync)              (unsigned int* count) = NULL;
-static int          (*_sym_glXWaitVideoSync)             (int divisor, int remainder, unsigned int* count) = NULL;
-static XID          (*_sym_glXCreatePixmap)              (Display* dpy, void* config, Pixmap pixmap, const int* attribList) = NULL;
-static void         (*_sym_glXDestroyPixmap)             (Display* dpy, XID pixmap) = NULL;
-static void         (*_sym_glXQueryDrawable)             (Display* dpy, XID draw, int attribute, unsigned int* value) = NULL;
-static int          (*_sym_glXSwapIntervalSGI)           (int interval) = NULL;
-static void         (*_sym_glXSwapIntervalEXT)           (Display* dpy, GLXDrawable draw, int interval) = NULL;
-
-//------------------//
-#endif
+error:
+   _internal_resources_destroy(eng_data, rsc);
+   return NULL;
+}
 
-//------------------------------------------------------//
-
-
-/* version 1: */
-void         (*GL(glActiveTexture)) (GLenum texture) = NULL;
-void         (*GL(glAttachShader)) (GLuint program, GLuint shader) = NULL;
-void         (*GL(glBindAttribLocation)) (GLuint program, GLuint index, const char* name) = NULL;
-void         (*GL(glBindBuffer)) (GLenum target, GLuint buffer) = NULL;
-void         (*GL(glBindFramebuffer)) (GLenum target, GLuint framebuffer) = NULL;
-void         (*GL(glBindRenderbuffer)) (GLenum target, GLuint renderbuffer) = NULL;
-void         (*GL(glBindTexture)) (GLenum target, GLuint texture) = NULL;
-void         (*GL(glBlendColor)) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) = NULL;
-void         (*GL(glBlendEquation)) ( GLenum mode ) = NULL;
-void         (*GL(glBlendEquationSeparate)) (GLenum modeRGB, GLenum modeAlpha) = NULL;
-void         (*GL(glBlendFunc)) (GLenum sfactor, GLenum dfactor) = NULL;
-void         (*GL(glBlendFuncSeparate)) (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) = NULL;
-void         (*GL(glBufferData)) (GLenum target, GLsizeiptr size, const void* data, GLenum usage) = NULL;
-void         (*GL(glBufferSubData)) (GLenum target, GLintptr offset, GLsizeiptr size, const void* data) = NULL;
-GLenum       (*GL(glCheckFramebufferStatus)) (GLenum target) = NULL;
-void         (*GL(glClear)) (GLbitfield mask) = NULL;
-void         (*GL(glClearColor)) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) = NULL;
-void         (*GL(glClearDepthf)) (GLclampf depth) = NULL;
-void         (*GL(glClearStencil)) (GLint s) = NULL;
-void         (*GL(glColorMask)) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) = NULL;
-void         (*GL(glCompileShader)) (GLuint shader) = NULL;
-void         (*GL(glCompressedTexImage2D)) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) = NULL;
-void         (*GL(glCompressedTexSubImage2D)) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) = NULL;
-void         (*GL(glCopyTexImage2D)) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) = NULL;
-void         (*GL(glCopyTexSubImage2D)) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) = NULL;
-GLuint       (*GL(glCreateProgram)) (void) = NULL;
-GLuint       (*GL(glCreateShader)) (GLenum type) = NULL;
-void         (*GL(glCullFace)) (GLenum mode) = NULL;
-void         (*GL(glDeleteBuffers)) (GLsizei n, const GLuint* buffers) = NULL;
-void         (*GL(glDeleteFramebuffers)) (GLsizei n, const GLuint* framebuffers) = NULL;
-void         (*GL(glDeleteProgram)) (GLuint program) = NULL;
-void         (*GL(glDeleteRenderbuffers)) (GLsizei n, const GLuint* renderbuffers) = NULL;
-void         (*GL(glDeleteShader)) (GLuint shader) = NULL;
-void         (*GL(glDeleteTextures)) (GLsizei n, const GLuint* textures) = NULL;
-void         (*GL(glDepthFunc)) (GLenum func) = NULL;
-void         (*GL(glDepthMask)) (GLboolean flag) = NULL;
-void         (*GL(glDepthRangef)) (GLclampf zNear, GLclampf zFar) = NULL;
-void         (*GL(glDetachShader)) (GLuint program, GLuint shader) = NULL;
-void         (*GL(glDisable)) (GLenum cap) = NULL;
-void         (*GL(glDisableVertexAttribArray)) (GLuint index) = NULL;
-void         (*GL(glDrawArrays)) (GLenum mode, GLint first, GLsizei count) = NULL;
-void         (*GL(glDrawElements)) (GLenum mode, GLsizei count, GLenum type, const void* indices) = NULL;
-void         (*GL(glEnable)) (GLenum cap) = NULL;
-void         (*GL(glEnableVertexAttribArray)) (GLuint index) = NULL;
-void         (*GL(glFinish)) (void) = NULL;
-void         (*GL(glFlush)) (void) = NULL;
-void         (*GL(glFramebufferRenderbuffer)) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) = NULL;
-void         (*GL(glFramebufferTexture2D)) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) = NULL;
-void         (*GL(glFrontFace)) (GLenum mode) = NULL;
-void         (*GL(glGenBuffers)) (GLsizei n, GLuint* buffers) = NULL;
-void         (*GL(glGenerateMipmap)) (GLenum target) = NULL;
-void         (*GL(glGenFramebuffers)) (GLsizei n, GLuint* framebuffers) = NULL;
-void         (*GL(glGenRenderbuffers)) (GLsizei n, GLuint* renderbuffers) = NULL;
-void         (*GL(glGenTextures)) (GLsizei n, GLuint* textures) = NULL;
-void         (*GL(glGetActiveAttrib)) (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) = NULL;
-void         (*GL(glGetActiveUniform)) (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) = NULL;
-void         (*GL(glGetAttachedShaders)) (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) = NULL;
-int          (*GL(glGetAttribLocation)) (GLuint program, const char* name) = NULL;
-void         (*GL(glGetBooleanv)) (GLenum pname, GLboolean* params) = NULL;
-void         (*GL(glGetBufferParameteriv)) (GLenum target, GLenum pname, GLint* params) = NULL;
-GLenum       (*GL(glGetError)) (void) = NULL;
-void         (*GL(glGetFloatv)) (GLenum pname, GLfloat* params) = NULL;
-void         (*GL(glGetFramebufferAttachmentParameteriv)) (GLenum target, GLenum attachment, GLenum pname, GLint* params) = NULL;
-void         (*GL(glGetIntegerv)) (GLenum pname, GLint* params) = NULL;
-void         (*GL(glGetProgramiv)) (GLuint program, GLenum pname, GLint* params) = NULL;
-void         (*GL(glGetProgramInfoLog)) (GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) = NULL;
-void         (*GL(glGetRenderbufferParameteriv)) (GLenum target, GLenum pname, GLint* params) = NULL;
-void         (*GL(glGetShaderiv)) (GLuint shader, GLenum pname, GLint* params) = NULL;
-void         (*GL(glGetShaderInfoLog)) (GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) = NULL;
-void         (*GL(glGetShaderPrecisionFormat)) (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) = NULL;
-void         (*GL(glGetShaderSource)) (GLuint shader, GLsizei bufsize, GLsizei* length, char* source) = NULL;
-const GLubyte *(*GL(glGetString)) (GLenum name) = NULL;
-void         (*GL(glGetTexParameterfv)) (GLenum target, GLenum pname, GLfloat* params) = NULL;
-void         (*GL(glGetTexParameteriv)) (GLenum target, GLenum pname, GLint* params) = NULL;
-void         (*GL(glGetUniformfv)) (GLuint program, GLint location, GLfloat* params) = NULL;
-void         (*GL(glGetUniformiv)) (GLuint program, GLint location, GLint* params) = NULL;
-int          (*GL(glGetUniformLocation)) (GLuint program, const char* name) = NULL;
-void         (*GL(glGetVertexAttribfv)) (GLuint index, GLenum pname, GLfloat* params) = NULL;
-void         (*GL(glGetVertexAttribiv)) (GLuint index, GLenum pname, GLint* params) = NULL;
-void         (*GL(glGetVertexAttribPointerv)) (GLuint index, GLenum pname, void** pointer) = NULL;
-void         (*GL(glHint)) (GLenum target, GLenum mode) = NULL;
-GLboolean    (*GL(glIsBuffer)) (GLuint buffer) = NULL;
-GLboolean    (*GL(glIsEnabled)) (GLenum cap) = NULL;
-GLboolean    (*GL(glIsFramebuffer)) (GLuint framebuffer) = NULL;
-GLboolean    (*GL(glIsProgram)) (GLuint program) = NULL;
-GLboolean    (*GL(glIsRenderbuffer)) (GLuint renderbuffer) = NULL;
-GLboolean    (*GL(glIsShader)) (GLuint shader) = NULL;
-GLboolean    (*GL(glIsTexture)) (GLuint texture) = NULL;
-void         (*GL(glLineWidth)) (GLfloat width) = NULL;
-void         (*GL(glLinkProgram)) (GLuint program) = NULL;
-void         (*GL(glPixelStorei)) (GLenum pname, GLint param) = NULL;
-void         (*GL(glPolygonOffset)) (GLfloat factor, GLfloat units) = NULL;
-void         (*GL(glReadPixels)) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) = NULL;
-void         (*GL(glReleaseShaderCompiler)) (void) = NULL;
-void         (*GL(glRenderbufferStorage)) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height) = NULL;
-void         (*GL(glSampleCoverage)) (GLclampf value, GLboolean invert) = NULL;
-void         (*GL(glScissor)) (GLint x, GLint y, GLsizei width, GLsizei height) = NULL;
-void         (*GL(glShaderBinary)) (GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) = NULL;
-void         (*GL(glShaderSource)) (GLuint shader, GLsizei count, const char** string, const GLint* length) = NULL;
-void         (*GL(glStencilFunc)) (GLenum func, GLint ref, GLuint mask) = NULL;
-void         (*GL(glStencilFuncSeparate)) (GLenum face, GLenum func, GLint ref, GLuint mask) = NULL;
-void         (*GL(glStencilMask)) (GLuint mask) = NULL;
-void         (*GL(glStencilMaskSeparate)) (GLenum face, GLuint mask) = NULL;
-void         (*GL(glStencilOp)) (GLenum fail, GLenum zfail, GLenum zpass) = NULL;
-void         (*GL(glStencilOpSeparate)) (GLenum face, GLenum fail, GLenum zfail, GLenum zpass) = NULL;
-void         (*GL(glTexImage2D)) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels) = NULL;
-void         (*GL(glTexParameterf)) (GLenum target, GLenum pname, GLfloat param) = NULL;
-void         (*GL(glTexParameterfv)) (GLenum target, GLenum pname, const GLfloat* params) = NULL;
-void         (*GL(glTexParameteri)) (GLenum target, GLenum pname, GLint param) = NULL;
-void         (*GL(glTexParameteriv)) (GLenum target, GLenum pname, const GLint* params) = NULL;
-void         (*GL(glTexSubImage2D)) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) = NULL;
-void         (*GL(glUniform1f)) (GLint location, GLfloat x) = NULL;
-void         (*GL(glUniform1fv)) (GLint location, GLsizei count, const GLfloat* v) = NULL;
-void         (*GL(glUniform1i)) (GLint location, GLint x) = NULL;
-void         (*GL(glUniform1iv)) (GLint location, GLsizei count, const GLint* v) = NULL;
-void         (*GL(glUniform2f)) (GLint location, GLfloat x, GLfloat y) = NULL;
-void         (*GL(glUniform2fv)) (GLint location, GLsizei count, const GLfloat* v) = NULL;
-void         (*GL(glUniform2i)) (GLint location, GLint x, GLint y) = NULL;
-void         (*GL(glUniform2iv)) (GLint location, GLsizei count, const GLint* v) = NULL;
-void         (*GL(glUniform3f)) (GLint location, GLfloat x, GLfloat y, GLfloat z) = NULL;
-void         (*GL(glUniform3fv)) (GLint location, GLsizei count, const GLfloat* v) = NULL;
-void         (*GL(glUniform3i)) (GLint location, GLint x, GLint y, GLint z) = NULL;
-void         (*GL(glUniform3iv)) (GLint location, GLsizei count, const GLint* v) = NULL;
-void         (*GL(glUniform4f)) (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) = NULL;
-void         (*GL(glUniform4fv)) (GLint location, GLsizei count, const GLfloat* v) = NULL;
-void         (*GL(glUniform4i)) (GLint location, GLint x, GLint y, GLint z, GLint w) = NULL;
-void         (*GL(glUniform4iv)) (GLint location, GLsizei count, const GLint* v) = NULL;
-void         (*GL(glUniformMatrix2fv)) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) = NULL;
-void         (*GL(glUniformMatrix3fv)) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) = NULL;
-void         (*GL(glUniformMatrix4fv)) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) = NULL;
-void         (*GL(glUseProgram)) (GLuint program) = NULL;
-void         (*GL(glValidateProgram)) (GLuint program) = NULL;
-void         (*GL(glVertexAttrib1f)) (GLuint indx, GLfloat x) = NULL;
-void         (*GL(glVertexAttrib1fv)) (GLuint indx, const GLfloat* values) = NULL;
-void         (*GL(glVertexAttrib2f)) (GLuint indx, GLfloat x, GLfloat y) = NULL;
-void         (*GL(glVertexAttrib2fv)) (GLuint indx, const GLfloat* values) = NULL;
-void         (*GL(glVertexAttrib3f)) (GLuint indx, GLfloat x, GLfloat y, GLfloat z) = NULL;
-void         (*GL(glVertexAttrib3fv)) (GLuint indx, const GLfloat* values) = NULL;
-void         (*GL(glVertexAttrib4f)) (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) = NULL;
-void         (*GL(glVertexAttrib4fv)) (GLuint indx, const GLfloat* values) = NULL;
-void         (*GL(glVertexAttribPointer)) (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) = NULL;
-void         (*GL(glViewport)) (GLint x, GLint y, GLsizei width, GLsizei height) = NULL;
-
-/* Extensions */
-void         (*GL(glGetProgramBinary)) (GLuint program, GLsizei bufsize, GLsizei *length, GLenum *binaryFormat, void *binary) = NULL;
-void         (*GL(glProgramBinary)) (GLuint program, GLenum binaryFormat, const void *binary, GLint length) = NULL;
-void         (*GL(glProgramParameteri)) (GLuint a, GLuint b, GLint d) = NULL;
-
-
-//------------------------------------------------------//
-// GLES 2.0 APIs...
-static void       (*_sym_glActiveTexture)                       (GLenum texture) = NULL;
-static void       (*_sym_glAttachShader)                        (GLuint program, GLuint shader) = NULL;
-static void       (*_sym_glBindAttribLocation)                  (GLuint program, GLuint index, const char* name) = NULL;
-static void       (*_sym_glBindBuffer)                          (GLenum target, GLuint buffer) = NULL;
-static void       (*_sym_glBindFramebuffer)                     (GLenum target, GLuint framebuffer) = NULL;
-static void       (*_sym_glBindRenderbuffer)                    (GLenum target, GLuint renderbuffer) = NULL;
-static void       (*_sym_glBindTexture)                         (GLenum target, GLuint texture) = NULL;
-static void       (*_sym_glBlendColor)                          (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) = NULL;
-static void       (*_sym_glBlendEquation)                       (GLenum mode) = NULL;
-static void       (*_sym_glBlendEquationSeparate)               (GLenum modeRGB, GLenum modeAlpha) = NULL;
-static void       (*_sym_glBlendFunc)                           (GLenum sfactor, GLenum dfactor) = NULL;
-static void       (*_sym_glBlendFuncSeparate)                   (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) = NULL;
-static void       (*_sym_glBufferData)                          (GLenum target, GLsizeiptr size, const void* data, GLenum usage) = NULL;
-static void       (*_sym_glBufferSubData)                       (GLenum target, GLintptr offset, GLsizeiptr size, const void* data) = NULL;
-static GLenum     (*_sym_glCheckFramebufferStatus)              (GLenum target) = NULL;
-static void       (*_sym_glClear)                               (GLbitfield mask) = NULL;
-static void       (*_sym_glClearColor)                          (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) = NULL;
-static void       (*_sym_glClearDepthf)                         (GLclampf depth) = NULL;
-static void       (*_sym_glClearStencil)                        (GLint s) = NULL;
-static void       (*_sym_glColorMask)                           (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) = NULL;
-static void       (*_sym_glCompileShader)                       (GLuint shader) = NULL;
-static void       (*_sym_glCompressedTexImage2D)                (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) = NULL;
-static void       (*_sym_glCompressedTexSubImage2D)             (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) = NULL;
-static void       (*_sym_glCopyTexImage2D)                      (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) = NULL;
-static void       (*_sym_glCopyTexSubImage2D)                   (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) = NULL;
-static GLuint     (*_sym_glCreateProgram)                       (void) = NULL;
-static GLuint     (*_sym_glCreateShader)                        (GLenum type) = NULL;
-static void       (*_sym_glCullFace)                            (GLenum mode) = NULL;
-static void       (*_sym_glDeleteBuffers)                       (GLsizei n, const GLuint* buffers) = NULL;
-static void       (*_sym_glDeleteFramebuffers)                  (GLsizei n, const GLuint* framebuffers) = NULL;
-static void       (*_sym_glDeleteProgram)                       (GLuint program) = NULL;
-static void       (*_sym_glDeleteRenderbuffers)                 (GLsizei n, const GLuint* renderbuffers) = NULL;
-static void       (*_sym_glDeleteShader)                        (GLuint shader) = NULL;
-static void       (*_sym_glDeleteTextures)                      (GLsizei n, const GLuint* textures) = NULL;
-static void       (*_sym_glDepthFunc)                           (GLenum func) = NULL;
-static void       (*_sym_glDepthMask)                           (GLboolean flag) = NULL;
-static void       (*_sym_glDepthRangef)                         (GLclampf zNear, GLclampf zFar) = NULL;
-static void       (*_sym_glDetachShader)                        (GLuint program, GLuint shader) = NULL;
-static void       (*_sym_glDisable)                             (GLenum cap) = NULL;
-static void       (*_sym_glDisableVertexAttribArray)            (GLuint index) = NULL;
-static void       (*_sym_glDrawArrays)                          (GLenum mode, GLint first, GLsizei count) = NULL;
-static void       (*_sym_glDrawElements)                        (GLenum mode, GLsizei count, GLenum type, const void* indices) = NULL;
-static void       (*_sym_glEnable)                              (GLenum cap) = NULL;
-static void       (*_sym_glEnableVertexAttribArray)             (GLuint index) = NULL;
-static void       (*_sym_glFinish)                              (void) = NULL;
-static void       (*_sym_glFlush)                               (void) = NULL;
-static void       (*_sym_glFramebufferRenderbuffer)             (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) = NULL;
-static void       (*_sym_glFramebufferTexture2D)                (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) = NULL;
-static void       (*_sym_glFrontFace)                           (GLenum mode) = NULL;
-static void       (*_sym_glGenBuffers)                          (GLsizei n, GLuint* buffers) = NULL;
-static void       (*_sym_glGenerateMipmap)                      (GLenum target) = NULL;
-static void       (*_sym_glGenFramebuffers)                     (GLsizei n, GLuint* framebuffers) = NULL;
-static void       (*_sym_glGenRenderbuffers)                    (GLsizei n, GLuint* renderbuffers) = NULL;
-static void       (*_sym_glGenTextures)                         (GLsizei n, GLuint* textures) = NULL;
-static void       (*_sym_glGetActiveAttrib)                     (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) = NULL;
-static void       (*_sym_glGetActiveUniform)                    (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) = NULL;
-static void       (*_sym_glGetAttachedShaders)                  (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) = NULL;
-static int        (*_sym_glGetAttribLocation)                   (GLuint program, const char* name) = NULL;
-static void       (*_sym_glGetBooleanv)                         (GLenum pname, GLboolean* params) = NULL;
-static void       (*_sym_glGetBufferParameteriv)                (GLenum target, GLenum pname, GLint* params) = NULL;
-static GLenum     (*_sym_glGetError)                            (void) = NULL;
-static void       (*_sym_glGetFloatv)                           (GLenum pname, GLfloat* params) = NULL;
-static void       (*_sym_glGetFramebufferAttachmentParameteriv) (GLenum target, GLenum attachment, GLenum pname, GLint* params) = NULL;
-static void       (*_sym_glGetIntegerv)                         (GLenum pname, GLint* params) = NULL;
-static void       (*_sym_glGetProgramiv)                        (GLuint program, GLenum pname, GLint* params) = NULL;
-static void       (*_sym_glGetProgramInfoLog)                   (GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) = NULL;
-static void       (*_sym_glGetRenderbufferParameteriv)          (GLenum target, GLenum pname, GLint* params) = NULL;
-static void       (*_sym_glGetShaderiv)                         (GLuint shader, GLenum pname, GLint* params) = NULL;
-static void       (*_sym_glGetShaderInfoLog)                    (GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) = NULL;
-static void       (*_sym_glGetShaderPrecisionFormat)            (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) = NULL;
-static void       (*_sym_glGetShaderSource)                     (GLuint shader, GLsizei bufsize, GLsizei* length, char* source) = NULL;
-static const GLubyte *(*_sym_glGetString)                           (GLenum name) = NULL;
-static void       (*_sym_glGetTexParameterfv)                   (GLenum target, GLenum pname, GLfloat* params) = NULL;
-static void       (*_sym_glGetTexParameteriv)                   (GLenum target, GLenum pname, GLint* params) = NULL;
-static void       (*_sym_glGetUniformfv)                        (GLuint program, GLint location, GLfloat* params) = NULL;
-static void       (*_sym_glGetUniformiv)                        (GLuint program, GLint location, GLint* params) = NULL;
-static int        (*_sym_glGetUniformLocation)                  (GLuint program, const char* name) = NULL;
-static void       (*_sym_glGetVertexAttribfv)                   (GLuint index, GLenum pname, GLfloat* params) = NULL;
-static void       (*_sym_glGetVertexAttribiv)                   (GLuint index, GLenum pname, GLint* params) = NULL;
-static void       (*_sym_glGetVertexAttribPointerv)             (GLuint index, GLenum pname, void** pointer) = NULL;
-static void       (*_sym_glHint)                                (GLenum target, GLenum mode) = NULL;
-static GLboolean  (*_sym_glIsBuffer)                            (GLuint buffer) = NULL;
-static GLboolean  (*_sym_glIsEnabled)                           (GLenum cap) = NULL;
-static GLboolean  (*_sym_glIsFramebuffer)                       (GLuint framebuffer) = NULL;
-static GLboolean  (*_sym_glIsProgram)                           (GLuint program) = NULL;
-static GLboolean  (*_sym_glIsRenderbuffer)                      (GLuint renderbuffer) = NULL;
-static GLboolean  (*_sym_glIsShader)                            (GLuint shader) = NULL;
-static GLboolean  (*_sym_glIsTexture)                           (GLuint texture) = NULL;
-static void       (*_sym_glLineWidth)                           (GLfloat width) = NULL;
-static void       (*_sym_glLinkProgram)                         (GLuint program) = NULL;
-static void       (*_sym_glPixelStorei)                         (GLenum pname, GLint param) = NULL;
-static void       (*_sym_glPolygonOffset)                       (GLfloat factor, GLfloat units) = NULL;
-static void       (*_sym_glReadPixels)                          (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) = NULL;
-static void       (*_sym_glReleaseShaderCompiler)               (void) = NULL;
-static void       (*_sym_glRenderbufferStorage)                 (GLenum target, GLenum internalformat, GLsizei width, GLsizei height) = NULL;
-static void       (*_sym_glSampleCoverage)                      (GLclampf value, GLboolean invert) = NULL;
-static void       (*_sym_glScissor)                             (GLint x, GLint y, GLsizei width, GLsizei height) = NULL;
-static void       (*_sym_glShaderBinary)                        (GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) = NULL;
-static void       (*_sym_glShaderSource)                        (GLuint shader, GLsizei count, const char** string, const GLint* length) = NULL;
-static void       (*_sym_glStencilFunc)                         (GLenum func, GLint ref, GLuint mask) = NULL;
-static void       (*_sym_glStencilFuncSeparate)                 (GLenum face, GLenum func, GLint ref, GLuint mask) = NULL;
-static void       (*_sym_glStencilMask)                         (GLuint mask) = NULL;
-static void       (*_sym_glStencilMaskSeparate)                 (GLenum face, GLuint mask) = NULL;
-static void       (*_sym_glStencilOp)                           (GLenum fail, GLenum zfail, GLenum zpass) = NULL;
-static void       (*_sym_glStencilOpSeparate)                   (GLenum face, GLenum fail, GLenum zfail, GLenum zpass) = NULL;
-static void       (*_sym_glTexImage2D)                          (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels) = NULL;
-static void       (*_sym_glTexParameterf)                       (GLenum target, GLenum pname, GLfloat param) = NULL;
-static void       (*_sym_glTexParameterfv)                      (GLenum target, GLenum pname, const GLfloat* params) = NULL;
-static void       (*_sym_glTexParameteri)                       (GLenum target, GLenum pname, GLint param) = NULL;
-static void       (*_sym_glTexParameteriv)                      (GLenum target, GLenum pname, const GLint* params) = NULL;
-static void       (*_sym_glTexSubImage2D)                       (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) = NULL;
-static void       (*_sym_glUniform1f)                           (GLint location, GLfloat x) = NULL;
-static void       (*_sym_glUniform1fv)                          (GLint location, GLsizei count, const GLfloat* v) = NULL;
-static void       (*_sym_glUniform1i)                           (GLint location, GLint x) = NULL;
-static void       (*_sym_glUniform1iv)                          (GLint location, GLsizei count, const GLint* v) = NULL;
-static void       (*_sym_glUniform2f)                           (GLint location, GLfloat x, GLfloat y) = NULL;
-static void       (*_sym_glUniform2fv)                          (GLint location, GLsizei count, const GLfloat* v) = NULL;
-static void       (*_sym_glUniform2i)                           (GLint location, GLint x, GLint y) = NULL;
-static void       (*_sym_glUniform2iv)                          (GLint location, GLsizei count, const GLint* v) = NULL;
-static void       (*_sym_glUniform3f)                           (GLint location, GLfloat x, GLfloat y, GLfloat z) = NULL;
-static void       (*_sym_glUniform3fv)                          (GLint location, GLsizei count, const GLfloat* v) = NULL;
-static void       (*_sym_glUniform3i)                           (GLint location, GLint x, GLint y, GLint z) = NULL;
-static void       (*_sym_glUniform3iv)                          (GLint location, GLsizei count, const GLint* v) = NULL;
-static void       (*_sym_glUniform4f)                           (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) = NULL;
-static void       (*_sym_glUniform4fv)                          (GLint location, GLsizei count, const GLfloat* v) = NULL;
-static void       (*_sym_glUniform4i)                           (GLint location, GLint x, GLint y, GLint z, GLint w) = NULL;
-static void       (*_sym_glUniform4iv)                          (GLint location, GLsizei count, const GLint* v) = NULL;
-static void       (*_sym_glUniformMatrix2fv)                    (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) = NULL;
-static void       (*_sym_glUniformMatrix3fv)                    (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) = NULL;
-static void       (*_sym_glUniformMatrix4fv)                    (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) = NULL;
-static void       (*_sym_glUseProgram)                          (GLuint program) = NULL;
-static void       (*_sym_glValidateProgram)                     (GLuint program) = NULL;
-static void       (*_sym_glVertexAttrib1f)                      (GLuint indx, GLfloat x) = NULL;
-static void       (*_sym_glVertexAttrib1fv)                     (GLuint indx, const GLfloat* values) = NULL;
-static void       (*_sym_glVertexAttrib2f)                      (GLuint indx, GLfloat x, GLfloat y) = NULL;
-static void       (*_sym_glVertexAttrib2fv)                     (GLuint indx, const GLfloat* values) = NULL;
-static void       (*_sym_glVertexAttrib3f)                      (GLuint indx, GLfloat x, GLfloat y, GLfloat z) = NULL;
-static void       (*_sym_glVertexAttrib3fv)                     (GLuint indx, const GLfloat* values) = NULL;
-static void       (*_sym_glVertexAttrib4f)                      (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) = NULL;
-static void       (*_sym_glVertexAttrib4fv)                     (GLuint indx, const GLfloat* values) = NULL;
-static void       (*_sym_glVertexAttribPointer)                 (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) = NULL;
-static void       (*_sym_glViewport)                            (GLint x, GLint y, GLsizei width, GLsizei height) = NULL;
-
-// GLES Extensions...
-static void       (*_sym_glGetProgramBinary)                    (GLuint a, GLsizei b, GLsizei* c, GLenum* d, void* e) = NULL;
-static void       (*_sym_glProgramBinary)                       (GLuint a, GLenum b, const void* c, GLint d) = NULL;
-static void       (*_sym_glProgramParameteri)                   (GLuint a, GLuint b, GLint d) = NULL;
-
-
-//------------------------------------------------------//
-// Inline function for debugging
-static inline void thread_check()
+static void
+_internal_resources_destroy(void *eng_data, EVGL_Resource *rsc)
 {
-   if (current_tid == 0)
-      current_tid = syscall(__NR_gettid);
-   else
-      EVAS_GL_DEBUG_ASSERT(current_tid == syscall(__NR_gettid));
+   if ((!eng_data) || (!rsc)) return;
+
+   if (rsc->context)
+      evgl_engine->funcs->context_destroy(eng_data, rsc->context);
+   if (rsc->surface)
+      evgl_engine->funcs->surface_destroy(eng_data, rsc->surface);
+   if (rsc->window)
+      evgl_engine->funcs->native_window_destroy(eng_data, rsc->window);
+
+   free(rsc);
 }
 
-//-------------------------------//
-// Get Type
-// 0 = glGet
-// 1 = glGetVertexAttrib
-// 2 = glGetVertexAttribPointer
-//-------------------------------//
-/*
-static void
-get_state(int index, GLenum state, int get_type, int val_type, void *value)
+static int
+_internal_resource_make_current(void *eng_data, EVGL_Context *ctx)
 {
-   int i;
+   EVGL_Resource *rsc = NULL;
+   void *surface = NULL;
+   void *context = NULL;
+   int ret = 0;
 
-   if (get_type == 0)
-     {
-        // Integer Type
-        if (val_type == 0)
-          {
-             GLint real_val[4] = {-1, -1, -1, -1};
-             GLint *curr_val = (GLint*)value;
-             _sym_glGetIntegerv(state, real_val);
-          }
-        // Boolean Type
-        else if (val_type == 1)
-          {
-             GLboolean real_val[4] = {3, 3, 3, 3};
-             GLboolean *curr_val = (GLboolean*)value;
-             _sym_glGetBooleanv(state, real_val);
-          }
-        // Float Type
-        else if (val_type == 2)
-          {
-             GLfloat real_val[4] = {-1, -1, -1, -1};
-             GLfloat *curr_val = (GLfloat*)value;
-             _sym_glGetFloatv(state, real_val);
-          }
-        else
-           fprintf(stderr, "Error Setting State: %d...\n", state);
-     }
-   else if (get_type == 1)
+   // Retrieve the resource object
+   if (!(rsc = _evgl_tls_resource_get()))
      {
-        // GetVertexAttrib
-        if (val_type == 0)
-          {
-             GLint real_val[4] = {-1, -1, -1, -1};
-             GLint *curr_val = (GLint*)value;
-             _sym_glGetVertexAttribiv(index, state, real_val);
-          }
-        else if (val_type == 2)
+        if (!(rsc = _evgl_tls_resource_create(eng_data)))
           {
-             GLfloat real_val[4] = {-1, -1, -1, -1};
-             GLfloat *curr_val = (GLfloat*)value;
-             _sym_glGetVertexAttribfv(index, state, real_val);
+             ERR("Error creting resources in tls.");
+             return 0;
           }
      }
-   else if (get_type == 2)
-     {
-        GLint real_val[4] = {-1, -1, -1, -1};
-        GLint *curr_val = (GLint*)value;
-        _sym_glGetVertexAttribPointerv(index, state, real_val);
-
-     }
-}
-
-*/
 
+   // Set context from input or from resource
+   if (ctx)
+      context = ctx->context;
+   else
+      context = (void*)rsc->context;
 
+   // Set the surface to evas surface if it's there
+   if (rsc->id == evgl_engine->main_tid)
+      rsc->direct.surface = evgl_engine->funcs->evas_surface_get(eng_data);
 
-#if 0
-//------------------------------------------------------//
-static int
-init_states(EvasGlueContext ctx)
-{
-   int i;
+   if (rsc->direct.surface)
+      surface = (void*)rsc->direct.surface;
+   else
+      surface = (void*)rsc->surface;
 
-   if (!ctx)
+   // Do the make current
+   ret = evgl_engine->funcs->make_current(eng_data, surface, context, 1);
+   if (!ret)
      {
-        ERR("Context NULL\n");
+        ERR("Engine make_current with internal resources failed.");
         return 0;
      }
 
-   // Set Magic and other inits
-   ctx->magic      = MAGIC_GLFAST;
-   //ctx->initialized = 1;
-
-#define GET_STATE(glstate, type, evglstate, num, all) \
-   print_state(#glstate, glstate, type, num, &(current_ctx->evglstate), all, 0, 0);
-
+   return 1;
+}
 
-   fprintf(stderr, "---------------Current Actual GL Context %p States----------------\n", current_ctx);
-   fprintf(stderr, "Print GL States Called from %s @ line %d\n", func_name, line_num);
-   fprintf(stderr, "---TID: %d\n\n", syscall(__NR_gettid));
-//-----------------------------------------------------------//
+//---------------------------------------------------------------//
+// Surface Related Functions
+//  - Texture/ Renderbuffer Creation/ Attachment to FBO
+//  - Surface capability check
+//  - Internal config choose function
+//---------------------------------------------------------------//
+// Gen Texture
+static void
+_texture_create(GLuint *tex)
+{
+   glGenTextures(1, tex);
+}
 
+// Create and allocate 2D texture
+static void
+_texture_allocate_2d(GLuint tex, GLint ifmt, GLenum fmt, GLenum type, int w, int h)
+{
+   //if (!(*tex))
+   //   glGenTextures(1, tex);
+   glBindTexture(GL_TEXTURE_2D, tex);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   glTexImage2D(GL_TEXTURE_2D, 0, ifmt, w, h, 0, fmt, type, NULL);
+   glBindTexture(GL_TEXTURE_2D, 0);
+}
 
-   GET_STATE(GL_ARRAY_BUFFER_BINDING, 0);
-   GET_STATE(GL_ELEMENT_ARRAY_BUFFER_BINDING, 0);
-   GET_STATE(GL_FRAMEBUFFER_BINDING, 0);
-   GET_STATE(GL_RENDERBUFFER_BINDING, 0);
+// Destroy Texture
+static void
+_texture_destroy(GLuint *tex)
+{
+   if (*tex)
+     {
+        glDeleteTextures(1, tex);
+        *tex = 0;
+     }
+}
 
-   GET_STATE(GL_BLEND, 1);
-   GET_STATE(GL_CULL_FACE, 1);
-   GET_STATE(GL_DEPTH_TEST, 1);
-   GET_STATE(GL_DITHER, 1);
+// Attach 2D texture with the given format to already bound FBO
+// *NOTE: attach2 here is used for depth_stencil attachment in GLES env.
+static void
+_texture_attach_2d(GLuint tex, GLenum attach, GLenum attach2, int samples, Eina_Bool use_extension)
+{
+   if (samples)
+     {
+#ifdef GL_GLES
+        //<<< TODO : CHECK EXTENSION SUPPORT>>>
+        EXT_FUNC(glFramebufferTexture2DMultisample)(GL_FRAMEBUFFER,
+                                                    attach,
+                                                    GL_TEXTURE_2D, tex,
+                                                    0, samples);
 
-   GET_STATE(GL_POLYGON_OFFSET_FILL, 1);
-   GET_STATE(GL_SAMPLE_ALPHA_TO_COVERAGE, 1);
-   GET_STATE(GL_SAMPLE_COVERAGE, 1);
-   GET_STATE(GL_SCISSOR_TEST, 1);
-   GET_STATE(GL_STENCIL_TEST, 1);
+        if (attach2)
+           EXT_FUNC(glFramebufferTexture2DMultisample)(GL_FRAMEBUFFER,
+                                                       attach2,
+                                                       GL_TEXTURE_2D, tex,
+                                                       0, samples);
+#else
+        ERR("MSAA not supported.  Should not have come in here...!");
+#endif
+     }
+   else if (use_extension)
+     {
+        if (gles1_funcs->glFramebufferTexture2DOES)
+          gles1_funcs->glFramebufferTexture2DOES(GL_FRAMEBUFFER, attach, GL_TEXTURE_2D, tex, 0);
 
-   GET_STATE(GL_VIEWPORT, 0);
-   GET_STATE(GL_CURRENT_PROGRAM, 0);
+        if (attach2)
+          if (gles1_funcs->glFramebufferTexture2DOES)
+            gles1_funcs->glFramebufferTexture2DOES(GL_FRAMEBUFFER, attach2, GL_TEXTURE_2D, tex, 0);
+     }
+   else
+     {
+        glFramebufferTexture2D(GL_FRAMEBUFFER, attach, GL_TEXTURE_2D, tex, 0);
 
-   GET_STATE(GL_COLOR_CLEAR_VALUE, 2);
+        if (attach2)
+           glFramebufferTexture2D(GL_FRAMEBUFFER, attach2, GL_TEXTURE_2D, tex, 0);
 
-   GET_STATE(GL_COLOR_WRITEMASK, 1);
+     }
+}
 
-   GET_STATE(GL_DEPTH_RANGE, 2);
-   GET_STATE(GL_DEPTH_CLEAR_VALUE, 2);
-   GET_STATE(GL_DEPTH_FUNC, 0);
-   GET_STATE(GL_DEPTH_WRITEMASK, 1);
-   GET_STATE(GL_CULL_FACE_MODE, 0);
+static void *
+_egl_image_create(EVGL_Context *context, int target, void *buffer)
+{
+#ifdef GL_GLES
+   EGLDisplay dpy = EGL_NO_DISPLAY;
+   EGLContext ctx = EGL_NO_CONTEXT;
+   EVGL_Resource *rsc = NULL;
+   int attribs[10];
+   int n = 0;
 
-   int active_tex;
-   _sym_glGetIntegerv(GL_ACTIVE_TEXTURE, &active_tex);
-
-   for (i=0; i<MAX_TEXTURE_UNITS; ++i)
+   // Retrieve the resource object
+   if (!(rsc = _evgl_tls_resource_get()))
      {
-        _sym_glActiveTexture(GL_TEXTURE0 + i);
-        GET_STATE(GL_TEXTURE_BINDING_2D, 0);
+        ERR("Error creating resources in tls.");
+        return NULL;
      }
-   for (i=0; i<MAX_TEXTURE_UNITS; ++i)
+
+   dpy = (EGLDisplay)rsc->display;
+   if (target == EGL_GL_TEXTURE_2D_KHR)
      {
-        _sym_glActiveTexture(GL_TEXTURE0 + i);
-        GET_STATE(GL_TEXTURE_BINDING_CUBE_MAP, 0);
+   ctx = (EGLContext)context->context;
+        attribs[n++] = EGL_GL_TEXTURE_LEVEL_KHR;
+        attribs[n++] = 0;
      }
-   _sym_glActiveTexture(active_tex);
-
-   GET_STATE(GL_ACTIVE_TEXTURE, 0);
-   GET_STATE(GL_GENERATE_MIPMAP_HINT, 0);
-   //GET_STATE(GL_TEXTURE_BINDING_, 0);
-   //GET_STATE(GL_TEXTURE_BINDING_CUBE_MAP, 0);
-
-   GET_STATE(GL_BLEND_COLOR, 2);
-   GET_STATE(GL_BLEND_SRC_RGB, 0);
-   GET_STATE(GL_BLEND_SRC_ALPHA, 0);
-   GET_STATE(GL_BLEND_DST_RGB, 0);
-   GET_STATE(GL_BLEND_DST_ALPHA, 0);
-   GET_STATE(GL_BLEND_EQUATION_RGB, 0);
-   GET_STATE(GL_BLEND_EQUATION_ALPHA, 0);
-
-   GET_STATE(GL_STENCIL_FUNC, 0);
-   GET_STATE(GL_STENCIL_REF, 0);
-   GET_STATE(GL_STENCIL_VALUE_MASK, 3);
-   GET_STATE(GL_STENCIL_FAIL, 0);
-   GET_STATE(GL_STENCIL_PASS_DEPTH_FAIL, 0);
-   GET_STATE(GL_STENCIL_PASS_DEPTH_PASS, 0);
-   GET_STATE(GL_STENCIL_WRITEMASK, 3);
-
-   GET_STATE(GL_STENCIL_BACK_FUNC, 0);
-   GET_STATE(GL_STENCIL_BACK_REF, 0);
-   GET_STATE(GL_STENCIL_BACK_VALUE_MASK, 3);
-   GET_STATE(GL_STENCIL_BACK_FAIL, 0);
-   GET_STATE(GL_STENCIL_BACK_PASS_DEPTH_FAIL, 0);
-   GET_STATE(GL_STENCIL_BACK_PASS_DEPTH_PASS, 0);
-   GET_STATE(GL_STENCIL_BACK_WRITEMASK, 3);
-
-   GET_STATE(GL_STENCIL_CLEAR_VALUE, 0);
-
-   GET_STATE(GL_FRONT_FACE, 0);
-   GET_STATE(GL_LINE_WIDTH, 2);
-   GET_STATE(GL_POLYGON_OFFSET_FACTOR, 2);
-   GET_STATE(GL_POLYGON_OFFSET_UNITS, 2);
-   GET_STATE(GL_SAMPLE_COVERAGE_VALUE, 2);
-   GET_STATE(GL_SAMPLE_COVERAGE_INVERT, 1);
-
-   GET_STATE(GL_SCISSOR_BOX, 0);
-   GET_STATE(GL_PACK_ALIGNMENT, 0);
-   GET_STATE(GL_UNPACK_ALIGNMENT, 0);
-
-   for (i=0; i<MAX_VERTEX_ATTRIBS; ++i)
-     {
-        //fprintf(stderr, "--Vertex Attrib Array Index: %d ----\n", i);
-        PRINT_VA_STATE(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, 0, vertex_array[i].buf_id, 1, print_all);
-        PRINT_VA_STATE(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, 0, vertex_array[i].enabled, 1, print_all);
-        PRINT_VA_STATE(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, 0, vertex_array[i].size, 1, print_all);
-        PRINT_VA_STATE(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, 0, vertex_array[i].type, 1, print_all);
-        PRINT_VA_STATE(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 0, vertex_array[i].normalized, 1, print_all);
-        PRINT_VA_STATE(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, 0, vertex_array[i].stride, 1, print_all);
-        PRINT_VA_POINTER(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, 0, vertex_array[i].pointer, print_all);
-     }
-
-   for (i=0; i<MAX_VERTEX_ATTRIBS; ++i)
-     {
-        PRINT_VA_STATE(i, GL_CURRENT_VERTEX_ATTRIB, 2, vertex_attrib[i].value[0], 4, print_all);
-     }
-
-   fprintf(stderr, "-----------------------------------------------------------\n\n", current_ctx);
-#undef GET_STATE
-#undef PRINT_VA_STATE
-#undef PRINT_VA_POINTER
-
-   //-------------------//
-   ctx->num_tex_units                          = MAX_TEXTURE_UNITS;
-   ctx->num_vertex_attribs                     = MAX_VERTEX_ATTRIBS;
-
-   //----------------------------------------//
-   // GL States
-   // Bind Functions
-   // glBind {Buffer, Framebuffer, Renderbuffer, Texture}
-   ctx->gl_array_buffer_binding                = 0;
-   ctx->gl_element_array_buffer_binding        = 0;
-   ctx->gl_framebuffer_binding                 = 0;
-   ctx->gl_renderbuffer_binding                = 0;
-
-   // Enable States
-   // glEnable()
-   ctx->gl_blend                               = GL_FALSE;
-   ctx->gl_cull_face                           = GL_FALSE;
-   ctx->gl_depth_test                          = GL_FALSE;
-   ctx->gl_dither                              = GL_TRUE;
-   ctx->gl_polygon_offset_fill                 = GL_FALSE;
-   ctx->gl_sample_alpha_to_coverage            = GL_FALSE;
-   ctx->gl_sample_coverage                     = GL_FALSE;
-   ctx->gl_scissor_test                        = GL_FALSE;
-   ctx->gl_stencil_test                        = GL_FALSE;
-
-   ctx->gl_cull_face_mode                      = GL_BACK;
-
-   // Viewport - Set it to 0
-   ctx->gl_viewport[0]                         = 0;       // (0,0,w,h)
-   ctx->gl_viewport[1]                         = 0;       // (0,0,w,h)
-   ctx->gl_viewport[2]                         = 0;       // (0,0,w,h)
-   ctx->gl_viewport[3]                         = 0;       // (0,0,w,h)
-
-   // Program (Shaders)
-   ctx->gl_current_program                     = 0;
-
-   // Texture
-   //   ctx->tex_state[MAX_TEXTURE_UNITS]
-   ctx->gl_active_texture                      = GL_TEXTURE0;
-   ctx->gl_generate_mipmap_hint                = GL_DONT_CARE;
-   //ctx->gl_texture_binding_2d                  = 0;
-   //ctx->gl_texture_binding_cube_map            = 0;
-
-
-   // Clear Color
-   ctx->gl_color_clear_value[0]                = 0;
-   ctx->gl_color_clear_value[1]                = 0;
-   ctx->gl_color_clear_value[2]                = 0;
-   ctx->gl_color_clear_value[3]                = 0;
-   ctx->gl_color_writemask[0]                  = GL_TRUE;
-   ctx->gl_color_writemask[1]                  = GL_TRUE;
-   ctx->gl_color_writemask[2]                  = GL_TRUE;
-   ctx->gl_color_writemask[3]                  = GL_TRUE;
-
-   // Depth
-   ctx->gl_depth_range[0]                      = 0;
-   ctx->gl_depth_range[1]                      = 1;
-   ctx->gl_depth_clear_value                   = 1;
-   ctx->gl_depth_func                          = GL_LESS;
-   ctx->gl_depth_writemask                     = GL_TRUE;
-
-   // Blending
-   ctx->gl_blend_color[0]                      = 0;
-   ctx->gl_blend_color[1]                      = 0;
-   ctx->gl_blend_color[2]                      = 0;
-   ctx->gl_blend_color[3]                      = 0;
-   ctx->gl_blend_src_rgb                       = GL_ONE;
-   ctx->gl_blend_src_alpha                     = GL_ONE;
-   ctx->gl_blend_dst_rgb                       = GL_ZERO;
-   ctx->gl_blend_dst_alpha                     = GL_ZERO;
-   ctx->gl_blend_equation_rgb                  = GL_FUNC_ADD;
-   ctx->gl_blend_equation_alpha                = GL_FUNC_ADD;
-
-   // Stencil
-   ctx->gl_stencil_fail                        = GL_KEEP;
-   ctx->gl_stencil_func                        = GL_ALWAYS;
-   ctx->gl_stencil_pass_depth_fail             = GL_KEEP;
-   ctx->gl_stencil_pass_depth_pass             = GL_KEEP;
-   ctx->gl_stencil_ref                         = 0;
-   ctx->gl_stencil_value_mask                  = 0xffffffff;
-   ctx->gl_stencil_writemask                   = 0xffffffff;
-
-   ctx->gl_stencil_back_fail                   = GL_KEEP;
-   ctx->gl_stencil_back_func                   = GL_ALWAYS;
-   ctx->gl_stencil_back_pass_depth_fail        = GL_KEEP;
-   ctx->gl_stencil_back_pass_depth_pass        = GL_KEEP;
-   ctx->gl_stencil_back_ref                    = 0;
-   ctx->gl_stencil_back_value_mask             = 0xffffffff;
-   ctx->gl_stencil_back_writemask              = 0xffffffff;
-   ctx->gl_stencil_clear_value                 = 0;
-
-   // Misc.
-   ctx->gl_front_face                          = GL_CCW;
-   ctx->gl_line_width                          = 1;
-   ctx->gl_polygon_offset_factor               = 0;
-   ctx->gl_polygon_offset_units                = 0;
-
-   ctx->gl_sample_coverage_value               = 1.0;
-   ctx->gl_sample_coverage_invert              = GL_FALSE;
-   ctx->gl_scissor_box[0]                      = 0;
-   ctx->gl_scissor_box[1]                      = 0;
-   ctx->gl_scissor_box[2]                      = 0;      // Supposed to be w
-   ctx->gl_scissor_box[3]                      = 0;      // Supposed to be h
-
-   ctx->gl_pack_alignment                      = 4;
-   ctx->gl_unpack_alignment                    = 4;
-
-
-   // Vertex Attrib Array
-   for (i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-     {
-        ctx->vertex_array[i].modified          = GL_FALSE;
-        ctx->vertex_array[i].enabled           = GL_FALSE;
-        ctx->vertex_array[i].size              = 4;
-        ctx->vertex_array[i].type              = GL_FLOAT;
-        ctx->vertex_array[i].normalized        = GL_FALSE;
-        ctx->vertex_array[i].stride            = GL_FALSE;
-        ctx->vertex_array[i].pointer           = NULL;
-
-        ctx->vertex_attrib[i].modified         = GL_FALSE;
-        ctx->vertex_attrib[i].value[0]         = 0;
-        ctx->vertex_attrib[i].value[1]         = 0;
-        ctx->vertex_attrib[i].value[2]         = 0;
-        ctx->vertex_attrib[i].value[3]         = 1;
-     }
-
-   ctx->gl_current_vertex_attrib[0]            = 0;
-   ctx->gl_current_vertex_attrib[1]            = 0;
-   ctx->gl_current_vertex_attrib[2]            = 0;
-   ctx->gl_current_vertex_attrib[3]            = 1;
-
-   return 1;
-}
+   attribs[n++] = EGL_IMAGE_PRESERVED_KHR;
+   attribs[n++] = 0;
+   attribs[n++] = EGL_NONE;
 
+   return EXT_FUNC(eglCreateImage)(dpy, ctx, target, (EGLClientBuffer)(uintptr_t)buffer, attribs);
+#else
+   (void) context; (void) target; (void) buffer;
+   return NULL;
 #endif
+}
 
-
-
-
-
-
-// For internal fastpath
-static int
-init_context_states(EvasGlueContext ctx)
+static void
+_egl_image_destroy(void *image)
 {
-   int i;
+#ifdef GL_GLES
+   EGLDisplay dpy = EGL_NO_DISPLAY;
+   EVGL_Resource *rsc = NULL;
 
-   if (!ctx)
+   // Retrieve the resource object
+   if (!(rsc = _evgl_tls_resource_get()))
      {
-        ERR("Context NULL\n");
-        return 0;
+        ERR("Error creating resources in tls.");
+        return;
      }
 
-   // Set Magic and other inits
-   ctx->magic      = MAGIC_GLFAST;
-   //ctx->initialized = 0;
-
-   //-------------------//
-   ctx->num_tex_units                          = MAX_TEXTURE_UNITS;
-   ctx->num_vertex_attribs                     = MAX_VERTEX_ATTRIBS;
-
-   //----------------------------------------//
-   // GL States
-   // Bind Functions
-   // glBind {Buffer, Framebuffer, Renderbuffer, Texture}
-   ctx->gl_array_buffer_binding                = 0;
-   ctx->gl_element_array_buffer_binding        = 0;
-   ctx->gl_framebuffer_binding                 = 0;
-   ctx->gl_renderbuffer_binding                = 0;
-
-   // Enable States
-   // glEnable()
-   ctx->gl_blend                               = GL_FALSE;
-   ctx->gl_cull_face                           = GL_FALSE;
-   ctx->gl_depth_test                          = GL_FALSE;
-   ctx->gl_dither                              = GL_TRUE;
-   ctx->gl_polygon_offset_fill                 = GL_FALSE;
-   ctx->gl_sample_alpha_to_coverage            = GL_FALSE;
-   ctx->gl_sample_coverage                     = GL_FALSE;
-   ctx->gl_scissor_test                        = GL_FALSE;
-   ctx->gl_stencil_test                        = GL_FALSE;
-
-   ctx->gl_cull_face_mode                      = GL_BACK;
-
-   // Viewport - Set it to 0
-   ctx->gl_viewport[0]                         = 0;       // (0,0,w,h)
-   ctx->gl_viewport[1]                         = 0;       // (0,0,w,h)
-   ctx->gl_viewport[2]                         = 0;       // (0,0,w,h)
-   ctx->gl_viewport[3]                         = 0;       // (0,0,w,h)
-
-   // Program (Shaders)
-   ctx->gl_current_program                     = 0;
-
-   // Texture
-   //   ctx->tex_state[MAX_TEXTURE_UNITS]
-   ctx->gl_active_texture                      = GL_TEXTURE0;
-   ctx->gl_generate_mipmap_hint                = GL_DONT_CARE;
-   //ctx->gl_texture_binding_2d                  = 0;
-   //ctx->gl_texture_binding_cube_map            = 0;
-
-
-   // Clear Color
-   ctx->gl_color_clear_value[0]                = 0;
-   ctx->gl_color_clear_value[1]                = 0;
-   ctx->gl_color_clear_value[2]                = 0;
-   ctx->gl_color_clear_value[3]                = 0;
-   ctx->gl_color_writemask[0]                  = GL_TRUE;
-   ctx->gl_color_writemask[1]                  = GL_TRUE;
-   ctx->gl_color_writemask[2]                  = GL_TRUE;
-   ctx->gl_color_writemask[3]                  = GL_TRUE;
-
-   // Depth
-   ctx->gl_depth_range[0]                      = 0;
-   ctx->gl_depth_range[1]                      = 1;
-   ctx->gl_depth_clear_value                   = 1;
-   ctx->gl_depth_func                          = GL_LESS;
-   ctx->gl_depth_writemask                     = GL_TRUE;
-
-   // Blending
-   ctx->gl_blend_color[0]                      = 0;
-   ctx->gl_blend_color[1]                      = 0;
-   ctx->gl_blend_color[2]                      = 0;
-   ctx->gl_blend_color[3]                      = 0;
-   ctx->gl_blend_src_rgb                       = GL_ONE;
-   ctx->gl_blend_src_alpha                     = GL_ONE;
-   ctx->gl_blend_dst_rgb                       = GL_ZERO;
-   ctx->gl_blend_dst_alpha                     = GL_ZERO;
-   ctx->gl_blend_equation_rgb                  = GL_FUNC_ADD;
-   ctx->gl_blend_equation_alpha                = GL_FUNC_ADD;
-
-   // Stencil
-   ctx->gl_stencil_fail                        = GL_KEEP;
-   ctx->gl_stencil_func                        = GL_ALWAYS;
-   ctx->gl_stencil_pass_depth_fail             = GL_KEEP;
-   ctx->gl_stencil_pass_depth_pass             = GL_KEEP;
-   ctx->gl_stencil_ref                         = 0;
-   ctx->gl_stencil_value_mask                  = 0xffffffff;
-   ctx->gl_stencil_writemask                   = 0xffffffff;
-
-   ctx->gl_stencil_back_fail                   = GL_KEEP;
-   ctx->gl_stencil_back_func                   = GL_ALWAYS;
-   ctx->gl_stencil_back_pass_depth_fail        = GL_KEEP;
-   ctx->gl_stencil_back_pass_depth_pass        = GL_KEEP;
-   ctx->gl_stencil_back_ref                    = 0;
-   ctx->gl_stencil_back_value_mask             = 0xffffffff;
-   ctx->gl_stencil_back_writemask              = 0xffffffff;
-   ctx->gl_stencil_clear_value                 = 0;
-
-   // Misc.
-   ctx->gl_front_face                          = GL_CCW;
-   ctx->gl_line_width                          = 1;
-   ctx->gl_polygon_offset_factor               = 0;
-   ctx->gl_polygon_offset_units                = 0;
-
-   ctx->gl_sample_coverage_value               = 1.0;
-   ctx->gl_sample_coverage_invert              = GL_FALSE;
-   ctx->gl_scissor_box[0]                      = 0;
-   ctx->gl_scissor_box[1]                      = 0;
-   ctx->gl_scissor_box[2]                      = 0;      // Supposed to be w
-   ctx->gl_scissor_box[3]                      = 0;      // Supposed to be h
-
-   ctx->gl_pack_alignment                      = 4;
-   ctx->gl_unpack_alignment                    = 4;
-
-
-   // Vertex Attrib Array
-   for (i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-     {
-        ctx->vertex_array[i].modified          = GL_FALSE;
-        ctx->vertex_array[i].enabled           = GL_FALSE;
-        ctx->vertex_array[i].size              = 4;
-        ctx->vertex_array[i].type              = GL_FLOAT;
-        ctx->vertex_array[i].normalized        = GL_FALSE;
-        ctx->vertex_array[i].stride            = GL_FALSE;
-        ctx->vertex_array[i].pointer           = NULL;
-
-        ctx->vertex_attrib[i].modified         = GL_FALSE;
-        ctx->vertex_attrib[i].value[0]         = 0;
-        ctx->vertex_attrib[i].value[1]         = 0;
-        ctx->vertex_attrib[i].value[2]         = 0;
-        ctx->vertex_attrib[i].value[3]         = 1;
-     }
-
-   ctx->gl_current_vertex_attrib[0]            = 0;
-   ctx->gl_current_vertex_attrib[1]            = 0;
-   ctx->gl_current_vertex_attrib[2]            = 0;
-   ctx->gl_current_vertex_attrib[3]            = 1;
+   dpy = (EGLDisplay)rsc->display;
+   if (!dpy) return;
 
-   return 1;
+   EXT_FUNC(eglDestroyImage)(dpy, image);
+#else
+   (void) image;
+#endif
 }
 
-//-------------------------------//
-// Get Type
-// 0 = glGet
-// 1 = glGetVertexAttrib
-// 2 = glGetVertexAttribPointer
-//-------------------------------//
-
-typedef enum _State_Type
+static void
+_framebuffer_create(GLuint *buf, Eina_Bool use_extension)
 {
-   STATE_INT,
-   STATE_HEX,
-   STATE_BOOLEAN,
-   STATE_FLOAT,
-   VA_STATE_INT,
-   VA_STATE_FLOAT,
-   VA_STATE_POINTER,
-} State_Type;
+   if (use_extension)
+     {
+        if (gles1_funcs && gles1_funcs->glGenFramebuffersOES)
+          gles1_funcs->glGenFramebuffersOES(1, buf);
+     }
+   else
+     {
+        glGenFramebuffers(1, buf);
+     }
+}
 
 static void
-print_state_bool(const char * name, int index, GLboolean *val1,
-                 GLboolean *val2, int num, State_Type state_type, int print_all)
+_framebuffer_bind(GLuint buf, Eina_Bool use_extension)
 {
-   int i;
-
-   for (i=0; i<num; ++i)
-      if ( (print_all) || (val1[i] != val2[i]) )
-         switch (state_type)
-           {
-            case STATE_BOOLEAN:
-               fprintf(stderr, "\t %-25.25s    : %10d    %10d\n",
-                       name, val1[i], val2[i]);
-               break;
-            default:
-               fprintf(stderr, "\t Error: Invalid State Print Bool Type.\n");
-           }
+   if (use_extension)
+     {
+        if (gles1_funcs && gles1_funcs->glBindFramebufferOES)
+          gles1_funcs->glBindFramebufferOES(GL_FRAMEBUFFER, buf);
+     }
+   else
+     {
+        glBindFramebuffer(GL_FRAMEBUFFER, buf);
+     }
+}
 
+static GLenum
+_framebuffer_check(Eina_Bool use_extension)
+{
+   GLenum ret = 0;
+   if (use_extension)
+     {
+        if (gles1_funcs && gles1_funcs->glCheckFramebufferStatusOES)
+          ret = gles1_funcs->glCheckFramebufferStatusOES(GL_FRAMEBUFFER);
+     }
+   else
+     {
+        ret = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+     }
+   return ret;
+}
 
+// Gen Renderbuffer
+static void
+_renderbuffer_create(GLuint *buf)
+{
+   glGenRenderbuffers(1, buf);
 }
 
+
+// Attach a renderbuffer with the given format to already bound FBO
 static void
-print_state_int(const char * name, int index, GLint *val1,
-            GLint *val2, int num, State_Type state_type, int print_all)
+_renderbuffer_allocate(GLuint buf, GLenum fmt, int w, int h, int samples)
 {
-   int i;
-
-   for (i=0; i<num; ++i)
-      if ( (print_all) || (val1[i] != val2[i]) )
-         switch (state_type)
-           {
-            case STATE_INT:
-               fprintf(stderr, "\t %-25.25s    : %10d    %10d\n",
-                       name, val1[i], val2[i]);
-               break;
-            case STATE_HEX:
-               fprintf(stderr, "\t %-25.25s    : %10x    %10x\n",
-                       name, val1[i], val2[i]);
-               break;
-            case VA_STATE_INT:
-               if (num > 1)
-                  fprintf(stderr, "\t %-25.25s[%-2.2d||%-1.1d]: %10d    %10d\n",
-                          name, index, i, val1[i], val2[i]);
-               else
-                  fprintf(stderr, "\t %-25.25s[%-2.2d]   : %10d    %10d\n",
-                          name, index, val1[i], val2[i]);
-               break;
-            case VA_STATE_POINTER:
-               fprintf(stderr, "\t %-25.25s[%-2.2d]   : %10d    %10d\n",
-                       name, index, val1[i], val2[i]);
-               break;
-            default:
-               fprintf(stderr, "\t Error: Invalid State Print Type.\n");
-           }
+   glBindRenderbuffer(GL_RENDERBUFFER, buf);
+   if (samples)
+#ifdef GL_GLES
+      EXT_FUNC(glRenderbufferStorageMultisample)(GL_RENDERBUFFER, samples, fmt, w, h);
+#else
+      ERR("MSAA not supported.  Should not have come in here...!");
+#endif
+   else
+      glRenderbufferStorage(GL_RENDERBUFFER, fmt, w, h);
+   glBindRenderbuffer(GL_RENDERBUFFER, 0);
+
+   return;
+   samples = 0;
 }
 
 static void
-print_state_float(const char * name, int index, GLfloat *val1,
-                  GLfloat *val2, int num, State_Type state_type, int print_all)
+_renderbuffer_destroy(GLuint *buf)
 {
-   int i;
-
-   for (i=0; i<num; ++i)
-      if ( (print_all) || (val1[i] != val2[i]) )
-         switch (state_type)
-           {
-            case STATE_FLOAT:
-               fprintf(stderr, "\t %-25.25s    : %10.1f    %10.1f\n",
-                       name, val1[i], val2[i]);
-               break;
-            case VA_STATE_FLOAT:
-               if (num > 1)
-                  fprintf(stderr, "\t %-25.25s[%-2.2d||%-1.1d]: %10.1f    %10.1f\n",
-                          name, index, i, val1[i], val2[i]);
-               else
-                  fprintf(stderr, "\t %-25.25s[%-2.2d]   : %10.1f    %10.1f\n",
-                          name, index, val1[i], val2[i]);
-
-               break;
-            default:
-               fprintf(stderr, "\t Error: Invalid State Print Float Type.\n");
-           }
+   if (*buf)
+     {
+        glDeleteRenderbuffers(1, buf);
+        *buf = 0;
+     }
 }
 
-/*
+// Attach a renderbuffer with the given format to already bound FBO
 static void
-get_state(GLenum state, State_Type type, int index, void *value)
+_renderbuffer_attach(GLuint buf, GLenum attach, Eina_Bool use_extension)
 {
-   switch (type)
+   if (use_extension)
      {
-      case STATE_INT | STATE_HEX:
-        _sym_glGetIntegerv(state, (GLint*)value);
-        break;
+        if (gles1_funcs->glFramebufferRenderbufferOES)
+          gles1_funcs->glFramebufferRenderbufferOES(GL_FRAMEBUFFER, attach, GL_RENDERBUFFER, buf);
+     }
+   else
+     {
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, attach, GL_RENDERBUFFER, buf);
+     }
+}
 
-      case STATE_BOOLEAN:
-        _sym_glGetBooleanv(state, (GLboolean*)value);
-        break;
+// Check whether the given FBO surface config is supported by the driver
+static int
+_fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
+                      GLenum depth_fmt, GLenum stencil_fmt, int mult_samples)
+{
+   GLuint fbo = 0;
+   GLuint color_buf = 0;
+   GLuint depth_buf = 0;
+   GLuint stencil_buf = 0;
+   GLuint depth_stencil_buf = 0;
+   int depth_stencil = 0;
+   int fb_status = 0;
+   int w = 2, h = 2;   // Test it with a simple (2,2) surface.  Should I test it with NPOT?
 
-      case STATE_FLOAT:
-        _sym_glGetFloatv(state, (GLfloat*)value);
-        break;
+   // Gen FBO
+   glGenFramebuffers(1, &fbo);
+   glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 
-      case VA_STATE_FLOAT:
-        _sym_glGetVertexAttribiv(index, state, (GLfloat*)value);
-        break;
+   // Color Buffer Texture
+   if ((color_ifmt) && (color_fmt))
+     {
+        _texture_create(&color_buf);
+        _texture_allocate_2d(color_buf, color_ifmt, color_fmt, GL_UNSIGNED_BYTE, w, h);
+        _texture_attach_2d(color_buf, GL_COLOR_ATTACHMENT0, 0, mult_samples, EINA_FALSE);
+     }
 
-      case VA_STATE_POINTER:
-        _sym_glGetVertexAttribPointerv(index, state, (GLfloat*)value);
-        break;
+   // Check Depth_Stencil Format First
+#ifdef GL_GLES
+   if (depth_fmt == GL_DEPTH_STENCIL_OES)
+     {
+        _texture_create(&depth_stencil_buf);
+        _texture_allocate_2d(depth_stencil_buf, depth_fmt,
+                           depth_fmt, GL_UNSIGNED_INT_24_8_OES, w, h);
+        _texture_attach_2d(depth_stencil_buf, GL_DEPTH_ATTACHMENT,
+                           GL_STENCIL_ATTACHMENT, mult_samples, EINA_FALSE);
+        depth_stencil = 1;
+     }
+#else
+   if (depth_fmt == GL_DEPTH24_STENCIL8)
+     {
+        _renderbuffer_create(&depth_stencil_buf);
+        _renderbuffer_allocate(depth_stencil_buf, depth_fmt, w, h, mult_samples);
+        _renderbuffer_attach(depth_stencil_buf, GL_DEPTH_STENCIL_ATTACHMENT, EINA_FALSE);
+        depth_stencil = 1;
+     }
+#endif
 
-      case default:
-        fprintf(stderr, "\t Error: Invalid State Print Type.\n");
+   // Depth Attachment
+   if ((!depth_stencil) && (depth_fmt))
+     {
+        _renderbuffer_create(&depth_buf);
+        _renderbuffer_allocate(depth_buf, depth_fmt, w, h, mult_samples);
+        _renderbuffer_attach(depth_buf, GL_DEPTH_ATTACHMENT, EINA_FALSE);
      }
-}
-*/
 
-static void
-print_get_state(const char *state_name, GLenum state, State_Type type, int index, int num, void *value, int all)
-{
-   switch (type)
-     {
-      case STATE_INT:
-      case STATE_HEX:
-           {
-              GLint real_val[4] = {-1, -1, -1, -1};
-              GLint *curr_val = (GLint*)value;
-              _sym_glGetIntegerv(state, real_val);
-              print_state_int(state_name, index, real_val, curr_val, num, type, all);
-           }
-         break;
+   // Stencil Attachment
+   if ((!depth_stencil) && (stencil_fmt))
+     {
+        _renderbuffer_create(&stencil_buf);
+        _renderbuffer_allocate(stencil_buf, stencil_fmt, w, h, mult_samples);
+        _renderbuffer_attach(stencil_buf, GL_STENCIL_ATTACHMENT, EINA_FALSE);
+     }
 
-      case STATE_BOOLEAN:
-           {
-              GLboolean real_val[4] = {3, 3, 3, 3};
-              GLboolean *curr_val = (GLboolean*)value;
-              _sym_glGetBooleanv(state, real_val);
-              print_state_bool(state_name, index, real_val, curr_val, num, type, all);
-           }
-         break;
+   // Check FBO for completeness
+   fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
 
-      case STATE_FLOAT:
-           {
-              GLfloat real_val[4] = {-1, -1, -1, -1};
-              GLfloat *curr_val = (GLfloat*)value;
-              _sym_glGetFloatv(state, real_val);
-              print_state_float(state_name, index, real_val, curr_val, num, type, all);
-           }
-         break;
+   // Delete Created Resources
+   _texture_destroy(&color_buf);
+   _renderbuffer_destroy(&depth_buf);
+   _renderbuffer_destroy(&stencil_buf);
+#ifdef GL_GLES
+   _texture_destroy(&depth_stencil_buf);
+#else
+   _renderbuffer_destroy(&depth_stencil_buf);
+#endif
 
-      case VA_STATE_INT:
-           {
-              GLint real_val[4] = {-1, -1, -1, -1};
-              GLint *curr_val = (GLint*)value;
-              _sym_glGetVertexAttribiv(index, state, real_val);
-              print_state_int(state_name, index, real_val, curr_val, num, type, all);
-           }
-         break;
+   // Delete FBO
+   glBindFramebuffer(GL_FRAMEBUFFER, 0);
+   if (fbo) glDeleteFramebuffers(1, &fbo);
 
-      case VA_STATE_FLOAT:
-           {
-              GLfloat real_val[4] = {-1, -1, -1, -1};
-              GLfloat *curr_val = (GLfloat*)value;
-              _sym_glGetVertexAttribfv(index, state, real_val);
-              print_state_float(state_name, index, real_val, curr_val, num, type, all);
-           }
-         break;
+   // Return the result
+   if (fb_status != GL_FRAMEBUFFER_COMPLETE)
+     {
+        int err = glGetError();
 
-      case VA_STATE_POINTER:
-           {
-              GLint real_val[4] = {-1, -1, -1, -1};
-              GLint *curr_val = (GLint*)value;
-              _sym_glGetVertexAttribPointerv(index, state, real_val);
-              print_state_int(state_name, index, (GLint*)real_val, (GLint*)curr_val, num, type, all);
-           }
-         break;
+        if (err != GL_NO_ERROR)
+           DBG("glGetError() returns %x ", err);
 
-      default:
-         fprintf(stderr, "\t Error: Invalid State Print Type.\n");
+        return 0;
      }
+   else
+      return 1;
 }
 
-/*
-static void
-print_state(const char *state_name, GLenum state, State_Type print_type, int num, void *value, int all, int get_type, int index)
+static int
+_surface_cap_test(EVGL_Surface_Format *fmt, GL_Format *color,
+                  GL_Format *depth, GL_Format *stencil, int samples)
 {
-   int i;
+   int ret = 0;
 
-   if (get_type == 0)
+   if ( (depth->bit == DEPTH_STENCIL) && (stencil->bit != STENCIL_BIT_8))
+      return 0;
+
+   ret = _fbo_surface_cap_test((GLint)color->fmt,
+                               color->fmt,
+                               depth->fmt,
+                               stencil->fmt, samples);
+   if (ret)
      {
-        GLint real_val[4] = {-1, -1, -1, -1};
-        GLint *curr_val = (GLint*)value;
-        _sym_glGetIntegerv(state, real_val);
-        print_state(state_name, index, real_val, curr_val, num, print_type, all);
+        fmt->color_bit  = color->bit;
+        fmt->color_ifmt = (GLint)color->fmt;
+        fmt->color_fmt  = color->fmt;
+        fmt->samples = samples;
 
-        // Boolean Type
-        else if (print_type == 1)
-          {
-             GLboolean real_val[4] = {3, 3, 3, 3};
-             GLboolean *curr_val = (GLboolean*)value;
-             _sym_glGetBooleanv(state, real_val);
-             for (i=0; i<num; ++i)
-                if ( (all) || (real_val[i] != curr_val[i]) )
-                   fprintf(stderr, "\t %-25.25s    : %10d    %10d\n",
-                           state_name, real_val[i], curr_val[i]);
-          }
-        // Float Type
-        else if (print_type == 2)
+        if (depth->bit == DEPTH_STENCIL)
           {
-             GLfloat real_val[4] = {-1, -1, -1, -1};
-             GLfloat *curr_val = (GLfloat*)value;
-             _sym_glGetFloatv(state, real_val);
-             for (i=0; i<num; ++i)
-                if ( (all) || (real_val[i] != curr_val[i]) )
-                   fprintf(stderr, "\t %-25.25s    : %10.1f    %10.1f\n",
-                           state_name, real_val[i], curr_val[i]);
+             // Depth Stencil Case
+             fmt->depth_stencil_fmt = depth->fmt;
+             fmt->depth_bit   = DEPTH_BIT_24;
+             fmt->depth_fmt   = 0;
+             fmt->stencil_bit = STENCIL_BIT_8;
+             fmt->stencil_fmt = 0;
           }
         else
-           fprintf(stderr, "Error Priting State: %s...\n", state_name);
-     }
-   else if (get_type == 1)
-     {
-        // GetVertexAttrib
-        if (print_type == 0)
-          {
-             GLint real_val[4] = {-1, -1, -1, -1};
-             GLint *curr_val = (GLint*)value;
-             _sym_glGetVertexAttribiv(index, state, real_val);
-
-             for (i=0; i<num; ++i)
-                if ( (all) || (real_val[i] != curr_val[i]) )
-                   if (num > 1)
-                      fprintf(stderr, "\t %-25.25s[%-2.2d||%-1.1d]: %10d    %10d\n",
-                              state_name, index, i, real_val[i], curr_val[i]);
-                   else
-                      fprintf(stderr, "\t %-25.25s[%-2.2d]   : %10d    %10d\n",
-                              state_name, index, real_val[i], curr_val[i]);
-          }
-        else if (print_type == 2)
           {
-             GLfloat real_val[4] = {-1, -1, -1, -1};
-             GLfloat *curr_val = (GLfloat*)value;
-             _sym_glGetVertexAttribfv(index, state, real_val);
-             for (i=0; i<num; ++i)
-                if ( (all) || (real_val[i] != curr_val[i]) )
-                   if (num > 1)
-                      fprintf(stderr, "\t %-25.25s[%-2.2d||%-1.1d]: %10.1f    %10.1f\n",
-                              state_name, index, i, real_val[i], curr_val[i]);
-                   else
-                      fprintf(stderr, "\t %-25.25s[%-2.2d]   : %10.1f    %10.1f\n",
-                              state_name, index, real_val[i], curr_val[i]);
+             fmt->depth_stencil_fmt = 0;
+             fmt->depth_bit = depth->bit;
+             fmt->depth_fmt = depth->fmt;
+             fmt->stencil_bit = stencil->bit;
+             fmt->stencil_fmt = stencil->fmt;
           }
      }
-   else if (get_type == 2)
-     {
-        GLint real_val[4] = {-1, -1, -1, -1};
-        GLint *curr_val = (GLint*)value;
-        _sym_glGetVertexAttribPointerv(index, state, real_val);
-
-        for (i=0; i<num; ++i)
-           if ( (all) || (real_val[i] != curr_val[i]) )
-              fprintf(stderr, "\t %-25.25s[%-2.2d]   : %10d    %10d\n",
-                      state_name, index, real_val[i], curr_val[i]);
-     }
 
+   return ret;
 }
-*/
 
 
-void
-print_gl_states(const char* func_name, int line_num )
-{
-   int i;
+static int
+_surface_cap_check()
+{
+   int num_fmts = 0;
+   int i, j, k, m;
+
+   GL_Format color[]   = {
+                           { COLOR_RGB_888,   GL_RGB },
+                           { COLOR_RGBA_8888, GL_RGBA },
+                           { -1, -1 },
+                         };
+
+#ifdef GL_GLES
+   GL_Format depth[]   = {
+                           { DEPTH_NONE,   0 },
+                           { DEPTH_STENCIL, GL_DEPTH_STENCIL_OES },
+                           { DEPTH_BIT_8,   GL_DEPTH_COMPONENT },
+                           { DEPTH_BIT_16,  GL_DEPTH_COMPONENT16 },
+                           { DEPTH_BIT_24,  GL_DEPTH_COMPONENT24_OES },
+                           { DEPTH_BIT_32,  GL_DEPTH_COMPONENT32_OES },
+                           { -1, -1 },
+                         };
+   GL_Format stencil[] = {
+                           { STENCIL_NONE, 0 },
+                           { STENCIL_BIT_1, GL_STENCIL_INDEX1_OES },
+                           { STENCIL_BIT_4, GL_STENCIL_INDEX4_OES },
+                           { STENCIL_BIT_8, GL_STENCIL_INDEX8 },
+                           { -1, -1 },
+                         };
+#else
+   GL_Format depth[]   = {
+                           { DEPTH_NONE,   0 },
+                           { DEPTH_STENCIL, GL_DEPTH24_STENCIL8 },
+                           { DEPTH_BIT_8,   GL_DEPTH_COMPONENT },
+                           { DEPTH_BIT_16,  GL_DEPTH_COMPONENT16 },
+                           { DEPTH_BIT_24,  GL_DEPTH_COMPONENT24 },
+                           { DEPTH_BIT_32,  GL_DEPTH_COMPONENT32 },
+                           { -1, -1 },
+                         };
+   GL_Format stencil[] = {
+                           { STENCIL_NONE, 0 },
+                           { STENCIL_BIT_1, GL_STENCIL_INDEX1 },
+                           { STENCIL_BIT_4, GL_STENCIL_INDEX4 },
+                           { STENCIL_BIT_8, GL_STENCIL_INDEX8 },
+                           { -1, -1 },
+                         };
+#endif
+
+   int msaa_samples[4] = {0, -1, -1, -1};  // { NO_MSAA, LOW, MED, HIGH }
 
-   if (!log_opt) return;
+   EVGL_Surface_Format *fmt = NULL;
 
-   if (!current_ctx)
+   // Check if engine is valid
+   if (!evgl_engine)
      {
-        ERR("Error Printing. No Current Context:");
-        return;
+        ERR("EVGL Engine not initialized!");
+        return 0;
+     }
+
+   // Check Surface Cap for MSAA
+   if (evgl_engine->caps.msaa_supported)
+     {
+        if ((evgl_engine->caps.msaa_samples[2] != evgl_engine->caps.msaa_samples[1]) &&
+            (evgl_engine->caps.msaa_samples[2] != evgl_engine->caps.msaa_samples[0]))
+             msaa_samples[3] = evgl_engine->caps.msaa_samples[2];    // HIGH
+        if ((evgl_engine->caps.msaa_samples[1] != evgl_engine->caps.msaa_samples[0]))
+             msaa_samples[2] = evgl_engine->caps.msaa_samples[1];    // MED
+        if (evgl_engine->caps.msaa_samples[0])
+             msaa_samples[1] = evgl_engine->caps.msaa_samples[0];    // LOW
      }
 
 
-#define PRINT_STATE(glstate, type, evglstate, num, all) \
-   print_get_state(#glstate, glstate, type, 0, num, (void*)&(current_ctx->evglstate), all);
+   // MSAA
+   for ( m = 0; m < 4; m++)
+     {
+        if (msaa_samples[m] < 0) continue;
+
+        // Color Formats
+        i = 0;
+        while ( color[i].bit >= 0 )
+          {
+             j = 0;
+             // Depth Formats
+             while ( depth[j].bit >= 0 )
+               {
+                  k = 0;
+                  // Stencil Formats
+                  while ( stencil[k].bit >= 0)
+                    {
+                       fmt = &evgl_engine->caps.fbo_fmts[num_fmts];
+                       if (_surface_cap_test(fmt, &color[i], &depth[j], &stencil[k], msaa_samples[m]))
+                          num_fmts++;
+                       k++;
+                    }
+                  j++;
+               }
+             i++;
+          }
+     }
 
-#define PRINT_VA_STATE(index, glstate, type, evglstate, num, all) \
-   print_get_state(#glstate, glstate, type, index, num, (void*)&(current_ctx->evglstate), all);
+   return num_fmts;
+}
 
+static int
+_surface_cap_load(Eet_File *ef)
+{
+   int res = 0, i = 0, length = 0;
+   char tag[80];
+   char *data = NULL;
+
+   data = eet_read(ef, "num_fbo_fmts", &length);
+   if ((!data) || (length <= 0)) goto finish;
+   if (data[length - 1] != 0) goto finish;
+   evgl_engine->caps.num_fbo_fmts = atoi(data);
+   free(data);
+   data = NULL;
+
+   // !!!FIXME
+   // Should use eet functionality instead of just reading using sscanfs...
+   for (i = 0; i < evgl_engine->caps.num_fbo_fmts; ++i)
+     {
+        EVGL_Surface_Format *fmt = &evgl_engine->caps.fbo_fmts[i];
+
+        snprintf(tag, sizeof(tag), "fbo_%d", i);
+        data = eet_read(ef, tag, &length);
+        if ((!data) || (length <= 0)) goto finish;
+        if (data[length - 1] != 0) goto finish;
+        sscanf(data, "%d%d%d%d%d%d%d%d%d%d",
+               &(fmt->index),
+               (int*)(&(fmt->color_bit)), &(fmt->color_ifmt), &(fmt->color_fmt),
+               (int*)(&(fmt->depth_bit)), &(fmt->depth_fmt),
+               (int*)(&(fmt->stencil_bit)), &(fmt->stencil_fmt),
+               &(fmt->depth_stencil_fmt),
+               &(fmt->samples));
+        free(data);
+        data = NULL;
+     }
+   res = 1;
+
+finish:
+   if (data) free(data);
+   return res;
+}
 
-   fprintf(stderr, "---------------Current Actual GL Context %p States----------------\n", current_ctx);
-   fprintf(stderr, "Print GL States Called from %s @ line %d\n", func_name, line_num);
-   fprintf(stderr, "---TID: %d\n\n", syscall(__NR_gettid));
-//-----------------------------------------------------------//
+static int
+_surface_cap_save(Eet_File *ef)
+{
+   int i = 0;
+   char tag[80], data[80];
 
+   snprintf(data, sizeof(data), "%d", evgl_engine->caps.num_fbo_fmts);
+   if (eet_write(ef, "num_fbo_fmts", data, strlen(data) + 1, 1) < 0)
+      return 0;
 
-   int print_all = 0;
+   // !!!FIXME
+   // Should use eet functionality instead of just writing out using snprintfs...
+   for (i = 0; i < evgl_engine->caps.num_fbo_fmts; ++i)
+     {
+        EVGL_Surface_Format *fmt = &evgl_engine->caps.fbo_fmts[i];
 
-   if (log_opt==2) print_all = 1;
+        snprintf(tag, sizeof(tag), "fbo_%d", i);
+        snprintf(data, sizeof(data), "%d %d %d %d %d %d %d %d %d %d",
+                 fmt->index,
+                 fmt->color_bit, fmt->color_ifmt, fmt->color_fmt,
+                 fmt->depth_bit, fmt->depth_fmt,
+                 fmt->stencil_bit, fmt->stencil_fmt,
+                 fmt->depth_stencil_fmt,
+                 fmt->samples);
+        if (eet_write(ef, tag, data, strlen(data) + 1, 1) < 0) return 0;
+     }
 
-   PRINT_STATE(GL_ARRAY_BUFFER_BINDING, STATE_INT, gl_array_buffer_binding, 1, print_all);
-   PRINT_STATE(GL_ELEMENT_ARRAY_BUFFER_BINDING, STATE_INT, gl_element_array_buffer_binding, 1, print_all);
-   PRINT_STATE(GL_FRAMEBUFFER_BINDING, STATE_INT, gl_framebuffer_binding, 1, print_all);
-   PRINT_STATE(GL_RENDERBUFFER_BINDING, STATE_INT, gl_renderbuffer_binding, 1, print_all);
+   return 1;
+}
 
-   PRINT_STATE(GL_BLEND, STATE_BOOLEAN, gl_blend, 1, print_all);
-   PRINT_STATE(GL_CULL_FACE, STATE_BOOLEAN, gl_cull_face, 1, print_all);
-   PRINT_STATE(GL_DEPTH_TEST, STATE_BOOLEAN, gl_depth_test, 1, print_all);
-   PRINT_STATE(GL_DITHER, STATE_BOOLEAN, gl_dither, 1, print_all);
+static int
+_surface_cap_cache_load()
+{
+   /* check eet */
+   Eet_File *et = NULL;
+   char cap_dir_path[PATH_MAX];
+   char cap_file_path[PATH_MAX];
 
-   PRINT_STATE(GL_POLYGON_OFFSET_FILL, STATE_BOOLEAN, gl_polygon_offset_fill, 1, print_all);
-   PRINT_STATE(GL_SAMPLE_ALPHA_TO_COVERAGE, STATE_BOOLEAN, gl_sample_alpha_to_coverage, 1, print_all);
-   PRINT_STATE(GL_SAMPLE_COVERAGE, STATE_BOOLEAN, gl_sample_coverage, 1, print_all);
-   PRINT_STATE(GL_SCISSOR_TEST, STATE_BOOLEAN, gl_scissor_test, 1, print_all);
-   PRINT_STATE(GL_STENCIL_TEST, STATE_BOOLEAN, gl_stencil_test, 1, print_all);
+   if (!evas_gl_common_file_cache_dir_check(cap_dir_path, sizeof(cap_dir_path)))
+      return 0;
 
-   PRINT_STATE(GL_VIEWPORT, STATE_INT, gl_viewport[0], 4, print_all);
-   PRINT_STATE(GL_CURRENT_PROGRAM, STATE_INT, gl_current_program, 1, print_all);
+   if (!evas_gl_common_file_cache_file_check(cap_dir_path, "surface_cap",
+                                             cap_file_path, sizeof(cap_dir_path)))
+      return 0;
 
-   PRINT_STATE(GL_COLOR_CLEAR_VALUE, STATE_FLOAT, gl_color_clear_value[0], 4, print_all);
+   /* use eet */
+   if (!eet_init()) return 0;
+   et = eet_open(cap_file_path, EET_FILE_MODE_READ);
+   if (!et) goto error;
 
-   PRINT_STATE(GL_COLOR_WRITEMASK, STATE_BOOLEAN, gl_color_writemask[0], 4, print_all);
+   if (!_surface_cap_load(et))
+      goto error;
 
-   PRINT_STATE(GL_DEPTH_RANGE, STATE_FLOAT, gl_depth_range[0], 2, print_all);
-   PRINT_STATE(GL_DEPTH_CLEAR_VALUE, STATE_FLOAT, gl_depth_clear_value, 1, print_all);
-   PRINT_STATE(GL_DEPTH_FUNC, STATE_INT, gl_depth_func, 1, print_all);
-   PRINT_STATE(GL_DEPTH_WRITEMASK, STATE_BOOLEAN, gl_depth_writemask, 1, print_all);
-   PRINT_STATE(GL_CULL_FACE_MODE, STATE_INT, gl_cull_face_mode, 1, print_all);
+   if (et) eet_close(et);
+   eet_shutdown();
+   return 1;
 
-   int active_tex;
-   _sym_glGetIntegerv(GL_ACTIVE_TEXTURE, &active_tex);
+error:
+   if (et) eet_close(et);
+   eet_shutdown();
+   return 0;
+}
 
-   for (i=0; i<MAX_TEXTURE_UNITS; ++i)
-     {
-        _sym_glActiveTexture(GL_TEXTURE0 + i);
-        PRINT_STATE(GL_TEXTURE_BINDING_2D, STATE_INT, tex_2d_state[i], 1, print_all);
-     }
-   for (i=0; i<MAX_TEXTURE_UNITS; ++i)
+static int
+_surface_cap_cache_save()
+{
+   /* check eet */
+   Eet_File *et = NULL; //check eet file
+   int tmpfd;
+   int res = 0;
+   char cap_dir_path[PATH_MAX];
+   char cap_file_path[PATH_MAX];
+   char tmp_file[PATH_MAX];
+
+   if (!evas_gl_common_file_cache_dir_check(cap_dir_path, sizeof(cap_dir_path)))
      {
-        _sym_glActiveTexture(GL_TEXTURE0 + i);
-        PRINT_STATE(GL_TEXTURE_BINDING_CUBE_MAP, STATE_INT, tex_cube_map_state[i], 1, print_all);
+        res = evas_gl_common_file_cache_mkpath(cap_dir_path);
+        if (!res) return 0; /* we can't make directory */
      }
-   _sym_glActiveTexture(active_tex);
 
-   PRINT_STATE(GL_ACTIVE_TEXTURE, STATE_INT, gl_active_texture, 1, print_all);
-   PRINT_STATE(GL_GENERATE_MIPMAP_HINT, STATE_INT, gl_generate_mipmap_hint, 1, print_all);
-   //PRINT_STATE(GL_TEXTURE_BINDING_, 0, gl_texture_binding_2D, 1);
-   //PRINT_STATE(GL_TEXTURE_BINDING_CUBE_MAP, 0, gl_texture_binding_cube_map, 1);
+   evas_gl_common_file_cache_file_check(cap_dir_path, "surface_cap", cap_file_path,
+                                        sizeof(cap_dir_path));
 
-   PRINT_STATE(GL_BLEND_COLOR, STATE_FLOAT, gl_blend_color[0], 4, print_all);
-   PRINT_STATE(GL_BLEND_SRC_RGB, STATE_INT, gl_blend_src_rgb, 1, print_all);
-   PRINT_STATE(GL_BLEND_SRC_ALPHA, STATE_INT, gl_blend_src_alpha, 1, print_all);
-   PRINT_STATE(GL_BLEND_DST_RGB, STATE_INT, gl_blend_dst_rgb, 1, print_all);
-   PRINT_STATE(GL_BLEND_DST_ALPHA, STATE_INT, gl_blend_dst_alpha, 1, print_all);
-   PRINT_STATE(GL_BLEND_EQUATION_RGB, STATE_INT, gl_blend_equation_rgb, 1, print_all);
-   PRINT_STATE(GL_BLEND_EQUATION_ALPHA, STATE_INT, gl_blend_equation_alpha, 1, print_all);
+   /* use mkstemp for writing */
+   snprintf(tmp_file, sizeof(tmp_file), "%s.XXXXXX", cap_file_path);
+   tmpfd = mkstemp(tmp_file);
+   if (tmpfd < 0) goto error;
+   close(tmpfd);
 
-   PRINT_STATE(GL_STENCIL_FUNC, STATE_INT, gl_stencil_func, 1, print_all);
-   PRINT_STATE(GL_STENCIL_REF, STATE_INT, gl_stencil_ref, 1, print_all);
-   PRINT_STATE(GL_STENCIL_VALUE_MASK, STATE_HEX, gl_stencil_value_mask, 1, print_all);
-   PRINT_STATE(GL_STENCIL_FAIL, STATE_INT, gl_stencil_fail, 1, print_all);
-   PRINT_STATE(GL_STENCIL_PASS_DEPTH_FAIL, STATE_INT, gl_stencil_pass_depth_fail, 1, print_all);
-   PRINT_STATE(GL_STENCIL_PASS_DEPTH_PASS, STATE_INT, gl_stencil_pass_depth_pass, 1, print_all);
-   PRINT_STATE(GL_STENCIL_WRITEMASK, STATE_HEX, gl_stencil_writemask, 1, print_all);
+   /* use eet */
+   if (!eet_init()) goto error;
 
-   PRINT_STATE(GL_STENCIL_BACK_FUNC, STATE_INT, gl_stencil_back_func, 1, print_all);
-   PRINT_STATE(GL_STENCIL_BACK_REF, STATE_INT, gl_stencil_back_ref, 1, print_all);
-   PRINT_STATE(GL_STENCIL_BACK_VALUE_MASK, STATE_HEX, gl_stencil_back_value_mask, 1, print_all);
-   PRINT_STATE(GL_STENCIL_BACK_FAIL, STATE_INT, gl_stencil_back_fail, 1, print_all);
-   PRINT_STATE(GL_STENCIL_BACK_PASS_DEPTH_FAIL, STATE_INT, gl_stencil_back_pass_depth_fail, 1, print_all);
-   PRINT_STATE(GL_STENCIL_BACK_PASS_DEPTH_PASS, STATE_INT, gl_stencil_back_pass_depth_pass, 1, print_all);
-   PRINT_STATE(GL_STENCIL_BACK_WRITEMASK, STATE_HEX, gl_stencil_back_writemask, 1, print_all);
+   et = eet_open(tmp_file, EET_FILE_MODE_WRITE);
+   if (!et) goto error;
 
-   PRINT_STATE(GL_STENCIL_CLEAR_VALUE, STATE_INT, gl_stencil_clear_value, 1, print_all);
+   if (!_surface_cap_save(et)) goto error;
 
-   PRINT_STATE(GL_FRONT_FACE, STATE_INT, gl_front_face, 1, print_all);
-   PRINT_STATE(GL_LINE_WIDTH, STATE_FLOAT, gl_line_width, 1, print_all);
-   PRINT_STATE(GL_POLYGON_OFFSET_FACTOR, STATE_FLOAT, gl_polygon_offset_factor, 1, print_all);
-   PRINT_STATE(GL_POLYGON_OFFSET_UNITS, STATE_FLOAT, gl_polygon_offset_units, 1, print_all);
-   PRINT_STATE(GL_SAMPLE_COVERAGE_VALUE, STATE_FLOAT, gl_sample_coverage_value, 1, print_all);
-   PRINT_STATE(GL_SAMPLE_COVERAGE_INVERT, STATE_BOOLEAN, gl_sample_coverage_invert, 1, print_all);
+   if (eet_close(et) != EET_ERROR_NONE) goto error;
+   if (rename(tmp_file,cap_file_path) < 0) goto error;
+   eet_shutdown();
+   return 1;
 
-   PRINT_STATE(GL_SCISSOR_BOX, STATE_INT, gl_scissor_box[0], 4, print_all);
-   PRINT_STATE(GL_PACK_ALIGNMENT, STATE_INT, gl_pack_alignment, 1, print_all);
-   PRINT_STATE(GL_UNPACK_ALIGNMENT, STATE_INT, gl_unpack_alignment, 1, print_all);
+error:
+   if (et) eet_close(et);
+   if (evas_gl_common_file_cache_file_exists(tmp_file)) unlink(tmp_file);
+   eet_shutdown();
+   return 0;
+}
 
-   for (i=0; i<MAX_VERTEX_ATTRIBS; ++i)
-     {
-        PRINT_VA_STATE(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, VA_STATE_INT, vertex_array[i].buf_id, 1, print_all);
-        PRINT_VA_STATE(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, VA_STATE_INT, vertex_array[i].enabled, 1, print_all);
-        PRINT_VA_STATE(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, VA_STATE_INT, vertex_array[i].size, 1, print_all);
-        PRINT_VA_STATE(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, VA_STATE_INT, vertex_array[i].type, 1, print_all);
-        PRINT_VA_STATE(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, VA_STATE_INT, vertex_array[i].normalized, 1, print_all);
-        PRINT_VA_STATE(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, VA_STATE_INT, vertex_array[i].stride, 1, print_all);
-        PRINT_VA_STATE(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, VA_STATE_POINTER, vertex_array[i].pointer, 1, print_all);
-     }
+static int
+_surface_cap_init(void *eng_data)
+{
+   int max_size = 0;
 
-   for (i=0; i<MAX_VERTEX_ATTRIBS; ++i)
+   // Do internal make current
+   if (!_internal_resource_make_current(eng_data, NULL))
      {
-        PRINT_VA_STATE(i, GL_CURRENT_VERTEX_ATTRIB, VA_STATE_FLOAT, vertex_attrib[i].value[0], 4, print_all);
+        ERR("Error doing an internal resource make current");
+        return 0;
      }
 
-   fprintf(stderr, "-----------------------------------------------------------\n\n", current_ctx);
-#undef PRINT_STATE
-   /*
-#undef PRINT_VA_STATE
-#undef PRINT_VA_POINTER
-*/
-}
-
-
-static void
-make_context_current(EvasGlueContext oldctx, EvasGlueContext newctx)
-{
-   unsigned char flag = 0;
-   int i = 0;
+   // Query the max width and height of the surface
+   glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &max_size);
 
-   // Return if they're the same
-   if (oldctx==newctx) return;
+   evgl_engine->caps.max_w = max_size;
+   evgl_engine->caps.max_h = max_size;
+   DBG("Max Surface Width: %d   Height: %d", evgl_engine->caps.max_w, evgl_engine->caps.max_h);
 
-#ifdef EVAS_GL_DEBUG
-   #define STATE_COMPARE(state) \
-      if (1)
-   #define STATES_COMPARE(state_ptr, bytes) \
-      if (1)
-#else
-   #define STATE_COMPARE(state) \
-      if ((oldctx->state) != (newctx->state))
-   #define STATES_COMPARE(state_ptr, bytes) \
-      if ((memcmp((oldctx->state_ptr), (newctx->state_ptr), (bytes))) != 0)
-#endif
+   // Check for MSAA support
+#ifdef GL_GLES
+   int max_samples = 0;
 
-   _sym_glFlush();
+   if (EXTENSION_SUPPORT(IMG_multisampled_render_to_texture))
+     {
+        glGetIntegerv(GL_MAX_SAMPLES_IMG, &max_samples);
+     }
+   else if (EXTENSION_SUPPORT(EXT_multisampled_render_to_texture))
+     {
+        glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_samples);
+     }
 
-   //------------------//
-   // _bind_flag
-   flag = oldctx->_bind_flag | newctx->_bind_flag;
-   if (COMPARE_OPT_SKIP flag)
+   if (max_samples >= 2)
      {
-        STATE_COMPARE(gl_array_buffer_binding)
-          {
-             _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding);
-          }
-        STATE_COMPARE(gl_element_array_buffer_binding)
-          {
-             _sym_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding);
-          }
-        STATE_COMPARE(gl_framebuffer_binding)
-          {
-             _sym_glBindFramebuffer(GL_FRAMEBUFFER, newctx->gl_framebuffer_binding);
-          }
-        STATE_COMPARE(gl_renderbuffer_binding)
-          {
-             _sym_glBindRenderbuffer(GL_RENDERBUFFER, newctx->gl_renderbuffer_binding);
-          }
+        evgl_engine->caps.msaa_samples[0] = 2;
+        evgl_engine->caps.msaa_samples[1] = (max_samples >> 1) < 2 ? 2 : (max_samples >> 1);
+        evgl_engine->caps.msaa_samples[2] = max_samples;
+        evgl_engine->caps.msaa_supported  = 1;
      }
+#endif
 
-   //------------------//
-   // Enable States
-   // _enable_flag1
-   flag = oldctx->_enable_flag1 | newctx->_enable_flag1;
-   if (COMPARE_OPT_SKIP flag)
+   // Load Surface Cap
+   if (!_surface_cap_cache_load())
      {
-        STATE_COMPARE(gl_blend)
-          {
-             if (newctx->gl_blend)
-                _sym_glEnable(GL_BLEND);
-             else
-                _sym_glDisable(GL_BLEND);
-          }
-        STATE_COMPARE(gl_cull_face)
-          {
-             if (newctx->gl_cull_face)
-                _sym_glEnable(GL_CULL_FACE);
-             else
-                _sym_glDisable(GL_CULL_FACE);
-          }
-        STATE_COMPARE(gl_depth_test)
-          {
-             if (newctx->gl_depth_test)
-                _sym_glEnable(GL_DEPTH_TEST);
-             else
-                _sym_glDisable(GL_DEPTH_TEST);
-          }
-        STATE_COMPARE(gl_dither)
-          {
-             if (newctx->gl_dither)
-                _sym_glEnable(GL_DITHER);
-             else
-                _sym_glDisable(GL_DITHER);
-          }
-     }
-
-   // _enable_flag2
-   flag = oldctx->_enable_flag2 | newctx->_enable_flag2;
-   if (COMPARE_OPT_SKIP flag)
-     {
-        STATE_COMPARE(gl_polygon_offset_fill)
-          {
-             if (newctx->gl_polygon_offset_fill)
-                _sym_glEnable(GL_POLYGON_OFFSET_FILL);
-             else
-                _sym_glDisable(GL_POLYGON_OFFSET_FILL);
-          }
-        STATE_COMPARE(gl_sample_alpha_to_coverage)
-          {
-             if (newctx->gl_sample_alpha_to_coverage)
-                _sym_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
-             else
-                _sym_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
-          }
-        STATE_COMPARE(gl_sample_coverage)
-          {
-             if (newctx->gl_sample_coverage)
-                _sym_glEnable(GL_SAMPLE_COVERAGE);
-             else
-                _sym_glDisable(GL_SAMPLE_COVERAGE);
-          }
-        STATE_COMPARE(gl_scissor_test)
-          {
-             if (newctx->gl_scissor_test)
-                _sym_glEnable(GL_SCISSOR_TEST);
-             else
-                _sym_glDisable(GL_SCISSOR_TEST);
-          }
-        STATE_COMPARE(gl_stencil_test)
-          {
-             if (newctx->gl_stencil_test)
-                _sym_glEnable(GL_STENCIL_TEST);
-             else
-                _sym_glDisable(GL_STENCIL_TEST);
-          }
-     }
-
-   //------------------//
-   // _clear_flag1
-   flag = oldctx->_clear_flag1 | newctx->_clear_flag1;
-   if (COMPARE_OPT_SKIP flag)
-     {
-        // Viewport.
-        STATES_COMPARE(gl_viewport, 4*sizeof(GLint))
-          {
-             _sym_glViewport(newctx->gl_viewport[0],
-                             newctx->gl_viewport[1],
-                             newctx->gl_viewport[2],
-                             newctx->gl_viewport[3]);
-          }
-        STATE_COMPARE(gl_current_program)
-          {
-             _sym_glUseProgram(newctx->gl_current_program);
-          }
-        STATES_COMPARE(gl_color_clear_value, 4*sizeof(GLclampf))
-          {
-             _sym_glClearColor(newctx->gl_color_clear_value[0],
-                               newctx->gl_color_clear_value[1],
-                               newctx->gl_color_clear_value[2],
-                               newctx->gl_color_clear_value[3]);
-          }
-     }
-
-
-   // _clear_flag2
-   flag = oldctx->_clear_flag2 | newctx->_clear_flag2;
-   if (COMPARE_OPT_SKIP flag)
-     {
-        STATES_COMPARE(gl_color_writemask, 4*sizeof(GLboolean))
-          {
-             _sym_glColorMask(newctx->gl_color_writemask[0],
-                              newctx->gl_color_writemask[1],
-                              newctx->gl_color_writemask[2],
-                              newctx->gl_color_writemask[3]);
-          }
-        STATES_COMPARE(gl_depth_range, 2*sizeof(GLclampf))
-          {
-             _sym_glDepthRangef(newctx->gl_depth_range[0],
-                                newctx->gl_depth_range[1]);
-          }
-        STATE_COMPARE(gl_depth_clear_value)
-          {
-             _sym_glClearDepthf(newctx->gl_depth_clear_value);
-          }
-        STATE_COMPARE(gl_depth_func)
-          {
-             _sym_glDepthFunc(newctx->gl_depth_func);
-          }
-        STATE_COMPARE(gl_depth_writemask)
-          {
-             _sym_glDepthMask(newctx->gl_depth_writemask);
-          }
-        STATE_COMPARE(gl_cull_face_mode)
-          {
-             _sym_glCullFace(newctx->gl_cull_face_mode);
-          }
-
-     }
-   //------------------//
-   // Texture here...
-   flag = oldctx->_tex_flag1 | newctx->_tex_flag1;
-   if (COMPARE_OPT_SKIP flag)
-     {
-
-        for (i = 0; i < oldctx->num_tex_units; i++)
-          {
-             STATE_COMPARE(tex_2d_state[i])
-               {
-                  _sym_glActiveTexture(GL_TEXTURE0+i);
-                  _sym_glBindTexture(GL_TEXTURE_2D, newctx->tex_2d_state[i]);
-               }
-
-             STATE_COMPARE(tex_cube_map_state[i])
-               {
-                  _sym_glActiveTexture(GL_TEXTURE0+i);
-                  _sym_glBindTexture(GL_TEXTURE_CUBE_MAP, newctx->tex_cube_map_state[i]);
-               }
-          }
-
-        // Restore active texture
-        _sym_glActiveTexture(newctx->gl_active_texture);
-
-        STATE_COMPARE(gl_generate_mipmap_hint)
-          {
-             _sym_glHint(GL_GENERATE_MIPMAP_HINT, newctx->gl_generate_mipmap_hint);
-          }
-     }
-
-
-   //------------------//
-   flag = oldctx->_blend_flag | newctx->_blend_flag;
-   if (COMPARE_OPT_SKIP flag)
-     {
-        STATES_COMPARE(gl_blend_color, 4*sizeof(GLclampf))
-          {
-             _sym_glBlendColor(newctx->gl_blend_color[0],
-                               newctx->gl_blend_color[1],
-                               newctx->gl_blend_color[2],
-                               newctx->gl_blend_color[3]);
-          }
-        if ( COMPARE_OPT_SKIP
-            (oldctx->gl_blend_src_rgb != newctx->gl_blend_src_rgb) ||
-            (oldctx->gl_blend_dst_rgb != newctx->gl_blend_dst_rgb) ||
-            (oldctx->gl_blend_src_alpha != newctx->gl_blend_src_alpha) ||
-            (oldctx->gl_blend_dst_alpha != newctx->gl_blend_dst_alpha))
-          {
-             _sym_glBlendFuncSeparate(newctx->gl_blend_src_rgb,
-                                      newctx->gl_blend_dst_rgb,
-                                      newctx->gl_blend_src_alpha,
-                                      newctx->gl_blend_dst_alpha);
-          }
-        if ( COMPARE_OPT_SKIP
-            (oldctx->gl_blend_equation_rgb != newctx->gl_blend_equation_rgb) ||
-            (oldctx->gl_blend_equation_alpha != newctx->gl_blend_equation_alpha))
-          {
-             _sym_glBlendEquationSeparate(newctx->gl_blend_equation_rgb, newctx->gl_blend_equation_alpha);
-          }
-
-     }
-
-   //------------------//
-   // _stencil_flag1
-   flag = oldctx->_stencil_flag1 | newctx->_stencil_flag1;
-   if (COMPARE_OPT_SKIP flag)
-     {
-        if ( COMPARE_OPT_SKIP
-            (oldctx->gl_stencil_func != newctx->gl_stencil_func) ||
-            (oldctx->gl_stencil_ref  != newctx->gl_stencil_ref)  ||
-            (oldctx->gl_stencil_value_mask != newctx->gl_stencil_value_mask))
-          {
-             _sym_glStencilFuncSeparate(GL_FRONT,
-                                        newctx->gl_stencil_func,
-                                        newctx->gl_stencil_ref,
-                                        newctx->gl_stencil_value_mask);
-          }
-        if ( COMPARE_OPT_SKIP
-            (oldctx->gl_stencil_fail != newctx->gl_stencil_fail) ||
-            (oldctx->gl_stencil_pass_depth_fail != newctx->gl_stencil_pass_depth_fail) ||
-            (oldctx->gl_stencil_pass_depth_pass != newctx->gl_stencil_pass_depth_pass))
-          {
-             _sym_glStencilOpSeparate(GL_FRONT,
-                                      newctx->gl_stencil_fail,
-                                      newctx->gl_stencil_pass_depth_fail,
-                                      newctx->gl_stencil_pass_depth_pass);
-          }
-        STATE_COMPARE(gl_stencil_writemask)
-          {
-             _sym_glStencilMaskSeparate(GL_FRONT, newctx->gl_stencil_writemask);
-          }
-     }
-
-
-   // _stencil_flag1
-   flag = oldctx->_stencil_flag2 | newctx->_stencil_flag2;
-   if (COMPARE_OPT_SKIP flag)
-     {
-        if ( COMPARE_OPT_SKIP
-            (oldctx->gl_stencil_back_func != newctx->gl_stencil_back_func) ||
-            (oldctx->gl_stencil_back_ref  != newctx->gl_stencil_back_ref)  ||
-            (oldctx->gl_stencil_back_value_mask != newctx->gl_stencil_back_value_mask))
-          {
-             _sym_glStencilFuncSeparate(GL_BACK,
-                                        newctx->gl_stencil_back_func,
-                                        newctx->gl_stencil_back_ref,
-                                        newctx->gl_stencil_back_value_mask);
-          }
-        if ( COMPARE_OPT_SKIP
-            (oldctx->gl_stencil_back_fail != newctx->gl_stencil_back_fail) ||
-            (oldctx->gl_stencil_back_pass_depth_fail != newctx->gl_stencil_back_pass_depth_fail) ||
-            (oldctx->gl_stencil_back_pass_depth_pass != newctx->gl_stencil_back_pass_depth_pass))
-          {
-             _sym_glStencilOpSeparate(GL_BACK,
-                                      newctx->gl_stencil_back_fail,
-                                      newctx->gl_stencil_back_pass_depth_fail,
-                                      newctx->gl_stencil_back_pass_depth_pass);
-          }
-        STATE_COMPARE(gl_stencil_back_writemask)
-          {
-             _sym_glStencilMaskSeparate(GL_BACK, newctx->gl_stencil_back_writemask);
-          }
-        STATE_COMPARE(gl_stencil_clear_value)
-          {
-             _sym_glClearStencil(newctx->gl_stencil_clear_value);
-          }
-     }
-
-   //------------------//
-   // _misc_flag1
-   flag = oldctx->_misc_flag1 | newctx->_misc_flag1;
-   if (COMPARE_OPT_SKIP flag)
-     {
-        STATE_COMPARE(gl_front_face)
-          {
-             _sym_glFrontFace(newctx->gl_front_face);
-          }
-        STATE_COMPARE(gl_line_width)
-          {
-             _sym_glLineWidth(newctx->gl_line_width);
-          }
-        if ( COMPARE_OPT_SKIP
-            (oldctx->gl_polygon_offset_factor != newctx->gl_polygon_offset_factor) ||
-            (oldctx->gl_polygon_offset_units  != newctx->gl_polygon_offset_units))
-          {
-             _sym_glPolygonOffset(newctx->gl_polygon_offset_factor,
-                                  newctx->gl_polygon_offset_units);
-          }
-        if ( COMPARE_OPT_SKIP
-            (oldctx->gl_sample_coverage_value  != newctx->gl_sample_coverage_value) ||
-            (oldctx->gl_sample_coverage_invert != newctx->gl_sample_coverage_invert))
-          {
-             _sym_glSampleCoverage(newctx->gl_sample_coverage_value,
-                                   newctx->gl_sample_coverage_invert);
-          }
-     }
-
-   // _misc_flag2
-   flag = oldctx->_misc_flag2 | newctx->_misc_flag2;
-   if (COMPARE_OPT_SKIP flag)
-     {
-        STATES_COMPARE(gl_scissor_box, 4*sizeof(GLint))
-          {
-             _sym_glScissor(newctx->gl_scissor_box[0],
-                            newctx->gl_scissor_box[1],
-                            newctx->gl_scissor_box[2],
-                            newctx->gl_scissor_box[3]);
-          }
-        STATE_COMPARE(gl_pack_alignment)
-          {
-             _sym_glPixelStorei(GL_PACK_ALIGNMENT, newctx->gl_pack_alignment);
-          }
-        STATE_COMPARE(gl_unpack_alignment)
-          {
-             _sym_glPixelStorei(GL_UNPACK_ALIGNMENT, newctx->gl_unpack_alignment);
-          }
-     }
-
-   // _varray_flag
-   flag = oldctx->_vattrib_flag | newctx->_vattrib_flag;
-   if (COMPARE_OPT_SKIP flag)
-     {
-        for (i = 0; i < oldctx->num_vertex_attribs; i++)
-          {
-             if ( COMPARE_OPT_SKIP
-                 newctx->vertex_array[i].buf_id != oldctx->vertex_array[i].buf_id)
-               {
-                  _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->vertex_array[i].buf_id);
-               }
-             else _sym_glBindBuffer(GL_ARRAY_BUFFER, 0);
-
-             _sym_glVertexAttribPointer(i,
-                                        newctx->vertex_array[i].size,
-                                        newctx->vertex_array[i].type,
-                                        newctx->vertex_array[i].normalized,
-                                        newctx->vertex_array[i].stride,
-                                        newctx->vertex_array[i].pointer);
-
-             STATES_COMPARE(vertex_attrib[i].value, 4*sizeof(GLfloat))
-               {
-                _sym_glVertexAttrib4fv(i, newctx->vertex_attrib[i].value);
-               }
-
-             if (newctx->vertex_array[i].enabled == GL_TRUE)
-               {
-                  _sym_glEnableVertexAttribArray(i);
-               }
-             else
-               {
-                  _sym_glDisableVertexAttribArray(i);
-               }
-          }
-
-        STATE_COMPARE(gl_array_buffer_binding)
-          {
-             _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding);
-          }
-        STATE_COMPARE(gl_element_array_buffer_binding)
-          {
-             _sym_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding);
-          }
-
-     }
-#undef STATE_COMPARE
-#undef STATES_COMPARE
-}
-//----------------------------------------------------------------//
-//                                                                //
-//                      Wrapped Glue Functions                    //
-//                                                                //
-//----------------------------------------------------------------//
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-
-//----------------------------------------------------------------//
-//                      Wrapped EGL Functions                     //
-//----------------------------------------------------------------//
-static _eng_fn
-evgl_eglGetProcAddress(const char* procname)
-{
-   return _sym_eglGetProcAddress(procname);
-}
-
-static EGLint
-evgl_eglGetError(void)
-{
-   return _sym_eglGetError();
-}
-
-static EGLDisplay
-evgl_eglGetDisplay(EGLNativeDisplayType display_id)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLDisplay result;
-   result = _sym_eglGetDisplay(display_id);
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return result;
-}
-
-static EGLBoolean
-evgl_eglInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLBoolean result;
-   result = _sym_eglInitialize(dpy, major, minor);
-
-   return result;
-}
-
-static EGLBoolean
-evgl_eglTerminate(EGLDisplay dpy)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLBoolean result;
-   result = _sym_eglTerminate(dpy);
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return result;
-}
-
-static EGLBoolean
-evgl_eglChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLBoolean result;
-
-   result = _sym_eglChooseConfig(dpy, attrib_list, configs, config_size, num_config);
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return result;
-}
-
-static EGLSurface
-evgl_eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint* attrib_list)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLSurface result;
-   result = _sym_eglCreateWindowSurface(dpy, config, win, attrib_list);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static EGLSurface
-evgl_eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint* attrib_list)
-{
-   EVAS_GL_START_LOG(mc_log);
-   EGLSurface result;
-   result = _sym_eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static EGLBoolean
-evgl_eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLBoolean result;
-   result = _sym_eglDestroySurface(dpy, surface);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static EGLBoolean
-evgl_eglBindAPI(EGLenum api)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLBoolean result;
-   result = _sym_eglBindAPI(api);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static EGLBoolean
-evgl_eglWaitClient(void)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLBoolean result;
-   result = _sym_eglWaitClient();
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static EGLBoolean
-evgl_eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLBoolean result;
-   result = _sym_eglSurfaceAttrib(dpy, surface, attribute, value);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static void
-evgl_eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_eglBindTexImage(dpy, surface, buffer);
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static EGLBoolean
-evgl_eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLBoolean result;
-   result = _sym_eglReleaseTexImage(dpy, surface, buffer);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static EGLBoolean
-evgl_eglSwapInterval(EGLDisplay dpy, EGLint interval)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLBoolean result;
-   result = _sym_eglSwapInterval(dpy, interval);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static EGLContext
-evgl_eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint* attrib_list)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLBoolean result;
-   result = _sym_eglCreateContext(dpy, config, share_context, attrib_list);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static EGLBoolean
-evgl_eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLBoolean result;
-   result = _sym_eglDestroyContext(dpy, ctx);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static EGLBoolean
-evgl_eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
-{
-   /*
-   if (_sym_eglMakeCurrent(dpy, draw, read, ctx))
-     {
-        current_egl_context = ctx;
-        current_surf = draw;
-        return EGL_TRUE;
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-   else return EGL_FALSE;
-   */
-
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLBoolean result;
-   result = _sym_eglMakeCurrent(dpy, draw, read, ctx);
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return result;
-}
-
-static EGLContext
-evgl_eglGetCurrentContext(void)
-{
-   EVAS_GL_START_LOG(mc_log);
-   //return current_egl_context;
-   EGLContext result;
-   result = _sym_eglGetCurrentContext();
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static EGLSurface
-evgl_eglGetCurrentSurface(EGLint readdraw)
-{
-   EVAS_GL_START_LOG(mc_log);
-   EGLSurface result;
-   result = _sym_eglGetCurrentSurface(readdraw);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static EGLDisplay
-evgl_eglGetCurrentDisplay(void)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLDisplay result;
-   result = _sym_eglGetCurrentDisplay();
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static EGLBoolean
-evgl_eglWaitGL(void)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLBoolean result;
-   result = _sym_eglWaitGL();
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static EGLBoolean
-evgl_eglWaitNative(EGLint engine)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLBoolean result;
-   result = _sym_eglWaitNative(engine);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static EGLBoolean
-evgl_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   frame_count++;
-   EGLBoolean result;
-   result = _sym_eglSwapBuffers(dpy, surface);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static EGLBoolean
-evgl_eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLBoolean result;
-   result = _sym_eglCopyBuffers(dpy, surface, target);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static char const *
-evgl_eglQueryString(EGLDisplay dpy, EGLint name)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   char const * result;
-   result = _sym_eglQueryString(dpy, name);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static void
-evgl_eglCreateImage (void *a, void *b, GLenum c, void *d, const int *e)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_eglCreateImage(a, b, c, d, e);
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static unsigned int
-evgl_eglDestroyImage (void *a, void *b)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   unsigned int result;
-   result = _sym_eglDestroyImage(a, b);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static void
-evgl_glEGLImageTargetTexture2DOES (int a, void *b)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glEGLImageTargetTexture2DOES(a, b);
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glEGLImageTargetRenderbufferStorageOES (int a, void *b)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glEGLImageTargetRenderbufferStorageOES(a, b);
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void *
-evgl_eglMapImageSEC (void *a, void *b)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   void * result;
-   result = _sym_eglMapImageSEC(a, b);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static unsigned int
-evgl_eglUnmapImageSEC (void *a, void *b)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   unsigned int result;
-   result = _sym_eglUnmapImageSEC(a, b);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-static unsigned int
-evgl_eglGetImageAttribSEC (void *a, void *b, int c, int *d)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   unsigned int result;
-   result = _sym_eglGetImageAttribSEC(a, b, c, d);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-//----------------------------------------------------------------//
-//                   Fastpath EGL Functions                       //
-//    The functions have prefix 'fpgl_' for (fastpath gl)         //
-//----------------------------------------------------------------//
-static EGLContext
-fpgl_eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint* attrib_list)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-   EvasGlueContext ctx;
-
-   // Create a global context if it hasn't been created
-   if (!global_ctx)
-     {
-        global_dpy = dpy;
-        // Create a global context if it hasn't been created yet
-        global_ctx = _sym_eglCreateContext(dpy, config, NULL, attrib_list);
-
-        if (!global_ctx)
-          {
-             ERR("Failed creating a glX global context for FastPath.\n");
-             return 0;
-          }
-        //fprintf(stderr, "---TID: %d\n", syscall(__NR_gettid));
-     }
-
-   // Allocate a new context
-   ctx = calloc(1, sizeof(struct _EvasGlueContext));
-   if (!ctx)
-     {
-        ERR("Error creating a new EvasGlueContext.\n");
-        return NULL;
-     }
-
-   ctx->initialized = 0;
-   ctx->magic      = MAGIC_GLFAST;
-   /*
-   // Initialize context states
-   if (!init_context_states(ctx))
-     {
-        ERR("Error intialing intial context\n");
-        free(ctx);
-        return NULL;
-     }
-     */
-
-   ctx_ref_count++;
-
-   return (EGLContext)ctx;
-}
-
-static EGLBoolean
-fpgl_eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-   EvasGlueContext ectx = (EvasGlueContext)ctx;
-
-   if (ctx!=NULL)
-     {
-        if (ectx->magic != MAGIC_GLFAST)
-          {
-             ERR("Magic Check Failed!!!\n");
-             return EGL_FALSE;
-          }
-
-        if (ectx == current_ctx)
-          {
-             DBG("Destroying current context... %d\n", ctx_ref_count);
-             if ((real_current_ctx) && (real_current_ctx->destroyed))
-                free(real_current_ctx);
-             real_current_ctx = current_ctx;
-             real_current_ctx->destroyed = 1;
-             current_ctx = NULL;
-          }
-        else
-          {
-             if (ectx)
-                free(ectx);
-          }
-
-        if (!(--ctx_ref_count))
-          {
-             if ((real_current_ctx) && (real_current_ctx->destroyed))
-                free(real_current_ctx);
-
-             DBG("Destroying the global context...\n");
-             _sym_eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-             _sym_eglDestroyContext(dpy, global_ctx);
-             global_ctx = NULL;
-             current_ctx = NULL;
-             real_current_ctx = NULL;
-          }
-
-        return EGL_TRUE;
-     }
-   else
-     {
-        ERR("Invalid Context.\n");
-        return EGL_FALSE;
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static EGLBoolean
-fpgl_eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-   // Do a Make Current NULL  (This is to unreference the currently bound surface)
-   if (!_sym_eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
-     {
-        ERR("Error making context current with the drawable.\n");
-        return EGL_FALSE;
-     }
-
-   if (current_ctx)
-     {
-        if ((real_current_ctx) && (real_current_ctx->destroyed))
-           free(real_current_ctx);
-        real_current_ctx = current_ctx;
-     }
-
-   current_ctx = NULL;
-   current_surf = EGL_NO_SURFACE;
-
-   EGLBoolean result;
-   result = _sym_eglDestroySurface(dpy, surface);
-
-   EVAS_GL_END_LOG(mc_log);
-   return result;
-}
-
-
-static EGLBoolean
-fpgl_eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-   EvasGlueContext ectx = (EvasGlueContext)ctx;
-
-   current_surf = _sym_eglGetCurrentSurface(EGL_DRAW);
-
-   // Check if the values are null
-   if ((draw == EGL_NO_SURFACE) || (ctx == NULL))
-     {
-        if (current_ctx)
-          {
-             if ((real_current_ctx) && (real_current_ctx->destroyed))
-                free(real_current_ctx);
-             real_current_ctx = current_ctx;
-          }
-
-        current_ctx = NULL;
-        current_surf = EGL_NO_SURFACE;
-        EVAS_GL_END_LOG(mc_log);
-
-        return EGL_TRUE;
-     }
-
-   // Check if the object is correct
-   if (ectx->magic != MAGIC_GLFAST)
-     {
-        ERR("Magic Check Failed!!!\n");
-        EVAS_GL_END_LOG(mc_log);
-        return EGL_FALSE;
-     }
-
-
-   // If it's a first time or drawable changed, do a make current
-   if (!global_ctx_initted)
-     {
-        if (!_sym_eglMakeCurrent(dpy, draw, read, global_ctx))
-          {
-             ERR("Error making context current with the drawable.\n");
-             EVAS_GL_END_LOG(mc_log);
-             return False;
-          }
-
-        current_ctx      = ectx;
-        current_surf     = draw;
-        real_current_ctx = current_ctx;
-
-        global_ctx_initted = 1;
-     }
-
-
-   if (!current_ctx) current_ctx = real_current_ctx;
-
-   // If drawable changed, do a make current
-   if (current_surf != draw)
-     {
-        if (!_sym_eglMakeCurrent(dpy, draw, read, global_ctx))
-          {
-             ERR("Error making context current with the drawable.\n");
-             EVAS_GL_END_LOG(mc_log);
-             return False;
-          }
-        current_surf = draw;
-     }
-
-   // If it's first time...
-   if (ectx->initialized == 0)
-     {
-        if (!init_context_states(ectx))
-          {
-             ERR("Error intialing intial context\n");
-             return False;
-          }
-
-        // FIXME!!!:
-        // Actually, i need to query the drawable size...
-        // Do some initializations that required make_current
-        _sym_glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &ectx->num_tex_units);
-        _sym_glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &ectx->num_vertex_attribs);
-        _sym_glGetIntegerv(GL_VIEWPORT, ectx->gl_viewport);
-        _sym_glGetIntegerv(GL_SCISSOR_BOX, ectx->gl_scissor_box);
-        DBG("----Num Tex Units: %d, Num Vertex Attribs: %d \n", ectx->num_tex_units, ectx->num_vertex_attribs);
-
-        ectx->initialized = 1;
-     }
-
-   // if context is same, return
-   if ( (current_ctx == ectx) && (current_surf == draw) )
-     {
-        EVAS_GL_END_LOG(mc_log);
-        return EGL_TRUE;
-     }
-
-   make_context_current(current_ctx, ectx);
-
-   current_ctx = ectx;
-   current_surf = draw;
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return EGL_TRUE;
-}
-
-static EGLContext
-fpgl_eglGetCurrentContext(void)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLContext result;
-   result = (EGLContext)current_ctx;
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return result;
-   //return _sym_eglGetCurrentContext();
-}
-
-static EGLSurface
-fpgl_eglGetCurrentSurface(EGLint readdraw)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-   EGLSurface result;
-   result = (EGLSurface)current_surf;
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return result;
-   //return _sym_eglGetCurrentSurface(readdraw);
-}
-
-// FIXME!!!!
-static void
-fpgl_glEGLImageTargetTexture2DOES (int a, void *b)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glEGLImageTargetTexture2DOES(a, b);
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-// FIXME!!!!
-static void
-fpgl_glEGLImageTargetRenderbufferStorageOES (int a, void *b)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glEGLImageTargetRenderbufferStorageOES(a, b);
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-
-#else
-
-//----------------------------------------------------------------//
-//                      Wrapped GLX Functions                     //
-//----------------------------------------------------------------//
-static _eng_fn
-evgl_glXGetProcAddress(const char* procName)
-{
-   return _sym_glXGetProcAddress(procName);
-}
-
-static XVisualInfo*
-evgl_glXChooseVisual(Display* dpy, int screen, int* attribList)
-{
-   return _sym_glXChooseVisual(dpy, screen, attribList);
-}
-
-static GLXContext
-evgl_glXCreateContext(Display* dpy, XVisualInfo* vis, GLXContext shareList, Bool direct)
-{
-   return _sym_glXCreateContext(dpy, vis, shareList, direct);
-}
-
-static void
-evgl_glXDestroyContext(Display* dpy, GLXContext ctx)
-{
-   _sym_glXDestroyContext(dpy, ctx);
-}
-
-static GLXContext
-evgl_glXGetCurrentContext(void)
-{
-   return _sym_glXGetCurrentContext();
-}
-
-static GLXDrawable
-evgl_glXGetCurrentDrawable(void)
-{
-   return _sym_glXGetCurrentDrawable();
-}
-
-
-static Bool
-evgl_glXMakeCurrent(Display* dpy, GLXDrawable draw, GLXContext ctx)
-{
-   return _sym_glXMakeCurrent(dpy, draw, ctx);
-}
-
-static void
-evgl_glXSwapBuffers(Display* dpy, GLXDrawable draw)
-{
-   _sym_glXSwapBuffers(dpy, draw);
-}
-
-static void
-evgl_glXWaitX(void)
-{
-   _sym_glXWaitX();
-}
-
-static void
-evgl_glXWaitGL(void)
-{
-   _sym_glXWaitGL();
-}
-
-static Bool
-evgl_glXQueryExtension(Display* dpy, int* errorb, int* event)
-{
-   return _sym_glXQueryExtension(dpy, errorb, event);
-}
-
-static const char *
-evgl_glXQueryExtensionsString(Display *dpy, int screen)
-{
-   return _sym_glXQueryExtensionsString(dpy, screen);
-}
-
-static GLXFBConfig*
-evgl_glXChooseFBConfig(Display* dpy, int screen, const int* attribList, int* nitems)
-{
-   return _sym_glXChooseFBConfig(dpy, screen, attribList, nitems);
-}
-
-static GLXFBConfig*
-evgl_glXGetFBConfigs(Display* dpy, int screen, int* nelements)
-{
-   return _sym_glXGetFBConfigs(dpy, screen, nelements);
-}
-
-//!!!!! FIXME Called too many times
-static int
-evgl_glXGetFBConfigAttrib(Display* dpy, GLXFBConfig config, int attribute, int* value)
-{
-   return _sym_glXGetFBConfigAttrib(dpy, config, attribute, value);
-}
-
-//!!!!! FIXME Called too many times
-static XVisualInfo*
-evgl_glXGetVisualFromFBConfig(Display* dpy, GLXFBConfig config)
-{
-   return _sym_glXGetVisualFromFBConfig(dpy, config);
-}
-
-static void
-evgl_glXDestroyWindow(Display* dpy, GLXWindow window)
-{
-   _sym_glXDestroyWindow(dpy, window);
-}
-
-static Bool
-evgl_glXMakeContextCurrent(Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
-{
-   return _sym_glXMakeContextCurrent(dpy, draw, read, ctx);
-}
-
-static void
-evgl_glXBindTexImage(Display* dpy, GLXDrawable draw, int buffer, int* attribList)
-{
-   _sym_glXBindTexImage(dpy, draw, buffer, attribList);
-}
-
-static void
-evgl_glXReleaseTexImage(Display* dpy, GLXDrawable draw, int buffer)
-{
-   _sym_glXReleaseTexImage(dpy, draw, buffer);
-}
-
-static int
-evgl_glXGetVideoSync(unsigned int* count)
-{
-   return _sym_glXGetVideoSync(count);
-}
-
-static int
-evgl_glXWaitVideoSync(int divisor, int remainder, unsigned int* count)
-{
-   return _sym_glXWaitVideoSync(divisor, remainder, count);
-}
-
-static XID
-evgl_glXCreatePixmap(Display* dpy, void* config, Pixmap pixmap, const int* attribList)
-{
-   return _sym_glXCreatePixmap(dpy, config, pixmap, attribList);
-}
-
-static void
-evgl_glXDestroyPixmap(Display* dpy, XID pixmap)
-{
-   _sym_glXDestroyPixmap(dpy, pixmap);
-}
-
-static void
-evgl_glXQueryDrawable(Display* dpy, XID draw, int attribute, unsigned int* value)
-{
-   _sym_glXQueryDrawable(dpy, draw, attribute, value);
-}
-
-static int
-evgl_glXSwapIntervalSGI(int interval)
-{
-   return _sym_glXSwapIntervalSGI(interval);
-}
-
-static void
-evgl_glXSwapIntervalEXT(Display* dpy, GLXDrawable draw, int interval)
-{
-   _sym_glXSwapIntervalEXT(dpy, draw, interval);
-}
-
-
-//----------------------------------------------------------------//
-//                   Fastpath GLX Functions                       //
-//       The functions have prefix 'fpgl_' for (fastpath gl)      //
-//----------------------------------------------------------------//
-static GLXContext
-fpgl_glXCreateContext(Display* dpy, XVisualInfo* vis, GLXContext shareList, Bool direct)
-{
-   THREAD_CHECK_DEBUG();
-
-   EvasGlueContext ctx;
-
-   // Create a global context if it hasn't been created
-   if (!global_ctx)
-     {
-        global_dpy = dpy;
-        // Create a global context if it hasn't been created yet
-        global_ctx = _sym_glXCreateContext(dpy, vis, NULL, 1);
-        if (!global_ctx)
-          {
-             ERR("Failed creating a glX global context for FastPath.\n");
-             return 0;
-          }
-        ctx_ref_count++;
-     }
-
-   // Allocate a new context
-   ctx = calloc(1, sizeof(struct _EvasGlueContext));
-   if (!ctx)
-     {
-        ERR("Error creating a new EvasGlueContext.\n");
-        return NULL;
-     }
-
-   if (!init_context_states(ctx))
-     {
-        ERR("Error intialing intial context\n");
-        free(ctx);
-        return NULL;
-     }
-
-   ctx_ref_count++;
-
-   return (GLXContext)ctx;
-
-}
-
-static void
-fpgl_glXDestroyContext(Display* dpy, GLXContext ctx)
-{
-   THREAD_CHECK_DEBUG();
-
-   EvasGlueContext ectx = (EvasGlueContext)ctx;
-
-   if (ctx!=NULL)
-     {
-        if (ectx->magic != MAGIC_GLFAST)
-          {
-             ERR("Magic Check Failed!!!\n");
-             return;
-          }
-
-        if (ectx == current_ctx)
-          {
-             DBG("Destroying current context... %d\n", ctx_ref_count);
-             if ((real_current_ctx) && (real_current_ctx->destroyed))
-                free(real_current_ctx);
-             real_current_ctx = current_ctx;
-             real_current_ctx->destroyed = 1;
-             current_ctx = NULL;
-          }
-        else
-          {
-             if (ectx)
-                free(ectx);
-          }
-
-        if (!(--ctx_ref_count))
-          {
-             if ((real_current_ctx) && (real_current_ctx->destroyed))
-                free(real_current_ctx);
-
-             DBG("Destroying the global context...\n");
-             _sym_glXDestroyContext(dpy, global_ctx);
-             global_ctx = NULL;
-             current_ctx = NULL;
-             real_current_ctx = NULL;
-          }
-     }
-}
-
-
-static GLXContext
-fpgl_glXGetCurrentContext(void)
-{
-   THREAD_CHECK_DEBUG();
-
-   return (GLXContext)current_ctx;
-}
-
-static GLXDrawable
-fpgl_glXGetCurrentDrawable(void)
-{
-   THREAD_CHECK_DEBUG();
-
-   //return _sym_glXGetCurrentDrawable();
-   return (GLXDrawable)current_surf;
-}
-
-
-static Bool
-fpgl_glXMakeCurrent(Display* dpy, GLXDrawable draw, GLXContext ctx)
-{
-   THREAD_CHECK_DEBUG();
-
-   EvasGlueContext ectx = (EvasGlueContext)ctx;
-
-   // Check if the values are null
-   if ((draw == None) || (ctx == NULL))
-     {
-        if (current_ctx)
-          {
-             if ((real_current_ctx) && (real_current_ctx->destroyed))
-                free(real_current_ctx);
-             real_current_ctx = current_ctx;
-          }
-
-        /*
-        if (!_sym_glXMakeCurrent(dpy, None, NULL))
-          {
-             ERR("Error making context current with the drawable.\n");
-             return False;
-          }
-          */
-
-        current_ctx = NULL;
-        current_surf = None;
-
-        return 1;
-     }
-
-   // Check if the object is correct
-   if (ectx->magic != MAGIC_GLFAST)
-     {
-        ERR("Magic Check Failed!!!\n");
-        return 0;
-     }
-
-
-   // If it's the first time
-   if (!global_ctx_initted)
-     {
-        if (!_sym_glXMakeCurrent(dpy, draw, global_ctx))
-          {
-             ERR("Error making context current with the drawable.\n");
-             return False;
-          }
-
-        current_ctx  = ectx;
-        current_surf = draw;
-
-        real_current_ctx = current_ctx;
-
-        global_ctx_initted = 1;
-     }
-
-
-   if (!current_ctx) current_ctx = real_current_ctx;
-
-   // If drawable changed, do a make current
-   if (current_surf != draw)
-     {
-        if (!_sym_glXMakeCurrent(dpy, draw, global_ctx))
-          {
-             ERR("Error making context current with the drawable.\n");
-             return False;
-          }
-        current_surf = draw;
-     }
-
-   // If it's first time...
-   if (ectx->initialized == 1)
-     {
-        // FIXME!!!:
-        // Actually, i need to query the drawable size...
-        // Do some initializations that required make_current
-        _sym_glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &ectx->num_tex_units);
-        _sym_glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &ectx->num_vertex_attribs);
-        _sym_glGetIntegerv(GL_VIEWPORT, ectx->gl_viewport);
-        _sym_glGetIntegerv(GL_SCISSOR_BOX, ectx->gl_scissor_box);
-        DBG("----Num Tex Units: %d, Num Vertex Attribs: %d \n", ectx->num_tex_units, ectx->num_vertex_attribs);
-
-        ectx->initialized = 0;
-     }
-
-   // if context is same, return
-   if ( (current_ctx == ectx) && (current_surf == draw) )
-     {
-        return True;
-     }
-
-   make_context_current(current_ctx, ectx);
-
-   current_ctx = ectx;
-   current_surf = draw;
-
-   return True;
-}
-
-static Bool
-fpgl_glXMakeContextCurrent(Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
-{
-   THREAD_CHECK_DEBUG();
-
-   ERR("NOT IMPLEMENTED YET!!! GLX Function Wrapped. Not fastpathed yet...\n");
-   return _sym_glXMakeContextCurrent(dpy, draw, read, ctx);
-}
-
-
-#endif // (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-
-
-
-//----------------------------------------------------------------//
-//                                                                //
-//                      Wrapped GL Functions                      //
-//                                                                //
-//----------------------------------------------------------------//
-
-static void
-evgl_glActiveTexture(GLenum texture)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glActiveTexture(texture);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glAttachShader(GLuint program, GLuint shader)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glAttachShader(program, shader);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glBindAttribLocation(GLuint program, GLuint index, const char* name)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glBindAttribLocation(program, index, name);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glBindBuffer(GLenum target, GLuint buffer)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glBindBuffer(target, buffer);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glBindFramebuffer(GLenum target, GLuint framebuffer)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glBindFramebuffer(target, framebuffer);
-
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glBindRenderbuffer(target, renderbuffer);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glBindTexture(GLenum target, GLuint texture)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glBindTexture(target, texture);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glBlendColor(red, green, blue, alpha);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glBlendEquation(GLenum mode)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glBlendEquation(mode);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glBlendEquationSeparate(modeRGB, modeAlpha);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glBlendFunc(GLenum sfactor, GLenum dfactor)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glBlendFunc(sfactor, dfactor);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glBufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glBufferData(target, size, data, usage);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glBufferSubData(target, offset, size, data);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static GLenum
-evgl_glCheckFramebufferStatus(GLenum target)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   GLenum result;
-
-   result = _sym_glCheckFramebufferStatus(target);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return result;
-}
-
-static void
-evgl_glClear(GLbitfield mask)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glClear(mask);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glClearColor(red, green, blue, alpha);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glClearDepthf(GLclampf depth)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glClearDepthf(depth);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glClearStencil(GLint s)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glClearStencil(s);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glColorMask(red, green, blue, alpha);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glCompileShader(GLuint shader)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glCompileShader(shader);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static GLuint
-evgl_glCreateProgram(void)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   GLuint program;
-
-   program = _sym_glCreateProgram();
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return program;
-}
-
-static GLuint
-evgl_glCreateShader(GLenum type)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   GLuint shader;
-
-   shader = _sym_glCreateShader(type);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return shader;
-}
-
-static void
-evgl_glCullFace(GLenum mode)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glCullFace(mode);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glDeleteBuffers(GLsizei n, const GLuint* buffers)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glDeleteBuffers(n, buffers);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glDeleteFramebuffers(n, framebuffers);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glDeleteProgram(GLuint program)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glDeleteProgram(program);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glDeleteRenderbuffers(n, renderbuffers);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glDeleteShader(GLuint shader)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glDeleteShader(shader);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glDeleteTextures(GLsizei n, const GLuint* textures)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glDeleteTextures(n, textures);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glDepthFunc(GLenum func)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glDepthFunc(func);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glDepthMask(GLboolean flag)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glDepthMask(flag);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glDepthRangef(GLclampf zNear, GLclampf zFar)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glDepthRangef(zNear, zFar);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glDetachShader(GLuint program, GLuint shader)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glDetachShader(program, shader);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glDisable(GLenum cap)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glDisable(cap);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glDisableVertexAttribArray(GLuint index)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glDisableVertexAttribArray(index);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glDrawArrays(GLenum mode, GLint first, GLsizei count)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glDrawArrays(mode, first, count);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glDrawElements(mode, count, type, indices);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glEnable(GLenum cap)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glEnable(cap);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glEnableVertexAttribArray(GLuint index)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glEnableVertexAttribArray(index);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glFinish(void)
-{
-   //EVAS_GL_START_LOG(mc_log);
-
-   _sym_glFinish();
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   //EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glFlush(void)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glFlush();
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glFramebufferTexture2D(target, attachment, textarget, texture, level);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glFrontFace(GLenum mode)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glFrontFace(mode);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetVertexAttribfv(index, pname, params);
-
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetVertexAttribiv(index, pname, params);
-
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetVertexAttribPointerv(index, pname, pointer);
-
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-
-}
-
-static void
-evgl_glHint(GLenum target, GLenum mode)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glHint(target, mode);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGenBuffers(GLsizei n, GLuint* buffers)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGenBuffers(n, buffers);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGenerateMipmap(GLenum target)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGenerateMipmap(target);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGenFramebuffers(GLsizei n, GLuint* framebuffers)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGenFramebuffers(n, framebuffers);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGenRenderbuffers(n, renderbuffers);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGenTextures(GLsizei n, GLuint* textures)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGenTextures(n, textures);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetActiveAttrib(program, index, bufsize, length, size, type, name);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetActiveUniform(program, index, bufsize, length, size, type, name);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetAttachedShaders(program, maxcount, count, shaders);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static int
-evgl_glGetAttribLocation(GLuint program, const char* name)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   int location;
-
-   location = _sym_glGetAttribLocation(program, name);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return location;
-}
-
-static void
-evgl_glGetBooleanv(GLenum pname, GLboolean* params)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetBooleanv(pname, params);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetBufferParameteriv(target, pname, params);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static GLenum
-evgl_glGetError(void)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   return _sym_glGetError();
-}
-
-static void
-evgl_glGetFloatv(GLenum pname, GLfloat* params)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetFloatv(pname, params);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetIntegerv(GLenum pname, GLint* params)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetIntegerv(pname, params);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetProgramiv(GLuint program, GLenum pname, GLint* params)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetProgramiv(program, pname, params);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetProgramInfoLog(program, bufsize, length, infolog);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetRenderbufferParameteriv(target, pname, params);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetShaderiv(shader, pname, params);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetShaderInfoLog(shader, bufsize, length, infolog);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   _sym_glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-#else
-   if (range)
-     {
-        range[0] = -126; // floor(log2(FLT_MIN))
-        range[1] = 127; // floor(log2(FLT_MAX))
-     }
-   if (precision)
-     {
-        precision[0] = 24; // floor(-log2((1.0/16777218.0)));
-     }
-   return;
-   shadertype = precisiontype = 0;
-#endif
-
-}
-
-static void
-evgl_glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetShaderSource(shader, bufsize, length, source);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static const GLubyte *
-evgl_glGetString(GLenum name)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   const GLubyte *str;
-
-   str =_sym_glGetString(name);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return str;
-}
-
-static void
-evgl_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetTexParameterfv(target, pname, params);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetTexParameteriv(target, pname, params);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetUniformfv(GLuint program, GLint location, GLfloat* params)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetUniformfv(program, location, params);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glGetUniformiv(GLuint program, GLint location, GLint* params)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetUniformiv(program, location, params);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static int
-evgl_glGetUniformLocation(GLuint program, const char* name)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   int location;
-
-   location = _sym_glGetUniformLocation(program, name);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return location;
-}
-
-static GLboolean
-evgl_glIsBuffer(GLuint buffer)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   GLboolean result;
-
-   result =  _sym_glIsBuffer(buffer);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return result;
-}
-
-static GLboolean
-evgl_glIsEnabled(GLenum cap)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   GLboolean result;
-
-   result =  _sym_glIsEnabled(cap);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return result;
-}
-
-static GLboolean
-evgl_glIsFramebuffer(GLuint framebuffer)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   GLboolean result;
-
-   result = _sym_glIsFramebuffer(framebuffer);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return result;
-}
-
-static GLboolean
-evgl_glIsProgram(GLuint program)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   GLboolean result;
-
-   result =  _sym_glIsProgram(program);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return result;
-}
-
-static GLboolean
-evgl_glIsRenderbuffer(GLuint renderbuffer)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   GLboolean result;
-
-   result =  _sym_glIsRenderbuffer(renderbuffer);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return result;
-}
-
-static GLboolean
-evgl_glIsShader(GLuint shader)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   GLboolean result;
-
-   result =  _sym_glIsShader(shader);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return result;
-}
-
-static GLboolean
-evgl_glIsTexture(GLuint texture)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   GLboolean result;
-
-   result = _sym_glIsTexture(texture);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-
-   return result;
-}
-
-static void
-evgl_glLineWidth(GLfloat width)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glLineWidth(width);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glLinkProgram(GLuint program)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glLinkProgram(program);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glPixelStorei(GLenum pname, GLint param)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glPixelStorei(pname, param);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glPolygonOffset(GLfloat factor, GLfloat units)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glPolygonOffset(factor, units);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glReadPixels(x, y, width, height, format, type, pixels);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glReleaseShaderCompiler(void)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   _sym_glReleaseShaderCompiler();
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-#else
-   //FIXME!!! need something here?
-
-#endif
-}
-
-static void
-evgl_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glRenderbufferStorage(target, internalformat, width, height);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glSampleCoverage(GLclampf value, GLboolean invert)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glSampleCoverage(value, invert);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glScissor(x, y, width, height);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   _sym_glShaderBinary(n, shaders, binaryformat, binary, length);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-#else
-// FIXME: need to dlsym/getprocaddress for this
-   return;
-/*
-   n = binaryformat = length = 0;
-   shaders = binary = 0;
-*/
-#endif
-}
-
-static void
-evgl_glShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glShaderSource(shader, count, string, length);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glStencilFunc(GLenum func, GLint ref, GLuint mask)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glStencilFunc(func, ref, mask);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glStencilFuncSeparate(face, func, ref, mask);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glStencilMask(GLuint mask)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glStencilMask(mask);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glStencilMaskSeparate(GLenum face, GLuint mask)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glStencilMaskSeparate(face, mask);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glStencilOp(fail, zfail, zpass);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glStencilOpSeparate(face, fail, zfail, zpass);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glTexParameterf(GLenum target, GLenum pname, GLfloat param)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glTexParameterf(target, pname, param);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glTexParameterfv(target, pname, params);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glTexParameteri(GLenum target, GLenum pname, GLint param)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glTexParameteri(target, pname, param);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glTexParameteriv(target, pname, params);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniform1f(GLint location, GLfloat x)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniform1f(location, x);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniform1fv(location, count, v);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniform1i(GLint location, GLint x)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniform1i(location, x);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniform1iv(GLint location, GLsizei count, const GLint* v)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniform1iv(location, count, v);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniform2f(GLint location, GLfloat x, GLfloat y)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniform2f(location, x, y);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniform2fv(location, count, v);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniform2i(GLint location, GLint x, GLint y)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniform2i(location, x, y);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniform2iv(GLint location, GLsizei count, const GLint* v)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniform2iv(location, count, v);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniform3f(location, x, y, z);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniform3fv(location, count, v);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniform3i(GLint location, GLint x, GLint y, GLint z)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniform3i(location, x, y, z);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniform3iv(GLint location, GLsizei count, const GLint* v)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniform3iv(location, count, v);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniform4f(location, x, y, z, w);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniform4fv(location, count, v);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniform4i(location, x, y, z, w);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniform4iv(GLint location, GLsizei count, const GLint* v)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniform4iv(location, count, v);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniformMatrix2fv(location, count, transpose, value);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniformMatrix3fv(location, count, transpose, value);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUniformMatrix4fv(location, count, transpose, value);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glUseProgram(GLuint program)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glUseProgram(program);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glValidateProgram(GLuint program)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glValidateProgram(program);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glVertexAttrib1f(GLuint indx, GLfloat x)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glVertexAttrib1f(indx, x);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glVertexAttrib1fv(GLuint indx, const GLfloat* values)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glVertexAttrib1fv(indx, values);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glVertexAttrib2f(indx, x, y);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glVertexAttrib2fv(GLuint indx, const GLfloat* values)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glVertexAttrib2fv(indx, values);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glVertexAttrib3f(indx, x, y, z);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glVertexAttrib3fv(GLuint indx, const GLfloat* values)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glVertexAttrib3fv(indx, values);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glVertexAttrib4f(indx, x, y, z, w);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glVertexAttrib4fv(GLuint indx, const GLfloat* values)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glVertexAttrib4fv(indx, values);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glViewport(x, y, width, height);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-
-// GLES Extensions...
-static void
-evgl_glGetProgramBinary(GLuint program, GLsizei bufsize, GLsizei* length, GLenum* binaryFormat, void* binary)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glGetProgramBinary(program, bufsize, length, binaryFormat, binary);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-evgl_glProgramBinary(GLuint program, GLenum binaryFormat, const void* binary, GLint length)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glProgramBinary(program, binaryFormat, binary, length);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-
-static void
-evgl_glProgramParameteri(GLuint program, GLuint pname, GLint value)
-{
-   EVAS_GL_START_LOG(mc_log);
-
-   _sym_glProgramParameteri(program, pname, value);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-//----------------------------------------------------------------//
-//                                                                //
-//                      Fastpath GL Functions                     //
-// The functions have prefix 'fpgl_' for (fastpath gl)            //
-//                                                                //
-//----------------------------------------------------------------//
-
-#ifdef EVAS_GL_DEBUG
-   #define CURR_STATE_COMPARE(curr_state, state ) \
-      if (1)
-#else
-   #define CURR_STATE_COMPARE(curr_state, state ) \
-      if ((current_ctx->curr_state) != (state))
-#endif
-
-
-static void
-fpgl_glActiveTexture(GLenum texture)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   CURR_STATE_COMPARE(gl_active_texture, texture)
-     {
-        _sym_glActiveTexture(texture);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_tex_flag1 |= FLAG_BIT_1;
-        current_ctx->gl_active_texture = texture;
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glBindBuffer(GLenum target, GLuint buffer)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   if (target == GL_ARRAY_BUFFER)
-     {
-        CURR_STATE_COMPARE(gl_array_buffer_binding, buffer)
-          {
-             _sym_glBindBuffer(target, buffer);
-
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-             /*
-                if (buffer == 0)
-                current_ctx->_bind_flag &= (~FLAG_BIT_0);
-                else
-              */
-             current_ctx->_bind_flag |= FLAG_BIT_0;
-             current_ctx->gl_array_buffer_binding = buffer;
-          }
-     }
-   else if (target == GL_ELEMENT_ARRAY_BUFFER)
-     {
-        CURR_STATE_COMPARE(gl_element_array_buffer_binding, buffer)
-          {
-             _sym_glBindBuffer(target, buffer);
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-             /*
-                if (buffer == 0)
-                current_ctx->_bind_flag &= (~FLAG_BIT_1);
-                else
-              */
-             current_ctx->_bind_flag |= FLAG_BIT_1;
-             current_ctx->gl_element_array_buffer_binding = buffer;
-          }
-     }
-   else
-     {
-        // For error recording
-        _sym_glBindBuffer(target, buffer);
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glBindFramebuffer(GLenum target, GLuint framebuffer)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   if (target == GL_FRAMEBUFFER)
-     {
-        CURR_STATE_COMPARE(gl_framebuffer_binding, framebuffer)
-          {
-             _sym_glBindFramebuffer(target, framebuffer);
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-             /*
-                if (framebuffer == 0)
-                current_ctx->_bind_flag &= (~FLAG_BIT_2);
-                else
-              */
-             current_ctx->_bind_flag |= FLAG_BIT_2;
-             current_ctx->gl_framebuffer_binding = framebuffer;
-          }
-     }
-   else
-     {
-        // For error recording
-        _sym_glBindFramebuffer(target, framebuffer);
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   if (target == GL_RENDERBUFFER)
-     {
-        CURR_STATE_COMPARE(gl_renderbuffer_binding, renderbuffer)
-          {
-             _sym_glBindRenderbuffer(target, renderbuffer);
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-             if (renderbuffer == 0)
-                current_ctx->_bind_flag &= (~FLAG_BIT_3);
-             else
-                current_ctx->_bind_flag |= FLAG_BIT_3;
-             current_ctx->gl_renderbuffer_binding = renderbuffer;
-          }
-     }
-   else
-     {
-        // For error recording
-        _sym_glBindRenderbuffer(target, renderbuffer);
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glBindTexture(GLenum target, GLuint texture)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   int tex_idx;
-
-   tex_idx = current_ctx->gl_active_texture - GL_TEXTURE0;
-
-   EVAS_GL_DEBUG_ASSERT(tex_idx < MAX_TEXTURE_UNITS);
-
-   if (target == GL_TEXTURE_2D)
-     {
-        CURR_STATE_COMPARE(tex_2d_state[tex_idx], texture)
-          {
-             _sym_glBindTexture(target, texture);
-
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-             /*
-                if (texture == 0)
-                current_ctx->_tex_flag1 &= (~FLAG_BIT_3);
-                else
-              */
-             current_ctx->_tex_flag1 |= FLAG_BIT_3;
-
-             current_ctx->tex_2d_state[tex_idx] = texture;
-          }
-     }
-   else if (target == GL_TEXTURE_CUBE_MAP)
-     {
-        CURR_STATE_COMPARE(tex_cube_map_state[tex_idx], texture)
-          {
-             _sym_glBindTexture(target, texture);
-
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-             /*
-                if (texture == 0)
-                current_ctx->_tex_flag1 &= (~FLAG_BIT_4);
-                else
-              */
-             current_ctx->_tex_flag1 |= FLAG_BIT_4;
-
-             current_ctx->gl_texture_binding_cube_map = texture;
-
-             current_ctx->tex_cube_map_state[tex_idx] = texture;
-             //current_ctx->tex_state[tex_idx].tex_unit = GL_TEXTURE_CUBE_MAP;
-             //current_ctx->tex_state[tex_idx].tex_id = texture;
-          }
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   if ( COMPARE_OPT_SKIP
-       (current_ctx->gl_blend_color[0] != red) ||
-       (current_ctx->gl_blend_color[1] != green) ||
-       (current_ctx->gl_blend_color[2] != blue) ||
-       (current_ctx->gl_blend_color[3] != alpha))
-     {
-        _sym_glBlendColor(red, green, blue, alpha);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_blend_flag |= FLAG_BIT_0;
-        current_ctx->gl_blend_color[0] = red;
-        current_ctx->gl_blend_color[1] = green;
-        current_ctx->gl_blend_color[2] = blue;
-        current_ctx->gl_blend_color[3] = alpha;
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-//!!! Optimze?
-static void
-fpgl_glBlendEquation(GLenum mode)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   _sym_glBlendEquation(mode);
-
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   current_ctx->_blend_flag |= (FLAG_BIT_5 | FLAG_BIT_6);
-   _sym_glGetIntegerv(GL_BLEND_EQUATION_RGB,   (GLint*)&(current_ctx->gl_blend_equation_rgb));
-   _sym_glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&(current_ctx->gl_blend_equation_alpha));
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   if ( COMPARE_OPT_SKIP
-       (current_ctx->gl_blend_equation_rgb != modeRGB) ||
-       (current_ctx->gl_blend_equation_alpha != modeAlpha))
-     {
-        _sym_glBlendEquationSeparate(modeRGB, modeAlpha);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_blend_flag |= (FLAG_BIT_5 | FLAG_BIT_6);
-        current_ctx->gl_blend_equation_rgb    = modeRGB;
-        current_ctx->gl_blend_equation_alpha  = modeAlpha;
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-//!!! Optimze?
-static void
-fpgl_glBlendFunc(GLenum sfactor, GLenum dfactor)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   _sym_glBlendFunc(sfactor, dfactor);
-
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   current_ctx->_blend_flag |= (FLAG_BIT_1 | FLAG_BIT_2 | FLAG_BIT_3 | FLAG_BIT_4);
-   _sym_glGetIntegerv(GL_BLEND_SRC_RGB,   (GLint*)&(current_ctx->gl_blend_src_rgb));
-   _sym_glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&(current_ctx->gl_blend_src_alpha));
-   _sym_glGetIntegerv(GL_BLEND_DST_RGB,   (GLint*)&(current_ctx->gl_blend_dst_rgb));
-   _sym_glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&(current_ctx->gl_blend_dst_alpha));
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   if ( COMPARE_OPT_SKIP
-       (current_ctx->gl_blend_src_rgb != srcRGB) ||
-       (current_ctx->gl_blend_dst_rgb != dstRGB) ||
-       (current_ctx->gl_blend_src_alpha != srcAlpha) ||
-       (current_ctx->gl_blend_dst_alpha != dstAlpha))
-     {
-        _sym_glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_blend_flag |= (FLAG_BIT_1 | FLAG_BIT_2 | FLAG_BIT_3 | FLAG_BIT_4);
-        current_ctx->gl_blend_src_rgb   = srcRGB;
-        current_ctx->gl_blend_dst_rgb   = dstRGB;
-        current_ctx->gl_blend_src_alpha = srcAlpha;
-        current_ctx->gl_blend_dst_alpha = dstAlpha;
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   if ( COMPARE_OPT_SKIP
-       (current_ctx->gl_color_clear_value[0] != red) ||
-       (current_ctx->gl_color_clear_value[1] != green) ||
-       (current_ctx->gl_color_clear_value[2] != blue) ||
-       (current_ctx->gl_color_clear_value[3] != alpha))
-     {
-        _sym_glClearColor(red, green, blue, alpha);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_clear_flag1 |= (FLAG_BIT_2);
-        current_ctx->gl_color_clear_value[0] = red;
-        current_ctx->gl_color_clear_value[1] = green;
-        current_ctx->gl_color_clear_value[2] = blue;
-        current_ctx->gl_color_clear_value[3] = alpha;
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glClearDepthf(GLclampf depth)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   CURR_STATE_COMPARE(gl_depth_clear_value, depth)
-     {
-        _sym_glClearDepthf(depth);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_clear_flag2 |= FLAG_BIT_2;
-        current_ctx->gl_depth_clear_value = depth;
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glClearStencil(GLint s)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   CURR_STATE_COMPARE(gl_stencil_clear_value, s)
-     {
-        _sym_glClearStencil(s);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_stencil_flag2 |= FLAG_BIT_7;
-        current_ctx->gl_stencil_clear_value = s;
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   if ( COMPARE_OPT_SKIP
-       (current_ctx->gl_color_writemask[0] != red) ||
-       (current_ctx->gl_color_writemask[1] != green) ||
-       (current_ctx->gl_color_writemask[2] != blue) ||
-       (current_ctx->gl_color_writemask[3] != alpha))
-     {
-        _sym_glColorMask(red, green, blue, alpha);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_clear_flag2 |= FLAG_BIT_0;
-        current_ctx->gl_color_writemask[0] = red;
-        current_ctx->gl_color_writemask[1] = green;
-        current_ctx->gl_color_writemask[2] = blue;
-        current_ctx->gl_color_writemask[3] = alpha;
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glCullFace(GLenum mode)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   CURR_STATE_COMPARE(gl_cull_face_mode, mode)
-     {
-        _sym_glCullFace(mode);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_clear_flag2 |= FLAG_BIT_5;
-        current_ctx->gl_cull_face_mode = mode;
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glDepthFunc(GLenum func)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   CURR_STATE_COMPARE(gl_depth_func, func)
-     {
-        _sym_glDepthFunc(func);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_clear_flag2 |= FLAG_BIT_3;
-        current_ctx->gl_depth_func = func;
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glDepthMask(GLboolean flag)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   CURR_STATE_COMPARE(gl_depth_writemask, flag)
-     {
-        _sym_glDepthMask(flag);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_clear_flag2 |= FLAG_BIT_4;
-        current_ctx->gl_depth_writemask = flag;
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glDepthRangef(GLclampf zNear, GLclampf zFar)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   if ((current_ctx->gl_depth_range[0] != zNear) ||
-       (current_ctx->gl_depth_range[1] != zFar))
-     {
-        _sym_glDepthRangef(zNear, zFar);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_clear_flag2 |= FLAG_BIT_1;
-        current_ctx->gl_depth_range[0] = zNear;
-        current_ctx->gl_depth_range[1] = zFar;
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glDisable(GLenum cap)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   switch(cap)
-     {
-      case GL_BLEND:
-         CURR_STATE_COMPARE(gl_blend, GL_FALSE)
-           {
-              _sym_glDisable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-              current_ctx->_enable_flag1 &= (~FLAG_BIT_0);
-              current_ctx->gl_blend = GL_FALSE;
-           }
-         break;
-      case GL_CULL_FACE:
-         CURR_STATE_COMPARE(gl_cull_face, GL_FALSE)
-           {
-              _sym_glDisable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-              current_ctx->_enable_flag1 &= (~FLAG_BIT_1);
-              current_ctx->gl_cull_face = GL_FALSE;
-           }
-         break;
-      case GL_DEPTH_TEST:
-         CURR_STATE_COMPARE(gl_depth_test, GL_FALSE)
-           {
-              _sym_glDisable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-              current_ctx->_enable_flag1 &= (~FLAG_BIT_2);
-              current_ctx->gl_depth_test = GL_FALSE;
-           }
-         break;
-      case GL_DITHER:
-         CURR_STATE_COMPARE(gl_dither, GL_FALSE)
-           {
-              _sym_glDisable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-              current_ctx->_enable_flag1 &= (~FLAG_BIT_3);
-              current_ctx->gl_dither = GL_FALSE;
-           }
-         break;
-      case GL_POLYGON_OFFSET_FILL:
-         CURR_STATE_COMPARE(gl_polygon_offset_fill, GL_FALSE)
-           {
-              _sym_glDisable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-              current_ctx->_enable_flag2 &= (~FLAG_BIT_0);
-              current_ctx->gl_polygon_offset_fill = GL_FALSE;
-           }
-         break;
-      case GL_SAMPLE_ALPHA_TO_COVERAGE:
-         CURR_STATE_COMPARE(gl_sample_alpha_to_coverage, GL_FALSE)
-           {
-              _sym_glDisable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-              current_ctx->_enable_flag2 &= (~FLAG_BIT_1);
-              current_ctx->gl_sample_alpha_to_coverage = GL_FALSE;
-           }
-         break;
-      case GL_SAMPLE_COVERAGE:
-         CURR_STATE_COMPARE(gl_sample_coverage, GL_FALSE)
-           {
-              _sym_glDisable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-              current_ctx->_enable_flag2 &= (~FLAG_BIT_2);
-              current_ctx->gl_sample_coverage = GL_FALSE;
-           }
-         break;
-      case GL_SCISSOR_TEST:
-         CURR_STATE_COMPARE(gl_scissor_test, GL_FALSE)
-           {
-              _sym_glDisable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-              current_ctx->_enable_flag2 &= (~FLAG_BIT_3);
-              current_ctx->gl_scissor_test = GL_FALSE;
-           }
-         break;
-      case GL_STENCIL_TEST:
-         CURR_STATE_COMPARE(gl_stencil_test, GL_FALSE)
-           {
-              _sym_glDisable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-              current_ctx->_enable_flag2 &= (~FLAG_BIT_4);
-              current_ctx->gl_stencil_test = GL_FALSE;
-           }
-         break;
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glDisableVertexAttribArray(GLuint index)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-
-   _sym_glDisableVertexAttribArray(index);
-
-   EVAS_GL_DEBUG_ASSERT(index < MAX_VERTEX_ATTRIBS);
-
-   current_ctx->_vattrib_flag |= FLAG_BIT_1;
-   current_ctx->vertex_array[index].enabled    = GL_FALSE;
-   //current_ctx->vertex_array[index].modified   = GL_FALSE;
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glDrawArrays(GLenum mode, GLint first, GLsizei count)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   _sym_glDrawArrays(mode, first, count);
+        // Check Surface Cap
+        evgl_engine->caps.num_fbo_fmts = _surface_cap_check();
+        _surface_cap_cache_save();
+        DBG("Ran Evas GL Surface Cap and Cached the existing values.");
+     }
+   else
+     {
+        DBG("Loaded cached Evas GL Surface Cap values.");
+     }
 
-   EVAS_GL_END_LOG(mc_log);
+   if (evgl_engine->caps.num_fbo_fmts)
+     {
+        _surface_cap_print(0);
+        DBG("Number of supported surface formats: %d", evgl_engine->caps.num_fbo_fmts);
+        return 1;
+     }
+   else
+     {
+        ERR("There are no available surface formats. Error!");
+        return 0;
+     }
 }
 
-static void
-fpgl_glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices)
+static int
+_context_ext_check(EVGL_Context *ctx)
 {
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   _sym_glDrawElements(mode, count, type, indices);
+   int fbo_supported = 0;
+   int egl_image_supported = 0;
+   int texture_image_supported = 0;
 
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glEnable(GLenum cap)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
+   if (!ctx)
+      return 0;
 
+   if (ctx->extension_checked)
+      return 1;
 
-   switch(cap)
+#ifdef GL_GLES
+   switch (ctx->version)
      {
-      case GL_BLEND:
-         CURR_STATE_COMPARE(gl_blend, GL_TRUE)
-           {
-              _sym_glEnable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-              current_ctx->_enable_flag1 |= FLAG_BIT_0;
-              current_ctx->gl_blend = GL_TRUE;
-           }
-         break;
-      case GL_CULL_FACE:
-         CURR_STATE_COMPARE(gl_cull_face, GL_TRUE)
-           {
-              _sym_glEnable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-
-              current_ctx->_enable_flag1 |= FLAG_BIT_1;
-              current_ctx->gl_cull_face = GL_TRUE;
-           }
-         break;
-      case GL_DEPTH_TEST:
-         CURR_STATE_COMPARE(gl_depth_test, GL_TRUE)
-           {
-              _sym_glEnable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-
-              current_ctx->_enable_flag1 |= FLAG_BIT_2;
-              current_ctx->gl_depth_test = GL_TRUE;
-           }
-         break;
-      case GL_DITHER:
-         CURR_STATE_COMPARE(gl_dither, GL_TRUE)
-           {
-              _sym_glEnable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-              current_ctx->_enable_flag1 |= FLAG_BIT_3;
-              current_ctx->gl_dither = GL_TRUE;
-           }
-         break;
-      case GL_POLYGON_OFFSET_FILL:
-         CURR_STATE_COMPARE(gl_polygon_offset_fill, GL_TRUE)
-           {
-              _sym_glEnable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-
-              current_ctx->_enable_flag2 |= FLAG_BIT_0;
-              current_ctx->gl_polygon_offset_fill = GL_TRUE;
-           }
-         break;
-      case GL_SAMPLE_ALPHA_TO_COVERAGE:
-         CURR_STATE_COMPARE(gl_sample_alpha_to_coverage, GL_TRUE)
-           {
-              _sym_glEnable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-
-              current_ctx->_enable_flag2 |= FLAG_BIT_1;
-              current_ctx->gl_sample_alpha_to_coverage = GL_TRUE;
-           }
-         break;
-      case GL_SAMPLE_COVERAGE:
-         CURR_STATE_COMPARE(gl_sample_coverage, GL_TRUE)
-           {
-              _sym_glEnable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-
-              current_ctx->_enable_flag2 |= FLAG_BIT_2;
-              current_ctx->gl_sample_coverage = GL_TRUE;
-           }
-         break;
-      case GL_SCISSOR_TEST:
-         CURR_STATE_COMPARE(gl_scissor_test, GL_TRUE)
-           {
-              _sym_glEnable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-
-              current_ctx->_enable_flag2 |= FLAG_BIT_3;
-              current_ctx->gl_scissor_test = GL_TRUE;
-           }
-         break;
-      case GL_STENCIL_TEST:
-         CURR_STATE_COMPARE(gl_stencil_test, GL_TRUE)
-           {
-              _sym_glEnable(cap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-
-              current_ctx->_enable_flag2 |= FLAG_BIT_4;
-              current_ctx->gl_stencil_test = GL_TRUE;
-           }
+      case EVAS_GL_GLES_1_X:
+         if (EXTENSION_SUPPORT_GLES1(framebuffer_object))
+           fbo_supported = 1;
          break;
+      case EVAS_GL_GLES_2_X:
+      case EVAS_GL_GLES_3_X:
       default:
-         DBG("Unsupported GL Enable Cap: %d", cap);
+         fbo_supported = 1;
      }
 
-   EVAS_GL_END_LOG(mc_log);
-}
-
-// Optimze?
-static void
-fpgl_glEnableVertexAttribArray(GLuint index)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   _sym_glEnableVertexAttribArray(index);
-
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_DEBUG_ASSERT(index < MAX_VERTEX_ATTRIBS);
-
-   current_ctx->_vattrib_flag |= FLAG_BIT_1;
-   current_ctx->vertex_array[index].enabled    = GL_TRUE;
-   //current_ctx->vertex_array[index].modified   = GL_FALSE;
-
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glFrontFace(GLenum mode)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
+   if (EXTENSION_SUPPORT(EGL_KHR_image_base))
+     egl_image_supported = 1;
 
+   if (EXTENSION_SUPPORT(EGL_KHR_gl_texture_2D_image))
+     texture_image_supported = 1;
+#else
+   fbo_supported = 1;
+   egl_image_supported = 0;
+   texture_image_supported = 0;
+#endif
 
-   CURR_STATE_COMPARE(gl_front_face, mode)
+   if (egl_image_supported)
      {
-        _sym_glFrontFace(mode);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_misc_flag1 |= FLAG_BIT_0;
-        current_ctx->gl_front_face = mode;
+        if (fbo_supported && texture_image_supported)
+          ctx->fbo_image_supported = 1;
+        else
+          ctx->pixmap_image_supported = 1;
      }
 
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   _sym_glGetVertexAttribfv(index, pname, params);
-
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
+   ctx->extension_checked = 1;
 
-
-   _sym_glGetVertexAttribiv(index, pname, params);
-
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
+   return 1;
 }
 
-static void
-fpgl_glGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   _sym_glGetVertexAttribPointerv(index, pname, pointer);
-
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_END_LOG(mc_log);
+static const char *
+_glenum_string_get(GLenum e)
+{
+   switch (e)
+     {
+      case 0:
+         return "0";
+      case GL_RGB:
+         return "GL_RGB";
+      case GL_RGBA:
+         return "GL_RGBA";
+
+#ifdef GL_GLES
+         // Depth
+      case GL_DEPTH_COMPONENT:
+         return "GL_DEPTH_COMPONENT";
+      case GL_DEPTH_COMPONENT16:
+         return "GL_DEPTH_COMPONENT16";
+      case GL_DEPTH_COMPONENT24_OES:
+         return "GL_DEPTH_COMPONENT24_OES";
+
+         // Stencil
+      case GL_STENCIL_INDEX1_OES:
+         return "GL_STENCIL_INDEX1_OES";
+      case GL_STENCIL_INDEX4_OES:
+         return "GL_STENCIL_INDEX4_OES";
+      case GL_STENCIL_INDEX8:
+         return "GL_STENCIL_INDEX8";
+
+         // Depth_Stencil
+      case GL_DEPTH_STENCIL_OES:
+         return "GL_DEPTH_STENCIL_OES";
+#else
+         // Depth
+      case GL_DEPTH_COMPONENT:
+         return "GL_DEPTH_COMPONENT";
+      case GL_DEPTH_COMPONENT16:
+         return "GL_DEPTH_COMPONENT16";
+      case GL_DEPTH_COMPONENT24:
+         return "GL_DEPTH_COMPONENT24";
+      case GL_DEPTH_COMPONENT32:
+         return "GL_DEPTH_COMPONENT32";
+
+         // Stencil
+      case GL_STENCIL_INDEX:
+         return "GL_STENCIL_INDEX";
+      case GL_STENCIL_INDEX1:
+         return "GL_STENCIL_INDEX1";
+      case GL_STENCIL_INDEX4:
+         return "GL_STENCIL_INDEX4";
+      case GL_STENCIL_INDEX8:
+         return "GL_STENCIL_INDEX8";
+
+         // Depth_Stencil
+      case GL_DEPTH24_STENCIL8:
+         return "GL_DEPTH24_STENCIL8";
+#endif
+      default:
+         return "ERR";
+     }
 }
 
-// Fix Maybe?
 static void
-fpgl_glHint(GLenum target, GLenum mode)
+_surface_cap_print(int error)
 {
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   if (target == GL_GENERATE_MIPMAP_HINT)
-     {
-        CURR_STATE_COMPARE(gl_generate_mipmap_hint, mode)
-          {
-             _sym_glHint(target, mode);
-
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-             current_ctx->_tex_flag1 |= FLAG_BIT_2;
-             current_ctx->gl_generate_mipmap_hint = mode;
-          }
+   int i = 0;
+#define PRINT_LOG(...) \
+   if (error) \
+      ERR(__VA_ARGS__); \
+   else \
+      DBG(__VA_ARGS__);
+
+   PRINT_LOG("----------------------------------------------------------------------------------------------------------------");
+   PRINT_LOG("                 Evas GL Supported Surface Format                                                               ");
+   PRINT_LOG("----------------------------------------------------------------------------------------------------------------\n");
+   PRINT_LOG(" Max Surface Width: %d Height: %d", evgl_engine->caps.max_w, evgl_engine->caps.max_h);
+   PRINT_LOG(" Multisample Support: %d", evgl_engine->caps.msaa_supported);
+   //if (evgl_engine->caps.msaa_supported)
+     {
+        PRINT_LOG("             Low  Samples: %d", evgl_engine->caps.msaa_samples[0]);
+        PRINT_LOG("             Med  Samples: %d", evgl_engine->caps.msaa_samples[1]);
+        PRINT_LOG("             High Samples: %d", evgl_engine->caps.msaa_samples[2]);
+     }
+   PRINT_LOG("[Index] [Color Format]  [------Depth Bits------]      [----Stencil Bits---]     [---Depth_Stencil---]  [Samples]");
+
+#define PRINT_SURFACE_CAP(IDX, COLOR, DEPTH, STENCIL, DS, SAMPLE) \
+     { \
+        PRINT_LOG("  %3d  %10s    %25s  %25s  %25s  %5d", IDX, _glenum_string_get(COLOR), _glenum_string_get(DEPTH), _glenum_string_get(STENCIL), _glenum_string_get(DS), SAMPLE ); \
      }
-   else
+
+   for (i = 0; i < evgl_engine->caps.num_fbo_fmts; ++i)
      {
-        // For GL Error to be picked up
-        _sym_glHint(target, mode);
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        EVGL_Surface_Format *fmt = &evgl_engine->caps.fbo_fmts[i];
+        PRINT_SURFACE_CAP(i, fmt->color_fmt, fmt->depth_fmt, fmt->stencil_fmt, fmt->depth_stencil_fmt, fmt->samples);
      }
 
-   EVAS_GL_END_LOG(mc_log);
+#undef PRINT_SURFACE_CAP
+#undef PRINT_LOG
 }
 
 static void
-fpgl_glLineWidth(GLfloat width)
+_surface_context_list_print()
 {
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   CURR_STATE_COMPARE(gl_line_width, width)
-     {
-        _sym_glLineWidth(width);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   Eina_List *l;
+   EVGL_Surface *s;
+   EVGL_Context *c;
+   int count = 0;
 
-        current_ctx->_misc_flag1 |= FLAG_BIT_1;
-        current_ctx->gl_line_width = width;
-     }
+   // Only print them when the log level is 6
+   if (_evas_gl_log_level < 6) return;
 
-   EVAS_GL_END_LOG(mc_log);
-}
+#define RESET "\e[m"
+#define GREEN "\e[1;32m"
+#define YELLOW "\e[1;33m"
+#define RED "\e[1;31m"
 
-static void
-fpgl_glPixelStorei(GLenum pname, GLint param)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
+   LKL(evgl_engine->lck);
 
+   DBG( YELLOW "-----------------------------------------------" RESET);
+   DBG("Total Number of active Evas GL Surfaces: %d", eina_list_count(evgl_engine->surfaces));
 
-   if (pname == GL_PACK_ALIGNMENT)
+   EINA_LIST_FOREACH(evgl_engine->surfaces, l, s)
      {
-        CURR_STATE_COMPARE(gl_pack_alignment, param)
-          {
-             _sym_glPixelStorei(pname, param);
-
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        DBG( YELLOW "\t-----------------------------------------------" RESET);
+        DBG( RED "\t[Surface %d]" YELLOW " Ptr: %p" RED " Appx Mem: %d Byte", count++, s, (s->buffer_mem[0]+s->buffer_mem[1]+s->buffer_mem[2]+s->buffer_mem[3]));
+        DBG( GREEN "\t\t Size:" RESET " (%d, %d)",  s->w, s->h);
 
-             current_ctx->_misc_flag2 |= FLAG_BIT_1;
-             current_ctx->gl_pack_alignment = param;
+        if (s->buffer_mem[0])
+          {
+             DBG( GREEN "\t\t Color Format:" RESET " %s", _glenum_string_get(s->color_fmt));
+             DBG( GREEN "\t\t Color Buffer Appx. Mem Usage:" RESET " %d Byte", s->buffer_mem[0]);
           }
-     }
-   else if (pname == GL_UNPACK_ALIGNMENT)
-     {
-        CURR_STATE_COMPARE(gl_unpack_alignment, param)
+        if (s->buffer_mem[1])
           {
-             _sym_glPixelStorei(pname, param);
-
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-             current_ctx->_misc_flag2 |= FLAG_BIT_2;
-             current_ctx->gl_unpack_alignment = param;
+             DBG( GREEN "\t\t Depth Format:" RESET " %s", _glenum_string_get(s->depth_fmt));
+             DBG( GREEN "\t\t Depth Buffer Appx. Mem Usage: " RESET "%d Byte", s->buffer_mem[1]);
           }
+        if (s->buffer_mem[2])
+          {
+             DBG( GREEN "\t\t Stencil Format:" RESET " %s", _glenum_string_get(s->stencil_fmt));
+             DBG( GREEN "\t\t Stencil Buffer Appx. Mem Usage:" RESET " %d Byte", s->buffer_mem[2]);
+          }
+        if (s->buffer_mem[3])
+          {
+             DBG( GREEN "\t\t D-Stencil Format:" RESET " %s", _glenum_string_get(s->depth_stencil_fmt));
+             DBG( GREEN "\t\t D-Stencil Buffer Appx. Mem Usage:" RESET " %d Byte", s->buffer_mem[3]);
+          }
+        if (s->msaa_samples)
+           DBG( GREEN "\t\t MSAA Samples:" RESET " %d", s->msaa_samples);
+        if (s->direct_fb_opt)
+           DBG( GREEN "\t\t Direct Option Enabled" RESET );
+        DBG( YELLOW "\t-----------------------------------------------" RESET);
      }
-   else
-     {
-        // For GL Error to be picked up
-        _sym_glPixelStorei(pname, param);
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glPolygonOffset(GLfloat factor, GLfloat units)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
 
+   count = 0;
 
-   if ( COMPARE_OPT_SKIP
-       (current_ctx->gl_polygon_offset_factor != factor) ||
-       (current_ctx->gl_polygon_offset_units != units))
+   DBG( YELLOW "-----------------------------------------------" RESET);
+   DBG("Total Number of active Evas GL Contexts: %d", eina_list_count(evgl_engine->contexts));
+   EINA_LIST_FOREACH(evgl_engine->contexts, l, c)
      {
-        _sym_glPolygonOffset(factor, units);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_misc_flag1 |= (FLAG_BIT_2 | FLAG_BIT_3);
-        current_ctx->gl_polygon_offset_factor = factor;
-        current_ctx->gl_polygon_offset_units  = units;
+        DBG( YELLOW "\t-----------------------------------------------" RESET);
+        DBG( RED "\t[Context %d]" YELLOW " Ptr: %p", count++, c);
      }
+   DBG( YELLOW "-----------------------------------------------" RESET);
+
+   LKU(evgl_engine->lck);
 
-   EVAS_GL_END_LOG(mc_log);
+#undef RESET
+#undef GREEN
+#undef YELLOW
+#undef RED
 }
 
-static void
-fpgl_glSampleCoverage(GLclampf value, GLboolean invert)
+//--------------------------------------------------------//
+// Start from here.....
+//--------------------------------------------------------//
+static int
+_surface_buffers_fbo_set(EVGL_Surface *sfc, GLuint fbo, Eina_Bool use_extension)
 {
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
+   int status;
 
+   _framebuffer_bind(fbo, use_extension);
 
-   if ( COMPARE_OPT_SKIP
-       (current_ctx->gl_sample_coverage_value != value) ||
-       (current_ctx->gl_sample_coverage_invert != invert))
-     {
-        _sym_glSampleCoverage(value, invert);
+   // Detach any previously attached buffers
+   _texture_attach_2d(0, GL_COLOR_ATTACHMENT0, 0, 0, use_extension);
+   _renderbuffer_attach(0, GL_DEPTH_ATTACHMENT, use_extension);
+   _renderbuffer_attach(0, GL_STENCIL_ATTACHMENT, use_extension);
+#ifdef GL_GLES
+   _texture_attach_2d(0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT, 0, use_extension);
+#else
+    _renderbuffer_attach(0, GL_DEPTH_STENCIL_ATTACHMENT, use_extension);
+#endif
 
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   // Render Target Texture
+   if (sfc->color_buf)
+     _texture_attach_2d(sfc->color_buf, GL_COLOR_ATTACHMENT0, 0, sfc->msaa_samples, use_extension);
 
-        current_ctx->_misc_flag1 |= (FLAG_BIT_4 | FLAG_BIT_5);
-        current_ctx->gl_sample_coverage_value  = value;
-        current_ctx->gl_sample_coverage_invert = invert;
+   // Depth Stencil RenderBuffer - Attach it to FBO
+   if (sfc->depth_stencil_buf)
+     {
+#ifdef GL_GLES
+        _texture_attach_2d(sfc->depth_stencil_buf, GL_DEPTH_ATTACHMENT,
+                           GL_STENCIL_ATTACHMENT, sfc->msaa_samples, use_extension);
+#else
+        _renderbuffer_attach(sfc->depth_stencil_buf, GL_DEPTH_STENCIL_ATTACHMENT, use_extension);
+#endif
      }
 
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
+   // Depth RenderBuffer - Attach it to FBO
+   if (sfc->depth_buf)
+     _renderbuffer_attach(sfc->depth_buf, GL_DEPTH_ATTACHMENT, use_extension);
 
+   // Stencil RenderBuffer - Attach it to FBO
+   if (sfc->stencil_buf)
+     _renderbuffer_attach(sfc->stencil_buf, GL_STENCIL_ATTACHMENT, use_extension);
 
-   if ( COMPARE_OPT_SKIP
-       (current_ctx->gl_scissor_box[0] != x) ||
-       (current_ctx->gl_scissor_box[1] != y) ||
-       (current_ctx->gl_scissor_box[2] != width) ||
-       (current_ctx->gl_scissor_box[3] != height))
+   // Check FBO for completeness
+   status = _framebuffer_check(use_extension);
+   if (status != GL_FRAMEBUFFER_COMPLETE)
      {
-        _sym_glScissor(x, y, width, height);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_misc_flag2 |= FLAG_BIT_0;
-        current_ctx->gl_scissor_box[0] = x;
-        current_ctx->gl_scissor_box[1] = y;
-        current_ctx->gl_scissor_box[2] = width;
-        current_ctx->gl_scissor_box[3] = height;
+        ERR("FBO not complete. Error Code: %x!", status);
+        return 0;
      }
 
-   EVAS_GL_END_LOG(mc_log);
+   return 1;
 }
 
-static void
-fpgl_glStencilFunc(GLenum func, GLint ref, GLuint mask)
+static int
+_surface_buffers_create(EVGL_Surface *sfc)
 {
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   if ( COMPARE_OPT_SKIP
-       (current_ctx->gl_stencil_func != func) ||
-       (current_ctx->gl_stencil_ref != ref) ||
-       (current_ctx->gl_stencil_value_mask != mask) ||
-       (current_ctx->gl_stencil_back_func != func) ||
-       (current_ctx->gl_stencil_back_ref != ref) ||
-       (current_ctx->gl_stencil_back_value_mask != mask))
+   // Create buffers
+   if (sfc->color_fmt)
      {
-        _sym_glStencilFunc(func, ref, mask);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_stencil_flag1 |= (FLAG_BIT_0 | FLAG_BIT_1 | FLAG_BIT_2);
-        current_ctx->gl_stencil_func             = func;
-        current_ctx->gl_stencil_ref              = ref;
-        current_ctx->gl_stencil_value_mask       = mask;
-
-        current_ctx->_stencil_flag2 |= (FLAG_BIT_0 | FLAG_BIT_1 | FLAG_BIT_2);
-        current_ctx->gl_stencil_back_func        = func;
-        current_ctx->gl_stencil_back_ref         = ref;
-        current_ctx->gl_stencil_back_value_mask  = mask;
+        _texture_create(&sfc->color_buf);
      }
 
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
 
-   if ((face == GL_FRONT) || (face == GL_FRONT_AND_BACK))
+   // Depth_stencil buffers or separate buffers
+   if (sfc->depth_stencil_fmt)
      {
-        if ( COMPARE_OPT_SKIP
-            (current_ctx->gl_stencil_func != func) ||
-            (current_ctx->gl_stencil_ref != ref) ||
-            (current_ctx->gl_stencil_value_mask != mask))
-          {
-             _sym_glStencilFuncSeparate(face, func, ref, mask);
-
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-             current_ctx->_stencil_flag1 |= (FLAG_BIT_0 | FLAG_BIT_1 | FLAG_BIT_2);
-
-             current_ctx->gl_stencil_func             = func;
-             current_ctx->gl_stencil_ref              = ref;
-             current_ctx->gl_stencil_value_mask       = mask;
-          }
+#ifdef GL_GLES
+        _texture_create(&sfc->depth_stencil_buf);
+#else
+        _renderbuffer_create(&sfc->depth_stencil_buf);
+#endif
      }
-
-   if ((face == GL_BACK) || (face == GL_FRONT_AND_BACK))
+   else
      {
-        if ( COMPARE_OPT_SKIP
-            (current_ctx->gl_stencil_back_func != func) ||
-            (current_ctx->gl_stencil_back_ref != ref) ||
-            (current_ctx->gl_stencil_back_value_mask != mask))
+        if (sfc->depth_fmt)
           {
-             _sym_glStencilFuncSeparate(face, func, ref, mask);
-
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-             current_ctx->_stencil_flag2 |= (FLAG_BIT_0 | FLAG_BIT_1 | FLAG_BIT_2);
-
-             current_ctx->gl_stencil_back_func        = func;
-             current_ctx->gl_stencil_back_ref         = ref;
-             current_ctx->gl_stencil_back_value_mask  = mask;
+             _renderbuffer_create(&sfc->depth_buf);
+          }
+        if (sfc->stencil_fmt)
+          {
+             _renderbuffer_create(&sfc->stencil_buf);
           }
      }
 
-   EVAS_GL_END_LOG(mc_log);
+   return 1; //ret;
 }
 
-static void
-fpgl_glStencilMask(GLuint mask)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   if ( COMPARE_OPT_SKIP
-       (current_ctx->gl_stencil_writemask != mask) ||
-       (current_ctx->gl_stencil_back_writemask != mask))
-     {
-        _sym_glStencilMask(mask);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_stencil_flag1 |= (FLAG_BIT_6);
-        current_ctx->_stencil_flag2 |= (FLAG_BIT_6);
-
-        current_ctx->gl_stencil_writemask        = mask;
-        current_ctx->gl_stencil_back_writemask   = mask;
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
 
-static void
-fpgl_glStencilMaskSeparate(GLenum face, GLuint mask)
+static int
+_surface_buffers_allocate(void *eng_data, EVGL_Surface *sfc, int w, int h, int mc)
 {
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
+   // Set the context current with resource context/surface
+   if (mc)
+      if (!_internal_resource_make_current(eng_data, NULL))
+        {
+           ERR("Error doing an internal resource make current");
+           return 0;
+        }
 
-   if ((face == GL_FRONT) || (face == GL_FRONT_AND_BACK))
+   // Create buffers
+   if (sfc->color_fmt)
      {
-        if ( COMPARE_OPT_SKIP
-           current_ctx->gl_stencil_writemask != mask)
+        if (sfc->native_buf)
           {
-             _sym_glStencilMaskSeparate(face, mask);
-
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+             if (sfc->native_img)
+               {
+                  evgl_engine->funcs->native_buffer_image_destroy(eng_data, sfc->native_img);
+                  sfc->native_img = NULL;
+               }
 
-             current_ctx->_stencil_flag1 |= (FLAG_BIT_6);
-             current_ctx->gl_stencil_writemask = mask;
+             if ((w>0) && (h>0))
+               {
+                  sfc->native_img = evgl_engine->funcs->native_buffer_image_create(eng_data, sfc->color_buf, sfc->native_tar, sfc->native_buf);
+                  if (!sfc->native_img)
+                    {
+                       ERR("Error allocating image from native buffer.");
+                       return 0;
+                    }
+                  DBG("Using user provided pixmap for FBO->eglImage for rendering instead of FBO->texture");
+               }
+             if ((sfc->current_ctx) && (sfc->current_ctx->fbo_image_supported))
+               sfc->egl_image = sfc->native_img;
           }
-     }
-
-   if ((face == GL_BACK) || (face == GL_FRONT_AND_BACK))
-     {
-        if ( COMPARE_OPT_SKIP
-            current_ctx->gl_stencil_back_writemask != mask)
+        else
           {
-             _sym_glStencilMaskSeparate(face, mask);
-
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-             current_ctx->_stencil_flag2 |= (FLAG_BIT_6);
-             current_ctx->gl_stencil_back_writemask   = mask;
+             _texture_allocate_2d(sfc->color_buf, sfc->color_ifmt, sfc->color_fmt,
+                                  GL_UNSIGNED_BYTE, w, h);
+             if ((sfc->current_ctx) && (sfc->current_ctx->fbo_image_supported))
+               sfc->egl_image = _egl_image_create(sfc->current_ctx, EGL_GL_TEXTURE_2D_KHR, (void *)(uintptr_t)sfc->color_buf);
           }
-     }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
 
+        sfc->buffer_mem[0] = w * h * 4;
+     }
 
-   if ( COMPARE_OPT_SKIP
-       (current_ctx->gl_stencil_fail != fail) ||
-       (current_ctx->gl_stencil_pass_depth_fail != zfail) ||
-       (current_ctx->gl_stencil_pass_depth_pass != zpass) ||
-       (current_ctx->gl_stencil_back_fail != fail) ||
-       (current_ctx->gl_stencil_back_pass_depth_fail != zfail) ||
-       (current_ctx->gl_stencil_back_pass_depth_pass != zpass))
+   // Depth_stencil buffers or separate buffers
+   if (sfc->depth_stencil_fmt)
      {
-        _sym_glStencilOp(fail, zfail, zpass);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_stencil_flag1 |= (FLAG_BIT_3 | FLAG_BIT_4 | FLAG_BIT_5);
-        current_ctx->gl_stencil_fail              = fail;
-        current_ctx->gl_stencil_pass_depth_fail   = zfail;
-        current_ctx->gl_stencil_pass_depth_pass   = zpass;
-
-        current_ctx->_stencil_flag2 |= (FLAG_BIT_3 | FLAG_BIT_4 | FLAG_BIT_5);
-        current_ctx->gl_stencil_back_fail         = fail;
-        current_ctx->gl_stencil_back_pass_depth_fail   = zfail;
-        current_ctx->gl_stencil_back_pass_depth_pass   = zpass;
+#ifdef GL_GLES
+        _texture_allocate_2d(sfc->depth_stencil_buf, sfc->depth_stencil_fmt,
+                             sfc->depth_stencil_fmt, GL_UNSIGNED_INT_24_8_OES,
+                             w, h);
+#else
+        _renderbuffer_allocate(sfc->depth_stencil_buf, sfc->depth_stencil_fmt,
+                               w, h, sfc->msaa_samples);
+#endif
+        sfc->buffer_mem[3] = w * h * 4;
      }
-
-   EVAS_GL_END_LOG(mc_log);
-}
-
-static void
-fpgl_glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-
-   if ((face == GL_FRONT) || (face == GL_FRONT_AND_BACK))
+   else
      {
-        if ( COMPARE_OPT_SKIP
-            (current_ctx->gl_stencil_fail != fail) ||
-            (current_ctx->gl_stencil_pass_depth_fail != zfail) ||
-            (current_ctx->gl_stencil_pass_depth_pass != zpass))
+        if (sfc->depth_fmt)
           {
-             _sym_glStencilOpSeparate(face, fail, zfail, zpass);
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-             current_ctx->_stencil_flag1 |= (FLAG_BIT_3 | FLAG_BIT_4 | FLAG_BIT_5);
-             current_ctx->gl_stencil_fail              = fail;
-             current_ctx->gl_stencil_pass_depth_fail   = zfail;
-             current_ctx->gl_stencil_pass_depth_pass   = zpass;
+             _renderbuffer_allocate(sfc->depth_buf, sfc->depth_fmt, w, h,
+                                    sfc->msaa_samples);
+             sfc->buffer_mem[1] = w * h * 3; // Assume it's 24 bits
           }
-     }
-
-   if ((face == GL_BACK) || (face == GL_FRONT_AND_BACK))
-     {
-        if ( COMPARE_OPT_SKIP
-            (current_ctx->gl_stencil_back_fail != fail) ||
-            (current_ctx->gl_stencil_back_pass_depth_fail != zfail) ||
-            (current_ctx->gl_stencil_back_pass_depth_pass != zpass))
+        if (sfc->stencil_fmt)
           {
-             _sym_glStencilOpSeparate(face, fail, zfail, zpass);
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-             current_ctx->_stencil_flag2 |= (FLAG_BIT_3 | FLAG_BIT_4 | FLAG_BIT_5);
-             current_ctx->gl_stencil_back_fail         = fail;
-             current_ctx->gl_stencil_back_pass_depth_fail   = zfail;
-             current_ctx->gl_stencil_back_pass_depth_pass   = zpass;
+             _renderbuffer_allocate(sfc->stencil_buf, sfc->stencil_fmt, w,
+                                    h, sfc->msaa_samples);
+             sfc->buffer_mem[2] = w * h; // Assume it's 8 bits
           }
      }
-   else
-     {
-        // For picking up error purpose
-        _sym_glStencilOpSeparate(face, fail, zfail, zpass);
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-     }
 
-   EVAS_GL_END_LOG(mc_log);
+   return 1; //ret;
 }
 
-static void
-fpgl_glUseProgram(GLuint program)
+static int
+_surface_buffers_destroy(void *eng_data, EVGL_Surface *sfc)
 {
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   CURR_STATE_COMPARE(gl_current_program, program)
+   if (sfc->egl_image)
      {
-        _sym_glUseProgram(program);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_clear_flag1 |= FLAG_BIT_1;
-        current_ctx->gl_current_program = program;
+        _egl_image_destroy(sfc->egl_image);
+        sfc->egl_image = NULL;
+     }
+   if (sfc->color_buf)
+     {
+        if (sfc->native_img)
+           evgl_engine->funcs->native_buffer_image_destroy(eng_data, sfc->native_img);
+        evgl_engine->funcs->texture_destroyed_cb(eng_data, sfc->color_buf);
+        _texture_destroy(&sfc->color_buf);
+     }
+   if (sfc->depth_buf)
+      _renderbuffer_destroy(&sfc->depth_buf);
+   if (sfc->stencil_buf)
+      _renderbuffer_destroy(&sfc->stencil_buf);
+   if (sfc->depth_stencil_buf)
+     {
+#ifdef GL_GLES
+        _texture_destroy(&sfc->depth_stencil_buf);
+#else
+        _renderbuffer_destroy(&sfc->depth_stencil_buf);
+#endif
      }
 
-   EVAS_GL_END_LOG(mc_log);
-}
-
-// Optmize?
-static void
-fpgl_glVertexAttrib1f(GLuint index, GLfloat x)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
-
-   _sym_glVertexAttrib1f(index, x);
-
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_DEBUG_ASSERT(index < MAX_VERTEX_ATTRIBS);
-
-   current_ctx->_vattrib_flag |= FLAG_BIT_0;
-   current_ctx->vertex_attrib[index].modified = GL_TRUE;
-   current_ctx->vertex_attrib[index].value[0] = x;
-   current_ctx->vertex_attrib[index].value[1] = 0;
-   current_ctx->vertex_attrib[index].value[2] = 0;
-   current_ctx->vertex_attrib[index].value[3] = 1;
-
-   EVAS_GL_END_LOG(mc_log);
+   return 1;
 }
 
-// Optmize?
-static void
-fpgl_glVertexAttrib1fv(GLuint index, const GLfloat* values)
+static int
+_internal_config_set(void *eng_data, EVGL_Surface *sfc, Evas_GL_Config *cfg)
 {
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
+   int i = 0, cfg_index = -1;
+   int color_bit = 0, depth_bit = 0, stencil_bit = 0, msaa_samples = 0;
+   int depth_size = 0;
+   int support_win_cfg = 1;
 
-   _sym_glVertexAttrib1fv(index, values);
-
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   // Check if engine is valid
+   if (!evgl_engine)
+     {
+        ERR("Invalid EVGL Engine!");
+        return 0;
+     }
 
-   EVAS_GL_DEBUG_ASSERT(index < MAX_VERTEX_ATTRIBS);
+   // Convert Config Format to bitmask friendly format
+   color_bit = (1 << cfg->color_format);
+   if (cfg->depth_bits)
+     {
+        depth_bit = (1 << (cfg->depth_bits-1));
+        depth_size = 8 * cfg->depth_bits;
+     }
+   if (cfg->stencil_bits) stencil_bit = (1 << (cfg->stencil_bits-1));
+   if (cfg->multisample_bits)
+     msaa_samples = evgl_engine->caps.msaa_samples[cfg->multisample_bits-1];
 
-   current_ctx->_vattrib_flag |= FLAG_BIT_0;
-   current_ctx->vertex_attrib[index].modified = GL_TRUE;
-   current_ctx->vertex_attrib[index].value[0] = values[0];
-   current_ctx->vertex_attrib[index].value[1] = 0;
-   current_ctx->vertex_attrib[index].value[2] = 0;
-   current_ctx->vertex_attrib[index].value[3] = 1;
+try_again:
+   // Run through all the available formats and choose the first match
+   for (i = 0; i < evgl_engine->caps.num_fbo_fmts; ++i)
+     {
+        // Check if the MSAA is supported.  Fallback if not.
+        if ((msaa_samples) && (evgl_engine->caps.msaa_supported))
+          {
+             if (msaa_samples > evgl_engine->caps.fbo_fmts[i].samples)
+                  continue;
+          }
 
-   EVAS_GL_END_LOG(mc_log);
-}
+        if (color_bit & evgl_engine->caps.fbo_fmts[i].color_bit)
+          {
+             if (depth_bit)
+               {
+                  if (!(depth_bit & evgl_engine->caps.fbo_fmts[i].depth_bit))
+                     continue;
+               }
 
-// Optmize?
-static void
-fpgl_glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
+             if (stencil_bit)
+               {
+                  if (!(stencil_bit & evgl_engine->caps.fbo_fmts[i].stencil_bit))
+                     continue;
+               }
 
+             // Set the surface format
+             sfc->color_ifmt        = evgl_engine->caps.fbo_fmts[i].color_ifmt;
+             sfc->color_fmt         = evgl_engine->caps.fbo_fmts[i].color_fmt;
+             sfc->depth_fmt         = evgl_engine->caps.fbo_fmts[i].depth_fmt;
+             sfc->stencil_fmt       = evgl_engine->caps.fbo_fmts[i].stencil_fmt;
+             sfc->depth_stencil_fmt = evgl_engine->caps.fbo_fmts[i].depth_stencil_fmt;
+             sfc->msaa_samples      = evgl_engine->caps.fbo_fmts[i].samples;
 
-   _sym_glVertexAttrib2f(index, x, y);
+             if (((depth_bit > 0)  ||(stencil_bit > 0) ||(msaa_samples > 0))
+                  && (evgl_engine->funcs->native_win_surface_config_check))
+               {
+                  DBG("request to check win cfg with depth %d, stencil %d, msaa %d",depth_size,stencil_bit,msaa_samples);
+                  support_win_cfg = evgl_engine->funcs->native_win_surface_config_check(eng_data,depth_size,stencil_bit,msaa_samples);
+               }
 
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+             if ((sfc->direct_override) ||(support_win_cfg == 1))
+               sfc->direct_fb_opt = !!(cfg->options_bits & EVAS_GL_OPTIONS_DIRECT);
 
-   EVAS_GL_DEBUG_ASSERT(index < MAX_VERTEX_ATTRIBS);
+             // Extra flags for direct rendering
+             sfc->client_side_rotation = !!(cfg->options_bits & EVAS_GL_OPTIONS_CLIENT_SIDE_ROTATION);
+             sfc->alpha = (cfg->color_format == EVAS_GL_RGBA_8888);
 
-   current_ctx->_vattrib_flag |= FLAG_BIT_0;
-   current_ctx->vertex_attrib[index].modified = GL_TRUE;
-   current_ctx->vertex_attrib[index].value[0] = x;
-   current_ctx->vertex_attrib[index].value[1] = y;
-   current_ctx->vertex_attrib[index].value[2] = 0;
-   current_ctx->vertex_attrib[index].value[3] = 1;
+             cfg_index = i;
+             break;
+          }
+     }
 
-   EVAS_GL_END_LOG(mc_log);
+   if (cfg_index < 0)
+     {
+        ERR("Unable to find a matching config format.");
+        if ((stencil_bit > 8) || (depth_size > 24))
+          {
+             INF("Please note that Evas GL might not support 32-bit depth or "
+                 "16-bit stencil buffers, so depth24, stencil8 are the maximum "
+                 "recommended values.");
+             if (depth_size > 24)
+               {
+                  depth_bit = 4; // see DEPTH_BIT_24
+                  depth_size = 24;
+               }
+             if (stencil_bit > 8) stencil_bit = 8; // see STENCIL_BIT_8
+             DBG("Fallback to depth:%d, stencil:%d", depth_size, stencil_bit);
+             goto try_again;
+          }
+        return 0;
+     }
+   else
+     {
+        DBG("-------------Evas GL Surface Config---------------");
+        DBG("  Selected Config Index: %d", cfg_index);
+        DBG("  Color Format     : %s", _glenum_string_get(sfc->color_fmt));
+        DBG("  Depth Format     : %s", _glenum_string_get(sfc->depth_fmt));
+        DBG("  Stencil Format   : %s", _glenum_string_get(sfc->stencil_fmt));
+        DBG("  D-Stencil Format : %s", _glenum_string_get(sfc->depth_stencil_fmt));
+        DBG("  MSAA Samples     : %d", sfc->msaa_samples);
+        DBG("  Direct Option    : %d", sfc->direct_fb_opt);
+        DBG("--------------------------------------------------");
+        sfc->cfg_index = cfg_index;
+        return 1;
+     }
 }
 
-// Optmize?
-static void
-fpgl_glVertexAttrib2fv(GLuint index, const GLfloat* values)
+static int
+_evgl_direct_renderable(EVGL_Resource *rsc, EVGL_Surface *sfc)
 {
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
+   if (evgl_engine->direct_force_off) return 0;
+   if (rsc->id != evgl_engine->main_tid) return 0;
+   if (!sfc->direct_fb_opt) return 0;
+   if (!rsc->direct.enabled) return 0;
 
-
-   _sym_glVertexAttrib2fv(index, values);
-
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_DEBUG_ASSERT(index < MAX_VERTEX_ATTRIBS);
-
-   current_ctx->_vattrib_flag |= FLAG_BIT_0;
-   current_ctx->vertex_attrib[index].modified = GL_TRUE;
-   current_ctx->vertex_attrib[index].value[0] = values[0];
-   current_ctx->vertex_attrib[index].value[1] = values[1];
-   current_ctx->vertex_attrib[index].value[2] = 0;
-   current_ctx->vertex_attrib[index].value[3] = 1;
-
-   EVAS_GL_END_LOG(mc_log);
+   return 1;
 }
 
-// Optmize?
-static void
-fpgl_glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
+//---------------------------------------------------------------//
+// Functions used by Evas GL module
+//---------------------------------------------------------------//
+EVGL_Resource *
+_evgl_tls_resource_get(void)
 {
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
+   EVGL_Resource *rsc = NULL;
 
-   _sym_glVertexAttrib3f(index, x, y, z);
-
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_DEBUG_ASSERT(index < MAX_VERTEX_ATTRIBS);
+   // Check if engine is valid
+   if (!evgl_engine)
+     {
+        ERR("Invalid EVGL Engine!");
+        return NULL;
+     }
 
-   current_ctx->_vattrib_flag |= FLAG_BIT_0;
-   current_ctx->vertex_attrib[index].modified = GL_TRUE;
-   current_ctx->vertex_attrib[index].value[0] = x;
-   current_ctx->vertex_attrib[index].value[1] = y;
-   current_ctx->vertex_attrib[index].value[2] = z;
-   current_ctx->vertex_attrib[index].value[3] = 1;
+   rsc = eina_tls_get(evgl_engine->resource_key);
 
-   EVAS_GL_END_LOG(mc_log);
+   if (!rsc)
+      return NULL;
+   else
+      return rsc;
 }
 
-// Optmize?
-static void
-fpgl_glVertexAttrib3fv(GLuint index, const GLfloat* values)
+EVGL_Resource *
+_evgl_tls_resource_create(void *eng_data)
 {
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
-
+   EVGL_Resource *rsc;
 
-   _sym_glVertexAttrib3fv(index, values);
-
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-   EVAS_GL_DEBUG_ASSERT(index < MAX_VERTEX_ATTRIBS);
+   // Check if engine is valid
+   if (!evgl_engine)
+     {
+        ERR("Invalid EVGL Engine!");
+        return NULL;
+     }
 
-   current_ctx->_vattrib_flag |= FLAG_BIT_0;
-   current_ctx->vertex_attrib[index].modified = GL_TRUE;
-   current_ctx->vertex_attrib[index].value[0] = values[0];
-   current_ctx->vertex_attrib[index].value[1] = values[1];
-   current_ctx->vertex_attrib[index].value[2] = values[2];
-   current_ctx->vertex_attrib[index].value[3] = 1;
+   // Create internal resources if it hasn't been created already
+   if (!(rsc = _internal_resources_create(eng_data)))
+     {
+        ERR("Error creating internal resources.");
+        return NULL;
+     }
 
-   EVAS_GL_END_LOG(mc_log);
+   // Set the resource in TLS
+   if (eina_tls_set(evgl_engine->resource_key, (void*)rsc) == EINA_TRUE)
+     {
+        // Add to the resource resource list for cleanup
+        LKL(evgl_engine->resource_lock);
+        rsc->id = evgl_engine->resource_count++;
+        evgl_engine->resource_list = eina_list_prepend(evgl_engine->resource_list, rsc);
+        LKU(evgl_engine->resource_lock);
+        return rsc;
+     }
+   else
+     {
+        ERR("Failed setting TLS Resource");
+        _internal_resources_destroy(eng_data, rsc);
+        return NULL;
+     }
 }
 
-// Optmize?
-static void
-fpgl_glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+void
+_evgl_tls_resource_destroy(void *eng_data)
 {
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
+   Eina_List *l;
+   EVGL_Resource *rsc;
 
+   // Check if engine is valid
+   if (!evgl_engine)
+     {
+        ERR("Invalid EVGL Engine!");
+        return;
+     }
 
-   _sym_glVertexAttrib4f(index, x, y, z, w);
+   if (!_evgl_tls_resource_get())
+     {
+        ERR("Error retrieving resource from TLS");
+        return;
+     }
 
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   LKL(evgl_engine->resource_lock);
+   EINA_LIST_FOREACH(evgl_engine->resource_list, l, rsc)
+     {
+        _internal_resources_destroy(eng_data, rsc);
+     }
+   eina_list_free(evgl_engine->resource_list);
+   LKU(evgl_engine->resource_lock);
 
-   EVAS_GL_DEBUG_ASSERT(index < MAX_VERTEX_ATTRIBS);
+   // Destroy TLS
+   if (evgl_engine->resource_key)
+      eina_tls_free(evgl_engine->resource_key);
+   evgl_engine->resource_key = 0;
+}
 
-   current_ctx->_vattrib_flag |= FLAG_BIT_0;
-   current_ctx->vertex_attrib[index].modified = GL_TRUE;
-   current_ctx->vertex_attrib[index].value[0] = x;
-   current_ctx->vertex_attrib[index].value[1] = y;
-   current_ctx->vertex_attrib[index].value[2] = z;
-   current_ctx->vertex_attrib[index].value[3] = w;
+EVGL_Context *
+_evgl_current_context_get(void)
+{
+   EVGL_Resource *rsc;
 
-   EVAS_GL_END_LOG(mc_log);
+   if (!(rsc = _evgl_tls_resource_get()))
+     {
+        ERR("No current context set.");
+        return NULL;
+     }
+   else
+     return rsc->current_ctx;
 }
 
-// Optmize?
-static void
-fpgl_glVertexAttrib4fv(GLuint index, const GLfloat* values)
+int
+_evgl_not_in_pixel_get(void)
 {
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
+   EVGL_Resource *rsc;
 
+   if (!(rsc=_evgl_tls_resource_get())) return 1;
 
-   _sym_glVertexAttrib4fv(index, values);
+   EVGL_Context *ctx = rsc->current_ctx;
 
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   if (evgl_engine->direct_force_off)
+     return 0;
 
-   EVAS_GL_DEBUG_ASSERT(index < MAX_VERTEX_ATTRIBS);
+   if (rsc->id != evgl_engine->main_tid)
+     return 0;
 
-   current_ctx->_vattrib_flag |= FLAG_BIT_0;
-   current_ctx->vertex_attrib[index].modified = GL_TRUE;
-   current_ctx->vertex_attrib[index].value[0] = values[0];
-   current_ctx->vertex_attrib[index].value[1] = values[1];
-   current_ctx->vertex_attrib[index].value[2] = values[2];
-   current_ctx->vertex_attrib[index].value[3] = values[3];
-
-   EVAS_GL_END_LOG(mc_log);
-}
+   if (!ctx || !ctx->current_sfc)
+     return 0;
 
+   if (!ctx->current_sfc->direct_fb_opt)
+     return 0;
 
-// Optmize?
-static void
-fpgl_glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
-{
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
+   if (rsc->direct.rot == 0)
+     return !rsc->direct.enabled;
 
+   if (!ctx->current_sfc->client_side_rotation)
+     return 0;
 
-   _sym_glVertexAttribPointer(index, size, type, normalized, stride, ptr);
+   return !rsc->direct.enabled;
 
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   // was:
+   /*
+   if ((!evgl_engine->direct_force_off) &&
+       (rsc->id == evgl_engine->main_tid) &&
+       (ctx) &&
+       (ctx->current_sfc) &&
+       (ctx->current_sfc->direct_fb_opt) &&
+       (!rsc->direct.enabled))
+      return 1;
+   else
+      return 0;
+   */
+}
 
-   EVAS_GL_DEBUG_ASSERT(index < MAX_VERTEX_ATTRIBS);
+int
+_evgl_direct_enabled(void)
+{
+   EVGL_Resource *rsc;
+   EVGL_Surface  *sfc;
 
-   current_ctx->_vattrib_flag |= FLAG_BIT_1;
-   current_ctx->vertex_array[index].modified   = GL_TRUE;
-   current_ctx->vertex_array[index].buf_id     = current_ctx->gl_array_buffer_binding;
-   current_ctx->vertex_array[index].size       = size;
-   current_ctx->vertex_array[index].type       = type;
-   current_ctx->vertex_array[index].normalized = normalized;
-   current_ctx->vertex_array[index].stride     = stride;
-   current_ctx->vertex_array[index].pointer    = ptr;
+   if (!(rsc=_evgl_tls_resource_get())) return 0;
+   if (!(rsc->current_ctx)) return 0;
+   if (!(sfc=rsc->current_ctx->current_sfc)) return 0;
 
-   EVAS_GL_END_LOG(mc_log);
+   return _evgl_direct_renderable(rsc, sfc);
 }
 
-static void
-fpgl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+void
+_evgl_error_set(int error_enum)
 {
-   THREAD_CHECK_DEBUG();
-   EVAS_GL_START_LOG(mc_log);
+   EVGL_Resource *rsc;
 
-
-   if ( COMPARE_OPT_SKIP
-       (current_ctx->gl_viewport[0] != x) ||
-       (current_ctx->gl_viewport[1] != y) ||
-       (current_ctx->gl_viewport[2] != width) ||
-       (current_ctx->gl_viewport[3] != height))
+   if (!(rsc=_evgl_tls_resource_get()))
      {
-        _sym_glViewport(x, y, width, height);
-
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-
-        current_ctx->_clear_flag1 |= FLAG_BIT_0;
-        current_ctx->gl_viewport[0] = x;
-        current_ctx->gl_viewport[1] = y;
-        current_ctx->gl_viewport[2] = width;
-        current_ctx->gl_viewport[3] = height;
+        WRN("evgl: Unable to set error!");
+        return;
      }
 
-   EVAS_GL_END_LOG(mc_log);
+   rsc->error_state = error_enum;
 }
 
-
-//----------------------------------------------------------------//
-//                                                                //
-//                      Load Symbols                              //
-//                                                                //
-//----------------------------------------------------------------//
-static void
-sym_missing(void)
-{
-   ERR("GL symbols missing!\n");
-}
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-//------------------------------------------------------//
-// EGL
-static int
-glue_sym_init(void)
+int
+_evgl_error_get(void)
 {
-   //------------------------------------------------//
-   // Use gl_lib_handle for finding both GL and GLX symbols
-#define FINDSYM(dst, sym, typ) \
-   if ((!dst) && (_sym_eglGetProcAddress)) dst = (typeof(dst))_sym_eglGetProcAddress(sym); \
-   if (!dst) dst = (typeof(dst))dlsym(egl_lib_handle, sym); \
-   if (!dst) DBG("Error loading %s\n", sym);
-#define FALLBAK(dst, typ) if (!dst) dst = (typeof(dst))sym_missing;
-
-   FINDSYM(_sym_eglGetProcAddress, "eglGetProcAddress", glsym_func_eng_fn);
-
-   FINDSYM(_sym_eglGetError, "eglGetError", glsym_func_int);
-   FINDSYM(_sym_eglGetDisplay, "eglGetDisplay", glsym_func_egldpy);
-   FINDSYM(_sym_eglInitialize, "eglInitialize", glsym_func_bool);
-   FINDSYM(_sym_eglTerminate, "eglTerminate", glsym_func_bool);
-   FINDSYM(_sym_eglChooseConfig, "eglChooseConfig", glsym_func_bool);
-   FINDSYM(_sym_eglCreateWindowSurface, "eglCreateWindowSurface", glsym_func_eglsfc);
-   FINDSYM(_sym_eglCreatePixmapSurface, "eglCreatePixmapSurface", glsym_func_eglsfc);
-   FINDSYM(_sym_eglDestroySurface, "eglDestroySurface", glsym_func_bool);
-   FINDSYM(_sym_eglBindAPI, "eglBindAPI", glsym_func_bool);
-   FINDSYM(_sym_eglWaitClient, "eglWaitClient", glsym_func_bool);
-   FINDSYM(_sym_eglSurfaceAttrib, "eglSurfaceAttrib", glsym_func_bool);
-   FINDSYM(_sym_eglBindTexImage, "eglBindTexImage", glsym_func_void);
-   FINDSYM(_sym_eglReleaseTexImage, "eglReleaseTexImage", glsym_func_bool);
-   FINDSYM(_sym_eglSwapInterval, "eglSwapInterval", glsym_func_bool);
-   FINDSYM(_sym_eglCreateContext, "eglCreateContext", glsym_func_eglctx);
-   FINDSYM(_sym_eglDestroyContext, "eglDestroyContext", glsym_func_bool);
-   FINDSYM(_sym_eglMakeCurrent, "eglMakeCurrent", glsym_func_bool);
-   FINDSYM(_sym_eglGetCurrentContext, "eglGetCurrentContext", glsym_func_eglctx);
-   FINDSYM(_sym_eglGetCurrentSurface, "eglGetCurrentSurface", glsym_func_eglsfc);
-   FINDSYM(_sym_eglGetCurrentDisplay, "eglGetCurrentDisplay", glsym_func_egldpy);
-   FINDSYM(_sym_eglWaitGL, "eglWaitGL", glsym_func_bool);
-   FINDSYM(_sym_eglWaitNative, "eglWaitNative", glsym_func_bool);
-   FINDSYM(_sym_eglSwapBuffers, "eglSwapBuffers", glsym_func_bool);
-   FINDSYM(_sym_eglCopyBuffers, "eglCopyBuffers", glsym_func_bool);
-   FINDSYM(_sym_eglQueryString, "eglQueryString", glsym_func_char_const_ptr);
-   //FINDSYM(_sym_eglGetProcAddress, "eglGetProcAddress", glsym_func_eng_fn);
-
-   //----------------//
-   FINDSYM(_sym_eglGetProcAddress, "eglGetProcAddressEXT", glsym_func_eng_fn);
-   FINDSYM(_sym_eglGetProcAddress, "eglGetProcAddressARB", glsym_func_eng_fn);
-   FINDSYM(_sym_eglGetProcAddress, "eglGetProcAddressKHR", glsym_func_eng_fn);
-
-   FINDSYM(_sym_eglCreateImage, "eglCreateImage", glsym_func_void_ptr);
-   FINDSYM(_sym_eglCreateImage, "eglCreateImageEXT", glsym_func_void_ptr);
-   FINDSYM(_sym_eglCreateImage, "eglCreateImageARB", glsym_func_void_ptr);
-   FINDSYM(_sym_eglCreateImage, "eglCreateImageKHR", glsym_func_void_ptr);
-
-   FINDSYM(_sym_eglDestroyImage, "eglDestroyImage", glsym_func_uint);
-   FINDSYM(_sym_eglDestroyImage, "eglDestroyImageEXT", glsym_func_uint);
-   FINDSYM(_sym_eglDestroyImage, "eglDestroyImageARB", glsym_func_uint);
-   FINDSYM(_sym_eglDestroyImage, "eglDestroyImageKHR", glsym_func_uint);
-
-   FINDSYM(_sym_eglMapImageSEC, "eglMapImageSEC", glsym_func_void_ptr);
-
-   FINDSYM(_sym_eglUnmapImageSEC, "eglUnmapImageSEC", glsym_func_uint);
-
-   FINDSYM(_sym_eglGetImageAttribSEC, "eglGetImageAttribSEC", glsym_func_uint);
-
-   FINDSYM(_sym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", glsym_func_void);
-   FINDSYM(_sym_glEGLImageTargetRenderbufferStorageOES, "glEGLImageTargetRenderbufferStorageOES", glsym_func_void);
-
-#undef FINDSYM
-#undef FALLBAK
-
-   return 1;
-}
+   EVGL_Resource *rsc;
 
+   if (!(rsc=_evgl_tls_resource_get()))
+     {
+        WRN("evgl: Unable to get error!");
+        return EVAS_GL_NOT_INITIALIZED;
+     }
 
-#else
-//------------------------------------------------------//
-// GLX
-static int
-glue_sym_init(void)
-{
-   //------------------------------------------------//
-   // Use gl_lib_handle for finding both GL and GLX symbols
-#define FINDSYM(dst, sym, typ) \
-   if ((!dst) && (_sym_glXGetProcAddress)) dst = (typeof(dst))_sym_glXGetProcAddress(sym); \
-   if (!dst) dst = (typeof(dst))dlsym(gl_lib_handle, sym); \
-   if (!dst) DBG("Error loading %s\n", sym);
-#define FALLBAK(dst, typ) if (!dst) dst = (typeof(dst))sym_missing;
-
-   //------------------------------------------------------//
-   // GLX APIs... Only ones that are being used.
-   FINDSYM(_sym_glXGetProcAddress, "glXGetProcAddress", glsym_func_eng_fn);
-   FINDSYM(_sym_glXGetProcAddress, "glXGetProcAddressEXT", glsym_func_eng_fn);
-   FINDSYM(_sym_glXGetProcAddress, "glXGetProcAddressARB", glsym_func_eng_fn);
-
-   // Standard Functions
-   FINDSYM(_sym_glXChooseVisual, "glXChooseVisual", glsym_func_xvisinfo_ptr);
-   FINDSYM(_sym_glXCreateContext, "glXCreateContext", glsym_func_glxctx);
-   FINDSYM(_sym_glXDestroyContext, "glXDestroyContext", glsym_func_void);
-   FINDSYM(_sym_glXGetCurrentContext, "glXGetCurrentContext", glsym_func_glxctx);
-   FINDSYM(_sym_glXGetCurrentDrawable, "glXGetCurrentDrawable", glsym_func_glxdraw);
-   FINDSYM(_sym_glXMakeCurrent, "glXMakeCurrent", glsym_func_bool);
-   FINDSYM(_sym_glXSwapBuffers, "glXSwapBuffers", glsym_func_void);
-   FINDSYM(_sym_glXWaitX, "glXWaitX", glsym_func_void);
-   FINDSYM(_sym_glXWaitGL, "glXWaitGL", glsym_func_void);
-   FINDSYM(_sym_glXQueryExtension, "glXQueryExtension", glsym_func_bool);
-   FINDSYM(_sym_glXQueryExtensionsString, "glXQueryExtensionsString", glsym_func_const_char_ptr);
-
-   // 1.3 and later
-   FINDSYM(_sym_glXChooseFBConfig, "glXChooseFBConfig", glsym_func_glxfbcfg_ptr);
-   FINDSYM(_sym_glXGetFBConfigs, "glXGetFBConfigs", glsym_func_glxfbcfg_ptr);
-   FINDSYM(_sym_glXGetFBConfigAttrib, "glXGetFBConfigAttrib", glsym_func_int);
-   FINDSYM(_sym_glXGetVisualFromFBConfig, "glXGetVisualFromFBConfig", glsym_func_xvisinfo_ptr);
-   FINDSYM(_sym_glXDestroyWindow, "glXDestroyWindow", glsym_func_void);
-   FINDSYM(_sym_glXMakeContextCurrent, "glXMakeContextCurrent", glsym_func_bool);
-
-
-   // Extension functions
-   FINDSYM(_sym_glXBindTexImage, "glXBindTexImage", glsym_func_void);
-   FINDSYM(_sym_glXBindTexImage, "glXBindTexImageEXT", glsym_func_void);
-   FINDSYM(_sym_glXBindTexImage, "glXBindTexImageARB", glsym_func_void);
-
-   FINDSYM(_sym_glXReleaseTexImage, "glXReleaseTexImage", glsym_func_void);
-   FINDSYM(_sym_glXReleaseTexImage, "glXReleaseTexImageEXT", glsym_func_void);
-   FINDSYM(_sym_glXReleaseTexImage, "glXReleaseTexImageARB", glsym_func_void);
-
-   FINDSYM(_sym_glXGetVideoSync, "glXGetVideoSyncSGI", glsym_func_int);
-
-   FINDSYM(_sym_glXWaitVideoSync, "glXWaitVideoSyncSGI", glsym_func_int);
-
-   FINDSYM(_sym_glXCreatePixmap, "glXCreatePixmap", glsym_func_xid);
-   FINDSYM(_sym_glXCreatePixmap, "glXCreatePixmapEXT", glsym_func_xid);
-   FINDSYM(_sym_glXCreatePixmap, "glXCreatePixmapARB", glsym_func_xid);
-
-   FINDSYM(_sym_glXDestroyPixmap, "glXDestroyPixmap", glsym_func_void);
-   FINDSYM(_sym_glXDestroyPixmap, "glXDestroyPixmapEXT", glsym_func_void);
-   FINDSYM(_sym_glXDestroyPixmap, "glXDestroyPixmapARB", glsym_func_void);
-
-   FINDSYM(_sym_glXQueryDrawable, "glXQueryDrawable", glsym_func_void);
-   FINDSYM(_sym_glXQueryDrawable, "glXQueryDrawableEXT", glsym_func_void);
-   FINDSYM(_sym_glXQueryDrawable, "glXQueryDrawableARB", glsym_func_void);
-
-   FINDSYM(_sym_glXSwapIntervalSGI, "glXSwapIntervalMESA", glsym_func_int);
-   FINDSYM(_sym_glXSwapIntervalSGI, "glXSwapIntervalSGI", glsym_func_int);
-
-   //----------//
-   FINDSYM(_sym_glXSwapIntervalEXT, "glXSwapIntervalEXT", glsym_func_void);
-
-
-#undef FINDSYM
-#undef FALLBAK
-
-   return 1;
+   return rsc->error_state;
 }
 
-#endif
+//---------------------------------------------------------------//
+// Exported functions for evas_engine to use
 
-static int
-gl_sym_init(void)
+// Initialize engine
+//    - Allocate the engine struct
+//    - Assign engine funcs form evas_engine
+//    - Create internal resources: internal context, surface for resource creation
+//    - Initialize extensions
+//    - Check surface capability
+//
+// This code should only be called once during evas_gl_new()
+EVGL_Engine *
+evgl_engine_init(void *eng_data, EVGL_Interface *efunc)
 {
+   int direct_off = 0, direct_soff = 0, debug_mode = 0;
+   char *s = NULL;
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-
-   //------------------------------------------------//
-   // Use eglGetProcAddress
-#  define FINDSYM(dst, sym, typ) \
-   if ((!dst) && (_sym_eglGetProcAddress)) dst = (typeof(dst))_sym_eglGetProcAddress(sym); \
-   if (!dst) dst = (typeof(dst))dlsym(gl_lib_handle, sym); \
-   if (!dst) DBG("Error loading %s\n", sym);
-#  define FALLBAK(dst, typ) \
-   if (!dst) \
-     { \
-        DBG("Symbol not found so falling back."); \
-        dst = (typeof(dst))sym_missing; \
+   // Initialize Log Domain
+   if (_evas_gl_log_dom < 0)
+      _evas_gl_log_dom = eina_log_domain_register("EvasGL", EVAS_DEFAULT_LOG_COLOR);
+   if (_evas_gl_log_dom < 0)
+     {
+        EINA_LOG_ERR("Can not create a module log domain.");
+        return NULL;
      }
 
-   FINDSYM(_sym_glGetProgramBinary, "glGetProgramBinary", glsym_func_void);
-   FINDSYM(_sym_glGetProgramBinary, "glGetProgramBinaryEXT", glsym_func_void);
-   FINDSYM(_sym_glGetProgramBinary, "glGetProgramBinaryARB", glsym_func_void);
-   FINDSYM(_sym_glGetProgramBinary, "glGetProgramBinaryOES", glsym_func_void);
-   FINDSYM(_sym_glGetProgramBinary, "glGetProgramBinaryKHR", glsym_func_void);
-
-   FINDSYM(_sym_glProgramBinary, "glProgramBinary", glsym_func_void);
-   FINDSYM(_sym_glProgramBinary, "glProgramBinaryEXT", glsym_func_void);
-   FINDSYM(_sym_glProgramBinary, "glProgramBinaryARB", glsym_func_void);
-   FINDSYM(_sym_glProgramBinary, "glProgramBinaryOES", glsym_func_void);
-   FINDSYM(_sym_glProgramBinary, "glProgramBinaryKHR", glsym_func_void);
+   // Store the Log Level
+   _evas_gl_log_level = eina_log_domain_level_get("EvasGL");
 
-   FINDSYM(_sym_glProgramParameteri, "glProgramParameteri", glsym_func_void);
-   FINDSYM(_sym_glProgramParameteri, "glProgramParameteriEXT", glsym_func_void);
-   FINDSYM(_sym_glProgramParameteri, "glProgramParameteriARB", glsym_func_void);
-   FINDSYM(_sym_glProgramParameteri, "glProgramParameteriOES", glsym_func_void);
-   FINDSYM(_sym_glProgramParameteri, "glProgramParameteriKHR", glsym_func_void);
-
-#else
-
-   //------------------------------------------------//
-   // Use gl_lib_handle for finding both GL and GLX symbols
-   // Try eglGetProcAddress
-#  define FINDSYM(dst, sym, typ) \
-   if ((!dst) && (_sym_glXGetProcAddress)) dst = (typeof(dst))_sym_glXGetProcAddress(sym); \
-   if (!dst) dst = (typeof(dst))dlsym(gl_lib_handle, sym); \
-   if (!dst) DBG("Error loading %s\n", sym);
-#  define FALLBAK(dst, typ) \
-   if (!dst) \
-     { \
-        ERR("Symbol not found so falling back."); \
-        dst = (typeof(dst))sym_missing; \
-        exit(1); \
+   // Check the validity of the efunc
+   if ((!efunc) ||
+       (!efunc->surface_create) ||
+       (!efunc->context_create) ||
+       (!efunc->make_current))
+     {
+        ERR("Invalid Engine Functions for Evas GL Engine.");
+        return NULL;
      }
 
-   //----------//
-   FINDSYM(_sym_glGetProgramBinary, "glGetProgramBinary", glsym_func_void);
-   FINDSYM(_sym_glGetProgramBinary, "glGetProgramBinaryEXT", glsym_func_void);
-   FINDSYM(_sym_glGetProgramBinary, "glGetProgramBinaryARB", glsym_func_void);
-   FINDSYM(_sym_glGetProgramBinary, "glGetProgramBinaryOES", glsym_func_void);
-
-   FINDSYM(_sym_glProgramBinary, "glProgramBinary", glsym_func_void);
-   FINDSYM(_sym_glProgramBinary, "glProgramBinaryEXT", glsym_func_void);
-   FINDSYM(_sym_glProgramBinary, "glProgramBinaryARB", glsym_func_void);
-
-   FINDSYM(_sym_glProgramParameteri, "glProgramParameteri", glsym_func_void);
-   FINDSYM(_sym_glProgramParameteri, "glProgramParameteriEXT", glsym_func_void);
-   FINDSYM(_sym_glProgramParameteri, "glProgramParameteriARB", glsym_func_void);
-
-#endif
-
-   //------------------------------------------------------//
-   // GLES 2.0 APIs...
-   FINDSYM(_sym_glActiveTexture, "glActiveTexture", glsym_func_void);
-   FALLBAK(_sym_glActiveTexture, glsym_func_void);
-
-   FINDSYM(_sym_glAttachShader, "glAttachShader", glsym_func_void);
-   FALLBAK(_sym_glAttachShader, glsym_func_void);
-
-   FINDSYM(_sym_glBindAttribLocation, "glBindAttribLocation", glsym_func_void);
-   FALLBAK(_sym_glBindAttribLocation, glsym_func_void);
-
-   FINDSYM(_sym_glBindBuffer, "glBindBuffer", glsym_func_void);
-   FALLBAK(_sym_glBindBuffer, glsym_func_void);
-
-   FINDSYM(_sym_glBindFramebuffer, "glBindFramebuffer", glsym_func_void);
-   FALLBAK(_sym_glBindFramebuffer, glsym_func_void);
-
-   FINDSYM(_sym_glBindRenderbuffer, "glBindRenderbuffer", glsym_func_void);
-   FALLBAK(_sym_glBindRenderbuffer, glsym_func_void);
-
-   FINDSYM(_sym_glBindTexture, "glBindTexture", glsym_func_void);
-   FALLBAK(_sym_glBindTexture, glsym_func_void);
-
-   FINDSYM(_sym_glBlendColor, "glBlendColor", glsym_func_void);
-   FALLBAK(_sym_glBlendColor, glsym_func_void);
-
-   FINDSYM(_sym_glBlendEquation, "glBlendEquation", glsym_func_void);
-   FALLBAK(_sym_glBlendEquation, glsym_func_void);
-
-   FINDSYM(_sym_glBlendEquationSeparate, "glBlendEquationSeparate", glsym_func_void);
-   FALLBAK(_sym_glBlendEquationSeparate, glsym_func_void);
-
-   FINDSYM(_sym_glBlendFunc, "glBlendFunc", glsym_func_void);
-   FALLBAK(_sym_glBlendFunc, glsym_func_void);
-
-   FINDSYM(_sym_glBlendFuncSeparate, "glBlendFuncSeparate", glsym_func_void);
-   FALLBAK(_sym_glBlendFuncSeparate, glsym_func_void);
-
-   FINDSYM(_sym_glBufferData, "glBufferData", glsym_func_void);
-   FALLBAK(_sym_glBufferData, glsym_func_void);
-
-   FINDSYM(_sym_glBufferSubData, "glBufferSubData", glsym_func_void);
-   FALLBAK(_sym_glBufferSubData, glsym_func_void);
+   // Allocate engine
+   evgl_engine = calloc(1, sizeof(EVGL_Engine));
+   if (!evgl_engine)
+     {
+        ERR("Error allocating EVGL Engine. GL initialization failed.");
+        goto error;
+     }
 
-   FINDSYM(_sym_glCheckFramebufferStatus, "glCheckFramebufferStatus", glsym_func_uint);
-   FALLBAK(_sym_glCheckFramebufferStatus, glsym_func_uint);
+   LKI(evgl_engine->lck);
 
-   FINDSYM(_sym_glClear, "glClear", glsym_func_void);
-   FALLBAK(_sym_glClear, glsym_func_void);
+   // Assign functions
+   evgl_engine->funcs = efunc;
 
-   FINDSYM(_sym_glClearColor, "glClearColor", glsym_func_void);
-   FALLBAK(_sym_glClearColor, glsym_func_void);
+   // Initialize Resource TLS
+   if (eina_tls_new(&evgl_engine->resource_key) == EINA_FALSE)
+     {
+        ERR("Error creating tls key");
+        goto error;
+     }
+   DBG("TLS KEY created: %d", evgl_engine->resource_key);
 
-   FINDSYM(_sym_glClearDepthf, "glClearDepthf", glsym_func_void);
-   FINDSYM(_sym_glClearDepthf, "glClearDepth", glsym_func_void);
-   FALLBAK(_sym_glClearDepthf, glsym_func_void);
+   evgl_engine->safe_extensions = eina_hash_string_small_new(NULL);
 
-   FINDSYM(_sym_glClearStencil, "glClearStencil", glsym_func_void);
-   FALLBAK(_sym_glClearStencil, glsym_func_void);
+   // Initialize Extensions
+   if (efunc->proc_address_get && efunc->ext_string_get)
+     {
+        if (!evgl_api_ext_init(efunc->proc_address_get, efunc->ext_string_get(eng_data)))
+          {
+             ERR("Extensions failed to load. This shouldn't happen, Evas GL load fails.");
+             goto error;
+          }
+     }
+   else
+     ERR("Proc address get function not available. Extensions not initialized.");
 
-   FINDSYM(_sym_glColorMask, "glColorMask", glsym_func_void);
-   FALLBAK(_sym_glColorMask, glsym_func_void);
+   if (efunc->ext_string_get)
+     DBG("GLUE Extension String: %s", efunc->ext_string_get(eng_data));
+   DBG("GL Extension String: %s", glGetString(GL_EXTENSIONS));
 
-   FINDSYM(_sym_glCompileShader, "glCompileShader", glsym_func_void);
-   FALLBAK(_sym_glCompileShader, glsym_func_void);
+   // Surface Caps
+   if (!_surface_cap_init(eng_data))
+     {
+        ERR("Error initializing surface cap");
+        goto error;
+     }
 
-   FINDSYM(_sym_glCompressedTexImage2D, "glCompressedTexImage2D", glsym_func_void);
-   FALLBAK(_sym_glCompressedTexImage2D, glsym_func_void);
+   // Check if Direct Rendering Override Force Off flag is on
+   s = getenv("EVAS_GL_DIRECT_OVERRIDE_FORCE_OFF");
+   if (s) direct_off = atoi(s);
+   if (direct_off == 1)
+      evgl_engine->direct_force_off = 1;
 
-   FINDSYM(_sym_glCompressedTexSubImage2D, "glCompressedTexSubImage2D", glsym_func_void);
-   FALLBAK(_sym_glCompressedTexSubImage2D, glsym_func_void);
+   // Check if Direct Rendering Override Force Off flag is on
+   s = getenv("EVAS_GL_DIRECT_SCISSOR_OFF");
+   if (s) direct_soff = atoi(s);
+   if (direct_soff == 1)
+      evgl_engine->direct_scissor_off = 1;
 
-   FINDSYM(_sym_glCopyTexImage2D, "glCopyTexImage2D", glsym_func_void);
-   FALLBAK(_sym_glCopyTexImage2D, glsym_func_void);
+   // Check if API Debug mode is on
+   s = getenv("EVAS_GL_API_DEBUG");
+   if (s) debug_mode = atoi(s);
+   if (debug_mode == 1)
+      evgl_engine->api_debug_mode = 1;
 
-   FINDSYM(_sym_glCopyTexSubImage2D, "glCopyTexSubImage2D", glsym_func_void);
-   FALLBAK(_sym_glCopyTexSubImage2D, glsym_func_void);
+   // Main Thread ID (get tid not available in eina thread yet)
+   evgl_engine->main_tid = 0;
 
-   FINDSYM(_sym_glCreateProgram, "glCreateProgram", glsym_func_uint);
-   FALLBAK(_sym_glCreateProgram, glsym_func_uint);
+   // Clear Function Pointers
+   if (!gl_funcs) gl_funcs = calloc(1, EVAS_GL_API_STRUCT_SIZE);
+   if (!gles1_funcs) gles1_funcs = calloc(1, EVAS_GL_API_STRUCT_SIZE);
 
-   FINDSYM(_sym_glCreateShader, "glCreateShader", glsym_func_uint);
-   FALLBAK(_sym_glCreateShader, glsym_func_uint);
 
-   FINDSYM(_sym_glCullFace, "glCullFace", glsym_func_void);
-   FALLBAK(_sym_glCullFace, glsym_func_void);
+   return evgl_engine;
 
-   FINDSYM(_sym_glDeleteBuffers, "glDeleteBuffers", glsym_func_void);
-   FALLBAK(_sym_glDeleteBuffers, glsym_func_void);
+error:
+   if (evgl_engine)
+     {
+        if (evgl_engine->safe_extensions)
+          eina_hash_free(evgl_engine->safe_extensions);
+        if (evgl_engine->resource_key)
+          eina_tls_free(evgl_engine->resource_key);
+        LKD(evgl_engine->lck);
+        free(evgl_engine);
+     }
+   evgl_engine = NULL;
+   return NULL;
+}
 
-   FINDSYM(_sym_glDeleteFramebuffers, "glDeleteFramebuffers", glsym_func_void);
-   FALLBAK(_sym_glDeleteFramebuffers, glsym_func_void);
+// Terminate engine and all the resources
+//    - destroy all internal resources
+//    - free allocated engine struct
+void
+evgl_engine_shutdown(void *eng_data)
+{
+   // Check if engine is valid
+   if (!evgl_engine)
+     {
+        ERR("EVGL Engine not valid!");
+        return;
+     }
 
-   FINDSYM(_sym_glDeleteProgram, "glDeleteProgram", glsym_func_void);
-   FALLBAK(_sym_glDeleteProgram, glsym_func_void);
+   // Log
+   eina_log_domain_unregister(_evas_gl_log_dom);
+   _evas_gl_log_dom = -1;
 
-   FINDSYM(_sym_glDeleteRenderbuffers, "glDeleteRenderbuffers", glsym_func_void);
-   FALLBAK(_sym_glDeleteRenderbuffers, glsym_func_void);
+   // Destroy internal resources
+   _evgl_tls_resource_destroy(eng_data);
 
-   FINDSYM(_sym_glDeleteShader, "glDeleteShader", glsym_func_void);
-   FALLBAK(_sym_glDeleteShader, glsym_func_void);
 
-   FINDSYM(_sym_glDeleteTextures, "glDeleteTextures", glsym_func_void);
-   FALLBAK(_sym_glDeleteTextures, glsym_func_void);
+   // Free engine
+   free(evgl_engine);
+   evgl_engine = NULL;
+}
 
-   FINDSYM(_sym_glDepthFunc, "glDepthFunc", glsym_func_void);
-   FALLBAK(_sym_glDepthFunc, glsym_func_void);
+void *
+evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int target, void *native, int w, int h)
+{
+   EVGL_Surface *sfc = NULL;
+   char *s = NULL;
+   int direct_override = 0, direct_mem_opt = 0;
+   Eina_Bool need_reconfigure = EINA_FALSE;
 
-   FINDSYM(_sym_glDepthMask, "glDepthMask", glsym_func_void);
-   FALLBAK(_sym_glDepthMask, glsym_func_void);
+   // Check if engine is valid
+   if (!evgl_engine)
+     {
+        ERR("Invalid EVGL Engine!");
+        _evgl_error_set(EVAS_GL_BAD_ACCESS);
+        return NULL;
+     }
 
-   FINDSYM(_sym_glDepthRangef, "glDepthRangef", glsym_func_void);
-   FINDSYM(_sym_glDepthRangef, "glDepthRange", glsym_func_void);
-   FALLBAK(_sym_glDepthRangef, glsym_func_void);
+   if (!cfg)
+     {
+        ERR("Invalid Config!");
+        _evgl_error_set(EVAS_GL_BAD_CONFIG);
+        return NULL;
+     }
 
-   FINDSYM(_sym_glDetachShader, "glDetachShader", glsym_func_void);
-   FALLBAK(_sym_glDetachShader, glsym_func_void);
+   // Check the size of the surface
+   if ((w > evgl_engine->caps.max_w) || (h > evgl_engine->caps.max_h))
+     {
+        ERR("Requested surface size [%d, %d] is greater than max supported size [%d, %d]",
+             w, h, evgl_engine->caps.max_w, evgl_engine->caps.max_h);
+        _evgl_error_set(EVAS_GL_BAD_PARAMETER);
+        return NULL;
+     }
 
-   FINDSYM(_sym_glDisable, "glDisable", glsym_func_void);
-   FALLBAK(_sym_glDisable, glsym_func_void);
+   // Allocate surface structure
+   sfc = calloc(1, sizeof(EVGL_Surface));
+   if (!sfc)
+     {
+        ERR("Surface allocation failed.");
+        _evgl_error_set(EVAS_GL_BAD_ALLOC);
+        goto error;
+     }
 
-   FINDSYM(_sym_glDisableVertexAttribArray, "glDisableVertexAttribArray", glsym_func_void);
-   FALLBAK(_sym_glDisableVertexAttribArray, glsym_func_void);
+   // Set surface info
+   sfc->w = w;
+   sfc->h = h;
 
-   FINDSYM(_sym_glDrawArrays, "glDrawArrays", glsym_func_void);
-   FALLBAK(_sym_glDrawArrays, glsym_func_void);
+   // Set native buffer if it's passed
+   if (native)
+     {
+        sfc->native_tar = target;
+        sfc->native_buf = native;
+     }
 
-   FINDSYM(_sym_glDrawElements, "glDrawElements", glsym_func_void);
-   FALLBAK(_sym_glDrawElements, glsym_func_void);
+   // Check for Direct rendering override env var.
+   if (!evgl_engine->direct_override)
+     if ((s = getenv("EVAS_GL_DIRECT_OVERRIDE")))
+       {
+          WRN("DIRECT_OVERRIDE flag is set to '%s' for the whole application. "
+              "This should never be done except for debugging purposes.", s);
+          direct_override = atoi(s);
+          if (direct_override == 1)
+            evgl_engine->direct_override = 1;
+          else
+            evgl_engine->direct_override = -1;
+       }
 
-   FINDSYM(_sym_glEnable, "glEnable", glsym_func_void);
-   FALLBAK(_sym_glEnable, glsym_func_void);
+   // Check if Direct Rendering Memory Optimzation flag is on
+   // Creates resources on demand when it fallsback to fbo rendering
+   if (!evgl_engine->direct_mem_opt)
+     if ((s = getenv("EVAS_GL_DIRECT_MEM_OPT")))
+       {
+          WRN("DIRECT_MEMORY_OPTIMIZE flag is set to '%s' for the whole application. "
+              "This should never be done except for debugging purposes.", s);
+          direct_mem_opt = atoi(s);
+          if (direct_mem_opt == 1)
+            evgl_engine->direct_mem_opt = 1;
+          else
+            evgl_engine->direct_mem_opt = -1;
+       }
 
-   FINDSYM(_sym_glEnableVertexAttribArray, "glEnableVertexAttribArray", glsym_func_void);
-   FALLBAK(_sym_glEnableVertexAttribArray, glsym_func_void);
+   // Extra options for DR
+   if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT_MEMORY_OPTIMIZE)
+     {
+        DBG("Setting DIRECT_MEMORY_OPTIMIZE bit");
+        sfc->direct_mem_opt = EINA_TRUE;
+     }
+   else if (evgl_engine->direct_mem_opt == 1)
+     sfc->direct_mem_opt = EINA_TRUE;
 
-   FINDSYM(_sym_glFinish, "glFinish", glsym_func_void);
-   FALLBAK(_sym_glFinish, glsym_func_void);
+   if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT_OVERRIDE)
+     {
+        DBG("Setting DIRECT_OVERRIDE bit");
+        sfc->direct_override = EINA_TRUE;
+     }
+   else if (evgl_engine->direct_override == 1)
+     sfc->direct_override = EINA_TRUE;
 
-   FINDSYM(_sym_glFlush, "glFlush", glsym_func_void);
-   FALLBAK(_sym_glFlush, glsym_func_void);
+   // Set the internal config value
+   if (!_internal_config_set(eng_data, sfc, cfg))
+     {
+        ERR("Unsupported Format!");
+        _evgl_error_set(EVAS_GL_BAD_CONFIG);
+        goto error;
+     }
+   sfc->cfg = cfg;
 
-   FINDSYM(_sym_glFramebufferRenderbuffer, "glFramebufferRenderbuffer", glsym_func_void);
-   FALLBAK(_sym_glFramebufferRenderbuffer, glsym_func_void);
+   // Keep track of all the created surfaces
+   LKL(evgl_engine->lck);
+   evgl_engine->surfaces = eina_list_prepend(evgl_engine->surfaces, sfc);
 
-   FINDSYM(_sym_glFramebufferTexture2D, "glFramebufferTexture2D", glsym_func_void);
-   FALLBAK(_sym_glFramebufferTexture2D, glsym_func_void);
+   if (sfc->direct_fb_opt &&
+       (sfc->depth_fmt || sfc->stencil_fmt || sfc->depth_stencil_fmt))
+     {
+        need_reconfigure = !evgl_engine->direct_depth_stencil_surfaces;
+        evgl_engine->direct_depth_stencil_surfaces =
+          eina_list_prepend(evgl_engine->direct_depth_stencil_surfaces, sfc);
+     }
+   LKU(evgl_engine->lck);
 
-   FINDSYM(_sym_glFrontFace, "glFrontFace", glsym_func_void);
-   FALLBAK(_sym_glFrontFace, glsym_func_void);
+   if (need_reconfigure)
+     {
+        // See FIXME notice above in _internal_config_set
+        WRN("Surface reconfigure is not implemented yet");
+     }
 
-   FINDSYM(_sym_glGenBuffers, "glGenBuffers", glsym_func_void);
-   FALLBAK(_sym_glGenBuffers, glsym_func_void);
+   return sfc;
 
-   FINDSYM(_sym_glGenerateMipmap, "glGenerateMipmap", glsym_func_void);
-   FALLBAK(_sym_glGenerateMipmap, glsym_func_void);
+error:
+   if (sfc) free(sfc);
+   return NULL;
+}
 
-   FINDSYM(_sym_glGenFramebuffers, "glGenFramebuffers", glsym_func_void);
-   FALLBAK(_sym_glGenFramebuffers, glsym_func_void);
+void *
+evgl_pbuffer_surface_create(void *eng_data, Evas_GL_Config *cfg,
+                            int w, int h, const int *attrib_list)
+{
+   EVGL_Surface *sfc = NULL;
+   void *pbuffer;
 
-   FINDSYM(_sym_glGenRenderbuffers, "glGenRenderbuffers", glsym_func_void);
-   FALLBAK(_sym_glGenRenderbuffers, glsym_func_void);
+   // Check if engine is valid
+   if (!evgl_engine)
+     {
+        ERR("Invalid EVGL Engine!");
+        _evgl_error_set(EVAS_GL_BAD_ACCESS);
+        return NULL;
+     }
 
-   FINDSYM(_sym_glGenTextures, "glGenTextures", glsym_func_void);
-   FALLBAK(_sym_glGenTextures, glsym_func_void);
+   if (!cfg)
+     {
+        ERR("Invalid Config!");
+        _evgl_error_set(EVAS_GL_BAD_CONFIG);
+        return NULL;
+     }
 
-   FINDSYM(_sym_glGetActiveAttrib, "glGetActiveAttrib", glsym_func_void);
-   FALLBAK(_sym_glGetActiveAttrib, glsym_func_void);
+   if (!evgl_engine->funcs->pbuffer_surface_create)
+     {
+        ERR("Engine can not create PBuffers");
+        _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+        return NULL;
+     }
 
-   FINDSYM(_sym_glGetActiveUniform, "glGetActiveUniform", glsym_func_void);
-   FALLBAK(_sym_glGetActiveUniform, glsym_func_void);
+   // Allocate surface structure
+   sfc = calloc(1, sizeof(EVGL_Surface));
+   if (!sfc)
+     {
+        ERR("Surface allocation failed.");
+        _evgl_error_set(EVAS_GL_BAD_ALLOC);
+        goto error;
+     }
 
-   FINDSYM(_sym_glGetAttachedShaders, "glGetAttachedShaders", glsym_func_void);
-   FALLBAK(_sym_glGetAttachedShaders, glsym_func_void);
+   sfc->w = w;
+   sfc->h = h;
+   sfc->pbuffer.color_fmt = cfg->color_format;
+   sfc->pbuffer.is_pbuffer = EINA_TRUE;
 
-   FINDSYM(_sym_glGetAttribLocation, "glGetAttribLocation", glsym_func_int);
-   FALLBAK(_sym_glGetAttribLocation, glsym_func_int);
+   // Set the context current with resource context/surface
+   if (!_internal_resource_make_current(eng_data, NULL))
+     {
+        ERR("Error doing an internal resource make current");
+        goto error;
+     }
 
-   FINDSYM(_sym_glGetBooleanv, "glGetBooleanv", glsym_func_void);
-   FALLBAK(_sym_glGetBooleanv, glsym_func_void);
+   // If the surface is defined as RGB or RGBA, then create an FBO
+   if (sfc->pbuffer.color_fmt != EVAS_GL_NO_FBO)
+     {
+        // Set the internal config value
+        if (!_internal_config_set(eng_data, sfc, cfg))
+          {
+             ERR("Unsupported Format!");
+             _evgl_error_set(EVAS_GL_BAD_CONFIG);
+             goto error;
+          }
 
-   FINDSYM(_sym_glGetBufferParameteriv, "glGetBufferParameteriv", glsym_func_void);
-   FALLBAK(_sym_glGetBufferParameteriv, glsym_func_void);
+        // What is DR for PBuffer?
+        /*
+        if (sfc->direct_fb_opt)
+          {
+             if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT_MEMORY_OPTIMIZE)
+               sfc->direct_mem_opt = EINA_TRUE;
+             if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT_OVERRIDE)
+               sfc->direct_override = EINA_TRUE;
+          }
+        */
 
-   FINDSYM(_sym_glGetError, "glGetError", glsym_func_uint);
-   FALLBAK(_sym_glGetError, glsym_func_uint);
+        // Create internal buffers
+        if (!_surface_buffers_create(sfc))
+          {
+             ERR("Unable Create Specificed Surfaces.");
+             _evgl_error_set(EVAS_GL_BAD_ALLOC);
+             goto error;
+          };
 
-   FINDSYM(_sym_glGetFloatv, "glGetFloatv", glsym_func_void);
-   FALLBAK(_sym_glGetFloatv, glsym_func_void);
+        // Allocate resources for fallback unless the flag is on
+        if (!sfc->direct_mem_opt)
+          {
+             if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, 0))
+               {
+                  ERR("Unable Create Allocate Memory for Surface.");
+                  _evgl_error_set(EVAS_GL_BAD_ALLOC);
+                  goto error;
+               }
+          }
+     }
+   sfc->cfg = cfg;
 
-   FINDSYM(_sym_glGetFramebufferAttachmentParameteriv, "glGetFramebufferAttachmentParameteriv", glsym_func_void);
-   FALLBAK(_sym_glGetFramebufferAttachmentParameteriv, glsym_func_void);
+   // Not calling make_current
 
-   FINDSYM(_sym_glGetIntegerv, "glGetIntegerv", glsym_func_void);
-   FALLBAK(_sym_glGetIntegerv, glsym_func_void);
+   pbuffer = evgl_engine->funcs->pbuffer_surface_create
+     (eng_data, sfc, attrib_list);
 
-   FINDSYM(_sym_glGetProgramiv, "glGetProgramiv", glsym_func_void);
-   FALLBAK(_sym_glGetProgramiv, glsym_func_void);
+   if (!pbuffer)
+     {
+        ERR("Engine failed to create a PBuffer");
+        goto error;
+     }
 
-   FINDSYM(_sym_glGetProgramInfoLog, "glGetProgramInfoLog", glsym_func_void);
-   FALLBAK(_sym_glGetProgramInfoLog, glsym_func_void);
+   sfc->pbuffer.native_surface = pbuffer;
 
-   FINDSYM(_sym_glGetRenderbufferParameteriv, "glGetRenderbufferParameteriv", glsym_func_void);
-   FALLBAK(_sym_glGetRenderbufferParameteriv, glsym_func_void);
+   if (!evgl_engine->funcs->make_current(eng_data, NULL, NULL, 0))
+     {
+        ERR("Error doing make_current(NULL, NULL).");
+        goto error;
+     }
 
-   FINDSYM(_sym_glGetShaderiv, "glGetShaderiv", glsym_func_void);
-   FALLBAK(_sym_glGetShaderiv, glsym_func_void);
+   // Keep track of all the created surfaces
+   LKL(evgl_engine->lck);
+   evgl_engine->surfaces = eina_list_prepend(evgl_engine->surfaces, sfc);
+   LKU(evgl_engine->lck);
 
-   FINDSYM(_sym_glGetShaderInfoLog, "glGetShaderInfoLog", glsym_func_void);
-   FALLBAK(_sym_glGetShaderInfoLog, glsym_func_void);
+   return sfc;
 
-   FINDSYM(_sym_glGetShaderPrecisionFormat, "glGetShaderPrecisionFormat", glsym_func_void);
-   FALLBAK(_sym_glGetShaderPrecisionFormat, glsym_func_void);
+error:
+   free(sfc);
+   return NULL;
+}
 
-   FINDSYM(_sym_glGetShaderSource, "glGetShaderSource", glsym_func_void);
-   FALLBAK(_sym_glGetShaderSource, glsym_func_void);
+int
+evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc)
+{
+   EVGL_Resource *rsc;
+   Eina_Bool need_reconfigure = EINA_FALSE;
 
-   FINDSYM(_sym_glGetString, "glGetString", glsym_func_uchar_ptr);
-   FALLBAK(_sym_glGetString, glsym_func_const_uchar_ptr);
+   // Check input parameter
+   if ((!evgl_engine) || (!sfc))
+     {
+        ERR("Invalid input data.  Engine: %p  Surface:%p", evgl_engine, sfc);
+        return 0;
+     }
 
-   FINDSYM(_sym_glGetTexParameterfv, "glGetTexParameterfv", glsym_func_void);
-   FALLBAK(_sym_glGetTexParameterfv, glsym_func_void);
+   // Retrieve the resource object
+   if (!(rsc = _evgl_tls_resource_get()))
+     {
+        ERR("Error retrieving resource from TLS");
+        return 0;
+     }
 
-   FINDSYM(_sym_glGetTexParameteriv, "glGetTexParameteriv", glsym_func_void);
-   FALLBAK(_sym_glGetTexParameteriv, glsym_func_void);
+   // Make current to current context to destroy surface buffers
+   if (!_internal_resource_make_current(eng_data, rsc->current_ctx))
+     {
+        ERR("Error doing an internal resource make current");
+        return 0;
+     }
 
-   FINDSYM(_sym_glGetUniformfv, "glGetUniformfv", glsym_func_void);
-   FALLBAK(_sym_glGetUniformfv, glsym_func_void);
+   // Destroy created buffers
+   if (!_surface_buffers_destroy(eng_data, sfc))
+     {
+        ERR("Error deleting surface resources.");
+        return 0;
+     }
 
-   FINDSYM(_sym_glGetUniformiv, "glGetUniformiv", glsym_func_void);
-   FALLBAK(_sym_glGetUniformiv, glsym_func_void);
+   // Destroy surface used for 1.1
+   if (sfc->gles1_indirect)
+     {
+        int ret;
+        if (!evgl_engine->funcs->gles1_surface_destroy)
+          {
+             ERR("Error destroying GLES 1.x surface");
+             return 0;
+          }
 
-   FINDSYM(_sym_glGetUniformLocation, "glGetUniformLocation", glsym_func_int);
-   FALLBAK(_sym_glGetUniformLocation, glsym_func_int);
+        INF("Destroying special surface used for GLES 1.x rendering");
+        ret = evgl_engine->funcs->gles1_surface_destroy(eng_data, sfc);
 
-   FINDSYM(_sym_glGetVertexAttribfv, "glGetVertexAttribfv", glsym_func_void);
-   FALLBAK(_sym_glGetVertexAttribfv, glsym_func_void);
+        if (!ret)
+          {
+             ERR("Engine failed to destroy a GLES1.x Surface.");
+             return ret;
+          }
+     }
 
-   FINDSYM(_sym_glGetVertexAttribiv, "glGetVertexAttribiv", glsym_func_void);
-   FALLBAK(_sym_glGetVertexAttribiv, glsym_func_void);
+   // Destroy PBuffer surfaces
+   if (sfc->pbuffer.native_surface)
+     {
+        int ret;
 
-   FINDSYM(_sym_glGetVertexAttribPointerv, "glGetVertexAttribPointerv", glsym_func_void);
-   FALLBAK(_sym_glGetVertexAttribPointerv, glsym_func_void);
+        if (sfc->pbuffer.fbo)
+          glDeleteFramebuffers(1, &sfc->pbuffer.fbo);
 
-   FINDSYM(_sym_glHint, "glHint", glsym_func_void);
-   FALLBAK(_sym_glHint, glsym_func_void);
+        ret = evgl_engine->funcs->surface_destroy(eng_data, sfc->pbuffer.native_surface);
+        LKL(evgl_engine->lck);
+        evgl_engine->surfaces = eina_list_remove(evgl_engine->surfaces, sfc);
+        LKU(evgl_engine->lck);
+        free(sfc);
 
-   FINDSYM(_sym_glIsBuffer, "glIsBuffer", glsym_func_uchar);
-   FALLBAK(_sym_glIsBuffer, glsym_func_uchar);
+        if (!ret) ERR("Engine failed to destroy a PBuffer.");
+        return ret;
+     }
 
-   FINDSYM(_sym_glIsEnabled, "glIsEnabled", glsym_func_uchar);
-   FALLBAK(_sym_glIsEnabled, glsym_func_uchar);
+   if ((rsc->current_ctx) && (rsc->current_ctx->current_sfc == sfc))
+     {
+        if (evgl_engine->api_debug_mode)
+          {
+             ERR("The surface is still current before it's being destroyed.");
+             ERR("Doing make_current(NULL, NULL)");
+          }
+        else
+          {
+             WRN("The surface is still current before it's being destroyed.");
+             WRN("Doing make_current(NULL, NULL)");
+          }
+        evgl_make_current(eng_data, NULL, NULL);
+     }
+   else
+     {
+        if (!evgl_engine->funcs->make_current(eng_data, NULL, NULL, 0))
+          {
+             ERR("Error doing make_current(NULL, NULL).");
+             return 0;
+          }
+     }
 
-   FINDSYM(_sym_glIsFramebuffer, "glIsFramebuffer", glsym_func_uchar);
-   FALLBAK(_sym_glIsFramebuffer, glsym_func_uchar);
+   // Remove it from the list
+   LKL(evgl_engine->lck);
+   evgl_engine->surfaces = eina_list_remove(evgl_engine->surfaces, sfc);
 
-   FINDSYM(_sym_glIsProgram, "glIsProgram", glsym_func_uchar);
-   FALLBAK(_sym_glIsProgram, glsym_func_uchar);
+   if (sfc->direct_fb_opt &&
+       (sfc->depth_fmt || sfc->stencil_fmt || sfc->depth_stencil_fmt))
+     {
+        Eina_List *found;
+        found = eina_list_data_find_list(evgl_engine->direct_depth_stencil_surfaces, sfc);
+        need_reconfigure = !!found;
+        evgl_engine->direct_depth_stencil_surfaces =
+          eina_list_remove_list(evgl_engine->direct_depth_stencil_surfaces, found);
+     }
+   LKU(evgl_engine->lck);
 
-   FINDSYM(_sym_glIsRenderbuffer, "glIsRenderbuffer", glsym_func_uchar);
-   FALLBAK(_sym_glIsRenderbuffer, glsym_func_uchar);
+   if (need_reconfigure)
+     {
+        // See FIXME notice above in _internal_config_set
+        WRN("Surface reconfigure is not implemented yet");
+     }
 
-   FINDSYM(_sym_glIsShader, "glIsShader", glsym_func_uchar);
-   FALLBAK(_sym_glIsShader, glsym_func_uchar);
+   free(sfc);
+   sfc = NULL;
 
-   FINDSYM(_sym_glIsTexture, "glIsTexture", glsym_func_uchar);
-   FALLBAK(_sym_glIsTexture, glsym_func_uchar);
+   return 1;
 
-   FINDSYM(_sym_glLineWidth, "glLineWidth", glsym_func_void);
-   FALLBAK(_sym_glLineWidth, glsym_func_void);
+}
 
-   FINDSYM(_sym_glLinkProgram, "glLinkProgram", glsym_func_void);
-   FALLBAK(_sym_glLinkProgram, glsym_func_void);
+void *
+evgl_context_create(void *eng_data, EVGL_Context *share_ctx,
+                    Evas_GL_Context_Version version)
+{
+   EVGL_Context *ctx   = NULL;
+   EVGL_Resource *rsc  = NULL;
 
-   FINDSYM(_sym_glPixelStorei, "glPixelStorei", glsym_func_void);
-   FALLBAK(_sym_glPixelStorei, glsym_func_void);
+   // Check the input
+   if (!evgl_engine)
+     {
+        ERR("Invalid EVGL Engine!");
+        _evgl_error_set(EVAS_GL_BAD_ACCESS);
+        return NULL;
+     }
 
-   FINDSYM(_sym_glPolygonOffset, "glPolygonOffset", glsym_func_void);
-   FALLBAK(_sym_glPolygonOffset, glsym_func_void);
+   if (!(rsc = _evgl_tls_resource_get()))
+     {
+        ERR("Error creating resources in tls.");
+        return NULL;
+     }
 
-   FINDSYM(_sym_glReadPixels, "glReadPixels", glsym_func_void);
-   FALLBAK(_sym_glReadPixels, glsym_func_void);
+   // Allocate context object
+   ctx = calloc(1, sizeof(EVGL_Context));
+   if (!ctx)
+     {
+        ERR("Error allocating context object.");
+        _evgl_error_set(EVAS_GL_BAD_ALLOC);
+        return NULL;
+     }
 
-   FINDSYM(_sym_glReleaseShaderCompiler, "glReleaseShaderCompiler", glsym_func_void);
-   FALLBAK(_sym_glReleaseShaderCompiler, glsym_func_void);
+   ctx->version = version;
 
-   FINDSYM(_sym_glRenderbufferStorage, "glRenderbufferStorage", glsym_func_void);
-   FALLBAK(_sym_glRenderbufferStorage, glsym_func_void);
+   // Call engine create context
+   if (share_ctx)
+     ctx->context = evgl_engine->funcs->context_create(eng_data, share_ctx->context, version);
+   else
+     ctx->context = evgl_engine->funcs->context_create(eng_data, NULL, version);
 
-   FINDSYM(_sym_glSampleCoverage, "glSampleCoverage", glsym_func_void);
-   FALLBAK(_sym_glSampleCoverage, glsym_func_void);
+   // Call engine create context
+   if (!ctx->context)
+     {
+        ERR("Error creating context from the Engine.");
+        free(ctx);
+        return NULL;
+     }
 
-   FINDSYM(_sym_glScissor, "glScissor", glsym_func_void);
-   FALLBAK(_sym_glScissor, glsym_func_void);
+   // Keep track of all the created context
+   LKL(evgl_engine->lck);
+   evgl_engine->contexts = eina_list_prepend(evgl_engine->contexts, ctx);
+   LKU(evgl_engine->lck);
 
-   FINDSYM(_sym_glShaderBinary, "glShaderBinary", glsym_func_void);
-   FALLBAK(_sym_glShaderBinary, glsym_func_void);
+   return ctx;
+}
 
-   FINDSYM(_sym_glShaderSource, "glShaderSource", glsym_func_void);
-   FALLBAK(_sym_glShaderSource, glsym_func_void);
 
-   FINDSYM(_sym_glStencilFunc, "glStencilFunc", glsym_func_void);
-   FALLBAK(_sym_glStencilFunc, glsym_func_void);
+int
+evgl_context_destroy(void *eng_data, EVGL_Context *ctx)
+{
+   // Check the input
+   if ((!evgl_engine) || (!ctx))
+     {
+        ERR("Invalid input data.  Engine: %p  Context:%p", evgl_engine, ctx);
+        return 0;
+     }
 
-   FINDSYM(_sym_glStencilFuncSeparate, "glStencilFuncSeparate", glsym_func_void);
-   FALLBAK(_sym_glStencilFuncSeparate, glsym_func_void);
+   // Set the context current with resource context/surface
+   if (!_internal_resource_make_current(eng_data, NULL))
+     {
+        ERR("Error doing an internal resource make current");
+        return 0;
+     }
 
-   FINDSYM(_sym_glStencilMask, "glStencilMask", glsym_func_void);
-   FALLBAK(_sym_glStencilMask, glsym_func_void);
+   // Delete the FBO
+   if (ctx->surface_fbo)
+      glDeleteFramebuffers(1, &ctx->surface_fbo);
 
-   FINDSYM(_sym_glStencilMaskSeparate, "glStencilMaskSeparate", glsym_func_void);
-   FALLBAK(_sym_glStencilMaskSeparate, glsym_func_void);
+   // Unset the currrent context
+   if (!evgl_engine->funcs->make_current(eng_data, NULL, NULL, 0))
+     {
+        ERR("Error doing make_current(NULL, NULL).");
+        return 0;
+     }
 
-   FINDSYM(_sym_glStencilOp, "glStencilOp", glsym_func_void);
-   FALLBAK(_sym_glStencilOp, glsym_func_void);
+   // Destroy GLES1 indirect rendering context
+   if (ctx->gles1_context &&
+       !evgl_engine->funcs->context_destroy(eng_data, ctx->context))
+     {
+        ERR("Error destroying the GLES1 context.");
+        return 0;
+     }
 
-   FINDSYM(_sym_glStencilOpSeparate, "glStencilOpSeparate", glsym_func_void);
-   FALLBAK(_sym_glStencilOpSeparate, glsym_func_void);
+   // Destroy engine context
+   if (!evgl_engine->funcs->context_destroy(eng_data, ctx->context))
+     {
+        ERR("Error destroying the engine context.");
+        return 0;
+     }
 
-   FINDSYM(_sym_glTexImage2D, "glTexImage2D", glsym_func_void);
-   FALLBAK(_sym_glTexImage2D, glsym_func_void);
+   // Remove it from the list
+   LKL(evgl_engine->lck);
+   evgl_engine->contexts = eina_list_remove(evgl_engine->contexts, ctx);
+   LKU(evgl_engine->lck);
 
-   FINDSYM(_sym_glTexParameterf, "glTexParameterf", glsym_func_void);
-   FALLBAK(_sym_glTexParameterf, glsym_func_void);
+   // Free context
+   free(ctx);
+   ctx = NULL;
 
-   FINDSYM(_sym_glTexParameterfv, "glTexParameterfv", glsym_func_void);
-   FALLBAK(_sym_glTexParameterfv, glsym_func_void);
+   return 1;
+}
 
-   FINDSYM(_sym_glTexParameteri, "glTexParameteri", glsym_func_void);
-   FALLBAK(_sym_glTexParameteri, glsym_func_void);
 
-   FINDSYM(_sym_glTexParameteriv, "glTexParameteriv", glsym_func_void);
-   FALLBAK(_sym_glTexParameteriv, glsym_func_void);
+int
+evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
+{
+   EVGL_Resource *rsc;
+   int curr_fbo = 0;
 
-   FINDSYM(_sym_glTexSubImage2D, "glTexSubImage2D", glsym_func_void);
-   FALLBAK(_sym_glTexSubImage2D, glsym_func_void);
+   // Check the input validity. If either sfc or ctx is NULL, it's also error.
+   if ( (!evgl_engine) ||
+        ((!sfc) && ctx) ||
+        (sfc && (!ctx)) )
+     {
+        ERR("Invalid Inputs. Engine: %p  Surface: %p   Context: %p!", evgl_engine, sfc, ctx);
+        if(!sfc) _evgl_error_set(EVAS_GL_BAD_SURFACE);
+        if(!ctx) _evgl_error_set(EVAS_GL_BAD_CONTEXT);
+        return 0;
+     }
 
-   FINDSYM(_sym_glUniform1f, "glUniform1f", glsym_func_void);
-   FALLBAK(_sym_glUniform1f, glsym_func_void);
+   // Get TLS Resources
+   if (!(rsc = _evgl_tls_resource_get()))
+     {
+        DBG("Creating new TLS for this thread."); // eina_thread_self()
+        rsc = _evgl_tls_resource_create(eng_data);
+        if (!rsc) return 0;
+     }
 
-   FINDSYM(_sym_glUniform1fv, "glUniform1fv", glsym_func_void);
-   FALLBAK(_sym_glUniform1fv, glsym_func_void);
+   // Unset
+   if ((!sfc) && (!ctx))
+     {
+        if (rsc->current_ctx)
+          {
+             if (rsc->direct.partial.enabled)
+                evgl_direct_partial_render_end();
+          }
 
-   FINDSYM(_sym_glUniform1i, "glUniform1i", glsym_func_void);
-   FALLBAK(_sym_glUniform1i, glsym_func_void);
+        if (!evgl_engine->funcs->make_current(eng_data, NULL, NULL, 0))
+          {
+             ERR("Error doing make_current(NULL, NULL).");
+             return 0;
+          }
 
-   FINDSYM(_sym_glUniform1iv, "glUniform1iv", glsym_func_void);
-   FALLBAK(_sym_glUniform1iv, glsym_func_void);
+        // FIXME -- What is this "FIXME" about?
+        if (rsc->current_ctx)
+          {
+             rsc->current_ctx->current_sfc = NULL;
+             rsc->current_ctx = NULL;
+             rsc->current_eng = NULL;
+          }
+        return 1;
+     }
 
-   FINDSYM(_sym_glUniform2f, "glUniform2f", glsym_func_void);
-   FALLBAK(_sym_glUniform2f, glsym_func_void);
+   // Disable partial rendering for previous context
+   if ((rsc->current_ctx) && (rsc->current_ctx != ctx))
+     {
+        evas_gl_common_tiling_done(NULL);
+        rsc->current_ctx->partial_render = 0;
+     }
 
-   FINDSYM(_sym_glUniform2fv, "glUniform2fv", glsym_func_void);
-   FALLBAK(_sym_glUniform2fv, glsym_func_void);
+   // Do a make current
+   if (!_internal_resource_make_current(eng_data, ctx))
+     {
+        ERR("Error doing a make current with internal surface. Context: %p", ctx);
+        _evgl_error_set(EVAS_GL_BAD_CONTEXT);
+        return 0;
+     }
+   sfc->current_ctx = ctx;
+   rsc->current_ctx = ctx;
+   rsc->current_eng = eng_data;
 
-   FINDSYM(_sym_glUniform2i, "glUniform2i", glsym_func_void);
-   FALLBAK(_sym_glUniform2i, glsym_func_void);
+   // Check whether extensions are supported for the current context version
+   // to use fbo & egl image passing to evas
+   if (!ctx->extension_checked)
+     {
+        if (!evgl_api_get(ctx->version))
+          {
+             ERR("Unable to get the list of GL APIs for version %d", ctx->version);
+             _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+             return 0;
+          }
 
-   FINDSYM(_sym_glUniform2iv, "glUniform2iv", glsym_func_void);
-   FALLBAK(_sym_glUniform2iv, glsym_func_void);
+        if (!_context_ext_check(ctx))
+          {
+             ERR("Unable to check required extension for the current context");
+             _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+             return 0;
+          }
+     }
 
-   FINDSYM(_sym_glUniform3f, "glUniform3f", glsym_func_void);
-   FALLBAK(_sym_glUniform3f, glsym_func_void);
+   if (!sfc->color_buf && !_surface_buffers_create(sfc))
+     {
+        ERR("Unable to create specified surfaces.");
+        _evgl_error_set(EVAS_GL_BAD_ALLOC);
+        return 0;
+     };
 
-   FINDSYM(_sym_glUniform3fv, "glUniform3fv", glsym_func_void);
-   FALLBAK(_sym_glUniform3fv, glsym_func_void);
+   // Allocate or free resources depending on what mode (direct of fbo) it's
+   // running only if the env var EVAS_GL_DIRECT_MEM_OPT is set.
+   if (sfc->direct_mem_opt)
+     {
+        if (_evgl_direct_renderable(rsc, sfc))
+          {
+             // Destroy created resources
+             if (sfc->buffers_allocated)
+               {
+                  if (!_surface_buffers_destroy(eng_data, sfc))
+                    {
+                       ERR("Unable to destroy surface buffers!");
+                       _evgl_error_set(EVAS_GL_BAD_ALLOC);
+                       return 0;
+                    }
+                  sfc->buffers_allocated = 0;
+               }
+          }
+        else
+          {
+             if (sfc->direct_fb_opt)
+               {
+                  DBG("Not creating fallback surfaces even though it should. Use at OWN discretion!");
+               }
+             else
+               {
+                  // Create internal buffers if not yet created
+                  if (!sfc->buffers_allocated)
+                    {
+                       if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, 1))
+                         {
+                            ERR("Unable Create Specificed Surfaces.  Unsupported format!");
+                            _evgl_error_set(EVAS_GL_BAD_ALLOC);
+                            return 0;
+                         };
+                       sfc->buffers_allocated = 1;
+                    }
+               }
+          }
+     }
+   else
+     {
+        if (!sfc->buffers_allocated)
+          {
+             if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, 0))
+               {
+                  ERR("Unable Create Allocate Memory for Surface.");
+                  _evgl_error_set(EVAS_GL_BAD_ALLOC);
+                  return 0;
+               }
+             sfc->buffers_allocated = 1;
+          }
+     }
 
-   FINDSYM(_sym_glUniform3i, "glUniform3i", glsym_func_void);
-   FALLBAK(_sym_glUniform3i, glsym_func_void);
+   if (ctx->pixmap_image_supported)
+     {
+        // Direct Rendering
+        if (_evgl_direct_renderable(rsc, sfc))
+          {
+             // Transition from indirect rendering to direct rendering
+             if (!rsc->direct.rendered)
+               {
+                  // Restore viewport and scissor test to direct rendering mode
+                  glViewport(ctx->viewport_direct[0], ctx->viewport_direct[1], ctx->viewport_direct[2], ctx->viewport_direct[3]);
+                  if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+                    glEnable(GL_SCISSOR_TEST);
+               }
+             rsc->direct.rendered = 1;
+          }
+        else
+          {
+             if (!sfc->gles1_sfc)
+               {
+                  evgl_engine->funcs->gles1_surface_create(eng_data, sfc, sfc->cfg, sfc->w, sfc->h);
+                  sfc->egl_image = _egl_image_create(NULL, EVAS_GL_NATIVE_PIXMAP, sfc->gles1_sfc_native);
+               }
+             if (!ctx->gles1_context)
+               {
+                  ctx->gles1_context =
+                        evgl_engine->funcs->gles1_context_create(eng_data, ctx, sfc);
+               }
+             if (!evgl_engine->funcs->make_current(eng_data, sfc->gles1_sfc,
+                                                   ctx->gles1_context, EINA_TRUE))
+               {
+                  ERR("Failed to make current with GLES1 indirect surface.");
+                  return 0;
+               }
 
-   FINDSYM(_sym_glUniform3iv, "glUniform3iv", glsym_func_void);
-   FALLBAK(_sym_glUniform3iv, glsym_func_void);
+             // Transition from direct rendering to pixmap surface rendering
+             if (rsc->direct.rendered)
+               {
+                  glViewport(ctx->viewport_coord[0], ctx->viewport_coord[1], ctx->viewport_coord[2], ctx->viewport_coord[3]);
+                  if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+                    glDisable(GL_SCISSOR_TEST);
+             }
 
-   FINDSYM(_sym_glUniform4f, "glUniform4f", glsym_func_void);
-   FALLBAK(_sym_glUniform4f, glsym_func_void);
+             ctx->current_fbo = 0;
+             rsc->direct.rendered = 0;
+          }
+     }
+   else
+     {
+        Eina_Bool use_extension = EINA_FALSE;
+        if ((ctx->version == EVAS_GL_GLES_1_X) && (gles1_funcs))
+          use_extension = EINA_TRUE;
 
-   FINDSYM(_sym_glUniform4fv, "glUniform4fv", glsym_func_void);
-   FALLBAK(_sym_glUniform4fv, glsym_func_void);
+        // Normal FBO Rendering
+        // Create FBO if it hasn't been created
+        if (!ctx->surface_fbo)
+          _framebuffer_create(&ctx->surface_fbo, use_extension);
 
-   FINDSYM(_sym_glUniform4i, "glUniform4i", glsym_func_void);
-   FALLBAK(_sym_glUniform4i, glsym_func_void);
+        // Direct Rendering
+        if (_evgl_direct_renderable(rsc, sfc))
+          {
+             if (rsc->direct.map_tex)
+               {
+                  if (rsc->direct.partial.enabled)
+                    evgl_direct_partial_render_end();
+                  _framebuffer_bind(ctx->surface_fbo, use_extension);
+                  ctx->current_fbo = ctx->surface_fbo;
+                  _texture_attach_2d(rsc->direct.map_tex, GL_COLOR_ATTACHMENT0, 0, sfc->msaa_samples, use_extension);
+                  ctx->map_tex = rsc->direct.map_tex;
+                }
+              else
+                {
+                   // This is to transition from FBO rendering to direct rendering
+                   glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo);
+                   if (ctx->surface_fbo == (GLuint)curr_fbo)
+                     {
+                        _framebuffer_bind(0, use_extension);
+                        ctx->current_fbo = 0;
+                     }
+                   else if (ctx->current_sfc && (ctx->current_sfc->pbuffer.is_pbuffer))
+                     {
+                        // Using the same context, we were rendering on a pbuffer
+                        _framebuffer_bind(0, use_extension);
+                        ctx->current_fbo = 0;
+                     }
+
+                   if (ctx->current_fbo == 0)
+                     {
+                        // If master clip is set and clip is greater than 0, do partial render
+                        if (rsc->direct.partial.enabled)
+                          {
+                             if (!ctx->partial_render)
+                               {
+                                  evgl_direct_partial_render_start();
+                                  ctx->partial_render = 1;
+                               }
+                          }
+                     }
+                   ctx->map_tex = 0;
+                }
+
+             rsc->direct.rendered = 1;
+          }
+        else if (sfc->pbuffer.native_surface)
+          {
+             // Call end tiling
+             if (rsc->direct.partial.enabled)
+                evgl_direct_partial_render_end();
+
+             if (sfc->color_buf)
+               {
+                  if (!sfc->pbuffer.fbo)
+                    {
+                       _framebuffer_create(&sfc->pbuffer.fbo, use_extension);
+                       GLERRLOG();
+                    }
+                  if (!_surface_buffers_fbo_set(sfc, sfc->pbuffer.fbo, use_extension))
+                    ERR("Could not detach current FBO");
+               }
 
-   FINDSYM(_sym_glUniform4iv, "glUniform4iv", glsym_func_void);
-   FALLBAK(_sym_glUniform4iv, glsym_func_void);
+             evgl_engine->funcs->make_current(eng_data, sfc->pbuffer.native_surface,
+                                              ctx->context, EINA_TRUE);
 
-   FINDSYM(_sym_glUniformMatrix2fv, "glUniformMatrix2fv", glsym_func_void);
-   FALLBAK(_sym_glUniformMatrix2fv, glsym_func_void);
+             // Bind to the previously bound buffer (may be 0)
+             if (ctx->current_fbo)
+               {
+                  _framebuffer_bind(ctx->current_fbo, use_extension);
+                  GLERRLOG();
+               }
 
-   FINDSYM(_sym_glUniformMatrix3fv, "glUniformMatrix3fv", glsym_func_void);
-   FALLBAK(_sym_glUniformMatrix3fv, glsym_func_void);
+             rsc->direct.rendered = 0;
+          }
+        else
+          {
+             // Attach fbo and the buffers
+             if ((rsc->current_ctx != ctx) || (ctx->current_sfc != sfc) || (rsc->direct.rendered))
+               {
+                  if ((sfc->direct_mem_opt) && (sfc->direct_fb_opt))
+                    {
+                       DBG("Not creating fallback surfaces even though it should. Use at OWN discretion!");
+                    }
+                  else
+                    {
+                       // If it's transitioning from direct render to fbo render
+                       // Call end tiling
+                       if (rsc->direct.partial.enabled)
+                          evgl_direct_partial_render_end();
+
+                       if (!_surface_buffers_fbo_set(sfc, ctx->surface_fbo, use_extension))
+                         {
+                            ERR("Attaching buffers to context fbo failed. Engine: %p  Surface: %p Context FBO: %u", evgl_engine, sfc, ctx->surface_fbo);
+                            _evgl_error_set(EVAS_GL_BAD_CONTEXT);
+                            return 0;
+                         }
+                    }
+
+                  // Bind to the previously bound buffer
+                  if (ctx->current_fbo)
+                    {
+                       _framebuffer_bind(ctx->current_fbo, use_extension);
+                       GLERRLOG();
+                    }
+               }
+             rsc->direct.rendered = 0;
+          }
+     }
 
-   FINDSYM(_sym_glUniformMatrix4fv, "glUniformMatrix4fv", glsym_func_void);
-   FALLBAK(_sym_glUniformMatrix4fv, glsym_func_void);
+   ctx->current_sfc = sfc;
+   rsc->current_ctx = ctx;
+   rsc->current_eng = eng_data;
 
-   FINDSYM(_sym_glUseProgram, "glUseProgram", glsym_func_void);
-   FALLBAK(_sym_glUseProgram, glsym_func_void);
 
-   FINDSYM(_sym_glValidateProgram, "glValidateProgram", glsym_func_void);
-   FALLBAK(_sym_glValidateProgram, glsym_func_void);
+   //_surface_context_list_print(evgl_engine);
 
-   FINDSYM(_sym_glVertexAttrib1f, "glVertexAttrib1f", glsym_func_void);
-   FALLBAK(_sym_glVertexAttrib1f, glsym_func_void);
+   return 1;
+}
 
-   FINDSYM(_sym_glVertexAttrib1fv, "glVertexAttrib1fv", glsym_func_void);
-   FALLBAK(_sym_glVertexAttrib1fv, glsym_func_void);
+const char *
+evgl_string_query(int name)
+{
+   switch(name)
+     {
+      case EVAS_GL_EXTENSIONS:
+         return evgl_api_ext_string_get(EINA_FALSE, EINA_FALSE);
+      default:
+         return "";
+     };
+}
 
-   FINDSYM(_sym_glVertexAttrib2f, "glVertexAttrib2f", glsym_func_void);
-   FALLBAK(_sym_glVertexAttrib2f, glsym_func_void);
+void
+evgl_safe_extension_add(const char *name, void *funcptr)
+{
+   if (!name) return;
 
-   FINDSYM(_sym_glVertexAttrib2fv, "glVertexAttrib2fv", glsym_func_void);
-   FALLBAK(_sym_glVertexAttrib2fv, glsym_func_void);
+   if (evgl_engine->api_debug_mode)
+     DBG("Whitelisting function [%p] %s", funcptr, name);
 
-   FINDSYM(_sym_glVertexAttrib3f, "glVertexAttrib3f", glsym_func_void);
-   FALLBAK(_sym_glVertexAttrib3f, glsym_func_void);
+   if (funcptr)
+     eina_hash_set(evgl_engine->safe_extensions, name, funcptr);
+   else
+     eina_hash_set(evgl_engine->safe_extensions, name, (void *) 0x1);
+}
 
-   FINDSYM(_sym_glVertexAttrib3fv, "glVertexAttrib3fv", glsym_func_void);
-   FALLBAK(_sym_glVertexAttrib3fv, glsym_func_void);
+Eina_Bool
+evgl_safe_extension_get(const char *name, void **pfuncptr)
+{
+   static Eina_Bool _unsafe_checked = EINA_FALSE, _unsafe = EINA_FALSE;
+   void *func;
 
-   FINDSYM(_sym_glVertexAttrib4f, "glVertexAttrib4f", glsym_func_void);
-   FALLBAK(_sym_glVertexAttrib4f, glsym_func_void);
+   if (!name || !*name)
+     return EINA_FALSE;
 
-   FINDSYM(_sym_glVertexAttrib4fv, "glVertexAttrib4fv", glsym_func_void);
-   FALLBAK(_sym_glVertexAttrib4fv, glsym_func_void);
+   // use this for debugging or if you want to break everything
+   if (!_unsafe_checked)
+     {
+        _unsafe_checked = EINA_TRUE;
+        if (getenv("EVAS_GL_UNSAFE_EXTENSIONS"))
+          _unsafe = EINA_TRUE;
+     }
 
-   FINDSYM(_sym_glVertexAttribPointer, "glVertexAttribPointer", glsym_func_void);
-   FALLBAK(_sym_glVertexAttribPointer, glsym_func_void);
+   if (_unsafe)
+     return EINA_TRUE;
 
-   FINDSYM(_sym_glViewport, "glViewport", glsym_func_void);
-   FALLBAK(_sym_glViewport, glsym_func_void);
+   func = eina_hash_find(evgl_engine->safe_extensions, name);
+   if (!func) return EINA_FALSE;
 
-#undef FINDSYM
-#undef FALLBAK
+   // this is for safe extensions of which we didn't resolve the address
+   if (func == (void *) 0x1)
+     {
+        if (pfuncptr) *pfuncptr = NULL;
+        return EINA_TRUE;
+     }
 
-   return 1;
+   if (pfuncptr) *pfuncptr = func;
+   return EINA_TRUE;
 }
 
-static int
-gl_lib_init(void)
+void *
+evgl_native_surface_buffer_get(EVGL_Surface *sfc)
 {
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   //------------------------------------------------//
-   // Open EGL Library as EGL is separate
-   egl_lib_handle = dlopen("libEGL.so.1", RTLD_NOW|RTLD_GLOBAL);
-   if (!egl_lib_handle)
-      egl_lib_handle = dlopen("libEGL.so", RTLD_NOW|RTLD_GLOBAL);
-   if (!egl_lib_handle)
+   if (!evgl_engine)
      {
-        ERR("%s\n", dlerror());
-        return 0;
+        ERR("Invalid input data.  Engine: %p", evgl_engine);
+        return NULL;
      }
 
-   // use gl_lib handle for GL symbols
-   gl_lib_handle = dlopen("libGLESv2.so.1", RTLD_NOW);
-   if (!gl_lib_handle)
-      gl_lib_handle = dlopen("libGLESv2.so", RTLD_NOW);
-   if (!gl_lib_handle)
+   return sfc->egl_image;
+}
+
+int
+evgl_native_surface_yinvert_get(EVGL_Surface *sfc)
+{
+   int ret = 0;
+   if (!evgl_engine)
      {
-        ERR("%s\n", dlerror());
+        ERR("Invalid input data.  Engine: %p", evgl_engine);
         return 0;
      }
-   //------------------------------------------------//
 
-#else // GLX
+   if (sfc->gles1_indirect)
+      ret = sfc->yinvert;
 
+   return ret;
+}
 
-   // use gl_lib handle for both GLX and GL symbols
-   //gl_lib_handle = dlopen("/usr/lib/libGL.so", RTLD_NOW);
-   gl_lib_handle = dlopen("libGL.so.1", RTLD_NOW);
-   if (!gl_lib_handle)
-      gl_lib_handle = dlopen("libGL.so", RTLD_NOW);
-   if (!gl_lib_handle)
+int
+evgl_native_surface_get(EVGL_Surface *sfc, Evas_Native_Surface *ns)
+{
+   // Check the input
+   if ((!evgl_engine) || (!ns))
      {
-        ERR("%s\n", dlerror());
+        ERR("Invalid input data.  Engine: %p  NS:%p", evgl_engine, ns);
         return 0;
      }
 
-   //------------------------------------------------//
-
-#endif // defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-
-   if (!glue_sym_init()) return 0;
-   if (!gl_sym_init()) return 0;
+     ns->type = EVAS_NATIVE_SURFACE_EVASGL;
+     ns->version = EVAS_NATIVE_SURFACE_VERSION;
+     ns->data.evasgl.surface = sfc;
 
    return 1;
 }
 
+int
+evgl_direct_rendered()
+{
+   EVGL_Resource *rsc;
 
-//----------------------------------------------------------------//
-//                      Override Functions                        //
-//----------------------------------------------------------------//
-#define EVASGLUE_API_OVERRIDE(func, api_pre, prefix) \
-   api_pre##func = prefix##func
+   if (!(rsc=_evgl_tls_resource_get())) return 0;
 
-#define EVASGL_API_OVERRIDE(func, api, prefix) \
-     (api)->func = prefix##func
+   return rsc->direct.rendered;
+}
 
-static void
-override_glue_normal_path()
+/*
+ * This function can tell the engine whether a surface can be directly
+ * rendered to the Evas, despite any window rotation. For that purpose,
+ * we let the engine know the surface flags for this texture
+ */
+Eina_Bool
+evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns,
+                                    Eina_Bool *direct_render,
+                                    Eina_Bool *client_side_rotation,
+                                    Eina_Bool *direct_override)
 {
-#ifdef EVAS_GL_NAME_MANGLE
-#  define N_ORD(f) EVASGLUE_API_OVERRIDE(f, glsym_, _sym_) // GL Normal Path
-#  define W_ORD(f) EVASGLUE_API_OVERRIDE(f, glsym_, evgl_) // GL Wrapped Path
-#else
-#  define N_ORD(f) EVASGLUE_API_OVERRIDE(f,, _sym_) // GL Normal Path
-#  define W_ORD(f) EVASGLUE_API_OVERRIDE(f,, evgl_) // GL Wrapped Path
-#endif
+   EVGL_Surface *sfc;
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   N_ORD(eglGetProcAddress);
-   N_ORD(eglGetError);
-   N_ORD(eglGetDisplay);
-   N_ORD(eglInitialize);
-   N_ORD(eglTerminate);
-   N_ORD(eglChooseConfig);
-   N_ORD(eglCreateWindowSurface);
-   N_ORD(eglCreatePixmapSurface);
-   N_ORD(eglDestroySurface);
-   N_ORD(eglBindAPI);
-   N_ORD(eglWaitClient);
-   N_ORD(eglSurfaceAttrib);
-   N_ORD(eglBindTexImage);
-   N_ORD(eglReleaseTexImage);
-   N_ORD(eglSwapInterval);
-   N_ORD(eglCreateContext);
-   N_ORD(eglDestroyContext);
-   N_ORD(eglGetCurrentContext);
-   N_ORD(eglGetCurrentSurface);
-   N_ORD(eglGetCurrentDisplay);
-   N_ORD(eglWaitGL);
-   N_ORD(eglWaitNative);
-   N_ORD(eglSwapBuffers);
-   N_ORD(eglCopyBuffers);
-   N_ORD(eglQueryString);
-
-   // Extensions
-   N_ORD(eglCreateImage);
-   N_ORD(eglDestroyImage);
-   N_ORD(eglMapImageSEC);
-   N_ORD(eglUnmapImageSEC);
-   N_ORD(eglGetImageAttribSEC);
-   N_ORD(glEGLImageTargetTexture2DOES);
-   N_ORD(glEGLImageTargetRenderbufferStorageOES);
-
-   // Wrapped functions for evasgl specific purpose
-   W_ORD(eglMakeCurrent);
-#else
-   N_ORD(glXGetProcAddress);
-   N_ORD(glXChooseVisual);
-   N_ORD(glXCreateContext);
-   N_ORD(glXDestroyContext);
-   N_ORD(glXGetCurrentContext);
-   N_ORD(glXGetCurrentDrawable);
-   N_ORD(glXSwapBuffers);
-   N_ORD(glXWaitX);
-   N_ORD(glXWaitGL);
-   N_ORD(glXQueryExtension);
-   N_ORD(glXQueryExtensionsString);
-   N_ORD(glXChooseFBConfig);
-   N_ORD(glXGetFBConfigs);
-   N_ORD(glXGetFBConfigAttrib);
-   N_ORD(glXGetVisualFromFBConfig);
-   N_ORD(glXDestroyWindow);
-   N_ORD(glXMakeContextCurrent);
-   N_ORD(glXBindTexImage);
-   N_ORD(glXReleaseTexImage);
-   N_ORD(glXGetVideoSync);
-   N_ORD(glXWaitVideoSync);
-   N_ORD(glXCreatePixmap);
-   N_ORD(glXDestroyPixmap);
-   N_ORD(glXQueryDrawable);
-   N_ORD(glXSwapIntervalSGI);
-   N_ORD(glXSwapIntervalEXT);
-
-   // Wrapped functions for evasgl specific purpose
-   W_ORD(glXMakeCurrent);
-#endif
+   if (direct_render) *direct_render = EINA_FALSE;
+   if (direct_override) *direct_override = EINA_FALSE;
+   if (client_side_rotation) *client_side_rotation = EINA_FALSE;
 
-#undef N_ORD
-#undef W_ORD
-}
+   if (!evgl_engine) return EINA_FALSE;
+   if (!ns) return EINA_FALSE;
 
+   if (ns->type == EVAS_NATIVE_SURFACE_EVASGL &&
+            ns->data.evasgl.surface)
+     {
+        sfc = ns->data.evasgl.surface;
+     }
+   else return EINA_FALSE;
 
-static void
-override_glue_wrapped_path()
-{
+   if (evgl_engine->api_debug_mode)
+     {
+        DBG("Found native surface: DR:%d DORR:%d CSR:%d",
+            (int) sfc->direct_fb_opt, (int) sfc->direct_override, (int) sfc->client_side_rotation);
+     }
 
-#ifdef EVAS_GL_NAME_MANGLE
-#  define W_ORD(f) EVASGLUE_API_OVERRIDE(f, glsym_, evgl_) // GL Wrapped Path
-#else
-#  define W_ORD(f) EVASGLUE_API_OVERRIDE(f,, evgl_) // GL Wrapped Path
-#endif
+   if (direct_render) *direct_render = sfc->direct_fb_opt;
+   if (direct_override) *direct_override = sfc->direct_override;
+   if (client_side_rotation) *client_side_rotation = sfc->client_side_rotation;
+   return EINA_TRUE;
+}
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   W_ORD(eglGetProcAddress);
-   W_ORD(eglGetError);
-   W_ORD(eglGetDisplay);
-   W_ORD(eglInitialize);
-   W_ORD(eglTerminate);
-   W_ORD(eglChooseConfig);
-   W_ORD(eglCreateWindowSurface);
-   W_ORD(eglCreatePixmapSurface);
-   W_ORD(eglDestroySurface);
-   W_ORD(eglBindAPI);
-   W_ORD(eglWaitClient);
-   W_ORD(eglSurfaceAttrib);
-   W_ORD(eglBindTexImage);
-   W_ORD(eglReleaseTexImage);
-   W_ORD(eglSwapInterval);
-   W_ORD(eglCreateContext);
-   W_ORD(eglDestroyContext);
-   W_ORD(eglGetCurrentContext);
-   W_ORD(eglGetCurrentSurface);
-   W_ORD(eglGetCurrentDisplay);
-   W_ORD(eglWaitGL);
-   W_ORD(eglWaitNative);
-   W_ORD(eglSwapBuffers);
-   W_ORD(eglCopyBuffers);
-   W_ORD(eglQueryString);
-
-   // Extensions
-   W_ORD(eglCreateImage);
-   W_ORD(eglDestroyImage);
-   W_ORD(eglMapImageSEC);
-   W_ORD(eglUnmapImageSEC);
-   W_ORD(eglGetImageAttribSEC);
-   W_ORD(glEGLImageTargetTexture2DOES);
-   W_ORD(glEGLImageTargetRenderbufferStorageOES);
-
-   // Wrapped functions for evasgl specific purpose
-   W_ORD(eglMakeCurrent);
-#else
-   W_ORD(glXGetProcAddress);
-   W_ORD(glXChooseVisual);
-   W_ORD(glXCreateContext);
-   W_ORD(glXDestroyContext);
-   W_ORD(glXGetCurrentContext);
-   W_ORD(glXGetCurrentDrawable);
-   W_ORD(glXSwapBuffers);
-   W_ORD(glXWaitX);
-   W_ORD(glXWaitGL);
-   W_ORD(glXQueryExtension);
-   W_ORD(glXQueryExtensionsString);
-   W_ORD(glXChooseFBConfig);
-   W_ORD(glXGetFBConfigs);
-   W_ORD(glXGetFBConfigAttrib);
-   W_ORD(glXGetVisualFromFBConfig);
-   W_ORD(glXDestroyWindow);
-   W_ORD(glXMakeContextCurrent);
-   W_ORD(glXBindTexImage);
-   W_ORD(glXReleaseTexImage);
-   W_ORD(glXGetVideoSync);
-   W_ORD(glXWaitVideoSync);
-   W_ORD(glXCreatePixmap);
-   W_ORD(glXDestroyPixmap);
-   W_ORD(glXQueryDrawable);
-   W_ORD(glXSwapIntervalSGI);
-   W_ORD(glXSwapIntervalEXT);
-
-   // Wrapped functions for evasgl specific purpose
-   W_ORD(glXMakeCurrent);
-#endif
+void
+evgl_direct_info_set(int win_w, int win_h, int rot, unsigned int map_tex,
+                     int img_x, int img_y, int img_w, int img_h,
+                     int clip_x, int clip_y, int clip_w, int clip_h,
+                     void *surface)
+{
+   EVGL_Resource *rsc;
+   EVGL_Surface *sfc = surface;
+
+   if (!(rsc = _evgl_tls_resource_get()))
+     return;
+
+   /* Check for direct rendering
+    *
+    * DR is allowed iif:
+    * - Rotation == 0
+    * OR: - Client-Side Rotation is set
+    *     - Direct Override is set (note: this flag is mostly useless)
+    *
+    * If the surface is not found, we assume indirect rendering.
+    */
+
+   if (sfc &&
+       ((rot == 0) || sfc->client_side_rotation || sfc->direct_override))
+     {
+        if (evgl_engine->api_debug_mode)
+          DBG("Direct rendering is enabled.");
+
+        rsc->direct.enabled = EINA_TRUE;
+
+        rsc->direct.win_w   = win_w;
+        rsc->direct.win_h   = win_h;
+        rsc->direct.rot     = rot;
+        rsc->direct.map_tex = map_tex;
+
+        rsc->direct.img.x   = img_x;
+        rsc->direct.img.y   = img_y;
+        rsc->direct.img.w   = img_w;
+        rsc->direct.img.h   = img_h;
+
+        rsc->direct.clip.x  = clip_x;
+        rsc->direct.clip.y  = clip_y;
+        rsc->direct.clip.w  = clip_w;
+        rsc->direct.clip.h  = clip_h;
+     }
+   else
+     {
+        if (evgl_engine->api_debug_mode)
+          DBG("Direct rendering is disabled.");
 
-#undef W_ORD
+        rsc->direct.enabled = EINA_FALSE;
+     }
 }
 
-static void
-override_glue_fast_path()
+void
+evgl_direct_info_clear()
 {
-   // Inherit from wrapped path
-   override_glue_wrapped_path();
-
-#ifdef EVAS_GL_NAME_MANGLE
-#  define F_ORD(f) EVASGLUE_API_OVERRIDE(f, glsym_, fpgl_) // GL Fast Path
-#else
-#  define F_ORD(f) EVASGLUE_API_OVERRIDE(f,, fpgl_) // GL Fast Path
-#endif
+   EVGL_Resource *rsc;
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   // Fastpath-ed Functions
-   F_ORD(eglCreateContext);
-   F_ORD(eglDestroyContext);
-   F_ORD(eglDestroySurface);
-   F_ORD(eglMakeCurrent);
-   F_ORD(eglGetCurrentContext);
-   F_ORD(eglGetCurrentSurface);
-
-#else
-   // Fastpath-ed Functions
-   F_ORD(glXCreateContext);
-   F_ORD(glXDestroyContext);
-   F_ORD(glXMakeCurrent);
-   F_ORD(glXGetCurrentContext);
-   F_ORD(glXGetCurrentDrawable);
-
-   F_ORD(glXMakeContextCurrent);
-#endif
+   if (!(rsc=_evgl_tls_resource_get())) return;
 
-#undef F_ORD
+   rsc->direct.map_tex = 0;
+   rsc->direct.enabled = EINA_FALSE;
 }
 
-static void
-override_gl_normal_path()
+Evas_GL_API *
+evgl_api_get(Evas_GL_Context_Version version)
 {
-#ifdef EVAS_GL_NAME_MANGLE
-#  define N_ORD(f) EVASGLUE_API_OVERRIDE(f, glsym_, _sym_) // GL Normal Path
-#  define W_ORD(f) EVASGLUE_API_OVERRIDE(f, glsym_, evgl_) // GL Wrapped Path
-#else
-#  define N_ORD(f) EVASGLUE_API_OVERRIDE(f,, _sym_) // GL Normal Path
-#  define W_ORD(f) EVASGLUE_API_OVERRIDE(f,, evgl_) // GL Wrapped Path
-#endif
-   N_ORD(glAttachShader);
-   N_ORD(glBindAttribLocation);
-   N_ORD(glBufferData);
-   N_ORD(glBufferSubData);
-   N_ORD(glCheckFramebufferStatus);
-   N_ORD(glClear);
-   N_ORD(glCompileShader);
-   N_ORD(glCompressedTexImage2D);
-   N_ORD(glCompressedTexSubImage2D);
-   N_ORD(glCopyTexImage2D);
-   N_ORD(glCopyTexSubImage2D);
-   N_ORD(glCreateProgram);
-   N_ORD(glCreateShader);
-   N_ORD(glDeleteBuffers);
-   N_ORD(glDeleteFramebuffers);
-   N_ORD(glDeleteProgram);
-   N_ORD(glDeleteRenderbuffers);
-   N_ORD(glDeleteShader);
-   N_ORD(glDeleteTextures);
-   N_ORD(glFinish);
-   N_ORD(glFlush);
-   N_ORD(glFramebufferRenderbuffer);
-   N_ORD(glFramebufferTexture2D);
-   N_ORD(glGenBuffers);
-   N_ORD(glGenerateMipmap);
-   N_ORD(glGenFramebuffers);
-   N_ORD(glGenRenderbuffers);
-   N_ORD(glGenTextures);
-   N_ORD(glGetActiveAttrib);
-   N_ORD(glGetActiveUniform);
-   N_ORD(glGetAttachedShaders);
-   N_ORD(glGetAttribLocation);
-   N_ORD(glGetBooleanv);
-   N_ORD(glGetBufferParameteriv);
-   N_ORD(glGetError);
-   N_ORD(glGetFloatv);
-   N_ORD(glGetFramebufferAttachmentParameteriv);
-   N_ORD(glGetIntegerv);
-   N_ORD(glGetProgramiv);
-   N_ORD(glGetProgramInfoLog);
-   N_ORD(glGetRenderbufferParameteriv);
-   N_ORD(glGetShaderiv);
-   N_ORD(glGetShaderInfoLog);
-   N_ORD(glGetShaderSource);
-   N_ORD(glGetString);
-   N_ORD(glGetTexParameterfv);
-   N_ORD(glGetTexParameteriv);
-   N_ORD(glGetUniformfv);
-   N_ORD(glGetUniformiv);
-   N_ORD(glGetUniformLocation);
-   N_ORD(glIsBuffer);
-   N_ORD(glIsEnabled);
-   N_ORD(glIsFramebuffer);
-   N_ORD(glIsProgram);
-   N_ORD(glIsRenderbuffer);
-   N_ORD(glIsShader);
-   N_ORD(glIsTexture);
-   N_ORD(glLineWidth);
-   N_ORD(glLinkProgram);
-   N_ORD(glReadPixels);
-   N_ORD(glRenderbufferStorage);
-   N_ORD(glShaderSource);
-   N_ORD(glTexImage2D);
-   N_ORD(glTexParameterf);
-   N_ORD(glTexParameterfv);
-   N_ORD(glTexParameteri);
-   N_ORD(glTexParameteriv);
-   N_ORD(glTexSubImage2D);
-   N_ORD(glUniform1f);
-   N_ORD(glUniform1fv);
-   N_ORD(glUniform1i);
-   N_ORD(glUniform1iv);
-   N_ORD(glUniform2f);
-   N_ORD(glUniform2fv);
-   N_ORD(glUniform2i);
-   N_ORD(glUniform2iv);
-   N_ORD(glUniform3f);
-   N_ORD(glUniform3fv);
-   N_ORD(glUniform3i);
-   N_ORD(glUniform3iv);
-   N_ORD(glUniform4f);
-   N_ORD(glUniform4fv);
-   N_ORD(glUniform4i);
-   N_ORD(glUniform4iv);
-   N_ORD(glUniformMatrix2fv);
-   N_ORD(glUniformMatrix3fv);
-   N_ORD(glUniformMatrix4fv);
-   N_ORD(glValidateProgram);
-
-   N_ORD(glActiveTexture);
-   N_ORD(glBindBuffer);
-   N_ORD(glBindTexture);
-   N_ORD(glBlendColor);
-   N_ORD(glBlendEquation);
-   N_ORD(glBlendEquationSeparate);
-   N_ORD(glBlendFunc);
-   N_ORD(glBlendFuncSeparate);
-   N_ORD(glClearColor);
-   N_ORD(glClearDepthf);
-   N_ORD(glClearStencil);
-   N_ORD(glColorMask);
-   N_ORD(glCullFace);
-   N_ORD(glDepthFunc);
-   N_ORD(glDepthMask);
-   N_ORD(glDepthRangef);
-   N_ORD(glDetachShader);
-   N_ORD(glDisable);
-   N_ORD(glDisableVertexAttribArray);
-   N_ORD(glDrawArrays);
-   N_ORD(glDrawElements);
-   N_ORD(glEnable);
-   N_ORD(glEnableVertexAttribArray);
-   N_ORD(glFrontFace);
-   N_ORD(glGetVertexAttribfv);
-   N_ORD(glGetVertexAttribiv);
-   N_ORD(glGetVertexAttribPointerv);
-   N_ORD(glHint);
-   N_ORD(glPixelStorei);
-   N_ORD(glPolygonOffset);
-   N_ORD(glSampleCoverage);
-   N_ORD(glScissor);
-   N_ORD(glStencilFunc);
-   N_ORD(glStencilFuncSeparate);
-   N_ORD(glStencilMask);
-   N_ORD(glStencilMaskSeparate);
-   N_ORD(glStencilOp);
-   N_ORD(glStencilOpSeparate);
-   N_ORD(glUseProgram);
-   N_ORD(glVertexAttrib1f);
-   N_ORD(glVertexAttrib1fv);
-   N_ORD(glVertexAttrib2f);
-   N_ORD(glVertexAttrib2fv);
-   N_ORD(glVertexAttrib3f);
-   N_ORD(glVertexAttrib3fv);
-   N_ORD(glVertexAttrib4f);
-   N_ORD(glVertexAttrib4fv);
-   N_ORD(glVertexAttribPointer);
-   N_ORD(glViewport);
-
-   // Extensions
-   N_ORD(glGetProgramBinary);
-   N_ORD(glProgramBinary);
-   N_ORD(glProgramParameteri);
-
-   //----------------------------------------------------//
-   // Functions that need to be overriden for evasgl use
-   W_ORD(glBindFramebuffer);
-   W_ORD(glBindRenderbuffer);
-
-   // GLES2.0 API compat on top of desktop gl
-   W_ORD(glGetShaderPrecisionFormat);
-   W_ORD(glReleaseShaderCompiler);
-   W_ORD(glShaderBinary);
-
-#undef N_ORD
-#undef W_ORD
+   if (version == EVAS_GL_GLES_2_X)
+     {
+        _evgl_api_get(gl_funcs, evgl_engine->api_debug_mode);
+        return gl_funcs;
+     }
+   else if (version == EVAS_GL_GLES_1_X)
+     {
+        _evgl_api_gles1_get(gles1_funcs, evgl_engine->api_debug_mode);
+        return gles1_funcs;
+     }
+   else return NULL;
 }
 
-static void
-override_gl_wrapped_path()
+
+void
+evgl_direct_partial_info_set(int pres)
 {
+   EVGL_Resource *rsc;
 
-#ifdef EVAS_GL_NAME_MANGLE
-#  define N_ORD(f) EVASGLUE_API_OVERRIDE(f, glsym_, _sym_) // GL Normal Path
-#  define W_ORD(f) EVASGLUE_API_OVERRIDE(f, glsym_, evgl_) // GL Wrapped Path
-#else
-#  define N_ORD(f) EVASGLUE_API_OVERRIDE(f,, _sym_) // GL Normal Path
-#  define W_ORD(f) EVASGLUE_API_OVERRIDE(f,, evgl_) // GL Wrapped Path
-#endif
+   if (!(rsc=_evgl_tls_resource_get())) return;
 
-   W_ORD(glAttachShader);
-   W_ORD(glBindAttribLocation);
-   W_ORD(glBufferData);
-   W_ORD(glBufferSubData);
-   W_ORD(glCheckFramebufferStatus);
-   W_ORD(glClear);
-   W_ORD(glCompileShader);
-   W_ORD(glCompressedTexImage2D);
-   W_ORD(glCompressedTexSubImage2D);
-   W_ORD(glCopyTexImage2D);
-   W_ORD(glCopyTexSubImage2D);
-   W_ORD(glCreateProgram);
-   W_ORD(glCreateShader);
-   W_ORD(glDeleteBuffers);
-   W_ORD(glDeleteFramebuffers);
-   W_ORD(glDeleteProgram);
-   W_ORD(glDeleteRenderbuffers);
-   W_ORD(glDeleteShader);
-   W_ORD(glDeleteTextures);
-   W_ORD(glFinish);
-   W_ORD(glFlush);
-   W_ORD(glFramebufferRenderbuffer);
-   W_ORD(glFramebufferTexture2D);
-   W_ORD(glGenBuffers);
-   W_ORD(glGenerateMipmap);
-   W_ORD(glGenFramebuffers);
-   W_ORD(glGenRenderbuffers);
-   W_ORD(glGenTextures);
-   W_ORD(glGetActiveAttrib);
-   W_ORD(glGetActiveUniform);
-   W_ORD(glGetAttachedShaders);
-   W_ORD(glGetAttribLocation);
-   W_ORD(glGetBooleanv);
-   W_ORD(glGetBufferParameteriv);
-   W_ORD(glGetError);
-   W_ORD(glGetFloatv);
-   W_ORD(glGetFramebufferAttachmentParameteriv);
-   W_ORD(glGetIntegerv);
-   W_ORD(glGetProgramiv);
-   W_ORD(glGetProgramInfoLog);
-   W_ORD(glGetRenderbufferParameteriv);
-   W_ORD(glGetShaderiv);
-   W_ORD(glGetShaderInfoLog);
-   W_ORD(glGetShaderSource);
-   W_ORD(glGetString);
-   W_ORD(glGetTexParameterfv);
-   W_ORD(glGetTexParameteriv);
-   W_ORD(glGetUniformfv);
-   W_ORD(glGetUniformiv);
-   W_ORD(glGetUniformLocation);
-   W_ORD(glIsBuffer);
-   W_ORD(glIsEnabled);
-   W_ORD(glIsFramebuffer);
-   W_ORD(glIsProgram);
-   W_ORD(glIsRenderbuffer);
-   W_ORD(glIsShader);
-   W_ORD(glIsTexture);
-   W_ORD(glLineWidth);
-   W_ORD(glLinkProgram);
-   W_ORD(glReadPixels);
-   W_ORD(glRenderbufferStorage);
-   W_ORD(glShaderSource);
-   W_ORD(glTexImage2D);
-   W_ORD(glTexParameterf);
-   W_ORD(glTexParameterfv);
-   W_ORD(glTexParameteri);
-   W_ORD(glTexParameteriv);
-   W_ORD(glTexSubImage2D);
-   W_ORD(glUniform1f);
-   W_ORD(glUniform1fv);
-   W_ORD(glUniform1i);
-   W_ORD(glUniform1iv);
-   W_ORD(glUniform2f);
-   W_ORD(glUniform2fv);
-   W_ORD(glUniform2i);
-   W_ORD(glUniform2iv);
-   W_ORD(glUniform3f);
-   W_ORD(glUniform3fv);
-   W_ORD(glUniform3i);
-   W_ORD(glUniform3iv);
-   W_ORD(glUniform4f);
-   W_ORD(glUniform4fv);
-   W_ORD(glUniform4i);
-   W_ORD(glUniform4iv);
-   W_ORD(glUniformMatrix2fv);
-   W_ORD(glUniformMatrix3fv);
-   W_ORD(glUniformMatrix4fv);
-   W_ORD(glValidateProgram);
-
-   W_ORD(glActiveTexture);
-   W_ORD(glBindBuffer);
-   W_ORD(glBindTexture);
-   W_ORD(glBlendColor);
-   W_ORD(glBlendEquation);
-   W_ORD(glBlendEquationSeparate);
-   W_ORD(glBlendFunc);
-   W_ORD(glBlendFuncSeparate);
-   W_ORD(glClearColor);
-   W_ORD(glClearDepthf);
-   W_ORD(glClearStencil);
-   W_ORD(glColorMask);
-   W_ORD(glCullFace);
-   W_ORD(glDepthFunc);
-   W_ORD(glDepthMask);
-   W_ORD(glDepthRangef);
-   W_ORD(glDetachShader);
-   W_ORD(glDisable);
-   W_ORD(glDisableVertexAttribArray);
-   W_ORD(glDrawArrays);
-   W_ORD(glDrawElements);
-   W_ORD(glEnable);
-   W_ORD(glEnableVertexAttribArray);
-   W_ORD(glFrontFace);
-   W_ORD(glGetVertexAttribfv);
-   W_ORD(glGetVertexAttribiv);
-   W_ORD(glGetVertexAttribPointerv);
-   W_ORD(glHint);
-   W_ORD(glPixelStorei);
-   W_ORD(glPolygonOffset);
-   W_ORD(glSampleCoverage);
-   W_ORD(glScissor);
-   W_ORD(glStencilFunc);
-   W_ORD(glStencilFuncSeparate);
-   W_ORD(glStencilMask);
-   W_ORD(glStencilMaskSeparate);
-   W_ORD(glStencilOp);
-   W_ORD(glStencilOpSeparate);
-   W_ORD(glUseProgram);
-   W_ORD(glVertexAttrib1f);
-   W_ORD(glVertexAttrib1fv);
-   W_ORD(glVertexAttrib2f);
-   W_ORD(glVertexAttrib2fv);
-   W_ORD(glVertexAttrib3f);
-   W_ORD(glVertexAttrib3fv);
-   W_ORD(glVertexAttrib4f);
-   W_ORD(glVertexAttrib4fv);
-   W_ORD(glVertexAttribPointer);
-   W_ORD(glViewport);
-
-   // Extensions
-   W_ORD(glGetProgramBinary);
-   W_ORD(glProgramBinary);
-   W_ORD(glProgramParameteri);
-
-   //----------------------------------------------------//
-   // Functions that need to be overriden for evasgl use
-   W_ORD(glBindFramebuffer);
-   W_ORD(glBindRenderbuffer);
-
-   // GLES2.0 API compat on top of desktop gl
-   W_ORD(glGetShaderPrecisionFormat);
-   W_ORD(glReleaseShaderCompiler);
-   W_ORD(glShaderBinary);
-
-#undef N_ORD
-#undef W_ORD
+   rsc->direct.partial.enabled  = EINA_TRUE;
+   rsc->direct.partial.preserve = pres;
 }
 
-static void
-override_gl_fast_path()
+void
+evgl_direct_partial_info_clear()
 {
-   // Inherit from wrapped path
-   override_gl_wrapped_path();
+   EVGL_Resource *rsc;
 
-#ifdef EVAS_GL_NAME_MANGLE
-#  define F_ORD(f) EVASGLUE_API_OVERRIDE(f, glsym_, fpgl_) // GL Wrapped Path
-#else
-#  define F_ORD(f) EVASGLUE_API_OVERRIDE(f,, fpgl_) // GL Wrapped Path
-#endif
+   if (!(rsc=_evgl_tls_resource_get())) return;
 
-   // Fast-Path Functions
-   F_ORD(glActiveTexture);
-   F_ORD(glBindBuffer);
-   F_ORD(glBindTexture);
-   F_ORD(glBlendColor);
-   F_ORD(glBlendEquation);
-   F_ORD(glBlendEquationSeparate);
-   F_ORD(glBlendFunc);
-   F_ORD(glBlendFuncSeparate);
-   F_ORD(glClearColor);
-   F_ORD(glClearDepthf);
-   F_ORD(glClearStencil);
-   F_ORD(glColorMask);
-   F_ORD(glCullFace);
-   F_ORD(glDepthFunc);
-   F_ORD(glDepthMask);
-   F_ORD(glDepthRangef);
-   F_ORD(glDisable);
-   F_ORD(glDisableVertexAttribArray);
-   F_ORD(glDrawArrays);
-   F_ORD(glDrawElements);
-   F_ORD(glEnable);
-   F_ORD(glEnableVertexAttribArray);
-   F_ORD(glFrontFace);
-   F_ORD(glGetVertexAttribfv);
-   F_ORD(glGetVertexAttribiv);
-   F_ORD(glGetVertexAttribPointerv);
-   F_ORD(glHint);
-   F_ORD(glLineWidth);
-   F_ORD(glPixelStorei);
-   F_ORD(glPolygonOffset);
-   F_ORD(glSampleCoverage);
-   F_ORD(glScissor);
-   F_ORD(glStencilFunc);
-   F_ORD(glStencilFuncSeparate);
-   F_ORD(glStencilMask);
-   F_ORD(glStencilMaskSeparate);
-   F_ORD(glStencilOp);
-   F_ORD(glStencilOpSeparate);
-   F_ORD(glUseProgram);
-   F_ORD(glVertexAttrib1f);
-   F_ORD(glVertexAttrib1fv);
-   F_ORD(glVertexAttrib2f);
-   F_ORD(glVertexAttrib2fv);
-   F_ORD(glVertexAttrib3f);
-   F_ORD(glVertexAttrib3fv);
-   F_ORD(glVertexAttrib4f);
-   F_ORD(glVertexAttrib4fv);
-   F_ORD(glVertexAttribPointer);
-   F_ORD(glViewport);
-
-   // Functions that need to be overriden for evasgl use
-   F_ORD(glBindFramebuffer);
-   F_ORD(glBindRenderbuffer);
-
-#undef F_ORD
+   rsc->direct.partial.enabled = EINA_FALSE;
 }
 
-
-static void
-override_glue_apis(Evas_GL_Opt_Flag opt)
+void
+evgl_direct_override_get(int *override, int *force_off)
 {
-   switch(opt)
-     {
-      case GL_NORMAL_PATH:
-         override_glue_normal_path();
-         break;
-      case GL_WRAPPED_PATH:
-         override_glue_wrapped_path();
-         break;
-      case GL_FAST_PATH:
-         override_glue_fast_path();
-         break;
-      default:
-         ERR("Invalide GL Override Option!!!\n");
-     }
+   (void) override;
+   if (!evgl_engine) return;
+   //if (override) *override  = evgl_engine->direct_override;
+   if (force_off) *force_off = evgl_engine->direct_force_off;
 }
 
-static void
-override_gl_apis(Evas_GL_Opt_Flag opt)
+void
+evgl_direct_partial_render_start()
 {
-   //_gl.version = EVAS_GL_API_VERSION;
-
-   switch(opt)
-     {
-      case GL_NORMAL_PATH:
-         override_gl_normal_path();
-         break;
-      case GL_WRAPPED_PATH:
-         override_gl_wrapped_path();
-         break;
-      case GL_FAST_PATH:
-         override_gl_fast_path();
-         break;
-      default:
-         ERR("Invalide GL Override Option!!!\n");
-     }
-}
+   EVGL_Resource *rsc;
 
+   if (!(rsc=_evgl_tls_resource_get())) return;
 
-int
-init_gl()
-{
-   char *fp_env;
-   int fastpath_opt = 0;
-   Evas_GL_Opt_Flag api_opt = GL_NORMAL_PATH;
+   evas_gl_common_tiling_start(NULL,
+                               rsc->direct.rot,
+                               rsc->direct.win_w,
+                               rsc->direct.win_h,
+                               rsc->direct.clip.x,
+                               rsc->direct.win_h - rsc->direct.clip.y - rsc->direct.clip.h,
+                               rsc->direct.clip.w,
+                               rsc->direct.clip.h,
+                               rsc->direct.partial.preserve);
 
-   fprintf(stderr, "Initializing OpenGL APIs...\n");
+   if (!rsc->direct.partial.preserve)
+      rsc->direct.partial.preserve = GL_COLOR_BUFFER_BIT0_QCOM;
+}
 
-   fp_env = getenv("EVAS_GL_FASTPATH");
+void
+evgl_direct_partial_render_end()
+{
+   EVGL_Context *ctx;
+   ctx = _evgl_current_context_get();
 
-   if (fp_env) fastpath_opt = atoi(fp_env);
-   else fastpath_opt = 0;
+   if (!ctx) return;
 
-   switch(fastpath_opt)
+   if (ctx->partial_render)
      {
-      case 1:
-         api_opt = GL_FAST_PATH;
-         fprintf(stderr, "API OPT: %d Fastpath enabled...\n", fastpath_opt);
-         fprintf(stderr, "#######################################################\n");
-         fprintf(stderr, "########### [Evas] Fast Path is enabled ###############\n");
-         fprintf(stderr, "#######################################################\n");
-         break;
-      case 2:
-         api_opt = GL_WRAPPED_PATH;
-         fprintf(stderr, "API OPT: %d Wrapped API path enabled...\n", fastpath_opt);
-         break;
-      case 3:
-         api_opt = GL_FAST_PATH;
-         log_opt = 1;
-         fprintf(stderr, "API OPT: %d Fastpath enabled...\n", fastpath_opt);
-         fprintf(stderr, "#######################################################\n");
-         fprintf(stderr, "########### [Evas] Fast Path is enabled ###############\n");
-         fprintf(stderr, "#######################################################\n");
-         break;
-      case 4:
-         api_opt = GL_FAST_PATH;
-         log_opt = 2;
-         fprintf(stderr, "API OPT: %d Fastpath enabled...\n", fastpath_opt);
-         fprintf(stderr, "#######################################################\n");
-         fprintf(stderr, "########### [Evas] Fast Path is enabled ###############\n");
-         fprintf(stderr, "#######################################################\n");
-         break;
-      default:
-         fprintf(stderr, "API OPT: %d Default API path enabled...\n", fastpath_opt);
-         api_opt = GL_NORMAL_PATH;
-         break;
+        evas_gl_common_tiling_done(NULL);
+        ctx->partial_render = 0;
      }
+}
 
-   if (!gl_lib_init()) return 0;
+int
+evgl_surface_is_texture(void *eng_data, EVGL_Surface *sfc)
+{
+   EVGL_Resource *rsc;
+   int is_texture = 1;
 
-   override_glue_apis(api_opt);
-   override_gl_apis(api_opt);
+   if (!(rsc=_evgl_tls_resource_get())) return -1;
 
-   EVAS_GL_INIT_LOG(mc_log);
+   if (_evgl_direct_renderable(rsc, sfc) && !rsc->direct.map_tex)
+      is_texture = 0;
 
-   return 1;
+   return is_texture;
 }
 
-void
-free_gl()
+EVGLNative_Context
+evgl_context_native_get(Evas_GL_Context *ctx)
 {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   if (global_ctx)
-     {
-        ERR("Destroying global context...\n");
-        _sym_eglMakeCurrent(global_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-        _sym_eglDestroyContext(global_dpy, global_ctx);
-     }
-   if (egl_lib_handle) dlclose(egl_lib_handle);
-   if (gl_lib_handle) dlclose (gl_lib_handle);
-#else
-   if (global_ctx)
-     {
-        ERR("Destroying global context...\n");
-        _sym_glXDestroyContext(global_dpy, global_ctx);
-     }
-   if (gl_lib_handle) dlclose (gl_lib_handle);
-#endif
+   EVGL_Context *evglctx = evas_gl_context_native_get(ctx);
+   if (!evglctx) return NULL;
+   return evglctx->context;
 }
 
+//-----------------------------------------------------//
+
+
old mode 100644 (file)
new mode 100755 (executable)
index cfc08a9..deb6866
-#ifndef EVAS_GL_CORE_H
-#define EVAS_GL_CORE_H
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#ifdef EVAS_GL_STANDALONE
-#  define ERR(...) \
-   fprintf(stderr, __VA_ARGS__);
-
-#  ifdef EVAS_GL_DEBUG
-#     define DBG(...) \
-         fprintf(stderr, __VA_ARGS__);
-#  endif
-#else
-#  include "config.h"
-#  include "evas_common.h"
-
-#  define EVAS_GL_NAME_MANGLE 1
-#endif
-
-// Name mangling used when built with Evas
-#ifdef EVAS_GL_NAME_MANGLE
-#  define GL(name) glsym_##name
-#else
-#  define GL(name) name
-#endif
-
-
-/*
- * This document is licensed under the SGI Free Software B License Version
- * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
- */
-
-/*-------------------------------------------------------------------------
- * Data type definitions
- *-----------------------------------------------------------------------*/
-
-typedef void             GLvoid;
-typedef unsigned int     GLenum;
-typedef unsigned char    GLboolean;
-typedef unsigned int     GLbitfield;
-typedef signed char      GLbyte;       // Changed khronos_int8_t
-typedef short            GLshort;
-typedef int              GLint;
-typedef int              GLsizei;
-typedef unsigned char    GLubyte;      // Changed khronos_uint8_t
-typedef unsigned short   GLushort;
-typedef unsigned int     GLuint;
-typedef float            GLfloat;      // Changed khronos_float_t
-typedef float            GLclampf;     // Changed khronos_float_t
-typedef signed int       GLfixed;      // Changed khronos_int32_t
-
-/* GL types for handling large vertex buffer objects */
-typedef signed long int  GLintptr;     // Changed khronos_intptr_t
-typedef signed long int  GLsizeiptr;   // Changed khronos_ssize_t
-
-#if (!defined(__gl2_h_) && !defined(__gl_h_))
-# define __gl_h_
-# define __gl2_h_
-
-/* OpenGL ES core versions */
-//#define GL_ES_VERSION_2_0                 1
-
-/* ClearBufferMask */
-#define GL_DEPTH_BUFFER_BIT               0x00000100
-#define GL_STENCIL_BUFFER_BIT             0x00000400
-#define GL_COLOR_BUFFER_BIT               0x00004000
-
-/* Boolean */
-#define GL_FALSE                          0
-#define GL_TRUE                           1
-
-/* BeginMode */
-#define GL_POINTS                         0x0000
-#define GL_LINES                          0x0001
-#define GL_LINE_LOOP                      0x0002
-#define GL_LINE_STRIP                     0x0003
-#define GL_TRIANGLES                      0x0004
-#define GL_TRIANGLE_STRIP                 0x0005
-#define GL_TRIANGLE_FAN                   0x0006
-
-/* AlphaFunction (not supported in ES20) */
-/*      GL_NEVER */
-/*      GL_LESS */
-/*      GL_EQUAL */
-/*      GL_LEQUAL */
-/*      GL_GREATER */
-/*      GL_NOTEQUAL */
-/*      GL_GEQUAL */
-/*      GL_ALWAYS */
-
-/* BlendingFactorDest */
-#define GL_ZERO                           0
-#define GL_ONE                            1
-#define GL_SRC_COLOR                      0x0300
-#define GL_ONE_MINUS_SRC_COLOR            0x0301
-#define GL_SRC_ALPHA                      0x0302
-#define GL_ONE_MINUS_SRC_ALPHA            0x0303
-#define GL_DST_ALPHA                      0x0304
-#define GL_ONE_MINUS_DST_ALPHA            0x0305
-
-/* BlendingFactorSrc */
-/*      GL_ZERO */
-/*      GL_ONE */
-#define GL_DST_COLOR                      0x0306
-#define GL_ONE_MINUS_DST_COLOR            0x0307
-#define GL_SRC_ALPHA_SATURATE             0x0308
-/*      GL_SRC_ALPHA */
-/*      GL_ONE_MINUS_SRC_ALPHA */
-/*      GL_DST_ALPHA */
-/*      GL_ONE_MINUS_DST_ALPHA */
-
-/* BlendEquationSeparate */
-#define GL_FUNC_ADD                       0x8006
-#define GL_BLEND_EQUATION                 0x8009
-#define GL_BLEND_EQUATION_RGB             0x8009    /* same as BLEND_EQUATION */
-#define GL_BLEND_EQUATION_ALPHA           0x883D
-
-/* BlendSubtract */
-#define GL_FUNC_SUBTRACT                  0x800A
-#define GL_FUNC_REVERSE_SUBTRACT          0x800B
-
-/* Separate Blend Functions */
-#define GL_BLEND_DST_RGB                  0x80C8
-#define GL_BLEND_SRC_RGB                  0x80C9
-#define GL_BLEND_DST_ALPHA                0x80CA
-#define GL_BLEND_SRC_ALPHA                0x80CB
-#define GL_CONSTANT_COLOR                 0x8001
-#define GL_ONE_MINUS_CONSTANT_COLOR       0x8002
-#define GL_CONSTANT_ALPHA                 0x8003
-#define GL_ONE_MINUS_CONSTANT_ALPHA       0x8004
-#define GL_BLEND_COLOR                    0x8005
-
-/* Buffer Objects */
-#define GL_ARRAY_BUFFER                   0x8892
-#define GL_ELEMENT_ARRAY_BUFFER           0x8893
-#define GL_ARRAY_BUFFER_BINDING           0x8894
-#define GL_ELEMENT_ARRAY_BUFFER_BINDING   0x8895
-
-#define GL_STREAM_DRAW                    0x88E0
-#define GL_STATIC_DRAW                    0x88E4
-#define GL_DYNAMIC_DRAW                   0x88E8
-
-#define GL_BUFFER_SIZE                    0x8764
-#define GL_BUFFER_USAGE                   0x8765
-
-#define GL_CURRENT_VERTEX_ATTRIB          0x8626
-
-/* CullFaceMode */
-#define GL_FRONT                          0x0404
-#define GL_BACK                           0x0405
-#define GL_FRONT_AND_BACK                 0x0408
-
-/* DepthFunction */
-/*      GL_NEVER */
-/*      GL_LESS */
-/*      GL_EQUAL */
-/*      GL_LEQUAL */
-/*      GL_GREATER */
-/*      GL_NOTEQUAL */
-/*      GL_GEQUAL */
-/*      GL_ALWAYS */
-
-/* EnableCap */
-#define GL_TEXTURE_2D                     0x0DE1
-#define GL_CULL_FACE                      0x0B44         // 2884
-#define GL_BLEND                          0x0BE2         // 3042
-#define GL_DITHER                         0x0BD0         // 3024
-#define GL_STENCIL_TEST                   0x0B90
-#define GL_DEPTH_TEST                     0x0B71         // 2929
-#define GL_SCISSOR_TEST                   0x0C11         // 3089
-#define GL_POLYGON_OFFSET_FILL            0x8037
-#define GL_SAMPLE_ALPHA_TO_COVERAGE       0x809E
-#define GL_SAMPLE_COVERAGE                0x80A0
-
-/* ErrorCode */
-#define GL_NO_ERROR                       0
-#define GL_INVALID_ENUM                   0x0500
-#define GL_INVALID_VALUE                  0x0501
-#define GL_INVALID_OPERATION              0x0502
-#define GL_OUT_OF_MEMORY                  0x0505
-
-/* FrontFaceDirection */
-#define GL_CW                             0x0900
-#define GL_CCW                            0x0901
-
-/* GetPName */
-#define GL_LINE_WIDTH                     0x0B21
-#define GL_ALIASED_POINT_SIZE_RANGE       0x846D
-#define GL_ALIASED_LINE_WIDTH_RANGE       0x846E
-#define GL_CULL_FACE_MODE                 0x0B45
-#define GL_FRONT_FACE                     0x0B46
-#define GL_DEPTH_RANGE                    0x0B70
-#define GL_DEPTH_WRITEMASK                0x0B72
-#define GL_DEPTH_CLEAR_VALUE              0x0B73
-#define GL_DEPTH_FUNC                     0x0B74
-#define GL_STENCIL_CLEAR_VALUE            0x0B91
-#define GL_STENCIL_FUNC                   0x0B92
-#define GL_STENCIL_FAIL                   0x0B94
-#define GL_STENCIL_PASS_DEPTH_FAIL        0x0B95
-#define GL_STENCIL_PASS_DEPTH_PASS        0x0B96
-#define GL_STENCIL_REF                    0x0B97
-#define GL_STENCIL_VALUE_MASK             0x0B93
-#define GL_STENCIL_WRITEMASK              0x0B98
-#define GL_STENCIL_BACK_FUNC              0x8800
-#define GL_STENCIL_BACK_FAIL              0x8801
-#define GL_STENCIL_BACK_PASS_DEPTH_FAIL   0x8802
-#define GL_STENCIL_BACK_PASS_DEPTH_PASS   0x8803
-#define GL_STENCIL_BACK_REF               0x8CA3
-#define GL_STENCIL_BACK_VALUE_MASK        0x8CA4
-#define GL_STENCIL_BACK_WRITEMASK         0x8CA5
-#define GL_VIEWPORT                       0x0BA2
-#define GL_SCISSOR_BOX                    0x0C10
-/*      GL_SCISSOR_TEST */
-#define GL_COLOR_CLEAR_VALUE              0x0C22
-#define GL_COLOR_WRITEMASK                0x0C23
-#define GL_UNPACK_ALIGNMENT               0x0CF5
-#define GL_PACK_ALIGNMENT                 0x0D05
-#define GL_MAX_TEXTURE_SIZE               0x0D33
-#define GL_MAX_VIEWPORT_DIMS              0x0D3A
-#define GL_SUBPIXEL_BITS                  0x0D50
-#define GL_RED_BITS                       0x0D52
-#define GL_GREEN_BITS                     0x0D53
-#define GL_BLUE_BITS                      0x0D54
-#define GL_ALPHA_BITS                     0x0D55
-#define GL_DEPTH_BITS                     0x0D56
-#define GL_STENCIL_BITS                   0x0D57
-#define GL_POLYGON_OFFSET_UNITS           0x2A00
-/*      GL_POLYGON_OFFSET_FILL */
-#define GL_POLYGON_OFFSET_FACTOR          0x8038
-#define GL_TEXTURE_BINDING_2D             0x8069
-#define GL_SAMPLE_BUFFERS                 0x80A8
-#define GL_SAMPLES                        0x80A9
-#define GL_SAMPLE_COVERAGE_VALUE          0x80AA
-#define GL_SAMPLE_COVERAGE_INVERT         0x80AB
-
-/* GetTextureParameter */
-/*      GL_TEXTURE_MAG_FILTER */
-/*      GL_TEXTURE_MIN_FILTER */
-/*      GL_TEXTURE_WRAP_S */
-/*      GL_TEXTURE_WRAP_T */
-
-#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
-#define GL_COMPRESSED_TEXTURE_FORMATS     0x86A3
-
-/* HintMode */
-#define GL_DONT_CARE                      0x1100
-#define GL_FASTEST                        0x1101
-#define GL_NICEST                         0x1102
-
-/* HintTarget */
-#define GL_GENERATE_MIPMAP_HINT            0x8192
-
-/* DataType */
-#define GL_BYTE                           0x1400
-#define GL_UNSIGNED_BYTE                  0x1401
-#define GL_SHORT                          0x1402
-#define GL_UNSIGNED_SHORT                 0x1403
-#define GL_INT                            0x1404
-#define GL_UNSIGNED_INT                   0x1405
-#define GL_FLOAT                          0x1406
-#define GL_FIXED                          0x140C
-
-/* PixelFormat */
-#define GL_DEPTH_COMPONENT                0x1902
-#define GL_ALPHA                          0x1906
-#define GL_RGB                            0x1907
-#define GL_RGBA                           0x1908
-#define GL_LUMINANCE                      0x1909
-#define GL_LUMINANCE_ALPHA                0x190A
-
-/* PixelType */
-/*      GL_UNSIGNED_BYTE */
-#define GL_UNSIGNED_SHORT_4_4_4_4         0x8033
-#define GL_UNSIGNED_SHORT_5_5_5_1         0x8034
-#define GL_UNSIGNED_SHORT_5_6_5           0x8363
-
-/* Shaders */
-#define GL_FRAGMENT_SHADER                  0x8B30
-#define GL_VERTEX_SHADER                    0x8B31
-#define GL_MAX_VERTEX_ATTRIBS               0x8869
-#define GL_MAX_VERTEX_UNIFORM_VECTORS       0x8DFB
-#define GL_MAX_VARYING_VECTORS              0x8DFC
-#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
-#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS   0x8B4C
-#define GL_MAX_TEXTURE_IMAGE_UNITS          0x8872
-#define GL_MAX_FRAGMENT_UNIFORM_VECTORS     0x8DFD
-#define GL_SHADER_TYPE                      0x8B4F
-#define GL_DELETE_STATUS                    0x8B80
-#define GL_LINK_STATUS                      0x8B82
-#define GL_VALIDATE_STATUS                  0x8B83
-#define GL_ATTACHED_SHADERS                 0x8B85
-#define GL_ACTIVE_UNIFORMS                  0x8B86
-#define GL_ACTIVE_UNIFORM_MAX_LENGTH        0x8B87
-#define GL_ACTIVE_ATTRIBUTES                0x8B89
-#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH      0x8B8A
-#define GL_SHADING_LANGUAGE_VERSION         0x8B8C
-#define GL_CURRENT_PROGRAM                  0x8B8D
-
-/* StencilFunction */
-#define GL_NEVER                          0x0200
-#define GL_LESS                           0x0201
-#define GL_EQUAL                          0x0202
-#define GL_LEQUAL                         0x0203
-#define GL_GREATER                        0x0204
-#define GL_NOTEQUAL                       0x0205
-#define GL_GEQUAL                         0x0206
-#define GL_ALWAYS                         0x0207
-
-/* StencilOp */
-/*      GL_ZERO */
-#define GL_KEEP                           0x1E00
-#define GL_REPLACE                        0x1E01
-#define GL_INCR                           0x1E02
-#define GL_DECR                           0x1E03
-#define GL_INVERT                         0x150A
-#define GL_INCR_WRAP                      0x8507
-#define GL_DECR_WRAP                      0x8508
-
-/* StringName */
-#define GL_VENDOR                         0x1F00
-#define GL_RENDERER                       0x1F01
-#define GL_VERSION                        0x1F02
-#define GL_EXTENSIONS                     0x1F03
-
-/* TextureMagFilter */
-#define GL_NEAREST                        0x2600
-#define GL_LINEAR                         0x2601
-
-/* TextureMinFilter */
-/*      GL_NEAREST */
-/*      GL_LINEAR */
-#define GL_NEAREST_MIPMAP_NEAREST         0x2700
-#define GL_LINEAR_MIPMAP_NEAREST          0x2701
-#define GL_NEAREST_MIPMAP_LINEAR          0x2702
-#define GL_LINEAR_MIPMAP_LINEAR           0x2703
-
-/* TextureParameterName */
-#define GL_TEXTURE_MAG_FILTER             0x2800
-#define GL_TEXTURE_MIN_FILTER             0x2801
-#define GL_TEXTURE_WRAP_S                 0x2802
-#define GL_TEXTURE_WRAP_T                 0x2803
-
-/* TextureTarget */
-/*      GL_TEXTURE_2D */
-#define GL_TEXTURE                        0x1702
-
-#define GL_TEXTURE_CUBE_MAP               0x8513
-#define GL_TEXTURE_BINDING_CUBE_MAP       0x8514
-#define GL_TEXTURE_CUBE_MAP_POSITIVE_X    0x8515
-#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X    0x8516
-#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y    0x8517
-#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y    0x8518
-#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z    0x8519
-#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z    0x851A
-#define GL_MAX_CUBE_MAP_TEXTURE_SIZE      0x851C
-
-/* TextureUnit */
-#define GL_TEXTURE0                       0x84C0
-#define GL_TEXTURE1                       0x84C1
-#define GL_TEXTURE2                       0x84C2
-#define GL_TEXTURE3                       0x84C3
-#define GL_TEXTURE4                       0x84C4
-#define GL_TEXTURE5                       0x84C5
-#define GL_TEXTURE6                       0x84C6
-#define GL_TEXTURE7                       0x84C7
-#define GL_TEXTURE8                       0x84C8
-#define GL_TEXTURE9                       0x84C9
-#define GL_TEXTURE10                      0x84CA
-#define GL_TEXTURE11                      0x84CB
-#define GL_TEXTURE12                      0x84CC
-#define GL_TEXTURE13                      0x84CD
-#define GL_TEXTURE14                      0x84CE
-#define GL_TEXTURE15                      0x84CF
-#define GL_TEXTURE16                      0x84D0
-#define GL_TEXTURE17                      0x84D1
-#define GL_TEXTURE18                      0x84D2
-#define GL_TEXTURE19                      0x84D3
-#define GL_TEXTURE20                      0x84D4
-#define GL_TEXTURE21                      0x84D5
-#define GL_TEXTURE22                      0x84D6
-#define GL_TEXTURE23                      0x84D7
-#define GL_TEXTURE24                      0x84D8
-#define GL_TEXTURE25                      0x84D9
-#define GL_TEXTURE26                      0x84DA
-#define GL_TEXTURE27                      0x84DB
-#define GL_TEXTURE28                      0x84DC
-#define GL_TEXTURE29                      0x84DD
-#define GL_TEXTURE30                      0x84DE
-#define GL_TEXTURE31                      0x84DF
-#define GL_ACTIVE_TEXTURE                 0x84E0
-
-/* TextureWrapMode */
-#define GL_REPEAT                         0x2901
-#define GL_CLAMP_TO_EDGE                  0x812F
-#define GL_MIRRORED_REPEAT                0x8370
-
-/* Uniform Types */
-#define GL_FLOAT_VEC2                     0x8B50
-#define GL_FLOAT_VEC3                     0x8B51
-#define GL_FLOAT_VEC4                     0x8B52
-#define GL_INT_VEC2                       0x8B53
-#define GL_INT_VEC3                       0x8B54
-#define GL_INT_VEC4                       0x8B55
-#define GL_BOOL                           0x8B56
-#define GL_BOOL_VEC2                      0x8B57
-#define GL_BOOL_VEC3                      0x8B58
-#define GL_BOOL_VEC4                      0x8B59
-#define GL_FLOAT_MAT2                     0x8B5A
-#define GL_FLOAT_MAT3                     0x8B5B
-#define GL_FLOAT_MAT4                     0x8B5C
-#define GL_SAMPLER_2D                     0x8B5E
-#define GL_SAMPLER_CUBE                   0x8B60
-
-/* Vertex Arrays */
-#define GL_VERTEX_ATTRIB_ARRAY_ENABLED        0x8622
-#define GL_VERTEX_ATTRIB_ARRAY_SIZE           0x8623
-#define GL_VERTEX_ATTRIB_ARRAY_STRIDE         0x8624
-#define GL_VERTEX_ATTRIB_ARRAY_TYPE           0x8625
-#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED     0x886A
-#define GL_VERTEX_ATTRIB_ARRAY_POINTER        0x8645
-#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
-
-/* Read Format */
-#define GL_IMPLEMENTATION_COLOR_READ_TYPE   0x8B9A
-#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
-
-/* Shader Source */
-#define GL_COMPILE_STATUS                 0x8B81
-#define GL_INFO_LOG_LENGTH                0x8B84
-#define GL_SHADER_SOURCE_LENGTH           0x8B88
-#define GL_SHADER_COMPILER                0x8DFA
-
-/* Shader Binary */
-#define GL_SHADER_BINARY_FORMATS          0x8DF8
-#define GL_NUM_SHADER_BINARY_FORMATS      0x8DF9
-
-/* Shader Precision-Specified Types */
-#define GL_LOW_FLOAT                      0x8DF0
-#define GL_MEDIUM_FLOAT                   0x8DF1
-#define GL_HIGH_FLOAT                     0x8DF2
-#define GL_LOW_INT                        0x8DF3
-#define GL_MEDIUM_INT                     0x8DF4
-#define GL_HIGH_INT                       0x8DF5
-
-/* Framebuffer Object. */
-#define GL_FRAMEBUFFER                    0x8D40
-#define GL_RENDERBUFFER                   0x8D41
-
-#define GL_RGBA4                          0x8056
-#define GL_RGB5_A1                        0x8057
-#define GL_RGB565                         0x8D62
-#define GL_DEPTH_COMPONENT16              0x81A5
-#define GL_STENCIL_INDEX                  0x1901
-#define GL_STENCIL_INDEX8                 0x8D48
-
-#define GL_RENDERBUFFER_WIDTH             0x8D42
-#define GL_RENDERBUFFER_HEIGHT            0x8D43
-#define GL_RENDERBUFFER_INTERNAL_FORMAT   0x8D44
-#define GL_RENDERBUFFER_RED_SIZE          0x8D50
-#define GL_RENDERBUFFER_GREEN_SIZE        0x8D51
-#define GL_RENDERBUFFER_BLUE_SIZE         0x8D52
-#define GL_RENDERBUFFER_ALPHA_SIZE        0x8D53
-#define GL_RENDERBUFFER_DEPTH_SIZE        0x8D54
-#define GL_RENDERBUFFER_STENCIL_SIZE      0x8D55
-
-#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE           0x8CD0
-#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME           0x8CD1
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL         0x8CD2
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
-
-#define GL_COLOR_ATTACHMENT0              0x8CE0
-#define GL_DEPTH_ATTACHMENT               0x8D00
-#define GL_STENCIL_ATTACHMENT             0x8D20
-
-#define GL_NONE                           0
-
-#define GL_FRAMEBUFFER_COMPLETE                      0x8CD5
-#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT         0x8CD6
-#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
-#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS         0x8CD9
-#define GL_FRAMEBUFFER_UNSUPPORTED                   0x8CDD
-
-#define GL_FRAMEBUFFER_BINDING            0x8CA6
-#define GL_RENDERBUFFER_BINDING           0x8CA7
-#define GL_MAX_RENDERBUFFER_SIZE          0x84E8
-
-#define GL_INVALID_FRAMEBUFFER_OPERATION  0x0506
-
-//---------------------------//
-// GLES extension defines
-
-/* GL_OES_get_program_binary */
-#ifndef GL_OES_get_program_binary
-#define GL_PROGRAM_BINARY_LENGTH_OES                            0x8741
-#define GL_NUM_PROGRAM_BINARY_FORMATS_OES                       0x87FE
-#define GL_PROGRAM_BINARY_FORMATS_OES                           0x87FF
-#endif
-
-#ifndef GL_ARB_get_program_binary
-#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
-#define GL_PROGRAM_BINARY_LENGTH          0x8741
-#define GL_NUM_PROGRAM_BINARY_FORMATS     0x87FE
-#define GL_PROGRAM_BINARY_FORMATS         0x87FF
-#endif
-
-/* GL_EXT_read_format_bgra */
-#ifndef GL_EXT_read_format_bgra
-#define GL_BGRA_EXT                                             0x80E1
-#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT                       0x8365
-#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT                       0x8366
-#endif
-
-/* GL_EXT_texture_filter_anisotropic */
-#ifndef GL_EXT_texture_filter_anisotropic
-#define GL_TEXTURE_MAX_ANISOTROPY_EXT                           0x84FE
-#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT                       0x84FF
-#endif
-
-/* GL_EXT_texture_format_BGRA8888 */
-#ifndef GL_EXT_texture_format_BGRA8888
-#define GL_BGRA_EXT                                             0x80E1
-#endif
-
-#endif
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-//------------------------------------------------------//
-//                         EGL
-//------------------------------------------------------//
-
-/* EGL Types */
-/* EGLint is defined in eglplatform.h */
-
-//!!!! Should be in
-typedef int EGLint;     // Should properly handle 64bit machine...
-
-//!!!! X11 Dependent...
-typedef Display *EGLNativeDisplayType;
-typedef Pixmap   EGLNativePixmapType;
-typedef Window   EGLNativeWindowType;
-
-typedef unsigned int EGLBoolean;
-typedef unsigned int EGLenum;
-typedef void *EGLConfig;
-typedef void *EGLContext;
-typedef void *EGLDisplay;
-typedef void *EGLSurface;
-typedef void *EGLClientBuffer;
-
-/* EGL Versioning */
-#define EGL_VERSION_1_0                        1
-#define EGL_VERSION_1_1                        1
-#define EGL_VERSION_1_2                        1
-#define EGL_VERSION_1_3                        1
-#define EGL_VERSION_1_4                        1
-
-/* EGL Enumerants. Bitmasks and other exceptional cases aside, most
- * enums are assigned unique values starting at 0x3000.
- */
-
-/* EGL aliases */
-#define EGL_FALSE                      0
-#define EGL_TRUE                       1
-
-/* Out-of-band handle values */
-#define EGL_DEFAULT_DISPLAY            ((EGLNativeDisplayType)0)
-#define EGL_NO_CONTEXT                 ((EGLContext)0)
-#define EGL_NO_DISPLAY                 ((EGLDisplay)0)
-#define EGL_NO_SURFACE                 ((EGLSurface)0)
-
-/* Out-of-band attribute value */
-#define EGL_DONT_CARE                  ((EGLint)-1)
-
-/* Errors / GetError return values */
-#define EGL_SUCCESS                    0x3000
-#define EGL_NOT_INITIALIZED            0x3001
-#define EGL_BAD_ACCESS                 0x3002
-#define EGL_BAD_ALLOC                  0x3003
-#define EGL_BAD_ATTRIBUTE              0x3004
-#define EGL_BAD_CONFIG                 0x3005
-#define EGL_BAD_CONTEXT                        0x3006
-#define EGL_BAD_CURRENT_SURFACE                0x3007
-#define EGL_BAD_DISPLAY                        0x3008
-#define EGL_BAD_MATCH                  0x3009
-#define EGL_BAD_NATIVE_PIXMAP          0x300A
-#define EGL_BAD_NATIVE_WINDOW          0x300B
-#define EGL_BAD_PARAMETER              0x300C
-#define EGL_BAD_SURFACE                        0x300D
-#define EGL_CONTEXT_LOST               0x300E  /* EGL 1.1 - IMG_power_management */
-
-/* Reserved 0x300F-0x301F for additional errors */
-
-/* Config attributes */
-#define EGL_BUFFER_SIZE                        0x3020
-#define EGL_ALPHA_SIZE                 0x3021
-#define EGL_BLUE_SIZE                  0x3022
-#define EGL_GREEN_SIZE                 0x3023
-#define EGL_RED_SIZE                   0x3024
-#define EGL_DEPTH_SIZE                 0x3025
-#define EGL_STENCIL_SIZE               0x3026
-#define EGL_CONFIG_CAVEAT              0x3027
-#define EGL_CONFIG_ID                  0x3028
-#define EGL_LEVEL                      0x3029
-#define EGL_MAX_PBUFFER_HEIGHT         0x302A
-#define EGL_MAX_PBUFFER_PIXELS         0x302B
-#define EGL_MAX_PBUFFER_WIDTH          0x302C
-#define EGL_NATIVE_RENDERABLE          0x302D
-#define EGL_NATIVE_VISUAL_ID           0x302E
-#define EGL_NATIVE_VISUAL_TYPE         0x302F
-#define EGL_PRESERVED_RESOURCES                0x3030
-#define EGL_SAMPLES                    0x3031
-#define EGL_SAMPLE_BUFFERS             0x3032
-#define EGL_SURFACE_TYPE               0x3033
-#define EGL_TRANSPARENT_TYPE           0x3034
-#define EGL_TRANSPARENT_BLUE_VALUE     0x3035
-#define EGL_TRANSPARENT_GREEN_VALUE    0x3036
-#define EGL_TRANSPARENT_RED_VALUE      0x3037
-#define EGL_NONE                       0x3038  /* Attrib list terminator */
-#define EGL_BIND_TO_TEXTURE_RGB                0x3039
-#define EGL_BIND_TO_TEXTURE_RGBA       0x303A
-#define EGL_MIN_SWAP_INTERVAL          0x303B
-#define EGL_MAX_SWAP_INTERVAL          0x303C
-#define EGL_LUMINANCE_SIZE             0x303D
-#define EGL_ALPHA_MASK_SIZE            0x303E
-#define EGL_COLOR_BUFFER_TYPE          0x303F
-#define EGL_RENDERABLE_TYPE            0x3040
-#define EGL_MATCH_NATIVE_PIXMAP                0x3041  /* Pseudo-attribute (not queryable) */
-#define EGL_CONFORMANT                 0x3042
-
-/* Reserved 0x3041-0x304F for additional config attributes */
-
-/* Config attribute values */
-#define EGL_SLOW_CONFIG                        0x3050  /* EGL_CONFIG_CAVEAT value */
-#define EGL_NON_CONFORMANT_CONFIG      0x3051  /* EGL_CONFIG_CAVEAT value */
-#define EGL_TRANSPARENT_RGB            0x3052  /* EGL_TRANSPARENT_TYPE value */
-#define EGL_RGB_BUFFER                 0x308E  /* EGL_COLOR_BUFFER_TYPE value */
-#define EGL_LUMINANCE_BUFFER           0x308F  /* EGL_COLOR_BUFFER_TYPE value */
-
-/* More config attribute values, for EGL_TEXTURE_FORMAT */
-#define EGL_NO_TEXTURE                 0x305C
-#define EGL_TEXTURE_RGB                        0x305D
-#define EGL_TEXTURE_RGBA               0x305E
-#define EGL_TEXTURE_2D                 0x305F
-
-/* Config attribute mask bits */
-#define EGL_PBUFFER_BIT                        0x0001  /* EGL_SURFACE_TYPE mask bits */
-#define EGL_PIXMAP_BIT                 0x0002  /* EGL_SURFACE_TYPE mask bits */
-#define EGL_WINDOW_BIT                 0x0004  /* EGL_SURFACE_TYPE mask bits */
-#define EGL_VG_COLORSPACE_LINEAR_BIT   0x0020  /* EGL_SURFACE_TYPE mask bits */
-#define EGL_VG_ALPHA_FORMAT_PRE_BIT    0x0040  /* EGL_SURFACE_TYPE mask bits */
-#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 /* EGL_SURFACE_TYPE mask bits */
-#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 /* EGL_SURFACE_TYPE mask bits */
-
-#define EGL_OPENGL_ES_BIT              0x0001  /* EGL_RENDERABLE_TYPE mask bits */
-#define EGL_OPENVG_BIT                 0x0002  /* EGL_RENDERABLE_TYPE mask bits */
-#define EGL_OPENGL_ES2_BIT             0x0004  /* EGL_RENDERABLE_TYPE mask bits */
-#define EGL_OPENGL_BIT                 0x0008  /* EGL_RENDERABLE_TYPE mask bits */
-
-/* QueryString targets */
-#define EGL_VENDOR                     0x3053
-#define EGL_VERSION                    0x3054
-#define EGL_EXTENSIONS                 0x3055
-#define EGL_CLIENT_APIS                        0x308D
-
-/* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */
-#define EGL_HEIGHT                     0x3056
-#define EGL_WIDTH                      0x3057
-#define EGL_LARGEST_PBUFFER            0x3058
-#define EGL_TEXTURE_FORMAT             0x3080
-#define EGL_TEXTURE_TARGET             0x3081
-#define EGL_MIPMAP_TEXTURE             0x3082
-#define EGL_MIPMAP_LEVEL               0x3083
-#define EGL_RENDER_BUFFER              0x3086
-#define EGL_VG_COLORSPACE              0x3087
-#define EGL_VG_ALPHA_FORMAT            0x3088
-#define EGL_HORIZONTAL_RESOLUTION      0x3090
-#define EGL_VERTICAL_RESOLUTION                0x3091
-#define EGL_PIXEL_ASPECT_RATIO         0x3092
-#define EGL_SWAP_BEHAVIOR              0x3093
-#define EGL_MULTISAMPLE_RESOLVE                0x3099
-
-/* EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets */
-#define EGL_BACK_BUFFER                        0x3084
-#define EGL_SINGLE_BUFFER              0x3085
-
-/* OpenVG color spaces */
-#define EGL_VG_COLORSPACE_sRGB         0x3089  /* EGL_VG_COLORSPACE value */
-#define EGL_VG_COLORSPACE_LINEAR       0x308A  /* EGL_VG_COLORSPACE value */
-
-/* OpenVG alpha formats */
-#define EGL_VG_ALPHA_FORMAT_NONPRE     0x308B  /* EGL_ALPHA_FORMAT value */
-#define EGL_VG_ALPHA_FORMAT_PRE                0x308C  /* EGL_ALPHA_FORMAT value */
-
-/* Constant scale factor by which fractional display resolutions &
- * aspect ratio are scaled when queried as integer values.
- */
-#define EGL_DISPLAY_SCALING            10000
-
-/* Unknown display resolution/aspect ratio */
-#define EGL_UNKNOWN                    ((EGLint)-1)
-
-/* Back buffer swap behaviors */
-#define EGL_BUFFER_PRESERVED           0x3094  /* EGL_SWAP_BEHAVIOR value */
-#define EGL_BUFFER_DESTROYED           0x3095  /* EGL_SWAP_BEHAVIOR value */
-
-/* CreatePbufferFromClientBuffer buffer types */
-#define EGL_OPENVG_IMAGE               0x3096
-
-/* QueryContext targets */
-#define EGL_CONTEXT_CLIENT_TYPE                0x3097
-
-/* CreateContext attributes */
-#define EGL_CONTEXT_CLIENT_VERSION     0x3098
-
-/* Multisample resolution behaviors */
-#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A /* EGL_MULTISAMPLE_RESOLVE value */
-#define EGL_MULTISAMPLE_RESOLVE_BOX    0x309B  /* EGL_MULTISAMPLE_RESOLVE value */
-
-/* BindAPI/QueryAPI targets */
-#define EGL_OPENGL_ES_API              0x30A0
-#define EGL_OPENVG_API                 0x30A1
-#define EGL_OPENGL_API                 0x30A2
-
-/* GetCurrentSurface targets */
-#define EGL_DRAW                       0x3059
-#define EGL_READ                       0x305A
-
-/* WaitNative engines */
-#define EGL_CORE_NATIVE_ENGINE         0x305B
-
-/* EGL 1.2 tokens renamed for consistency in EGL 1.3 */
-#define EGL_COLORSPACE                 EGL_VG_COLORSPACE
-#define EGL_ALPHA_FORMAT               EGL_VG_ALPHA_FORMAT
-#define EGL_COLORSPACE_sRGB            EGL_VG_COLORSPACE_sRGB
-#define EGL_COLORSPACE_LINEAR          EGL_VG_COLORSPACE_LINEAR
-#define EGL_ALPHA_FORMAT_NONPRE                EGL_VG_ALPHA_FORMAT_NONPRE
-#define EGL_ALPHA_FORMAT_PRE           EGL_VG_ALPHA_FORMAT_PRE
-
-// KHR Extention
-#ifndef EGL_NATIVE_PIXMAP_KHR
-# define EGL_NATIVE_PIXMAP_KHR 0x30b0
-#endif
-
-#else
-
-//------------------------------------------------------//
-//                         GLX
-//------------------------------------------------------//
-
-#define GLX_VERSION_1_1                1
-#define GLX_VERSION_1_2                1
-#define GLX_VERSION_1_3                1
-#define GLX_VERSION_1_4                1
-
-#define GLX_EXTENSION_NAME   "GLX"
-
-/*
- * Tokens for glXChooseVisual and glXGetConfig:
- */
-#define GLX_USE_GL             1
-#define GLX_BUFFER_SIZE                2
-#define GLX_LEVEL              3
-#define GLX_RGBA               4
-#define GLX_DOUBLEBUFFER       5
-#define GLX_STEREO             6
-#define GLX_AUX_BUFFERS                7
-#define GLX_RED_SIZE           8
-#define GLX_GREEN_SIZE         9
-#define GLX_BLUE_SIZE          10
-#define GLX_ALPHA_SIZE         11
-#define GLX_DEPTH_SIZE         12
-#define GLX_STENCIL_SIZE       13
-#define GLX_ACCUM_RED_SIZE     14
-#define GLX_ACCUM_GREEN_SIZE   15
-#define GLX_ACCUM_BLUE_SIZE    16
-#define GLX_ACCUM_ALPHA_SIZE   17
-
-
-/*
- * Error codes returned by glXGetConfig:
- */
-#define GLX_BAD_SCREEN         1
-#define GLX_BAD_ATTRIBUTE      2
-#define GLX_NO_EXTENSION       3
-#define GLX_BAD_VISUAL         4
-#define GLX_BAD_CONTEXT                5
-#define GLX_BAD_VALUE          6
-#define GLX_BAD_ENUM           7
-
-
-/*
- * GLX 1.1 and later:
- */
-#define GLX_VENDOR             1
-#define GLX_VERSION            2
-#define GLX_EXTENSIONS                 3
-
-
-/*
- * GLX 1.3 and later:
- */
-#define GLX_CONFIG_CAVEAT              0x20
-#define GLX_DONT_CARE                  0xFFFFFFFF
-#define GLX_X_VISUAL_TYPE              0x22
-#define GLX_TRANSPARENT_TYPE           0x23
-#define GLX_TRANSPARENT_INDEX_VALUE    0x24
-#define GLX_TRANSPARENT_RED_VALUE      0x25
-#define GLX_TRANSPARENT_GREEN_VALUE    0x26
-#define GLX_TRANSPARENT_BLUE_VALUE     0x27
-#define GLX_TRANSPARENT_ALPHA_VALUE    0x28
-#define GLX_WINDOW_BIT                 0x00000001
-#define GLX_PIXMAP_BIT                 0x00000002
-#define GLX_PBUFFER_BIT                        0x00000004
-#define GLX_AUX_BUFFERS_BIT            0x00000010
-#define GLX_FRONT_LEFT_BUFFER_BIT      0x00000001
-#define GLX_FRONT_RIGHT_BUFFER_BIT     0x00000002
-#define GLX_BACK_LEFT_BUFFER_BIT       0x00000004
-#define GLX_BACK_RIGHT_BUFFER_BIT      0x00000008
-#define GLX_DEPTH_BUFFER_BIT           0x00000020
-#define GLX_STENCIL_BUFFER_BIT         0x00000040
-#define GLX_ACCUM_BUFFER_BIT           0x00000080
-#define GLX_NONE                       0x8000
-#define GLX_SLOW_CONFIG                        0x8001
-#define GLX_TRUE_COLOR                 0x8002
-#define GLX_DIRECT_COLOR               0x8003
-#define GLX_PSEUDO_COLOR               0x8004
-#define GLX_STATIC_COLOR               0x8005
-#define GLX_GRAY_SCALE                 0x8006
-#define GLX_STATIC_GRAY                        0x8007
-#define GLX_TRANSPARENT_RGB            0x8008
-#define GLX_TRANSPARENT_INDEX          0x8009
-#define GLX_VISUAL_ID                  0x800B
-#define GLX_SCREEN                     0x800C
-#define GLX_NON_CONFORMANT_CONFIG      0x800D
-#define GLX_DRAWABLE_TYPE              0x8010
-#define GLX_RENDER_TYPE                        0x8011
-#define GLX_X_RENDERABLE               0x8012
-#define GLX_FBCONFIG_ID                        0x8013
-#define GLX_RGBA_TYPE                  0x8014
-#define GLX_COLOR_INDEX_TYPE           0x8015
-#define GLX_MAX_PBUFFER_WIDTH          0x8016
-#define GLX_MAX_PBUFFER_HEIGHT         0x8017
-#define GLX_MAX_PBUFFER_PIXELS         0x8018
-#define GLX_PRESERVED_CONTENTS         0x801B
-#define GLX_LARGEST_PBUFFER            0x801C
-#define GLX_WIDTH                      0x801D
-#define GLX_HEIGHT                     0x801E
-#define GLX_EVENT_MASK                 0x801F
-#define GLX_DAMAGED                    0x8020
-#define GLX_SAVED                      0x8021
-#define GLX_WINDOW                     0x8022
-#define GLX_PBUFFER                    0x8023
-#define GLX_PBUFFER_HEIGHT              0x8040
-#define GLX_PBUFFER_WIDTH               0x8041
-#define GLX_RGBA_BIT                   0x00000001
-#define GLX_COLOR_INDEX_BIT            0x00000002
-#define GLX_PBUFFER_CLOBBER_MASK       0x08000000
-
-
-/*
- * GLX 1.4 and later:
- */
-#define GLX_SAMPLE_BUFFERS              0x186a0 /*100000*/
-#define GLX_SAMPLES                     0x186a1 /*100001*/
-
-
-
-typedef struct __GLXcontextRec *GLXContext;
-typedef XID GLXPixmap;
-typedef XID GLXDrawable;
-/* GLX 1.3 and later */
-typedef struct __GLXFBConfigRec *GLXFBConfig;
-typedef XID GLXFBConfigID;
-typedef XID GLXContextID;
-typedef XID GLXWindow;
-typedef XID GLXPbuffer;
-
-
-
-/*
- * #?. GLX_EXT_texture_from_pixmap
- * XXX not finished?
- */
-#ifndef GLX_EXT_texture_from_pixmap
-#define GLX_EXT_texture_from_pixmap 1
-
-#define GLX_BIND_TO_TEXTURE_RGB_EXT        0x20D0
-#define GLX_BIND_TO_TEXTURE_RGBA_EXT       0x20D1
-#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT     0x20D2
-#define GLX_BIND_TO_TEXTURE_TARGETS_EXT    0x20D3
-#define GLX_Y_INVERTED_EXT                 0x20D4
-
-#define GLX_TEXTURE_FORMAT_EXT             0x20D5
-#define GLX_TEXTURE_TARGET_EXT             0x20D6
-#define GLX_MIPMAP_TEXTURE_EXT             0x20D7
-
-#define GLX_TEXTURE_FORMAT_NONE_EXT        0x20D8
-#define GLX_TEXTURE_FORMAT_RGB_EXT         0x20D9
-#define GLX_TEXTURE_FORMAT_RGBA_EXT        0x20DA
-
-#define GLX_TEXTURE_1D_BIT_EXT             0x00000001
-#define GLX_TEXTURE_2D_BIT_EXT             0x00000002
-#define GLX_TEXTURE_RECTANGLE_BIT_EXT      0x00000004
-
-#define GLX_TEXTURE_1D_EXT                 0x20DB
-#define GLX_TEXTURE_2D_EXT                 0x20DC
-#define GLX_TEXTURE_RECTANGLE_EXT          0x20DD
-
-#define GLX_FRONT_LEFT_EXT                 0x20DE
-#define GLX_FRONT_RIGHT_EXT                0x20DF
-#define GLX_BACK_LEFT_EXT                  0x20E0
-#define GLX_BACK_RIGHT_EXT                 0x20E1
-#define GLX_FRONT_EXT                      GLX_FRONT_LEFT_EXT
-#define GLX_BACK_EXT                       GLX_BACK_LEFT_EXT
-#define GLX_AUX0_EXT                       0x20E2
-#define GLX_AUX1_EXT                       0x20E3
-#define GLX_AUX2_EXT                       0x20E4
-#define GLX_AUX3_EXT                       0x20E5
-#define GLX_AUX4_EXT                       0x20E6
-#define GLX_AUX5_EXT                       0x20E7
-#define GLX_AUX6_EXT                       0x20E8
-#define GLX_AUX7_EXT                       0x20E9
-#define GLX_AUX8_EXT                       0x20EA
-#define GLX_AUX9_EXT                       0x20EB
-
-#endif //GLX_EXT_texture_from_pixmap
-
-#endif //EGL vs. GLX
-
-
-//------------------------------------------------------//
-
-#define MAX_TEXTURE_UNITS 32
-#define MAX_VERTEX_ATTRIBS 16
-typedef struct _EvasGlueContext     *EvasGlueContext;
-
-typedef struct _GL_Texture_State
-{
-   GLint    tex_unit;
-   GLuint   tex_id;
-} GL_Texture_State;
-
-typedef struct _GL_Vertex_Array_State
-{
-   GLboolean   modified;
-   GLboolean   enabled;
-   GLuint      buf_id;
-   GLint       size;
-   GLenum      type;
-   GLboolean   normalized;
-   GLsizei     stride;
-   void       *pointer;
-} GL_Vertex_Array_State;
-
-typedef struct _GL_Vertex_Attrib
-{
-   GLboolean   modified;
-   GLfloat     value[4];
-} GL_Vertex_Attrib;
-
-
-#define MAGIC_GLFAST   0x73777770
-
-struct _EvasGlueContext
-{
-
-   int            magic;
-
-   // First time flag
-   int            initialized;
-   int            destroyed;
-
-   // Default Framebuffer and RenderBuffers
-   GLuint         fb_zero;
-   GLuint         rb_zero;
-   GLuint         evasgl_enabled;
-
-   GLint          num_tex_units;
-   GLint          num_vertex_attribs;
-
-   //----------------------------------------//
-   // GL States
-   // Bind Functions
-   // glBind {Buffer, Framebuffer, Renderbuffer}
-   // * Texture Binding is done with textures
-   unsigned char _bind_flag;
-   GLuint      gl_array_buffer_binding;               // 0
-   GLuint      gl_element_array_buffer_binding;       // 0
-   GLuint      gl_framebuffer_binding;                // 0
-   GLuint      gl_renderbuffer_binding;               // 0
-
-   //------------------//
-   // Enable States
-   // glEnable()
-   unsigned char _enable_flag1;
-   GLboolean   gl_blend;                              // GL_FALSE
-   GLboolean   gl_cull_face;                          // GL_FALSE
-   GLboolean   gl_depth_test;                         // GL_FALSE
-   GLboolean   gl_dither;                             // GL_TRUE
-
-   unsigned char _enable_flag2;
-   GLboolean   gl_polygon_offset_fill;                // GL_FALSE
-   GLboolean   gl_sample_alpha_to_coverage;           // GL_FALSE
-   GLboolean   gl_sample_coverage;                    // GL_FALSE
-   GLboolean   gl_scissor_test;                       // GL_FALSE
-   GLboolean   gl_stencil_test;                       // GL_FALSE
-
-   //------------------//
-   unsigned char _clear_flag1;
-   // Viewport
-   GLint       gl_viewport[4];                        // (0,0,w,h)
-   // Program (Shaders)
-   GLuint      gl_current_program;                    // 0
-
-   // Clear Color
-   GLclampf    gl_color_clear_value[4];               // (0,0,0,0)
-
-   //------------------//
-   unsigned char _clear_flag2;
-   GLboolean   gl_color_writemask[4];                 // (GL_TRUE x 4)
-   // Depth
-   GLclampf    gl_depth_range[2];                     // (0,1)
-   GLclampf    gl_depth_clear_value;                  // 1
-   GLenum      gl_depth_func;                         // GL_LESS
-   GLboolean   gl_depth_writemask;                    // GL_TRUE
-
-   GLenum      gl_cull_face_mode;                     // GL_BACK
-
-   //------------------//
-   unsigned char _tex_flag1;
-   // Texture
-   //GL_Texture_State  tex_state[MAX_TEXTURE_UNITS];
-   GLuint            tex_2d_state[MAX_TEXTURE_UNITS];
-   GLuint            tex_cube_map_state[MAX_TEXTURE_UNITS];
-   GLenum            gl_active_texture;               // GL_TEXTURE0
-   GLenum            gl_generate_mipmap_hint;         // GL_DONT_CARE
-   GLuint            gl_texture_binding_2d;           // 0
-   GLuint            gl_texture_binding_cube_map;     // 0
-
-   //unsigned char _tex_flag2[4];
-
-   //------------------//
-   unsigned char _blend_flag;
-   // Blending
-   GLclampf    gl_blend_color[4];
-   GLenum      gl_blend_src_rgb;                      // GL_ONE
-   GLenum      gl_blend_src_alpha;                    // GL_ONE
-   GLenum      gl_blend_dst_rgb;                      // GL_ZERO
-   GLenum      gl_blend_dst_alpha;                    // GL_ZERO
-   GLenum      gl_blend_equation_rgb;
-   GLenum      gl_blend_equation_alpha;
-
-   //------------------//
-   unsigned char _stencil_flag1;
-   // Stencil
-   GLenum      gl_stencil_func;                       // GL_ALWAYS
-   GLint       gl_stencil_ref;
-   GLuint      gl_stencil_value_mask;                 // 0xffffffff
-   GLenum      gl_stencil_fail;                       // GL_KEEP
-   GLenum      gl_stencil_pass_depth_fail;            // GL_KEEP
-   GLenum      gl_stencil_pass_depth_pass;            // GL_KEEP
-   GLuint      gl_stencil_writemask;                  // 0xffffffff
-
-   unsigned char _stencil_flag2;
-   GLenum      gl_stencil_back_func;                  // GL_ALWAYS
-   GLint       gl_stencil_back_ref;
-   GLuint      gl_stencil_back_value_mask;            // 0xffffffff
-   GLenum      gl_stencil_back_fail;                  // GL_KEEP
-   GLenum      gl_stencil_back_pass_depth_fail;       // GL_KEEP
-   GLenum      gl_stencil_back_pass_depth_pass;       // GL_KEEP
-   GLuint      gl_stencil_back_writemask;             // 0xffffffff
-
-   GLint       gl_stencil_clear_value;
-
-
-   //------------------//
-
-
-   //------------------//
-   unsigned char _misc_flag1;
-   GLenum      gl_front_face;                         // GL_CCW
-   GLfloat     gl_line_width;                         // 1
-   GLfloat     gl_polygon_offset_factor;              // 0
-   GLfloat     gl_polygon_offset_units;               // 0
-   GLclampf    gl_sample_coverage_value;
-   GLboolean   gl_sample_coverage_invert;
-
-   unsigned char _misc_flag2;
-   GLint       gl_scissor_box[4];                     // (0,0,w,h)
-   GLint       gl_pack_alignment;                     // 4
-   GLint       gl_unpack_alignment;                   // 4
-
-   //------------------//
-   // Vertex Attrib Array
-   unsigned char _vattrib_flag;
-   GL_Vertex_Array_State      vertex_array[MAX_VERTEX_ATTRIBS];
-   GLint                      gl_current_vertex_attrib[4];
-   GL_Vertex_Attrib           vertex_attrib[MAX_VERTEX_ATTRIBS];
-
-   int id;
-
-};
-
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-//------------------------------------------------------//
-
-typedef void (*_eng_fn) (void);
-
-//------------------------------------------------------//
-// EGL APIs... Only ones that are being used.
-
-// Standard EGL APIs
-extern _eng_fn       (*GL(eglGetProcAddress))                     (const char* procname);
-
-extern EGLint        (*GL(eglGetError))                  (void);
-extern EGLDisplay    (*GL(eglGetDisplay))                (EGLNativeDisplayType display_id);
-extern EGLBoolean    (*GL(eglInitialize))                (EGLDisplay dpy, EGLint* major, EGLint *minor);
-extern EGLBoolean    (*GL(eglTerminate))                 (EGLDisplay dpy);
-extern EGLBoolean    (*GL(eglChooseConfig))              (EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config);
-extern EGLSurface    (*GL(eglCreateWindowSurface))       (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint* attrib_list);
-extern EGLSurface    (*GL(eglCreatePixmapSurface))       (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint* attrib_list);
-extern EGLBoolean    (*GL(eglDestroySurface))            (EGLDisplay dpy, EGLSurface surface);
-extern EGLBoolean    (*GL(eglBindAPI))                   (EGLenum api);
-extern EGLBoolean    (*GL(eglWaitClient))                (void);
-extern EGLBoolean    (*GL(eglSurfaceAttrib))             (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
-extern void          (*GL(eglBindTexImage))              (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-extern EGLBoolean    (*GL(eglReleaseTexImage))           (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-extern EGLBoolean    (*GL(eglSwapInterval))              (EGLDisplay dpy, EGLint interval);
-extern EGLContext    (*GL(eglCreateContext))             (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint* attrib_list);
-extern EGLBoolean    (*GL(eglDestroyContext))            (EGLDisplay dpy, EGLContext ctx);
-extern EGLBoolean    (*GL(eglMakeCurrent))               (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
-extern EGLContext    (*GL(eglGetCurrentContext))         (void);
-extern EGLSurface    (*GL(eglGetCurrentSurface))         (EGLint readdraw);
-extern EGLDisplay    (*GL(eglGetCurrentDisplay))         (void);
-extern EGLBoolean    (*GL(eglWaitGL))                    (void);
-extern EGLBoolean    (*GL(eglWaitNative))                (EGLint engine);
-extern EGLBoolean    (*GL(eglSwapBuffers))               (EGLDisplay dpy, EGLSurface surface);
-extern EGLBoolean    (*GL(eglCopyBuffers))               (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
-extern char const   *(*GL(eglQueryString))               (EGLDisplay dpy, EGLint name);
-
-// Extensions
-extern void         *(*GL(eglCreateImage))               (void *a, void *b, GLenum c, void *d, const int *e);
-extern unsigned int  (*GL(eglDestroyImage))              (void *a, void *b);
-extern void          (*GL(glEGLImageTargetTexture2DOES)) (int a, void *b);
-extern void          (*GL(glEGLImageTargetRenderbufferStorageOES)) (int a, void *b);
-extern void         *(*GL(eglMapImageSEC))               (void *a, void *b);
-extern unsigned int  (*GL(eglUnmapImageSEC))             (void *a, void *b);
-extern unsigned int  (*GL(eglGetImageAttribSEC))         (void *a, void *b, int c, int *d);
-//extern unsigned int   (*GL(eglLockSurface))              (EGLDisplay a, EGLSurface b, const int *attrib_list);
-//extern unsigned int   (*GL(eglUnlockSurface))            (EGLDisplay a, EGLSurface b);
-
-
-//------------------------------------------------------//
-
-#else
-
-//------------------------------------------------------//
-
-typedef void (*_eng_fn) (void);
-
-//------------------------------------------------------//
-// GLX APIs... Only ones that are being used.
-
-//--------//
-extern _eng_fn      (*GL(glXGetProcAddress))            (const char* procName);
-
-// Standard GL(glX) functions
-extern XVisualInfo* (*GL(glXChooseVisual))              (Display* dpy, int screen, int* attribList);
-extern GLXContext   (*GL(glXCreateContext))             (Display* dpy, XVisualInfo* vis, GLXContext shareList, Bool direct);
-extern void         (*GL(glXDestroyContext))            (Display* dpy, GLXContext ctx);
-extern GLXContext   (*GL(glXGetCurrentContext))         (void);
-extern GLXDrawable  (*GL(glXGetCurrentDrawable))        (void);
-extern Bool         (*GL(glXMakeCurrent))               (Display* dpy, GLXDrawable draw, GLXContext ctx);
-extern void         (*GL(glXSwapBuffers))               (Display* dpy, GLXDrawable draw);
-extern void         (*GL(glXWaitX))                     (void);
-extern void         (*GL(glXWaitGL))                    (void);
-extern Bool         (*GL(glXQueryExtension))            (Display* dpy, int* errorb, int* event);
-extern const char  *(*GL(glXQueryExtensionsString))     (Display *dpy, int screen);
-
-//--------//
-extern GLXFBConfig* (*GL(glXChooseFBConfig))            (Display* dpy, int screen, const int* attribList, int* nitems);
-extern GLXFBConfig* (*GL(glXGetFBConfigs))              (Display* dpy, int screen, int* nelements);
-extern int          (*GL(glXGetFBConfigAttrib))         (Display* dpy, GLXFBConfig config, int attribute, int* value);
-extern XVisualInfo* (*GL(glXGetVisualFromFBConfig))     (Display* dpy, GLXFBConfig config);
-extern void         (*GL(glXDestroyWindow))             (Display* dpy, GLXWindow window);
-extern Bool         (*GL(glXMakeContextCurrent))        (Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
-//--------//
-
-extern void         (*GL(glXBindTexImage))              (Display* dpy, GLXDrawable draw, int buffer, int* attribList);
-extern void         (*GL(glXReleaseTexImage))           (Display* dpy, GLXDrawable draw, int buffer);
-extern int          (*GL(glXGetVideoSync))              (unsigned int* count);
-extern int          (*GL(glXWaitVideoSync))             (int divisor, int remainder, unsigned int* count);
-extern XID          (*GL(glXCreatePixmap))              (Display* dpy, void* config, Pixmap pixmap, const int* attribList);
-extern void         (*GL(glXDestroyPixmap))             (Display* dpy, XID pixmap);
-extern void         (*GL(glXQueryDrawable))             (Display* dpy, XID draw, int attribute, unsigned int* value);
-extern int          (*GL(glXSwapIntervalSGI))           (int interval);
-extern void         (*GL(glXSwapIntervalEXT))           (Display* dpy, GLXDrawable draw, int interval);
-
-//--------//
-
-#endif // EGL vs. GLX
-
-//------------------------------------------------------//
-
-typedef enum _Evas_GL_Opt_Flag
-{
-   GL_NORMAL_PATH,
-   GL_WRAPPED_PATH,
-   GL_FAST_PATH
-} Evas_GL_Opt_Flag;
-
-
-//#define GL_ERRORS 1
-   /*
-   { \
-      int __gl_err = GL(glGetError)(); \
-      if (__gl_err != GL_NO_ERROR) glerr(__gl_err, fl, fn, ln, op); \
-   }
-   */
-#ifdef GL_ERRORS
-# define GLERR(fn, fl, ln, op) \
-   { \
-      int __gl_err = GL(glGetError)(); \
-      if (__gl_err != GL_NO_ERROR) glerr(__gl_err, fl, fn, ln, op); \
-   }
-#else
-# define GLERR(fn, fl, ln, op)
-#endif
-
-extern int  init_gl();
-extern void free_gl();
-extern void print_gl_states();
-
-#define PRINT_GL_STATES(fn, ln)  \
-   print_gl_states(fn, ln);
-
-   /* version 1: */
-extern   void         (*GL(glActiveTexture)) (GLenum texture);
-extern   void         (*GL(glAttachShader)) (GLuint program, GLuint shader);
-extern   void         (*GL(glBindAttribLocation)) (GLuint program, GLuint index, const char* name);
-extern   void         (*GL(glBindBuffer)) (GLenum target, GLuint buffer);
-extern   void         (*GL(glBindFramebuffer)) (GLenum target, GLuint framebuffer);
-extern   void         (*GL(glBindRenderbuffer)) (GLenum target, GLuint renderbuffer);
-extern   void         (*GL(glBindTexture)) (GLenum target, GLuint texture);
-extern   void         (*GL(glBlendColor)) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
-extern   void         (*GL(glBlendEquation)) ( GLenum mode );
-extern   void         (*GL(glBlendEquationSeparate)) (GLenum modeRGB, GLenum modeAlpha);
-extern   void         (*GL(glBlendFunc)) (GLenum sfactor, GLenum dfactor);
-extern   void         (*GL(glBlendFuncSeparate)) (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
-extern   void         (*GL(glBufferData)) (GLenum target, GLsizeiptr size, const void* data, GLenum usage);
-extern   void         (*GL(glBufferSubData)) (GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
-extern   GLenum       (*GL(glCheckFramebufferStatus)) (GLenum target);
-extern   void         (*GL(glClear)) (GLbitfield mask);
-extern   void         (*GL(glClearColor)) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
-extern   void         (*GL(glClearDepthf)) (GLclampf depth);
-extern   void         (*GL(glClearStencil)) (GLint s);
-extern   void         (*GL(glColorMask)) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
-extern   void         (*GL(glCompileShader)) (GLuint shader);
-extern   void         (*GL(glCompressedTexImage2D)) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data);
-extern   void         (*GL(glCompressedTexSubImage2D)) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data);
-extern   void         (*GL(glCopyTexImage2D)) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
-extern   void         (*GL(glCopyTexSubImage2D)) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
-extern   GLuint       (*GL(glCreateProgram)) (void);
-extern   GLuint       (*GL(glCreateShader)) (GLenum type);
-extern   void         (*GL(glCullFace)) (GLenum mode);
-extern   void         (*GL(glDeleteBuffers)) (GLsizei n, const GLuint* buffers);
-extern   void         (*GL(glDeleteFramebuffers)) (GLsizei n, const GLuint* framebuffers);
-extern   void         (*GL(glDeleteProgram)) (GLuint program);
-extern   void         (*GL(glDeleteRenderbuffers)) (GLsizei n, const GLuint* renderbuffers);
-extern   void         (*GL(glDeleteShader)) (GLuint shader);
-extern   void         (*GL(glDeleteTextures)) (GLsizei n, const GLuint* textures);
-extern   void         (*GL(glDepthFunc)) (GLenum func);
-extern   void         (*GL(glDepthMask)) (GLboolean flag);
-extern   void         (*GL(glDepthRangef)) (GLclampf zNear, GLclampf zFar);
-extern   void         (*GL(glDetachShader)) (GLuint program, GLuint shader);
-extern   void         (*GL(glDisable)) (GLenum cap);
-extern   void         (*GL(glDisableVertexAttribArray)) (GLuint index);
-extern   void         (*GL(glDrawArrays)) (GLenum mode, GLint first, GLsizei count);
-extern   void         (*GL(glDrawElements)) (GLenum mode, GLsizei count, GLenum type, const void* indices);
-extern   void         (*GL(glEnable)) (GLenum cap);
-extern   void         (*GL(glEnableVertexAttribArray)) (GLuint index);
-extern   void         (*GL(glFinish)) (void);
-extern   void         (*GL(glFlush)) (void);
-extern   void         (*GL(glFramebufferRenderbuffer)) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
-extern   void         (*GL(glFramebufferTexture2D)) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
-extern   void         (*GL(glFrontFace)) (GLenum mode);
-extern   void         (*GL(glGenBuffers)) (GLsizei n, GLuint* buffers);
-extern   void         (*GL(glGenerateMipmap)) (GLenum target);
-extern   void         (*GL(glGenFramebuffers)) (GLsizei n, GLuint* framebuffers);
-extern   void         (*GL(glGenRenderbuffers)) (GLsizei n, GLuint* renderbuffers);
-extern   void         (*GL(glGenTextures)) (GLsizei n, GLuint* textures);
-extern   void         (*GL(glGetActiveAttrib)) (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
-extern   void         (*GL(glGetActiveUniform)) (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
-extern   void         (*GL(glGetAttachedShaders)) (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
-extern   int          (*GL(glGetAttribLocation)) (GLuint program, const char* name);
-extern   void         (*GL(glGetBooleanv)) (GLenum pname, GLboolean* params);
-extern   void         (*GL(glGetBufferParameteriv)) (GLenum target, GLenum pname, GLint* params);
-extern   GLenum       (*GL(glGetError)) (void);
-extern   void         (*GL(glGetFloatv)) (GLenum pname, GLfloat* params);
-extern   void         (*GL(glGetFramebufferAttachmentParameteriv)) (GLenum target, GLenum attachment, GLenum pname, GLint* params);
-extern   void         (*GL(glGetIntegerv)) (GLenum pname, GLint* params);
-extern   void         (*GL(glGetProgramiv)) (GLuint program, GLenum pname, GLint* params);
-extern   void         (*GL(glGetProgramInfoLog)) (GLuint program, GLsizei bufsize, GLsizei* length, char* infolog);
-extern   void         (*GL(glGetRenderbufferParameteriv)) (GLenum target, GLenum pname, GLint* params);
-extern   void         (*GL(glGetShaderiv)) (GLuint shader, GLenum pname, GLint* params);
-extern   void         (*GL(glGetShaderInfoLog)) (GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog);
-extern   void         (*GL(glGetShaderPrecisionFormat)) (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
-extern   void         (*GL(glGetShaderSource)) (GLuint shader, GLsizei bufsize, GLsizei* length, char* source);
-extern   const GLubyte *(*GL(glGetString)) (GLenum name);
-extern   void         (*GL(glGetTexParameterfv)) (GLenum target, GLenum pname, GLfloat* params);
-extern   void         (*GL(glGetTexParameteriv)) (GLenum target, GLenum pname, GLint* params);
-extern   void         (*GL(glGetUniformfv)) (GLuint program, GLint location, GLfloat* params);
-extern   void         (*GL(glGetUniformiv)) (GLuint program, GLint location, GLint* params);
-extern   int          (*GL(glGetUniformLocation)) (GLuint program, const char* name);
-extern   void         (*GL(glGetVertexAttribfv)) (GLuint index, GLenum pname, GLfloat* params);
-extern   void         (*GL(glGetVertexAttribiv)) (GLuint index, GLenum pname, GLint* params);
-extern   void         (*GL(glGetVertexAttribPointerv)) (GLuint index, GLenum pname, void** pointer);
-extern   void         (*GL(glHint)) (GLenum target, GLenum mode);
-extern   GLboolean    (*GL(glIsBuffer)) (GLuint buffer);
-extern   GLboolean    (*GL(glIsEnabled)) (GLenum cap);
-extern   GLboolean    (*GL(glIsFramebuffer)) (GLuint framebuffer);
-extern   GLboolean    (*GL(glIsProgram)) (GLuint program);
-extern   GLboolean    (*GL(glIsRenderbuffer)) (GLuint renderbuffer);
-extern   GLboolean    (*GL(glIsShader)) (GLuint shader);
-extern   GLboolean    (*GL(glIsTexture)) (GLuint texture);
-extern   void         (*GL(glLineWidth)) (GLfloat width);
-extern   void         (*GL(glLinkProgram)) (GLuint program);
-extern   void         (*GL(glPixelStorei)) (GLenum pname, GLint param);
-extern   void         (*GL(glPolygonOffset)) (GLfloat factor, GLfloat units);
-extern   void         (*GL(glReadPixels)) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels);
-extern   void         (*GL(glReleaseShaderCompiler)) (void);
-extern   void         (*GL(glRenderbufferStorage)) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
-extern   void         (*GL(glSampleCoverage)) (GLclampf value, GLboolean invert);
-extern   void         (*GL(glScissor)) (GLint x, GLint y, GLsizei width, GLsizei height);
-extern   void         (*GL(glShaderBinary)) (GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length);
-extern   void         (*GL(glShaderSource)) (GLuint shader, GLsizei count, const char** string, const GLint* length);
-extern   void         (*GL(glStencilFunc)) (GLenum func, GLint ref, GLuint mask);
-extern   void         (*GL(glStencilFuncSeparate)) (GLenum face, GLenum func, GLint ref, GLuint mask);
-extern   void         (*GL(glStencilMask)) (GLuint mask);
-extern   void         (*GL(glStencilMaskSeparate)) (GLenum face, GLuint mask);
-extern   void         (*GL(glStencilOp)) (GLenum fail, GLenum zfail, GLenum zpass);
-extern   void         (*GL(glStencilOpSeparate)) (GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
-extern   void         (*GL(glTexImage2D)) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels);
-extern   void         (*GL(glTexParameterf)) (GLenum target, GLenum pname, GLfloat param);
-extern   void         (*GL(glTexParameterfv)) (GLenum target, GLenum pname, const GLfloat* params);
-extern   void         (*GL(glTexParameteri)) (GLenum target, GLenum pname, GLint param);
-extern   void         (*GL(glTexParameteriv)) (GLenum target, GLenum pname, const GLint* params);
-extern   void         (*GL(glTexSubImage2D)) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels);
-extern   void         (*GL(glUniform1f)) (GLint location, GLfloat x);
-extern   void         (*GL(glUniform1fv)) (GLint location, GLsizei count, const GLfloat* v);
-extern   void         (*GL(glUniform1i)) (GLint location, GLint x);
-extern   void         (*GL(glUniform1iv)) (GLint location, GLsizei count, const GLint* v);
-extern   void         (*GL(glUniform2f)) (GLint location, GLfloat x, GLfloat y);
-extern   void         (*GL(glUniform2fv)) (GLint location, GLsizei count, const GLfloat* v);
-extern   void         (*GL(glUniform2i)) (GLint location, GLint x, GLint y);
-extern   void         (*GL(glUniform2iv)) (GLint location, GLsizei count, const GLint* v);
-extern   void         (*GL(glUniform3f)) (GLint location, GLfloat x, GLfloat y, GLfloat z);
-extern   void         (*GL(glUniform3fv)) (GLint location, GLsizei count, const GLfloat* v);
-extern   void         (*GL(glUniform3i)) (GLint location, GLint x, GLint y, GLint z);
-extern   void         (*GL(glUniform3iv)) (GLint location, GLsizei count, const GLint* v);
-extern   void         (*GL(glUniform4f)) (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-extern   void         (*GL(glUniform4fv)) (GLint location, GLsizei count, const GLfloat* v);
-extern   void         (*GL(glUniform4i)) (GLint location, GLint x, GLint y, GLint z, GLint w);
-extern   void         (*GL(glUniform4iv)) (GLint location, GLsizei count, const GLint* v);
-extern   void         (*GL(glUniformMatrix2fv)) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
-extern   void         (*GL(glUniformMatrix3fv)) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
-extern   void         (*GL(glUniformMatrix4fv)) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
-extern   void         (*GL(glUseProgram)) (GLuint program);
-extern   void         (*GL(glValidateProgram)) (GLuint program);
-extern   void         (*GL(glVertexAttrib1f)) (GLuint indx, GLfloat x);
-extern   void         (*GL(glVertexAttrib1fv)) (GLuint indx, const GLfloat* values);
-extern   void         (*GL(glVertexAttrib2f)) (GLuint indx, GLfloat x, GLfloat y);
-extern   void         (*GL(glVertexAttrib2fv)) (GLuint indx, const GLfloat* values);
-extern   void         (*GL(glVertexAttrib3f)) (GLuint indx, GLfloat x, GLfloat y, GLfloat z);
-extern   void         (*GL(glVertexAttrib3fv)) (GLuint indx, const GLfloat* values);
-extern   void         (*GL(glVertexAttrib4f)) (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-extern   void         (*GL(glVertexAttrib4fv)) (GLuint indx, const GLfloat* values);
-extern   void         (*GL(glVertexAttribPointer)) (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
-extern   void         (*GL(glViewport)) (GLint x, GLint y, GLsizei width, GLsizei height);
-
-/* Extensions */
-extern   void         (*GL(glGetProgramBinary)) (GLuint program, GLsizei bufsize, GLsizei *length, GLenum *binaryFormat, void *binary);
-extern   void         (*GL(glProgramBinary)) (GLuint program, GLenum binaryFormat, const void *binary, GLint length);
-extern   void         (*GL(glProgramParameteri)) (GLuint a, GLuint b, GLint d);
-
-
-#endif // EVAS_GL_CORE_H
+#ifndef _EVAS_GL_CORE_H
+#define _EVAS_GL_CORE_H
+#define EVAS_GL_NO_GL_H_CHECK 1
+#include "Evas_GL.h"
+
+typedef void *EVGLNative_Display;
+typedef void *EVGLNative_Window;
+typedef void *EVGLNative_Surface;
+typedef void *EVGLNative_Context;
+typedef struct _EVGL_Engine         EVGL_Engine;
+typedef struct _EVGL_Interface      EVGL_Interface;
+typedef struct _EVGL_Surface        EVGL_Surface;
+typedef struct _EVGL_Native_Window  EVGL_Native_Window;
+typedef struct _EVGL_Context        EVGL_Context;
+typedef struct _EVGL_Resource       EVGL_Resource;
+typedef struct _EVGL_Cap            EVGL_Cap;
+typedef struct _EVGL_Surface_Cap    EVGL_Surface_Cap;
+typedef struct _EVGL_Surface_Format EVGL_Surface_Format;
+
+void        evgl_engine_shutdown(void *eng_data);
+EAPI void   *evgl_native_surface_buffer_get(EVGL_Surface *sfc);
+EAPI int    evgl_native_surface_yinvert_get(EVGL_Surface *sfc);
+
+EVGL_Engine *evgl_engine_init(void *eng_data, EVGL_Interface *efunc);
+
+void        *evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int target, void *native, int w, int h);
+void        *evgl_pbuffer_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h, const int *attrib_list);
+int          evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc);
+void        *evgl_context_create(void *eng_data, EVGL_Context *share_ctx, Evas_GL_Context_Version version);
+int          evgl_context_destroy(void *eng_data, EVGL_Context *ctx);
+int          evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx);
+
+const char  *evgl_string_query(int name);
+int          evgl_native_surface_get(EVGL_Surface *sfc, Evas_Native_Surface *ns);
+Evas_GL_API *evgl_api_get(Evas_GL_Context_Version version);
+void         evgl_safe_extension_add(const char *name, void *funcptr);
+Eina_Bool    evgl_safe_extension_get(const char *name, void **pfuncptr);
+
+int          evgl_direct_rendered();
+void         evgl_direct_override_get(int *override, int *force_off);
+void         evgl_direct_info_set(int win_w, int win_h, int rot, unsigned int map_tex,
+                                  int img_x, int img_y, int img_w, int img_h,
+                                  int clip_x, int clip_y, int clip_w, int clip_h,
+                                  void *surface);
+void         evgl_direct_info_clear();
+
+Eina_Bool    evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns,
+                                                 Eina_Bool *direct_render,
+                                                 Eina_Bool *client_side_rotation,
+                                                 Eina_Bool *direct_override);
+
+void         evgl_direct_partial_info_set(int pres);
+void         evgl_direct_partial_info_clear();
+void         evgl_direct_partial_render_start();
+void         evgl_direct_partial_render_end();
+
+int          evgl_surface_is_texture(void *eng_data, EVGL_Surface *sfc);
+
+// This one is implemented in evas_gl.c -- please fixme (bad declaration location)
+EAPI void   *evas_gl_context_native_get(Evas_GL_Context *ctx);
+EVGLNative_Context evgl_context_native_get(Evas_GL_Context *ctx);
+
+#endif //_EVAS_GL_CORE_H
diff --git a/src/modules/engines/gl_common/evas_gl_core_private.h b/src/modules/engines/gl_common/evas_gl_core_private.h
new file mode 100755 (executable)
index 0000000..96e5607
--- /dev/null
@@ -0,0 +1,375 @@
+#ifndef _EVAS_GL_CORE_PRIVATE_H
+#define _EVAS_GL_CORE_PRIVATE_H
+#include "evas_gl_private.h"
+#include "evas_gl_core.h"
+#include "evas_gl_api_ext.h"
+#define EVAS_GL_NO_GL_H_CHECK 1
+#include "Evas_GL.h"
+
+//#include "evas_gl_ext.h"
+
+extern int _evas_gl_log_dom;
+
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_evas_gl_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+# undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_evas_gl_log_dom, __VA_ARGS__)
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_evas_gl_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+# undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_evas_gl_log_dom, __VA_ARGS__)
+
+#ifdef CRIT
+# undef CRIT
+#endif
+#define CRIT(...) EINA_LOG_DOM_CRIT(_evas_gl_log_dom, __VA_ARGS__)
+
+
+struct _EVGL_Interface
+{
+   // Returns the native display of evas engine.
+   void       *(*display_get)(void *data);
+
+   // Returns the Window surface that evas uses for direct rendering opt.
+   void       *(*evas_surface_get)(void *data);
+   void       *(*native_window_create)(void *data);
+   int         (*native_window_destroy)(void *data, void *window);
+
+   // Creates/Destroys the native surface from evas engine.
+   void       *(*surface_create)(void *data, void *native_window);
+   int         (*surface_destroy)(void *data, void *surface);
+
+   // Creates/Destroys a GL context.
+   void       *(*context_create)(void *data, void *share_ctx, Evas_GL_Context_Version version);
+   int         (*context_destroy)(void *data, void *context);
+
+   // Calls the make_current from evas_engine.
+   int         (*make_current)(void *data, void *surface, void *context, int flush);
+
+   // Returns the get proc_address function
+   void       *(*proc_address_get)(const char *name);
+
+   // Returns the string of supported extensions
+   const char *(*ext_string_get)(void *data);
+
+   // Returns the current rotation angle of evas
+   int         (*rotation_angle_get)(void *data);
+
+   // Given Creates/Destroys the native buffer from evas engine
+   void       *(*native_buffer_image_create)(void *data, int tex, int target, void *native);
+   int         (*native_buffer_image_destroy)(void *data, void *native_image);
+
+   // Called immediately from EvasGL when a texture is destroyed
+   int         (*texture_destroyed_cb)(void *data, GLuint texid);
+
+   // Create a pbuffer surface
+   void       *(*pbuffer_surface_create)(void *data, EVGL_Surface *evgl_sfc, const int *attrib_list);
+
+   // Create a surface for 1.x rendering (could be pbuffer or xpixmap for instance)
+   void       *(*gles1_surface_create)(void *data, EVGL_Surface *evgl_sfc, Evas_GL_Config *cfg, int w, int h);
+
+   // Destroy 1.x surface (could be pbuffer or xpixmap for instance)
+   int        (*gles1_surface_destroy)(void *data, EVGL_Surface *evgl_sfc);
+
+   // Create an indirect rendering context for GLES 1.x
+   void      *(*gles1_context_create)(void *data, EVGL_Context *share_ctx, EVGL_Surface *evgl_sfc);
+
+   // Check native window surface config for Evas GL Direct Rendering
+   int        (*native_win_surface_config_check)(void *data, int evgl_depth, int evgl_stencil, int evgl_msaa);
+};
+
+struct _EVGL_Surface
+{
+   int w, h;
+
+   //-------------------------//
+   // Related to FBO Surface
+
+   // MSAA
+   GLint   msaa_samples;
+
+   // Color Buffer Target
+   GLuint  color_buf;
+   GLint   color_ifmt;
+   GLenum  color_fmt;
+   int     native_tar;
+   void   *native_buf;
+   void   *native_img;
+
+   // Depth Buffer Target
+   GLuint  depth_buf;
+   GLenum  depth_fmt;
+
+   // Stencil Buffer Target
+   GLuint  stencil_buf;
+   GLenum  stencil_fmt;
+
+   // Depth_Stencil Target
+   GLuint  depth_stencil_buf;
+   GLenum  depth_stencil_fmt;
+
+   // Direct Rendering Options
+   unsigned direct_fb_opt : 1;
+   unsigned client_side_rotation : 1;
+   unsigned alpha : 1;
+
+   // Flag indicating this surface is used for GLES 1 indirect rendering
+   unsigned gles1_indirect : 1;
+   unsigned yinvert : 1;
+   unsigned xpixmap : 1;
+
+   // Moved from evgl_engine
+   unsigned direct_override : 1;
+   unsigned direct_mem_opt : 1;
+
+   void   *cfg;
+   int     cfg_index;
+
+   // Attached Context
+   int     fbo_attached;
+
+   // Init Flag
+   int     buffers_allocated;
+
+   // Rough estimate of buffer in memory per renderbuffer
+   // 0. color 1. depth 2. stencil 3. depth_stencil
+   int     buffer_mem[4];
+
+   //-------------------------//
+   // Used if gles1_indirect == 1
+   EVGLNative_Surface gles1_sfc;
+   void              *gles1_sfc_native;
+   void              *gles1_sfc_visual;
+   void              *gles1_sfc_config;
+   void              *egl_image;
+
+   //-------------------------//
+   // Related to PBuffer Surface
+   struct {
+      EVGLNative_Surface    native_surface;
+      Evas_GL_Color_Format  color_fmt;
+      GLuint                fbo;
+      Eina_Bool             is_pbuffer : 1;
+   } pbuffer;
+
+
+   //-------------------------//
+
+   EVGL_Context *current_ctx;
+};
+
+
+
+struct _EVGL_Context
+{
+   EVGLNative_Context context;
+
+   Evas_GL_Context_Version version;
+
+   // Context FBO
+   GLuint       surface_fbo;
+
+   // Current FBO
+   GLuint       current_fbo;
+
+   // Map texture
+   GLuint       map_tex;
+
+   // Direct Rendering Related
+   unsigned     scissor_enabled : 1;
+   unsigned     scissor_updated : 1;
+   unsigned     direct_scissor : 1;
+   unsigned     viewport_updated : 1;
+   unsigned     extension_checked : 1;
+   unsigned     fbo_image_supported : 1;
+   unsigned     pixmap_image_supported : 1;
+
+   int          scissor_coord[4];
+   int          viewport_coord[4];
+   int          viewport_direct[4];
+
+   // For GLES1 with indirect rendering
+   EVGLNative_Context gles1_context;
+
+   // Partial Rendering
+   int          partial_render;
+
+   EVGL_Surface *current_sfc;
+};
+
+typedef enum _EVGL_Color_Bit
+{
+   COLOR_NONE      = 0,
+   COLOR_RGB_888   = 0x1,
+   COLOR_RGBA_8888 = 0x3,
+} EVGL_Color_Bit;
+
+
+typedef enum _EVGL_Depth_Bit
+{
+   DEPTH_NONE   = 0,
+   DEPTH_BIT_8  = 0x1,
+   DEPTH_BIT_16 = 0x3,
+   DEPTH_BIT_24 = 0x7,
+   DEPTH_BIT_32 = 0xF,
+   DEPTH_STENCIL = 0xFF,
+} EVGL_Depth_Bit;
+
+typedef enum _EVGL_Stencil_Bit
+{
+   STENCIL_NONE   = 0,
+   STENCIL_BIT_1  = 0x1,
+   STENCIL_BIT_2  = 0x3,
+   STENCIL_BIT_4  = 0x7,
+   STENCIL_BIT_8  = 0xF,
+   STENCIL_BIT_16 = 0x1F,
+} EVGL_Stencil_Bit;
+
+
+struct _EVGL_Surface_Format
+{
+   int index;
+
+   EVGL_Color_Bit       color_bit;
+   GLint                color_ifmt;
+   GLenum               color_fmt;
+
+   EVGL_Depth_Bit       depth_bit;
+   GLenum               depth_fmt;
+
+   EVGL_Stencil_Bit     stencil_bit;
+   GLenum               stencil_fmt;
+
+   GLenum               depth_stencil_fmt;
+
+   int                  samples;
+};
+
+struct _EVGL_Cap
+{
+   EVGL_Surface_Format  fbo_fmts[100];
+   int                  num_fbo_fmts;
+
+   int                  max_w;
+   int                  max_h;
+
+   int                  msaa_supported;
+   int                  msaa_samples[3];  // High, Med, Low
+};
+
+struct _EVGL_Resource
+{
+   int id;
+
+   EVGLNative_Display   display;
+   EVGLNative_Context   context;
+   EVGLNative_Window    window;
+   EVGLNative_Surface   surface;
+
+   EVGL_Context        *current_ctx;
+   void                *current_eng;
+
+   int error_state;
+
+   struct {
+        EVGLNative_Surface   surface;
+        int                  rendered;
+
+        int                  rot;
+        int                  win_w;
+        int                  win_h;
+
+        GLuint               map_tex;
+
+        struct {
+             int             x, y, w, h;
+        } img;
+
+        struct {
+             int             x, y, w, h;
+        } clip;
+
+        struct {
+             int             preserve;
+             Eina_Bool       enabled  : 1;
+        } partial;
+
+        Eina_Bool            enabled  : 1;
+   } direct;
+   struct {
+        GLclampf r, g, b, a;
+   } clear_color;
+};
+
+struct _EVGL_Engine
+{
+   int initted;
+
+   EVGL_Interface     *funcs;
+
+   EVGL_Cap            caps;
+
+   const char         *gl_ext;
+   const char         *evgl_ext;
+
+   // Resource context/surface per Thread in TLS for evasgl use
+   LK(resource_lock);
+   Eina_TLS           resource_key;
+   Eina_List         *resource_list;
+   int                resource_count;
+   int                main_tid;
+
+   // Add more debug logs (DBG levels 4 and 6)
+   int                api_debug_mode;
+
+   // Force Off for Debug purposes
+   int                direct_force_off;
+
+   // Force Direct Scissoring off for Debug purposes
+   int                direct_scissor_off;
+
+   // Other DR flags for debugging purposes
+   int                direct_override; // 0: invalid, -1: no, 1: yes
+   int                direct_mem_opt; // 0: invalid, -1: no, 1: yes
+
+   // Keep track of all the current surfaces/contexts
+   Eina_List         *surfaces;
+   Eina_List         *contexts;
+   Eina_List         *direct_depth_stencil_surfaces;
+   Eina_Lock          lck;
+
+   //void              *engine_data;
+
+   int                references;
+   Eina_Hash         *safe_extensions;
+};
+
+
+// Evas GL Engine
+extern EVGL_Engine   *evgl_engine;
+
+// Internally used functions
+extern void           _evgl_api_get(Evas_GL_API *api, Eina_Bool debug);
+extern void           _evgl_api_gles1_get(Evas_GL_API *api, Eina_Bool debug);
+extern EVGL_Resource *_evgl_tls_resource_get(void);
+extern EVGL_Resource *_evgl_tls_resource_create(void *data);
+extern void           _evgl_tls_resource_destroy(void *data);
+extern EVGL_Context  *_evgl_current_context_get(void);
+extern int            _evgl_not_in_pixel_get(void);
+extern int            _evgl_direct_enabled(void);
+extern void           _evgl_error_set(int error_enum);
+extern int            _evgl_error_get(void);
+Eina_Bool             _evgl_api_gles1_ext_init(void);
+Evas_GL_API*          _evgl_api_gles1_internal_get(void);
+
+#endif //_EVAS_GL_CORE_PRIVATE_H
diff --git a/src/modules/engines/gl_common/evas_gl_file_cache.c b/src/modules/engines/gl_common/evas_gl_file_cache.c
new file mode 100644 (file)
index 0000000..e90285d
--- /dev/null
@@ -0,0 +1,113 @@
+#include "evas_gl_private.h"
+
+static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
+
+Eina_Bool
+evas_gl_common_file_cache_is_dir(const char *file)
+{
+   struct stat st;
+
+   if (stat(file, &st) < 0) return EINA_FALSE;
+   if (S_ISDIR(st.st_mode)) return EINA_TRUE;
+   return EINA_FALSE;
+}
+
+Eina_Bool
+evas_gl_common_file_cache_mkdir(const char *dir)
+{
+   /* evas gl only call this function when the dir is not exist */
+   if (mkdir(dir, default_mode) < 0) return EINA_FALSE;
+   return EINA_TRUE;
+}
+
+Eina_Bool
+evas_gl_common_file_cache_file_exists(const char *file)
+{
+   struct stat st;
+   if (!file) return EINA_FALSE;
+   if (stat(file, &st) < 0) return EINA_FALSE;
+   return EINA_TRUE;
+}
+
+Eina_Bool
+evas_gl_common_file_cache_mkpath_if_not_exists(const char *path)
+{
+   struct stat st;
+
+   if (stat(path, &st) < 0)
+      return evas_gl_common_file_cache_mkdir(path);
+   else if (!S_ISDIR(st.st_mode))
+      return EINA_FALSE;
+   else
+      return EINA_TRUE;
+}
+
+Eina_Bool
+evas_gl_common_file_cache_mkpath(const char *path)
+{
+   char ss[PATH_MAX];
+   unsigned int i;
+
+   if (evas_gl_common_file_cache_is_dir(path)) return EINA_TRUE;
+
+   for (i = 0; path[i]; ss[i] = path[i], i++)
+     {
+        if (i == sizeof(ss) - 1) return EINA_FALSE;
+        if ((path[i] == '/') && (i > 0))
+          {
+             ss[i] = 0;
+             if (!evas_gl_common_file_cache_mkpath_if_not_exists(ss))
+                return EINA_FALSE;
+          }
+     }
+   ss[i] = 0;
+   return evas_gl_common_file_cache_mkpath_if_not_exists(ss);
+}
+
+int
+evas_gl_common_file_cache_dir_check(char *cache_dir, int num)
+{
+   char *home = NULL;
+   char *subdir = ".cache/evas_gl_common_caches";
+
+   home = getenv("HOME");
+   if ((!home) || (!home[0])) return 0;
+
+   snprintf(cache_dir, num, "%s/%s", home, subdir);
+   return evas_gl_common_file_cache_file_exists(cache_dir);
+}
+
+int
+evas_gl_common_file_cache_file_check(const char *cache_dir, const char *cache_name, char *cache_file, int dir_num)
+{
+   char before_name[PATH_MAX];
+   char after_name[PATH_MAX];
+   int new_path_len = 0;
+   int i = 0, j = 0;
+
+   char *vendor = NULL;
+   char *driver = NULL;
+   char *version = NULL;
+
+   vendor = (char *)glGetString(GL_VENDOR);
+   driver = (char *)glGetString(GL_RENDERER);
+   version = (char *)glGetString(GL_VERSION);
+
+   new_path_len = snprintf(before_name, sizeof(before_name), "%s::%s::%s::%s::%s.eet", vendor, version, driver, MODULE_ARCH, cache_name);
+
+   /* remove '/' from file name */
+   for (i = 0; i < new_path_len; i++)
+     {
+        if (before_name[i] != '/')
+          {
+             after_name[j] = before_name[i];
+             j++;
+          }
+     }
+   after_name[j] = 0;
+
+   snprintf(cache_file, dir_num, "%s/%s", cache_dir, after_name);
+
+   return evas_gl_common_file_cache_file_exists(cache_file);
+}
+
index 78eddc6..69c5b58 100644 (file)
@@ -5,10 +5,8 @@ evas_gl_font_texture_new(void *context, RGBA_Font_Glyph *fg)
 {
    Evas_Engine_GL_Context *gc = context;
    Evas_GL_Texture *tex;
-   DATA8 *data;
-   int w, h, j, nw;
-   DATA8 *ndata;
-   int fh;
+   int w, h, j, nw, fh, x, y;
+   DATA8 *ndata, *data, *p1, *p2;
 
    if (fg->ext_dat) return fg->ext_dat; // FIXME: one engine at a time can do this :(
 
@@ -16,77 +14,38 @@ evas_gl_font_texture_new(void *context, RGBA_Font_Glyph *fg)
    h = fg->glyph_out->bitmap.rows;
    if ((w == 0) || (h == 0)) return NULL;
 
-   data = fg->glyph_out->bitmap.buffer;
-   j = fg->glyph_out->bitmap.pitch;
+   if (!fg->glyph_out->rle) return NULL;
+   data = evas_common_font_glyph_uncompress(fg, &w, &h);
+   if (!data) return NULL;
+   j = w;
    if (j < w) j = w;
 
+   // expand to 32bit (4 byte) aligned rows for texture upload
    nw = ((w + 3) / 4) * 4;
    ndata = alloca(nw *h);
    if (!ndata) return NULL;
-   if ((fg->glyph_out->bitmap.num_grays == 256) &&
-       (fg->glyph_out->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY))
+   for (y = 0; y < h; y++)
      {
-       int x, y;
-       DATA8 *p1, *p2;
-
-       for (y = 0; y < h; y++)
-         {
-            p1 = data + (j * y);
-            p2 = ndata + (nw * y);
-            for (x = 0; x < w; x++)
-              {
-                 *p2 = *p1;
-                 p1++;
-                 p2++;
-              }
-         }
-     }
-   else
-     {
-       DATA8 *tmpbuf = NULL, *dp, *tp, bits;
-       int bi, bj, end;
-       const DATA8 bitrepl[2] = {0x0, 0xff};
-
-       tmpbuf = alloca(w);
-       if (tmpbuf)
-         {
-            int x, y;
-            DATA8 *p1, *p2;
-
-            for (y = 0; y < h; y++)
-              {
-                 p1 = tmpbuf;
-                 p2 = ndata + (nw * y);
-                 tp = tmpbuf;
-                 dp = data + (y * fg->glyph_out->bitmap.pitch);
-                 for (bi = 0; bi < w; bi += 8)
-                   {
-                      bits = *dp;
-                      if ((w - bi) < 8) end = w - bi;
-                      else end = 8;
-                      for (bj = 0; bj < end; bj++)
-                        {
-                           *tp = bitrepl[(bits >> (7 - bj)) & 0x1];
-                           tp++;
-                        }
-                      dp++;
-                   }
-                 for (x = 0; x < w; x++)
-                   {
-                      *p2 = *p1;
-                      p1++;
-                      p2++;
-                   }
-              }
-         }
+        p1 = data + (j * y);
+        p2 = ndata + (nw * y);
+        for (x = 0; x < w; x++)
+          {
+             *p2 = *p1;
+             p1++;
+             p2++;
+          }
      }
-//   fh = h;
    fh = fg->fi->max_h;
    tex = evas_gl_common_texture_alpha_new(gc, ndata, w, h, fh);
+   if (!tex) goto done;
    tex->sx1 = ((double)(tex->x)) / (double)tex->pt->w;
    tex->sy1 = ((double)(tex->y)) / (double)tex->pt->h;
    tex->sx2 = ((double)(tex->x + tex->w)) / (double)tex->pt->w;
    tex->sy2 = ((double)(tex->y + tex->h)) / (double)tex->pt->h;
+   tex->fglyph = fg;
+   gc->font_glyph_textures = eina_list_append(gc->font_glyph_textures, tex);
+done:
+   free(data);
    return tex;
 }
 
@@ -102,7 +61,8 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co
 {
    Evas_Engine_GL_Context *gc = context;
    RGBA_Draw_Context *dc = draw_context;
-   Evas_GL_Texture *tex;
+   Evas_GL_Image *mask = gc->dc->clip.mask;
+   Evas_GL_Texture *tex, *mtex = mask ? mask->tex : NULL;
    static Cutout_Rects *rects = NULL;
    Cutout_Rect  *rct;
    int r, g, b, a;
@@ -110,6 +70,8 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co
    int c, cx, cy, cw, ch;
    int i;
    int sx, sy, sw, sh;
+   double mx = 0.0, my = 0.0, mw = 0.0, mh = 0.0;
+   Eina_Bool mask_smooth = EINA_FALSE;
 
    if (dc != gc->dc) return;
    tex = fg->ext_dat;
@@ -120,6 +82,48 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co
    g = (dc->col.col >> 8 ) & 0xff;
    b = (dc->col.col      ) & 0xff;
    sx = 0; sy = 0; sw = tex->w, sh = tex->h;
+
+   if (gc->dc->clip.mask && (sw > 0) && (sh > 0))
+     {
+        double nx, ny, nw, nh, dx, dy, dw, dh;
+        const double mask_x = gc->dc->clip.mask_x;
+        const double mask_y = gc->dc->clip.mask_y;
+        const double tmw = mtex->pt->w;
+        const double tmh = mtex->pt->h;
+        double scalex = 1.0;
+        double scaley = 1.0;
+
+        // canvas coords
+        nx = x; ny = y; nw = tex->w; nh = tex->h;
+        RECTS_CLIP_TO_RECT(nx, ny, nw, nh,
+                           gc->dc->clip.x, gc->dc->clip.y,
+                           gc->dc->clip.w, gc->dc->clip.h);
+        if ((nw < 1) || (nh < 1)) return;
+        dx = x; dy = y; dw = sw; dh = sh;
+        mx = mask_x; my = mask_y;
+        if (mask->scaled.origin && mask->scaled.w && mask->scaled.h)
+          {
+             mw = mask->scaled.w;
+             mh = mask->scaled.h;
+             scalex = mask->w / (double)mask->scaled.w;
+             scaley = mask->h / (double)mask->scaled.h;
+             mask_smooth = mask->scaled.smooth;
+          }
+        else
+          {
+             mw = mask->w;
+             mh = mask->h;
+          }
+        //RECTS_CLIP_TO_RECT(mx, my, mw, mh, cx, cy, cw, ch);
+        RECTS_CLIP_TO_RECT(mx, my, mw, mh, dx, dy, dw, dh);
+
+        // convert to tex coords
+        mx = (mtex->x / tmw) + ((mx - mask_x + (mw * (nx - dx)) / dw) * scalex / tmw);
+        my = (mtex->y / tmh) + ((my - mask_y + (mh * (ny - dy)) / dy) * scaley / tmh);
+        mw = (mw * nw * scalex / dw) / tmw;
+        mh = (mh * nh * scaley / dh) / tmh;
+     }
+
    if ((!gc->dc->cutout.rects) ||
        ((gc->shared->info.tune.cutout.max > 0) &&
            (gc->dc->cutout.active > gc->shared->info.tune.cutout.max)))
@@ -139,6 +143,7 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co
                                                    0.0, 0.0, 0.0, 0.0,
 //                                                   sx, sy, sw, sh,
                                                    x, y, tex->w, tex->h,
+                                                   mtex, mx, my, mw, mh, mask_smooth,
                                                    r, g, b, a);
                   return;
                }
@@ -149,6 +154,7 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co
              evas_gl_common_context_font_push(gc, tex,
                                               ssx, ssy, ssw, ssh,
                                               nx, ny, nw, nh,
+                                              mtex, mx, my, mw, mh, mask_smooth,
                                               r, g, b, a);
           }
         else
@@ -157,6 +163,7 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co
                                               0.0, 0.0, 0.0, 0.0,
 //                                              sx, sy, sw, sh,
                                               x, y, tex->w, tex->h,
+                                              mtex, mx, my, mw, mh, mask_smooth,
                                               r, g, b, a);
           }
         return;
@@ -186,6 +193,7 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co
                                               0.0, 0.0, 0.0, 0.0,
 //                                              sx, sy, sw, sh,
                                               x, y, tex->w, tex->h,
+                                              mtex, mx, my, mw, mh, mask_smooth,
                                               r, g, b, a);
              continue;
           }
@@ -196,6 +204,7 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co
         evas_gl_common_context_font_push(gc, tex,
                                          ssx, ssy, ssw, ssh,
                                          nx, ny, nw, nh,
+                                         mtex, mx, my, mw, mh, mask_smooth,
                                          r, g, b, a);
      }
    /* restore clip info */
old mode 100644 (file)
new mode 100755 (executable)
index 79e33e7..7116398
@@ -1,6 +1,14 @@
 #include "evas_gl_private.h"
 
 void
+evas_gl_common_image_alloc_ensure(Evas_GL_Image *im)
+{
+   if (!im->im) return;
+   im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry,
+                                                    im->w, im->h);
+}
+
+void
 evas_gl_common_image_all_unload(Evas_Engine_GL_Context *gc)
 {
    Eina_List *l;
@@ -96,12 +104,35 @@ evas_gl_common_image_unref(Evas_GL_Image *im)
      }
 }
 
+static void
+_evas_gl_cspace_list_fill(Evas_Engine_GL_Context *gc)
+{
+#define CS_APPEND(cs) gc->shared->info.cspaces = eina_list_append \
+   (gc->shared->info.cspaces, (void *) (intptr_t) cs)
+   if (gc->shared->info.etc2)
+     {
+        CS_APPEND(EVAS_COLORSPACE_RGBA8_ETC2_EAC);
+        CS_APPEND(EVAS_COLORSPACE_RGB8_ETC2);
+        CS_APPEND(EVAS_COLORSPACE_ETC1);
+        CS_APPEND(EVAS_COLORSPACE_ETC1_ALPHA);
+     }
+   else if (gc->shared->info.etc1)
+     {
+        CS_APPEND(EVAS_COLORSPACE_ETC1);
+        CS_APPEND(EVAS_COLORSPACE_ETC1_ALPHA);
+     }
+   CS_APPEND(EVAS_COLORSPACE_GRY8);
+   CS_APPEND(EVAS_COLORSPACE_AGRY88);
+   CS_APPEND(EVAS_COLORSPACE_ARGB8888);
+}
+
 Evas_GL_Image *
 evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error)
 {
    Evas_GL_Image        *im;
    RGBA_Image           *im_im;
    Eina_List            *l;
+   Evas_Colorspace cspace = EVAS_COLORSPACE_ARGB8888;
 
    im_im = evas_common_load_image_from_file(file, key, lo, error);
    if (!im_im) return NULL;
@@ -117,18 +148,17 @@ evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const ch
         return NULL;
      }
     */
-   
+
    // FIXME: keep unreffed shared images around
    EINA_LIST_FOREACH(gc->shared->images, l, im)
      {
        if (im->im == im_im)
          {
-// why did i put this here? i think to free the rgba pixel data once a texture
-// exists.
-//             evas_cache_image_drop(&(im_im->cache_entry));
+        // drop a reference in  evas_cache as gl_cache is taking a reference.
+        evas_cache_image_drop(&(im_im->cache_entry));
             gc->shared->images = eina_list_remove_list(gc->shared->images, l);
             gc->shared->images = eina_list_prepend(gc->shared->images, im);
-             evas_gl_common_image_ref(im);
+        evas_gl_common_image_ref(im);
             *error = EVAS_LOAD_ERROR_NONE;
             return im;
          }
@@ -141,14 +171,44 @@ evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const ch
        *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
        return NULL;
      }
+   if (im_im->cache_entry.cspaces)
+     {
+        Evas_Colorspace cs;
+        unsigned int i;
+        Eina_List *l2;
+        void *ldata;
+
+        if (!gc->shared->info.cspaces)
+          _evas_gl_cspace_list_fill(gc);
+
+        cspace = EVAS_COLORSPACE_ARGB8888;
+        for (i = 0; im_im->cache_entry.cspaces[i] != EVAS_COLORSPACE_ARGB8888; i++)
+          EINA_LIST_FOREACH(gc->shared->info.cspaces, l2, ldata)
+            {
+               cs = (Evas_Colorspace) (intptr_t) ldata;
+               if (cs == im_im->cache_entry.cspaces[i])
+                 {
+                    cspace = cs;
+                    goto found_cspace;
+                 }
+            }
+
+found_cspace:
+        // ETC2 is backwards compatible with ETC1 but we prefer ETC2
+        if (cspace == EVAS_COLORSPACE_ETC1 && gc->shared->info.etc2)
+          cspace = EVAS_COLORSPACE_RGB8_ETC2;
+
+        im_im->cache_entry.space = cspace;
+     }
    im->references = 1;
    im->im = im_im;
    im->gc = gc;
    im->cached = 1;
-   im->cs.space = EVAS_COLORSPACE_ARGB8888;
+   im->cs.space = cspace;
    im->alpha = im->im->cache_entry.flags.alpha;
    im->w = im->im->cache_entry.w;
    im->h = im->im->cache_entry.h;
+   im->native.target = GL_TEXTURE_2D;
    if (lo) im->load_opts = *lo;
    gc->shared->images = eina_list_prepend(gc->shared->images, im);
    return im;
@@ -162,8 +222,12 @@ evas_gl_common_image_new_from_data(Evas_Engine_GL_Context *gc, unsigned int w, u
 
    if (((int)w > gc->shared->info.max_texture_size) ||
        ((int)h > gc->shared->info.max_texture_size))
-     return NULL;
-     
+     {
+        ERR("Image w :%d h :%d greater than supported value: %d", w, h,
+           gc->shared->info.max_texture_size);
+        return NULL;
+     }
+
    if (data)
      {
         EINA_LIST_FOREACH(gc->shared->images, l, im)
@@ -189,6 +253,7 @@ evas_gl_common_image_new_from_data(Evas_Engine_GL_Context *gc, unsigned int w, u
        free(im);
        return NULL;
      }
+   im->native.target = GL_TEXTURE_2D;
    im->gc = gc;
    im->cs.space = cspace;
    im->alpha = im->im->cache_entry.flags.alpha;
@@ -197,6 +262,17 @@ evas_gl_common_image_new_from_data(Evas_Engine_GL_Context *gc, unsigned int w, u
    switch (cspace)
      {
       case EVAS_COLORSPACE_ARGB8888:
+      case EVAS_COLORSPACE_GRY8:
+      case EVAS_COLORSPACE_AGRY88:
+        break;
+      case EVAS_COLORSPACE_ETC1:
+        if (gc->shared->info.etc1 && !gc->shared->info.etc2) break;
+        ERR("We don't know what to do with ETC1 on this hardware. You need to add a software converter here.");
+        break;
+      case EVAS_COLORSPACE_RGB8_ETC2:
+      case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+        if (gc->shared->info.etc2) break;
+        ERR("We don't know what to do with ETC2 on this hardware. You need to add a software converter here.");
         break;
       case EVAS_COLORSPACE_YCBCR422P601_PL:
       case EVAS_COLORSPACE_YCBCR422P709_PL:
@@ -219,8 +295,12 @@ evas_gl_common_image_new_from_copied_data(Evas_Engine_GL_Context *gc, unsigned i
 
    if (((int)w > gc->shared->info.max_texture_size) ||
        ((int)h > gc->shared->info.max_texture_size))
-     return NULL;
-   
+   {
+      ERR("Image w :%d h :%d greater than supported value: %d", w, h,
+         gc->shared->info.max_texture_size);
+      return NULL;
+   }
+
    im = calloc(1, sizeof(Evas_GL_Image));
    if (!im) return NULL;
    im->references = 1;
@@ -231,6 +311,7 @@ evas_gl_common_image_new_from_copied_data(Evas_Engine_GL_Context *gc, unsigned i
        free(im);
        return NULL;
      }
+   im->native.target = GL_TEXTURE_2D;
    im->gc = gc;
    im->cs.space = cspace;
    im->alpha = im->im->cache_entry.flags.alpha;
@@ -239,7 +320,18 @@ evas_gl_common_image_new_from_copied_data(Evas_Engine_GL_Context *gc, unsigned i
    switch (cspace)
      {
       case EVAS_COLORSPACE_ARGB8888:
-       break;
+      case EVAS_COLORSPACE_GRY8:
+      case EVAS_COLORSPACE_AGRY88:
+        break;
+      case EVAS_COLORSPACE_ETC1:
+        if (gc->shared->info.etc1 && !gc->shared->info.etc2) break;
+        ERR("We don't know what to do with ETC1 on this hardware. You need to add a software converter here.");
+        break;
+      case EVAS_COLORSPACE_RGB8_ETC2:
+      case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+        if (gc->shared->info.etc2) break;
+        ERR("We don't know what to do with ETC2 on this hardware. You need to add a software converter here.");
+        break;
       case EVAS_COLORSPACE_YCBCR422P601_PL:
       case EVAS_COLORSPACE_YCBCR422P709_PL:
         if (im->tex) evas_gl_common_texture_free(im->tex);
@@ -264,8 +356,12 @@ evas_gl_common_image_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned in
 
    if (((int)w > gc->shared->info.max_texture_size) ||
        ((int)h > gc->shared->info.max_texture_size))
-     return NULL;
-   
+   {
+      ERR("Image w :%d h :%d greater than supported value: %d", w, h,
+         gc->shared->info.max_texture_size);
+      return NULL;
+   }
+
    im = calloc(1, sizeof(Evas_GL_Image));
    if (!im) return NULL;
    im->references = 1;
@@ -275,6 +371,7 @@ evas_gl_common_image_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned in
        free(im);
        return NULL;
      }
+   im->native.target = GL_TEXTURE_2D;
    im->gc = gc;
    im->im->cache_entry.flags.alpha = alpha ? 1 : 0;
    im->cs.space = cspace;
@@ -288,7 +385,18 @@ evas_gl_common_image_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned in
    switch (cspace)
      {
       case EVAS_COLORSPACE_ARGB8888:
-       break;
+      case EVAS_COLORSPACE_GRY8:
+      case EVAS_COLORSPACE_AGRY88:
+        break;
+      case EVAS_COLORSPACE_ETC1:
+        if (gc->shared->info.etc1 && !gc->shared->info.etc2) break;
+        ERR("We don't know what to do with ETC1 on this hardware. You need to add a software converter here.");
+        break;
+      case EVAS_COLORSPACE_RGB8_ETC2:
+      case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+        if (gc->shared->info.etc2) break;
+        ERR("We don't know what to do with ETC2 on this hardware. You need to add a software converter here.");
+        break;
       case EVAS_COLORSPACE_YCBCR422P601_PL:
       case EVAS_COLORSPACE_YCBCR422P709_PL:
       case EVAS_COLORSPACE_YCBCR422601_PL:
@@ -314,14 +422,21 @@ evas_gl_common_image_alpha_set(Evas_GL_Image *im, int alpha)
    if (im->alpha == alpha) return im;
    im->alpha = alpha;
    if (!im->im) return im;
+   evas_gl_common_image_alloc_ensure(im);
+   evas_cache_image_load_data(&im->im->cache_entry);
    im->im->cache_entry.flags.alpha = alpha ? 1 : 0;
-   if (im->tex)
+
+   if (im->tex) evas_gl_common_texture_free(im->tex);
+   if (im->tex_only)
      {
-        evas_gl_common_texture_free(im->tex);
-        im->tex = NULL;
+        im->tex = evas_gl_common_texture_native_new(im->gc, im->w, im->h,
+                                                    im->alpha, im);
+     }
+   else
+     {
+        im->tex = evas_gl_common_texture_new(im->gc, im->im);
+        if (im->tex) evas_gl_common_texture_update(im->tex, im->im);
      }
-   if (!im->tex)
-     im->tex = evas_gl_common_texture_new(im->gc, im->im);
    return im;
 }
 
@@ -376,9 +491,6 @@ evas_gl_common_image_native_disable(Evas_GL_Image *im)
    im->im->cache_entry.flags.alpha = im->alpha;
    im->cs.space = EVAS_COLORSPACE_ARGB8888;
    evas_cache_image_colorspace(&im->im->cache_entry, im->cs.space);
-   im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, im->w, im->h);
-   if (!im->tex)
-     im->tex = evas_gl_common_texture_new(im->gc, im->im);
 }
 
 void
@@ -396,10 +508,16 @@ evas_gl_common_image_content_hint_set(Evas_GL_Image *im, int hint)
    if (im->content_hint == hint) return;
    im->content_hint = hint;
    if (!im->gc) return;
-   if (!im->gc->shared->info.sec_image_map) return;
+   if ((!im->gc->shared->info.sec_image_map)
+       && (!im->gc->shared->info.sec_tbm_surface)) return;
    if (!im->gc->shared->info.bgra) return;
    // does not handle yuv yet.
-   if (im->cs.space != EVAS_COLORSPACE_ARGB8888) return;
+   if ((im->cs.space != EVAS_COLORSPACE_ARGB8888)
+       && (im->cs.space != EVAS_COLORSPACE_GRY8)
+       && (im->cs.space != EVAS_COLORSPACE_AGRY88)
+       && (im->cs.space != EVAS_COLORSPACE_ETC1)
+       && (im->cs.space != EVAS_COLORSPACE_RGB8_ETC2)
+       && (im->cs.space != EVAS_COLORSPACE_RGBA8_ETC2_EAC)) return;
    if (im->content_hint == EVAS_IMAGE_CONTENT_HINT_DYNAMIC)
      {
         if (im->cs.data)
@@ -444,7 +562,7 @@ evas_gl_common_image_content_hint_set(Evas_GL_Image *im, int hint)
 
         im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
         im->im->cache_entry.flags.alpha = im->alpha;
-        im->cs.space = EVAS_COLORSPACE_ARGB8888;
+        im->im->cache_entry.space = im->cs.space;
         evas_cache_image_colorspace(&im->im->cache_entry, im->cs.space);
         im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, im->w, im->h);
         if (!im->tex)
@@ -469,6 +587,12 @@ evas_gl_common_image_free(Evas_GL_Image *im)
    im->references--;
    if (im->references > 0) return;
 
+   if (im->scaled.origin)
+     {
+        evas_gl_common_image_free(im->scaled.origin);
+        im->scaled.origin = NULL;
+     }
+
    if (im->native.func.free)
      im->native.func.free(im->native.func.data, im);
 
@@ -502,10 +626,15 @@ evas_gl_common_image_surface_new(Evas_Engine_GL_Context *gc, unsigned int w, uns
 
    if (((int)w > gc->shared->info.max_texture_size) ||
        ((int)h > gc->shared->info.max_texture_size))
-     return NULL;
-   
+   {
+      ERR("Image w :%d h :%d greater than supported value: %d", w, h,
+         gc->shared->info.max_texture_size);
+      return NULL;
+   }
+
    im = calloc(1, sizeof(Evas_GL_Image));
    if (!im) return NULL;
+   im->native.target = GL_TEXTURE_2D;
    im->references = 1;
    im->gc = gc;
    im->cs.space = EVAS_COLORSPACE_ARGB8888;
@@ -527,6 +656,7 @@ evas_gl_common_image_dirty(Evas_GL_Image *im, unsigned int x, unsigned int y, un
      }
    if (im->im)
      {
+        evas_gl_common_image_alloc_ensure(im);
         im->im = (RGBA_Image *)evas_cache_image_dirty(&im->im->cache_entry, x, y, w, h);
      }
    im->dirty = 1;
@@ -538,6 +668,7 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
    Image_Entry *ie;
    if (!im->im) return;
    ie = (Image_Entry *)(im->im);
+   evas_gl_common_image_alloc_ensure(im);
 /*
    if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
        (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
@@ -562,6 +693,11 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
    switch (im->cs.space)
      {
       case EVAS_COLORSPACE_ARGB8888:
+      case EVAS_COLORSPACE_GRY8:
+      case EVAS_COLORSPACE_AGRY88:
+      case EVAS_COLORSPACE_ETC1:
+      case EVAS_COLORSPACE_RGB8_ETC2:
+      case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
          if ((im->tex) &&
              ((im->dirty) || (ie->flags.animated)))
           {
@@ -569,7 +705,7 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
              evas_gl_common_texture_update(im->tex, im->im);
              evas_cache_image_unload_data(&im->im->cache_entry);
           }
-       if (!im->tex)
+       if ((!im->tex) && (ie->load_error == 0))
           {
              evas_cache_image_load_data(&im->im->cache_entry);
              im->tex = evas_gl_common_texture_new(gc, im->im);
@@ -578,6 +714,22 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
         im->dirty = 0;
         if (!im->tex) return;
        break;
+      case EVAS_COLORSPACE_ETC1_ALPHA:
+        if ((im->tex) && (im->dirty))
+          {
+             evas_cache_image_load_data(&im->im->cache_entry);
+             evas_gl_common_texture_rgb_a_pair_update(im->tex, im->im);
+             evas_cache_image_unload_data(&im->im->cache_entry);
+          }
+        else if ((!im->tex))
+          {
+             evas_cache_image_load_data(&im->im->cache_entry);
+             im->tex = evas_gl_common_texture_rgb_a_pair_new(gc, im->im);
+             evas_cache_image_unload_data(&im->im->cache_entry);
+          }
+        im->dirty = 0;
+        if (!im->tex) return;
+        break;
       case EVAS_COLORSPACE_YCBCR422P601_PL:
       case EVAS_COLORSPACE_YCBCR422P709_PL:
         if ((im->tex) && (im->dirty))
@@ -655,13 +807,16 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
 
 void
 evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
-                              int npoints, RGBA_Map_Point *p, int smooth, int level __UNUSED__)
+                              int npoints, RGBA_Map_Point *p, int smooth, int level EINA_UNUSED)
 {
-   RGBA_Draw_Context *dc;
+   int mx = 0, my = 0, mw = 0, mh = 0;
+   RGBA_Draw_Context *dc = gc->dc;
+   Eina_Bool mask_smooth = EINA_FALSE;
+   Evas_GL_Image *mask = dc->clip.mask;
+   Evas_GL_Texture *mtex = mask ? mask->tex : NULL;
    int r, g, b, a;
    int c, cx, cy, cw, ch;
 
-   dc = gc->dc;
    if (dc->mul.use)
      {
         a = (dc->mul.col >> 24) & 0xff;
@@ -676,13 +831,39 @@ evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
 
    evas_gl_common_image_update(gc, im);
 
-   c = gc->dc->clip.use;
-   cx = gc->dc->clip.x; cy = gc->dc->clip.y;
-   cw = gc->dc->clip.w; ch = gc->dc->clip.h;
+   c = dc->clip.use;
+   cx = dc->clip.x;   cy = dc->clip.y;
+   cw = dc->clip.w;   ch = dc->clip.h;
+   if (!im->tex) return;
    im->tex->im = im;
 
+   if (mtex && mtex->pt && mtex->pt->w && mtex->pt->h)
+     {
+        // canvas coords
+        mx = dc->clip.mask_x;
+        my = dc->clip.mask_y;
+        if (mask->scaled.origin)
+          {
+             mw = mask->scaled.w;
+             mh = mask->scaled.h;
+             //scalex = mask->w / (double)mask->scaled.w;
+             //scaley = mask->h / (double)mask->scaled.h;
+             mask_smooth = mask->scaled.smooth;
+          }
+        else
+          {
+             mw = mask->w;
+             mh = mask->h;
+          }
+        //if (c) RECTS_CLIP_TO_RECT(mx, my, mw, mh, cx, cy, cw, ch);
+        //mx = mx - dc->clip.mask_x;
+        //my = my - dc->clip.mask_y;
+     }
+   else mtex = NULL;
+
    evas_gl_common_context_image_map_push(gc, im->tex, npoints, p,
                                          c, cx, cy, cw, ch,
+                                         mtex, mx, my, mw, mh, mask_smooth,
                                          r, g, b, a, smooth, im->tex_only,
                                          im->cs.space);
 }
@@ -692,21 +873,24 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
 {
    static Cutout_Rects *rects = NULL;
    RGBA_Draw_Context *dc;
-   Evas_GL_Image *imm;
    int r, g, b, a;
    double ssx, ssy, ssw, ssh;
-   double mssx, mssy, mssw, mssh;
    Cutout_Rect  *rct;
    int c, cx, cy, cw, ch;
    int i;
    int yuv = 0;
    int yuy2 = 0;
    int nv12 = 0;
+   int rgb_a_pair = 0;
+   Evas_GL_Image *mask;
+   int mask_x, mask_y;
+   double mx = 0, my = 0, mw = 0, mh = 0;
+   Evas_GL_Texture *mtex = NULL;
+   Eina_Bool mask_smooth = EINA_FALSE;
 
    if (sw < 1) sw = 1;
    if (sh < 1) sh = 1;
    dc = gc->dc;
-   imm = (Evas_GL_Image *)dc->mask.mask;
    if (dc->mul.use)
      {
        a = (dc->mul.col >> 24) & 0xff;
@@ -719,17 +903,28 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
        r = g = b = a = 255;
      }
 
+   // Prepare mask image, if there is one
+   mask = dc->clip.mask;
+   mask_x = dc->clip.mask_x;
+   mask_y = dc->clip.mask_y;
+   if (mask)
+     {
+        evas_gl_common_image_update(gc, mask);
+        if (!mask->tex)
+          {
+             ERR("Failed to apply mask image");
+             mask = NULL;
+             mask_x = 0;
+             mask_y = 0;
+          }
+     }
+
    evas_gl_common_image_update(gc, im);
    if (!im->tex)
      {
         evas_gl_common_rect_draw(gc, dx, dy, dw, dh);
         return;
      }
-   if (imm)
-     {
-        evas_gl_common_image_update(gc, imm);
-        if (!imm->tex) imm = NULL; /* Turn of mask on error */
-     }
 
    if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
        (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
@@ -739,52 +934,104 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
    if ((im->cs.space == EVAS_COLORSPACE_YCBCR420NV12601_PL) ||
        (im->cs.space == EVAS_COLORSPACE_YCBCR420TM12601_PL))
      nv12 = 1;
+   if (im->cs.space == EVAS_COLORSPACE_ETC1_ALPHA)
+     rgb_a_pair = 1;
 
    im->tex->im = im;
-   if (imm) imm->tex->im = imm;
    if ((!gc->dc->cutout.rects) ||
        ((gc->shared->info.tune.cutout.max > 0) &&
-           (gc->dc->cutout.active > gc->shared->info.tune.cutout.max)))
+           (gc->dc->cutout.active > gc->shared->info.tune.cutout.max)) ||
+       (im->native.ratio > 0))
      {
-        if (gc->dc->clip.use)
+        mtex = mask ? mask->tex : NULL;
+        if (mtex && mtex->pt && mtex->pt->w && mtex->pt->h)
+          {
+             const double tmw = mtex->pt->w;
+             const double tmh = mtex->pt->h;
+             double scalex = 1.0;
+             double scaley = 1.0;
+
+             // canvas coords
+             mx = mask_x; my = mask_y;
+             if (mask->scaled.origin)
+               {
+                  mw = mask->scaled.w;
+                  mh = mask->scaled.h;
+                  scalex = mask->w / (double)mask->scaled.w;
+                  scaley = mask->h / (double)mask->scaled.h;
+                  mask_smooth = mask->scaled.smooth;
+               }
+             else
+               {
+                  mw = mask->w;
+                  mh = mask->h;
+               }
+             // WARNING NOTE: The below code works upstream because
+             // the function calling _evas_gl_common_image_push sets cx,cy,cw,ch
+             // based on the destination geometry if clip is not used.
+             //RECTS_CLIP_TO_RECT(mx, my, mw, mh, cx, cy, cw, ch);
+             //RECTS_CLIP_TO_RECT(mx, my, mw, mh, dx, dy, dw, dh);
+             c = gc->dc->clip.use; cx = gc->dc->clip.x; cy = gc->dc->clip.y; cw = gc->dc->clip.w; ch = gc->dc->clip.h;
+             if (c) RECTS_CLIP_TO_RECT(mx, my, mw, mh, cx, cy, cw, ch);
+             RECTS_CLIP_TO_RECT(mx, my, mw, mh, dx, dy, dw, dh);
+
+             // convert to tex coords
+             mx = (mtex->x / tmw) + ((mx - mask_x) * scalex / tmw);
+             my = (mtex->y / tmh) + ((my - mask_y) * scaley / tmh);
+             mw = mw * scalex / tmw;
+             mh = mh * scaley / tmh;
+          }
+        else mtex = NULL;
+
+        if ((gc->dc->clip.use) && (im->native.ratio == 0))
           {
              int nx, ny, nw, nh;
-             double scalex,scaley;
 
              nx = dx; ny = dy; nw = dw; nh = dh;
              RECTS_CLIP_TO_RECT(nx, ny, nw, nh,
                                 gc->dc->clip.x, gc->dc->clip.y,
                                 gc->dc->clip.w, gc->dc->clip.h);
              if ((nw < 1) || (nh < 1)) return;
-             if ((!imm) && (nx == dx) && (ny == dy) && (nw == dw) && (nh == dh))
+             if ((nx == dx) && (ny == dy) && (nw == dw) && (nh == dh))
                {
                   if (yuv)
                     evas_gl_common_context_yuv_push(gc,
                                                     im->tex,
                                                     sx, sy, sw, sh,
                                                     dx, dy, dw, dh,
+                                                    mtex, mx, my, mw, mh, mask_smooth,
                                                     r, g, b, a,
                                                     smooth);
                   else if (yuy2)
                     evas_gl_common_context_yuy2_push(gc,
                                                     im->tex,
                                                     sx, sy, sw, sh,
-                                                    dx, dy, dw, dh,
+                                                     dx, dy, dw, dh,
+                                                     mtex, mx, my, mw, mh, mask_smooth,
                                                     r, g, b, a,
                                                     smooth);
                   else if (nv12)
                     evas_gl_common_context_nv12_push(gc,
                                                     im->tex,
                                                     sx, sy, sw, sh,
-                                                    dx, dy, dw, dh,
+                                                     dx, dy, dw, dh,
+                                                     mtex, mx, my, mw, mh, mask_smooth,
                                                     r, g, b, a,
                                                     smooth);
+                  else if (rgb_a_pair)
+                    evas_gl_common_context_rgb_a_pair_push(gc,
+                                                           im->tex,
+                                                           sx, sy, sw, sh,
+                                                           dx, dy, dw, dh,
+                                                           /* mtex, mmx, mmy, mmw, mmh, */
+                                                           r, g, b, a,
+                                                           smooth);
                   else
-
                     evas_gl_common_context_image_push(gc,
                                                       im->tex,
                                                       sx, sy, sw, sh,
                                                       dx, dy, dw, dh,
+                                                      mtex, mx, my, mw, mh, mask_smooth,
                                                       r, g, b, a,
                                                       smooth, im->tex_only);
                   return;
@@ -794,53 +1041,44 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
              ssy = (double)sy + ((double)(sh * (ny - dy)) / (double)(dh));
              ssw = ((double)sw * (double)(nw)) / (double)(dw);
              ssh = ((double)sh * (double)(nh)) / (double)(dh);
-             if (imm)
-               {
-                  /* Correct ones here */
-                  scalex = imm->w / (double)dc->mask.w;
-                  scaley = imm->h / (double)dc->mask.h;
-                  mssx = scalex * (nx - dc->mask.x);
-                  mssy = scaley * (ny - dc->mask.y);
-                  mssw = scalex * nw;
-                  mssh = scaley * nh;
-
-                  /* No yuv + imm I'm afraid */
-                  evas_gl_common_context_image_mask_push(gc,
-                                               im->tex,
-                                               imm->tex,
-                                               ssx, ssy, ssw, ssh,
-                                               mssx, mssy, mssw, mssh,
-                                               //dc->mask.x, dc->mask.y, dc->mask.w, dc->mask.h,
-                                               nx, ny, nw, nh,
-                                               r, g, b, a,
-                                               smooth);
-               }
-             else if (yuv)
+             if (yuv)
                evas_gl_common_context_yuv_push(gc,
                                                im->tex,
                                                ssx, ssy, ssw, ssh,
                                                nx, ny, nw, nh,
+                                               mtex, mx, my, mw, mh, mask_smooth,
                                                r, g, b, a,
                                                smooth);
              else if (yuy2)
                evas_gl_common_context_yuy2_push(gc,
                                                im->tex,
                                                ssx, ssy, ssw, ssh,
-                                               nx, ny, nw, nh,
+                                                nx, ny, nw, nh,
+                                                mtex, mx, my, mw, mh, mask_smooth,
                                                r, g, b, a,
                                                smooth);
              else if (nv12)
                evas_gl_common_context_nv12_push(gc,
                                                im->tex,
                                                ssx, ssy, ssw, ssh,
-                                               nx, ny, nw, nh,
+                                                nx, ny, nw, nh,
+                                                mtex, mx, my, mw, mh, mask_smooth,
                                                r, g, b, a,
                                                smooth);
+             else if (rgb_a_pair)
+               evas_gl_common_context_rgb_a_pair_push(gc,
+                                                      im->tex,
+                                                      ssx, ssy, ssw, ssh,
+                                                      nx, ny, nw, nh,
+                                                      /* mtex, mmx, mmy, mmw, mmh, */
+                                                      r, g, b, a,
+                                                      smooth);
              else
                evas_gl_common_context_image_push(gc,
                                                  im->tex,
                                                  ssx, ssy, ssw, ssh,
                                                  nx, ny, nw, nh,
+                                                 mtex, mx, my, mw, mh, mask_smooth,
                                                  r, g, b, a,
                                                  smooth, im->tex_only);
           }
@@ -851,27 +1089,39 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
                                                im->tex,
                                                sx, sy, sw, sh,
                                                dx, dy, dw, dh,
+                                               mtex, mx, my, mw, mh, mask_smooth,
                                                r, g, b, a,
                                                smooth);
              else if (yuy2)
                evas_gl_common_context_yuy2_push(gc,
                                                im->tex,
                                                sx, sy, sw, sh,
-                                               dx, dy, dw, dh,
+                                                dx, dy, dw, dh,
+                                                mtex, mx, my, mw, mh, mask_smooth,
                                                r, g, b, a,
-                                               smooth);
+                                                smooth);
              else if (nv12)
                evas_gl_common_context_nv12_push(gc,
-                                               im->tex,
-                                               sx, sy, sw, sh,
-                                               dx, dy, dw, dh,
-                                               r, g, b, a,
-                                               smooth);
+                                                im->tex,
+                                                sx, sy, sw, sh,
+                                                dx, dy, dw, dh,
+                                                mtex, mx, my, mw, mh, mask_smooth,
+                                                r, g, b, a,
+                                                smooth);
+             else if (rgb_a_pair)
+               evas_gl_common_context_rgb_a_pair_push(gc,
+                                                      im->tex,
+                                                      sx, sy, sw, sh,
+                                                      dx, dy, dw, dh,
+                                                      /* mtex, mmx, mmy, mmw, mmh, */
+                                                      r, g, b, a,
+                                                      smooth);
              else
                evas_gl_common_context_image_push(gc,
                                                  im->tex,
                                                  sx, sy, sw, sh,
                                                  dx, dy, dw, dh,
+                                                 mtex, mx, my, mw, mh, mask_smooth,
                                                  r, g, b, a,
                                                  smooth, im->tex_only);
           }
@@ -896,6 +1146,45 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
         rct = rects->rects + i;
         nx = dx; ny = dy; nw = dw; nh = dh;
         RECTS_CLIP_TO_RECT(nx, ny, nw, nh, rct->x, rct->y, rct->w, rct->h);
+
+        mtex = mask ? mask->tex : NULL;
+        if (mtex && mtex->pt && mtex->pt->w && mtex->pt->h)
+          {
+             const double tmw = mtex->pt->w;
+             const double tmh = mtex->pt->h;
+             double scalex = 1.0;
+             double scaley = 1.0;
+
+             // canvas coords
+             mx = mask_x; my = mask_y;
+             if (mask->scaled.origin)
+               {
+                  mw = mask->scaled.w;
+                  mh = mask->scaled.h;
+                  scalex = mask->w / (double)mask->scaled.w;
+                  scaley = mask->h / (double)mask->scaled.h;
+                  mask_smooth = mask->scaled.smooth;
+               }
+             else
+               {
+                  mw = mask->w;
+                  mh = mask->h;
+               }
+             // WARNING NOTE: The below code works upstream because
+             // the function calling _evas_gl_common_image_push sets cx,cy,cw,ch
+             // based on the destination geometry if clip is not used.
+             //RECTS_CLIP_TO_RECT(mx, my, mw, mh, cx, cy, cw, ch);
+             //RECTS_CLIP_TO_RECT(mx, my, mw, mh, dx, dy, dw, dh);
+             if (c) RECTS_CLIP_TO_RECT(mx, my, mw, mh, cx, cy, cw, ch);
+             RECTS_CLIP_TO_RECT(mx, my, mw, mh, nx, ny, nw, nh);
+
+             // convert to tex coords
+             mx = (mtex->x / tmw) + ((mx - mask_x) * scalex / tmw);
+             my = (mtex->y / tmh) + ((my - mask_y) * scaley / tmh);
+             mw = mw * scalex / tmw;
+             mh = mh * scaley / tmh;
+          }
+
         if ((nw < 1) || (nh < 1)) continue;
         if ((nx == dx) && (ny == dy) && (nw == dw) && (nh == dh))
           {
@@ -904,27 +1193,39 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
                                                im->tex,
                                                sx, sy, sw, sh,
                                                dx, dy, dw, dh,
+                                               mtex, mx, my, mw, mh, mask_smooth,
                                                r, g, b, a,
                                                smooth);
              else if (yuy2)
                evas_gl_common_context_yuy2_push(gc,
                                                im->tex,
                                                sx, sy, sw, sh,
-                                               dx, dy, dw, dh,
+                                                dx, dy, dw, dh,
+                                                mtex, mx, my, mw, mh, mask_smooth,
                                                r, g, b, a,
-                                               smooth);
+                                                smooth);
              else if (nv12)
                evas_gl_common_context_nv12_push(gc,
-                                               im->tex,
-                                               sx, sy, sw, sh,
-                                               dx, dy, dw, dh,
-                                               r, g, b, a,
-                                               smooth);
+                                                im->tex,
+                                                sx, sy, sw, sh,
+                                                dx, dy, dw, dh,
+                                                mtex, mx, my, mw, mh, mask_smooth,
+                                                r, g, b, a,
+                                                smooth);
+             else if (rgb_a_pair)
+               evas_gl_common_context_rgb_a_pair_push(gc,
+                                                      im->tex,
+                                                      sx, sy, sw, sh,
+                                                      dx, dy, dw, dh,
+                                                      /* mtex, mmx, mmy, mmw, mmh, */
+                                                      r, g, b, a,
+                                                      smooth);
              else
                evas_gl_common_context_image_push(gc,
                                                  im->tex,
                                                  sx, sy, sw, sh,
                                                  dx, dy, dw, dh,
+                                                 mtex, mx, my, mw, mh, mask_smooth,
                                                  r, g, b, a,
                                                  smooth, im->tex_only);
              continue;
@@ -938,27 +1239,39 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
                                           im->tex,
                                           ssx, ssy, ssw, ssh,
                                           nx, ny, nw, nh,
+                                          mtex, mx, my, mw, mh, mask_smooth,
                                           r, g, b, a,
                                           smooth);
         else if (yuy2)
           evas_gl_common_context_yuy2_push(gc,
                                           im->tex,
                                           ssx, ssy, ssw, ssh,
-                                          nx, ny, nw, nh,
+                                           nx, ny, nw, nh,
+                                           mtex, mx, my, mw, mh, mask_smooth,
                                           r, g, b, a,
-                                          smooth);
+                                           smooth);
         else if (nv12)
           evas_gl_common_context_nv12_push(gc,
-                                          im->tex,
-                                          ssx, ssy, ssw, ssh,
-                                          nx, ny, nw, nh,
-                                          r, g, b, a,
-                                          smooth);
+                                           im->tex,
+                                           ssx, ssy, ssw, ssh,
+                                           nx, ny, nw, nh,
+                                           mtex, mx, my, mw, mh, mask_smooth,
+                                           r, g, b, a,
+                                           smooth);
+        else if (rgb_a_pair)
+          evas_gl_common_context_rgb_a_pair_push(gc,
+                                                 im->tex,
+                                                 ssx, ssy, ssw, ssh,
+                                                 nx, ny, nw, nh,
+                                                 /* mtex, mmx, mmy, mmw, mmh, */
+                                                 r, g, b, a,
+                                                 smooth);
         else
           evas_gl_common_context_image_push(gc,
                                             im->tex,
                                             ssx, ssy, ssw, ssh,
                                             nx, ny, nw, nh,
+                                            mtex, mx, my, mw, mh, mask_smooth,
                                             r, g, b, a,
                                             smooth, im->tex_only);
      }
index fb9ae56..bae0ff0 100644 (file)
@@ -6,6 +6,11 @@ evas_gl_common_line_draw(Evas_Engine_GL_Context *gc, int x1, int y1, int x2, int
    RGBA_Draw_Context *dc;
    int r, g, b, a;
    int c, cx, cy, cw, ch;
+   static int offset_hack = -1;
+   const int OFFSET_HACK_OFF = 0;
+   const int OFFSET_HACK_DEFAULT = 1;
+   const int OFFSET_HACK_ARM = 2;
+   const int OFFSET_HACK_QUALCOMM = 3;
 
    dc = gc->dc;
    if (dc->mul.use)
@@ -27,6 +32,69 @@ evas_gl_common_line_draw(Evas_Engine_GL_Context *gc, int x1, int y1, int x2, int
    cx = gc->dc->clip.x; cy = gc->dc->clip.y;
    cw = gc->dc->clip.w; ch = gc->dc->clip.h;
 
+   //I have no idea but shift lines/clips since the gl line origin position and
+   //scissor area is slightly different by the gl driver.
+   if (offset_hack == -1)
+     {
+        if (!getenv("EVAS_GL_LINE_OFFSET_HACK_DISABLE"))
+          {
+             const char *vendor_name;
+             vendor_name = (char *) glGetString(GL_VENDOR);
+             if (vendor_name && !strcmp(vendor_name, "ARM"))
+               offset_hack = OFFSET_HACK_ARM;
+             else if (vendor_name && !strcmp(vendor_name, "Qualcomm"))
+               offset_hack = OFFSET_HACK_QUALCOMM;
+          }
+        else offset_hack = OFFSET_HACK_OFF;
+     }
+
+   if (offset_hack == OFFSET_HACK_DEFAULT)
+     {
+        if ((gc->rot == 0) || (gc->rot == 90))
+          {
+             x1++;
+             x2++;
+          }
+        if ((gc->rot == 90) || (gc->rot == 180))
+          {
+             y1++;
+             y2++;
+          }
+     }
+   else if (offset_hack == OFFSET_HACK_QUALCOMM)
+     {
+        //Increment pixels since the gl line origin position is slightly different for Qualcomm 8974 chipset
+        if ((gc->rot == 0) || (gc->rot == 270))
+          {
+             if (x1 == x2)
+               {
+                  x1++;
+                  x2++;
+               }
+          }
+        if ((gc->rot == 0) || (gc->rot == 90))
+          {
+             if (y1 == y2)
+               {
+                  y1++;
+                  y2++;
+               }
+          }
+     }
+   else if (offset_hack == OFFSET_HACK_ARM)
+     {
+        if ((gc->rot == 90) || (gc->rot == 180))
+          {
+             cx--;
+             cw--;
+          }
+        if ((gc->rot == 180) || (gc->rot == 270))
+          {
+             cy--;
+             ch--;
+          }
+     }
+
    evas_gl_common_context_line_push(gc, x1, y1, x2, y2,
                                     c, cx, cy, cw, ch,
                                     r, g, b, a);
index 81f041e..1b0f5c5 100644 (file)
@@ -70,10 +70,15 @@ evas_gl_common_poly_point_add(Evas_GL_Polygon *poly, int x, int y)
 {
    Evas_GL_Polygon_Point *pt;
 
-   if (!poly) poly = calloc(1, sizeof(Evas_GL_Polygon));
-   if (!poly) return NULL;
    pt = calloc(1, sizeof(Evas_GL_Polygon_Point));
    if (!pt) return NULL;
+
+   if (!poly) poly = calloc(1, sizeof(Evas_GL_Polygon));
+   if (!poly)
+     {
+        free(pt);
+        return NULL;
+     }
    pt->x = x;
    pt->y = y;
    poly->points = eina_list_append(poly->points, pt);
@@ -263,12 +268,13 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int
                   y = span->y;
                   w = span->w;
                   h = 1;
-                  evas_gl_common_context_rectangle_push(gc, x, y, w, h, cr, cg, cb, ca);
+                  evas_gl_common_context_rectangle_push(gc, x, y, w, h,
+                                                        cr, cg, cb, ca,
+                                                        NULL, 0, 0, 0, 0, EINA_FALSE);
                }
           }
         else
           {
-             evas_common_draw_context_clip_clip(gc->dc, x, y, w, h);
              /* our clip is 0 size.. abort */
              if ((gc->dc->clip.w > 0) && (gc->dc->clip.h > 0))
                {
@@ -286,7 +292,9 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int
                                  h = 1;
                                  RECTS_CLIP_TO_RECT(x, y, w, h, r->x, r->y, r->w, r->h);
                                  if ((w > 0) && (h > 0))
-                                   evas_gl_common_context_rectangle_push(gc, x, y, w, h, cr, cg, cb, ca);
+                                   evas_gl_common_context_rectangle_push(gc, x, y, w, h,
+                                                                         cr, cg, cb, ca,
+                                                                         NULL, 0, 0, 0, 0, EINA_FALSE);
                               }
                          }
                     }
index d95b5a2..eae8302 100644 (file)
@@ -6,6 +6,10 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
    static Cutout_Rects *rects = NULL;
    Cutout_Rect  *r;
    int          c, cx, cy, cw, ch, cr, cg, cb, ca, i;
+   double mx = 0, my = 0, mw = 0, mh = 0;
+   Eina_Bool mask_smooth = EINA_FALSE;
+   Evas_GL_Image *mask = gc->dc->clip.mask;
+   Evas_GL_Texture *mtex = mask ? mask->tex : NULL;
 
    if ((w <= 0) || (h <= 0)) return;
    if (!(RECTS_INTERSECT(x, y, w, h, 0, 0, gc->w, gc->h))) return;
@@ -20,7 +24,7 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
    evas_common_draw_context_clip_clip(gc->dc, 0, 0, gc->shared->w, gc->shared->h);
    /* no cutouts - cut right to the chase */
 
-   if ((gc->dc) && (gc->dc->clip.use))
+   if (gc->dc->clip.use)
      {
         RECTS_CLIP_TO_RECT(x, y, w, h,
                            gc->dc->clip.x, gc->dc->clip.y,
@@ -29,7 +33,42 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
 
    if (!gc->dc->cutout.rects)
      {
-        evas_gl_common_context_rectangle_push(gc, x, y, w, h, cr, cg, cb, ca);
+        if (mtex)
+          {
+             const double mask_x = gc->dc->clip.mask_x;
+             const double mask_y = gc->dc->clip.mask_y;
+             const double tmw = mtex->pt->w;
+             const double tmh = mtex->pt->h;
+             double scalex = 1.0;
+             double scaley = 1.0;
+
+             // canvas coords
+             mx = mask_x; my = mask_y;
+             if (mask->scaled.origin && mask->scaled.w && mask->scaled.h)
+               {
+                  mw = mask->scaled.w;
+                  mh = mask->scaled.h;
+                  scalex = mask->w / (double)mask->scaled.w;
+                  scaley = mask->h / (double)mask->scaled.h;
+                  mask_smooth = mask->scaled.smooth;
+               }
+             else
+               {
+                  mw = mask->w;
+                  mh = mask->h;
+               }
+             RECTS_CLIP_TO_RECT(mx, my, mw, mh, x, y, w, h);
+             mx -= gc->dc->clip.mask_x;
+             my -= gc->dc->clip.mask_y;
+
+             // convert to tex coords
+             mx = (mtex->x / tmw) + ((mx - mask_x) * scalex / tmw);
+             my = (mtex->y / tmh) + ((my - mask_y) * scaley / tmh);
+             mw = mw * scalex / tmw;
+             mh = mh * scaley / tmh;
+          }
+
+        evas_gl_common_context_rectangle_push(gc, x, y, w, h, cr, cg, cb, ca, mtex, mx, my, mw, mh, mask_smooth);
      }
    else
      {
@@ -43,7 +82,43 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
                   r = rects->rects + i;
                   if ((r->w > 0) && (r->h > 0))
                     {
-                       evas_gl_common_context_rectangle_push(gc, r->x, r->y, r->w, r->h, cr, cg, cb, ca);
+                       if (mtex)
+                         {
+                            const double mask_x = gc->dc->clip.mask_x;
+                            const double mask_y = gc->dc->clip.mask_y;
+                            const double tmw = mtex->pt->w;
+                            const double tmh = mtex->pt->h;
+                            double scalex = 1.0;
+                            double scaley = 1.0;
+
+                            // canvas coords
+                            mx = mask_x; my = mask_y;
+                            if (mask->scaled.origin && mask->scaled.w && mask->scaled.h)
+                              {
+                                 mw = mask->scaled.w;
+                                 mh = mask->scaled.h;
+                                 scalex = mask->w / (double)mask->scaled.w;
+                                 scaley = mask->h / (double)mask->scaled.h;
+                                 mask_smooth = mask->scaled.smooth;
+                              }
+                            else
+                              {
+                                 mw = mask->w;
+                                 mh = mask->h;
+                              }
+                            RECTS_CLIP_TO_RECT(mx, my, mw, mh, cx, cy, cw, ch);
+                            RECTS_CLIP_TO_RECT(mx, my, mw, mh, r->x, r->y, r->w, r->h);
+                            mx -= gc->dc->clip.mask_x;
+                            my -= gc->dc->clip.mask_y;
+
+                            // convert to tex coords
+                            mx = (mtex->x / tmw) + ((mx - mask_x) * scalex / tmw);
+                            my = (mtex->y / tmh) + ((my - mask_y) * scaley / tmh);
+                            mw = mw * scalex / tmw;
+                            mh = mh * scaley / tmh;
+                         }
+
+                       evas_gl_common_context_rectangle_push(gc, r->x, r->y, r->w, r->h, cr, cg, cb, ca, mtex, mx, my, mw, mh, mask_smooth);
                     }
                }
           }
old mode 100644 (file)
new mode 100755 (executable)
index 4d0f342..13c7080
 #include "evas_gl_private.h"
 
 /////////////////////////////////////////////
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int rect_frag_bin[] =
-{
-# include "shader/rect_frag_bin_s3c6410.h"
-};
-#endif
-
 const char rect_frag_glsl[] =
 #include "shader/rect_frag.h"
   ;
 Evas_GL_Program_Source shader_rect_frag_src =
 {
    rect_frag_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     rect_frag_bin, sizeof(rect_frag_bin)
-#else
-     NULL, 0
-#endif
+   NULL, 0
 };
 
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int rect_vert_bin[] =
-{
-# include "shader/rect_vert_bin_s3c6410.h"
-};
-#endif
 const char rect_vert_glsl[] =
 #include "shader/rect_vert.h"
   ;
 Evas_GL_Program_Source shader_rect_vert_src =
 {
    rect_vert_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     rect_vert_bin, sizeof(rect_vert_bin)
-#else
-     NULL, 0
-#endif
+   NULL, 0
 };
 
 /////////////////////////////////////////////
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int font_frag_bin[] =
-{
-# include "shader/font_frag_bin_s3c6410.h"
-};
-#endif
-
 const char font_frag_glsl[] =
 #include "shader/font_frag.h"
   ;
 Evas_GL_Program_Source shader_font_frag_src =
 {
    font_frag_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     font_frag_bin, sizeof(font_frag_bin)
-#else
-     NULL, 0
-#endif
+   NULL, 0
 };
 
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int font_vert_bin[] =
-{
-# include "shader/font_vert_bin_s3c6410.h"
-};
-#endif
 const char font_vert_glsl[] =
 #include "shader/font_vert.h"
   ;
 Evas_GL_Program_Source shader_font_vert_src =
 {
    font_vert_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     font_vert_bin, sizeof(font_vert_bin)
-#else
-     NULL, 0
-#endif
+   NULL, 0
 };
 
-/////////////////////////////////////////////
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int yuv_frag_bin[] =
-{
-# include "shader/yuv_frag_bin_s3c6410.h"
-};
-#endif
 
-const char yuv_frag_glsl[] =
-#include "shader/yuv_frag.h"
+
+/////////////////////////////////////////////
+const char img_frag_glsl[] =
+#include "shader/img_frag.h"
   ;
-Evas_GL_Program_Source shader_yuv_frag_src =
+Evas_GL_Program_Source shader_img_frag_src =
 {
-   yuv_frag_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     yuv_frag_bin, sizeof(yuv_frag_bin)
-#else
-     NULL, 0
-#endif
+   img_frag_glsl,
+   NULL, 0
 };
 
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int yuv_vert_bin[] =
-{
-# include "shader/yuv_vert_bin_s3c6410.h"
-};
-#endif
-const char yuv_vert_glsl[] =
-#include "shader/yuv_vert.h"
+const char img_vert_glsl[] =
+#include "shader/img_vert.h"
   ;
-Evas_GL_Program_Source shader_yuv_vert_src =
+Evas_GL_Program_Source shader_img_vert_src =
 {
-   yuv_vert_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     yuv_vert_bin, sizeof(yuv_vert_bin)
-#else
-     NULL, 0
-#endif
+   img_vert_glsl,
+   NULL, 0
 };
 
 /////////////////////////////////////////////
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int yuy2_frag_bin[] =
-{
-# include "shader/yuy2_frag_bin_s3c6410.h"
-};
-#endif
-
-const char yuy2_frag_glsl[] =
-#include "shader/yuy2_frag.h"
+const char img_nomul_frag_glsl[] =
+#include "shader/img_nomul_frag.h"
   ;
-Evas_GL_Program_Source shader_yuy2_frag_src =
+Evas_GL_Program_Source shader_img_nomul_frag_src =
 {
-   yuy2_frag_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     yuy2_frag_bin, sizeof(yuy2_frag_bin)
-#else
-     NULL, 0
-#endif
+   img_nomul_frag_glsl,
+   NULL, 0
 };
 
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int yuy2_vert_bin[] =
-{
-# include "shader/yuy2_vert_bin_s3c6410.h"
-};
-#endif
-const char yuy2_vert_glsl[] =
-#include "shader/yuy2_vert.h"
+const char img_nomul_vert_glsl[] =
+#include "shader/img_nomul_vert.h"
   ;
-Evas_GL_Program_Source shader_yuy2_vert_src =
+Evas_GL_Program_Source shader_img_nomul_vert_src =
 {
-   yuy2_vert_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     yuy2_vert_bin, sizeof(yuy2_vert_bin)
-#else
-     NULL, 0
-#endif
+   img_nomul_vert_glsl,
+   NULL, 0
 };
 
 /////////////////////////////////////////////
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int yuy2_nomul_frag_bin[] =
-{
-# include "shader/yuy2_nomul_frag_bin_s3c6410.h"
-};
-#endif
-
-const char yuy2_nomul_frag_glsl[] =
-#include "shader/yuy2_nomul_frag.h"
+const char img_afill_frag_glsl[] =
+#include "shader/img_afill_frag.h"
   ;
-Evas_GL_Program_Source shader_yuy2_nomul_frag_src =
+Evas_GL_Program_Source shader_img_afill_frag_src =
 {
-   yuy2_nomul_frag_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     yuy2_nomul_frag_bin, sizeof(yuy2_nomul_frag_bin)
-#else
-     NULL, 0
-#endif
+   img_afill_frag_glsl,
+   NULL, 0
 };
 
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int yuy2_nomul_vert_bin[] =
-{
-# include "shader/yuy2_nomul_vert_bin_s3c6410.h"
-};
-#endif
-const char yuy2_nomul_vert_glsl[] =
-#include "shader/yuy2_nomul_vert.h"
+const char img_afill_vert_glsl[] =
+#include "shader/img_afill_vert.h"
   ;
-Evas_GL_Program_Source shader_yuy2_nomul_vert_src =
+Evas_GL_Program_Source shader_img_afill_vert_src =
 {
-   yuy2_nomul_vert_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     yuy2_nomul_vert_bin, sizeof(yuy2_nomul_vert_bin)
-#else
-     NULL, 0
-#endif
+   img_afill_vert_glsl,
+   NULL, 0
 };
 
 /////////////////////////////////////////////
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int nv12_nomul_vert_bin[] =
-{
-# include "shader/nv12_nomul_vert_bin_s3c6410.h"
-};
-#endif
-const char nv12_nomul_vert_glsl[] =
-#include "shader/nv12_nomul_vert.h"
+const char img_nomul_afill_frag_glsl[] =
+#include "shader/img_nomul_afill_frag.h"
   ;
-Evas_GL_Program_Source shader_nv12_nomul_vert_src =
+Evas_GL_Program_Source shader_img_nomul_afill_frag_src =
 {
-   nv12_nomul_vert_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     nv12_nomul_vert_bin, sizeof(nv12_nomul_vert_bin)
-#else
-     NULL, 0
-#endif
+   img_nomul_afill_frag_glsl,
+   NULL, 0
 };
 
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int nv12_vert_bin[] =
-{
-# include "shader/nv12_vert_bin_s3c6410.h"
-};
-#endif
-const char nv12_vert_glsl[] =
-#include "shader/nv12_vert.h"
+const char img_nomul_afill_vert_glsl[] =
+#include "shader/img_nomul_afill_vert.h"
   ;
-Evas_GL_Program_Source shader_nv12_vert_src =
+Evas_GL_Program_Source shader_img_nomul_afill_vert_src =
 {
-   nv12_vert_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     nv12_vert_bin, sizeof(nv12_vert_bin)
-#else
-     NULL, 0
-#endif
+   img_nomul_afill_vert_glsl,
+   NULL, 0
 };
 
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int nv12_nomul_frag_bin[] =
+/////////////////////////////////////////////
+const char img_bgra_frag_glsl[] =
+#include "shader/img_bgra_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_bgra_frag_src =
 {
-# include "shader/nv12_nomul_frag_bin_s3c6410.h"
+   img_bgra_frag_glsl,
+   NULL, 0
 };
-#endif
 
-const char nv12_frag_glsl[] =
-#include "shader/nv12_frag.h"
+const char img_bgra_vert_glsl[] =
+#include "shader/img_bgra_vert.h"
   ;
-Evas_GL_Program_Source shader_nv12_frag_src =
+Evas_GL_Program_Source shader_img_bgra_vert_src =
 {
-   nv12_frag_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     nv12_frag_bin, sizeof(nv12_frag_bin)
-#else
-     NULL, 0
-#endif
+   img_bgra_vert_glsl,
+   NULL, 0
 };
 
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int nv12_nomul_frag_bin[] =
+/////////////////////////////////////////////
+const char img_bgra_nomul_frag_glsl[] =
+#include "shader/img_bgra_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_bgra_nomul_frag_src =
 {
-# include "shader/nv12_nomul_frag_bin_s3c6410.h"
+   img_bgra_nomul_frag_glsl,
+   NULL, 0
 };
-#endif
 
-const char nv12_nomul_frag_glsl[] =
-#include "shader/nv12_nomul_frag.h"
+const char img_bgra_nomul_vert_glsl[] =
+#include "shader/img_bgra_nomul_vert.h"
   ;
-Evas_GL_Program_Source shader_nv12_nomul_frag_src =
+Evas_GL_Program_Source shader_img_bgra_nomul_vert_src =
 {
-   nv12_nomul_frag_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     nv12_nomul_frag_bin, sizeof(nv12_nomul_frag_bin)
-#else
-     NULL, 0
-#endif
+   img_bgra_nomul_vert_glsl,
+   NULL, 0
 };
 
 /////////////////////////////////////////////
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int yuv_nomul_frag_bin[] =
+const char img_bgra_afill_frag_glsl[] =
+#include "shader/img_bgra_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_bgra_afill_frag_src =
 {
-# include "shader/yuv_nomul_frag_bin_s3c6410.h"
+   img_bgra_afill_frag_glsl,
+   NULL, 0
 };
-#endif
 
-const char yuv_nomul_frag_glsl[] =
-#include "shader/yuv_nomul_frag.h"
+const char img_bgra_afill_vert_glsl[] =
+#include "shader/img_bgra_afill_vert.h"
   ;
-Evas_GL_Program_Source shader_yuv_nomul_frag_src =
+Evas_GL_Program_Source shader_img_bgra_afill_vert_src =
 {
-   yuv_nomul_frag_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     yuv_nomul_frag_bin, sizeof(yuv_nomul_frag_bin)
-#else
-     NULL, 0
-#endif
+   img_bgra_afill_vert_glsl,
+   NULL, 0
 };
 
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int yuv_nomul_vert_bin[] =
-{
-# include "shader/yuv_nomul_vert_bin_s3c6410.h"
-};
-#endif
-const char yuv_nomul_vert_glsl[] =
-#include "shader/yuv_nomul_vert.h"
+/////////////////////////////////////////////
+const char img_bgra_nomul_afill_frag_glsl[] =
+#include "shader/img_bgra_nomul_afill_frag.h"
   ;
-Evas_GL_Program_Source shader_yuv_nomul_vert_src =
+Evas_GL_Program_Source shader_img_bgra_nomul_afill_frag_src =
 {
-   yuv_nomul_vert_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     yuv_nomul_vert_bin, sizeof(yuv_nomul_vert_bin)
-#else
-     NULL, 0
-#endif
+   img_bgra_nomul_afill_frag_glsl,
+   NULL, 0
 };
 
-/////////////////////////////////////////////
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int tex_frag_bin[] =
+const char img_bgra_nomul_afill_vert_glsl[] =
+#include "shader/img_bgra_nomul_afill_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_bgra_nomul_afill_vert_src =
 {
-# include "shader/tex_frag_bin_s3c6410.h"
+   img_bgra_nomul_afill_vert_glsl,
+   NULL, 0
 };
-#endif
 
+/////////////////////////////////////////////
 const char tex_frag_glsl[] =
 #include "shader/tex_frag.h"
   ;
 Evas_GL_Program_Source shader_tex_frag_src =
 {
    tex_frag_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     tex_frag_bin, sizeof(tex_frag_bin)
-#else
-     NULL, 0
-#endif
+   NULL, 0
 };
 
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int tex_vert_bin[] =
-{
-# include "shader/tex_vert_bin_s3c6410.h"
-};
-#endif
 const char tex_vert_glsl[] =
 #include "shader/tex_vert.h"
   ;
 Evas_GL_Program_Source shader_tex_vert_src =
 {
    tex_vert_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     tex_vert_bin, sizeof(tex_vert_bin)
-#else
-     NULL, 0
-#endif
+   NULL, 0
 };
 
 /////////////////////////////////////////////
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int tex_nomul_frag_bin[] =
-{
-# include "shader/tex_nomul_frag_bin_s3c6410.h"
-};
-#endif
-
 const char tex_nomul_frag_glsl[] =
 #include "shader/tex_nomul_frag.h"
   ;
 Evas_GL_Program_Source shader_tex_nomul_frag_src =
 {
    tex_nomul_frag_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     tex_nomul_frag_bin, sizeof(tex_nomul_frag_bin)
-#else
-     NULL, 0
-#endif
+   NULL, 0
 };
 
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int tex_nomul_vert_bin[] =
-{
-# include "shader/tex_nomul_vert_bin_s3c6410.h"
-};
-#endif
 const char tex_nomul_vert_glsl[] =
 #include "shader/tex_nomul_vert.h"
   ;
 Evas_GL_Program_Source shader_tex_nomul_vert_src =
 {
    tex_nomul_vert_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     tex_nomul_vert_bin, sizeof(tex_nomul_vert_bin)
-#else
-     NULL, 0
-#endif
+   NULL, 0
 };
 
 /////////////////////////////////////////////
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int img_frag_bin[] =
+const char tex_afill_frag_glsl[] =
+#include "shader/tex_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_tex_afill_frag_src =
 {
-# include "shader/img_frag_bin_s3c6410.h"
+   tex_afill_frag_glsl,
+   NULL, 0
 };
-#endif
 
-const char img_frag_glsl[] =
-#include "shader/img_frag.h"
+const char tex_afill_vert_glsl[] =
+#include "shader/tex_afill_vert.h"
   ;
-Evas_GL_Program_Source shader_img_frag_src =
+Evas_GL_Program_Source shader_tex_afill_vert_src =
 {
-   img_frag_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     img_frag_bin, sizeof(img_frag_bin)
-#else
-     NULL, 0
-#endif
+   tex_afill_vert_glsl,
+   NULL, 0
 };
 
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int img_vert_bin[] =
+/////////////////////////////////////////////
+const char tex_nomul_afill_frag_glsl[] =
+#include "shader/tex_nomul_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_tex_nomul_afill_frag_src =
 {
-# include "shader/img_vert_bin_s3c6410.h"
+   tex_nomul_afill_frag_glsl,
+   NULL, 0
 };
-#endif
-const char img_vert_glsl[] =
-#include "shader/img_vert.h"
+
+const char tex_nomul_afill_vert_glsl[] =
+#include "shader/tex_nomul_afill_vert.h"
   ;
-Evas_GL_Program_Source shader_img_vert_src =
+Evas_GL_Program_Source shader_tex_nomul_afill_vert_src =
 {
-   img_vert_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     img_vert_bin, sizeof(img_vert_bin)
-#else
-     NULL, 0
-#endif
+   tex_nomul_afill_vert_glsl,
+   NULL, 0
 };
 
 /////////////////////////////////////////////
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int img_nomul_frag_bin[] =
+const char img_21_frag_glsl[] =
+#include "shader/img_21_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_21_frag_src =
 {
-# include "shader/img_nomul_frag_bin_s3c6410.h"
+   img_21_frag_glsl,
+   NULL, 0
 };
-#endif
 
-const char img_nomul_frag_glsl[] =
-#include "shader/img_nomul_frag.h"
+const char img_21_vert_glsl[] =
+#include "shader/img_21_vert.h"
   ;
-Evas_GL_Program_Source shader_img_nomul_frag_src =
+Evas_GL_Program_Source shader_img_21_vert_src =
 {
-   img_nomul_frag_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     img_nomul_frag_bin, sizeof(img_nomul_frag_bin)
-#else
-     NULL, 0
-#endif
+   img_21_vert_glsl,
+   NULL, 0
 };
 
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int img_nomul_vert_bin[] =
-{
-# include "shader/img_nomul_vert_bin_s3c6410.h"
-};
-#endif
-const char img_nomul_vert_glsl[] =
-#include "shader/img_nomul_vert.h"
+/////////////////////////////////////////////
+const char img_21_nomul_frag_glsl[] =
+#include "shader/img_21_nomul_frag.h"
   ;
-Evas_GL_Program_Source shader_img_nomul_vert_src =
+Evas_GL_Program_Source shader_img_21_nomul_frag_src =
 {
-   img_nomul_vert_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     img_nomul_vert_bin, sizeof(img_nomul_vert_bin)
-#else
-     NULL, 0
-#endif
+   img_21_nomul_frag_glsl,
+   NULL, 0
+};
+
+const char img_21_nomul_vert_glsl[] =
+#include "shader/img_21_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_21_nomul_vert_src =
+{
+   img_21_nomul_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char img_21_afill_frag_glsl[] =
+#include "shader/img_21_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_21_afill_frag_src =
+{
+   img_21_afill_frag_glsl,
+   NULL, 0
+};
+
+const char img_21_afill_vert_glsl[] =
+#include "shader/img_21_afill_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_21_afill_vert_src =
+{
+   img_21_afill_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char img_21_nomul_afill_frag_glsl[] =
+#include "shader/img_21_nomul_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_21_nomul_afill_frag_src =
+{
+   img_21_nomul_afill_frag_glsl,
+   NULL, 0
+};
+
+const char img_21_nomul_afill_vert_glsl[] =
+#include "shader/img_21_nomul_afill_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_21_nomul_afill_vert_src =
+{
+   img_21_nomul_afill_vert_glsl,
+   NULL, 0
+};
+
+
+/////////////////////////////////////////////
+const char img_21_bgra_frag_glsl[] =
+#include "shader/img_21_bgra_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_21_bgra_frag_src =
+{
+   img_21_bgra_frag_glsl,
+   NULL, 0
+};
+
+const char img_21_bgra_vert_glsl[] =
+#include "shader/img_21_bgra_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_21_bgra_vert_src =
+{
+   img_21_bgra_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char img_21_bgra_nomul_frag_glsl[] =
+#include "shader/img_21_bgra_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_21_bgra_nomul_frag_src =
+{
+   img_21_bgra_nomul_frag_glsl,
+   NULL, 0
+};
+
+const char img_21_bgra_nomul_vert_glsl[] =
+#include "shader/img_21_bgra_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_21_bgra_nomul_vert_src =
+{
+   img_21_bgra_nomul_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char img_21_bgra_afill_frag_glsl[] =
+#include "shader/img_21_bgra_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_21_bgra_afill_frag_src =
+{
+   img_21_bgra_afill_frag_glsl,
+   NULL, 0
+};
+
+const char img_21_bgra_afill_vert_glsl[] =
+#include "shader/img_21_bgra_afill_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_21_bgra_afill_vert_src =
+{
+   img_21_bgra_afill_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char img_21_bgra_nomul_afill_frag_glsl[] =
+#include "shader/img_21_bgra_nomul_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_21_bgra_nomul_afill_frag_src =
+{
+   img_21_bgra_nomul_afill_frag_glsl,
+   NULL, 0
+};
+
+const char img_21_bgra_nomul_afill_vert_glsl[] =
+#include "shader/img_21_bgra_nomul_afill_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_21_bgra_nomul_afill_vert_src =
+{
+   img_21_bgra_nomul_afill_vert_glsl,
+   NULL, 0
+};
+
+
+/////////////////////////////////////////////
+const char tex_21_frag_glsl[] =
+#include "shader/tex_21_frag.h"
+  ;
+Evas_GL_Program_Source shader_tex_21_frag_src =
+{
+   tex_21_frag_glsl,
+   NULL, 0
+};
+
+const char tex_21_vert_glsl[] =
+#include "shader/tex_21_vert.h"
+  ;
+Evas_GL_Program_Source shader_tex_21_vert_src =
+{
+   tex_21_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char tex_21_nomul_frag_glsl[] =
+#include "shader/tex_21_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_tex_21_nomul_frag_src =
+{
+   tex_21_nomul_frag_glsl,
+   NULL, 0
+};
+
+const char tex_21_nomul_vert_glsl[] =
+#include "shader/tex_21_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_tex_21_nomul_vert_src =
+{
+   tex_21_nomul_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char tex_21_afill_frag_glsl[] =
+#include "shader/tex_21_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_tex_21_afill_frag_src =
+{
+   tex_21_afill_frag_glsl,
+   NULL, 0
+};
+
+const char tex_21_afill_vert_glsl[] =
+#include "shader/tex_21_afill_vert.h"
+  ;
+Evas_GL_Program_Source shader_tex_21_afill_vert_src =
+{
+   tex_21_afill_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char tex_21_nomul_afill_frag_glsl[] =
+#include "shader/tex_21_nomul_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_tex_21_nomul_afill_frag_src =
+{
+   tex_21_nomul_afill_frag_glsl,
+   NULL, 0
+};
+
+const char tex_21_nomul_afill_vert_glsl[] =
+#include "shader/tex_21_nomul_afill_vert.h"
+  ;
+Evas_GL_Program_Source shader_tex_21_nomul_afill_vert_src =
+{
+   tex_21_nomul_afill_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char img_12_frag_glsl[] =
+#include "shader/img_12_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_12_frag_src =
+{
+   img_12_frag_glsl,
+   NULL, 0
+};
+
+const char img_12_vert_glsl[] =
+#include "shader/img_12_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_12_vert_src =
+{
+   img_12_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char img_12_nomul_frag_glsl[] =
+#include "shader/img_12_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_12_nomul_frag_src =
+{
+   img_12_nomul_frag_glsl,
+   NULL, 0
+};
+
+const char img_12_nomul_vert_glsl[] =
+#include "shader/img_12_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_12_nomul_vert_src =
+{
+   img_12_nomul_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char img_12_afill_frag_glsl[] =
+#include "shader/img_12_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_12_afill_frag_src =
+{
+   img_12_afill_frag_glsl,
+   NULL, 0
+};
+
+const char img_12_afill_vert_glsl[] =
+#include "shader/img_12_afill_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_12_afill_vert_src =
+{
+   img_12_afill_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char img_12_nomul_afill_frag_glsl[] =
+#include "shader/img_12_nomul_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_12_nomul_afill_frag_src =
+{
+   img_12_nomul_afill_frag_glsl,
+   NULL, 0
+};
+
+const char img_12_nomul_afill_vert_glsl[] =
+#include "shader/img_12_nomul_afill_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_12_nomul_afill_vert_src =
+{
+   img_12_nomul_afill_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char img_12_bgra_frag_glsl[] =
+#include "shader/img_12_bgra_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_12_bgra_frag_src =
+{
+   img_12_bgra_frag_glsl,
+   NULL, 0
+};
+
+const char img_12_bgra_vert_glsl[] =
+#include "shader/img_12_bgra_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_12_bgra_vert_src =
+{
+   img_12_bgra_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char img_12_bgra_nomul_frag_glsl[] =
+#include "shader/img_12_bgra_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_12_bgra_nomul_frag_src =
+{
+   img_12_bgra_nomul_frag_glsl,
+   NULL, 0
+};
+
+const char img_12_bgra_nomul_vert_glsl[] =
+#include "shader/img_12_bgra_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_12_bgra_nomul_vert_src =
+{
+   img_12_bgra_nomul_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char img_12_bgra_afill_frag_glsl[] =
+#include "shader/img_12_bgra_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_12_bgra_afill_frag_src =
+{
+   img_12_bgra_afill_frag_glsl,
+   NULL, 0
+};
+
+const char img_12_bgra_afill_vert_glsl[] =
+#include "shader/img_12_bgra_afill_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_12_bgra_afill_vert_src =
+{
+   img_12_bgra_afill_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char img_12_bgra_nomul_afill_frag_glsl[] =
+#include "shader/img_12_bgra_nomul_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_12_bgra_nomul_afill_frag_src =
+{
+   img_12_bgra_nomul_afill_frag_glsl,
+   NULL, 0
+};
+
+const char img_12_bgra_nomul_afill_vert_glsl[] =
+#include "shader/img_12_bgra_nomul_afill_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_12_bgra_nomul_afill_vert_src =
+{
+   img_12_bgra_nomul_afill_vert_glsl,
+   NULL, 0
+};
+
+
+/////////////////////////////////////////////
+const char tex_12_frag_glsl[] =
+#include "shader/tex_12_frag.h"
+  ;
+Evas_GL_Program_Source shader_tex_12_frag_src =
+{
+   tex_12_frag_glsl,
+   NULL, 0
+};
+
+const char tex_12_vert_glsl[] =
+#include "shader/tex_12_vert.h"
+  ;
+Evas_GL_Program_Source shader_tex_12_vert_src =
+{
+   tex_12_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char tex_12_nomul_frag_glsl[] =
+#include "shader/tex_12_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_tex_12_nomul_frag_src =
+{
+   tex_12_nomul_frag_glsl,
+   NULL, 0
+};
+
+const char tex_12_nomul_vert_glsl[] =
+#include "shader/tex_12_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_tex_12_nomul_vert_src =
+{
+   tex_12_nomul_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char tex_12_afill_frag_glsl[] =
+#include "shader/tex_12_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_tex_12_afill_frag_src =
+{
+   tex_12_afill_frag_glsl,
+   NULL, 0
+};
+
+const char tex_12_afill_vert_glsl[] =
+#include "shader/tex_12_afill_vert.h"
+  ;
+Evas_GL_Program_Source shader_tex_12_afill_vert_src =
+{
+   tex_12_afill_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char tex_12_nomul_afill_frag_glsl[] =
+#include "shader/tex_12_nomul_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_tex_12_nomul_afill_frag_src =
+{
+  tex_12_nomul_afill_frag_glsl,
+  NULL, 0
+};
+
+const char tex_12_nomul_afill_vert_glsl[] =
+#include "shader/tex_12_nomul_afill_vert.h"
+  ;
+Evas_GL_Program_Source shader_tex_12_nomul_afill_vert_src =
+{
+   tex_12_nomul_afill_vert_glsl,
+   NULL, 0
+};
+
+
+
+/////////////////////////////////////////////
+const char img_22_frag_glsl[] =
+#include "shader/img_22_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_22_frag_src =
+{
+   img_22_frag_glsl,
+   NULL, 0
+};
+
+const char img_22_vert_glsl[] =
+#include "shader/img_22_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_22_vert_src =
+{
+   img_22_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char img_22_nomul_frag_glsl[] =
+#include "shader/img_22_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_22_nomul_frag_src =
+{
+   img_22_nomul_frag_glsl,
+   NULL, 0
+};
+
+const char img_22_nomul_vert_glsl[] =
+#include "shader/img_22_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_22_nomul_vert_src =
+{
+   img_22_nomul_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char img_22_afill_frag_glsl[] =
+#include "shader/img_22_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_22_afill_frag_src =
+{
+   img_22_afill_frag_glsl,
+   NULL, 0
+};
+
+const char img_22_afill_vert_glsl[] =
+#include "shader/img_22_afill_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_22_afill_vert_src =
+{
+   img_22_afill_vert_glsl,
+   NULL, 0
 };
 
 /////////////////////////////////////////////
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int img_bgra_frag_bin[] =
+const char img_22_nomul_afill_frag_glsl[] =
+#include "shader/img_22_nomul_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_22_nomul_afill_frag_src =
 {
-# include "shader/img_bgra_frag_bin_s3c6410.h"
+   img_22_nomul_afill_frag_glsl,
+   NULL, 0
 };
-#endif
 
-const char img_bgra_frag_glsl[] =
-#include "shader/img_bgra_frag.h"
+const char img_22_nomul_afill_vert_glsl[] =
+#include "shader/img_22_nomul_afill_vert.h"
   ;
-Evas_GL_Program_Source shader_img_bgra_frag_src =
+Evas_GL_Program_Source shader_img_22_nomul_afill_vert_src =
 {
-   img_bgra_frag_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     img_bgra_frag_bin, sizeof(img_bgra_frag_bin)
-#else
-     NULL, 0
-#endif
+   img_22_nomul_afill_vert_glsl,
+   NULL, 0
 };
 
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int img_bgra_vert_bin[] =
+
+/////////////////////////////////////////////
+const char img_22_bgra_frag_glsl[] =
+#include "shader/img_22_bgra_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_22_bgra_frag_src =
 {
-# include "shader/img_bgra_vert_bin_s3c6410.h"
+   img_22_bgra_frag_glsl,
+   NULL, 0
 };
-#endif
-const char img_bgra_vert_glsl[] =
-#include "shader/img_bgra_vert.h"
+
+const char img_22_bgra_vert_glsl[] =
+#include "shader/img_22_bgra_vert.h"
   ;
-Evas_GL_Program_Source shader_img_bgra_vert_src =
+Evas_GL_Program_Source shader_img_22_bgra_vert_src =
 {
-   img_bgra_vert_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     img_bgra_vert_bin, sizeof(img_bgra_vert_bin)
-#else
-     NULL, 0
-#endif
+   img_22_bgra_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char img_22_bgra_nomul_frag_glsl[] =
+#include "shader/img_22_bgra_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_22_bgra_nomul_frag_src =
+{
+   img_22_bgra_nomul_frag_glsl,
+   NULL, 0
 };
 
+const char img_22_bgra_nomul_vert_glsl[] =
+#include "shader/img_22_bgra_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_22_bgra_nomul_vert_src =
+{
+   img_22_bgra_nomul_vert_glsl,
+   NULL, 0
+};
 
 /////////////////////////////////////////////
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int img_mask_frag_bin[] =
+const char img_22_bgra_afill_frag_glsl[] =
+#include "shader/img_22_bgra_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_22_bgra_afill_frag_src =
 {
-# include "shader/img_mask_frag_bin_s3c6410.h"
+   img_22_bgra_afill_frag_glsl,
+   NULL, 0
 };
-#endif
 
-const char img_mask_frag_glsl[] =
-#include "shader/img_mask_frag.h"
+const char img_22_bgra_afill_vert_glsl[] =
+#include "shader/img_22_bgra_afill_vert.h"
   ;
-Evas_GL_Program_Source shader_img_mask_frag_src =
+Evas_GL_Program_Source shader_img_22_bgra_afill_vert_src =
 {
-   img_mask_frag_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     img_mask_frag_bin, sizeof(img_mask_frag_bin)
-#else
-     NULL, 0
-#endif
+   img_22_bgra_afill_vert_glsl,
+   NULL, 0
 };
 
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int img_mask_vert_bin[] =
+/////////////////////////////////////////////
+const char img_22_bgra_nomul_afill_frag_glsl[] =
+#include "shader/img_22_bgra_nomul_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_22_bgra_nomul_afill_frag_src =
 {
-# include "shader/img_mask_vert_bin_s3c6410.h"
+   img_22_bgra_nomul_afill_frag_glsl,
+   NULL, 0
 };
-#endif
-const char img_mask_vert_glsl[] =
-#include "shader/img_mask_vert.h"
+
+const char img_22_bgra_nomul_afill_vert_glsl[] =
+#include "shader/img_22_bgra_nomul_afill_vert.h"
   ;
-Evas_GL_Program_Source shader_img_mask_vert_src =
+Evas_GL_Program_Source shader_img_22_bgra_nomul_afill_vert_src =
 {
-   img_mask_vert_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     img_mask_vert_bin, sizeof(img_mask_vert_bin)
-#else
-     NULL, 0
-#endif
+   img_22_bgra_nomul_afill_vert_glsl,
+   NULL, 0
 };
 
 
 /////////////////////////////////////////////
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int img_bgra_nomul_frag_bin[] =
+const char tex_22_frag_glsl[] =
+#include "shader/tex_22_frag.h"
+  ;
+Evas_GL_Program_Source shader_tex_22_frag_src =
 {
-# include "shader/img_bgra_nomul_frag_bin_s3c6410.h"
+   tex_22_frag_glsl,
+   NULL, 0
 };
-#endif
 
-const char img_bgra_nomul_frag_glsl[] =
-#include "shader/img_bgra_nomul_frag.h"
+const char tex_22_vert_glsl[] =
+#include "shader/tex_22_vert.h"
   ;
-Evas_GL_Program_Source shader_img_bgra_nomul_frag_src =
+Evas_GL_Program_Source shader_tex_22_vert_src =
 {
-   img_bgra_nomul_frag_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     img_bgra_nomul_frag_bin, sizeof(img_bgra_nomul_frag_bin)
-#else
-     NULL, 0
-#endif
+   tex_22_vert_glsl,
+   NULL, 0
 };
 
-#if defined (GLES_VARIETY_S3C6410)
-const unsigned int img_bgra_nomul_vert_bin[] =
+/////////////////////////////////////////////
+const char tex_22_nomul_frag_glsl[] =
+#include "shader/tex_22_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_tex_22_nomul_frag_src =
 {
-# include "shader/img_bgra_nomul_vert_bin_s3c6410.h"
+   tex_22_nomul_frag_glsl,
+   NULL, 0
 };
-#endif
-const char img_bgra_nomul_vert_glsl[] =
-#include "shader/img_bgra_nomul_vert.h"
+
+const char tex_22_nomul_vert_glsl[] =
+#include "shader/tex_22_nomul_vert.h"
   ;
-Evas_GL_Program_Source shader_img_bgra_nomul_vert_src =
+Evas_GL_Program_Source shader_tex_22_nomul_vert_src =
+{
+   tex_22_nomul_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char tex_22_afill_frag_glsl[] =
+#include "shader/tex_22_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_tex_22_afill_frag_src =
+{
+   tex_22_afill_frag_glsl,
+   NULL, 0
+};
+
+const char tex_22_afill_vert_glsl[] =
+#include "shader/tex_22_afill_vert.h"
+  ;
+Evas_GL_Program_Source shader_tex_22_afill_vert_src =
+{
+   tex_22_afill_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char tex_22_nomul_afill_frag_glsl[] =
+#include "shader/tex_22_nomul_afill_frag.h"
+  ;
+Evas_GL_Program_Source shader_tex_22_nomul_afill_frag_src =
+{
+   tex_22_nomul_afill_frag_glsl,
+   NULL, 0
+};
+
+const char tex_22_nomul_afill_vert_glsl[] =
+#include "shader/tex_22_nomul_afill_vert.h"
+  ;
+Evas_GL_Program_Source shader_tex_22_nomul_afill_vert_src =
+{
+   tex_22_nomul_afill_vert_glsl,
+   NULL, 0
+};
+
+
+
+/////////////////////////////////////////////
+const char yuv_frag_glsl[] =
+#include "shader/yuv_frag.h"
+  ;
+Evas_GL_Program_Source shader_yuv_frag_src =
+{
+   yuv_frag_glsl,
+   NULL, 0
+};
+
+const char yuv_vert_glsl[] =
+#include "shader/yuv_vert.h"
+  ;
+Evas_GL_Program_Source shader_yuv_vert_src =
+{
+   yuv_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char yuy2_frag_glsl[] =
+#include "shader/yuy2_frag.h"
+  ;
+Evas_GL_Program_Source shader_yuy2_frag_src =
+{
+   yuy2_frag_glsl,
+   NULL, 0
+};
+
+const char yuy2_vert_glsl[] =
+#include "shader/yuy2_vert.h"
+  ;
+Evas_GL_Program_Source shader_yuy2_vert_src =
+{
+   yuy2_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char yuy2_nomul_frag_glsl[] =
+#include "shader/yuy2_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_yuy2_nomul_frag_src =
+{
+   yuy2_nomul_frag_glsl,
+   NULL, 0
+};
+
+const char yuy2_nomul_vert_glsl[] =
+#include "shader/yuy2_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_yuy2_nomul_vert_src =
+{
+   yuy2_nomul_vert_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char nv12_nomul_vert_glsl[] =
+#include "shader/nv12_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_nv12_nomul_vert_src =
+{
+   nv12_nomul_vert_glsl,
+   NULL, 0
+};
+
+const char nv12_vert_glsl[] =
+#include "shader/nv12_vert.h"
+  ;
+Evas_GL_Program_Source shader_nv12_vert_src =
+{
+   nv12_vert_glsl,
+   NULL, 0
+};
+
+const char nv12_frag_glsl[] =
+#include "shader/nv12_frag.h"
+  ;
+Evas_GL_Program_Source shader_nv12_frag_src =
+{
+   nv12_frag_glsl,
+   NULL, 0
+};
+
+const char nv12_nomul_frag_glsl[] =
+#include "shader/nv12_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_nv12_nomul_frag_src =
+{
+   nv12_nomul_frag_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+
+const char tizen_nomul_vert_glsl[] =
+#include "shader/tizen_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_tizen_nomul_vert_src =
+{
+   tizen_nomul_vert_glsl,
+   NULL, 0
+};
+
+const char tizen_vert_glsl[] =
+#include "shader/tizen_vert.h"
+  ;
+Evas_GL_Program_Source shader_tizen_vert_src =
+{
+   tizen_vert_glsl,
+   NULL, 0
+};
+
+const char tizen_nomul_frag_glsl[] =
+#include "shader/tizen_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_tizen_nomul_frag_src =
+{
+   tizen_nomul_frag_glsl,
+   NULL, 0
+};
+
+const char tizen_frag_glsl[] =
+#include "shader/tizen_frag.h"
+  ;
+Evas_GL_Program_Source shader_tizen_frag_src =
+{
+   tizen_frag_glsl,
+   NULL, 0
+};
+
+const char tizen_mask_nomul_vert_glsl[] =
+#include "shader/tizen_mask_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_tizen_mask_nomul_vert_src =
+{
+   tizen_mask_nomul_vert_glsl,
+   NULL, 0
+};
+
+const char tizen_mask_vert_glsl[] =
+#include "shader/tizen_mask_vert.h"
+  ;
+Evas_GL_Program_Source shader_tizen_mask_vert_src =
+{
+   tizen_mask_vert_glsl,
+   NULL, 0
+};
+
+const char tizen_mask_nomul_frag_glsl[] =
+#include "shader/tizen_mask_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_tizen_mask_nomul_frag_src =
+{
+   tizen_mask_nomul_frag_glsl,
+   NULL, 0
+};
+
+const char tizen_mask_frag_glsl[] =
+#include "shader/tizen_mask_frag.h"
+  ;
+Evas_GL_Program_Source shader_tizen_mask_frag_src =
+{
+   tizen_mask_frag_glsl,
+   NULL, 0
+};
+
+/////////////////////////////////////////////
+const char yuv_nomul_frag_glsl[] =
+#include "shader/yuv_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_yuv_nomul_frag_src =
+{
+   yuv_nomul_frag_glsl,
+   NULL, 0
+};
+
+const char yuv_nomul_vert_glsl[] =
+#include "shader/yuv_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_yuv_nomul_vert_src =
 {
-   img_bgra_nomul_vert_glsl,
-#if defined (GLES_VARIETY_S3C6410)
-     img_bgra_nomul_vert_bin, sizeof(img_bgra_nomul_vert_bin)
-#else
-     NULL, 0
-#endif
+   yuv_nomul_vert_glsl,
+   NULL, 0
 };
 
 /////////////////////////////////////////////
@@ -628,6 +1175,7 @@ Evas_GL_Program_Source shader_filter_invert_bgra_frag_src =
    filter_invert_bgra_frag_glsl,
    NULL, 0
 };
+
 const char filter_invert_bgra_nomul_frag_glsl[] =
 #include "shader/filter_invert_bgra_nomul.h"
   ;
@@ -711,8 +1259,8 @@ Evas_GL_Program_Source shader_filter_sepia_bgra_nomul_frag_src =
 
 /////////////////////////////////////////////
 #if 0
-       Blur is a work in progress currently.
-       Mostly because GPUs are so hopeless.
+        Blur is a work in progress currently.
+        Mostly because GPUs are so hopeless.
 const char filter_blur_vert_glsl[] =
 #include "shader/filter_blur_vert.h"
   ;
@@ -761,150 +1309,335 @@ Evas_GL_Program_Source shader_filter_blur_bgra_nomul_frag_src =
 #endif
 
 
+/////////////////////////////////////////////
+const char rgb_a_pair_frag_glsl[] =
+#include "shader/rgb_a_pair_frag.h"
+  ;
+Evas_GL_Program_Source shader_rgb_a_pair_frag_src =
+{
+   rgb_a_pair_frag_glsl,
+   NULL, 0
+};
+
+const char rgb_a_pair_vert_glsl[] =
+#include "shader/rgb_a_pair_vert.h"
+  ;
+Evas_GL_Program_Source shader_rgb_a_pair_vert_src =
+{
+   rgb_a_pair_vert_glsl,
+   NULL, 0
+};
+
+const char rgb_a_pair_nomul_frag_glsl[] =
+#include "shader/rgb_a_pair_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_rgb_a_pair_nomul_frag_src =
+{
+   rgb_a_pair_nomul_frag_glsl,
+   NULL, 0
+};
+
+const char rgb_a_pair_nomul_vert_glsl[] =
+#include "shader/rgb_a_pair_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_rgb_a_pair_nomul_vert_src =
+{
+   rgb_a_pair_nomul_vert_glsl,
+   NULL, 0
+};
+
 
 /////////////////////////////////////////////
-static void
-gl_compile_link_error(GLuint target, const char *action)
+// Masking shaders
+
+const char font_mask_frag_glsl[] =
+#include "shader/font_mask_frag.h"
+  ;
+Evas_GL_Program_Source shader_font_mask_frag_src =
 {
-   int loglen = 0, chars = 0;
-   char *logtxt;
+   font_mask_frag_glsl,
+   NULL, 0
+};
 
-   /* Shader info log */
-   glGetShaderiv(target, GL_INFO_LOG_LENGTH, &loglen);
-   if (loglen > 0)
-     {
-        logtxt = calloc(loglen, sizeof(char));
-        if (logtxt)
-          {
-             glGetShaderInfoLog(target, loglen, &chars, logtxt);
-             ERR("Failed to %s: %s", action, logtxt);
-             free(logtxt);
-          }
-     }
+const char font_mask_vert_glsl[] =
+#include "shader/font_mask_vert.h"
+  ;
+Evas_GL_Program_Source shader_font_mask_vert_src =
+{
+   font_mask_vert_glsl,
+   NULL, 0
+};
 
-   /* Program info log */
-   glGetProgramiv(target, GL_INFO_LOG_LENGTH, &loglen);
-   if (loglen > 0)
-     {
-        logtxt = calloc(loglen, sizeof(char));
-        if (logtxt)
-          {
-             glGetProgramInfoLog(target, loglen, &chars, logtxt);
-             ERR("Failed to %s: %s", action, logtxt);
-             free(logtxt);
-          }
-     }
-}
+const char img_mask_frag_glsl[] =
+#include "shader/img_mask_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_mask_frag_src =
+{
+   img_mask_frag_glsl,
+   NULL, 0
+};
 
-static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
+const char img_mask_vert_glsl[] =
+#include "shader/img_mask_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_mask_vert_src =
+{
+   img_mask_vert_glsl,
+   NULL, 0
+};
 
-static Eina_Bool
-_evas_gl_shader_file_is_dir(const char *file)
+const char img_mask_bgra_frag_glsl[] =
+#include "shader/img_mask_bgra_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_mask_bgra_frag_src =
 {
-   struct stat st;
+   img_mask_bgra_frag_glsl,
+   NULL, 0
+};
 
-   if (stat(file, &st) < 0) return EINA_FALSE;
-   if (S_ISDIR(st.st_mode)) return EINA_TRUE;
-   return EINA_FALSE;
-}
+const char img_mask_bgra_nomul_frag_glsl[] =
+#include "shader/img_mask_bgra_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_mask_bgra_nomul_frag_src =
+{
+   img_mask_bgra_nomul_frag_glsl,
+   NULL, 0
+};
 
-static Eina_Bool
-_evas_gl_shader_file_mkdir(const char *dir)
+const char img_mask_bgra_nomul_vert_glsl[] =
+#include "shader/img_mask_bgra_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_mask_bgra_nomul_vert_src =
 {
-   /* evas gl shader only call this function when the dir is not exist */
-   if (mkdir(dir, default_mode) < 0) return EINA_FALSE;
-   return EINA_TRUE;
-}
+   img_mask_bgra_nomul_vert_glsl,
+   NULL, 0
+};
 
-static Eina_Bool
-_evas_gl_shader_file_exists(const char *file)
+const char img_mask_bgra_vert_glsl[] =
+#include "shader/img_mask_bgra_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_mask_bgra_vert_src =
 {
-   struct stat st;
-   if (!file) return EINA_FALSE;
-   if (stat(file, &st) < 0) return EINA_FALSE;
-   return EINA_TRUE;
-}
+   img_mask_bgra_vert_glsl,
+   NULL, 0
+};
 
-static inline Eina_Bool
-_evas_gl_shader_file_mkpath_if_not_exists(const char *path)
+const char img_mask_nomul_frag_glsl[] =
+#include "shader/img_mask_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_img_mask_nomul_frag_src =
 {
-   struct stat st;
+   img_mask_nomul_frag_glsl,
+   NULL, 0
+};
 
-   if (stat(path, &st) < 0)
-     return _evas_gl_shader_file_mkdir(path);
-   else if (!S_ISDIR(st.st_mode))
-     return EINA_FALSE;
-   else
-     return EINA_TRUE;
-}
+const char img_mask_nomul_vert_glsl[] =
+#include "shader/img_mask_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_img_mask_nomul_vert_src =
+{
+   img_mask_nomul_vert_glsl,
+   NULL, 0
+};
 
-static Eina_Bool
-_evas_gl_shader_file_mkpath(const char *path)
+const char nv12_mask_frag_glsl[] =
+#include "shader/nv12_mask_frag.h"
+  ;
+Evas_GL_Program_Source shader_nv12_mask_frag_src =
 {
-   char ss[PATH_MAX];
-   unsigned int i;
+   nv12_mask_frag_glsl,
+   NULL, 0
+};
+
+const char nv12_mask_vert_glsl[] =
+#include "shader/nv12_mask_vert.h"
+  ;
+Evas_GL_Program_Source shader_nv12_mask_vert_src =
+{
+   nv12_mask_vert_glsl,
+   NULL, 0
+};
 
-   if (_evas_gl_shader_file_is_dir(path)) return EINA_TRUE;
+const char rect_mask_frag_glsl[] =
+#include "shader/rect_mask_frag.h"
+  ;
+Evas_GL_Program_Source shader_rect_mask_frag_src =
+{
+   rect_mask_frag_glsl,
+   NULL, 0
+};
 
-   for (i = 0; path[i]; ss[i] = path[i], i++)
-     {
-        if (i == sizeof(ss) - 1) return EINA_FALSE;
-        if ((path[i] == '/') && (i > 0))
-          {
-             ss[i] = 0;
-             if (!_evas_gl_shader_file_mkpath_if_not_exists(ss))
-               return EINA_FALSE;
-          }
-     }
-   ss[i] = 0;
-   return _evas_gl_shader_file_mkpath_if_not_exists(ss);
-}
+const char rect_mask_vert_glsl[] =
+#include "shader/rect_mask_vert.h"
+  ;
+Evas_GL_Program_Source shader_rect_mask_vert_src =
+{
+   rect_mask_vert_glsl,
+   NULL, 0
+};
 
-static int
-_evas_gl_shader_dir_check(char *bin_shader_dir, int num)
+/*
+const char rgb_a_pair_mask_frag_glsl[] =
+#include "shader/rgb_a_pair_mask_frag.h"
+  ;
+Evas_GL_Program_Source shader_rgb_a_pair_mask_frag_src =
 {
-   char *home = NULL;
-   char *subdir = ".cache/evas_gl_common_shaders";
+   rgb_a_pair_mask_frag_glsl,
+   NULL, 0
+};
 
-   home = getenv("HOME");
-   if ((!home) || (!home[0])) return 0;
+const char rgb_a_pair_mask_vert_glsl[] =
+#include "shader/rgb_a_pair_mask_vert.h"
+  ;
+Evas_GL_Program_Source shader_rgb_a_pair_mask_vert_src =
+{
+   rgb_a_pair_mask_vert_glsl,
+   NULL, 0
+};
+*/
 
-   snprintf(bin_shader_dir, num, "%s/%s", home, subdir);
-   return _evas_gl_shader_file_exists(bin_shader_dir);
-}
+const char yuv_mask_frag_glsl[] =
+#include "shader/yuv_mask_frag.h"
+  ;
+Evas_GL_Program_Source shader_yuv_mask_frag_src =
+{
+   yuv_mask_frag_glsl,
+   NULL, 0
+};
 
-static int
-_evas_gl_shader_file_check(const char *bin_shader_dir, char *bin_shader_file, int dir_num)
+const char yuv_mask_vert_glsl[] =
+#include "shader/yuv_mask_vert.h"
+  ;
+Evas_GL_Program_Source shader_yuv_mask_vert_src =
+{
+   yuv_mask_vert_glsl,
+   NULL, 0
+};
+
+const char yuy2_mask_frag_glsl[] =
+#include "shader/yuy2_mask_frag.h"
+  ;
+Evas_GL_Program_Source shader_yuy2_mask_frag_src =
+{
+   yuy2_mask_frag_glsl,
+   NULL, 0
+};
+
+const char yuy2_mask_vert_glsl[] =
+#include "shader/yuy2_mask_vert.h"
+  ;
+Evas_GL_Program_Source shader_yuy2_mask_vert_src =
+{
+   yuy2_mask_vert_glsl,
+   NULL, 0
+};
+
+const char map_mask_frag_glsl[] =
+#include "shader/map_mask_frag.h"
+  ;
+Evas_GL_Program_Source shader_map_mask_frag_src =
+{
+   map_mask_frag_glsl,
+   NULL, 0
+};
+
+const char map_mask_vert_glsl[] =
+#include "shader/map_mask_vert.h"
+  ;
+Evas_GL_Program_Source shader_map_mask_vert_src =
+{
+   map_mask_vert_glsl,
+   NULL, 0
+};
+
+
+const char map_mask_bgra_frag_glsl[] =
+#include "shader/map_mask_bgra_frag.h"
+  ;
+Evas_GL_Program_Source shader_map_mask_bgra_frag_src =
+{
+   map_mask_bgra_frag_glsl,
+   NULL, 0
+};
+
+const char map_mask_bgra_nomul_frag_glsl[] =
+#include "shader/map_mask_bgra_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_map_mask_bgra_nomul_frag_src =
+{
+   map_mask_bgra_nomul_frag_glsl,
+   NULL, 0
+};
+
+const char map_mask_bgra_nomul_vert_glsl[] =
+#include "shader/map_mask_bgra_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_map_mask_bgra_nomul_vert_src =
+{
+   map_mask_bgra_nomul_vert_glsl,
+   NULL, 0
+};
+
+const char map_mask_bgra_vert_glsl[] =
+#include "shader/map_mask_bgra_vert.h"
+  ;
+Evas_GL_Program_Source shader_map_mask_bgra_vert_src =
+{
+   map_mask_bgra_vert_glsl,
+   NULL, 0
+};
+
+const char map_mask_nomul_frag_glsl[] =
+#include "shader/map_mask_nomul_frag.h"
+  ;
+Evas_GL_Program_Source shader_map_mask_nomul_frag_src =
 {
-   char before_name[PATH_MAX];
-   char after_name[PATH_MAX];
-   int new_path_len = 0;
-   int i = 0, j = 0;
+   map_mask_nomul_frag_glsl,
+   NULL, 0
+};
 
-   char *vendor = NULL;
-   char *driver = NULL;
-   char *version = NULL;
+const char map_mask_nomul_vert_glsl[] =
+#include "shader/map_mask_nomul_vert.h"
+  ;
+Evas_GL_Program_Source shader_map_mask_nomul_vert_src =
+{
+   map_mask_nomul_vert_glsl,
+   NULL, 0
+};
 
-   vendor = (char *)glGetString(GL_VENDOR);
-   driver = (char *)glGetString(GL_RENDERER);
-   version = (char *)glGetString(GL_VERSION);
 
-   new_path_len = snprintf(before_name, sizeof(before_name), "%s::%s::%s::%s::binary_shader.eet", vendor, version, driver, MODULE_ARCH);
+/////////////////////////////////////////////
+static void
+gl_compile_link_error(GLuint target, const char *action)
+{
+   int loglen = 0, chars = 0;
+   char *logtxt;
 
-   /* remove '/' from file name */
-   for (i = 0; i < new_path_len; i++)
+   /* Shader info log */
+   glGetShaderiv(target, GL_INFO_LOG_LENGTH, &loglen);
+   if (loglen > 0)
      {
-        if (before_name[i] != '/')
+        logtxt = calloc(loglen, sizeof(char));
+        if (logtxt)
           {
-             after_name[j] = before_name[i];
-             j++;
+             glGetShaderInfoLog(target, loglen, &chars, logtxt);
+             ERR("Failed to %s: %s", action, logtxt);
+             free(logtxt);
           }
      }
-   after_name[j] = 0;
-
-   snprintf(bin_shader_file, dir_num, "%s/%s", bin_shader_dir, after_name);
 
-   return _evas_gl_shader_file_exists(bin_shader_file);
+   /* Program info log */
+   glGetProgramiv(target, GL_INFO_LOG_LENGTH, &loglen);
+   if (loglen > 0)
+     {
+        logtxt = calloc(loglen, sizeof(char));
+        if (logtxt)
+          {
+             glGetProgramInfoLog(target, loglen, &chars, logtxt);
+             ERR("Failed to %s: %s", action, logtxt);
+             free(logtxt);
+          }
+     }
 }
 
 static int
@@ -934,8 +1667,8 @@ _evas_gl_common_shader_program_binary_init(Evas_GL_Program *p,
    p->prog = glCreateProgram();
 
 #if 1
-   // TODO: invalid rendering error occurs when attempting to use a 
-   // glProgramBinary. in order to render correctly we should create a dummy 
+   // TODO: invalid rendering error occurs when attempting to use a
+   // glProgramBinary. in order to render correctly we should create a dummy
    // vertex shader.
    p->vert = glCreateShader(GL_VERTEX_SHADER);
    glAttachShader(p->prog, p->vert);
@@ -950,6 +1683,7 @@ _evas_gl_common_shader_program_binary_init(Evas_GL_Program *p,
    glBindAttribLocation(p->prog, SHAD_TEXUV2, "tex_coord2");
    glBindAttribLocation(p->prog, SHAD_TEXUV3, "tex_coord3");
    glBindAttribLocation(p->prog, SHAD_TEXM,   "tex_coordm");
+   glBindAttribLocation(p->prog, SHAD_TEXSAM, "tex_sample");
 
    glGetProgramiv(p->prog, GL_LINK_STATUS, &ok);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
@@ -960,6 +1694,7 @@ _evas_gl_common_shader_program_binary_init(Evas_GL_Program *p,
         goto finish;
      }
 
+   p->init = EINA_TRUE;
    res = 1;
 
 finish:
@@ -1017,14 +1752,11 @@ _evas_gl_common_shader_program_source_init(Evas_GL_Program *p,
 {
    GLint ok;
 
+   if (p->init) return 1;
+
    p->vert = glCreateShader(GL_VERTEX_SHADER);
    p->frag = glCreateShader(GL_FRAGMENT_SHADER);
-#if defined (GLES_VARIETY_S3C6410)
-   glShaderBinary(1, &(p->vert), 0, vert->bin, vert->bin_size);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   glShaderBinary(1, &(p->frag), 0, frag->bin, frag->bin_size);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-#else
+
    glShaderSource(p->vert, 1,
                   (const char **)&(vert->src), NULL);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
@@ -1040,7 +1772,7 @@ _evas_gl_common_shader_program_source_init(Evas_GL_Program *p,
         return 0;
      }
    glShaderSource(p->frag, 1,
-                        (const char **)&(frag->src), NULL);
+                  (const char **)&(frag->src), NULL);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
    glCompileShader(p->frag);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
@@ -1053,9 +1785,9 @@ _evas_gl_common_shader_program_source_init(Evas_GL_Program *p,
         ERR("Abort compile of shader frag (%s): %s", name, frag->src);
         return 0;
      }
-#endif
+
    p->prog = glCreateProgram();
-#if defined(GLES_VARIETY_S3C6410) || defined(GLES_VARIETY_SGX)
+#ifdef GL_GLES
 #else
    if ((glsym_glGetProgramBinary) && (glsym_glProgramParameteri))
       glsym_glProgramParameteri(p->prog, GL_PROGRAM_BINARY_RETRIEVABLE_HINT,
@@ -1078,6 +1810,8 @@ _evas_gl_common_shader_program_source_init(Evas_GL_Program *p,
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
    glBindAttribLocation(p->prog, SHAD_TEXM, "tex_coordm");
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   glBindAttribLocation(p->prog, SHAD_TEXSAM, "tex_sample");
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
 
    glLinkProgram(p->prog);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
@@ -1108,19 +1842,67 @@ static const struct {
 } _shaders_source[] = {
   SHADER_SOURCE_LINE(RECT, rect),
   SHADER_SOURCE_LINE(FONT, font),
+
   SHADER_SOURCE_LINE(IMG, img),
   SHADER_SOURCE_LINE(IMG_NOMUL, img_nomul),
+  SHADER_SOURCE_LINE(IMG_AFILL, img_afill),
+  SHADER_SOURCE_LINE(IMG_NOMUL_AFILL, img_nomul_afill),
   SHADER_SOURCE_LINE(IMG_BGRA, img_bgra),
   SHADER_SOURCE_LINE(IMG_BGRA_NOMUL, img_bgra_nomul),
-  SHADER_SOURCE_LINE(IMG_MASK, img_mask),
+  SHADER_SOURCE_LINE(IMG_BGRA_AFILL, img_bgra_afill),
+  SHADER_SOURCE_LINE(IMG_BGRA_NOMUL_AFILL, img_bgra_nomul_afill),
+  SHADER_SOURCE_LINE(TEX, tex),
+  SHADER_SOURCE_LINE(TEX_NOMUL, tex_nomul),
+  SHADER_SOURCE_LINE(TEX_AFILL, tex_afill),
+  SHADER_SOURCE_LINE(TEX_NOMUL_AFILL, tex_nomul_afill),
+
+  SHADER_SOURCE_LINE(IMG_21, img_21),
+  SHADER_SOURCE_LINE(IMG_21_NOMUL, img_21_nomul),
+  SHADER_SOURCE_LINE(IMG_21_AFILL, img_21_afill),
+  SHADER_SOURCE_LINE(IMG_21_NOMUL_AFILL, img_21_nomul_afill),
+  SHADER_SOURCE_LINE(IMG_21_BGRA, img_21_bgra),
+  SHADER_SOURCE_LINE(IMG_21_BGRA_NOMUL, img_21_bgra_nomul),
+  SHADER_SOURCE_LINE(IMG_21_BGRA_AFILL, img_21_bgra_afill),
+  SHADER_SOURCE_LINE(IMG_21_BGRA_NOMUL_AFILL, img_21_bgra_nomul_afill),
+  SHADER_SOURCE_LINE(TEX_21, tex_21),
+  SHADER_SOURCE_LINE(TEX_21_NOMUL, tex_21_nomul),
+  SHADER_SOURCE_LINE(TEX_21_AFILL, tex_21_afill),
+  SHADER_SOURCE_LINE(TEX_21_NOMUL_AFILL, tex_21_nomul_afill),
+
+  SHADER_SOURCE_LINE(IMG_12, img_12),
+  SHADER_SOURCE_LINE(IMG_12_NOMUL, img_12_nomul),
+  SHADER_SOURCE_LINE(IMG_12_AFILL, img_12_afill),
+  SHADER_SOURCE_LINE(IMG_12_NOMUL_AFILL, img_12_nomul_afill),
+  SHADER_SOURCE_LINE(IMG_12_BGRA, img_12_bgra),
+  SHADER_SOURCE_LINE(IMG_12_BGRA_NOMUL, img_12_bgra_nomul),
+  SHADER_SOURCE_LINE(IMG_12_BGRA_AFILL, img_12_bgra_afill),
+  SHADER_SOURCE_LINE(IMG_12_BGRA_NOMUL_AFILL, img_12_bgra_nomul_afill),
+  SHADER_SOURCE_LINE(TEX_12, tex_12),
+  SHADER_SOURCE_LINE(TEX_12_NOMUL, tex_12_nomul),
+  SHADER_SOURCE_LINE(TEX_12_AFILL, tex_12_afill),
+  SHADER_SOURCE_LINE(TEX_12_NOMUL_AFILL, tex_12_nomul_afill),
+
+  SHADER_SOURCE_LINE(IMG_22, img_22),
+  SHADER_SOURCE_LINE(IMG_22_NOMUL, img_22_nomul),
+  SHADER_SOURCE_LINE(IMG_22_AFILL, img_22_afill),
+  SHADER_SOURCE_LINE(IMG_22_NOMUL_AFILL, img_22_nomul_afill),
+  SHADER_SOURCE_LINE(IMG_22_BGRA, img_22_bgra),
+  SHADER_SOURCE_LINE(IMG_22_BGRA_NOMUL, img_22_bgra_nomul),
+  SHADER_SOURCE_LINE(IMG_22_BGRA_AFILL, img_22_bgra_afill),
+  SHADER_SOURCE_LINE(IMG_22_BGRA_NOMUL_AFILL, img_22_bgra_nomul_afill),
+  SHADER_SOURCE_LINE(TEX_22, tex_22),
+  SHADER_SOURCE_LINE(TEX_22_NOMUL, tex_22_nomul),
+  SHADER_SOURCE_LINE(TEX_22_AFILL, tex_22_afill),
+  SHADER_SOURCE_LINE(TEX_22_NOMUL_AFILL, tex_22_nomul_afill),
+
   SHADER_SOURCE_LINE(YUV, yuv),
   SHADER_SOURCE_LINE(YUV_NOMUL, yuv_nomul),
   SHADER_SOURCE_LINE(YUY2, yuy2),
   SHADER_SOURCE_LINE(YUY2_NOMUL, yuy2_nomul),
   SHADER_SOURCE_LINE(NV12, nv12),
   SHADER_SOURCE_LINE(NV12_NOMUL, nv12_nomul),
-  SHADER_SOURCE_LINE(TEX, tex),
-  SHADER_SOURCE_LINE(TEX_NOMUL, tex_nomul),
+
+  /* FIXME: Filters are disabled. This useless code must be removed. */
    /* Most of the filters use the image fragment shader */
   SHADER_SOURCE_FILTER_LINE(FILTER_INVERT, filter_invert),
   SHADER_SOURCE_FILTER_LINE(FILTER_INVERT_NOMUL, filter_invert_nomul),
@@ -1133,11 +1915,37 @@ static const struct {
   SHADER_SOURCE_FILTER_LINE(FILTER_SEPIA, filter_sepia),
   SHADER_SOURCE_FILTER_LINE(FILTER_SEPIA_NOMUL, filter_sepia_nomul),
   SHADER_SOURCE_FILTER_LINE(FILTER_SEPIA_BGRA, filter_sepia_bgra),
-  SHADER_SOURCE_FILTER_LINE(FILTER_SEPIA_BGRA_NOMUL, filter_sepia_bgra_nomul)/* , */
+  SHADER_SOURCE_FILTER_LINE(FILTER_SEPIA_BGRA_NOMUL, filter_sepia_bgra_nomul),
   /* SHADER_SOURCE_LINE(FILTER_BLUR, filter_blur), */
   /* SHADER_SOURCE_LINE(FILTER_BLUR_NOMUL, filter_blur_nomul), */
   /* SHADER_SOURCE_LINE(FILTER_BLUR_BGRA, filter_blur_bgra), */
   /* SHADER_SOURCE_LINE(FILTER_BLUR_BGRA_NOMUL, filter_blur_bgra_nomul) */
+#ifdef HAVE_NATIVE_BUFFER
+  SHADER_SOURCE_LINE(TIZEN, tizen),
+  SHADER_SOURCE_LINE(TIZEN_MASK, tizen_mask),
+  SHADER_SOURCE_LINE(TIZEN_NOMUL, tizen_nomul),
+  SHADER_SOURCE_LINE(TIZEN_MASK_NOMUL, tizen_mask_nomul),
+#endif
+
+  SHADER_SOURCE_LINE(RGB_A_PAIR, rgb_a_pair),
+  SHADER_SOURCE_LINE(RGB_A_PAIR_NOMUL, rgb_a_pair_nomul),
+
+  /* Masks */
+  SHADER_SOURCE_LINE(FONT_MASK, font_mask),
+  SHADER_SOURCE_LINE(IMG_MASK, img_mask),
+  SHADER_SOURCE_LINE(IMG_MASK_BGRA, img_mask_bgra),
+  SHADER_SOURCE_LINE(IMG_MASK_BGRA_NOMUL, img_mask_bgra_nomul),
+  SHADER_SOURCE_LINE(IMG_MASK_NOMUL, img_mask_nomul),
+  SHADER_SOURCE_LINE(NV12_MASK, nv12_mask),
+  SHADER_SOURCE_LINE(RECT_MASK, rect_mask),
+  //SHADER_SOURCE_LINE(RGB_A_PAIR_MASK, rgb_a_pair_mask),
+  SHADER_SOURCE_LINE(YUV_MASK, yuv_mask),
+  SHADER_SOURCE_LINE(YUY2_MASK, yuy2_mask),
+
+  SHADER_SOURCE_LINE(MAP_MASK, map_mask),
+  SHADER_SOURCE_LINE(MAP_MASK_BGRA, map_mask_bgra),
+  SHADER_SOURCE_LINE(MAP_MASK_NOMUL, map_mask_nomul),
+  SHADER_SOURCE_LINE(MAP_MASK_BGRA_NOMUL, map_mask_bgra_nomul),
 };
 
 static int
@@ -1145,13 +1953,15 @@ _evas_gl_common_shader_source_init(Evas_GL_Shared *shared)
 {
   unsigned int i;
 
-  for (i = 0; i < sizeof (_shaders_source) / sizeof (_shaders_source[0]); ++i)
-    if (!_evas_gl_common_shader_program_source_init(&(shared->shader[_shaders_source[i].id]),
-                                                    _shaders_source[i].vert,
-                                                    _shaders_source[i].frag,
-                                                    _shaders_source[i].name))
-        return 0;
-
+  for (i = 0; i < sizeof (_shaders_source) / sizeof (_shaders_source[0]); i++)
+     {
+    if (!_evas_gl_common_shader_program_source_init
+            (&(shared->shader[_shaders_source[i].id]),
+                _shaders_source[i].vert,
+                _shaders_source[i].frag,
+                _shaders_source[i].name))
+          return 0;
+     }
    return 1;
 }
 
@@ -1163,11 +1973,12 @@ _evas_gl_common_shader_binary_init(Evas_GL_Shared *shared)
    char bin_dir_path[PATH_MAX];
    char bin_file_path[PATH_MAX];
    unsigned int i;
+   int res = 0;
 
-   if (!_evas_gl_shader_dir_check(bin_dir_path, sizeof(bin_dir_path)))
+   if (!evas_gl_common_file_cache_dir_check(bin_dir_path, sizeof(bin_dir_path)))
       return 0;
 
-   if (!_evas_gl_shader_file_check(bin_dir_path, bin_file_path,
+   if (!evas_gl_common_file_cache_file_check(bin_dir_path, "binary_shader", bin_file_path,
                                    sizeof(bin_dir_path)))
       return 0;
 
@@ -1176,20 +1987,17 @@ _evas_gl_common_shader_binary_init(Evas_GL_Shared *shared)
    et = eet_open(bin_file_path, EET_FILE_MODE_READ);
    if (!et) goto error;
 
+   res = 1;
    for (i = 0; i < sizeof (_shaders_source) / sizeof (_shaders_source[0]); ++i)
      if (!_evas_gl_common_shader_program_binary_init(&(shared->shader[_shaders_source[i].id]),
-                                                     _shaders_source[i].name,
-                                                     et))
-       goto error;
-
-   if (et) eet_close(et);
-   eet_shutdown();
-   return 1;
+                                                _shaders_source[i].name,
+                                                et))
+        res = 0;
 
 error:
    if (et) eet_close(et);
    eet_shutdown();
-   return 0;
+   return res;
 }
 
 static int
@@ -1204,13 +2012,13 @@ _evas_gl_common_shader_binary_save(Evas_GL_Shared *shared)
    char tmp_file[PATH_MAX];
    unsigned int i;
 
-   if (!_evas_gl_shader_dir_check(bin_dir_path, sizeof(bin_dir_path)))
+   if (!evas_gl_common_file_cache_dir_check(bin_dir_path, sizeof(bin_dir_path)))
      {
-        res = _evas_gl_shader_file_mkpath(bin_dir_path);
+        res = evas_gl_common_file_cache_mkpath(bin_dir_path);
         if (!res) return 0; /* we can't make directory */
      }
 
-   _evas_gl_shader_file_check(bin_dir_path, bin_file_path,
+   evas_gl_common_file_cache_file_check(bin_dir_path, "binary_shader", bin_file_path,
                               sizeof(bin_dir_path));
 
    /* use mkstemp for writing */
@@ -1238,7 +2046,7 @@ _evas_gl_common_shader_binary_save(Evas_GL_Shared *shared)
 
 error:
    if (et) eet_close(et);
-   if (_evas_gl_shader_file_exists(tmp_file)) unlink(tmp_file);
+   if (evas_gl_common_file_cache_file_exists(tmp_file)) unlink(tmp_file);
    eet_shutdown();
    return 0;
 }
@@ -1259,7 +2067,7 @@ evas_gl_common_shader_program_init(Evas_GL_Shared *shared)
 void
 evas_gl_common_shader_program_init_done(void)
 {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
    glReleaseShaderCompiler();
 #else
    if (glsym_glReleaseShaderCompiler) glsym_glReleaseShaderCompiler();
old mode 100644 (file)
new mode 100755 (executable)
index 934ff41..d229989
@@ -1,29 +1,31 @@
 #include "evas_gl_private.h"
 
+static int evas_gl_texture_rect_pool = -1;
 static const GLenum rgba_fmt   = GL_RGBA;
 static const GLenum rgba_ifmt  = GL_RGBA;
-//#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-//static const GLenum rgb_fmt    = GL_RGBA;
-//static const GLenum rgb_ifmt   = GL_RGBA;
-//#else
 static const GLenum rgb_fmt    = GL_RGBA;
 static const GLenum rgb_ifmt   = GL_RGB;
-//#endif
-#ifdef GL_BGRA
-# if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+
+#ifdef GL_GLES
 static const GLenum bgra_fmt   = GL_BGRA;
 static const GLenum bgra_ifmt  = GL_BGRA;
 static const GLenum bgr_fmt    = GL_BGRA;
 static const GLenum bgr_ifmt   = GL_BGRA;
-# else
+#else
 static const GLenum bgra_fmt   = GL_BGRA;
 static const GLenum bgra_ifmt  = GL_RGBA;
 static const GLenum bgr_fmt    = GL_BGRA;
 static const GLenum bgr_ifmt   = GL_RGB;
-# endif
 #endif
+
+#ifdef GL_GLES
 static const GLenum alpha_fmt      = GL_ALPHA;
 static const GLenum alpha_ifmt     = GL_ALPHA;
+#else
+static const GLenum alpha_fmt      = GL_ALPHA;
+static const GLenum alpha_ifmt     = GL_ALPHA4;
+#endif
+
 static const GLenum lum_fmt        = GL_LUMINANCE;
 static const GLenum lum_ifmt       = GL_LUMINANCE;
 static const GLenum lum_alpha_fmt  = GL_LUMINANCE_ALPHA;
@@ -31,12 +33,106 @@ static const GLenum lum_alpha_ifmt = GL_LUMINANCE_ALPHA;
 static const GLenum rgba8_ifmt     = GL_RGBA;
 static const GLenum rgba8_fmt      = GL_BGRA;
 
+/* FIXME: RGB8_ETC2 is a superset of ETC1,
+ * but is GL_ETC1_RGB8_OES supported whenever GL_COMPRESSED_RGB8_ETC2 is?
+ */
+static const GLenum etc1_fmt       = GL_ETC1_RGB8_OES;
+static const GLenum etc2_rgb_fmt   = GL_COMPRESSED_RGB8_ETC2;
+static const GLenum etc2_rgba_fmt  = GL_COMPRESSED_RGBA8_ETC2_EAC;
+
 static struct {
    struct {
       int num, pix;
    } c, a, v, r, n, d;
 } texinfo = {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}};
 
+typedef enum {
+   MATCH_FALSE = EINA_FALSE,
+   MATCH_TRUE  = EINA_TRUE,
+   MATCH_ANY   = 2
+} Eina_Bool_Match;
+
+static const struct {
+   Eina_Bool_Match alpha;
+   Eina_Bool_Match bgra;
+
+   Evas_Colorspace cspace;
+
+   const GLenum *intformat;
+   const GLenum *format;
+} matching_format[] = {
+  { MATCH_TRUE, MATCH_TRUE, EVAS_COLORSPACE_ARGB8888, &bgra_ifmt, &bgra_fmt },
+  { MATCH_TRUE, MATCH_FALSE, EVAS_COLORSPACE_ARGB8888, &rgba_ifmt, &rgba_fmt },
+  { MATCH_FALSE, MATCH_TRUE, EVAS_COLORSPACE_ARGB8888, &bgr_ifmt, &bgr_fmt },
+#ifdef GL_GLES
+  { MATCH_FALSE, MATCH_FALSE, EVAS_COLORSPACE_ARGB8888, &rgba_ifmt, &rgba_fmt },
+#else
+  { MATCH_FALSE, MATCH_FALSE, EVAS_COLORSPACE_ARGB8888, &rgb_ifmt, &rgb_fmt },
+#endif
+  { MATCH_FALSE, MATCH_ANY, EVAS_COLORSPACE_GRY8, &lum_fmt, &lum_ifmt },
+  { MATCH_TRUE, MATCH_ANY, EVAS_COLORSPACE_AGRY88, &lum_alpha_fmt, &lum_alpha_ifmt },
+  // ETC1/2 support
+  { MATCH_FALSE, MATCH_ANY, EVAS_COLORSPACE_ETC1, &etc1_fmt, &etc1_fmt },
+  { MATCH_FALSE, MATCH_ANY, EVAS_COLORSPACE_RGB8_ETC2, &etc2_rgb_fmt, &etc2_rgb_fmt },
+  { MATCH_ANY, MATCH_ANY, EVAS_COLORSPACE_RGBA8_ETC2_EAC, &etc2_rgba_fmt, &etc2_rgba_fmt },
+  { MATCH_ANY, MATCH_ANY, EVAS_COLORSPACE_ETC1_ALPHA, &etc1_fmt, &etc1_fmt }
+};
+
+static const GLenum matching_rgba[] = { GL_RGBA4, GL_RGBA8, GL_RGBA12, GL_RGBA16, 0x0 };
+static const GLenum matching_alpha[] = { GL_ALPHA4, GL_ALPHA8, GL_ALPHA12, GL_ALPHA16, 0x0 };
+static const GLenum matching_luminance[] = { GL_LUMINANCE4, GL_LUMINANCE8, GL_LUMINANCE12, GL_LUMINANCE16, 0x0 };
+static const GLenum matching_luminance_alpha[] = { GL_LUMINANCE4_ALPHA4, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE12_ALPHA12, GL_LUMINANCE16_ALPHA16, 0x0 };
+
+static const struct {
+   GLenum master;
+   const GLenum *matching;
+} matching_fmt[] = {
+  { GL_RGBA, matching_rgba },
+  { GL_ALPHA, matching_alpha },
+  { GL_LUMINANCE, matching_luminance },
+  { GL_LUMINANCE_ALPHA, matching_luminance_alpha }
+};
+
+#define MATCH(_r, _v) ((_r == MATCH_ANY) || (_v == MATCH_ANY) || (_r == _v))
+
+static int
+_evas_gl_texture_search_format(Eina_Bool alpha, Eina_Bool bgra, Evas_Colorspace cspace)
+{
+   unsigned int i;
+
+   alpha = !!alpha;
+   bgra = !!bgra;
+
+   for (i = 0; i < sizeof (matching_format) / sizeof (matching_format[0]); ++i)
+     if (MATCH(matching_format[i].alpha, alpha) &&
+         MATCH(matching_format[i].bgra, bgra) &&
+         matching_format[i].cspace == cspace)
+       return i;
+
+   CRIT("There is no supported texture format for this colorspace: "
+        "cspace(%d) alpha(%d) bgra(%d)", cspace, alpha, bgra);
+   return -1;
+}
+
+void
+evas_gl_common_texture_shared_specific(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt, int i)
+{
+   if (!pt || pt->texture != gc->pipe[i].shader.cur_tex)
+     {
+        if (gc->pipe[i].array.im)
+          glBindTexture(gc->pipe[i].array.im->native.target, gc->pipe[i].shader.cur_tex);
+        else
+          glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_tex);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+     }
+}
+
+void
+evas_gl_common_texture_shared_back(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt)
+{
+   evas_gl_common_texture_shared_specific(gc, pt, 0);
+}
+
 static void
 _print_tex_count(void)
 {
@@ -89,34 +185,89 @@ _tex_format_index(GLuint format)
 {
    switch (format)
      {
-     case GL_RGBA:
+      case GL_RGBA:
 #ifdef GL_BGRA
-     case GL_BGRA:
+      case GL_BGRA:
 #endif
         return 0;
-     case GL_RGB:
+      case GL_RGB:
         return 1;
-     case GL_ALPHA:
+      case GL_ALPHA:
         return 2;
-     case GL_LUMINANCE: // never used in atlas
+      case GL_ETC1_RGB8_OES:
         return 3;
-     default:
+      case GL_COMPRESSED_RGB8_ETC2:
+        return 4;
+      case GL_COMPRESSED_RGBA8_ETC2_EAC:
+        return 5;
+      case GL_LUMINANCE: // never used in atlas
+        return 6;
+      case GL_LUMINANCE_ALPHA: // never used in atlas
+        return 7;
+      default:
+        // abort?
         return 0;
      }
    return 0;
 }
 
-static void
-_tex_2d(int intfmt, int w, int h, int fmt, int type)
+static inline int
+_evas_gl_texture_size_get(int w, int h, int intfmt, Eina_Bool *comp)
 {
+   if (comp) *comp = EINA_FALSE;
+   switch (intfmt)
+     {
+      case GL_RGBA:
+      case GL_BGRA:
+      case GL_RGB:
+        return w * h * 4;
+      case GL_ALPHA:
+        return w * h * 1;
+      case GL_ALPHA4:
+        return w * h / 2; // TODO: Check this
+      case GL_LUMINANCE:
+        return w * h * 1;
+      case GL_LUMINANCE_ALPHA:
+        return w * h * 2;
+      case GL_ETC1_RGB8_OES:
+      case GL_COMPRESSED_RGB8_ETC2:
+        if (comp) *comp = EINA_TRUE;
+        return ((w + 3) >> 2) * ((h + 3) >> 2) * 8;
+      case GL_COMPRESSED_RGBA8_ETC2_EAC:
+        if (comp) *comp = EINA_TRUE;
+        return ((w + 3) >> 2) * ((h + 3) >> 2) * 16;
+      default:
+        return 0;
+     }
+}
+
+static Eina_Bool
+_tex_2d(Evas_Engine_GL_Context *gc, int intfmt, int w, int h, int fmt, int type)
+{
+   Eina_Bool comp;
+   int sz;
 #ifdef GL_TEXTURE_INTERNAL_FORMAT
    int intfmtret = -1;
-#endif   
-   glTexImage2D(GL_TEXTURE_2D, 0, intfmt, w, h, 0, fmt, type, NULL);
+#endif
+
+   if ((w > gc->shared->info.max_texture_size) ||
+       (h > gc->shared->info.max_texture_size))
+     {
+        ERR("Fail tex too big %ix%i", w, h);
+        return EINA_FALSE;
+     }
+   sz = _evas_gl_texture_size_get(w, h, intfmt, &comp);
+   if (!comp)
+     glTexImage2D(GL_TEXTURE_2D, 0, intfmt, w, h, 0, fmt, type, NULL);
+   else
+     glCompressedTexImage2D(GL_TEXTURE_2D, 0, intfmt, w, h, 0, sz, NULL);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
 #ifdef GL_TEXTURE_INTERNAL_FORMAT
-// this is not in opengles!!! hrrrm   
-   if (glGetTexLevelParameteriv)
+# ifdef GL_GLES
+# else
+// this is not in opengles!!! hrrrm
+//   if (glGetTexLevelParameteriv) // in case of weak symbols?
      {
         glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
                                  GL_TEXTURE_INTERNAL_FORMAT, &intfmtret);
@@ -124,13 +275,16 @@ _tex_2d(int intfmt, int w, int h, int fmt, int type)
           {
              ERR("Fail tex alloc %ix%i", w, h);
              //        XXX send async err to evas
+             return EINA_FALSE;
           }
      }
-   else
-     {
-        ERR("GL_TEXTURE_INTERNAL_FORMAT defined but no symbol loaded.");
-     }
-#endif   
+//   else
+//     {
+//        ERR("GL_TEXTURE_INTERNAL_FORMAT defined but no symbol loaded.");
+//     }
+# endif
+#endif
+   return EINA_TRUE;
 }
 
 static void
@@ -140,15 +294,30 @@ _tex_sub_2d(int x, int y, int w, int h, int fmt, int type, const void *pix)
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
 }
 
+static void
+_comp_tex_sub_2d(int x, int y, int w, int h, int fmt, int size, const void *pix)
+{
+   glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, fmt, size, pix);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+}
+
 static Evas_GL_Texture_Pool *
 _pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, GLenum format)
 {
    Evas_GL_Texture_Pool *pt;
+   Eina_Bool ok, no_rounding = EINA_FALSE;
 
    pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
    if (!pt) return NULL;
-   h = _tex_round_slot(gc, h) * gc->shared->info.tune.atlas.slot_size;
-   _tex_adjust(gc, &w, &h);
+
+   if (!gc->shared->info.etc1_subimage && (intformat == etc1_fmt))
+     no_rounding = EINA_TRUE;
+
+   if (!no_rounding && evas_gl_texture_rect_pool == 0)
+     {
+        h = _tex_round_slot(gc, h) * gc->shared->info.tune.atlas.slot_size;
+        _tex_adjust(gc, &w, &h);
+     }
    pt->gc = gc;
    pt->w = w;
    pt->h = h;
@@ -156,24 +325,11 @@ _pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, GLenum fo
    pt->format = format;
    pt->dataformat = GL_UNSIGNED_BYTE;
    pt->references = 0;
-
-   if (format == alpha_fmt)
-      {
-         texinfo.a.num++;
-         texinfo.a.pix += pt->w * pt->h;
-      }
-   else if (format == lum_fmt)
-      {
-         texinfo.v.num++;
-         texinfo.v.pix += pt->w * pt->h;
-      }
-   else
-      {
-         texinfo.c.num++;
-         texinfo.c.pix += pt->w * pt->h;
-      }
-
-   _print_tex_count();
+   if (!no_rounding && evas_gl_texture_rect_pool == 1)
+     {
+        pt->eina_pool = eina_rectangle_pool_new(w, h);
+        //eina_rectangle_pool_packing_set(pt->eina_pool, Eina_Packing_Ascending);
+     }
 
    glGenTextures(1, &(pt->texture));
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
@@ -187,14 +343,63 @@ _pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, GLenum fo
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   _tex_2d(pt->intformat, w, h, pt->format, pt->dataformat);
-   glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   ok = _tex_2d(gc, pt->intformat, w, h, pt->format, pt->dataformat);
+   evas_gl_common_texture_shared_back(gc, pt);
+   if (!ok)
+     {
+        glDeleteTextures(1, &(pt->texture));
+        if (evas_gl_texture_rect_pool == 1)
+          if (pt->eina_pool)
+            eina_rectangle_pool_free(pt->eina_pool);
+        free(pt);
+        return NULL;
+     }
+
+   if (format == alpha_fmt)
+     {
+        texinfo.a.num++;
+        texinfo.a.pix += pt->w * pt->h;
+     }
+   else if (format == lum_fmt)
+     {
+        texinfo.v.num++;
+        texinfo.v.pix += pt->w * pt->h;
+     }
+   else
+     {
+        texinfo.c.num++;
+        texinfo.c.pix += pt->w * pt->h;
+     }
+   _print_tex_count();
    return pt;
 }
 
 static int
-_pool_tex_alloc(Evas_GL_Texture_Pool *pt, int w, int h __UNUSED__, int *u, int *v, Eina_List **l_after)
+_rectangle_pool_tex_alloc(Evas_GL_Texture_Pool *pt, int w, int h, int *u, int *v, Eina_List **l_after,
+                Evas_GL_Texture* tex)
+{
+   Eina_Rectangle *r = NULL;
+
+   if (pt)
+     {
+        r = eina_rectangle_pool_request( pt->eina_pool, w, h);
+        if (r)
+          {
+             *v = r->y;
+             *u = r->x;
+             *l_after = NULL;
+             tex->rect = r;
+             return 1;
+         }
+     }
+
+   *l_after = NULL;
+   return 0;
+}
+
+static int
+_pool_tex_alloc(Evas_GL_Texture_Pool *pt, int w, int h __UNUSED__,
+                int *u, int *v, Eina_List **l_after, Eina_Bool align4)
 {
    Eina_List *l;
    Evas_GL_Texture *tex, *tex2;
@@ -203,7 +408,7 @@ _pool_tex_alloc(Evas_GL_Texture_Pool *pt, int w, int h __UNUSED__, int *u, int *
    if (pt->allocations)
      {
         tex = pt->allocations->data;
-        // if firest tex is not at left edge...
+        // if first tex is not at left edge...
         if (tex->x > (0 + 1))
           {
              if ((tex->x - 1) >= w)
@@ -218,6 +423,8 @@ _pool_tex_alloc(Evas_GL_Texture_Pool *pt, int w, int h __UNUSED__, int *u, int *
    EINA_LIST_FOREACH(pt->allocations, l, tex)
      {
         b = tex->x + tex->w + 2;
+        if (align4)
+          b = (b + 3) & ~3;
         if (l->next)
           {
              tex2 = l->next->data;
@@ -239,9 +446,66 @@ _pool_tex_alloc(Evas_GL_Texture_Pool *pt, int w, int h __UNUSED__, int *u, int *
 }
 
 static Evas_GL_Texture_Pool *
-_pool_tex_find(Evas_Engine_GL_Context *gc, int w, int h,
+_rectangle_pool_tex_find(Evas_Engine_GL_Context *gc, int w, int h,
                int intformat, int format, int *u, int *v,
-               Eina_List **l_after, int atlas_w)
+               Eina_List **l_after, int atlas_w, Evas_GL_Texture* tex)
+{
+   Evas_GL_Texture_Pool *pt = NULL;
+   Eina_List *l;
+   int th, th2;
+   int pool_h;
+
+   if (atlas_w > gc->shared->info.max_texture_size)
+      atlas_w = gc->shared->info.max_texture_size;
+   if ((w > gc->shared->info.tune.atlas.max_w) ||
+       (h > gc->shared->info.tune.atlas.max_h) ||
+       (!gc->shared->info.etc1_subimage && (intformat == etc1_fmt)))
+     {
+        pt = _pool_tex_new(gc, w, h, intformat, format);
+        if (!pt) return NULL;
+        gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, pt);
+        pt->slot = -1;
+        pt->fslot = -1;
+        pt->whole = 1;
+        *u = 0;
+        *v = 0;
+        *l_after = NULL;
+        return pt;
+     }
+   th = 0;
+   th2 = _tex_format_index(intformat);
+   EINA_LIST_FOREACH(gc->shared->tex.atlas[th][th2], l, pt)
+     {
+        if (_rectangle_pool_tex_alloc(pt, w, h, u, v, l_after, tex))
+          {
+             gc->shared->tex.atlas[th][th2] =
+               eina_list_remove_list(gc->shared->tex.atlas[th][th2], l);
+             gc->shared->tex.atlas[th][th2] =
+               eina_list_prepend(gc->shared->tex.atlas[th][th2], pt);
+             return pt;
+          }
+     }
+   pool_h = atlas_w;
+   if ( h > pool_h || w > atlas_w )
+     {
+        atlas_w = gc->shared->info.tune.atlas.max_w;
+        pool_h = gc->shared->info.tune.atlas.max_h;
+     }
+     pt = _pool_tex_new(gc, atlas_w, pool_h, intformat, format);
+
+   if (!pt) return NULL;
+   gc->shared->tex.atlas[th][th2] =
+     eina_list_prepend(gc->shared->tex.atlas[th][th2], pt);
+   pt->slot = th;
+   pt->fslot = th2;
+     _rectangle_pool_tex_alloc(pt, w, h, u, v, l_after, tex);
+   return pt;
+}
+
+static Evas_GL_Texture_Pool *
+_pool_tex_find(Evas_Engine_GL_Context *gc, int w, int h,
+               GLenum intformat, GLenum format, int *u, int *v,
+               Eina_List **l_after, int atlas_w, Eina_Bool align4)
 {
    Evas_GL_Texture_Pool *pt = NULL;
    Eina_List *l;
@@ -250,9 +514,11 @@ _pool_tex_find(Evas_Engine_GL_Context *gc, int w, int h,
    if (atlas_w > gc->shared->info.max_texture_size)
       atlas_w = gc->shared->info.max_texture_size;
    if ((w > gc->shared->info.tune.atlas.max_w) ||
-       (h > gc->shared->info.tune.atlas.max_h))
+       (h > gc->shared->info.tune.atlas.max_h) ||
+       (!gc->shared->info.etc1_subimage && (intformat == etc1_fmt)))
      {
         pt = _pool_tex_new(gc, w, h, intformat, format);
+        if (!pt) return NULL;
         gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, pt);
         pt->slot = -1;
         pt->fslot = -1;
@@ -267,7 +533,7 @@ _pool_tex_find(Evas_Engine_GL_Context *gc, int w, int h,
    th2 = _tex_format_index(intformat);
    EINA_LIST_FOREACH(gc->shared->tex.atlas[th][th2], l, pt)
      {
-        if (_pool_tex_alloc(pt, w, h, u, v, l_after))
+        if (_pool_tex_alloc(pt, w, h, u, v, l_after, align4))
           {
              gc->shared->tex.atlas[th][th2] =
                eina_list_remove_list(gc->shared->tex.atlas[th][th2], l);
@@ -276,7 +542,12 @@ _pool_tex_find(Evas_Engine_GL_Context *gc, int w, int h,
              return pt;
           }
      }
+
+   /* Allocate texture of max height in current slot */
+   h = th * gc->shared->info.tune.atlas.slot_size;
+
    pt = _pool_tex_new(gc, atlas_w, h, intformat, format);
+   if (!pt) return NULL;
    gc->shared->tex.atlas[th][th2] =
      eina_list_prepend(gc->shared->tex.atlas[th][th2], pt);
    pt->slot = th;
@@ -292,7 +563,60 @@ evas_gl_common_texture_new(Evas_Engine_GL_Context *gc, RGBA_Image *im)
 {
    Evas_GL_Texture *tex;
    Eina_List *l_after = NULL;
-   int u = 0, v = 0;
+   int u = 0, v = 0, yoffset = 0;
+   Eina_Bool align4 = EINA_FALSE;
+   GLsizei w, h;
+   int lformat;
+
+   lformat = _evas_gl_texture_search_format(im->cache_entry.flags.alpha, gc->shared->info.bgra, im->cache_entry.space);
+   if (lformat < 0) return NULL;
+
+#define TEX_HREP 1
+#define TEX_VREP 1
+
+   if (evas_gl_texture_rect_pool == -1)
+   {
+      if (getenv("EVAS_GL_TEXTURE_RECT_POOL_DISABLE"))  evas_gl_texture_rect_pool = 0;
+      else evas_gl_texture_rect_pool = 1;
+   }
+
+#warning FIXME: Hack for compatibility with weird evas 1.7 code. No idea why there was a difference.
+   int EXTRA_HREP = (im->cache_entry.flags.alpha ? 1 : 2);
+
+   switch (im->cache_entry.space)
+     {
+      case EVAS_COLORSPACE_ETC1:
+      case EVAS_COLORSPACE_RGB8_ETC2:
+      case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+        // Add border to avoid artifacts
+        w = im->cache_entry.w + 2;
+        h = im->cache_entry.h + 2;
+        yoffset = 1;
+
+        // Adjust w and h for ETC1/2 formats (multiple of 4 pixels on both axes)
+        w = ((w >> 2) + (w & 0x3 ? 1 : 0)) << 2;
+        h = ((h >> 2) + (h & 0x3 ? 1 : 0)) << 2;
+
+        // For the old allocator
+        align4 = EINA_TRUE;
+        break;
+
+      case EVAS_COLORSPACE_ETC1_ALPHA:
+        // One must call evas_gl_common_texture_rgb_a_pair_new() instead.
+        ERR("Trying to upload ETC1+Alpha texture as a normal texture. Abort.");
+        return NULL;
+
+     default:
+        /* This need to be adjusted if we do something else than strip allocation */
+        w = im->cache_entry.w + TEX_HREP + EXTRA_HREP; /* one pixel stop gap and two pixels for the border */
+        if (evas_gl_texture_rect_pool == 1)
+          {
+             h = im->cache_entry.h + TEX_VREP + EXTRA_HREP;
+             yoffset = 1;
+          }
+        else
+           h = im->cache_entry.h + TEX_VREP; /* only one added border for security down */
+     }
 
    tex = calloc(1, sizeof(Evas_GL_Texture));
    if (!tex) return NULL;
@@ -300,47 +624,28 @@ evas_gl_common_texture_new(Evas_Engine_GL_Context *gc, RGBA_Image *im)
    tex->gc = gc;
    tex->references = 1;
 
-   if (im->cache_entry.flags.alpha)
-     {
-        if (gc->shared->info.bgra)
-           tex->pt = _pool_tex_find(gc, im->cache_entry.w + 2,
-                                    im->cache_entry.h + 1, bgra_ifmt, bgra_fmt,
-                                    &u, &v, &l_after,
-                                    gc->shared->info.tune.atlas.max_alloc_size);
-        else
-           tex->pt = _pool_tex_find(gc, im->cache_entry.w + 2,
-                                    im->cache_entry.h + 1, rgba_ifmt, rgba_fmt,
-                                    &u, &v, &l_after,
-                                    gc->shared->info.tune.atlas.max_alloc_size);
-        tex->alpha = 1;
-     }
-   else
-     {
-        if (gc->shared->info.bgra)
-           tex->pt = _pool_tex_find(gc, im->cache_entry.w + 3,
-                                    im->cache_entry.h + 1, bgr_ifmt, bgr_fmt,
-                                    &u, &v, &l_after,
-                                    gc->shared->info.tune.atlas.max_alloc_size);
-        else
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-           tex->pt = _pool_tex_find(gc, im->cache_entry.w + 3,
-                                    im->cache_entry.h + 1, rgba_ifmt, rgba_fmt,
-                                    &u, &v, &l_after,
-                                    gc->shared->info.tune.atlas.max_alloc_size);
-#else
-           tex->pt = _pool_tex_find(gc, im->cache_entry.w + 3,
-                                    im->cache_entry.h + 1, rgb_ifmt, rgb_fmt,
-                                    &u, &v, &l_after,
-                                    gc->shared->info.tune.atlas.max_alloc_size);
-#endif
-     }
+   if (evas_gl_texture_rect_pool == 1)
+     tex->pt = _rectangle_pool_tex_find(gc, w, h,
+                             *matching_format[lformat].intformat,
+                             *matching_format[lformat].format,
+                             &u, &v, &l_after,
+                             gc->shared->info.tune.atlas.max_alloc_size, tex);
+    else
+       tex->pt = _pool_tex_find(gc, w, h,
+                             *matching_format[lformat].intformat,
+                             *matching_format[lformat].format,
+                             &u, &v, &l_after,
+                             gc->shared->info.tune.atlas.max_alloc_size,
+                             align4);
+
+   tex->alpha = im->cache_entry.flags.alpha;
    if (!tex->pt)
      {
         free(tex);
         return NULL;
      }
    tex->x = u + 1;
-   tex->y = v;
+   tex->y = v + yoffset;
    tex->w = im->cache_entry.w;
    tex->h = im->cache_entry.h;
    if (l_after)
@@ -349,6 +654,7 @@ evas_gl_common_texture_new(Evas_Engine_GL_Context *gc, RGBA_Image *im)
    else
      tex->pt->allocations =
      eina_list_prepend(tex->pt->allocations, tex);
+
    tex->pt->references++;
    evas_gl_common_texture_update(tex, im);
    return tex;
@@ -358,11 +664,19 @@ static Evas_GL_Texture_Pool *
 _pool_tex_render_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, int format)
 {
    Evas_GL_Texture_Pool *pt;
+   int fnum;
+   Eina_Bool ok;
 
+   if ((w > gc->shared->info.max_texture_size) ||
+       (h > gc->shared->info.max_texture_size))
+     {
+        ERR("Fail tex too big %ix%i", w, h);
+        return NULL;
+     }
    pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
    if (!pt) return NULL;
-   h = _tex_round_slot(gc, h) * gc->shared->info.tune.atlas.slot_size;
-   _tex_adjust(gc, &w, &h);
+   if (evas_gl_texture_rect_pool == 0)
+     _tex_adjust(gc, &w, &h);
    pt->gc = gc;
    pt->w = w;
    pt->h = h;
@@ -371,7 +685,12 @@ _pool_tex_render_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, in
    pt->dataformat = GL_UNSIGNED_BYTE;
    pt->render = 1;
    pt->references = 0;
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+   if (evas_gl_texture_rect_pool == 1)
+     {
+        pt->eina_pool = eina_rectangle_pool_new(w, h);
+        //eina_rectangle_pool_packing_set(pt->eina_pool, Eina_Packing_Ascending);
+     }
+#ifdef GL_GLES
 # ifndef GL_FRAMEBUFFER
 #  define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
 # endif
@@ -386,11 +705,7 @@ _pool_tex_render_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, in
 #  define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT
 # endif
 #endif
-   texinfo.r.num++;
-   texinfo.r.pix += pt->w * pt->h;
-
-   _print_tex_count();
-
+   glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fnum);
    glGenTextures(1, &(pt->texture));
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
    glBindTexture(GL_TEXTURE_2D, pt->texture);
@@ -403,7 +718,7 @@ _pool_tex_render_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, in
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   _tex_2d(pt->intformat, w, h, pt->format, pt->dataformat);
+   ok = _tex_2d(gc, pt->intformat, w, h, pt->format, pt->dataformat);
 
    glGenFramebuffers(1, &(pt->fb));
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
@@ -411,11 +726,41 @@ _pool_tex_render_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, in
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pt->texture, 0);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   glBindFramebuffer(GL_FRAMEBUFFER, 0);
+   glBindFramebuffer(GL_FRAMEBUFFER, fnum);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
 
-   glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+   if ( (gc->master_clip.enabled) &&
+        (gc->master_clip.w > 0) && (gc->master_clip.h > 0))
+     {
+        if (gc->master_clip.used)
+          {
+             int gw = gc->w;
+             int gh = gc->h;
+             evas_gl_common_tiling_start(gc, gc->rot, gw, gh,
+                                             gc->master_clip.x,
+                                             gh - gc->master_clip.y - gc->master_clip.h,
+                                             gc->master_clip.w, gc->master_clip.h,
+                                             gc->preserve_bit);
+          }
+     }
+
+
+   evas_gl_common_texture_shared_back(gc, pt);
+
+   if (!ok)
+     {
+        glDeleteTextures(1, &(pt->texture));
+        if (evas_gl_texture_rect_pool == 1)
+          if (pt->eina_pool)
+            eina_rectangle_pool_free(pt->eina_pool);
+        free(pt);
+        return NULL;
+     }
+
+   texinfo.r.num++;
+   texinfo.r.pix += pt->w * pt->h;
+   _print_tex_count();
    return pt;
 }
 
@@ -424,6 +769,12 @@ _pool_tex_native_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, in
 {
    Evas_GL_Texture_Pool *pt;
 
+   if ((w > gc->shared->info.max_texture_size) ||
+       (h > gc->shared->info.max_texture_size))
+     {
+        ERR("Fail tex too big %ix%i", w, h);
+        return NULL;
+     }
    pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
    if (!pt) return NULL;
    pt->gc = gc;
@@ -445,6 +796,11 @@ _pool_tex_native_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, in
    pt->format = format;
    pt->dataformat = GL_UNSIGNED_BYTE;
    pt->references = 0;
+   if (evas_gl_texture_rect_pool == 1)
+     {
+        pt->eina_pool = eina_rectangle_pool_new(w, h);
+        //eina_rectangle_pool_packing_set(pt->eina_pool, Eina_Packing_Ascending);
+     }
    pt->native = 1;
    texinfo.n.num++;
    texinfo.n.pix += pt->w * pt->h;
@@ -456,7 +812,7 @@ _pool_tex_native_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, in
    glBindTexture(im->native.target, pt->texture);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
 #else
    if (im->native.loose)
      {
@@ -475,8 +831,8 @@ _pool_tex_native_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, in
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
    glBindTexture(im->native.target, 0);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   glBindTexture(im->native.target, gc->pipe[0].shader.cur_tex);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+   evas_gl_common_texture_shared_back(gc, pt);
    return pt;
 }
 
@@ -485,38 +841,18 @@ _pool_tex_dynamic_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, i
 {
    Evas_GL_Texture_Pool *pt = NULL;
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   int fmt; // EGL_MAP_GL_TEXTURE_RGBA_SEC or EGL_MAP_GL_TEXTURE_RGB_SEC or bust
-   int pixtype; // EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC or bust
-   int attr[] =
-     {
-        EGL_MAP_GL_TEXTURE_WIDTH_SEC, 32,
-        EGL_MAP_GL_TEXTURE_HEIGHT_SEC, 32,
-        EGL_MAP_GL_TEXTURE_FORMAT_SEC, EGL_MAP_GL_TEXTURE_RGBA_SEC,
-        EGL_MAP_GL_TEXTURE_PIXEL_TYPE_SEC, EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC,
-        EGL_NONE
-     };
+#ifdef GL_GLES
    void *egldisplay;
 
    if (intformat != format) return NULL;
 
-   switch (intformat)
-     {
-#ifdef EGL_MAP_GL_TEXTURE_LUMINANCE_SEC
-     case GL_LUMINANCE: attr[5] = EGL_MAP_GL_TEXTURE_LUMINANCE_SEC; break;
-#endif
-#ifdef EGL_MAP_GL_TEXTURE_LUMINANCE_ALPHA_SEC
-     case GL_LUMINANCE_ALPHA: attr[5] = EGL_MAP_GL_TEXTURE_LUMINANCE_ALPHA_SEC; break;
-#endif
-     case GL_RGBA: attr[5] = EGL_MAP_GL_TEXTURE_RGBA_SEC; break;
-     case GL_BGRA: attr[5] = EGL_MAP_GL_TEXTURE_BGRA_SEC; break;
-     default: fprintf(stderr, "unknown format\n"); return NULL;
-     }
-
    pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
    if (!pt) return NULL;
-   h = _tex_round_slot(gc, h) * gc->shared->info.tune.atlas.slot_size;
-   _tex_adjust(gc, &w, &h);
+   if (evas_gl_texture_rect_pool == 0)
+      {
+         h = _tex_round_slot(gc, h) * gc->shared->info.tune.atlas.slot_size;
+         _tex_adjust(gc, &w, &h);
+      }
    pt->gc = gc;
    pt->w = w;
    pt->h = h;
@@ -525,6 +861,11 @@ _pool_tex_dynamic_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, i
    pt->dataformat = GL_UNSIGNED_BYTE;
    pt->render = 1;
    pt->references = 0;
+   if (evas_gl_texture_rect_pool == 1)
+     {
+        pt->eina_pool = eina_rectangle_pool_new(w, h);
+        //eina_rectangle_pool_packing_set(pt->eina_pool, Eina_Packing_Ascending);
+     }
    texinfo.d.num++;
    texinfo.d.pix += pt->w * pt->h;
 
@@ -545,51 +886,115 @@ _pool_tex_dynamic_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, i
 
    egldisplay = pt->gc->egldisp;
 
-   attr[1] = pt->w;
-   attr[3] = pt->h;
+   if (gc->shared->info.sec_tbm_surface)
+     {
+        int attr[] =
+          {
+             EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
+             EGL_NONE,
+          };
 
-   // FIXME: seems a bit slower than i'd like - maybe too many flushes?
-   // FIXME: YCbCr no support as yet
-   pt->dyn.img = secsym_eglCreateImage(egldisplay,
-                                       EGL_NO_CONTEXT,
-                                       EGL_MAP_GL_TEXTURE_2D_SEC,
-                                       0, attr);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   if (!pt->dyn.img)
+        tbm_format buffer_format = TBM_FORMAT_RGBA8888;
+        switch (intformat)
+          {
+          case GL_LUMINANCE: buffer_format = TBM_FORMAT_C8; break;
+          case GL_LUMINANCE_ALPHA: buffer_format = TBM_FORMAT_C8; break;
+          case GL_RGBA: buffer_format = TBM_FORMAT_RGBA8888; break;
+          case GL_BGRA: buffer_format = TBM_FORMAT_BGRA8888; break;
+          case GL_RGB: buffer_format = TBM_FORMAT_RGB888; break;
+          default: fprintf(stderr, "unknown format\n"); goto error;
+          }
+
+        pt->dyn.buffer = (void *)secsym_tbm_surface_create(pt->w,
+                                                    pt->h,
+                                                    buffer_format);
+        if (!pt->dyn.buffer) goto error;
+
+        pt->dyn.img = secsym_eglCreateImage(egldisplay,
+                                            EGL_NO_CONTEXT,
+                                            EGL_NATIVE_SURFACE_TIZEN,
+                                            pt->dyn.buffer, attr);
+        if (!pt->dyn.img)
+          {
+             secsym_tbm_surface_destroy(pt->dyn.buffer);
+             goto error;
+          }
+        tbm_surface_info_s info;
+        secsym_tbm_surface_get_info(pt->dyn.buffer, &info);
+        pt->dyn.w = info.width;
+        pt->dyn.h = info.height;
+        pt->dyn.stride = info.planes[0].stride;
+     }
+   else if (gc->shared->info.sec_image_map)
      {
-        glBindTexture(GL_TEXTURE_2D, 0);
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-        glDeleteTextures(1, &(pt->texture));
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-        free(pt);
-        return NULL;
+        int fmt; // EGL_MAP_GL_TEXTURE_RGBA_SEC or EGL_MAP_GL_TEXTURE_RGB_SEC or bust
+        int pixtype; // EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC or bust
+
+        int attr[] =
+          {
+             EGL_MAP_GL_TEXTURE_WIDTH_SEC, 32,
+             EGL_MAP_GL_TEXTURE_HEIGHT_SEC, 32,
+             EGL_MAP_GL_TEXTURE_FORMAT_SEC, EGL_MAP_GL_TEXTURE_RGBA_SEC,
+             EGL_MAP_GL_TEXTURE_PIXEL_TYPE_SEC, EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC,
+             EGL_NONE
+          };
+
+        switch (intformat)
+          {
+#ifdef EGL_MAP_GL_TEXTURE_LUMINANCE_SEC
+          case GL_LUMINANCE: attr[5] = EGL_MAP_GL_TEXTURE_LUMINANCE_SEC; break;
+#endif
+#ifdef EGL_MAP_GL_TEXTURE_LUMINANCE_ALPHA_SEC
+          case GL_LUMINANCE_ALPHA: attr[5] = EGL_MAP_GL_TEXTURE_LUMINANCE_ALPHA_SEC; break;
+#endif
+          case GL_RGBA: attr[5] = EGL_MAP_GL_TEXTURE_RGBA_SEC; break;
+          case GL_BGRA: attr[5] = EGL_MAP_GL_TEXTURE_BGRA_SEC; break;
+          default: fprintf(stderr, "unknown format\n"); goto error;
+          }
+
+        attr[1] = pt->w;
+        attr[3] = pt->h;
+
+        // FIXME: seems a bit slower than i'd like - maybe too many flushes?
+        // FIXME: YCbCr no support as yet
+        pt->dyn.img = secsym_eglCreateImage(egldisplay,
+                                            EGL_NO_CONTEXT,
+                                            EGL_MAP_GL_TEXTURE_2D_SEC,
+                                            0, attr);
+        if (!pt->dyn.img) goto error;
+
+        if (secsym_eglGetImageAttribSEC(egldisplay,
+                                        pt->dyn.img,
+                                        EGL_MAP_GL_TEXTURE_WIDTH_SEC,
+                                        &(pt->dyn.w)) != EGL_TRUE) goto error;
+        if (secsym_eglGetImageAttribSEC(egldisplay,
+                                        pt->dyn.img,
+                                        EGL_MAP_GL_TEXTURE_HEIGHT_SEC,
+                                        &(pt->dyn.h)) != EGL_TRUE) goto error;
+        if (secsym_eglGetImageAttribSEC(egldisplay,
+                                        pt->dyn.img,
+                                        EGL_MAP_GL_TEXTURE_STRIDE_IN_BYTES_SEC,
+                                        &(pt->dyn.stride)) != EGL_TRUE) goto error;
+        if (secsym_eglGetImageAttribSEC(egldisplay,
+                                        pt->dyn.img,
+                                        EGL_MAP_GL_TEXTURE_FORMAT_SEC,
+                                        &(fmt)) != EGL_TRUE) goto error;
+
+        if (secsym_eglGetImageAttribSEC(egldisplay,
+                                        pt->dyn.img,
+                                        EGL_MAP_GL_TEXTURE_PIXEL_TYPE_SEC,
+                                        &(pixtype)) != EGL_TRUE) goto error;
+
+        if (pixtype != EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC) goto error;
      }
-   if (secsym_eglGetImageAttribSEC(egldisplay,
-                                   pt->dyn.img,
-                                   EGL_MAP_GL_TEXTURE_WIDTH_SEC,
-                                   &(pt->dyn.w)) != EGL_TRUE) goto error;
-   if (secsym_eglGetImageAttribSEC(egldisplay,
-                                   pt->dyn.img,
-                                   EGL_MAP_GL_TEXTURE_HEIGHT_SEC,
-                                   &(pt->dyn.h)) != EGL_TRUE) goto error;
-   if (secsym_eglGetImageAttribSEC(egldisplay,
-                                   pt->dyn.img,
-                                   EGL_MAP_GL_TEXTURE_STRIDE_IN_BYTES_SEC,
-                                   &(pt->dyn.stride)) != EGL_TRUE) goto error;
-   if (secsym_eglGetImageAttribSEC(egldisplay,
-                                   pt->dyn.img,
-                                   EGL_MAP_GL_TEXTURE_FORMAT_SEC,
-                                   &(fmt)) != EGL_TRUE) goto error;
-
-   if (secsym_eglGetImageAttribSEC(egldisplay,
-                                   pt->dyn.img,
-                                   EGL_MAP_GL_TEXTURE_PIXEL_TYPE_SEC,
-                                   &(pixtype)) != EGL_TRUE) goto error;
-
-   if (pixtype != EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC) goto error;
-
-   glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   else
+     {
+        ERR("TBM surface or SEC image map should be enabled!");
+        goto error;
+     }
+
+   evas_gl_common_texture_shared_back(gc, pt);
+
 #else
    gc = NULL;
    w = 0;
@@ -600,18 +1005,24 @@ _pool_tex_dynamic_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, i
    return pt;
 
 /* ERROR HANDLING */
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
 error:
-  secsym_eglDestroyImage(egldisplay, pt->dyn.img);
-  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-  pt->dyn.img = NULL;
+  if (pt->dyn.img)
+    {
+       secsym_eglDestroyImage(egldisplay, pt->dyn.img);
+       GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+       pt->dyn.img = NULL;
+    }
   glBindTexture(GL_TEXTURE_2D, 0);
   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
   glDeleteTextures(1, &(pt->texture));
   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+  if (evas_gl_texture_rect_pool == 1)
+    if (pt->eina_pool)
+      eina_rectangle_pool_free(pt->eina_pool);
   free(pt);
   return NULL;
-#endif   
+#endif
 }
 
 void
@@ -619,6 +1030,9 @@ evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt)
 {
    if (!pt->gc) return;
 
+   int eina_rect_pool_w = 0;
+   int eina_rect_pool_h = 0;
+
    if (pt->format == alpha_fmt)
       {
          texinfo.a.num--;
@@ -652,13 +1066,21 @@ evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt)
 
    _print_tex_count();
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
    if (pt->dyn.img)
      {
         if (pt->dyn.checked_out > 0)
-          secsym_eglUnmapImageSEC(pt->gc->egldisp, pt->dyn.img);
+          {
+             if (pt->gc->shared->info.sec_tbm_surface)
+               secsym_tbm_surface_unmap(pt->dyn.buffer);
+             else if (pt->gc->shared->info.sec_image_map)
+               secsym_eglUnmapImageSEC(pt->gc->egldisp, pt->dyn.img, EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC);
+          }
+        if (pt->dyn.buffer)
+          secsym_tbm_surface_destroy(pt->dyn.buffer);
         secsym_eglDestroyImage(pt->gc->egldisp, pt->dyn.img);
         pt->dyn.img = NULL;
+        pt->dyn.buffer = NULL;
         pt->dyn.data = NULL;
         pt->dyn.w = 0;
         pt->dyn.h = 0;
@@ -669,15 +1091,26 @@ evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt)
 
    glDeleteTextures(1, &(pt->texture));
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   if (pt->gc->pipe[0].shader.cur_tex == pt->texture)
+     {
+        pt->gc->pipe[0].shader.cur_tex = 0;
+     }
    if (pt->fb)
      {
         glDeleteFramebuffers(1, &(pt->fb));
         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
         pt->fb = 0;
      }
-   while (pt->allocations)
-      pt->allocations =
-      eina_list_remove_list(pt->allocations, pt->allocations);
+   pt->allocations = eina_list_free(pt->allocations);
+   //Free the Eina_rect_pool and create new one
+   if (evas_gl_texture_rect_pool == 1)
+     {
+        eina_rectangle_pool_geometry_get(pt->eina_pool, &eina_rect_pool_w, &eina_rect_pool_h);
+        if (pt->eina_pool)
+          eina_rectangle_pool_free(pt->eina_pool);
+        pt->eina_pool = eina_rectangle_pool_new(eina_rect_pool_w, eina_rect_pool_h);
+     }
+
    pt->texture = 0;
    pt->gc = NULL;
    pt->w = 0;
@@ -702,6 +1135,9 @@ pt_unref(Evas_GL_Texture_Pool *pt)
            eina_list_remove(pt->gc->shared->tex.atlas[pt->slot][pt->fslot], pt);
      }
    evas_gl_texture_pool_empty(pt);
+   if (evas_gl_texture_rect_pool == 1)
+     if (pt->eina_pool)
+       eina_rectangle_pool_free(pt->eina_pool);
    free(pt);
 }
 
@@ -720,27 +1156,19 @@ Evas_GL_Texture *
 evas_gl_common_texture_native_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, Evas_GL_Image *im)
 {
    Evas_GL_Texture *tex;
+   int lformat;
 
    tex = calloc(1, sizeof(Evas_GL_Texture));
    if (!tex) return NULL;
 
    tex->gc = gc;
-   tex->references = 1;
-   tex->alpha = alpha;
-   if (alpha)
-     {
-        if (gc->shared->info.bgra)
-          tex->pt = _pool_tex_native_new(gc, w, h, rgba_ifmt, rgba_fmt, im);
-        else
-          tex->pt = _pool_tex_native_new(gc, w, h, rgba_ifmt, rgba_fmt, im);
-     }
-   else
-     {
-        if (gc->shared->info.bgra)
-          tex->pt = _pool_tex_native_new(gc, w, h, rgb_ifmt, rgb_fmt, im);
-        else
-          tex->pt = _pool_tex_native_new(gc, w, h, rgb_ifmt, rgb_fmt, im);
-     }
+   tex->references = 1;
+   tex->alpha = alpha;
+   lformat = _evas_gl_texture_search_format(alpha, gc->shared->info.bgra, EVAS_COLORSPACE_ARGB8888);
+   tex->pt = _pool_tex_native_new(gc, w, h,
+                                  *matching_format[lformat].intformat,
+                                  *matching_format[lformat].format,
+                                  im);
    if (!tex->pt)
      {
         free(tex);
@@ -758,6 +1186,7 @@ Evas_GL_Texture *
 evas_gl_common_texture_render_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha)
 {
    Evas_GL_Texture *tex;
+   int lformat;
 
    tex = calloc(1, sizeof(Evas_GL_Texture));
    if (!tex) return NULL;
@@ -765,20 +1194,10 @@ evas_gl_common_texture_render_new(Evas_Engine_GL_Context *gc, unsigned int w, un
    tex->gc = gc;
    tex->references = 1;
    tex->alpha = alpha;
-   if (alpha)
-     {
-        if (gc->shared->info.bgra)
-          tex->pt = _pool_tex_render_new(gc, w, h, rgba_ifmt, rgba_fmt);
-        else
-          tex->pt = _pool_tex_render_new(gc, w, h, rgba_ifmt, rgba_fmt);
-     }
-   else
-     {
-        if (gc->shared->info.bgra)
-          tex->pt = _pool_tex_render_new(gc, w, h, rgb_ifmt, rgb_fmt);
-        else
-          tex->pt = _pool_tex_render_new(gc, w, h, rgb_ifmt, rgb_fmt);
-     }
+   lformat = _evas_gl_texture_search_format(alpha, gc->shared->info.bgra, EVAS_COLORSPACE_ARGB8888);
+   tex->pt = _pool_tex_render_new(gc, w, h,
+                                  *matching_format[lformat].intformat,
+                                  *matching_format[lformat].format);
    if (!tex->pt)
      {
         free(tex);
@@ -796,6 +1215,7 @@ Evas_GL_Texture *
 evas_gl_common_texture_dynamic_new(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
 {
    Evas_GL_Texture *tex;
+   int lformat;
 
    tex = calloc(1, sizeof(Evas_GL_Texture));
    if (!tex) return NULL;
@@ -807,20 +1227,10 @@ evas_gl_common_texture_dynamic_new(Evas_Engine_GL_Context *gc, Evas_GL_Image *im
    tex->y = 0;
    tex->w = im->w;
    tex->h = im->h;
-   if (tex->alpha)
-     {
-        if (gc->shared->info.bgra)
-          tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h, bgra_ifmt, bgra_fmt);
-        else
-          tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h, bgra_ifmt, bgra_fmt);
-     }
-   else
-     {
-        if (gc->shared->info.bgra)
-          tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h, bgra_ifmt, bgra_fmt);
-        else
-          tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h, bgra_ifmt, bgra_fmt);
-     }
+   lformat = _evas_gl_texture_search_format(tex->alpha, gc->shared->info.bgra, EVAS_COLORSPACE_ARGB8888);
+   tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h,
+                                  *matching_format[lformat].intformat,
+                                  *matching_format[lformat].format);
    if (!tex->pt)
      {
         free(tex);
@@ -833,37 +1243,112 @@ evas_gl_common_texture_dynamic_new(Evas_Engine_GL_Context *gc, Evas_GL_Image *im
 void
 evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
 {
+   unsigned int bytes_count, bsize = 8;
    GLuint fmt;
 
    if (tex->alpha != im->cache_entry.flags.alpha)
      {
+        int lformat;
+
+        lformat = _evas_gl_texture_search_format(im->cache_entry.flags.alpha, tex->gc->shared->info.bgra, im->cache_entry.space);
+        if (lformat < 0) return;
+
         tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex);
         pt_unref(tex->pt);
         tex->alpha = im->cache_entry.flags.alpha;
-        if (tex->alpha)
-          {
-             if (tex->gc->shared->info.bgra)
-               tex->pt = _pool_tex_render_new(tex->gc, tex->w, tex->h, bgra_ifmt, bgra_fmt);
-             else
-               tex->pt = _pool_tex_render_new(tex->gc, tex->w, tex->h, rgba_ifmt, rgba_fmt);
-          }
-        else
-          {
-             if (tex->gc->shared->info.bgra)
-               tex->pt = _pool_tex_render_new(tex->gc, tex->w, tex->h, bgr_ifmt, bgr_fmt);
-             else
-               tex->pt = _pool_tex_render_new(tex->gc, tex->w, tex->h, rgb_ifmt, rgb_fmt);
-          }
+
+        // FIXME: why a 'render' new here ??? Should already have been allocated, quite a weird path.
+        tex->pt = _pool_tex_render_new(tex->gc, tex->w, tex->h,
+                                       *matching_format[lformat].intformat,
+                                       *matching_format[lformat].format);
      }
    if (!tex->pt) return;
    if (!im->image.data) return;
 
+   switch (im->cache_entry.space)
+     {
+      case EVAS_COLORSPACE_ARGB8888: bytes_count = 4; break;
+      case EVAS_COLORSPACE_GRY8: bytes_count = 1; break;
+      case EVAS_COLORSPACE_AGRY88: bytes_count = 2; break;
+      case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+        bsize = 16;
+        // fallthrough
+      case EVAS_COLORSPACE_ETC1:
+      case EVAS_COLORSPACE_RGB8_ETC2:
+        {
+           GLsizei width, height;
+           GLint x, y;
+
+           x = tex->x - 1;
+           y = tex->y - 1;
+           width = im->cache_entry.w + 2;
+           height = im->cache_entry.h + 2;
+           width = ((width >> 2) + (width & 0x3 ? 1 : 0)) << 2;
+           height = ((height >> 2) + (height & 0x3 ? 1 : 0)) << 2;
+
+           glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
+           GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+           if ((tex->gc->shared->info.etc1_subimage ||
+                (im->cache_entry.space != EVAS_COLORSPACE_ETC1))
+               && (tex->pt->w != width || tex->pt->h != height))
+             {
+                int err;
+                err = glGetError();
+
+                glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
+                                          x, y, width, height,
+                                          tex->pt->format,
+                                          ((width * height) >> 4) * bsize,
+                                          im->image.data);
+
+                err = glGetError();
+                if (err != GL_NO_ERROR)
+                  {
+                     glerr(err, __FILE__, __FUNCTION__, __LINE__, "glCompressedTexSubImage2D");
+
+                     // FIXME: Changing settings on the fly.
+                     // The first texture will be black.
+                     // How to fallback? We need a whole texture now.
+                     if (im->cache_entry.space == EVAS_COLORSPACE_ETC1)
+                       tex->gc->shared->info.etc1_subimage = EINA_FALSE;
+                  }
+             }
+           else
+             {
+                glCompressedTexImage2D(GL_TEXTURE_2D, 0, tex->pt->format,
+                                       width, height, 0,
+                                       ((width * height) >> 4) * bsize,
+                                       im->image.data);
+                GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+             }
+
+           if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
+             {
+                glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
+                GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+             }
+
+           return;
+        }
+      case EVAS_COLORSPACE_ETC1_ALPHA:
+        // One must call evas_gl_common_texture_rgb_a_pair_update() instead.
+        ERR("Can't upload ETC1+Alpha texture as a normal texture. Abort.");
+        return;
+      default:
+        ERR("Can't upload texture in colorspace %i.", im->cache_entry.space);
+        return;
+     }
+
    fmt = tex->pt->format;
    glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
 #ifdef GL_UNPACK_ROW_LENGTH
-   glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   if (tex->gc->shared->info.unpack_row_length)
+     {
+        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+     }
 #endif
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
@@ -875,58 +1360,92 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
    _tex_sub_2d(tex->x, tex->y,
                im->cache_entry.w, im->cache_entry.h,
                fmt, tex->pt->dataformat,
-               im->image.data);
+               im->image.data8);
    //  xxx
    //  xxx
    //  ---
    _tex_sub_2d(tex->x, tex->y + im->cache_entry.h,
                im->cache_entry.w, 1,
                fmt, tex->pt->dataformat,
-               im->image.data + ((im->cache_entry.h - 1) * im->cache_entry.w));
+               im->image.data8 + ((im->cache_entry.h - 1) * im->cache_entry.w * bytes_count));
    //  xxx
    //  xxx
    // o
    _tex_sub_2d(tex->x - 1, tex->y + im->cache_entry.h,
                1, 1,
                fmt, tex->pt->dataformat,
-               im->image.data + ((im->cache_entry.h - 1) * im->cache_entry.w));
+               im->image.data8 + ((im->cache_entry.h - 1) * im->cache_entry.w * bytes_count));
    //  xxx
    //  xxx
    //     o
    _tex_sub_2d(tex->x + im->cache_entry.w, tex->y + im->cache_entry.h,
                1, 1,
                fmt, tex->pt->dataformat,
-               im->image.data + ((im->cache_entry.h - 1) * im->cache_entry.w) + (im->cache_entry.w - 1));
-#ifdef GL_UNPACK_ROW_LENGTH
-   glPixelStorei(GL_UNPACK_ROW_LENGTH, im->cache_entry.w);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   // |xxx
-   // |xxx
-   //
-   _tex_sub_2d(tex->x - 1, tex->y,
-               1, im->cache_entry.h,
+               im->image.data8 + (((im->cache_entry.h - 1) * im->cache_entry.w) + (im->cache_entry.w - 1)) * bytes_count);
+
+   if (evas_gl_texture_rect_pool == 1)
+     {
+        //2D packing
+
+        // ---
+        // xxx
+        // xxx
+        _tex_sub_2d(tex->x, tex->y - 1,
+               im->cache_entry.w, 1,
                fmt, tex->pt->dataformat,
-               im->image.data);
-   //  xxx|
-   //  xxx|
-   //
-   _tex_sub_2d(tex->x + im->cache_entry.w, tex->y,
-               1, im->cache_entry.h,
+               im->image.data8);
+
+        // o
+        //  xxx
+        //  xxx
+        _tex_sub_2d(tex->x - 1, tex->y - 1,
+               1, 1,
                fmt, tex->pt->dataformat,
-               im->image.data + (im->cache_entry.w - 1));
-#else
+               im->image.data8);
+
+        //    o
+        // xxx
+        // xxx
+        _tex_sub_2d(tex->x + im->cache_entry.w, tex->y - 1,
+               1, 1,
+               fmt, tex->pt->dataformat,
+               im->image.data8 + (im->cache_entry.w - 1) * bytes_count);
+     }
+
+#ifdef GL_UNPACK_ROW_LENGTH
+   if (tex->gc->shared->info.unpack_row_length)
+     {
+        glPixelStorei(GL_UNPACK_ROW_LENGTH, im->cache_entry.w);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        // |xxx
+        // |xxx
+        //
+        _tex_sub_2d(tex->x - 1, tex->y,
+                    1, im->cache_entry.h,
+                    fmt, tex->pt->dataformat,
+                    im->image.data8);
+        //  xxx|
+        //  xxx|
+        //
+        _tex_sub_2d(tex->x + im->cache_entry.w, tex->y,
+                    1, im->cache_entry.h,
+                    fmt, tex->pt->dataformat,
+                    im->image.data8 + (im->cache_entry.w - 1) * bytes_count);
+     }
+   else
+#endif
      {
-        DATA32 *tpix, *ps, *pd;
+        DATA8 *tpix, *ps, *pd;
         int i;
-        
-        tpix = alloca(im->cache_entry.h * sizeof(DATA32));
+
+        tpix = alloca(im->cache_entry.h * bytes_count);
         pd = tpix;
-        ps = im->image.data;
+        ps = im->image.data8;
         for (i = 0; i < (int)im->cache_entry.h; i++)
           {
-             *pd = *ps;
-             pd++;
-             ps += im->cache_entry.w;
+             memcpy(pd, ps, bytes_count);
+             pd += bytes_count;
+             ps += im->cache_entry.w * bytes_count;
           }
         // |xxx
         // |xxx
@@ -936,12 +1455,12 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
                     fmt, tex->pt->dataformat,
                     tpix);
         pd = tpix;
-        ps = im->image.data + (im->cache_entry.w - 1);
+        ps = im->image.data8 + (im->cache_entry.w - 1) * bytes_count;
         for (i = 0; i < (int)im->cache_entry.h; i++)
           {
-             *pd = *ps;
-             pd++;
-             ps += im->cache_entry.w;
+             memcpy(pd, ps, bytes_count);
+             pd += bytes_count;
+             ps += im->cache_entry.w * bytes_count;
           }
         //  xxx|
         //  xxx|
@@ -951,12 +1470,7 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
                     fmt, tex->pt->dataformat,
                     tpix);
      }
-#endif
-   if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
-     {
-        glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-     }
+   evas_gl_common_texture_shared_back(tex->gc, tex->pt);
 }
 
 void
@@ -965,6 +1479,12 @@ evas_gl_common_texture_free(Evas_GL_Texture *tex)
    if (!tex) return;
    tex->references--;
    if (tex->references != 0) return;
+   if (tex->fglyph && tex->gc)
+     {
+        tex->gc->font_glyph_textures = eina_list_remove(tex->gc->font_glyph_textures, tex);
+        tex->fglyph->ext_dat = NULL;
+        tex->fglyph->ext_dat_free = NULL;
+     }
    if (tex->double_buffer.pt[0])
      {
         tex->double_buffer.pt[0]->allocations = eina_list_remove(tex->double_buffer.pt[0]->allocations, tex);
@@ -977,21 +1497,33 @@ evas_gl_common_texture_free(Evas_GL_Texture *tex)
         if (tex->pt)
           {
              tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex);
+             if (evas_gl_texture_rect_pool == 1)
+               if (tex->rect)
+                 eina_rectangle_pool_release(tex->rect);
              pt_unref(tex->pt);
           }
         if (tex->ptu)
           {
              tex->ptu->allocations = eina_list_remove(tex->ptu->allocations, tex);
+             if (evas_gl_texture_rect_pool == 1)
+               if (tex->rect)
+                 eina_rectangle_pool_release(tex->rect);
              pt_unref(tex->ptu);
           }
         if (tex->ptv)
           {
              tex->ptv->allocations = eina_list_remove(tex->ptv->allocations, tex);
+             if (evas_gl_texture_rect_pool == 1)
+               if (tex->rect)
+                 eina_rectangle_pool_release(tex->rect);
              pt_unref(tex->ptv);
           }
         if (tex->ptuv)
           {
              tex->ptuv->allocations = eina_list_remove(tex->ptuv->allocations, tex);
+             if (evas_gl_texture_rect_pool == 1)
+               if (tex->rect)
+                 eina_rectangle_pool_release(tex->rect);
              pt_unref(tex->ptuv);
           }
      }
@@ -1009,11 +1541,25 @@ evas_gl_common_texture_alpha_new(Evas_Engine_GL_Context *gc, DATA8 *pixels,
    tex = calloc(1, sizeof(Evas_GL_Texture));
    if (!tex) return NULL;
 
+   if (evas_gl_texture_rect_pool == -1)
+     {
+        if (getenv("EVAS_GL_TEXTURE_RECT_POOL_DISABLE"))
+          evas_gl_texture_rect_pool = 0;
+        else
+          evas_gl_texture_rect_pool = 1;
+     }
+
    tex->gc = gc;
    tex->references = 1;
-   tex->pt = _pool_tex_find(gc, w + 3, fh, alpha_ifmt, alpha_fmt, &u, &v,
+   if (evas_gl_texture_rect_pool == 1)
+     tex->pt = _rectangle_pool_tex_find(gc, w + 3, fh, alpha_ifmt, alpha_fmt, &u, &v,
+                            &l_after,
+                            gc->shared->info.tune.atlas.max_alloc_alpha_size, tex);
+   else
+     tex->pt = _pool_tex_find(gc, w + 3, fh, alpha_ifmt, alpha_fmt, &u, &v,
                             &l_after,
-                            gc->shared->info.tune.atlas.max_alloc_alpha_size);
+                            gc->shared->info.tune.atlas.max_alloc_alpha_size,
+                            EINA_FALSE);
    if (!tex->pt)
      {
         free(tex);
@@ -1041,18 +1587,206 @@ evas_gl_common_texture_alpha_update(Evas_GL_Texture *tex, DATA8 *pixels,
    glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
 #ifdef GL_UNPACK_ROW_LENGTH
-   glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   if (tex->gc->shared->info.unpack_row_length)
+     {
+        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+     }
 #endif
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
    _tex_sub_2d(tex->x, tex->y, w, h, tex->pt->format, tex->pt->dataformat,
                pixels);
-   if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
+
+   evas_gl_common_texture_shared_back(tex->gc, tex->pt);
+}
+
+Evas_GL_Texture *
+evas_gl_common_texture_rgb_a_pair_new(Evas_Engine_GL_Context *gc,
+                                      RGBA_Image *im)
+{
+   Evas_GL_Texture *tex;
+   int lformat, w, h, tw, th, top = 0, left = 0;
+
+   if (im->cache_entry.space != EVAS_COLORSPACE_ETC1_ALPHA)
+     WRN("Using RGB+A texture pair with format %d", im->cache_entry.space);
+
+   tw = w = im->cache_entry.w;
+   th = h = im->cache_entry.h;
+
+   if (((int) im->cache_entry.space >= (int) EVAS_COLORSPACE_ETC1) &&
+       ((int) im->cache_entry.space <= (int) EVAS_COLORSPACE_ETC1_ALPHA))
      {
-        glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        // Add 1 pixel borders and align to 4x4
+        tw = (w + 2 + 3) & ~0x3;
+        th = (h + 2 + 3) & ~0x3;
+        top = 1;
+        left = 1;
+     }
+
+   lformat = _evas_gl_texture_search_format(EINA_TRUE, gc->shared->info.bgra,
+                                            im->cache_entry.space);
+   if (lformat < 0) return NULL;
+
+   tex = calloc(1, sizeof(Evas_GL_Texture));
+   if (!tex) return NULL;
+
+   tex->gc = gc;
+   tex->references = 1;
+   tex->alpha = EINA_TRUE;
+   tex->w = w;
+   tex->h = h;
+   tex->x = left;
+   tex->y = top;
+
+   // Allocate RGB texture normally - as a 'whole'
+   tex->pt = _pool_tex_new(gc, tw, th,
+                           *matching_format[lformat].intformat,
+                           *matching_format[lformat].format);
+   if (!tex->pt)
+     {
+        free(tex);
+        return NULL;
+     }
+   pt_link(gc, tex, tex->pt);
+
+   // And now Alpha texture -- FIXME could intformat be different? (eg. ALPHA4)
+   tex->pta = _pool_tex_new(gc, tw, th,
+                            *matching_format[lformat].intformat,
+                            *matching_format[lformat].format);
+   if (!tex->pta)
+     {
+        pt_unref(tex->pt);
+        free(tex);
+        return NULL;
+     }
+   pt_link(gc, tex, tex->pta);
+
+   evas_gl_common_texture_rgb_a_pair_update(tex, im);
+   return tex;
+}
+
+void
+evas_gl_common_texture_rgb_a_pair_update(Evas_GL_Texture *tex,
+                                         RGBA_Image *im)
+{
+   DATA8 *data1, *data2;
+   Eina_Bool comp, upload, subimage = EINA_TRUE;
+   int w, h, sz, rowlen, ystep = 1, align = 1, borders = 0;
+
+   if (!tex->pt) return;
+
+   // Handle compressed formats with 4x4 blocks format
+   if (((int) im->cache_entry.space >= (int) EVAS_COLORSPACE_ETC1) &&
+       ((int) im->cache_entry.space <= (int) EVAS_COLORSPACE_ETC1_ALPHA))
+     {
+        ystep = 4;
+        align = 4;
+        borders = 2;
+     }
+
+   if ((im->cache_entry.space == EVAS_COLORSPACE_ETC1) ||
+       (im->cache_entry.space == EVAS_COLORSPACE_ETC1_ALPHA))
+     subimage = tex->gc->shared->info.etc1_subimage;
+
+   w = (im->cache_entry.w + borders + align - 1) & (~(align - 1));
+   h = (im->cache_entry.h + borders + align - 1) & (~(align - 1));
+   rowlen = _evas_gl_texture_size_get(w, ystep, tex->pt->intformat, NULL);
+   sz = _evas_gl_texture_size_get(w, h, tex->pt->intformat, &comp);
+   data1 = im->image.data8;
+   data2 = data1 + sz;
+   upload = !!data1;
+
+   if ((w == tex->pt->w) && (h == tex->pt->h))
+     subimage = EINA_FALSE;
+
+   if (!subimage || tex->gc->shared->info.unpack_row_length)
+     {
+        if (tex->gc->shared->info.unpack_row_length)
+          {
+             glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, w); GLERRLOG();
+          }
+        glPixelStorei(GL_UNPACK_ALIGNMENT, 1); GLERRLOG();
+        glBindTexture(GL_TEXTURE_2D, tex->pt->texture); GLERRLOG();
+        if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat))
+          goto on_error;
+        if (upload)
+          {
+             if (comp)
+               glCompressedTexImage2D(GL_TEXTURE_2D, 0, tex->pt->intformat, w, h, 0, sz, data1);
+             else
+               _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, data1);
+          }
+        glBindTexture(GL_TEXTURE_2D, tex->pta->texture); GLERRLOG();
+        if (!_tex_2d(tex->gc, tex->pta->intformat, w, h, tex->pta->format, tex->pta->dataformat))
+          goto on_error;
+        if (upload)
+          {
+             if (comp)
+               glCompressedTexImage2D(GL_TEXTURE_2D, 0, tex->pta->intformat, w, h, 0, sz, data2);
+             else
+               _tex_sub_2d(0, 0, w, h, tex->pta->format, tex->pta->dataformat, data2);
+          }
+     }
+   else
+     {
+        int y;
+
+        glPixelStorei(GL_UNPACK_ALIGNMENT, 1); GLERRLOG();
+        glBindTexture(GL_TEXTURE_2D, tex->pt->texture); GLERRLOG();
+        if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format,
+                     tex->pt->dataformat))
+          goto on_error;
+        if (upload)
+          {
+             if (w == tex->w)
+               {
+                  if (comp)
+                    _comp_tex_sub_2d(0, 0, w, h, tex->pt->format, sz, data1);
+                  else
+                    _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, data1);
+               }
+             else
+               {
+                  for (y = 0; y < h; y += ystep)
+                    {
+                       if (comp)
+                         _comp_tex_sub_2d(0, 0, w, h, tex->pt->format, sz, data1);
+                       else
+                         _tex_sub_2d(0, y, w, ystep, tex->pt->format,
+                                     tex->pt->dataformat, data1 + rowlen * y / ystep);
+                    }
+               }
+          }
+
+        glBindTexture(GL_TEXTURE_2D, tex->pta->texture); GLERRLOG();
+        if (!_tex_2d(tex->gc, tex->pta->intformat, w, h, tex->pta->format,
+                     tex->pta->dataformat))
+          goto on_error;
+        if (upload)
+          {
+             if (w == tex->w)
+               {
+                  if (comp)
+                    _comp_tex_sub_2d(0, 0, w, h, tex->pta->format, sz, data2);
+                  else
+                    _tex_sub_2d(0, 0, w, h, tex->pta->format, tex->pta->dataformat, data2);
+               }
+             else
+               {
+                  for (y = 0; y < h; y += ystep)
+                    {
+                       if (comp)
+                         _comp_tex_sub_2d(0, 0, w, h, tex->pta->format, sz, data2);
+                       else
+                         _tex_sub_2d(0, y, w, ystep, tex->pta->format,
+                                     tex->pta->dataformat, data2 + rowlen * y / ystep);
+                    }
+               }
+          }
      }
+on_error:
+   glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex); GLERRLOG();
 }
 
 Evas_GL_Texture *
@@ -1078,7 +1812,6 @@ evas_gl_common_texture_yuv_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigne
    tex->ptv = _pool_tex_new(gc,  tex->ptu->w, tex->ptu->h, lum_ifmt, lum_fmt);
    if (!tex->ptv)
      {
-        pt_unref(tex->pt);
         pt_unref(tex->ptu);
         free(tex);
         return NULL;
@@ -1090,6 +1823,8 @@ evas_gl_common_texture_yuv_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigne
    tex->pt = _pool_tex_new(gc, tex->ptu->w * 2, tex->ptu->h * 2, lum_ifmt, lum_fmt);
    if (!tex->pt)
      {
+        pt_unref(tex->ptu);
+        pt_unref(tex->ptv);
         free(tex);
         return NULL;
      }
@@ -1117,69 +1852,71 @@ evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned i
    if (!tex->pt) return;
    // FIXME: works on lowest size 4 pixel high buffers. must also be multiple of 2
 #ifdef GL_UNPACK_ROW_LENGTH
-   glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   _tex_2d(tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat);
-   _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
-   glBindTexture(GL_TEXTURE_2D, tex->ptu->texture);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + 1] - rows[h]);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   _tex_2d(tex->ptu->intformat, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat);
-   _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat, rows[h]);
-   glBindTexture(GL_TEXTURE_2D, tex->ptv->texture);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + (h / 2) + 1] - rows[h + (h / 2)]);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   _tex_2d(tex->ptv->intformat, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat);
-   _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2)]);
-#else
-   unsigned int y;
-
-   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   _tex_2d(tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat);
-   if ((rows[1] - rows[0]) == (int)w)
-     _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
-   else
-     {
-        for (y = 0; y < h; y++)
-          _tex_sub_2d(0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
-     }
-
-   glBindTexture(GL_TEXTURE_2D, tex->ptu->texture);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   _tex_2d(tex->ptu->intformat, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat);
-   if ((rows[h + 1] - rows[h]) == (int)(w / 2))
-     _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat, rows[h]);
-   else
+   if (tex->gc->shared->info.unpack_row_length)
      {
-        for (y = 0; y < (h / 2); y++)
-          _tex_sub_2d(0, y, w / 2, 1, tex->ptu->format, tex->ptu->dataformat, rows[h + y]);
+        glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat)) return;
+        _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
+        glBindTexture(GL_TEXTURE_2D, tex->ptu->texture);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + 1] - rows[h]);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        if (!_tex_2d(tex->gc, tex->ptu->intformat, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat)) return;
+        _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat, rows[h]);
+        glBindTexture(GL_TEXTURE_2D, tex->ptv->texture);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + (h / 2) + 1] - rows[h + (h / 2)]);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        if (!_tex_2d(tex->gc, tex->ptv->intformat, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat)) return;
+        _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2)]);
      }
-
-   glBindTexture(GL_TEXTURE_2D, tex->ptv->texture);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   _tex_2d(tex->ptv->intformat, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat);
-   if ((rows[h + (h / 2) + 1] - rows[h + (h / 2)]) == (int)(w / 2))
-     _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2)]);
    else
-     {
-        for (y = 0; y < (h / 2); y++)
-          _tex_sub_2d(0, y, w / 2, 1, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2) + y]);
-     }
 #endif
-   if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
      {
-        glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
+        unsigned int y;
+
+         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat)) return;
+        if ((rows[1] - rows[0]) == (int)w)
+          _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
+        else
+          {
+             for (y = 0; y < h; y++)
+               _tex_sub_2d(0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
+          }
+
+        glBindTexture(GL_TEXTURE_2D, tex->ptu->texture);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        if (!_tex_2d(tex->gc, tex->ptu->intformat, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat)) return;
+        if ((rows[h + 1] - rows[h]) == (int)(w / 2))
+          _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat, rows[h]);
+        else
+          {
+             for (y = 0; y < (h / 2); y++)
+               _tex_sub_2d(0, y, w / 2, 1, tex->ptu->format, tex->ptu->dataformat, rows[h + y]);
+          }
+
+        glBindTexture(GL_TEXTURE_2D, tex->ptv->texture);
         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        if (!_tex_2d(tex->gc, tex->ptv->intformat, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat)) return;
+        if ((rows[h + (h / 2) + 1] - rows[h + (h / 2)]) == (int)(w / 2))
+          _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2)]);
+        else
+          {
+             for (y = 0; y < (h / 2); y++)
+               _tex_sub_2d(0, y, w / 2, 1, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2) + y]);
+          }
      }
+
+   evas_gl_common_texture_shared_back(tex->gc, tex->ptv);
 }
 
 static Evas_GL_Texture *
@@ -1288,7 +2025,7 @@ evas_gl_common_texture_nv12_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsign
 {
    Evas_GL_Texture *tex;
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
    tex = _evas_gl_common_texture_y2uv_new(gc, w, h, EINA_TRUE, EINA_TRUE, lum_ifmt, lum_fmt, lum_alpha_ifmt, lum_alpha_fmt, 1);
    if (!tex)
 #endif
@@ -1303,7 +2040,7 @@ evas_gl_common_texture_nv12tiled_new(Evas_Engine_GL_Context *gc, DATA8 **rows, u
 {
    Evas_GL_Texture *tex = NULL;
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
    tex = _evas_gl_common_texture_y2uv_new(gc, w, h, EINA_TRUE, EINA_TRUE, lum_ifmt, lum_fmt, lum_alpha_ifmt, lum_alpha_fmt, 1);
    if (!tex)
 #endif
@@ -1328,7 +2065,7 @@ evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
    glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   _tex_2d(tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat);
+   if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat)) return;
    if ((rows[1] - rows[0]) == (int)w * 4)
      _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
    else
@@ -1339,7 +2076,7 @@ evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned
 
    glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   _tex_2d(tex->ptuv->intformat, w / 2, h, tex->ptuv->format, tex->ptuv->dataformat);
+   if (!_tex_2d(tex->gc, tex->ptuv->intformat, w / 2, h, tex->ptuv->format, tex->ptuv->dataformat)) return;
 #if 0
    /*
      FIXME: this piece of code doesn't work anymore since texture width
@@ -1354,11 +2091,7 @@ evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned
           _tex_sub_2d(0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[y]);
      }
 
-   if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
-     {
-        glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-     }
+   evas_gl_common_texture_shared_back(tex->gc, tex->ptuv);
 }
 
 void
@@ -1372,52 +2105,54 @@ evas_gl_common_texture_nv12_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned
 
    // FIXME: works on lowest size 4 pixel high buffers. must also be multiple of 2
 #ifdef GL_UNPACK_ROW_LENGTH
-   glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   _tex_2d(tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat);
-   _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
-   glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + 1] - rows[h]);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   _tex_2d(tex->ptuv->intformat, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat);
-   _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat, rows[h]);
-#else
-   unsigned int y;
-
-   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   _tex_2d(tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat);
-   if ((rows[1] - rows[0]) == (int)w)
-     _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
-   else
+   if (tex->gc->shared->info.unpack_row_length)
      {
-        for (y = 0; y < h; y++)
-          _tex_sub_2d(0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
+        glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat)) return;
+        _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
+        glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + 1] - rows[h]);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        if (!_tex_2d(tex->gc, tex->ptuv->intformat, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat)) return;
+        _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat, rows[h]);
      }
-
-   glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
-   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-   _tex_2d(tex->ptuv->intformat, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat);
-   if ((rows[h + 1] - rows[h]) == (int)(w / 2))
-     _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat, rows[h]);
    else
-     {
-        for (y = 0; y < (h / 2); y++)
-          _tex_sub_2d(0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[h + y]);
-     }
 #endif
-   if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
      {
-        glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
+        unsigned int y;
+
+        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat)) return;
+        if ((rows[1] - rows[0]) == (int)w)
+          _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
+        else
+          {
+             for (y = 0; y < h; y++)
+               _tex_sub_2d(0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
+          }
+
+        glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        if (!_tex_2d(tex->gc, tex->ptuv->intformat, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat)) return;
+        if ((rows[h + 1] - rows[h]) == (int)(w / 2))
+          _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat, rows[h]);
+        else
+          {
+             for (y = 0; y < (h / 2); y++)
+               _tex_sub_2d(0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[h + y]);
+          }
      }
+
+   evas_gl_common_texture_shared_back(tex->gc, tex->ptuv);
 }
 
 void
@@ -1435,13 +2170,17 @@ evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsi
    mb_w = w / 64 + (w % 64 ? 1 : 0);
    mb_h = h / 32 + (h % 32 ? 1 : 0);
 
-#if ( defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) )
+#ifdef GL_GLES
    if (tex->dyn)
      {
         char *texture_addr;
        char *tmp;
 
-       texture_addr = secsym_eglMapImageSEC(tex->gc->egldisp, tex->pt->dyn.img);
+       texture_addr = secsym_eglMapImageSEC
+                                      (tex->gc->egldisp,
+                                       tex->pt->dyn.img,
+                                       EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC,
+                                       EGL_MAP_GL_TEXTURE_OPTION_WRITE_SEC);
 
        /* Iterate each Y macroblock like we do in evas_convert_yuv.c */
        for (mb_y = 0; mb_y < (mb_h >> 1); mb_y++)
@@ -1496,9 +2235,13 @@ evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsi
               }
          }
 
-       secsym_eglUnmapImageSEC(tex->gc->egldisp, tex->pt->dyn.img);
+       secsym_eglUnmapImageSEC(tex->gc->egldisp, tex->pt->dyn.img, EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC);
 
-       texture_addr = secsym_eglMapImageSEC(tex->gc->egldisp, tex->ptuv->dyn.img);
+       texture_addr = secsym_eglMapImageSEC
+                                      (tex->gc->egldisp,
+                                       tex->ptuv->dyn.img,
+                                      EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC,
+                                      EGL_MAP_GL_TEXTURE_OPTION_WRITE_SEC);
 
        /* Iterate each UV macroblock like we do in evas_convert_yuv.c */
        base_h = (mb_h >> 1) + (mb_h & 0x1);
@@ -1563,7 +2306,7 @@ evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsi
               }
          }
 
-       secsym_eglUnmapImageSEC(tex->gc->egldisp, tex->ptuv->dyn.img);
+       secsym_eglUnmapImageSEC(tex->gc->egldisp, tex->ptuv->dyn.img, EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC);
        return ;
      }
 #endif
@@ -1575,7 +2318,7 @@ evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsi
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
 
    // We are telling the driver to not swizzle back the buffer as we are going to replace all pixel
-   _tex_2d(tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat);
+   if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat)) return;
 
    /* Iterate each Y macroblock like we do in evas_convert_yuv.c */
    for (mb_y = 0; mb_y < (mb_h >> 1); mb_y++)
@@ -1621,7 +2364,7 @@ evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsi
    glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
 
-   _tex_2d(tex->ptuv->intformat, w, h, tex->ptuv->format, tex->ptuv->dataformat);
+   if (!_tex_2d(tex->gc, tex->ptuv->intformat, w, h, tex->ptuv->format, tex->ptuv->dataformat)) return;
 
    /* Iterate each UV macroblock like we do in evas_convert_yuv.c */
    base_h = (mb_h >> 1) + (mb_h & 0x1);
@@ -1673,4 +2416,6 @@ evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsi
        for (mb_x = 0; mb_x < mb_w; mb_x++, x += 32, rmb_x += 64 * 32)
          _tex_sub_2d(x, ry, 64, 32, tex->ptuv->format, tex->ptuv->dataformat, rows[mb_y + base_h] + rmb_x);
      }
+
+   evas_gl_common_texture_shared_back(tex->gc, tex->ptuv);
 }
diff --git a/src/modules/engines/gl_common/shader/compile-s3c6410.sh b/src/modules/engines/gl_common/shader/compile-s3c6410.sh
deleted file mode 100755 (executable)
index 450e5de..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/sh
-ORIONEXE=/home/raster/Data/orion/orion.exe
-OPTS="-O --nolodcalc -lp"
-
-function compile()
-{
-  F=$1
-
-  make-c-str.sh $F"_frag.shd" > $F"_frag.h"
-  if test -f $F"_frag_s3c6410.asm"; then
-    wine $ORIONEXE -a $OPTS -f $F"_frag_s3c6410.asm"
-    make-c-bin.sh $F"_frag_s3c6410.bin" > $F"_frag_bin_s3c6410.h"
-    rm -f   $F"_frag_s3c6410.bin"   $F"_frag_s3c6410.h"
-  else
-    wine $ORIONEXE $OPTS -f $F"_frag.shd"
-    make-c-bin.sh $F"_frag.shd.bin" > $F"_frag_bin_s3c6410.h"
-    rm -f   $F"_frag.shd.bin"   $F"_frag.shd.asm"   $F"_frag.shd.h"
-  fi
-
-  make-c-str.sh $F"_vert.shd" > $F"_vert.h"
-  if test -f $F"_vert_s3c6410.asm"; then
-    wine $ORIONEXE -a $OPTS -v $F"_vert_s3c6410.asm"
-    make-c-bin.sh $F"_vert_s3c6410.bin" > $F"_vert_bin_s3c6410.h"
-    rm -f   $F"_vert_s3c6410.bin"   $F"_vert_s3c6410.h"
-  else
-    wine $ORIONEXE $OPTS -v $F"_vert.shd"
-    make-c-bin.sh $F"_vert.shd.bin" > $F"_vert_bin_s3c6410.h"
-    rm -f   $F"_vert.shd.bin"   $F"_vert.shd.asm"   $F"_vert.shd.h"
-  fi
-}
-
-compile rect
-compile font
-compile img
-compile img_nomul
-compile img_bgra
-compile img_bgra_nomul
-compile img_mask
-compile yuv
-compile yuv_nomul
-compile tex
-compile tex_nomul
-compile nv12
-compile nv12_nomul
-compile yuy2
-compile yuy2_nomul
-## FIXME: compile filter_*
diff --git a/src/modules/engines/gl_common/shader/compile-sgx.sh b/src/modules/engines/gl_common/shader/compile-sgx.sh
deleted file mode 100755 (executable)
index b84c6b6..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/bin/bash
-function compile()
-{
-  F=$1
-
-  if [ -f $F".shd" ]; then
-    make-c-str.sh $F".shd" > $F".h"
-  fi
-  if [ -f $F"_frag.shd" ]; then
-    make-c-str.sh $F"_frag.shd" > $F"_frag.h"
-  fi
-  if [ -f $F"_vert.shd" ]; then
-    make-c-str.sh $F"_vert.shd" > $F"_vert.h"
-  fi
-}
-
-compile rect
-compile font
-compile img
-compile img_nomul
-compile img_bgra
-compile img_bgra_nomul
-compile img_mask
-compile yuv
-compile yuv_nomul
-compile tex
-compile tex_nomul
-compile filter_blur_bgra
-compile filter_blur_bgra_nomul
-compile filter_blur
-compile filter_blur_nomul
-compile filter_greyscale_bgra
-compile filter_greyscale_bgra_nomul
-compile filter_greyscale
-compile filter_greyscale_nomul
-compile filter_invert_bgra
-compile filter_invert_bgra_nomul
-compile filter_invert
-compile filter_invert_nomul
-compile filter_sepia_bgra
-compile filter_sepia_bgra_nomul
-compile filter_sepia
-compile filter_sepia_nomul
-compile nv12
-compile nv12_nomul
-compile yuy2
-compile yuy2_nomul
-## FIXME: compile filter_*
-
diff --git a/src/modules/engines/gl_common/shader/compile.sh b/src/modules/engines/gl_common/shader/compile.sh
new file mode 100755 (executable)
index 0000000..0bec6bb
--- /dev/null
@@ -0,0 +1,125 @@
+#!/bin/bash
+
+DIR=`dirname $0`
+MAKESTR="sh $DIR/make-c-str.sh"
+
+function compile()
+{
+  F="$DIR/$1"
+
+  if [ -f $F".shd" ]; then
+    $MAKESTR $F".shd" > $F".h"
+  fi
+  if [ -f $F"_frag.shd" ]; then
+    $MAKESTR $F"_frag.shd" > $F"_frag.h"
+  fi
+  if [ -f $F"_vert.shd" ]; then
+    $MAKESTR $F"_vert.shd" > $F"_vert.h"
+  fi
+}
+
+compile rect
+compile font
+
+compile img
+compile img_nomul
+compile img_afill
+compile img_nomul_afill
+compile img_bgra
+compile img_bgra_nomul
+compile img_bgra_afill
+compile img_bgra_nomul_afill
+compile tex
+compile tex_nomul
+compile tex_afill
+compile tex_nomul_afill
+
+compile img_21
+compile img_21_nomul
+compile img_21_afill
+compile img_21_nomul_afill
+compile img_21_bgra
+compile img_21_bgra_nomul
+compile img_21_bgra_afill
+compile img_21_bgra_nomul_afill
+compile tex_21
+compile tex_21_nomul
+compile tex_21_afill
+compile tex_21_nomul_afill
+
+compile img_12
+compile img_12_nomul
+compile img_12_afill
+compile img_12_nomul_afill
+compile img_12_bgra
+compile img_12_bgra_nomul
+compile img_12_bgra_afill
+compile img_12_bgra_nomul_afill
+compile tex_12
+compile tex_12_nomul
+compile tex_12_afill
+compile tex_12_nomul_afill
+
+compile img_22
+compile img_22_nomul
+compile img_22_afill
+compile img_22_nomul_afill
+compile img_22_bgra
+compile img_22_bgra_nomul
+compile img_22_bgra_afill
+compile img_22_bgra_nomul_afill
+compile tex_22
+compile tex_22_nomul
+compile tex_22_afill
+compile tex_22_nomul_afill
+
+## above section must have 21, 22 and 12 versions
+
+compile yuv
+compile yuv_nomul
+compile nv12
+compile nv12_nomul
+compile yuy2
+compile yuy2_nomul
+
+compile rgb_a_pair
+compile rgb_a_pair_nomul
+
+compile filter_blur_bgra
+compile filter_blur_bgra_nomul
+compile filter_blur
+compile filter_blur_nomul
+compile filter_greyscale_bgra
+compile filter_greyscale_bgra_nomul
+compile filter_greyscale
+compile filter_greyscale_nomul
+compile filter_invert_bgra
+compile filter_invert_bgra_nomul
+compile filter_invert
+compile filter_invert_nomul
+compile filter_sepia_bgra
+compile filter_sepia_bgra_nomul
+compile filter_sepia
+compile filter_sepia_nomul
+
+compile tizen
+compile tizen_mask
+compile tizen_nomul
+compile tizen_mask_nomul
+
+# Masking shaders
+compile font_mask
+compile img_mask
+compile img_mask_bgra
+compile img_mask_bgra_nomul
+compile img_mask_nomul
+compile nv12_mask
+compile rect_mask
+compile rgb_a_pair_mask
+compile yuv_mask
+compile yuy2_mask
+compile map_mask
+compile map_mask_bgra
+compile map_mask_bgra_nomul
+compile map_mask_nomul
+
diff --git a/src/modules/engines/gl_common/shader/font_frag_bin_s3c6410.h b/src/modules/engines/gl_common/shader/font_frag_bin_s3c6410.h
deleted file mode 100644 (file)
index daca692..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-0x20205350, 0xffff0008, 0x00000048, 0x01020000, 0x00000003, 0x00000000, 
-0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000001, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000e, 0x00000000, 
-0x00000000, 0x0000e407, 0x307820e4, 0x00000000, 0x01000000, 0x0100e400, 
-0x237a10ff, 0x00000000, 0x00000000, 0x00000000, 0x1e000000, 0x00000000, 
-0x00000004, 0x00000003, 0x00000009, 0x00000000, 0x00000004, 0x00000008, 
-0x00000005, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 
-0x0000000f, 0x00030005, 0x00000000, 0x00786574, 0x006c6f63, 0x5f786574, 
-0x00000063, 
\ No newline at end of file
diff --git a/src/modules/engines/gl_common/shader/font_frag_s3c6410.asm b/src/modules/engines/gl_common/shader/font_frag_s3c6410.asm
deleted file mode 100644 (file)
index 4ed116f..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#-------------------------------------------------
-# ORION - OpenGL ES 2.0 Shading Language Compiler
-# SAMSUNG INDIA SOFTWARE OPERATIONS PVT. LTD.
-# Compiler Version      : v04.00.09
-# Release Date          : 19.01.2009
-# FIMG VERSION      : FIMGv1.5
-# Optimizer Options :  -O --nolodcalc
-#-------------------------------------------------
-
-# hand optimised - removed useless ops
-
-ps_3_0
-
-fimg_version    0x01020000
-
-dcl_s2_tex      s0
-dcl_f4_col      v1.x
-dcl_f2_tex_c    v0.x
-
-label start
-label main_
-texld r0.xyzw, v0.xyzw, s0      # tex=s0
-mul_sat oColor.xyzw, r0.wwww, v1.xyzw   # gl_FragColor=oColor.xyzw, col=v1.xyzw
-label main_end
-ret
-# 4 instructions, 4 C regs, 1 R regs
diff --git a/src/modules/engines/gl_common/shader/font_mask_frag.h b/src/modules/engines/gl_common/shader/font_mask_frag.h
new file mode 100644 (file)
index 0000000..d1bc77f
--- /dev/null
@@ -0,0 +1,17 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"uniform sampler2D texm;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_m;\n"
+"void main()\n"
+"{\n"
+"   gl_FragColor = texture2D(tex, tex_c.xy).aaaa * texture2D(texm, tex_m.xy).aaaa * col;\n"
+"}\n"
+"\n"
diff --git a/src/modules/engines/gl_common/shader/font_mask_frag.shd b/src/modules/engines/gl_common/shader/font_mask_frag.shd
new file mode 100644 (file)
index 0000000..48c926c
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+uniform sampler2D texm;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_m;
+void main()
+{
+   gl_FragColor = texture2D(tex, tex_c.xy).aaaa * texture2D(texm, tex_m.xy).aaaa * col;
+}
+
diff --git a/src/modules/engines/gl_common/shader/font_mask_vert.h b/src/modules/engines/gl_common/shader/font_mask_vert.h
new file mode 100644 (file)
index 0000000..cc4dd89
--- /dev/null
@@ -0,0 +1,19 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_coordm;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_m;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_m = tex_coordm;\n"
+"}\n"
+"\n"
diff --git a/src/modules/engines/gl_common/shader/font_mask_vert.shd b/src/modules/engines/gl_common/shader/font_mask_vert.shd
new file mode 100644 (file)
index 0000000..2651689
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_coordm;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_m;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_m = tex_coordm;
+}
+
diff --git a/src/modules/engines/gl_common/shader/font_vert_bin_s3c6410.h b/src/modules/engines/gl_common/shader/font_vert_bin_s3c6410.h
deleted file mode 100644 (file)
index 1402448..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-0x20205356, 0xffff0008, 0x00000048, 0x01020000, 0x00000007, 0x00000006, 
-0x00000000, 0x00000000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000031, 0x00000000, 
-0x00000000, 0x02020000, 0x237820e4, 0x00000000, 0x00e40100, 0x02035500, 
-0x2ef820e4, 0x00000000, 0x00e40100, 0x0204aa00, 0x2ef820e4, 0x00000000, 
-0x00e40100, 0x0205ff00, 0x2ef800e4, 0x00000000, 0x00000000, 0x00010000, 
-0x20f801e4, 0x00000000, 0x00000000, 0x00020000, 0x20980254, 0x00000000, 
-0x00000000, 0x00000000, 0x1e000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000006, 
-0x00000009, 0x00000000, 0x00000000, 0x00000013, 0x00000005, 0x00000009, 
-0x00000000, 0x00000004, 0x00000019, 0x00000009, 0x00000003, 0x00000000, 
-0x00000008, 0x00000000, 0x0000000b, 0x00000009, 0x00010004, 0x00000000, 
-0x00000027, 0x00000003, 0x00000009, 0x00010004, 0x00000004, 0x0000002b, 
-0x00000005, 0x00000003, 0x00010004, 0x00000008, 0x00000023, 0x00000003, 
-0x0000000e, 0x00020001, 0x00000008, 0x505f6c67, 0x7469736f, 0x006e6f69, 
-0x74726576, 0x63007865, 0x726f6c6f, 0x78657400, 0x6f6f635f, 0x6d006472, 
-0x63007076, 0x74006c6f, 0x635f7865, 0x00000000, 
\ No newline at end of file
diff --git a/src/modules/engines/gl_common/shader/img_12_afill_frag.h b/src/modules/engines/gl_common/shader/img_12_afill_frag.h
new file mode 100644 (file)
index 0000000..72265cd
--- /dev/null
@@ -0,0 +1,19 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;\n"
+"   vec4 c = ((col00 + col01) / div_s) * col;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_12_afill_frag.shd b/src/modules/engines/gl_common/shader/img_12_afill_frag.shd
new file mode 100644 (file)
index 0000000..0f6633e
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;
+   vec4 c = ((col00 + col01) / div_s) * col;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/img_12_afill_vert.h b/src/modules/engines/gl_common/shader/img_12_afill_vert.h
new file mode 100644 (file)
index 0000000..56cd064
--- /dev/null
@@ -0,0 +1,21 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(0, -tex_sample.y);\n"
+"   tex_s[1] = vec2(0,  tex_sample.y);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_12_afill_vert.shd b/src/modules/engines/gl_common/shader/img_12_afill_vert.shd
new file mode 100644 (file)
index 0000000..810d73a
--- /dev/null
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(0, -tex_sample.y);
+   tex_s[1] = vec2(0,  tex_sample.y);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/img_12_bgra_afill_frag.h b/src/modules/engines/gl_common/shader/img_12_bgra_afill_frag.h
new file mode 100644 (file)
index 0000000..217fb15
--- /dev/null
@@ -0,0 +1,19 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   vec4 c = ((col00 + col01) / div_s) * col;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_12_bgra_afill_frag.shd b/src/modules/engines/gl_common/shader/img_12_bgra_afill_frag.shd
new file mode 100644 (file)
index 0000000..ab7550a
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   vec4 c = ((col00 + col01) / div_s) * col;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/img_12_bgra_afill_vert.h b/src/modules/engines/gl_common/shader/img_12_bgra_afill_vert.h
new file mode 100644 (file)
index 0000000..56cd064
--- /dev/null
@@ -0,0 +1,21 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(0, -tex_sample.y);\n"
+"   tex_s[1] = vec2(0,  tex_sample.y);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_12_bgra_afill_vert.shd b/src/modules/engines/gl_common/shader/img_12_bgra_afill_vert.shd
new file mode 100644 (file)
index 0000000..810d73a
--- /dev/null
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(0, -tex_sample.y);
+   tex_s[1] = vec2(0,  tex_sample.y);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/img_12_bgra_frag.h b/src/modules/engines/gl_common/shader/img_12_bgra_frag.h
new file mode 100644 (file)
index 0000000..a076fb5
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   gl_FragColor = ((col00 + col01) / div_s) * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_12_bgra_frag.shd b/src/modules/engines/gl_common/shader/img_12_bgra_frag.shd
new file mode 100644 (file)
index 0000000..d23e17b
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   gl_FragColor = ((col00 + col01) / div_s) * col;
+}
diff --git a/src/modules/engines/gl_common/shader/img_12_bgra_nomul_afill_frag.h b/src/modules/engines/gl_common/shader/img_12_bgra_nomul_afill_frag.h
new file mode 100644 (file)
index 0000000..3b02610
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   vec4 c = (col00 + col01) / div_s;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_12_bgra_nomul_afill_frag.shd b/src/modules/engines/gl_common/shader/img_12_bgra_nomul_afill_frag.shd
new file mode 100644 (file)
index 0000000..a7bff98
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   vec4 c = (col00 + col01) / div_s;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/img_12_bgra_nomul_afill_vert.h b/src/modules/engines/gl_common/shader/img_12_bgra_nomul_afill_vert.h
new file mode 100644 (file)
index 0000000..cee10ea
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(0, -tex_sample.y);\n"
+"   tex_s[1] = vec2(0,  tex_sample.y);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_12_bgra_nomul_afill_vert.shd b/src/modules/engines/gl_common/shader/img_12_bgra_nomul_afill_vert.shd
new file mode 100644 (file)
index 0000000..40144aa
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(0, -tex_sample.y);
+   tex_s[1] = vec2(0,  tex_sample.y);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/img_12_bgra_nomul_frag.h b/src/modules/engines/gl_common/shader/img_12_bgra_nomul_frag.h
new file mode 100644 (file)
index 0000000..0be15b3
--- /dev/null
@@ -0,0 +1,17 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   gl_FragColor = (col00 + col01) / div_s;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_12_bgra_nomul_frag.shd b/src/modules/engines/gl_common/shader/img_12_bgra_nomul_frag.shd
new file mode 100644 (file)
index 0000000..4d29510
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   gl_FragColor = (col00 + col01) / div_s;
+}
diff --git a/src/modules/engines/gl_common/shader/img_12_bgra_nomul_vert.h b/src/modules/engines/gl_common/shader/img_12_bgra_nomul_vert.h
new file mode 100644 (file)
index 0000000..cee10ea
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(0, -tex_sample.y);\n"
+"   tex_s[1] = vec2(0,  tex_sample.y);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_12_bgra_nomul_vert.shd b/src/modules/engines/gl_common/shader/img_12_bgra_nomul_vert.shd
new file mode 100644 (file)
index 0000000..40144aa
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(0, -tex_sample.y);
+   tex_s[1] = vec2(0,  tex_sample.y);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/img_12_bgra_vert.h b/src/modules/engines/gl_common/shader/img_12_bgra_vert.h
new file mode 100644 (file)
index 0000000..56cd064
--- /dev/null
@@ -0,0 +1,21 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(0, -tex_sample.y);\n"
+"   tex_s[1] = vec2(0,  tex_sample.y);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_12_bgra_vert.shd b/src/modules/engines/gl_common/shader/img_12_bgra_vert.shd
new file mode 100644 (file)
index 0000000..810d73a
--- /dev/null
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(0, -tex_sample.y);
+   tex_s[1] = vec2(0,  tex_sample.y);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/img_12_frag.h b/src/modules/engines/gl_common/shader/img_12_frag.h
new file mode 100644 (file)
index 0000000..2cc4493
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;\n"
+"   gl_FragColor = ((col00 + col01) / div_s) * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_12_frag.shd b/src/modules/engines/gl_common/shader/img_12_frag.shd
new file mode 100644 (file)
index 0000000..2647ab2
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;
+   gl_FragColor = ((col00 + col01) / div_s) * col;
+}
diff --git a/src/modules/engines/gl_common/shader/img_12_nomul_afill_frag.h b/src/modules/engines/gl_common/shader/img_12_nomul_afill_frag.h
new file mode 100644 (file)
index 0000000..55fbf9e
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;\n"
+"   vec4 c = (col00 + col01) / div_s;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_12_nomul_afill_frag.shd b/src/modules/engines/gl_common/shader/img_12_nomul_afill_frag.shd
new file mode 100644 (file)
index 0000000..71c839a
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;
+   vec4 c = (col00 + col01) / div_s;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/img_12_nomul_afill_vert.h b/src/modules/engines/gl_common/shader/img_12_nomul_afill_vert.h
new file mode 100644 (file)
index 0000000..cee10ea
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(0, -tex_sample.y);\n"
+"   tex_s[1] = vec2(0,  tex_sample.y);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_12_nomul_afill_vert.shd b/src/modules/engines/gl_common/shader/img_12_nomul_afill_vert.shd
new file mode 100644 (file)
index 0000000..40144aa
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(0, -tex_sample.y);
+   tex_s[1] = vec2(0,  tex_sample.y);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/img_12_nomul_frag.h b/src/modules/engines/gl_common/shader/img_12_nomul_frag.h
new file mode 100644 (file)
index 0000000..9ff8813
--- /dev/null
@@ -0,0 +1,17 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;\n"
+"   gl_FragColor = (col00 + col01) / div_s;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_12_nomul_frag.shd b/src/modules/engines/gl_common/shader/img_12_nomul_frag.shd
new file mode 100644 (file)
index 0000000..49872cf
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;
+   gl_FragColor = (col00 + col01) / div_s;
+}
diff --git a/src/modules/engines/gl_common/shader/img_12_nomul_vert.h b/src/modules/engines/gl_common/shader/img_12_nomul_vert.h
new file mode 100644 (file)
index 0000000..cee10ea
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(0, -tex_sample.y);\n"
+"   tex_s[1] = vec2(0,  tex_sample.y);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_12_nomul_vert.shd b/src/modules/engines/gl_common/shader/img_12_nomul_vert.shd
new file mode 100644 (file)
index 0000000..40144aa
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(0, -tex_sample.y);
+   tex_s[1] = vec2(0,  tex_sample.y);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/img_12_vert.h b/src/modules/engines/gl_common/shader/img_12_vert.h
new file mode 100644 (file)
index 0000000..56cd064
--- /dev/null
@@ -0,0 +1,21 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(0, -tex_sample.y);\n"
+"   tex_s[1] = vec2(0,  tex_sample.y);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_12_vert.shd b/src/modules/engines/gl_common/shader/img_12_vert.shd
new file mode 100644 (file)
index 0000000..810d73a
--- /dev/null
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(0, -tex_sample.y);
+   tex_s[1] = vec2(0,  tex_sample.y);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/img_21_afill_frag.h b/src/modules/engines/gl_common/shader/img_21_afill_frag.h
new file mode 100644 (file)
index 0000000..72265cd
--- /dev/null
@@ -0,0 +1,19 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;\n"
+"   vec4 c = ((col00 + col01) / div_s) * col;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_21_afill_frag.shd b/src/modules/engines/gl_common/shader/img_21_afill_frag.shd
new file mode 100644 (file)
index 0000000..0f6633e
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;
+   vec4 c = ((col00 + col01) / div_s) * col;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/img_21_afill_vert.h b/src/modules/engines/gl_common/shader/img_21_afill_vert.h
new file mode 100644 (file)
index 0000000..88d1470
--- /dev/null
@@ -0,0 +1,21 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, 0);\n"
+"   tex_s[1] = vec2( tex_sample.x, 0);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_21_afill_vert.shd b/src/modules/engines/gl_common/shader/img_21_afill_vert.shd
new file mode 100644 (file)
index 0000000..98d9154
--- /dev/null
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, 0);
+   tex_s[1] = vec2( tex_sample.x, 0);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/img_21_bgra_afill_frag.h b/src/modules/engines/gl_common/shader/img_21_bgra_afill_frag.h
new file mode 100644 (file)
index 0000000..217fb15
--- /dev/null
@@ -0,0 +1,19 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   vec4 c = ((col00 + col01) / div_s) * col;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_21_bgra_afill_frag.shd b/src/modules/engines/gl_common/shader/img_21_bgra_afill_frag.shd
new file mode 100644 (file)
index 0000000..ab7550a
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   vec4 c = ((col00 + col01) / div_s) * col;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/img_21_bgra_afill_vert.h b/src/modules/engines/gl_common/shader/img_21_bgra_afill_vert.h
new file mode 100644 (file)
index 0000000..88d1470
--- /dev/null
@@ -0,0 +1,21 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, 0);\n"
+"   tex_s[1] = vec2( tex_sample.x, 0);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_21_bgra_afill_vert.shd b/src/modules/engines/gl_common/shader/img_21_bgra_afill_vert.shd
new file mode 100644 (file)
index 0000000..98d9154
--- /dev/null
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, 0);
+   tex_s[1] = vec2( tex_sample.x, 0);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/img_21_bgra_frag.h b/src/modules/engines/gl_common/shader/img_21_bgra_frag.h
new file mode 100644 (file)
index 0000000..a076fb5
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   gl_FragColor = ((col00 + col01) / div_s) * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_21_bgra_frag.shd b/src/modules/engines/gl_common/shader/img_21_bgra_frag.shd
new file mode 100644 (file)
index 0000000..d23e17b
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   gl_FragColor = ((col00 + col01) / div_s) * col;
+}
diff --git a/src/modules/engines/gl_common/shader/img_21_bgra_nomul_afill_frag.h b/src/modules/engines/gl_common/shader/img_21_bgra_nomul_afill_frag.h
new file mode 100644 (file)
index 0000000..3b02610
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   vec4 c = (col00 + col01) / div_s;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_21_bgra_nomul_afill_frag.shd b/src/modules/engines/gl_common/shader/img_21_bgra_nomul_afill_frag.shd
new file mode 100644 (file)
index 0000000..a7bff98
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   vec4 c = (col00 + col01) / div_s;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/img_21_bgra_nomul_afill_vert.h b/src/modules/engines/gl_common/shader/img_21_bgra_nomul_afill_vert.h
new file mode 100644 (file)
index 0000000..7c7d7db
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, 0);\n"
+"   tex_s[1] = vec2( tex_sample.x, 0);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_21_bgra_nomul_afill_vert.shd b/src/modules/engines/gl_common/shader/img_21_bgra_nomul_afill_vert.shd
new file mode 100644 (file)
index 0000000..a6b149f
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, 0);
+   tex_s[1] = vec2( tex_sample.x, 0);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/img_21_bgra_nomul_frag.h b/src/modules/engines/gl_common/shader/img_21_bgra_nomul_frag.h
new file mode 100644 (file)
index 0000000..0be15b3
--- /dev/null
@@ -0,0 +1,17 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   gl_FragColor = (col00 + col01) / div_s;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_21_bgra_nomul_frag.shd b/src/modules/engines/gl_common/shader/img_21_bgra_nomul_frag.shd
new file mode 100644 (file)
index 0000000..4d29510
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   gl_FragColor = (col00 + col01) / div_s;
+}
diff --git a/src/modules/engines/gl_common/shader/img_21_bgra_nomul_vert.h b/src/modules/engines/gl_common/shader/img_21_bgra_nomul_vert.h
new file mode 100644 (file)
index 0000000..7c7d7db
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, 0);\n"
+"   tex_s[1] = vec2( tex_sample.x, 0);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_21_bgra_nomul_vert.shd b/src/modules/engines/gl_common/shader/img_21_bgra_nomul_vert.shd
new file mode 100644 (file)
index 0000000..a6b149f
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, 0);
+   tex_s[1] = vec2( tex_sample.x, 0);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/img_21_bgra_vert.h b/src/modules/engines/gl_common/shader/img_21_bgra_vert.h
new file mode 100644 (file)
index 0000000..88d1470
--- /dev/null
@@ -0,0 +1,21 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, 0);\n"
+"   tex_s[1] = vec2( tex_sample.x, 0);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_21_bgra_vert.shd b/src/modules/engines/gl_common/shader/img_21_bgra_vert.shd
new file mode 100644 (file)
index 0000000..98d9154
--- /dev/null
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, 0);
+   tex_s[1] = vec2( tex_sample.x, 0);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/img_21_frag.h b/src/modules/engines/gl_common/shader/img_21_frag.h
new file mode 100644 (file)
index 0000000..2cc4493
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;\n"
+"   gl_FragColor = ((col00 + col01) / div_s) * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_21_frag.shd b/src/modules/engines/gl_common/shader/img_21_frag.shd
new file mode 100644 (file)
index 0000000..2647ab2
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;
+   gl_FragColor = ((col00 + col01) / div_s) * col;
+}
diff --git a/src/modules/engines/gl_common/shader/img_21_nomul_afill_frag.h b/src/modules/engines/gl_common/shader/img_21_nomul_afill_frag.h
new file mode 100644 (file)
index 0000000..55fbf9e
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;\n"
+"   vec4 c = (col00 + col01) / div_s;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_21_nomul_afill_frag.shd b/src/modules/engines/gl_common/shader/img_21_nomul_afill_frag.shd
new file mode 100644 (file)
index 0000000..71c839a
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;
+   vec4 c = (col00 + col01) / div_s;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/img_21_nomul_afill_vert.h b/src/modules/engines/gl_common/shader/img_21_nomul_afill_vert.h
new file mode 100644 (file)
index 0000000..7c7d7db
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, 0);\n"
+"   tex_s[1] = vec2( tex_sample.x, 0);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_21_nomul_afill_vert.shd b/src/modules/engines/gl_common/shader/img_21_nomul_afill_vert.shd
new file mode 100644 (file)
index 0000000..a6b149f
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, 0);
+   tex_s[1] = vec2( tex_sample.x, 0);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/img_21_nomul_frag.h b/src/modules/engines/gl_common/shader/img_21_nomul_frag.h
new file mode 100644 (file)
index 0000000..9ff8813
--- /dev/null
@@ -0,0 +1,17 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;\n"
+"   gl_FragColor = (col00 + col01) / div_s;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_21_nomul_frag.shd b/src/modules/engines/gl_common/shader/img_21_nomul_frag.shd
new file mode 100644 (file)
index 0000000..49872cf
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;
+   gl_FragColor = (col00 + col01) / div_s;
+}
diff --git a/src/modules/engines/gl_common/shader/img_21_nomul_vert.h b/src/modules/engines/gl_common/shader/img_21_nomul_vert.h
new file mode 100644 (file)
index 0000000..7c7d7db
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, 0);\n"
+"   tex_s[1] = vec2( tex_sample.x, 0);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_21_nomul_vert.shd b/src/modules/engines/gl_common/shader/img_21_nomul_vert.shd
new file mode 100644 (file)
index 0000000..a6b149f
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, 0);
+   tex_s[1] = vec2( tex_sample.x, 0);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/img_21_vert.h b/src/modules/engines/gl_common/shader/img_21_vert.h
new file mode 100644 (file)
index 0000000..88d1470
--- /dev/null
@@ -0,0 +1,21 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, 0);\n"
+"   tex_s[1] = vec2( tex_sample.x, 0);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_21_vert.shd b/src/modules/engines/gl_common/shader/img_21_vert.shd
new file mode 100644 (file)
index 0000000..98d9154
--- /dev/null
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, 0);
+   tex_s[1] = vec2( tex_sample.x, 0);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/img_22_afill_frag.h b/src/modules/engines/gl_common/shader/img_22_afill_frag.h
new file mode 100644 (file)
index 0000000..631693a
--- /dev/null
@@ -0,0 +1,21 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;\n"
+"   vec4 col10 = texture2D(tex, tex_c + tex_s[2]).bgra;\n"
+"   vec4 col11 = texture2D(tex, tex_c + tex_s[3]).bgra;\n"
+"   vec4 c = ((col00 + col01 + col10 + col11) / div_s) * col;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_22_afill_frag.shd b/src/modules/engines/gl_common/shader/img_22_afill_frag.shd
new file mode 100644 (file)
index 0000000..af03ae4
--- /dev/null
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;
+   vec4 col10 = texture2D(tex, tex_c + tex_s[2]).bgra;
+   vec4 col11 = texture2D(tex, tex_c + tex_s[3]).bgra;
+   vec4 c = ((col00 + col01 + col10 + col11) / div_s) * col;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/img_22_afill_vert.h b/src/modules/engines/gl_common/shader/img_22_afill_vert.h
new file mode 100644 (file)
index 0000000..e1fc7f4
--- /dev/null
@@ -0,0 +1,23 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);\n"
+"   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);\n"
+"   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);\n"
+"   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);\n"
+"   div_s = vec4(4, 4, 4, 4);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_22_afill_vert.shd b/src/modules/engines/gl_common/shader/img_22_afill_vert.shd
new file mode 100644 (file)
index 0000000..e964ea1
--- /dev/null
@@ -0,0 +1,23 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);
+   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);
+   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);
+   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);
+   div_s = vec4(4, 4, 4, 4);
+}
diff --git a/src/modules/engines/gl_common/shader/img_22_bgra_afill_frag.h b/src/modules/engines/gl_common/shader/img_22_bgra_afill_frag.h
new file mode 100644 (file)
index 0000000..1164c80
--- /dev/null
@@ -0,0 +1,21 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   vec4 col10 = texture2D(tex, tex_c + tex_s[2]);\n"
+"   vec4 col11 = texture2D(tex, tex_c + tex_s[3]);\n"
+"   vec4 c = ((col00 + col01 + col10 + col11) / div_s) * col;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_22_bgra_afill_frag.shd b/src/modules/engines/gl_common/shader/img_22_bgra_afill_frag.shd
new file mode 100644 (file)
index 0000000..f85e64b
--- /dev/null
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   vec4 col10 = texture2D(tex, tex_c + tex_s[2]);
+   vec4 col11 = texture2D(tex, tex_c + tex_s[3]);
+   vec4 c = ((col00 + col01 + col10 + col11) / div_s) * col;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/img_22_bgra_afill_vert.h b/src/modules/engines/gl_common/shader/img_22_bgra_afill_vert.h
new file mode 100644 (file)
index 0000000..e1fc7f4
--- /dev/null
@@ -0,0 +1,23 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);\n"
+"   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);\n"
+"   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);\n"
+"   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);\n"
+"   div_s = vec4(4, 4, 4, 4);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_22_bgra_afill_vert.shd b/src/modules/engines/gl_common/shader/img_22_bgra_afill_vert.shd
new file mode 100644 (file)
index 0000000..e964ea1
--- /dev/null
@@ -0,0 +1,23 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);
+   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);
+   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);
+   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);
+   div_s = vec4(4, 4, 4, 4);
+}
diff --git a/src/modules/engines/gl_common/shader/img_22_bgra_frag.h b/src/modules/engines/gl_common/shader/img_22_bgra_frag.h
new file mode 100644 (file)
index 0000000..748a33a
--- /dev/null
@@ -0,0 +1,20 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   vec4 col10 = texture2D(tex, tex_c + tex_s[2]);\n"
+"   vec4 col11 = texture2D(tex, tex_c + tex_s[3]);\n"
+"   gl_FragColor = ((col00 + col01 + col10 + col11) / div_s) * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_22_bgra_frag.shd b/src/modules/engines/gl_common/shader/img_22_bgra_frag.shd
new file mode 100644 (file)
index 0000000..ab1b121
--- /dev/null
@@ -0,0 +1,20 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   vec4 col10 = texture2D(tex, tex_c + tex_s[2]);
+   vec4 col11 = texture2D(tex, tex_c + tex_s[3]);
+   gl_FragColor = ((col00 + col01 + col10 + col11) / div_s) * col;
+}
diff --git a/src/modules/engines/gl_common/shader/img_22_bgra_nomul_afill_frag.h b/src/modules/engines/gl_common/shader/img_22_bgra_nomul_afill_frag.h
new file mode 100644 (file)
index 0000000..ce33563
--- /dev/null
@@ -0,0 +1,20 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   vec4 col10 = texture2D(tex, tex_c + tex_s[2]);\n"
+"   vec4 col11 = texture2D(tex, tex_c + tex_s[3]);\n"
+"   vec4 c = (col00 + col01 + col10 + col11) / div_s;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_22_bgra_nomul_afill_frag.shd b/src/modules/engines/gl_common/shader/img_22_bgra_nomul_afill_frag.shd
new file mode 100644 (file)
index 0000000..c017c31
--- /dev/null
@@ -0,0 +1,20 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   vec4 col10 = texture2D(tex, tex_c + tex_s[2]);
+   vec4 col11 = texture2D(tex, tex_c + tex_s[3]);
+   vec4 c = (col00 + col01 + col10 + col11) / div_s;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/img_22_bgra_nomul_afill_vert.h b/src/modules/engines/gl_common/shader/img_22_bgra_nomul_afill_vert.h
new file mode 100644 (file)
index 0000000..c6fb270
--- /dev/null
@@ -0,0 +1,20 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);\n"
+"   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);\n"
+"   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);\n"
+"   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);\n"
+"   div_s = vec4(4, 4, 4, 4);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_22_bgra_nomul_afill_vert.shd b/src/modules/engines/gl_common/shader/img_22_bgra_nomul_afill_vert.shd
new file mode 100644 (file)
index 0000000..e6303d7
--- /dev/null
@@ -0,0 +1,20 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);
+   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);
+   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);
+   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);
+   div_s = vec4(4, 4, 4, 4);
+}
diff --git a/src/modules/engines/gl_common/shader/img_22_bgra_nomul_frag.h b/src/modules/engines/gl_common/shader/img_22_bgra_nomul_frag.h
new file mode 100644 (file)
index 0000000..4af85f9
--- /dev/null
@@ -0,0 +1,19 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   vec4 col10 = texture2D(tex, tex_c + tex_s[2]);\n"
+"   vec4 col11 = texture2D(tex, tex_c + tex_s[3]);\n"
+"   gl_FragColor = (col00 + col01 + col10 + col11) / div_s;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_22_bgra_nomul_frag.shd b/src/modules/engines/gl_common/shader/img_22_bgra_nomul_frag.shd
new file mode 100644 (file)
index 0000000..3f380ea
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   vec4 col10 = texture2D(tex, tex_c + tex_s[2]);
+   vec4 col11 = texture2D(tex, tex_c + tex_s[3]);
+   gl_FragColor = (col00 + col01 + col10 + col11) / div_s;
+}
diff --git a/src/modules/engines/gl_common/shader/img_22_bgra_nomul_vert.h b/src/modules/engines/gl_common/shader/img_22_bgra_nomul_vert.h
new file mode 100644 (file)
index 0000000..c6fb270
--- /dev/null
@@ -0,0 +1,20 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);\n"
+"   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);\n"
+"   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);\n"
+"   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);\n"
+"   div_s = vec4(4, 4, 4, 4);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_22_bgra_nomul_vert.shd b/src/modules/engines/gl_common/shader/img_22_bgra_nomul_vert.shd
new file mode 100644 (file)
index 0000000..e6303d7
--- /dev/null
@@ -0,0 +1,20 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);
+   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);
+   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);
+   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);
+   div_s = vec4(4, 4, 4, 4);
+}
diff --git a/src/modules/engines/gl_common/shader/img_22_bgra_vert.h b/src/modules/engines/gl_common/shader/img_22_bgra_vert.h
new file mode 100644 (file)
index 0000000..e1fc7f4
--- /dev/null
@@ -0,0 +1,23 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);\n"
+"   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);\n"
+"   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);\n"
+"   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);\n"
+"   div_s = vec4(4, 4, 4, 4);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_22_bgra_vert.shd b/src/modules/engines/gl_common/shader/img_22_bgra_vert.shd
new file mode 100644 (file)
index 0000000..e964ea1
--- /dev/null
@@ -0,0 +1,23 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);
+   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);
+   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);
+   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);
+   div_s = vec4(4, 4, 4, 4);
+}
diff --git a/src/modules/engines/gl_common/shader/img_22_frag.h b/src/modules/engines/gl_common/shader/img_22_frag.h
new file mode 100644 (file)
index 0000000..3d64e07
--- /dev/null
@@ -0,0 +1,20 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;\n"
+"   vec4 col10 = texture2D(tex, tex_c + tex_s[2]).bgra;\n"
+"   vec4 col11 = texture2D(tex, tex_c + tex_s[3]).bgra;\n"
+"   gl_FragColor = ((col00 + col01 + col10 + col11) / div_s) * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_22_frag.shd b/src/modules/engines/gl_common/shader/img_22_frag.shd
new file mode 100644 (file)
index 0000000..1ff5ccc
--- /dev/null
@@ -0,0 +1,20 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;
+   vec4 col10 = texture2D(tex, tex_c + tex_s[2]).bgra;
+   vec4 col11 = texture2D(tex, tex_c + tex_s[3]).bgra;
+   gl_FragColor = ((col00 + col01 + col10 + col11) / div_s) * col;
+}
diff --git a/src/modules/engines/gl_common/shader/img_22_nomul_afill_frag.h b/src/modules/engines/gl_common/shader/img_22_nomul_afill_frag.h
new file mode 100644 (file)
index 0000000..87efe5e
--- /dev/null
@@ -0,0 +1,20 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;\n"
+"   vec4 col10 = texture2D(tex, tex_c + tex_s[2]).bgra;\n"
+"   vec4 col11 = texture2D(tex, tex_c + tex_s[3]).bgra;\n"
+"   vec4 c = (col00 + col01 + col10 + col11) / div_s;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_22_nomul_afill_frag.shd b/src/modules/engines/gl_common/shader/img_22_nomul_afill_frag.shd
new file mode 100644 (file)
index 0000000..ec261bb
--- /dev/null
@@ -0,0 +1,20 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;
+   vec4 col10 = texture2D(tex, tex_c + tex_s[2]).bgra;
+   vec4 col11 = texture2D(tex, tex_c + tex_s[3]).bgra;
+   vec4 c = (col00 + col01 + col10 + col11) / div_s;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/img_22_nomul_afill_vert.h b/src/modules/engines/gl_common/shader/img_22_nomul_afill_vert.h
new file mode 100644 (file)
index 0000000..c6fb270
--- /dev/null
@@ -0,0 +1,20 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);\n"
+"   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);\n"
+"   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);\n"
+"   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);\n"
+"   div_s = vec4(4, 4, 4, 4);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_22_nomul_afill_vert.shd b/src/modules/engines/gl_common/shader/img_22_nomul_afill_vert.shd
new file mode 100644 (file)
index 0000000..e6303d7
--- /dev/null
@@ -0,0 +1,20 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);
+   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);
+   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);
+   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);
+   div_s = vec4(4, 4, 4, 4);
+}
diff --git a/src/modules/engines/gl_common/shader/img_22_nomul_frag.h b/src/modules/engines/gl_common/shader/img_22_nomul_frag.h
new file mode 100644 (file)
index 0000000..2a7f073
--- /dev/null
@@ -0,0 +1,19 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;\n"
+"   vec4 col10 = texture2D(tex, tex_c + tex_s[2]).bgra;\n"
+"   vec4 col11 = texture2D(tex, tex_c + tex_s[3]).bgra;\n"
+"   gl_FragColor = (col00 + col01 + col10 + col11) / div_s;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_22_nomul_frag.shd b/src/modules/engines/gl_common/shader/img_22_nomul_frag.shd
new file mode 100644 (file)
index 0000000..3b87c09
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]).bgra;
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]).bgra;
+   vec4 col10 = texture2D(tex, tex_c + tex_s[2]).bgra;
+   vec4 col11 = texture2D(tex, tex_c + tex_s[3]).bgra;
+   gl_FragColor = (col00 + col01 + col10 + col11) / div_s;
+}
diff --git a/src/modules/engines/gl_common/shader/img_22_nomul_vert.h b/src/modules/engines/gl_common/shader/img_22_nomul_vert.h
new file mode 100644 (file)
index 0000000..c6fb270
--- /dev/null
@@ -0,0 +1,20 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);\n"
+"   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);\n"
+"   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);\n"
+"   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);\n"
+"   div_s = vec4(4, 4, 4, 4);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_22_nomul_vert.shd b/src/modules/engines/gl_common/shader/img_22_nomul_vert.shd
new file mode 100644 (file)
index 0000000..e6303d7
--- /dev/null
@@ -0,0 +1,20 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);
+   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);
+   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);
+   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);
+   div_s = vec4(4, 4, 4, 4);
+}
diff --git a/src/modules/engines/gl_common/shader/img_22_vert.h b/src/modules/engines/gl_common/shader/img_22_vert.h
new file mode 100644 (file)
index 0000000..e1fc7f4
--- /dev/null
@@ -0,0 +1,23 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);\n"
+"   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);\n"
+"   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);\n"
+"   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);\n"
+"   div_s = vec4(4, 4, 4, 4);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_22_vert.shd b/src/modules/engines/gl_common/shader/img_22_vert.shd
new file mode 100644 (file)
index 0000000..e964ea1
--- /dev/null
@@ -0,0 +1,23 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);
+   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);
+   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);
+   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);
+   div_s = vec4(4, 4, 4, 4);
+}
diff --git a/src/modules/engines/gl_common/shader/img_afill_frag.h b/src/modules/engines/gl_common/shader/img_afill_frag.h
new file mode 100644 (file)
index 0000000..366d618
--- /dev/null
@@ -0,0 +1,15 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"void main()\n"
+"{\n"
+"   vec4 c = texture2D(tex, tex_c.xy).bgra * col;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_afill_frag.shd b/src/modules/engines/gl_common/shader/img_afill_frag.shd
new file mode 100644 (file)
index 0000000..be6593a
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+void main()
+{
+   vec4 c = texture2D(tex, tex_c.xy).bgra * col;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/img_afill_vert.h b/src/modules/engines/gl_common/shader/img_afill_vert.h
new file mode 100644 (file)
index 0000000..8921d9d
--- /dev/null
@@ -0,0 +1,15 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_afill_vert.shd b/src/modules/engines/gl_common/shader/img_afill_vert.shd
new file mode 100644 (file)
index 0000000..606c297
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+}
diff --git a/src/modules/engines/gl_common/shader/img_bgra_afill_frag.h b/src/modules/engines/gl_common/shader/img_bgra_afill_frag.h
new file mode 100644 (file)
index 0000000..ffabd01
--- /dev/null
@@ -0,0 +1,15 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"void main()\n"
+"{\n"
+"   vec4 c = texture2D(tex, tex_c.xy) * col;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_bgra_afill_frag.shd b/src/modules/engines/gl_common/shader/img_bgra_afill_frag.shd
new file mode 100644 (file)
index 0000000..b951f60
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+void main()
+{
+   vec4 c = texture2D(tex, tex_c.xy) * col;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/img_bgra_afill_vert.h b/src/modules/engines/gl_common/shader/img_bgra_afill_vert.h
new file mode 100644 (file)
index 0000000..8921d9d
--- /dev/null
@@ -0,0 +1,15 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_bgra_afill_vert.shd b/src/modules/engines/gl_common/shader/img_bgra_afill_vert.shd
new file mode 100644 (file)
index 0000000..606c297
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+}
diff --git a/src/modules/engines/gl_common/shader/img_bgra_frag_bin_s3c6410.h b/src/modules/engines/gl_common/shader/img_bgra_frag_bin_s3c6410.h
deleted file mode 100644 (file)
index feb5bf5..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-0x20205350, 0xffff0008, 0x00000048, 0x01020000, 0x00000004, 0x00000003, 
-0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000001, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000e, 0x00000000, 
-0x00000000, 0x02025400, 0x23782050, 0x00000000, 0x00000000, 0x0100e407, 
-0x307820e4, 0x00000000, 0x01000000, 0x0100e400, 0x237a10e4, 0x00000000, 
-0x00000000, 0x00000000, 0x1e000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 
-0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000003, 
-0x00000009, 0x00000000, 0x00000004, 0x00000008, 0x00000005, 0x00000003, 
-0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x0000000f, 0x00030005, 
-0x00000000, 0x00786574, 0x006c6f63, 0x5f786574, 0x00000063, 
diff --git a/src/modules/engines/gl_common/shader/img_bgra_nomul_afill_frag.h b/src/modules/engines/gl_common/shader/img_bgra_nomul_afill_frag.h
new file mode 100644 (file)
index 0000000..43f7e63
--- /dev/null
@@ -0,0 +1,14 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"void main()\n"
+"{\n"
+"   vec4 c = texture2D(tex, tex_c.xy);\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_bgra_nomul_afill_frag.shd b/src/modules/engines/gl_common/shader/img_bgra_nomul_afill_frag.shd
new file mode 100644 (file)
index 0000000..569c32e
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+void main()
+{
+   vec4 c = texture2D(tex, tex_c.xy);
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/img_bgra_nomul_afill_vert.h b/src/modules/engines/gl_common/shader/img_bgra_nomul_afill_vert.h
new file mode 100644 (file)
index 0000000..13d5edd
--- /dev/null
@@ -0,0 +1,12 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_bgra_nomul_afill_vert.shd b/src/modules/engines/gl_common/shader/img_bgra_nomul_afill_vert.shd
new file mode 100644 (file)
index 0000000..74f3207
--- /dev/null
@@ -0,0 +1,12 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+uniform mat4 mvp;
+varying vec2 tex_c;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+}
diff --git a/src/modules/engines/gl_common/shader/img_bgra_nomul_frag_bin_s3c6410.h b/src/modules/engines/gl_common/shader/img_bgra_nomul_frag_bin_s3c6410.h
deleted file mode 100644 (file)
index b89eeb1..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-0x20205350, 0xffff0008, 0x00000048, 0x01020000, 0x00000003, 0x00000003, 
-0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000a, 0x00000000, 
-0x00000000, 0x02025400, 0x23782050, 0x00000000, 0x00000000, 0x0100e407, 
-0x307a10e4, 0x00000000, 0x00000000, 0x00000000, 0x1e000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 
-0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000004, 0x00000005, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 
-0x00000003, 0x0000000f, 0x00030005, 0x00000000, 0x00786574, 0x5f786574, 
-0x00000063, 
\ No newline at end of file
diff --git a/src/modules/engines/gl_common/shader/img_bgra_nomul_vert_bin_s3c6410.h b/src/modules/engines/gl_common/shader/img_bgra_nomul_vert_bin_s3c6410.h
deleted file mode 100644 (file)
index 314b5f3..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-0x20205356, 0xffff0008, 0x00000048, 0x01020000, 0x00000006, 0x00000006, 
-0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000001, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000027, 0x00000000, 
-0x00000000, 0x02020000, 0x237820e4, 0x00000000, 0x00e40100, 0x02035500, 
-0x2ef820e4, 0x00000000, 0x00e40100, 0x0204aa00, 0x2ef820e4, 0x00000000, 
-0x00e40100, 0x0205ff00, 0x2ef800e4, 0x00000000, 0x00000000, 0x00010000, 
-0x20980154, 0x00000000, 0x00000000, 0x00000000, 0x1e000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 
-0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x0000000c, 0x00000006, 0x00000009, 0x00000000, 0x00000000, 0x00000013, 
-0x00000009, 0x00000003, 0x00000000, 0x00000004, 0x00000000, 0x0000000b, 
-0x00000009, 0x00010004, 0x00000000, 0x00000021, 0x00000005, 0x00000003, 
-0x00010004, 0x00000004, 0x0000001d, 0x00000003, 0x0000000e, 0x00020001, 
-0x00000008, 0x505f6c67, 0x7469736f, 0x006e6f69, 0x74726576, 0x74007865, 
-0x635f7865, 0x64726f6f, 0x70766d00, 0x78657400, 0x0000635f, 
diff --git a/src/modules/engines/gl_common/shader/img_bgra_vert_bin_s3c6410.h b/src/modules/engines/gl_common/shader/img_bgra_vert_bin_s3c6410.h
deleted file mode 100644 (file)
index 1402448..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-0x20205356, 0xffff0008, 0x00000048, 0x01020000, 0x00000007, 0x00000006, 
-0x00000000, 0x00000000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000031, 0x00000000, 
-0x00000000, 0x02020000, 0x237820e4, 0x00000000, 0x00e40100, 0x02035500, 
-0x2ef820e4, 0x00000000, 0x00e40100, 0x0204aa00, 0x2ef820e4, 0x00000000, 
-0x00e40100, 0x0205ff00, 0x2ef800e4, 0x00000000, 0x00000000, 0x00010000, 
-0x20f801e4, 0x00000000, 0x00000000, 0x00020000, 0x20980254, 0x00000000, 
-0x00000000, 0x00000000, 0x1e000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000006, 
-0x00000009, 0x00000000, 0x00000000, 0x00000013, 0x00000005, 0x00000009, 
-0x00000000, 0x00000004, 0x00000019, 0x00000009, 0x00000003, 0x00000000, 
-0x00000008, 0x00000000, 0x0000000b, 0x00000009, 0x00010004, 0x00000000, 
-0x00000027, 0x00000003, 0x00000009, 0x00010004, 0x00000004, 0x0000002b, 
-0x00000005, 0x00000003, 0x00010004, 0x00000008, 0x00000023, 0x00000003, 
-0x0000000e, 0x00020001, 0x00000008, 0x505f6c67, 0x7469736f, 0x006e6f69, 
-0x74726576, 0x63007865, 0x726f6c6f, 0x78657400, 0x6f6f635f, 0x6d006472, 
-0x63007076, 0x74006c6f, 0x635f7865, 0x00000000, 
\ No newline at end of file
diff --git a/src/modules/engines/gl_common/shader/img_frag_bin_s3c6410.h b/src/modules/engines/gl_common/shader/img_frag_bin_s3c6410.h
deleted file mode 100644 (file)
index 3518e8d..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-0x20205350, 0xffff0008, 0x00000048, 0x01020000, 0x00000003, 0x00000000, 
-0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000001, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000e, 0x00000000, 
-0x00000000, 0x0000e407, 0x307820e4, 0x00000000, 0x01000000, 0x0100e400, 
-0x237a10c6, 0x00000000, 0x00000000, 0x00000000, 0x1e000000, 0x00000000, 
-0x00000004, 0x00000003, 0x00000009, 0x00000000, 0x00000004, 0x00000008, 
-0x00000005, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 
-0x0000000f, 0x00030005, 0x00000000, 0x00786574, 0x006c6f63, 0x5f786574, 
-0x00000063, 
\ No newline at end of file
diff --git a/src/modules/engines/gl_common/shader/img_frag_s3c6410.asm b/src/modules/engines/gl_common/shader/img_frag_s3c6410.asm
deleted file mode 100644 (file)
index 3716bce..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-
-#-------------------------------------------------
-# ORION - OpenGL ES 2.0 Shading Language Compiler
-# SAMSUNG INDIA SOFTWARE OPERATIONS PVT. LTD.
-# Compiler Version     : v04.00.09
-# Release Date         : 19.01.2009
-# FIMG VERSION      : FIMGv1.5
-# Optimizer Options :  -O --nolodcalc
-#-------------------------------------------------
-
-# hand optimised - removed useless ops
-
-ps_3_0
-
-fimg_version   0x01020000
-
-dcl_s2_tex     s0
-dcl_f4_col     v1.x
-dcl_f2_tex_c   v0.x
-
-label start
-label main_
-texld r0.xyzw, v0.xyzw, s0     # tex=s0
-mul_sat oColor.xyzw, r0.zyxw, v1.xyzw  # gl_FragColor=oColor.xyzw, col=v1.xyzw
-label main_end
-ret
diff --git a/src/modules/engines/gl_common/shader/img_map_mask_bgra_frag.shd b/src/modules/engines/gl_common/shader/img_map_mask_bgra_frag.shd
new file mode 100644 (file)
index 0000000..ad56737
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+uniform sampler2D texm;
+varying vec4 col;
+varying vec2 coord_c;
+varying vec2 coord_m;
+void main()
+{
+   gl_FragColor = texture2D(texm, coord_m.xy).a * texture2D(tex, coord_c.xy) * col;
+}
+
diff --git a/src/modules/engines/gl_common/shader/img_map_mask_bgra_vert.shd b/src/modules/engines/gl_common/shader/img_map_mask_bgra_vert.shd
new file mode 100644 (file)
index 0000000..df24781
--- /dev/null
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_coordm;
+attribute vec2 tex_sample; // mask vertex
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 coord_c;
+varying vec2 coord_m;
+void main()
+{
+   gl_Position = mvp * vertex;
+   mask_Position = mvp * vec4(tex_sample.xy, 0, 0);
+   col = color;
+   coord_c = tex_coord;
+   coord_m = tex_coordm;
+}
+
diff --git a/src/modules/engines/gl_common/shader/img_mask_bgra_frag.h b/src/modules/engines/gl_common/shader/img_mask_bgra_frag.h
new file mode 100644 (file)
index 0000000..47c4d78
--- /dev/null
@@ -0,0 +1,17 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"uniform sampler2D texm;\n"
+"varying vec4 col;\n"
+"varying vec2 coord_c;\n"
+"varying vec2 coord_m;\n"
+"void main()\n"
+"{\n"
+"   gl_FragColor = texture2D(texm, coord_m.xy).a * texture2D(tex, coord_c.xy) * col;\n"
+"}\n"
+"\n"
diff --git a/src/modules/engines/gl_common/shader/img_mask_bgra_frag.shd b/src/modules/engines/gl_common/shader/img_mask_bgra_frag.shd
new file mode 100644 (file)
index 0000000..ad56737
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+uniform sampler2D texm;
+varying vec4 col;
+varying vec2 coord_c;
+varying vec2 coord_m;
+void main()
+{
+   gl_FragColor = texture2D(texm, coord_m.xy).a * texture2D(tex, coord_c.xy) * col;
+}
+
diff --git a/src/modules/engines/gl_common/shader/img_mask_bgra_nomul_frag.h b/src/modules/engines/gl_common/shader/img_mask_bgra_nomul_frag.h
new file mode 100644 (file)
index 0000000..0af00b3
--- /dev/null
@@ -0,0 +1,16 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"uniform sampler2D texm;\n"
+"varying vec2 coord_c;\n"
+"varying vec2 coord_m;\n"
+"void main()\n"
+"{\n"
+"   gl_FragColor = texture2D(texm, coord_m.xy).a * texture2D(tex, coord_c.xy);\n"
+"}\n"
+"\n"
diff --git a/src/modules/engines/gl_common/shader/img_mask_bgra_nomul_frag.shd b/src/modules/engines/gl_common/shader/img_mask_bgra_nomul_frag.shd
new file mode 100644 (file)
index 0000000..5fc393b
--- /dev/null
@@ -0,0 +1,16 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+uniform sampler2D texm;
+varying vec2 coord_c;
+varying vec2 coord_m;
+void main()
+{
+   gl_FragColor = texture2D(texm, coord_m.xy).a * texture2D(tex, coord_c.xy);
+}
+
diff --git a/src/modules/engines/gl_common/shader/img_mask_bgra_nomul_vert.h b/src/modules/engines/gl_common/shader/img_mask_bgra_nomul_vert.h
new file mode 100644 (file)
index 0000000..6d70ab5
--- /dev/null
@@ -0,0 +1,16 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_coordm;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 coord_c;\n"
+"varying vec2 coord_m;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   coord_c = tex_coord;\n"
+"   coord_m = tex_coordm;\n"
+"}\n"
+"\n"
diff --git a/src/modules/engines/gl_common/shader/img_mask_bgra_nomul_vert.shd b/src/modules/engines/gl_common/shader/img_mask_bgra_nomul_vert.shd
new file mode 100644 (file)
index 0000000..973402f
--- /dev/null
@@ -0,0 +1,16 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_coordm;
+uniform mat4 mvp;
+varying vec2 coord_c;
+varying vec2 coord_m;
+void main()
+{
+   gl_Position = mvp * vertex;
+   coord_c = tex_coord;
+   coord_m = tex_coordm;
+}
+
diff --git a/src/modules/engines/gl_common/shader/img_mask_bgra_vert.h b/src/modules/engines/gl_common/shader/img_mask_bgra_vert.h
new file mode 100644 (file)
index 0000000..668aa99
--- /dev/null
@@ -0,0 +1,19 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_coordm;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 coord_c;\n"
+"varying vec2 coord_m;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   coord_c = tex_coord;\n"
+"   coord_m = tex_coordm;\n"
+"}\n"
+"\n"
diff --git a/src/modules/engines/gl_common/shader/img_mask_bgra_vert.shd b/src/modules/engines/gl_common/shader/img_mask_bgra_vert.shd
new file mode 100644 (file)
index 0000000..04da2aa
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_coordm;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 coord_c;
+varying vec2 coord_m;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   coord_c = tex_coord;
+   coord_m = tex_coordm;
+}
+
index 1b28128..174c3ed 100644 (file)
@@ -5,11 +5,13 @@
 "precision mediump float;\n"
 "#endif\n"
 "#endif\n"
-"uniform sampler2D tex, texm;\n"
+"uniform sampler2D tex;\n"
+"uniform sampler2D texm;\n"
 "varying vec4 col;\n"
-"varying vec2 tex_c, tex_cm;\n"
+"varying vec2 coord_c;\n"
+"varying vec2 coord_m;\n"
 "void main()\n"
 "{\n"
-"   gl_FragColor = texture2D(texm, tex_cm.xy).aaaa * texture2D(tex, tex_c.xy).rgba * col;\n"
+"   gl_FragColor = texture2D(texm, coord_m.xy).a * texture2D(tex, coord_c.xy).bgra * col;\n"
 "}\n"
 "\n"
index 0b7307e..34b1af9 100644 (file)
@@ -5,11 +5,13 @@ precision highp float;
 precision mediump float;
 #endif
 #endif
-uniform sampler2D tex, texm;
+uniform sampler2D tex;
+uniform sampler2D texm;
 varying vec4 col;
-varying vec2 tex_c, tex_cm;
+varying vec2 coord_c;
+varying vec2 coord_m;
 void main()
 {
-   gl_FragColor = texture2D(texm, tex_cm.xy).aaaa * texture2D(tex, tex_c.xy).rgba * col;
+   gl_FragColor = texture2D(texm, coord_m.xy).a * texture2D(tex, coord_c.xy).bgra * col;
 }
 
diff --git a/src/modules/engines/gl_common/shader/img_mask_nomul_frag.h b/src/modules/engines/gl_common/shader/img_mask_nomul_frag.h
new file mode 100644 (file)
index 0000000..bcadf46
--- /dev/null
@@ -0,0 +1,16 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"uniform sampler2D texm;\n"
+"varying vec2 coord_c;\n"
+"varying vec2 coord_m;\n"
+"void main()\n"
+"{\n"
+"   gl_FragColor = texture2D(tex, coord_c.xy) * texture2D(texm, coord_m).a;\n"
+"}\n"
+"\n"
diff --git a/src/modules/engines/gl_common/shader/img_mask_nomul_frag.shd b/src/modules/engines/gl_common/shader/img_mask_nomul_frag.shd
new file mode 100644 (file)
index 0000000..e172ebe
--- /dev/null
@@ -0,0 +1,16 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+uniform sampler2D texm;
+varying vec2 coord_c;
+varying vec2 coord_m;
+void main()
+{
+   gl_FragColor = texture2D(tex, coord_c.xy) * texture2D(texm, coord_m).a;
+}
+
diff --git a/src/modules/engines/gl_common/shader/img_mask_nomul_vert.h b/src/modules/engines/gl_common/shader/img_mask_nomul_vert.h
new file mode 100644 (file)
index 0000000..6d70ab5
--- /dev/null
@@ -0,0 +1,16 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_coordm;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 coord_c;\n"
+"varying vec2 coord_m;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   coord_c = tex_coord;\n"
+"   coord_m = tex_coordm;\n"
+"}\n"
+"\n"
diff --git a/src/modules/engines/gl_common/shader/img_mask_nomul_vert.shd b/src/modules/engines/gl_common/shader/img_mask_nomul_vert.shd
new file mode 100644 (file)
index 0000000..973402f
--- /dev/null
@@ -0,0 +1,16 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_coordm;
+uniform mat4 mvp;
+varying vec2 coord_c;
+varying vec2 coord_m;
+void main()
+{
+   gl_Position = mvp * vertex;
+   coord_c = tex_coord;
+   coord_m = tex_coordm;
+}
+
index 7508c98..668aa99 100644 (file)
@@ -3,14 +3,17 @@
 "#endif\n"
 "attribute vec4 vertex;\n"
 "attribute vec4 color;\n"
-"attribute vec2 tex_coord, tex_coordm;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_coordm;\n"
 "uniform mat4 mvp;\n"
 "varying vec4 col;\n"
-"varying vec2 tex_c, tex_cm;\n"
+"varying vec2 coord_c;\n"
+"varying vec2 coord_m;\n"
 "void main()\n"
 "{\n"
 "   gl_Position = mvp * vertex;\n"
 "   col = color;\n"
-"   tex_c = tex_coord;\n"
-"   tex_cm = tex_coordm;\n"
+"   coord_c = tex_coord;\n"
+"   coord_m = tex_coordm;\n"
 "}\n"
+"\n"
index 1414870..04da2aa 100644 (file)
@@ -3,14 +3,17 @@ precision highp float;
 #endif
 attribute vec4 vertex;
 attribute vec4 color;
-attribute vec2 tex_coord, tex_coordm;
+attribute vec2 tex_coord;
+attribute vec2 tex_coordm;
 uniform mat4 mvp;
 varying vec4 col;
-varying vec2 tex_c, tex_cm;
+varying vec2 coord_c;
+varying vec2 coord_m;
 void main()
 {
    gl_Position = mvp * vertex;
    col = color;
-   tex_c = tex_coord;
-   tex_cm = tex_coordm;
+   coord_c = tex_coord;
+   coord_m = tex_coordm;
 }
+
diff --git a/src/modules/engines/gl_common/shader/img_nomul_afill_frag.h b/src/modules/engines/gl_common/shader/img_nomul_afill_frag.h
new file mode 100644 (file)
index 0000000..fc4b9a8
--- /dev/null
@@ -0,0 +1,14 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"void main()\n"
+"{\n"
+"   vec4 c = texture2D(tex, tex_c.xy).bgra;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_nomul_afill_frag.shd b/src/modules/engines/gl_common/shader/img_nomul_afill_frag.shd
new file mode 100644 (file)
index 0000000..f8bd252
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+void main()
+{
+   vec4 c = texture2D(tex, tex_c.xy).bgra;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/img_nomul_afill_vert.h b/src/modules/engines/gl_common/shader/img_nomul_afill_vert.h
new file mode 100644 (file)
index 0000000..13d5edd
--- /dev/null
@@ -0,0 +1,12 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/img_nomul_afill_vert.shd b/src/modules/engines/gl_common/shader/img_nomul_afill_vert.shd
new file mode 100644 (file)
index 0000000..74f3207
--- /dev/null
@@ -0,0 +1,12 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+uniform mat4 mvp;
+varying vec2 tex_c;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+}
diff --git a/src/modules/engines/gl_common/shader/img_nomul_frag_bin_s3c6410.h b/src/modules/engines/gl_common/shader/img_nomul_frag_bin_s3c6410.h
deleted file mode 100644 (file)
index 61662c8..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-0x20205350, 0xffff0008, 0x00000048, 0x01020000, 0x00000003, 0x00000003, 
-0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000a, 0x00000000, 
-0x00000000, 0x02025400, 0x23782050, 0x00000000, 0x00000000, 0x0100e407, 
-0x307a10c6, 0x00000000, 0x00000000, 0x00000000, 0x1e000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 
-0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000004, 0x00000005, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 
-0x00000003, 0x0000000f, 0x00030005, 0x00000000, 0x00786574, 0x5f786574, 
-0x00000063, 
\ No newline at end of file
diff --git a/src/modules/engines/gl_common/shader/img_nomul_vert_bin_s3c6410.h b/src/modules/engines/gl_common/shader/img_nomul_vert_bin_s3c6410.h
deleted file mode 100644 (file)
index 314b5f3..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-0x20205356, 0xffff0008, 0x00000048, 0x01020000, 0x00000006, 0x00000006, 
-0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000001, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000027, 0x00000000, 
-0x00000000, 0x02020000, 0x237820e4, 0x00000000, 0x00e40100, 0x02035500, 
-0x2ef820e4, 0x00000000, 0x00e40100, 0x0204aa00, 0x2ef820e4, 0x00000000, 
-0x00e40100, 0x0205ff00, 0x2ef800e4, 0x00000000, 0x00000000, 0x00010000, 
-0x20980154, 0x00000000, 0x00000000, 0x00000000, 0x1e000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 
-0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x0000000c, 0x00000006, 0x00000009, 0x00000000, 0x00000000, 0x00000013, 
-0x00000009, 0x00000003, 0x00000000, 0x00000004, 0x00000000, 0x0000000b, 
-0x00000009, 0x00010004, 0x00000000, 0x00000021, 0x00000005, 0x00000003, 
-0x00010004, 0x00000004, 0x0000001d, 0x00000003, 0x0000000e, 0x00020001, 
-0x00000008, 0x505f6c67, 0x7469736f, 0x006e6f69, 0x74726576, 0x74007865, 
-0x635f7865, 0x64726f6f, 0x70766d00, 0x78657400, 0x0000635f, 
diff --git a/src/modules/engines/gl_common/shader/img_vert_bin_s3c6410.h b/src/modules/engines/gl_common/shader/img_vert_bin_s3c6410.h
deleted file mode 100644 (file)
index 1402448..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-0x20205356, 0xffff0008, 0x00000048, 0x01020000, 0x00000007, 0x00000006, 
-0x00000000, 0x00000000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000031, 0x00000000, 
-0x00000000, 0x02020000, 0x237820e4, 0x00000000, 0x00e40100, 0x02035500, 
-0x2ef820e4, 0x00000000, 0x00e40100, 0x0204aa00, 0x2ef820e4, 0x00000000, 
-0x00e40100, 0x0205ff00, 0x2ef800e4, 0x00000000, 0x00000000, 0x00010000, 
-0x20f801e4, 0x00000000, 0x00000000, 0x00020000, 0x20980254, 0x00000000, 
-0x00000000, 0x00000000, 0x1e000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000006, 
-0x00000009, 0x00000000, 0x00000000, 0x00000013, 0x00000005, 0x00000009, 
-0x00000000, 0x00000004, 0x00000019, 0x00000009, 0x00000003, 0x00000000, 
-0x00000008, 0x00000000, 0x0000000b, 0x00000009, 0x00010004, 0x00000000, 
-0x00000027, 0x00000003, 0x00000009, 0x00010004, 0x00000004, 0x0000002b, 
-0x00000005, 0x00000003, 0x00010004, 0x00000008, 0x00000023, 0x00000003, 
-0x0000000e, 0x00020001, 0x00000008, 0x505f6c67, 0x7469736f, 0x006e6f69, 
-0x74726576, 0x63007865, 0x726f6c6f, 0x78657400, 0x6f6f635f, 0x6d006472, 
-0x63007076, 0x74006c6f, 0x635f7865, 0x00000000, 
\ No newline at end of file
diff --git a/src/modules/engines/gl_common/shader/make-c-bin.sh b/src/modules/engines/gl_common/shader/make-c-bin.sh
deleted file mode 100755 (executable)
index 2902df6..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-od --width=4 -t x4 -v $1 | \
-awk '{ if (NF > 1) printf("0x%s, ", $2); L = L + 1; if (L > 5) { L = 0; printf("\n");}}'
diff --git a/src/modules/engines/gl_common/shader/map_mask_bgra_frag.h b/src/modules/engines/gl_common/shader/map_mask_bgra_frag.h
new file mode 100644 (file)
index 0000000..d81f5b0
--- /dev/null
@@ -0,0 +1,15 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex, texm;\n"
+"varying vec2 tex_c, tex_m;\n"
+"varying vec4 col;\n"
+"void main()\n"
+"{\n"
+"   // FIXME: Fix Mach band effect using proper 4-point color interpolation\n"
+"   gl_FragColor = texture2D(tex, tex_c) * texture2D(texm, tex_m).a *  col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/map_mask_bgra_frag.shd b/src/modules/engines/gl_common/shader/map_mask_bgra_frag.shd
new file mode 100644 (file)
index 0000000..be952b7
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex, texm;
+varying vec2 tex_c, tex_m;
+varying vec4 col;
+void main()
+{
+   // FIXME: Fix Mach band effect using proper 4-point color interpolation
+   gl_FragColor = texture2D(tex, tex_c) * texture2D(texm, tex_m).a *  col;
+}
diff --git a/src/modules/engines/gl_common/shader/map_mask_bgra_nomul_frag.h b/src/modules/engines/gl_common/shader/map_mask_bgra_nomul_frag.h
new file mode 100644 (file)
index 0000000..b4b77ef
--- /dev/null
@@ -0,0 +1,13 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex, texm;\n"
+"varying vec2 tex_c, tex_m;\n"
+"void main()\n"
+"{\n"
+"   gl_FragColor = texture2D(tex, tex_c) * texture2D(texm, tex_m).a;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/map_mask_bgra_nomul_frag.shd b/src/modules/engines/gl_common/shader/map_mask_bgra_nomul_frag.shd
new file mode 100644 (file)
index 0000000..a1ce622
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex, texm;
+varying vec2 tex_c, tex_m;
+void main()
+{
+   gl_FragColor = texture2D(tex, tex_c) * texture2D(texm, tex_m).a;
+}
diff --git a/src/modules/engines/gl_common/shader/map_mask_bgra_nomul_vert.h b/src/modules/engines/gl_common/shader/map_mask_bgra_nomul_vert.h
new file mode 100644 (file)
index 0000000..2c1933b
--- /dev/null
@@ -0,0 +1,17 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord, tex_coordm, tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c, tex_m;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"\n"
+"   // tex_sample contains the Y-invert flag\n"
+"   // position on screen in [0..1] range of current pixel\n"
+"   vec4 mask_Position = mvp * vertex * vec4(0.5, sign(tex_sample.y) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);\n"
+"   tex_m = mask_Position.xy * abs(tex_sample) + tex_coordm;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/map_mask_bgra_nomul_vert.shd b/src/modules/engines/gl_common/shader/map_mask_bgra_nomul_vert.shd
new file mode 100644 (file)
index 0000000..e526be8
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord, tex_coordm, tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c, tex_m;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+
+   // tex_sample contains the Y-invert flag
+   // position on screen in [0..1] range of current pixel
+   vec4 mask_Position = mvp * vertex * vec4(0.5, sign(tex_sample.y) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);
+   tex_m = mask_Position.xy * abs(tex_sample) + tex_coordm;
+}
diff --git a/src/modules/engines/gl_common/shader/map_mask_bgra_vert.h b/src/modules/engines/gl_common/shader/map_mask_bgra_vert.h
new file mode 100644 (file)
index 0000000..c3cb03a
--- /dev/null
@@ -0,0 +1,19 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex, color;\n"
+"attribute vec2 tex_coord, tex_coordm, tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c, tex_m;\n"
+"varying vec4 col;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   col = color;\n"
+"\n"
+"   // tex_coorda contains the Y-invert flag\n"
+"   // position on screen in [0..1] range of current pixel\n"
+"   vec4 mask_Position = mvp * vertex * vec4(0.5, sign(tex_sample.y) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);\n"
+"   tex_m = mask_Position.xy * abs(tex_sample) + tex_coordm;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/map_mask_bgra_vert.shd b/src/modules/engines/gl_common/shader/map_mask_bgra_vert.shd
new file mode 100644 (file)
index 0000000..cf3720d
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex, color;
+attribute vec2 tex_coord, tex_coordm, tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c, tex_m;
+varying vec4 col;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   col = color;
+
+   // tex_coorda contains the Y-invert flag
+   // position on screen in [0..1] range of current pixel
+   vec4 mask_Position = mvp * vertex * vec4(0.5, sign(tex_sample.y) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);
+   tex_m = mask_Position.xy * abs(tex_sample) + tex_coordm;
+}
diff --git a/src/modules/engines/gl_common/shader/map_mask_frag.h b/src/modules/engines/gl_common/shader/map_mask_frag.h
new file mode 100644 (file)
index 0000000..400834a
--- /dev/null
@@ -0,0 +1,15 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex, texm;\n"
+"varying vec2 tex_c, tex_m;\n"
+"varying vec4 col;\n"
+"void main()\n"
+"{\n"
+"   // FIXME: Fix Mach band effect using proper 4-point color interpolation\n"
+"   gl_FragColor = texture2D(tex, tex_c).bgra * texture2D(texm, tex_m).a *  col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/map_mask_frag.shd b/src/modules/engines/gl_common/shader/map_mask_frag.shd
new file mode 100644 (file)
index 0000000..17e91f4
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex, texm;
+varying vec2 tex_c, tex_m;
+varying vec4 col;
+void main()
+{
+   // FIXME: Fix Mach band effect using proper 4-point color interpolation
+   gl_FragColor = texture2D(tex, tex_c).bgra * texture2D(texm, tex_m).a *  col;
+}
diff --git a/src/modules/engines/gl_common/shader/map_mask_nomul_frag.h b/src/modules/engines/gl_common/shader/map_mask_nomul_frag.h
new file mode 100644 (file)
index 0000000..ca99121
--- /dev/null
@@ -0,0 +1,13 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex, texm;\n"
+"varying vec2 tex_c, tex_m;\n"
+"void main()\n"
+"{\n"
+"   gl_FragColor = texture2D(tex, tex_c).bgra * texture2D(texm, tex_m).a;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/map_mask_nomul_frag.shd b/src/modules/engines/gl_common/shader/map_mask_nomul_frag.shd
new file mode 100644 (file)
index 0000000..0720d58
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex, texm;
+varying vec2 tex_c, tex_m;
+void main()
+{
+   gl_FragColor = texture2D(tex, tex_c).bgra * texture2D(texm, tex_m).a;
+}
diff --git a/src/modules/engines/gl_common/shader/map_mask_nomul_vert.h b/src/modules/engines/gl_common/shader/map_mask_nomul_vert.h
new file mode 100644 (file)
index 0000000..9d4b74c
--- /dev/null
@@ -0,0 +1,17 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord, tex_coordm, tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c, tex_m;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"\n"
+"   // tex_coorda contains the Y-invert flag\n"
+"   // position on screen in [0..1] range of current pixel\n"
+"   vec4 mask_Position = mvp * vertex * vec4(0.5, sign(tex_sample.y) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);\n"
+"   tex_m = mask_Position.xy * abs(tex_sample) + tex_coordm;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/map_mask_nomul_vert.shd b/src/modules/engines/gl_common/shader/map_mask_nomul_vert.shd
new file mode 100644 (file)
index 0000000..f22f3ab
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord, tex_coordm, tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c, tex_m;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+
+   // tex_coorda contains the Y-invert flag
+   // position on screen in [0..1] range of current pixel
+   vec4 mask_Position = mvp * vertex * vec4(0.5, sign(tex_sample.y) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);
+   tex_m = mask_Position.xy * abs(tex_sample) + tex_coordm;
+}
diff --git a/src/modules/engines/gl_common/shader/map_mask_vert.h b/src/modules/engines/gl_common/shader/map_mask_vert.h
new file mode 100644 (file)
index 0000000..c3cb03a
--- /dev/null
@@ -0,0 +1,19 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex, color;\n"
+"attribute vec2 tex_coord, tex_coordm, tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c, tex_m;\n"
+"varying vec4 col;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   col = color;\n"
+"\n"
+"   // tex_coorda contains the Y-invert flag\n"
+"   // position on screen in [0..1] range of current pixel\n"
+"   vec4 mask_Position = mvp * vertex * vec4(0.5, sign(tex_sample.y) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);\n"
+"   tex_m = mask_Position.xy * abs(tex_sample) + tex_coordm;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/map_mask_vert.shd b/src/modules/engines/gl_common/shader/map_mask_vert.shd
new file mode 100644 (file)
index 0000000..cf3720d
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex, color;
+attribute vec2 tex_coord, tex_coordm, tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c, tex_m;
+varying vec4 col;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   col = color;
+
+   // tex_coorda contains the Y-invert flag
+   // position on screen in [0..1] range of current pixel
+   vec4 mask_Position = mvp * vertex * vec4(0.5, sign(tex_sample.y) * 0.5, 0.5, 0.5) + vec4(0.5, 0.5, 0, 0);
+   tex_m = mask_Position.xy * abs(tex_sample) + tex_coordm;
+}
diff --git a/src/modules/engines/gl_common/shader/nv12_mask_frag.h b/src/modules/engines/gl_common/shader/nv12_mask_frag.h
new file mode 100644 (file)
index 0000000..f10f0fb
--- /dev/null
@@ -0,0 +1,31 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex, texuv, texm;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c, tex_cuv, tex_m;\n"
+"void main()\n"
+"{\n"
+"  float y,u,v,vmu,r,g,b;\n"
+"  y=texture2D(tex,tex_c).g;\n"
+"  u=texture2D(texuv,tex_cuv).g;\n"
+"  v=texture2D(texuv,tex_cuv).a;\n"
+"\n"
+"  u=u-0.5;\n"
+"  v=v-0.5;\n"
+"  vmu=v*0.813+u*0.391;\n"
+"  u=u*2.018;\n"
+"  v=v*1.596;\n"
+"  y=(y-0.062)*1.164;\n"
+"\n"
+"  r=y+v;\n"
+"  g=y-vmu;\n"
+"  b=y+u;\n"
+"\n"
+"  gl_FragColor = vec4(r,g,b,1.0) * texture2D(tex, tex_m.xy).a * col;\n"
+"}\n"
+"\n"
diff --git a/src/modules/engines/gl_common/shader/nv12_mask_frag.shd b/src/modules/engines/gl_common/shader/nv12_mask_frag.shd
new file mode 100644 (file)
index 0000000..aa221d1
--- /dev/null
@@ -0,0 +1,31 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex, texuv, texm;
+varying vec4 col;
+varying vec2 tex_c, tex_cuv, tex_m;
+void main()
+{
+  float y,u,v,vmu,r,g,b;
+  y=texture2D(tex,tex_c).g;
+  u=texture2D(texuv,tex_cuv).g;
+  v=texture2D(texuv,tex_cuv).a;
+
+  u=u-0.5;
+  v=v-0.5;
+  vmu=v*0.813+u*0.391;
+  u=u*2.018;
+  v=v*1.596;
+  y=(y-0.062)*1.164;
+
+  r=y+v;
+  g=y-vmu;
+  b=y+u;
+
+  gl_FragColor = vec4(r,g,b,1.0) * texture2D(tex, tex_m.xy).a * col;
+}
+
diff --git a/src/modules/engines/gl_common/shader/nv12_mask_vert.h b/src/modules/engines/gl_common/shader/nv12_mask_vert.h
new file mode 100644 (file)
index 0000000..3883254
--- /dev/null
@@ -0,0 +1,17 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord, tex_coord2, tex_coordm;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c, tex_cuv, tex_m;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_cuv = tex_coord2 * 0.5;\n"
+"   tex_m = tex_coordm;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/nv12_mask_vert.shd b/src/modules/engines/gl_common/shader/nv12_mask_vert.shd
new file mode 100644 (file)
index 0000000..b77a0a5
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord, tex_coord2, tex_coordm;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c, tex_cuv, tex_m;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_cuv = tex_coord2 * 0.5;
+   tex_m = tex_coordm;
+}
diff --git a/src/modules/engines/gl_common/shader/rect_frag_bin_s3c6410.h b/src/modules/engines/gl_common/shader/rect_frag_bin_s3c6410.h
deleted file mode 100644 (file)
index ee94467..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-0x20205350, 0xffff0008, 0x00000048, 0x01020000, 0x00000002, 0x00000000, 
-0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 
-0x00000000, 0x00000000, 0x20fa10e4, 0x00000000, 0x00000000, 0x00000000, 
-0x1e000000, 0x00000000, 0x00000000, 0x00000003, 0x00000009, 0x00000000, 
-0x00000000, 0x006c6f63, 
\ No newline at end of file
diff --git a/src/modules/engines/gl_common/shader/rect_frag_s3c6410.asm b/src/modules/engines/gl_common/shader/rect_frag_s3c6410.asm
deleted file mode 100644 (file)
index 24c47ac..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-
-#-------------------------------------------------
-# ORION - OpenGL ES 2.0 Shading Language Compiler
-# SAMSUNG INDIA SOFTWARE OPERATIONS PVT. LTD.
-# Compiler Version     : v04.00.09
-# Release Date         : 19.01.2009
-# FIMG VERSION      : FIMGv1.5
-# Optimizer Options :  -O --nolodcalc
-#-------------------------------------------------
-
-# hand optimised - removed useless ops
-
-ps_3_0
-
-fimg_version   0x01020000
-
-dcl_f4_col     v0.x
-
-label start
-label main_
-label main_end
-mov_sat oColor.xyzw, v0.xyzw
-ret
-
diff --git a/src/modules/engines/gl_common/shader/rect_mask_frag.h b/src/modules/engines/gl_common/shader/rect_mask_frag.h
new file mode 100644 (file)
index 0000000..eca094a
--- /dev/null
@@ -0,0 +1,14 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D texm;\n"
+"varying vec4 col;\n"
+"varying vec4 coord_m;\n"
+"void main()\n"
+"{\n"
+"   gl_FragColor = texture2D(texm, coord_m.xy).a * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/rect_mask_frag.shd b/src/modules/engines/gl_common/shader/rect_mask_frag.shd
new file mode 100644 (file)
index 0000000..e278ea6
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D texm;
+varying vec4 col;
+varying vec4 coord_m;
+void main()
+{
+   gl_FragColor = texture2D(texm, coord_m.xy).a * col;
+}
diff --git a/src/modules/engines/gl_common/shader/rect_mask_vert.h b/src/modules/engines/gl_common/shader/rect_mask_vert.h
new file mode 100644 (file)
index 0000000..17dfb9a
--- /dev/null
@@ -0,0 +1,15 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec4 tex_coordm;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec4 coord_m;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   coord_m = tex_coordm;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/rect_mask_vert.shd b/src/modules/engines/gl_common/shader/rect_mask_vert.shd
new file mode 100644 (file)
index 0000000..4a1dd2c
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec4 tex_coordm;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec4 coord_m;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   coord_m = tex_coordm;
+}
diff --git a/src/modules/engines/gl_common/shader/rect_vert_bin_s3c6410.h b/src/modules/engines/gl_common/shader/rect_vert_bin_s3c6410.h
deleted file mode 100644 (file)
index 3130684..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-0x20205356, 0xffff0008, 0x00000048, 0x01020000, 0x00000006, 0x00000006, 
-0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000001, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000021, 0x00000000, 
-0x00000000, 0x02020000, 0x237820e4, 0x00000000, 0x00e40100, 0x02035500, 
-0x2ef820e4, 0x00000000, 0x00e40100, 0x0204aa00, 0x2ef820e4, 0x00000000, 
-0x00e40100, 0x0205ff00, 0x2ef800e4, 0x00000000, 0x00000000, 0x00010000, 
-0x20f801e4, 0x00000000, 0x00000000, 0x00000000, 0x1e000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 
-0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x0000000c, 0x00000006, 0x00000009, 0x00000000, 0x00000000, 0x00000013, 
-0x00000005, 0x00000009, 0x00000000, 0x00000004, 0x00000000, 0x0000000b, 
-0x00000009, 0x00010004, 0x00000000, 0x0000001d, 0x00000003, 0x00000009, 
-0x00010004, 0x00000004, 0x00000019, 0x00000003, 0x0000000e, 0x00020001, 
-0x00000008, 0x505f6c67, 0x7469736f, 0x006e6f69, 0x74726576, 0x63007865, 
-0x726f6c6f, 0x70766d00, 0x6c6f6300, 0x00000000, 
\ No newline at end of file
diff --git a/src/modules/engines/gl_common/shader/rgb_a_pair_frag.h b/src/modules/engines/gl_common/shader/rgb_a_pair_frag.h
new file mode 100644 (file)
index 0000000..168709d
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"uniform sampler2D texm;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_a;\n"
+"void main()\n"
+"{\n"
+"   gl_FragColor.rgb = texture2D(tex, tex_c.xy).rgb * col.rgb * texture2D(texm, tex_a).g;\n"
+"   gl_FragColor.a = col.a * texture2D(texm, tex_a).g;\n"
+"}\n"
+"\n"
diff --git a/src/modules/engines/gl_common/shader/rgb_a_pair_frag.shd b/src/modules/engines/gl_common/shader/rgb_a_pair_frag.shd
new file mode 100644 (file)
index 0000000..5dab4d0
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+uniform sampler2D texm;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_a;
+void main()
+{
+   gl_FragColor.rgb = texture2D(tex, tex_c.xy).rgb * col.rgb * texture2D(texm, tex_a).g;
+   gl_FragColor.a = col.a * texture2D(texm, tex_a).g;
+}
+
diff --git a/src/modules/engines/gl_common/shader/rgb_a_pair_nomul_frag.h b/src/modules/engines/gl_common/shader/rgb_a_pair_nomul_frag.h
new file mode 100644 (file)
index 0000000..c48aee4
--- /dev/null
@@ -0,0 +1,16 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"uniform sampler2D texm;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_a;\n"
+"void main()\n"
+"{\n"
+"   gl_FragColor.rgb = texture2D(tex, tex_c.xy).rgb * texture2D(texm, tex_a).g;\n"
+"   gl_FragColor.a   = texture2D(texm, tex_a).g;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/rgb_a_pair_nomul_frag.shd b/src/modules/engines/gl_common/shader/rgb_a_pair_nomul_frag.shd
new file mode 100644 (file)
index 0000000..6baba6c
--- /dev/null
@@ -0,0 +1,16 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+uniform sampler2D texm;
+varying vec2 tex_c;
+varying vec2 tex_a;
+void main()
+{
+   gl_FragColor.rgb = texture2D(tex, tex_c.xy).rgb * texture2D(texm, tex_a).g;
+   gl_FragColor.a   = texture2D(texm, tex_a).g;
+}
diff --git a/src/modules/engines/gl_common/shader/rgb_a_pair_nomul_vert.h b/src/modules/engines/gl_common/shader/rgb_a_pair_nomul_vert.h
new file mode 100644 (file)
index 0000000..a0685be
--- /dev/null
@@ -0,0 +1,16 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_coordm;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_a;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_a = tex_coordm;\n"
+"}\n"
+"\n"
diff --git a/src/modules/engines/gl_common/shader/rgb_a_pair_nomul_vert.shd b/src/modules/engines/gl_common/shader/rgb_a_pair_nomul_vert.shd
new file mode 100644 (file)
index 0000000..bf2c242
--- /dev/null
@@ -0,0 +1,16 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_coordm;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_a;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_a = tex_coordm;
+}
+
diff --git a/src/modules/engines/gl_common/shader/rgb_a_pair_vert.h b/src/modules/engines/gl_common/shader/rgb_a_pair_vert.h
new file mode 100644 (file)
index 0000000..e8158d1
--- /dev/null
@@ -0,0 +1,19 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_coordm;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_a;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_a = tex_coordm;\n"
+"}\n"
+"\n"
diff --git a/src/modules/engines/gl_common/shader/rgb_a_pair_vert.shd b/src/modules/engines/gl_common/shader/rgb_a_pair_vert.shd
new file mode 100644 (file)
index 0000000..4a57c52
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_coordm;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_a;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_a = tex_coordm;
+}
+
diff --git a/src/modules/engines/gl_common/shader/tex_12_afill_frag.h b/src/modules/engines/gl_common/shader/tex_12_afill_frag.h
new file mode 100644 (file)
index 0000000..94781bd
--- /dev/null
@@ -0,0 +1,19 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   vec4 c = (col00 + col01) / div_s;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1) * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_12_afill_frag.shd b/src/modules/engines/gl_common/shader/tex_12_afill_frag.shd
new file mode 100644 (file)
index 0000000..ee15fdd
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   vec4 c = (col00 + col01) / div_s;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1) * col;
+}
diff --git a/src/modules/engines/gl_common/shader/tex_12_afill_vert.h b/src/modules/engines/gl_common/shader/tex_12_afill_vert.h
new file mode 100644 (file)
index 0000000..56cd064
--- /dev/null
@@ -0,0 +1,21 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(0, -tex_sample.y);\n"
+"   tex_s[1] = vec2(0,  tex_sample.y);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_12_afill_vert.shd b/src/modules/engines/gl_common/shader/tex_12_afill_vert.shd
new file mode 100644 (file)
index 0000000..810d73a
--- /dev/null
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(0, -tex_sample.y);
+   tex_s[1] = vec2(0,  tex_sample.y);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/tex_12_frag.h b/src/modules/engines/gl_common/shader/tex_12_frag.h
new file mode 100644 (file)
index 0000000..a076fb5
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   gl_FragColor = ((col00 + col01) / div_s) * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_12_frag.shd b/src/modules/engines/gl_common/shader/tex_12_frag.shd
new file mode 100644 (file)
index 0000000..d23e17b
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   gl_FragColor = ((col00 + col01) / div_s) * col;
+}
diff --git a/src/modules/engines/gl_common/shader/tex_12_nomul_afill_frag.h b/src/modules/engines/gl_common/shader/tex_12_nomul_afill_frag.h
new file mode 100644 (file)
index 0000000..3b02610
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   vec4 c = (col00 + col01) / div_s;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_12_nomul_afill_frag.shd b/src/modules/engines/gl_common/shader/tex_12_nomul_afill_frag.shd
new file mode 100644 (file)
index 0000000..a7bff98
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   vec4 c = (col00 + col01) / div_s;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/tex_12_nomul_afill_vert.h b/src/modules/engines/gl_common/shader/tex_12_nomul_afill_vert.h
new file mode 100644 (file)
index 0000000..cee10ea
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(0, -tex_sample.y);\n"
+"   tex_s[1] = vec2(0,  tex_sample.y);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_12_nomul_afill_vert.shd b/src/modules/engines/gl_common/shader/tex_12_nomul_afill_vert.shd
new file mode 100644 (file)
index 0000000..40144aa
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(0, -tex_sample.y);
+   tex_s[1] = vec2(0,  tex_sample.y);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/tex_12_nomul_frag.h b/src/modules/engines/gl_common/shader/tex_12_nomul_frag.h
new file mode 100644 (file)
index 0000000..0be15b3
--- /dev/null
@@ -0,0 +1,17 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   gl_FragColor = (col00 + col01) / div_s;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_12_nomul_frag.shd b/src/modules/engines/gl_common/shader/tex_12_nomul_frag.shd
new file mode 100644 (file)
index 0000000..4d29510
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   gl_FragColor = (col00 + col01) / div_s;
+}
diff --git a/src/modules/engines/gl_common/shader/tex_12_nomul_vert.h b/src/modules/engines/gl_common/shader/tex_12_nomul_vert.h
new file mode 100644 (file)
index 0000000..cee10ea
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(0, -tex_sample.y);\n"
+"   tex_s[1] = vec2(0,  tex_sample.y);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_12_nomul_vert.shd b/src/modules/engines/gl_common/shader/tex_12_nomul_vert.shd
new file mode 100644 (file)
index 0000000..40144aa
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(0, -tex_sample.y);
+   tex_s[1] = vec2(0,  tex_sample.y);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/tex_12_vert.h b/src/modules/engines/gl_common/shader/tex_12_vert.h
new file mode 100644 (file)
index 0000000..56cd064
--- /dev/null
@@ -0,0 +1,21 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(0, -tex_sample.y);\n"
+"   tex_s[1] = vec2(0,  tex_sample.y);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_12_vert.shd b/src/modules/engines/gl_common/shader/tex_12_vert.shd
new file mode 100644 (file)
index 0000000..810d73a
--- /dev/null
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(0, -tex_sample.y);
+   tex_s[1] = vec2(0,  tex_sample.y);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/tex_21_afill_frag.h b/src/modules/engines/gl_common/shader/tex_21_afill_frag.h
new file mode 100644 (file)
index 0000000..94781bd
--- /dev/null
@@ -0,0 +1,19 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   vec4 c = (col00 + col01) / div_s;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1) * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_21_afill_frag.shd b/src/modules/engines/gl_common/shader/tex_21_afill_frag.shd
new file mode 100644 (file)
index 0000000..ee15fdd
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   vec4 c = (col00 + col01) / div_s;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1) * col;
+}
diff --git a/src/modules/engines/gl_common/shader/tex_21_afill_vert.h b/src/modules/engines/gl_common/shader/tex_21_afill_vert.h
new file mode 100644 (file)
index 0000000..88d1470
--- /dev/null
@@ -0,0 +1,21 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, 0);\n"
+"   tex_s[1] = vec2( tex_sample.x, 0);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_21_afill_vert.shd b/src/modules/engines/gl_common/shader/tex_21_afill_vert.shd
new file mode 100644 (file)
index 0000000..98d9154
--- /dev/null
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, 0);
+   tex_s[1] = vec2( tex_sample.x, 0);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/tex_21_frag.h b/src/modules/engines/gl_common/shader/tex_21_frag.h
new file mode 100644 (file)
index 0000000..a076fb5
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   gl_FragColor = ((col00 + col01) / div_s) * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_21_frag.shd b/src/modules/engines/gl_common/shader/tex_21_frag.shd
new file mode 100644 (file)
index 0000000..d23e17b
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   gl_FragColor = ((col00 + col01) / div_s) * col;
+}
diff --git a/src/modules/engines/gl_common/shader/tex_21_nomul_afill_frag.h b/src/modules/engines/gl_common/shader/tex_21_nomul_afill_frag.h
new file mode 100644 (file)
index 0000000..3b02610
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   vec4 c = (col00 + col01) / div_s;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_21_nomul_afill_frag.shd b/src/modules/engines/gl_common/shader/tex_21_nomul_afill_frag.shd
new file mode 100644 (file)
index 0000000..a7bff98
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   vec4 c = (col00 + col01) / div_s;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/tex_21_nomul_afill_vert.h b/src/modules/engines/gl_common/shader/tex_21_nomul_afill_vert.h
new file mode 100644 (file)
index 0000000..7c7d7db
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, 0);\n"
+"   tex_s[1] = vec2( tex_sample.x, 0);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_21_nomul_afill_vert.shd b/src/modules/engines/gl_common/shader/tex_21_nomul_afill_vert.shd
new file mode 100644 (file)
index 0000000..a6b149f
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, 0);
+   tex_s[1] = vec2( tex_sample.x, 0);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/tex_21_nomul_frag.h b/src/modules/engines/gl_common/shader/tex_21_nomul_frag.h
new file mode 100644 (file)
index 0000000..0be15b3
--- /dev/null
@@ -0,0 +1,17 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   gl_FragColor = (col00 + col01) / div_s;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_21_nomul_frag.shd b/src/modules/engines/gl_common/shader/tex_21_nomul_frag.shd
new file mode 100644 (file)
index 0000000..4d29510
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   gl_FragColor = (col00 + col01) / div_s;
+}
diff --git a/src/modules/engines/gl_common/shader/tex_21_nomul_vert.h b/src/modules/engines/gl_common/shader/tex_21_nomul_vert.h
new file mode 100644 (file)
index 0000000..7c7d7db
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, 0);\n"
+"   tex_s[1] = vec2( tex_sample.x, 0);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_21_nomul_vert.shd b/src/modules/engines/gl_common/shader/tex_21_nomul_vert.shd
new file mode 100644 (file)
index 0000000..a6b149f
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, 0);
+   tex_s[1] = vec2( tex_sample.x, 0);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/tex_21_vert.h b/src/modules/engines/gl_common/shader/tex_21_vert.h
new file mode 100644 (file)
index 0000000..88d1470
--- /dev/null
@@ -0,0 +1,21 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[2];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, 0);\n"
+"   tex_s[1] = vec2( tex_sample.x, 0);\n"
+"   div_s = vec4(2, 2, 2, 2);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_21_vert.shd b/src/modules/engines/gl_common/shader/tex_21_vert.shd
new file mode 100644 (file)
index 0000000..98d9154
--- /dev/null
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[2];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, 0);
+   tex_s[1] = vec2( tex_sample.x, 0);
+   div_s = vec4(2, 2, 2, 2);
+}
diff --git a/src/modules/engines/gl_common/shader/tex_22_afill_frag.h b/src/modules/engines/gl_common/shader/tex_22_afill_frag.h
new file mode 100644 (file)
index 0000000..5d2be19
--- /dev/null
@@ -0,0 +1,21 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   vec4 col10 = texture2D(tex, tex_c + tex_s[2]);\n"
+"   vec4 col11 = texture2D(tex, tex_c + tex_s[3]);\n"
+"   vec4 c = (col00 + col01 + col10 + col11) / div_s;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1) * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_22_afill_frag.shd b/src/modules/engines/gl_common/shader/tex_22_afill_frag.shd
new file mode 100644 (file)
index 0000000..cb2dd2b
--- /dev/null
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   vec4 col10 = texture2D(tex, tex_c + tex_s[2]);
+   vec4 col11 = texture2D(tex, tex_c + tex_s[3]);
+   vec4 c = (col00 + col01 + col10 + col11) / div_s;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1) * col;
+}
diff --git a/src/modules/engines/gl_common/shader/tex_22_afill_vert.h b/src/modules/engines/gl_common/shader/tex_22_afill_vert.h
new file mode 100644 (file)
index 0000000..e1fc7f4
--- /dev/null
@@ -0,0 +1,23 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);\n"
+"   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);\n"
+"   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);\n"
+"   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);\n"
+"   div_s = vec4(4, 4, 4, 4);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_22_afill_vert.shd b/src/modules/engines/gl_common/shader/tex_22_afill_vert.shd
new file mode 100644 (file)
index 0000000..e964ea1
--- /dev/null
@@ -0,0 +1,23 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);
+   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);
+   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);
+   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);
+   div_s = vec4(4, 4, 4, 4);
+}
diff --git a/src/modules/engines/gl_common/shader/tex_22_frag.h b/src/modules/engines/gl_common/shader/tex_22_frag.h
new file mode 100644 (file)
index 0000000..748a33a
--- /dev/null
@@ -0,0 +1,20 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   vec4 col10 = texture2D(tex, tex_c + tex_s[2]);\n"
+"   vec4 col11 = texture2D(tex, tex_c + tex_s[3]);\n"
+"   gl_FragColor = ((col00 + col01 + col10 + col11) / div_s) * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_22_frag.shd b/src/modules/engines/gl_common/shader/tex_22_frag.shd
new file mode 100644 (file)
index 0000000..ab1b121
--- /dev/null
@@ -0,0 +1,20 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   vec4 col10 = texture2D(tex, tex_c + tex_s[2]);
+   vec4 col11 = texture2D(tex, tex_c + tex_s[3]);
+   gl_FragColor = ((col00 + col01 + col10 + col11) / div_s) * col;
+}
diff --git a/src/modules/engines/gl_common/shader/tex_22_nomul_afill_frag.h b/src/modules/engines/gl_common/shader/tex_22_nomul_afill_frag.h
new file mode 100644 (file)
index 0000000..ce33563
--- /dev/null
@@ -0,0 +1,20 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   vec4 col10 = texture2D(tex, tex_c + tex_s[2]);\n"
+"   vec4 col11 = texture2D(tex, tex_c + tex_s[3]);\n"
+"   vec4 c = (col00 + col01 + col10 + col11) / div_s;\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_22_nomul_afill_frag.shd b/src/modules/engines/gl_common/shader/tex_22_nomul_afill_frag.shd
new file mode 100644 (file)
index 0000000..c017c31
--- /dev/null
@@ -0,0 +1,20 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   vec4 col10 = texture2D(tex, tex_c + tex_s[2]);
+   vec4 col11 = texture2D(tex, tex_c + tex_s[3]);
+   vec4 c = (col00 + col01 + col10 + col11) / div_s;
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/tex_22_nomul_afill_vert.h b/src/modules/engines/gl_common/shader/tex_22_nomul_afill_vert.h
new file mode 100644 (file)
index 0000000..c6fb270
--- /dev/null
@@ -0,0 +1,20 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);\n"
+"   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);\n"
+"   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);\n"
+"   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);\n"
+"   div_s = vec4(4, 4, 4, 4);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_22_nomul_afill_vert.shd b/src/modules/engines/gl_common/shader/tex_22_nomul_afill_vert.shd
new file mode 100644 (file)
index 0000000..e6303d7
--- /dev/null
@@ -0,0 +1,20 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);
+   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);
+   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);
+   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);
+   div_s = vec4(4, 4, 4, 4);
+}
diff --git a/src/modules/engines/gl_common/shader/tex_22_nomul_frag.h b/src/modules/engines/gl_common/shader/tex_22_nomul_frag.h
new file mode 100644 (file)
index 0000000..4af85f9
--- /dev/null
@@ -0,0 +1,19 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);\n"
+"   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);\n"
+"   vec4 col10 = texture2D(tex, tex_c + tex_s[2]);\n"
+"   vec4 col11 = texture2D(tex, tex_c + tex_s[3]);\n"
+"   gl_FragColor = (col00 + col01 + col10 + col11) / div_s;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_22_nomul_frag.shd b/src/modules/engines/gl_common/shader/tex_22_nomul_frag.shd
new file mode 100644 (file)
index 0000000..3f380ea
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   vec4 col00 = texture2D(tex, tex_c + tex_s[0]);
+   vec4 col01 = texture2D(tex, tex_c + tex_s[1]);
+   vec4 col10 = texture2D(tex, tex_c + tex_s[2]);
+   vec4 col11 = texture2D(tex, tex_c + tex_s[3]);
+   gl_FragColor = (col00 + col01 + col10 + col11) / div_s;
+}
diff --git a/src/modules/engines/gl_common/shader/tex_22_nomul_vert.h b/src/modules/engines/gl_common/shader/tex_22_nomul_vert.h
new file mode 100644 (file)
index 0000000..c6fb270
--- /dev/null
@@ -0,0 +1,20 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);\n"
+"   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);\n"
+"   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);\n"
+"   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);\n"
+"   div_s = vec4(4, 4, 4, 4);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_22_nomul_vert.shd b/src/modules/engines/gl_common/shader/tex_22_nomul_vert.shd
new file mode 100644 (file)
index 0000000..e6303d7
--- /dev/null
@@ -0,0 +1,20 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);
+   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);
+   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);
+   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);
+   div_s = vec4(4, 4, 4, 4);
+}
diff --git a/src/modules/engines/gl_common/shader/tex_22_vert.h b/src/modules/engines/gl_common/shader/tex_22_vert.h
new file mode 100644 (file)
index 0000000..e1fc7f4
--- /dev/null
@@ -0,0 +1,23 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_sample;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"varying vec2 tex_s[4];\n"
+"varying vec4 div_s;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);\n"
+"   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);\n"
+"   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);\n"
+"   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);\n"
+"   div_s = vec4(4, 4, 4, 4);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_22_vert.shd b/src/modules/engines/gl_common/shader/tex_22_vert.shd
new file mode 100644 (file)
index 0000000..e964ea1
--- /dev/null
@@ -0,0 +1,23 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_sample;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+varying vec2 tex_s[4];
+varying vec4 div_s;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_s[0] = vec2(-tex_sample.x, -tex_sample.y);
+   tex_s[1] = vec2( tex_sample.x, -tex_sample.y);
+   tex_s[2] = vec2( tex_sample.x,  tex_sample.y);
+   tex_s[3] = vec2(-tex_sample.x,  tex_sample.y);
+   div_s = vec4(4, 4, 4, 4);
+}
diff --git a/src/modules/engines/gl_common/shader/tex_afill_frag.h b/src/modules/engines/gl_common/shader/tex_afill_frag.h
new file mode 100644 (file)
index 0000000..6016853
--- /dev/null
@@ -0,0 +1,15 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"void main()\n"
+"{\n"
+"   vec4 c = texture2D(tex, tex_c.xy);\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1) * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_afill_frag.shd b/src/modules/engines/gl_common/shader/tex_afill_frag.shd
new file mode 100644 (file)
index 0000000..9ee0c37
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+void main()
+{
+   vec4 c = texture2D(tex, tex_c.xy);
+   gl_FragColor = vec4(c.r, c.g, c.b, 1) * col;
+}
diff --git a/src/modules/engines/gl_common/shader/tex_afill_vert.h b/src/modules/engines/gl_common/shader/tex_afill_vert.h
new file mode 100644 (file)
index 0000000..8921d9d
--- /dev/null
@@ -0,0 +1,15 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_afill_vert.shd b/src/modules/engines/gl_common/shader/tex_afill_vert.shd
new file mode 100644 (file)
index 0000000..606c297
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+}
diff --git a/src/modules/engines/gl_common/shader/tex_frag_bin_s3c6410.h b/src/modules/engines/gl_common/shader/tex_frag_bin_s3c6410.h
deleted file mode 100644 (file)
index 24af537..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-0x20205350, 0xffff0008, 0x00000048, 0x01020000, 0x00000003, 0x00000000, 
-0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000001, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000e, 0x00000000, 
-0x00000000, 0x0000e407, 0x307820e4, 0x00000000, 0x01000000, 0x0100e400, 
-0x237a10e4, 0x00000000, 0x00000000, 0x00000000, 0x1e000000, 0x00000000, 
-0x00000004, 0x00000003, 0x00000009, 0x00000000, 0x00000004, 0x00000008, 
-0x00000005, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 
-0x0000000f, 0x00030005, 0x00000000, 0x00786574, 0x006c6f63, 0x5f786574, 
-0x00000063, 
\ No newline at end of file
diff --git a/src/modules/engines/gl_common/shader/tex_frag_s3c6410.asm b/src/modules/engines/gl_common/shader/tex_frag_s3c6410.asm
deleted file mode 100644 (file)
index 14bbfa1..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-
-#-------------------------------------------------
-# ORION - OpenGL ES 2.0 Shading Language Compiler
-# SAMSUNG INDIA SOFTWARE OPERATIONS PVT. LTD.
-# Compiler Version     : v04.00.09
-# Release Date         : 19.01.2009
-# FIMG VERSION      : FIMGv1.5
-# Optimizer Options :  -O --nolodcalc
-#-------------------------------------------------
-
-# hand optimised - removed useless ops
-
-ps_3_0
-
-fimg_version   0x01020000
-
-dcl_s2_tex     s0
-dcl_f4_col     v1.x
-dcl_f2_tex_c   v0.x
-
-label start
-label main_
-texld r0.xyzw, v0.xyzw, s0     # tex=s0
-mul_sat oColor.xyzw, r0.xyzw, v1.xyzw  # gl_FragColor=oColor.xyzw, col=v1.xyzw
-label main_end
-ret
diff --git a/src/modules/engines/gl_common/shader/tex_nomul_afill_frag.h b/src/modules/engines/gl_common/shader/tex_nomul_afill_frag.h
new file mode 100644 (file)
index 0000000..43f7e63
--- /dev/null
@@ -0,0 +1,14 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex;\n"
+"varying vec2 tex_c;\n"
+"void main()\n"
+"{\n"
+"   vec4 c = texture2D(tex, tex_c.xy);\n"
+"   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_nomul_afill_frag.shd b/src/modules/engines/gl_common/shader/tex_nomul_afill_frag.shd
new file mode 100644 (file)
index 0000000..569c32e
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec2 tex_c;
+void main()
+{
+   vec4 c = texture2D(tex, tex_c.xy);
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/engines/gl_common/shader/tex_nomul_afill_vert.h b/src/modules/engines/gl_common/shader/tex_nomul_afill_vert.h
new file mode 100644 (file)
index 0000000..13d5edd
--- /dev/null
@@ -0,0 +1,12 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tex_nomul_afill_vert.shd b/src/modules/engines/gl_common/shader/tex_nomul_afill_vert.shd
new file mode 100644 (file)
index 0000000..74f3207
--- /dev/null
@@ -0,0 +1,12 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+uniform mat4 mvp;
+varying vec2 tex_c;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+}
diff --git a/src/modules/engines/gl_common/shader/tex_nomul_frag_bin_s3c6410.h b/src/modules/engines/gl_common/shader/tex_nomul_frag_bin_s3c6410.h
deleted file mode 100644 (file)
index b89eeb1..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-0x20205350, 0xffff0008, 0x00000048, 0x01020000, 0x00000003, 0x00000003, 
-0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000a, 0x00000000, 
-0x00000000, 0x02025400, 0x23782050, 0x00000000, 0x00000000, 0x0100e407, 
-0x307a10e4, 0x00000000, 0x00000000, 0x00000000, 0x1e000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 
-0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000004, 0x00000005, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 
-0x00000003, 0x0000000f, 0x00030005, 0x00000000, 0x00786574, 0x5f786574, 
-0x00000063, 
\ No newline at end of file
diff --git a/src/modules/engines/gl_common/shader/tex_nomul_vert_bin_s3c6410.h b/src/modules/engines/gl_common/shader/tex_nomul_vert_bin_s3c6410.h
deleted file mode 100644 (file)
index 314b5f3..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-0x20205356, 0xffff0008, 0x00000048, 0x01020000, 0x00000006, 0x00000006, 
-0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000001, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000027, 0x00000000, 
-0x00000000, 0x02020000, 0x237820e4, 0x00000000, 0x00e40100, 0x02035500, 
-0x2ef820e4, 0x00000000, 0x00e40100, 0x0204aa00, 0x2ef820e4, 0x00000000, 
-0x00e40100, 0x0205ff00, 0x2ef800e4, 0x00000000, 0x00000000, 0x00010000, 
-0x20980154, 0x00000000, 0x00000000, 0x00000000, 0x1e000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 
-0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x0000000c, 0x00000006, 0x00000009, 0x00000000, 0x00000000, 0x00000013, 
-0x00000009, 0x00000003, 0x00000000, 0x00000004, 0x00000000, 0x0000000b, 
-0x00000009, 0x00010004, 0x00000000, 0x00000021, 0x00000005, 0x00000003, 
-0x00010004, 0x00000004, 0x0000001d, 0x00000003, 0x0000000e, 0x00020001, 
-0x00000008, 0x505f6c67, 0x7469736f, 0x006e6f69, 0x74726576, 0x74007865, 
-0x635f7865, 0x64726f6f, 0x70766d00, 0x78657400, 0x0000635f, 
diff --git a/src/modules/engines/gl_common/shader/tex_rgb_frag.shd b/src/modules/engines/gl_common/shader/tex_rgb_frag.shd
new file mode 100644 (file)
index 0000000..382b8e5
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex;
+varying vec4 col;
+varying vec2 tex_c;
+void main()
+{
+   gl_FragColor = vec4(texture2D(tex, tex_c.xy).rgb, 1.0) * col / col;
+}
diff --git a/src/modules/engines/gl_common/shader/tex_rgb_vert.shd b/src/modules/engines/gl_common/shader/tex_rgb_vert.shd
new file mode 100644 (file)
index 0000000..606c297
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+}
diff --git a/src/modules/engines/gl_common/shader/tex_vert_bin_s3c6410.h b/src/modules/engines/gl_common/shader/tex_vert_bin_s3c6410.h
deleted file mode 100644 (file)
index 1402448..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-0x20205356, 0xffff0008, 0x00000048, 0x01020000, 0x00000007, 0x00000006, 
-0x00000000, 0x00000000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000031, 0x00000000, 
-0x00000000, 0x02020000, 0x237820e4, 0x00000000, 0x00e40100, 0x02035500, 
-0x2ef820e4, 0x00000000, 0x00e40100, 0x0204aa00, 0x2ef820e4, 0x00000000, 
-0x00e40100, 0x0205ff00, 0x2ef800e4, 0x00000000, 0x00000000, 0x00010000, 
-0x20f801e4, 0x00000000, 0x00000000, 0x00020000, 0x20980254, 0x00000000, 
-0x00000000, 0x00000000, 0x1e000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000c, 0x00000006, 
-0x00000009, 0x00000000, 0x00000000, 0x00000013, 0x00000005, 0x00000009, 
-0x00000000, 0x00000004, 0x00000019, 0x00000009, 0x00000003, 0x00000000, 
-0x00000008, 0x00000000, 0x0000000b, 0x00000009, 0x00010004, 0x00000000, 
-0x00000027, 0x00000003, 0x00000009, 0x00010004, 0x00000004, 0x0000002b, 
-0x00000005, 0x00000003, 0x00010004, 0x00000008, 0x00000023, 0x00000003, 
-0x0000000e, 0x00020001, 0x00000008, 0x505f6c67, 0x7469736f, 0x006e6f69, 
-0x74726576, 0x63007865, 0x726f6c6f, 0x78657400, 0x6f6f635f, 0x6d006472, 
-0x63007076, 0x74006c6f, 0x635f7865, 0x00000000, 
\ No newline at end of file
diff --git a/src/modules/engines/gl_common/shader/tizen_frag.h b/src/modules/engines/gl_common/shader/tizen_frag.h
new file mode 100644 (file)
index 0000000..8dc427c
--- /dev/null
@@ -0,0 +1,14 @@
+"#extension GL_OES_EGL_image_external : require\n"
+"\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"uniform samplerExternalOES tex;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"void main()\n"
+"{\n"
+"   gl_FragColor = texture2D(tex, tex_c.xy) * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tizen_frag.shd b/src/modules/engines/gl_common/shader/tizen_frag.shd
new file mode 100644 (file)
index 0000000..4e4fad3
--- /dev/null
@@ -0,0 +1,14 @@
+#extension GL_OES_EGL_image_external : require
+
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+uniform samplerExternalOES tex;
+varying vec4 col;
+varying vec2 tex_c;
+void main()
+{
+   gl_FragColor = texture2D(tex, tex_c.xy) * col;
+}
diff --git a/src/modules/engines/gl_common/shader/tizen_mask_frag.h b/src/modules/engines/gl_common/shader/tizen_mask_frag.h
new file mode 100644 (file)
index 0000000..776e40b
--- /dev/null
@@ -0,0 +1,16 @@
+"#extension GL_OES_EGL_image_external : require\n"
+"\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"uniform samplerExternalOES tex;\n"
+"uniform sampler2D texm;\n"
+"varying vec4 col;\n"
+"varying vec2 coord_c;\n"
+"varying vec2 coord_m;\n"
+"void main()\n"
+"{\n"
+"   gl_FragColor = texture2D(tex, coord_c.xy) * texture2D(texm, coord_m.xy).a * col;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tizen_mask_frag.shd b/src/modules/engines/gl_common/shader/tizen_mask_frag.shd
new file mode 100644 (file)
index 0000000..9d4d220
--- /dev/null
@@ -0,0 +1,16 @@
+#extension GL_OES_EGL_image_external : require
+
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+uniform samplerExternalOES tex;
+uniform sampler2D texm;
+varying vec4 col;
+varying vec2 coord_c;
+varying vec2 coord_m;
+void main()
+{
+   gl_FragColor = texture2D(tex, coord_c.xy) * texture2D(texm, coord_m.xy).a * col;
+}
diff --git a/src/modules/engines/gl_common/shader/tizen_mask_nomul_frag.h b/src/modules/engines/gl_common/shader/tizen_mask_nomul_frag.h
new file mode 100644 (file)
index 0000000..28c18ab
--- /dev/null
@@ -0,0 +1,15 @@
+"#extension GL_OES_EGL_image_external : require\n"
+"\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"uniform samplerExternalOES tex;\n"
+"uniform sampler2D texm;\n"
+"varying vec2 coord_c;\n"
+"varying vec2 coord_m;\n"
+"void main()\n"
+"{\n"
+"   gl_FragColor = texture2D(tex, coord_c.xy) * texture2D(texm, coord_m.xy).a;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tizen_mask_nomul_frag.shd b/src/modules/engines/gl_common/shader/tizen_mask_nomul_frag.shd
new file mode 100644 (file)
index 0000000..2fb870e
--- /dev/null
@@ -0,0 +1,15 @@
+#extension GL_OES_EGL_image_external : require
+
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+uniform samplerExternalOES tex;
+uniform sampler2D texm;
+varying vec2 coord_c;
+varying vec2 coord_m;
+void main()
+{
+   gl_FragColor = texture2D(tex, coord_c.xy) * texture2D(texm, coord_m.xy).a;
+}
diff --git a/src/modules/engines/gl_common/shader/tizen_mask_nomul_vert.h b/src/modules/engines/gl_common/shader/tizen_mask_nomul_vert.h
new file mode 100644 (file)
index 0000000..2e5b04f
--- /dev/null
@@ -0,0 +1,15 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_coordm;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 coord_c;\n"
+"varying vec2 coord_m;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   coord_c = tex_coord;\n"
+"   coord_m = tex_coordm;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tizen_mask_nomul_vert.shd b/src/modules/engines/gl_common/shader/tizen_mask_nomul_vert.shd
new file mode 100644 (file)
index 0000000..2665607
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+attribute vec2 tex_coordm;
+uniform mat4 mvp;
+varying vec2 coord_c;
+varying vec2 coord_m;
+void main()
+{
+   gl_Position = mvp * vertex;
+   coord_c = tex_coord;
+   coord_m = tex_coordm;
+}
diff --git a/src/modules/engines/gl_common/shader/tizen_mask_vert.h b/src/modules/engines/gl_common/shader/tizen_mask_vert.h
new file mode 100644 (file)
index 0000000..47fba0b
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"attribute vec2 tex_coordm;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 coord_c;\n"
+"varying vec2 coord_m;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   coord_c = tex_coord;\n"
+"   coord_m = tex_coordm;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tizen_mask_vert.shd b/src/modules/engines/gl_common/shader/tizen_mask_vert.shd
new file mode 100644 (file)
index 0000000..ad7b194
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+attribute vec2 tex_coordm;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 coord_c;
+varying vec2 coord_m;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   coord_c = tex_coord;
+   coord_m = tex_coordm;
+}
diff --git a/src/modules/engines/gl_common/shader/tizen_nomul_frag.h b/src/modules/engines/gl_common/shader/tizen_nomul_frag.h
new file mode 100644 (file)
index 0000000..92257d4
--- /dev/null
@@ -0,0 +1,13 @@
+"#extension GL_OES_EGL_image_external : require\n"
+"\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"uniform samplerExternalOES tex;\n"
+"varying vec2 tex_c;\n"
+"void main()\n"
+"{\n"
+"   gl_FragColor = texture2D(tex, tex_c.xy);\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tizen_nomul_frag.shd b/src/modules/engines/gl_common/shader/tizen_nomul_frag.shd
new file mode 100644 (file)
index 0000000..a05244c
--- /dev/null
@@ -0,0 +1,13 @@
+#extension GL_OES_EGL_image_external : require
+
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+uniform samplerExternalOES tex;
+varying vec2 tex_c;
+void main()
+{
+   gl_FragColor = texture2D(tex, tex_c.xy);
+}
diff --git a/src/modules/engines/gl_common/shader/tizen_nomul_vert.h b/src/modules/engines/gl_common/shader/tizen_nomul_vert.h
new file mode 100644 (file)
index 0000000..13d5edd
--- /dev/null
@@ -0,0 +1,12 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec2 tex_coord;\n"
+"uniform mat4 mvp;\n"
+"varying vec2 tex_c;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   tex_c = tex_coord;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tizen_nomul_vert.shd b/src/modules/engines/gl_common/shader/tizen_nomul_vert.shd
new file mode 100644 (file)
index 0000000..74f3207
--- /dev/null
@@ -0,0 +1,12 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+uniform mat4 mvp;
+varying vec2 tex_c;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+}
diff --git a/src/modules/engines/gl_common/shader/tizen_vert.h b/src/modules/engines/gl_common/shader/tizen_vert.h
new file mode 100644 (file)
index 0000000..8921d9d
--- /dev/null
@@ -0,0 +1,15 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/tizen_vert.shd b/src/modules/engines/gl_common/shader/tizen_vert.shd
new file mode 100644 (file)
index 0000000..606c297
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+}
diff --git a/src/modules/engines/gl_common/shader/yuv_frag_bin_s3c6410.h b/src/modules/engines/gl_common/shader/yuv_frag_bin_s3c6410.h
deleted file mode 100644 (file)
index cd301dc..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-0x20205350, 0xffff0008, 0x00000048, 0x01020000, 0x0000000d, 0x00000007, 
-0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x00000003, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000026, 0x00000000, 
-0x00000000, 0x02065400, 0x23782050, 0x00000000, 0x00000000, 0x0100e407, 
-0x307820e4, 0x00000000, 0x01000000, 0x02065400, 0x23782150, 0x00000000, 
-0x01000000, 0x0101e407, 0x307821e4, 0x00000000, 0x02000000, 0x02065400, 
-0x23782250, 0x00000000, 0x02000000, 0x0102e407, 0x307822e4, 0x00000000, 
-0x00000000, 0x02020001, 0x237823e4, 0x00000000, 0x01e40103, 0x02030001, 
-0x2ef823e4, 0x00000000, 0x02e40103, 0x02040001, 0x2ef823e4, 0x00000000, 
-0x00000000, 0x02050000, 0x20f824e4, 0x00000000, 0x06e40103, 0x01040002, 
-0x2ef823e4, 0x00000000, 0x03000000, 0x0103e400, 0x237a10e4, 0x00000000, 
-0x00000000, 0x00000000, 0x1e000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x3f94fdf4, 0x3f94fdf4, 0x3f94fdf4, 0x00000000, 0x00000000, 0xbeb02de0, 
-0x3fe2d0e5, 0x00000000, 0x3fb374bc, 0xbf36cf42, 0x00000000, 0x00000000, 
-0xbf4617c2, 0x3ee9a027, 0xbf7573eb, 0x3f800000, 0x3f800000, 0x00000000, 
-0x00000000, 0x00000000, 0x0000000e, 0x00000003, 0x00000009, 0x00000000, 
-0x0000000c, 0x00000012, 0x00000005, 0x00000003, 0x00000000, 0x00000000, 
-0x00000018, 0x00000006, 0x00000003, 0x00000000, 0x00000004, 0x0000001f, 
-0x00000006, 0x00000003, 0x00000000, 0x00000008, 0x00000000, 0x00000003, 
-0x0000000f, 0x00030005, 0x00000000, 0x00000004, 0x00000004, 0x0000000f, 
-0x00030005, 0x00000004, 0x00000009, 0x00000004, 0x0000000f, 0x00030005, 
-0x00000008, 0x00786574, 0x75786574, 0x78657400, 0x6f630076, 0x6574006c, 
-0x00635f78, 0x5f786574, 0x74003263, 0x635f7865, 0x00000033, 
diff --git a/src/modules/engines/gl_common/shader/yuv_frag_s3c6410.asm b/src/modules/engines/gl_common/shader/yuv_frag_s3c6410.asm
deleted file mode 100644 (file)
index 9a10bf0..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-
-#-------------------------------------------------
-# ORION - OpenGL ES 2.0 Shading Language Compiler
-# SAMSUNG INDIA SOFTWARE OPERATIONS PVT. LTD.
-# Compiler Version     : v04.00.09
-# Release Date         : 19.01.2009
-# FIMG VERSION      : FIMGv1.5
-# Optimizer Options :  -O --nolodcalc
-#-------------------------------------------------
-
-# hand optimised - removed useless ops
-
-ps_3_0
-
-fimg_version   0x01020000
-
-dcl_s2_tex     s0
-dcl_s2_texu    s1
-dcl_s2_texv    s2
-dcl_f4_col     v3.x
-dcl_f2_tex_c   v0.x
-dcl_f2_tex_c2  v1.x
-dcl_f2_tex_c3  v2.x
-
-def c2, 1.164000, 1.164000, 1.164000, 0.000000
-def c3, 0.000000, -0.344100, 1.772000, 0.000000
-def c4, 1.402000, -0.714100, 0.000000, 0.000000
-def c5, -0.773800, 0.456300, -0.958800, 1.000000
-def c6, 1.000000, 0.000000, 0.000000, 0.000000
-
-label start
-label main_
-mul r0.xyzw, c6.xxyy, v0.xyyy  # tex_c=v0.xyyy
-texld r0.xyzw, r0.xyzw, s0     # tex=s0
-mul r1.xyzw, c6.xxyy, v1.xyyy  # tex_c2=v1.xyyy
-texld r1.xyzw, r1.xyzw, s1     # texu=s1
-mul r2.xyzw, c6.xxyy, v2.xyyy  # tex_c3=v2.xyyy
-texld r2.xyzw, r2.xyzw, s2     # texv=s2
-mul r3.xyzw, c2.xyzw, r0.xxxx  # yuv=r0.xxxx
-mad r3.xyzw, c3.xyzw, r1.xxxx, r3.xyzw # yuv=r1.xxxx
-mad r3.xyzw, c4.xyzw, r2.xxxx, r3.xyzw # yuv=r2.xxxx
-mov r4.xyzw, c5.xyzw
-mad r3.xyzw, r4.xyzw, c6.xxxx, r3.xyzw # yuv=c6.xxxx
-mul_sat oColor.xyzw, r3.xyzw, v3.xyzw  # gl_FragColor=oColor.xyzw, col=v3.xyzw
-label main_end
-ret
diff --git a/src/modules/engines/gl_common/shader/yuv_mask_frag.h b/src/modules/engines/gl_common/shader/yuv_mask_frag.h
new file mode 100644 (file)
index 0000000..b9a7f31
--- /dev/null
@@ -0,0 +1,25 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex, texu, texv, texm;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c, tex_c2, tex_c3, tex_m;\n"
+"void main()\n"
+"{\n"
+"   float r, g, b, y, u, v;\n"
+"   y = texture2D(tex, tex_c.xy).r;\n"
+"   u = texture2D(texu, tex_c2.xy).r;\n"
+"   v = texture2D(texv, tex_c3.xy).r;\n"
+"   y = (y - 0.0625) * 1.164;\n"
+"   u = u - 0.5;\n"
+"   v = v - 0.5;\n"
+"   r = y + (1.402   * v);\n"
+"   g = y - (0.34414 * u) - (0.71414 * v);\n"
+"   b = y + (1.772   * u);\n"
+"   gl_FragColor = vec4(r, g, b, 1.0) * texture2D(texm, tex_m.xy).a * col;\n"
+"}\n"
+"\n"
diff --git a/src/modules/engines/gl_common/shader/yuv_mask_frag.shd b/src/modules/engines/gl_common/shader/yuv_mask_frag.shd
new file mode 100644 (file)
index 0000000..3f2185a
--- /dev/null
@@ -0,0 +1,25 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex, texu, texv, texm;
+varying vec4 col;
+varying vec2 tex_c, tex_c2, tex_c3, tex_m;
+void main()
+{
+   float r, g, b, y, u, v;
+   y = texture2D(tex, tex_c.xy).r;
+   u = texture2D(texu, tex_c2.xy).r;
+   v = texture2D(texv, tex_c3.xy).r;
+   y = (y - 0.0625) * 1.164;
+   u = u - 0.5;
+   v = v - 0.5;
+   r = y + (1.402   * v);
+   g = y - (0.34414 * u) - (0.71414 * v);
+   b = y + (1.772   * u);
+   gl_FragColor = vec4(r, g, b, 1.0) * texture2D(texm, tex_m.xy).a * col;
+}
+
diff --git a/src/modules/engines/gl_common/shader/yuv_mask_vert.h b/src/modules/engines/gl_common/shader/yuv_mask_vert.h
new file mode 100644 (file)
index 0000000..8d73aa6
--- /dev/null
@@ -0,0 +1,18 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord, tex_coord2, tex_coord3, tex_coordm;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c, tex_c2, tex_c3, tex_m;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_c2 = tex_coord2;\n"
+"   tex_c3 = tex_coord3;\n"
+"   tex_m = tex_coordm;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/yuv_mask_vert.shd b/src/modules/engines/gl_common/shader/yuv_mask_vert.shd
new file mode 100644 (file)
index 0000000..8a074d0
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord, tex_coord2, tex_coord3, tex_coordm;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c, tex_c2, tex_c3, tex_m;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_c2 = tex_coord2;
+   tex_c3 = tex_coord3;
+   tex_m = tex_coordm;
+}
diff --git a/src/modules/engines/gl_common/shader/yuv_nomul_frag_bin_s3c6410.h b/src/modules/engines/gl_common/shader/yuv_nomul_frag_bin_s3c6410.h
deleted file mode 100644 (file)
index 45aa66d..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-0x20205350, 0xffff0008, 0x00000048, 0x01020000, 0x0000000c, 0x00000007, 
-0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000022, 0x00000000, 
-0x00000000, 0x02065400, 0x23782050, 0x00000000, 0x00000000, 0x0100e407, 
-0x307820e4, 0x00000000, 0x01000000, 0x02065400, 0x23782150, 0x00000000, 
-0x01000000, 0x0101e407, 0x307821e4, 0x00000000, 0x02000000, 0x02065400, 
-0x23782250, 0x00000000, 0x02000000, 0x0102e407, 0x307822e4, 0x00000000, 
-0x00000000, 0x02020001, 0x237823e4, 0x00000000, 0x01e40103, 0x02030001, 
-0x2ef823e4, 0x00000000, 0x02e40103, 0x02040001, 0x2ef823e4, 0x00000000, 
-0x00000000, 0x02050000, 0x20f824e4, 0x00000000, 0x06e40103, 0x01040002, 
-0x2efa10e4, 0x00000000, 0x00000000, 0x00000000, 0x1e000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 
-0x3f800000, 0x3f800000, 0x3f94fdf4, 0x3f94fdf4, 0x3f94fdf4, 0x00000000, 
-0x00000000, 0xbeb02de0, 0x3fe2d0e5, 0x00000000, 0x3fb374bc, 0xbf36cf42, 
-0x00000000, 0x00000000, 0xbf4617c2, 0x3ee9a027, 0xbf7573eb, 0x3f800000, 
-0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0000000e, 0x00000005, 
-0x00000003, 0x00000000, 0x00000000, 0x00000014, 0x00000006, 0x00000003, 
-0x00000000, 0x00000004, 0x0000001b, 0x00000006, 0x00000003, 0x00000000, 
-0x00000008, 0x00000000, 0x00000003, 0x0000000f, 0x00030005, 0x00000000, 
-0x00000004, 0x00000004, 0x0000000f, 0x00030005, 0x00000004, 0x00000009, 
-0x00000004, 0x0000000f, 0x00030005, 0x00000008, 0x00786574, 0x75786574, 
-0x78657400, 0x65740076, 0x00635f78, 0x5f786574, 0x74003263, 0x635f7865, 
-0x00000033, 
\ No newline at end of file
diff --git a/src/modules/engines/gl_common/shader/yuv_nomul_vert_bin_s3c6410.h b/src/modules/engines/gl_common/shader/yuv_nomul_vert_bin_s3c6410.h
deleted file mode 100644 (file)
index 5942b4b..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-0x20205356, 0xffff0008, 0x00000048, 0x01020000, 0x00000008, 0x00000006, 
-0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000001, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000004b, 0x00000000, 
-0x00000000, 0x02020000, 0x237820e4, 0x00000000, 0x00e40100, 0x02035500, 
-0x2ef820e4, 0x00000000, 0x00e40100, 0x0204aa00, 0x2ef820e4, 0x00000000, 
-0x00e40100, 0x0205ff00, 0x2ef800e4, 0x00000000, 0x00000000, 0x00010000, 
-0x20980154, 0x00000000, 0x00000000, 0x00020000, 0x20980254, 0x00000000, 
-0x00000000, 0x00030000, 0x20980354, 0x00000000, 0x00000000, 0x00000000, 
-0x1e000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x0000000c, 0x00000006, 0x00000009, 0x00000000, 
-0x00000000, 0x00000013, 0x00000009, 0x00000003, 0x00000000, 0x00000004, 
-0x0000001d, 0x0000000a, 0x00000003, 0x00000000, 0x00000008, 0x00000028, 
-0x0000000a, 0x00000003, 0x00000000, 0x0000000c, 0x00000000, 0x0000000b, 
-0x00000009, 0x00010004, 0x00000000, 0x00000037, 0x00000005, 0x00000003, 
-0x00010004, 0x00000004, 0x0000003d, 0x00000006, 0x00000003, 0x00010004, 
-0x00000008, 0x00000044, 0x00000006, 0x00000003, 0x00010004, 0x0000000c, 
-0x00000033, 0x00000003, 0x0000000e, 0x00020001, 0x00000008, 0x505f6c67, 
-0x7469736f, 0x006e6f69, 0x74726576, 0x74007865, 0x635f7865, 0x64726f6f, 
-0x78657400, 0x6f6f635f, 0x00326472, 0x5f786574, 0x726f6f63, 0x6d003364, 
-0x74007076, 0x635f7865, 0x78657400, 0x0032635f, 0x5f786574, 0x00003363, 
diff --git a/src/modules/engines/gl_common/shader/yuv_vert_bin_s3c6410.h b/src/modules/engines/gl_common/shader/yuv_vert_bin_s3c6410.h
deleted file mode 100644 (file)
index e757b6d..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-0x20205356, 0xffff0008, 0x00000048, 0x01020000, 0x00000009, 0x00000006, 
-0x00000000, 0x00000000, 0x00000005, 0x00000005, 0x00000001, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000055, 0x00000000, 
-0x00000000, 0x02020000, 0x237820e4, 0x00000000, 0x00e40100, 0x02035500, 
-0x2ef820e4, 0x00000000, 0x00e40100, 0x0204aa00, 0x2ef820e4, 0x00000000, 
-0x00e40100, 0x0205ff00, 0x2ef800e4, 0x00000000, 0x00000000, 0x00010000, 
-0x20f801e4, 0x00000000, 0x00000000, 0x00020000, 0x20980254, 0x00000000, 
-0x00000000, 0x00030000, 0x20980354, 0x00000000, 0x00000000, 0x00040000, 
-0x20980454, 0x00000000, 0x00000000, 0x00000000, 0x1e000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 
-0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-0x0000000c, 0x00000006, 0x00000009, 0x00000000, 0x00000000, 0x00000013, 
-0x00000005, 0x00000009, 0x00000000, 0x00000004, 0x00000019, 0x00000009, 
-0x00000003, 0x00000000, 0x00000008, 0x00000023, 0x0000000a, 0x00000003, 
-0x00000000, 0x0000000c, 0x0000002e, 0x0000000a, 0x00000003, 0x00000000, 
-0x00000010, 0x00000000, 0x0000000b, 0x00000009, 0x00010004, 0x00000000, 
-0x0000003d, 0x00000003, 0x00000009, 0x00010004, 0x00000004, 0x00000041, 
-0x00000005, 0x00000003, 0x00010004, 0x00000008, 0x00000047, 0x00000006, 
-0x00000003, 0x00010004, 0x0000000c, 0x0000004e, 0x00000006, 0x00000003, 
-0x00010004, 0x00000010, 0x00000039, 0x00000003, 0x0000000e, 0x00020001, 
-0x00000008, 0x505f6c67, 0x7469736f, 0x006e6f69, 0x74726576, 0x63007865, 
-0x726f6c6f, 0x78657400, 0x6f6f635f, 0x74006472, 0x635f7865, 0x64726f6f, 
-0x65740032, 0x6f635f78, 0x3364726f, 0x70766d00, 0x6c6f6300, 0x78657400, 
-0x7400635f, 0x635f7865, 0x65740032, 0x33635f78, 0x00000000, 
diff --git a/src/modules/engines/gl_common/shader/yuy2_mask_frag.h b/src/modules/engines/gl_common/shader/yuy2_mask_frag.h
new file mode 100644 (file)
index 0000000..5ff2089
--- /dev/null
@@ -0,0 +1,30 @@
+"#ifdef GL_ES\n"
+"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+"precision highp float;\n"
+"#else\n"
+"precision mediump float;\n"
+"#endif\n"
+"#endif\n"
+"uniform sampler2D tex, texuv, texm;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c, tex_cuv, tex_m;\n"
+"void main()\n"
+"{\n"
+"  float y,u,v,vmu,r,g,b;\n"
+"  y=texture2D(tex,tex_c).r;\n"
+"  u=texture2D(texuv,tex_cuv).g;\n"
+"  v=texture2D(texuv,tex_cuv).a;\n"
+"\n"
+"  u=u-0.5;\n"
+"  v=v-0.5;\n"
+"  vmu=v*0.813+u*0.391;\n"
+"  u=u*2.018;\n"
+"  v=v*1.596;\n"
+"\n"
+"  r=y+v;\n"
+"  g=y-vmu;\n"
+"  b=y+u;\n"
+"\n"
+"  gl_FragColor = vec4(r,g,b,1.0) * texture2D(texm, tex_m.xy).a * col;\n"
+"}\n"
+"\n"
diff --git a/src/modules/engines/gl_common/shader/yuy2_mask_frag.shd b/src/modules/engines/gl_common/shader/yuy2_mask_frag.shd
new file mode 100644 (file)
index 0000000..899ac1e
--- /dev/null
@@ -0,0 +1,30 @@
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#endif
+uniform sampler2D tex, texuv, texm;
+varying vec4 col;
+varying vec2 tex_c, tex_cuv, tex_m;
+void main()
+{
+  float y,u,v,vmu,r,g,b;
+  y=texture2D(tex,tex_c).r;
+  u=texture2D(texuv,tex_cuv).g;
+  v=texture2D(texuv,tex_cuv).a;
+
+  u=u-0.5;
+  v=v-0.5;
+  vmu=v*0.813+u*0.391;
+  u=u*2.018;
+  v=v*1.596;
+
+  r=y+v;
+  g=y-vmu;
+  b=y+u;
+
+  gl_FragColor = vec4(r,g,b,1.0) * texture2D(texm, tex_m.xy).a * col;
+}
+
diff --git a/src/modules/engines/gl_common/shader/yuy2_mask_vert.h b/src/modules/engines/gl_common/shader/yuy2_mask_vert.h
new file mode 100644 (file)
index 0000000..31ed14b
--- /dev/null
@@ -0,0 +1,17 @@
+"#ifdef GL_ES\n"
+"precision highp float;\n"
+"#endif\n"
+"attribute vec4 vertex;\n"
+"attribute vec4 color;\n"
+"attribute vec2 tex_coord, tex_coord2, tex_coordm;\n"
+"uniform mat4 mvp;\n"
+"varying vec4 col;\n"
+"varying vec2 tex_c, tex_cuv, tex_m;\n"
+"void main()\n"
+"{\n"
+"   gl_Position = mvp * vertex;\n"
+"   col = color;\n"
+"   tex_c = tex_coord;\n"
+"   tex_cuv = vec2(tex_coord2.x * 0.5, tex_coord2.y);\n"
+"   tex_m = tex_coordm;\n"
+"}\n"
diff --git a/src/modules/engines/gl_common/shader/yuy2_mask_vert.shd b/src/modules/engines/gl_common/shader/yuy2_mask_vert.shd
new file mode 100644 (file)
index 0000000..c40a07e
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord, tex_coord2, tex_coordm;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c, tex_cuv, tex_m;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+   tex_cuv = vec2(tex_coord2.x * 0.5, tex_coord2.y);
+   tex_m = tex_coordm;
+}
index 9fd5827..86ed306 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/modules/engines/gl_common \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @GL_EET_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_engine_gl_sdl_cflags@
@@ -30,7 +30,7 @@ pkgdir = $(libdir)/evas/modules/engines/gl_sdl/$(MODULE_ARCH)
 pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = $(GL_SDL_SOURCES)
-module_la_LIBADD = @EINA_LIBS@ $(GL_SDL_LIBADD) $(top_builddir)/src/lib/libevas.la @dlopen_libs@
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ $(GL_SDL_LIBADD) $(top_builddir)/src/lib/libevas.la @dlopen_libs@
 module_la_LDFLAGS = -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
old mode 100644 (file)
new mode 100755 (executable)
index c032ad1..0e9ff5a
@@ -243,7 +243,7 @@ eng_output_flush(void *data)
    re->draw.drew = 0;
 
 #if 0
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
 //   glFlush();
    eglSwapBuffers(re->egl_disp, re->egl_surface[0]);
 #else
@@ -390,6 +390,9 @@ eng_image_alpha_set(void *data, void *image, int has_alpha)
      {
         Evas_GL_Image *im_new;
         
+        if (!im->im->image.data)
+          evas_cache_image_load_data(&im->im->cache_entry);
+        evas_gl_common_image_alloc_ensure(im);
         im_new = evas_gl_common_image_new_from_copied_data(im->gc, im->im->cache_entry.w, im->im->cache_entry.h, im->im->image.data,
                                                            eng_image_alpha_get(data, image),
                                                            eng_image_colorspace_get(data, image));
@@ -456,6 +459,7 @@ eng_image_colorspace_set(void *data, void *image, int cspace)
    if (im->native.data) return;
    /* FIXME: can move to gl_common */
    if (im->cs.space == cspace) return;
+   evas_gl_common_image_alloc_ensure(im);
    evas_cache_image_colorspace(&im->im->cache_entry, cspace);
    switch (cspace)
      {
@@ -497,7 +501,7 @@ struct _Native
 {
    Evas_Native_Surface ns;
    
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
    EGLSurface  egl_surface;
 #endif
 };
@@ -615,6 +619,7 @@ eng_image_size_set(void *data, void *image, int w, int h)
          break;
      }
 
+   evas_gl_common_image_alloc_ensure(im);
    if ((im_old) && (im_old->im->cache_entry.w == w) && (im_old->im->cache_entry.h == h))
      return image;
    if (im_old)
@@ -672,6 +677,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
         return im;
      }
    error = evas_cache_image_load_data(&im->im->cache_entry);
+   evas_gl_common_image_alloc_ensure(im);
    switch (im->cs.space)
      {
       case EVAS_COLORSPACE_ARGB8888:
@@ -723,6 +729,7 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
    if (!image) return NULL;
    im = image;
    if (im->native.data) return image;
+   evas_gl_common_image_alloc_ensure(im);
    switch (im->cs.space)
      {
       case EVAS_COLORSPACE_ARGB8888:
index 7d46720..adc03b9 100644 (file)
@@ -5,7 +5,7 @@
 
 #include "config.h"
 #include <SDL/SDL.h>
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
 # include <EGL/egl.h>
 # include <SDL/SDL_opengles.h>
 # ifdef HAVE_SDL_FLAG_OPENGLES
@@ -61,7 +61,7 @@ struct _Render_Engine
       int              drew : 1;
       int              x1, y1, x2, y2;
    } draw;
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
    EGLContext       egl_context[1];
    EGLSurface       egl_surface[1];
    EGLConfig        egl_config;
old mode 100644 (file)
new mode 100755 (executable)
index fb2c81c..8e1f923
@@ -5,6 +5,19 @@
 
 typedef struct _Evas_Engine_Info_GL_X11              Evas_Engine_Info_GL_X11;
 
+/* have this feature */
+#define EVAS_ENGINE_GL_X11_SWAP_MODE_EXISTS 1
+
+typedef enum _Evas_Engine_Info_GL_X11_Swap_Mode
+{
+   EVAS_ENGINE_GL_X11_SWAP_MODE_AUTO      = 0,
+   EVAS_ENGINE_GL_X11_SWAP_MODE_FULL      = 1,
+   EVAS_ENGINE_GL_X11_SWAP_MODE_COPY      = 2,
+   EVAS_ENGINE_GL_X11_SWAP_MODE_DOUBLE    = 3,
+   EVAS_ENGINE_GL_X11_SWAP_MODE_TRIPLE    = 4,
+   EVAS_ENGINE_GL_X11_SWAP_MODE_QUADRUPLE = 5
+} Evas_Engine_Info_GL_X11_Swap_Mode;
+
 struct _Evas_Engine_Info_GL_X11
 {
    /* PRIVATE - don't mess with this baby or evas will poke its tongue out */
@@ -15,12 +28,14 @@ struct _Evas_Engine_Info_GL_X11
    struct {
       Display     *display;
       Drawable     drawable;
+      Drawable     drawable_back;
       Visual      *visual;
       Colormap     colormap;
       int          depth;
       int          screen;
       int          rotation;
       unsigned int destination_alpha  : 1;
+      unsigned int offscreen : 1;
    } info;
    /* engine specific function calls to query stuff about the destination */
    /* engine (what visual & colormap & depth to use, performance info etc. */
@@ -42,5 +57,20 @@ struct _Evas_Engine_Info_GL_X11
 
    unsigned char vsync : 1; // does nothing right now
    unsigned char indirect : 1; // use indirect rendering
+   unsigned char swap_mode : 4; // what swap mode to assume
+
+   /* TIZEN ONLY
+    * Disable sync draw done from application side when it is needed.
+    * Currently this is set true when a back-end engine uses DRI2.
+    * This depends on engine so we need to check it from evas engine.
+    */
+   Eina_Bool disable_sync_draw_done : 1;
+
+   unsigned int atom;
+
+   /* If necessary, win surface should be made with these config*/
+    int          depth_bits;
+    int          stencil_bits;
+    int          msaa_bits;
 };
 #endif
index 99ad963..e185933 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/modules/engines/gl_common \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @GL_EET_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_engine_gl_xlib_cflags@
@@ -31,7 +31,7 @@ pkgdir = $(libdir)/evas/modules/engines/gl_x11/$(MODULE_ARCH)
 pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = $(GL_X11_SOURCES)
-module_la_LIBADD = @EINA_LIBS@ @GL_EET_LIBS@ $(GL_X11_LIBADD) $(top_builddir)/src/lib/libevas.la @dlopen_libs@
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @GL_EET_LIBS@ $(GL_X11_LIBADD) $(top_builddir)/src/lib/libevas.la @dlopen_libs@
 module_la_LDFLAGS = -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 886331a..9a004be 100755 (executable)
@@ -1,5 +1,12 @@
 #include "evas_common.h" /* Also includes international specific stuff */
 #include "evas_engine.h"
+#include "evas_gl_core_private.h"
+
+//#define TIMDBG 1
+#ifdef TIMDBG
+# include <sys/time.h>
+# include <unistd.h>
+#endif
 
 #ifdef HAVE_DLSYM
 # include <dlfcn.h>      /* dlopen,dlclose,etc */
 # error gl_x11 should not get compiled if dlsym is not found on the system!
 #endif
 
-#define EVAS_GL_NO_GL_H_CHECK 1
-#include "Evas_GL.h"
+#define EVAS_GL_UPDATE_TILE_SIZE 16
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-// EGL / GLES
-# if defined(GLES_VARIETY_S3C6410)
-# elif defined(GLES_VARIETY_SGX)
-# endif
-#else
-// GLX
-#endif
+#define _ATOM_SET_CARD32( win, atom, p_val, cnt)                               \
+      XChangeProperty(_evas_x_disp, win, atom, XA_CARDINAL, 32, PropModeReplace, \
+      (unsigned char *)p_val, cnt)
+
+
+/**
+ * @typedef Evas_X_Window_Rotation_Transform_Hint
+ * @brief Enumeration of the different transform hints of the window of Ecore_X.
+ *
+ * @remarks A value of @c 3 means, HINT_0 goes to HINT_180(0x3).
+ *          It is same as HINT_0 goes to HINT_FLIP_H(0x1) and it goes to HINT_FLIP_V(0x2).( 0x1 + 0x2 = 0x3 )
+ *
+ * @remarks A value of @c 7 means, HINT_0 goes to HINT_270(0x7).
+ *          It is same as HINT_0 goes to HINT_90(0x4) and it goes to HINT_FLIP_H(0x1) and HINT_FLIP_V(0x2).( 0x4 + 0x1 + 0x2 = 0x7 )
+ */
+typedef enum _Evas_X_Window_Rotation_Transform_Hint
+{
+   EVAS_X_WINDOW_ROTATION_TRANSFORM_HINT_0 = 0,
+   EVAS_X_WINDOW_ROTATION_TRANSFORM_HINT_FLIP_H = 0x1,  /**< Rotate source image along the horizontal axis */
+   EVAS_X_WINDOW_ROTATION_TRANSFORM_HINT_FLIP_V = 0x2,  /**< Rotate source image along the vertical axis */
+   EVAS_X_WINDOW_ROTATION_TRANSFORM_HINT_180 = 0x3,       /**< Rotate source image 180 degrees clockwise */
+   EVAS_X_WINDOW_ROTATION_TRANSFORM_HINT_90 = 0x4,         /**< Rotate source image 90 degrees clockwise */
+   EVAS_X_WINDOW_ROTATION_TRANSFORM_HINT_270 = 0x7,        /**< Rotate source image 270 degrees clockwise */
+   EVAS_X_WINDOW_PREROTATION_QUERY = 0x1111,            /**< Used to Query DDK prerotation support */
+   EVAS_X_WINDOW_PREROTATION_SUPPORT = 0x2222           /**< Value set by DDK if prerotation is supported */
+} Evas_X_Window_Rotation_Transform_Hint;
+
+
+enum {
+   MERGE_BOUNDING,
+   MERGE_FULL
+};
+
+static int partial_render_debug = -1;
+static int partial_rect_union_mode = -1;
+static int swap_buffer_debug_mode = -1;
+static int swap_buffer_debug = 0;
+Display *_evas_x_disp = NULL;
+
+enum {
+   MODE_FULL,
+   MODE_COPY,
+   MODE_DOUBLE,
+   MODE_TRIPLE,
+   MODE_QUADRUPLE
+};
 
 typedef struct _Render_Engine               Render_Engine;
-typedef struct _Render_Engine_GL_Surface    Render_Engine_GL_Surface;
-typedef struct _Render_Engine_GL_Context    Render_Engine_GL_Context;
-typedef struct _Render_Engine_GL_Resource   Render_Engine_GL_Resource;
-typedef struct _Extension_Entry             Extension_Entry;
 
 struct _Render_Engine
 {
+   Tilebuf_Rect            *rects;
+   Tilebuf_Rect            *rects_prev[4];
+   Eina_Inlist             *cur_rect;
+
    Evas_GL_X11_Window      *win;
    Evas_Engine_Info_GL_X11 *info;
    Evas                    *evas;
    Tilebuf                 *tb;
    int                      end;
-/*
-   XrmDatabase   xrdb; // xres - dpi
-   struct { // xres - dpi
-      int        dpi; // xres - dpi
-   } xr; // xres - dpi
- */
-   int w, h;
-   int vsync;
+   int                      mode;
+   int                      w, h;
+   int                      vsync;
+   int                      lost_back;
+   int                      prev_age;
+   int                      frame_cnt;
+   unsigned int             atom;
+
+   Eina_Bool context_current : 1;
+   Eina_Bool context_optimize : 1;
+   Eina_Bool is_compositor : 1;
+   Eina_Bool is_prerotate : 1;
 
-   // GL Surface Capability
    struct {
-        int max_rb_size;
-        int msaa_support;
-        int msaa_samples[4];
-
-        //---------//
-        int rgb_888[4];
-        int rgba_8888[4];
-
-        int depth_8[4];
-        int depth_16[4];
-        int depth_24[4];
-        int depth_32[4];
-
-        int stencil_1[4];
-        int stencil_2[4];
-        int stencil_4[4];
-        int stencil_8[4];
-        int stencil_16[4];
-
-        int depth_24_stencil_8[4];
-   } gl_cap;
-
-   int gl_cap_initted;
-};
-
-struct _Render_Engine_GL_Surface
-{
-   int      initialized;
-   int      fbo_attached;
-   int      w, h;
-   int      depth_bits;
-   int      stencil_bits;
-
-   int      direct_fb_opt;
-   int      multisample_bits;
-
-   // Render target Texture/Buffers
-   GLint    rt_msaa_samples;
-
-   GLuint   rt_tex;
-   GLint    rt_internal_fmt;
-   GLenum   rt_fmt;
-   GLuint   rb_depth;
-   GLenum   rb_depth_fmt;
-   GLuint   rb_stencil;
-   GLenum   rb_stencil_fmt;
-   GLuint   rb_depth_stencil;
-   GLenum   rb_depth_stencil_fmt;
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   EGLSurface  direct_sfc;
-#else
-   Window      direct_sfc;
-#endif
-
-   Render_Engine_GL_Context   *current_ctx;
-};
-
-struct _Render_Engine_GL_Context
-{
-   int         initialized;
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   EGLContext  context;
-#else
-   GLXContext  context;
-#endif
-   GLuint      context_fbo;
-   GLuint      current_fbo;
-
-   int         scissor_enabled;
-   int         scissor_upated;
-
-   Render_Engine_GL_Surface   *current_sfc;
-};
-
-// Resources used per thread
-struct _Render_Engine_GL_Resource
-{
-   // Resource context/surface per Thread in TLS for evasgl use
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   EGLContext context;
-   EGLSurface surface;
-#else
-   GLXContext context;
-#endif
-};
-
-// Extension Handling
-struct _Extension_Entry
-{
-   const char *name;
-   const char *real_name;
-   int supported;
+      Evas_Object_Image_Pixels_Get_Cb  get_pixels;
+      void                            *get_pixels_data;
+      Evas_Object                     *obj;
+      int                              clip;
+      int                              x, y, w, h;
+   } func;
 };
 
 static int initted = 0;
 static int gl_wins = 0;
-static int gl_direct_override = 0;
-static int gl_direct_enabled = 0;
-static Render_Engine_GL_Context *current_evgl_ctx = NULL;
-static Render_Engine *current_engine = NULL;
-static Evas_Object *gl_direct_img_obj = NULL;
-
-static int  _ext_initted = 0;
-static char *_gl_ext_string = NULL;
-static char *_evasgl_ext_string = NULL;
-
-// Resource context/surface per Thread in TLS for evasgl use
-static Eina_TLS   resource_key;
-static Eina_List *resource_list;
-LK(resource_lock);
+static int extn_have_buffer_age = 1;
+static int prev_extn_have_buffer_age = 1;
+#ifdef GL_GLES
+static int extn_have_y_inverted = 1;
+#endif
+static int evgl_initted = 0;
 
 typedef void            (*_eng_fn) (void);
 typedef _eng_fn         (*glsym_func_eng_fn) ();
@@ -161,30 +113,36 @@ typedef void            (*glsym_func_void) ();
 typedef void           *(*glsym_func_void_ptr) ();
 typedef int             (*glsym_func_int) ();
 typedef unsigned int    (*glsym_func_uint) ();
-typedef unsigned char   (*glsym_func_uchar) ();
-typedef unsigned char  *(*glsym_func_uchar_ptr) ();
 typedef const char     *(*glsym_func_const_char_ptr) ();
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
 
 #ifndef EGL_NATIVE_PIXMAP_KHR
 # define EGL_NATIVE_PIXMAP_KHR 0x30b0
 #endif
+#ifndef EGL_BUFFER_AGE_EXT
+# define EGL_BUFFER_AGE_EXT 0x313d
+#endif
+#ifndef EGL_Y_INVERTED_NOK
+# define EGL_Y_INVERTED_NOK 0x307F
+#endif
+
 _eng_fn  (*glsym_eglGetProcAddress)            (const char *a) = NULL;
-void     (*glsym_eglBindTexImage)              (EGLDisplay a, EGLSurface b, int c) = NULL;
-void     (*glsym_eglReleaseTexImage)           (EGLDisplay a, EGLSurface b, int c) = NULL;
 void    *(*glsym_eglCreateImage)               (EGLDisplay a, EGLContext b, EGLenum c, EGLClientBuffer d, const int *e) = NULL;
 void     (*glsym_eglDestroyImage)              (EGLDisplay a, void *b) = NULL;
 void     (*glsym_glEGLImageTargetTexture2DOES) (int a, void *b)  = NULL;
-void     (*glsym_glEGLImageTargetRenderbufferStorageOES) (int a, void *b)  = NULL;
-void          *(*glsym_eglMapImageSEC)         (void *a, void *b) = NULL;
-unsigned int   (*glsym_eglUnmapImageSEC)       (void *a, void *b) = NULL;
-const char    *(*glsym_eglQueryString)         (EGLDisplay a, int name) = NULL;
-
-unsigned int   (*glsym_eglLockSurface)          (EGLDisplay a, EGLSurface b, const int *attrib_list) = NULL;
-unsigned int   (*glsym_eglUnlockSurface)        (EGLDisplay a, EGLSurface b) = NULL;
+void          *(*glsym_eglMapImageSEC)         (void *a, void *b, int c, int d) = NULL;
+unsigned int   (*glsym_eglUnmapImageSEC)       (void *a, void *b, int c) = NULL;
+void           (*glsym_eglSwapBuffersWithDamage) (EGLDisplay a, void *b, const EGLint *d, EGLint c) = NULL;
+void          *(*glsym_evgl_native_surface_buffer_get)  (void *sfc) = NULL;
+int          (*glsym_evgl_native_surface_yinvert_get)  (void *sfc) = NULL;
 
 #else
+
+#ifndef GLX_BACK_BUFFER_AGE_EXT
+# define GLX_BACK_BUFFER_AGE_EXT 0x20f4
+#endif
+
 typedef XID     (*glsym_func_xid) ();
 
 _eng_fn  (*glsym_glXGetProcAddress)  (const char *a) = NULL;
@@ -197,4570 +155,5207 @@ void     (*glsym_glXDestroyPixmap)   (Display *a, XID b) = NULL;
 void     (*glsym_glXQueryDrawable)   (Display *a, XID b, int c, unsigned int *d) = NULL;
 int      (*glsym_glXSwapIntervalSGI) (int a) = NULL;
 void     (*glsym_glXSwapIntervalEXT) (Display *s, GLXDrawable b, int c) = NULL;
+void     (*glsym_glXReleaseBuffersMESA)   (Display *a, XID b) = NULL;
+const char *(*glsym_glXQueryExtensionsString) (Display *dpy, int screen) = NULL;
 
-const char *(*glsym_glXQueryExtensionsString) (Display *a, int screen) = NULL;
 #endif
 
-// GLES2 Extensions
-void   (*glsym_glGetProgramBinaryOES) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary) = NULL;
-void   (*glsym_glProgramBinaryOES) (GLuint program, GLenum binaryFormat, const void *binary, GLint length) = NULL;
-void*  (*glsym_glMapBufferOES) (GLenum target, GLenum access) = NULL;
-unsigned char  (*glsym_glUnmapBufferOES) (GLenum target) = NULL;
-void   (*glsym_glGetBufferPointervOES) (GLenum target, GLenum pname, void** params) = NULL;
-void   (*glsym_glTexImage3DOES) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) = NULL;
-void   (*glsym_glTexSubImage3DOES) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) = NULL;
-void   (*glsym_glCopyTexSubImage3DOES) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) = NULL;
-void   (*glsym_glCompressedTexImage3DOES) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data) = NULL;
-void   (*glsym_glCompressedTexSubImage3DOES) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data) = NULL;
-void   (*glsym_glFramebufferTexture3DOES) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) = NULL;
-void   (*glsym_glGetPerfMonitorGroupsAMD) (GLint* numGroups, GLsizei groupsSize, GLuint* groups) = NULL;
-void   (*glsym_glGetPerfMonitorCountersAMD) (GLuint group, GLint* numCounters, GLint* maxActiveCounters, GLsizei counterSize, GLuint* counters) = NULL;
-void   (*glsym_glGetPerfMonitorGroupStringAMD) (GLuint group, GLsizei bufSize, GLsizei* length, char* groupString) = NULL;
-void   (*glsym_glGetPerfMonitorCounterStringAMD) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, char* counterString) = NULL;
-void   (*glsym_glGetPerfMonitorCounterInfoAMD) (GLuint group, GLuint counter, GLenum pname, void* data) = NULL;
-void   (*glsym_glGenPerfMonitorsAMD) (GLsizei n, GLuint* monitors) = NULL;
-void   (*glsym_glDeletePerfMonitorsAMD) (GLsizei n, GLuint* monitors) = NULL;
-void   (*glsym_glSelectPerfMonitorCountersAMD) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* countersList) = NULL;
-void   (*glsym_glBeginPerfMonitorAMD) (GLuint monitor) = NULL;
-void   (*glsym_glEndPerfMonitorAMD) (GLuint monitor) = NULL;
-void   (*glsym_glGetPerfMonitorCounterDataAMD) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint* bytesWritten) = NULL;
-void   (*glsym_glDiscardFramebufferEXT) (GLenum target, GLsizei numAttachments, const GLenum* attachments) = NULL;
-void   (*glsym_glMultiDrawArraysEXT) (GLenum mode, GLint* first, GLsizei* count, GLsizei primcount) = NULL;
-void   (*glsym_glMultiDrawElementsEXT) (GLenum mode, const GLsizei* count, GLenum type, const GLvoid** indices, GLsizei primcount) = NULL;
-void   (*glsym_glDeleteFencesNV) (GLsizei n, const GLuint* fences) = NULL;
-void   (*glsym_glGenFencesNV) (GLsizei n, GLuint* fences) = NULL;
-unsigned char  (*glsym_glIsFenceNV) (GLuint fence) = NULL;
-unsigned char  (*glsym_glTestFenceNV) (GLuint fence) = NULL;
-void   (*glsym_glGetFenceivNV) (GLuint fence, GLenum pname, GLint* params) = NULL;
-void   (*glsym_glFinishFenceNV) (GLuint fence) = NULL;
-void   (*glsym_glSetFenceNV) (GLuint, GLenum) = NULL;
-void    (*glsym_glRenderbufferStorageMultisample) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) = NULL;
-void    (*glsym_glFramebufferTexture2DMultisample) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) = NULL;
-void   (*glsym_glGetDriverControlsQCOM) (GLint* num, GLsizei size, GLuint* driverControls) = NULL;
-void   (*glsym_glGetDriverControlStringQCOM) (GLuint driverControl, GLsizei bufSize, GLsizei* length, char* driverControlString) = NULL;
-void   (*glsym_glEnableDriverControlQCOM) (GLuint driverControl) = NULL;
-void   (*glsym_glDisableDriverControlQCOM) (GLuint driverControl) = NULL;
-void   (*glsym_glExtGetTexturesQCOM) (GLuint* textures, GLint maxTextures, GLint* numTextures) = NULL;
-void   (*glsym_glExtGetBuffersQCOM) (GLuint* buffers, GLint maxBuffers, GLint* numBuffers) = NULL;
-void   (*glsym_glExtGetRenderbuffersQCOM) (GLuint* renderbuffers, GLint maxRenderbuffers, GLint* numRenderbuffers) = NULL;
-void   (*glsym_glExtGetFramebuffersQCOM) (GLuint* framebuffers, GLint maxFramebuffers, GLint* numFramebuffers) = NULL;
-void   (*glsym_glExtGetTexLevelParameterivQCOM) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint* params) = NULL;
-void   (*glsym_glExtTexObjectStateOverrideiQCOM) (GLenum target, GLenum pname, GLint param) = NULL;
-void   (*glsym_glExtGetTexSubImageQCOM) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void* texels) = NULL;
-void   (*glsym_glExtGetBufferPointervQCOM) (GLenum target, void** params) = NULL;
-void   (*glsym_glExtGetShadersQCOM) (GLuint* shaders, GLint maxShaders, GLint* numShaders) = NULL;
-void   (*glsym_glExtGetProgramsQCOM) (GLuint* programs, GLint maxPrograms, GLint* numPrograms) = NULL;
-unsigned char  (*glsym_glExtIsProgramBinaryQCOM) (GLuint program) = NULL;
-void   (*glsym_glExtGetProgramBinarySourceQCOM) (GLuint program, GLenum shadertype, char* source, GLint* length) = NULL;
-
-
-//------ GLES 2.0 Extensions supported in EvasGL -----//
-static Extension_Entry _gl_ext_entries[] = {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-       //--- Function Extensions ---//
-       { "GL_OES_get_program_binary", "get_program_binary", 0 },
-       { "GL_OES_mapbuffer", "mapbuffer", 0 },
-       { "GL_OES_texture_3D", "texture_3D", 0 },
-       { "AMD_performance_monitor", "AMD_performance_monitor", 0 },
-       { "GL_EXT_discard_framebuffer", "discard_framebuffer", 0 },
-       { "GL_EXT_multi_draw_arrays", "multi_draw_arrays", 0 },
-       { "GL_NV_fence", "NV_fence", 0 },
-       { "GL_QCOM_driver_control", "QCOM_driver_control", 0 },
-       { "GL_QCOM_extended_get", "QCOM_extended_get", 0 },
-       { "GL_QCOM_extended_get2", "QCOM_extended_get2", 0 },
-       { "GL_IMG_multlisampled_render_to_texture", "multisampled_render_to_texture", 0 },
-
-       //--- Define Extensions ---//
-       { "GL_OES_compressed_ETC1_RGB8_texture", "compressed_ETC1_RGB8_texture", 0 },
-       { "GL_OES_compressed_paletted_texture", "compressed_paletted_texture", 0 },
-       { "GL_OES_depth24", "depth24", 0 },
-       { "GL_OES_depth32", "depth32", 0 },
-       { "GL_OES_EvasGL_image", "EGL_image", 0 },
-       { "GL_OES_packed_depth_stencil", "packed_depth_stencil", 0 },
-       { "GL_OES_rgb8_rgba8", "rgb8_rgba8", 0 },
-       { "GL_OES_standard_derivatives", "standard_derivatives", 0 },
-       { "GL_OES_stencil1", "stencil1", 0 },
-       { "GL_OES_stencil4", "stencil4", 0 },
-       { "GL_OES_texture_float", "texture_float", 0 },
-       { "GL_OES_texture_half_float", "texture_half_float", 0 },
-       { "GL_OES_texture_half_float_linear", "texture_half_float_linear", 0 },
-       { "GL_OES_texture_npot", "texture_npot", 0 },
-       { "GL_OES_vertex_half_float", "vertex_half_float", 0 },
-       { "GL_OES_vertex_type_10_10_10_2", "vertex_type_10_10_10_2", 0 },
-       { "GL_AMD_compressed_3DC_texture", "compressed_3DC_texture", 0 },
-       { "GL_AMD_compressed_ATC_texture", "compressed_ATC_texture", 0 },
-       { "GL_AMD_program_binary_Z400", "program_binary_Z400", 0 },
-       { "GL_EXT_blend_minmax", "blend_minmax", 0 },
-       { "GL_EXT_read_format_bgra", "read_format_bgra", 0 },
-       { "GL_EXT_texture_filter_anisotropic", "texture_filter_anisotrophic", 0 },
-       { "GL_EXT_texture_format_BGRA8888", "texture_format_BGRA8888", 0 },
-       { "GL_EXT_texture_type_2_10_10_10_REV", "texture_type_2_10_10_10_rev", 0 },
-       { "GL_IMG_program_binary", "IMG_program_binary", 0 },
-       { "GL_IMG_read_format", "IMG_read_format", 0 },
-       { "GL_IMG_shader_binary", "IMG_shader_binary", 0 },
-       { "GL_IMG_texture_compression_pvrtc", "IMG_texture_compression_pvrtc", 0 },
-       { "GL_QCOM_perfmon_global_mode", "QCOM_perfmon_global_mode", 0 },
-       { "GL_QCOM_writeonly_rendering", "QCOM_writeonly_rendering", 0 },
-#else
-       //--- Function Extensions ---//
-       { "GL_OES_get_program_binary", "get_program_binary", 0 },
-       { "GL_OES_mapbuffer", "mapbuffer", 0 },
-       { "GL_OES_texture_3D", "texture_3D", 0 },
-       { "AMD_performance_monitor", "AMD_performance_monitor", 0 },
-       { "GL_EXT_discard_framebuffer", "discard_framebuffer", 0 },
-       { "GL_EXT_multi_draw_arrays", "multi_draw_arrays", 0 },
-       { "GL_NV_fence", "NV_fence", 0 },
-       { "GL_QCOM_driver_control", "QCOM_driver_control", 0 },
-       { "GL_QCOM_extended_get", "QCOM_extended_get", 0 },
-       { "GL_QCOM_extended_get2", "QCOM_extended_get2", 0 },
-       { "GL_IMG_multlisampled_render_to_texture", "multisampled_render_to_texture", 0 },
-
-       //--- Define Extensions ---//
-       { "GL_OES_compressed_ETC1_RGB8_texture", "compressed_ETC1_RGB8_texture", 0 },
-       { "GL_OES_compressed_paletted_texture", "compressed_paletted_texture", 0 },
-       { "GL_OES_depth24", "depth24", 0 },
-       { "GL_OES_depth32", "depth32", 0 },
-       { "GL_OES_EvasGL_image", "EGL_image", 0 },
-       { "GL_OES_packed_depth_stencil", "packed_depth_stencil", 0 },
-       { "GL_OES_rgb8_rgba8", "rgb8_rgba8", 0 },
-       { "GL_OES_standard_derivatives", "standard_derivatives", 0 },
-       { "GL_OES_stencil1", "stencil1", 0 },
-       { "GL_OES_stencil4", "stencil4", 0 },
-       { "GL_OES_texture_float", "texture_float", 0 },
-       { "GL_OES_texture_half_float", "texture_half_float", 0 },
-       { "GL_OES_texture_half_float_linear", "texture_half_float_linear", 0 },
-       { "GL_OES_texture_npot", "texture_non_power_of_two", 0 },     // Desktop differs
-       { "GL_OES_vertex_half_float", "half_float_vertex", 0 }, // Desktop differs
-       { "GL_OES_vertex_type_10_10_10_2", "vertex_type_10_10_10_2", 0 },
-       { "GL_AMD_compressed_3DC_texture", "compressed_3DC_texture", 0 },
-       { "GL_AMD_compressed_ATC_texture", "compressed_ATC_texture", 0 },
-       { "GL_AMD_program_binary_Z400", "program_binary_Z400", 0 },
-       { "GL_EXT_blend_minmax", "blend_minmax", 0 },
-       { "GL_EXT_read_format_bgra", "bgra", 0 }, // Desktop differs
-       { "GL_EXT_texture_filter_anisotropic", "texture_filter_anisotrophic", 0 },
-       { "GL_EXT_texture_format_BGRA8888", "bgra", 0 }, // Desktop differs
-       { "GL_EXT_texture_type_2_10_10_10_REV", "vertex_type_2_10_10_10_rev", 0 },  // Desktop differs ???
-       { "GL_IMG_program_binary", "IMG_program_binary", 0 },
-       { "GL_IMG_read_format", "IMG_read_format", 0 },
-       { "GL_IMG_shader_binary", "IMG_shader_binary", 0 },
-       { "GL_IMG_texture_compression_pvrtc", "IMG_texture_compression_pvrtc", 0 },
-       { "GL_QCOM_perfmon_global_mode", "QCOM_perfmon_global_mode", 0 },
-       { "GL_QCOM_writeonly_rendering", "QCOM_writeonly_rendering", 0 },
+#ifdef TIMDBG
+static double
+gettime(void)
+{
+   struct timeval      timev;
 
-#endif
-       { NULL, NULL, 0}
-};
+   gettimeofday(&timev, NULL);
+   return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
+}
 
-//------ Extensions supported in EvasGL -----//
-static Extension_Entry _evasgl_ext_entries[] = {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-       { "EvasGL_KHR_image", "EGL_KHR_image", 0 },
-       { "EvasGL_KHR_vg_parent_image", "EGL_KHR_vg_parent_image", 0 },
-       { "EvasGL_KHR_gl_texture_2D_image", "EGL_KHR_gl_texture_2D_image", 0 },
-       { "EvasGL_KHR_gl_texture_cubemap_image", "EGL_KHR_gl_texture_cubemap_image", 0 },
-       { "EvasGL_KHR_gl_texture_3D_image", "EGL_KHR_gl_texture_3D_image", 0 },
-       { "EvasGL_KHR_gl_renderbuffer_image", "EGL_KHR_gl_renderbuffer_image", 0 },
-#else
+static void
+measure(int end, const char *name)
+{
+   FILE *fs;
+   static unsigned long user = 0, kern = 0, user2 = 0, kern2 = 0;
+   static double t = 0.0, t2 = 0.0;
+   unsigned long u = 0, k = 0;
+
+   fs = fopen("/proc/self/stat", "rb");
+   if (fs) {
+      fscanf(fs, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s "
+             "%lu %lu %*s", &u, &k);
+      fclose(fs);
+   }
+   if (end)
+     {
+        long hz;
+
+        t2 = gettime();
+        user2 = u;
+        kern2 = k;
+        hz = sysconf(_SC_CLK_TCK);
+        fprintf(stderr, "(%8lu %8lu) k=%4lu u=%4lu == tot=%4lu@%4li in=%3.5f < %s\n",
+                user, kern, kern2 - kern, user2 - user,
+                (kern2 - kern) + (user2 - user), hz, t2 - t, name);
+     }
+   else
+     {
+        user = u;
+        kern = k;
+        t = gettime();
+     }
+}
 #endif
-       { NULL, NULL, 0 }
-};
 
-static void
-_gl_ext_sym_init(void)
+static int
+_check_compositor(void)
 {
-   static int done = 0;
+#define COMPOSITOR "enlightenment"
+   FILE *f;
+   char *slash;
+   static int initialized = 0;
+   static unsigned int is_compositor = 0;
+   char app_name[128];
 
-   if (done) return;
+   if (initialized) return is_compositor;
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-#define FINDSYM(dst, sym, typ) \
-   if ((!dst) && (glsym_eglGetProcAddress)) dst = (typ)glsym_eglGetProcAddress(sym); \
-   if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym)
+   /* get the application name */
+   f = fopen("/proc/self/cmdline", "r");
+   if (!f)
+     {
+        perror(" file open error : ");
+        return -1;
+     }
+   memset(app_name, 0x00, sizeof(app_name));
+   if (fgets(app_name, 100, f) == NULL)
+     {
+        perror(" fgets open error : ");
+        fclose(f);
+        return -1;
+     }
+   fclose(f);
+   if ((slash=strrchr(app_name, '/')) != NULL)
+     {
+        memmove(app_name, slash+1, strlen(slash));
+     }
+   initialized = 1;
 
-   FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddress", glsym_func_eng_fn);
-   FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressEXT", glsym_func_eng_fn);
-   FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressARB", glsym_func_eng_fn);
-   FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressKHR", glsym_func_eng_fn);
+   if(app_name && !strncmp(app_name, COMPOSITOR, strlen(COMPOSITOR)))
+      is_compositor = 1;
 
-   FINDSYM(glsym_eglBindTexImage, "eglBindTexImage", glsym_func_void);
-   FINDSYM(glsym_eglBindTexImage, "eglBindTexImageEXT", glsym_func_void);
-   FINDSYM(glsym_eglBindTexImage, "eglBindTexImageARB", glsym_func_void);
-   FINDSYM(glsym_eglBindTexImage, "eglBindTexImageKHR", glsym_func_void);
+#undef COMPOSITOR
+   return is_compositor;
+}
 
-   FINDSYM(glsym_eglReleaseTexImage, "eglReleaseTexImage", glsym_func_void);
-   FINDSYM(glsym_eglReleaseTexImage, "eglReleaseTexImageEXT", glsym_func_void);
-   FINDSYM(glsym_eglReleaseTexImage, "eglReleaseTexImageARB", glsym_func_void);
-   FINDSYM(glsym_eglReleaseTexImage, "eglReleaseTexImageKHR", glsym_func_void);
+//----------------------------------------------------------//
+// NEW_EVAS_GL Engine Functions
+static void *
+evgl_eng_display_get(void *data)
+{
+   Render_Engine *re = (Render_Engine *)data;
 
-   FINDSYM(glsym_eglCreateImage, "eglCreateImage", glsym_func_void_ptr);
-   FINDSYM(glsym_eglCreateImage, "eglCreateImageEXT", glsym_func_void_ptr);
-   FINDSYM(glsym_eglCreateImage, "eglCreateImageARB", glsym_func_void_ptr);
-   FINDSYM(glsym_eglCreateImage, "eglCreateImageKHR", glsym_func_void_ptr);
+   if (!re)
+     {
+        ERR("Invalid Render Engine Data!");
+        return 0;
+     }
 
-   FINDSYM(glsym_eglDestroyImage, "eglDestroyImage", glsym_func_void);
-   FINDSYM(glsym_eglDestroyImage, "eglDestroyImageEXT", glsym_func_void);
-   FINDSYM(glsym_eglDestroyImage, "eglDestroyImageARB", glsym_func_void);
-   FINDSYM(glsym_eglDestroyImage, "eglDestroyImageKHR", glsym_func_void);
+#ifdef GL_GLES
+   if (re->win)
+      return (void*)re->win->egl_disp;
+#else
+   if (re->info)
+      return (void*)re->info->info.display;
+#endif
+   else
+      return NULL;
+}
 
-   FINDSYM(glsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", glsym_func_void);
+static void *
+evgl_eng_evas_surface_get(void *data)
+{
+   Render_Engine *re = (Render_Engine *)data;
 
-   FINDSYM(glsym_glEGLImageTargetRenderbufferStorageOES, "glEGLImageTargetRenderbufferStorageOES", glsym_func_void);
+   if (!re)
+     {
+        ERR("Invalid Render Engine Data!");
+        return 0;
+     }
 
-   FINDSYM(glsym_eglMapImageSEC, "eglMapImageSEC", glsym_func_void_ptr);
-   FINDSYM(glsym_eglUnmapImageSEC, "eglUnmapImageSEC", glsym_func_uint);
+#ifdef GL_GLES
+   if (re->win)
+      return (void*)re->win->egl_surface[re->win->offscreen];
+#else
+   if (re->win)
+      return (void*)re->win->win;
+#endif
+   else
+      return NULL;
+}
 
-   FINDSYM(glsym_eglQueryString, "eglQueryString", glsym_func_const_char_ptr);
+static int
+evgl_eng_make_current(void *data, void *surface, void *context, int flush)
+{
+   Render_Engine *re = (Render_Engine *)data;
+   int ret = 0;
 
-   FINDSYM(glsym_eglLockSurface, "eglLockSurface", glsym_func_uint);
-   FINDSYM(glsym_eglLockSurface, "eglLockSurfaceEXT", glsym_func_uint);
-   FINDSYM(glsym_eglLockSurface, "eglLockSurfaceARB", glsym_func_uint);
-   FINDSYM(glsym_eglLockSurface, "eglLockSurfaceKHR", glsym_func_uint);
+   if (!re)
+     {
+        ERR("Invalid Render Engine Data!");
+        _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+        return 0;
+     }
 
-   FINDSYM(glsym_eglUnlockSurface, "eglUnlockSurface", glsym_func_uint);
-   FINDSYM(glsym_eglUnlockSurface, "eglUnlockSurfaceEXT", glsym_func_uint);
-   FINDSYM(glsym_eglUnlockSurface, "eglUnlockSurfaceARB", glsym_func_uint);
-   FINDSYM(glsym_eglUnlockSurface, "eglUnlockSurfaceKHR", glsym_func_uint);
 
-#else
-#define FINDSYM(dst, sym, typ) \
-   if ((!dst) && (glsym_glXGetProcAddress)) dst = (typ)glsym_glXGetProcAddress(sym); \
-   if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym)
+#ifdef GL_GLES
+   EGLContext ctx = (EGLContext)context;
+   EGLSurface sfc = (EGLSurface)surface;
+   EGLDisplay dpy = re->win->egl_disp; //eglGetCurrentDisplay();
 
-   FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddress", glsym_func_eng_fn);
-   FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddressEXT", glsym_func_eng_fn);
-   FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddressARB", glsym_func_eng_fn);
+   if ((!context) && (!surface))
+     {
+        ret = eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+        if (!ret)
+          {
+             int err = eglGetError();
+             _evgl_error_set(err - EGL_SUCCESS);
+             ERR("eglMakeCurrent() failed! Error Code=%#x", err);
+             return 0;
+          }
+        return 1;
+     }
 
-   FINDSYM(glsym_glXBindTexImage, "glXBindTexImage", glsym_func_void);
-   FINDSYM(glsym_glXBindTexImage, "glXBindTexImageEXT", glsym_func_void);
-   FINDSYM(glsym_glXBindTexImage, "glXBindTexImageARB", glsym_func_void);
+   if ((eglGetCurrentDisplay() != dpy) ||
+       (eglGetCurrentContext() != ctx) ||
+       (eglGetCurrentSurface(EGL_READ) != sfc) ||
+       (eglGetCurrentSurface(EGL_DRAW) != sfc) )
+     {
 
-   FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImage", glsym_func_void);
-   FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageEXT", glsym_func_void);
-   FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageARB", glsym_func_void);
+        //!!!! Does it need to be flushed with it's set to NULL above??
+        // Flush remainder of what's in Evas' pipeline
+        if (flush) eng_window_use(NULL);
 
-   FINDSYM(glsym_glXGetVideoSync, "glXGetVideoSyncSGI", glsym_func_int);
+        // Do a make current
+        ret = eglMakeCurrent(dpy, sfc, sfc, ctx);
 
-   FINDSYM(glsym_glXWaitVideoSync, "glXWaitVideoSyncSGI", glsym_func_int);
+        if (!ret)
+          {
+             int err = eglGetError();
+             _evgl_error_set(err - EGL_SUCCESS);
+             ERR("eglMakeCurrent() failed! Error Code=%#x", err);
+             return 0;
+          }
+     }
 
-   FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmap", glsym_func_xid);
-   FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmapEXT", glsym_func_xid);
-   FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmapARB", glsym_func_xid);
+   return 1;
+#else
+   GLXContext ctx = (GLXContext)context;
+   Window     sfc = (Window)surface;
 
-   FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmap", glsym_func_void);
-   FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmapEXT", glsym_func_void);
-   FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmapARB", glsym_func_void);
+   if ((!context) && (!surface))
+     {
+        ret = glXMakeCurrent(re->info->info.display, None, NULL);
+        if (!ret)
+          {
+             ERR("glXMakeCurrent() failed!");
+             _evgl_error_set(EVAS_GL_BAD_DISPLAY);
+             return 0;
+          }
+        return 1;
+     }
 
-   FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawable", glsym_func_void);
-   FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawableEXT", glsym_func_void);
-   FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawableARB", glsym_func_void);
 
-   FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalMESA", glsym_func_int);
-   FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalSGI", glsym_func_int);
+   if ((glXGetCurrentContext() != ctx))
+     {
+        //!!!! Does it need to be flushed with it's set to NULL above??
+        // Flush remainder of what's in Evas' pipeline
+        if (flush) eng_window_use(NULL);
 
-   FINDSYM(glsym_glXSwapIntervalEXT, "glXSwapIntervalEXT", glsym_func_void);
+        // Do a make current
+        ret = glXMakeCurrent(re->info->info.display, sfc, ctx);
 
-   FINDSYM(glsym_glXQueryExtensionsString, "glXQueryExtensionsString", glsym_func_const_char_ptr);
+        if (!ret)
+          {
+             ERR("glXMakeCurrent() failed. Ret: %d! Context: %p Surface: %p", ret, (void*)ctx, (void*)sfc);
+             _evgl_error_set(EVAS_GL_BAD_DISPLAY);
+             return 0;
+          }
+     }
+   return 1;
 #endif
+}
 
-   //----------- GLES 2.0 Extensions ------------//
-   // If the symbol's not found, they get set to NULL
-   // If one of the functions in the extension exists, the extension in supported
-
-   /* GL_OES_get_program_binary */
-   FINDSYM(glsym_glGetProgramBinaryOES, "glGetProgramBinary", glsym_func_void);
-   FINDSYM(glsym_glGetProgramBinaryOES, "glGetProgramBinaryEXT", glsym_func_void);
-   FINDSYM(glsym_glGetProgramBinaryOES, "glGetProgramBinaryARB", glsym_func_void);
-   FINDSYM(glsym_glGetProgramBinaryOES, "glGetProgramBinaryOES", glsym_func_void);
-
-   FINDSYM(glsym_glProgramBinaryOES, "glProgramBinary", glsym_func_void);
-   FINDSYM(glsym_glProgramBinaryOES, "glProgramBinaryEXT", glsym_func_void);
-   FINDSYM(glsym_glProgramBinaryOES, "glProgramBinaryARB", glsym_func_void);
-   FINDSYM(glsym_glProgramBinaryOES, "glProgramBinaryOES", glsym_func_void);
-
-   // Check the first function to see if the extension is supported...
-   if (glsym_glGetProgramBinaryOES) _gl_ext_entries[0].supported = 1;
-
-
-   /* GL_OES_mapbuffer */
-   FINDSYM(glsym_glMapBufferOES, "glMapBuffer", glsym_func_void_ptr);
-   FINDSYM(glsym_glMapBufferOES, "glMapBufferEXT", glsym_func_void_ptr);
-   FINDSYM(glsym_glMapBufferOES, "glMapBufferARB", glsym_func_void_ptr);
-   FINDSYM(glsym_glMapBufferOES, "glMapBufferOES", glsym_func_void_ptr);
-
-   FINDSYM(glsym_glUnmapBufferOES, "glUnmapBuffer", glsym_func_uchar);
-   FINDSYM(glsym_glUnmapBufferOES, "glUnmapBufferEXT", glsym_func_uchar);
-   FINDSYM(glsym_glUnmapBufferOES, "glUnmapBufferARB", glsym_func_uchar);
-   FINDSYM(glsym_glUnmapBufferOES, "glUnmapBufferOES", glsym_func_uchar);
-
-   FINDSYM(glsym_glGetBufferPointervOES, "glGetBufferPointerv", glsym_func_void);
-   FINDSYM(glsym_glGetBufferPointervOES, "glGetBufferPointervEXT", glsym_func_void);
-   FINDSYM(glsym_glGetBufferPointervOES, "glGetBufferPointervARB", glsym_func_void);
-   FINDSYM(glsym_glGetBufferPointervOES, "glGetBufferPointervOES", glsym_func_void);
-
-   if (glsym_glMapBufferOES) _gl_ext_entries[1].supported = 1;
-
-   /* GL_OES_texture_3D */
-   FINDSYM(glsym_glTexImage3DOES, "glTexImage3D", glsym_func_void);
-   FINDSYM(glsym_glTexImage3DOES, "glTexImage3DEXT", glsym_func_void);
-   FINDSYM(glsym_glTexImage3DOES, "glTexImage3DARB", glsym_func_void);
-   FINDSYM(glsym_glTexImage3DOES, "glTexImage3DOES", glsym_func_void);
-
-   FINDSYM(glsym_glTexSubImage3DOES, "glTexSubImage3D", glsym_func_void);
-   FINDSYM(glsym_glTexSubImage3DOES, "glTexSubImage3DEXT", glsym_func_void);
-   FINDSYM(glsym_glTexSubImage3DOES, "glTexSubImage3DARB", glsym_func_void);
-   FINDSYM(glsym_glTexSubImage3DOES, "glTexSubImage3DOES", glsym_func_void);
-
-   FINDSYM(glsym_glCopyTexSubImage3DOES, "glCopyTexSubImage3D", glsym_func_void);
-   FINDSYM(glsym_glCopyTexSubImage3DOES, "glCopyTexSubImage3DARB", glsym_func_void);
-   FINDSYM(glsym_glCopyTexSubImage3DOES, "glCopyTexSubImage3DEXT", glsym_func_void);
-   FINDSYM(glsym_glCopyTexSubImage3DOES, "glCopyTexSubImage3DOES", glsym_func_void);
-
-   FINDSYM(glsym_glCompressedTexImage3DOES, "glCompressedTexImage3D", glsym_func_void);
-   FINDSYM(glsym_glCompressedTexImage3DOES, "glCompressedTexImage3DARB", glsym_func_void);
-   FINDSYM(glsym_glCompressedTexImage3DOES, "glCompressedTexImage3DEXT", glsym_func_void);
-   FINDSYM(glsym_glCompressedTexImage3DOES, "glCompressedTexImage3DOES", glsym_func_void);
-
-   FINDSYM(glsym_glCompressedTexSubImage3DOES, "glCompressedTexSubImage3D", glsym_func_void);
-   FINDSYM(glsym_glCompressedTexSubImage3DOES, "glCompressedTexSubImage3DARB", glsym_func_void);
-   FINDSYM(glsym_glCompressedTexSubImage3DOES, "glCompressedTexSubImage3DEXT", glsym_func_void);
-   FINDSYM(glsym_glCompressedTexSubImage3DOES, "glCompressedTexSubImage3DOES", glsym_func_void);
-
-   FINDSYM(glsym_glFramebufferTexture3DOES, "glFramebufferTexture3D", glsym_func_void);
-   FINDSYM(glsym_glFramebufferTexture3DOES, "glFramebufferTexture3DARB", glsym_func_void);
-   FINDSYM(glsym_glFramebufferTexture3DOES, "glFramebufferTexture3DEXT", glsym_func_void);
-   FINDSYM(glsym_glFramebufferTexture3DOES, "glFramebufferTexture3DOES", glsym_func_void);
-
-   if (glsym_glTexSubImage3DOES) _gl_ext_entries[2].supported = 1;
-
-   /* AMD_performance_monitor */
-   FINDSYM(glsym_glGetPerfMonitorGroupsAMD, "glGetPerfMonitorGroupsAMD", glsym_func_void);
-   FINDSYM(glsym_glGetPerfMonitorCountersAMD, "glGetPerfMonitorCountersAMD", glsym_func_void);
-   FINDSYM(glsym_glGetPerfMonitorGroupStringAMD, "glGetPerfMonitorGroupStringAMD", glsym_func_void);
-   FINDSYM(glsym_glGetPerfMonitorCounterStringAMD, "glGetPerfMonitorCounterStringAMD", glsym_func_void);
-   FINDSYM(glsym_glGetPerfMonitorCounterInfoAMD, "glGetPerfMonitorCounterInfoAMD", glsym_func_void);
-   FINDSYM(glsym_glGenPerfMonitorsAMD, "glGenPerfMonitorsAMD", glsym_func_void);
-   FINDSYM(glsym_glDeletePerfMonitorsAMD, "glDeletePerfMonitorsAMD", glsym_func_void);
-   FINDSYM(glsym_glSelectPerfMonitorCountersAMD, "glSelectPerfMonitorCountersAMD", glsym_func_void);
-   FINDSYM(glsym_glBeginPerfMonitorAMD, "glBeginPerfMonitorAMD", glsym_func_void);
-   FINDSYM(glsym_glEndPerfMonitorAMD, "glEndPerfMonitorAMD", glsym_func_void);
-   FINDSYM(glsym_glGetPerfMonitorCounterDataAMD, "glGetPerfMonitorCounterDataAMD", glsym_func_void);
-
-   if (glsym_glGetPerfMonitorGroupsAMD) _gl_ext_entries[3].supported = 1;
-
-   /* GL_EXT_discard_framebuffer */
-   FINDSYM(glsym_glDiscardFramebufferEXT, "glDiscardFramebuffer", glsym_func_void);
-   FINDSYM(glsym_glDiscardFramebufferEXT, "glDiscardFramebufferARB", glsym_func_void);
-   FINDSYM(glsym_glDiscardFramebufferEXT, "glDiscardFramebufferEXT", glsym_func_void);
-
-   if (glsym_glDiscardFramebufferEXT) _gl_ext_entries[4].supported = 1;
-
-   /* GL_EXT_multi_draw_arrays */
-   FINDSYM(glsym_glMultiDrawArraysEXT, "glMultiDrawArrays", glsym_func_void);
-   FINDSYM(glsym_glMultiDrawArraysEXT, "glMultiDrawArraysARB", glsym_func_void);
-   FINDSYM(glsym_glMultiDrawArraysEXT, "glMultiDrawArraysEXT", glsym_func_void);
-
-   FINDSYM(glsym_glMultiDrawElementsEXT, "glMultiDrawElements", glsym_func_void);
-   FINDSYM(glsym_glMultiDrawElementsEXT, "glMultiDrawElementsARB", glsym_func_void);
-   FINDSYM(glsym_glMultiDrawElementsEXT, "glMultiDrawElementsEXT", glsym_func_void);
-
-   if (glsym_glMultiDrawArraysEXT) _gl_ext_entries[5].supported = 1;
-
-   /* GL_NV_fence */
-   FINDSYM(glsym_glDeleteFencesNV, "glDeleteFencesNV", glsym_func_void);
-   FINDSYM(glsym_glGenFencesNV, "glGenFencesNV", glsym_func_void);
-   FINDSYM(glsym_glIsFenceNV, "glIsFenceNV", glsym_func_uchar);
-   FINDSYM(glsym_glTestFenceNV, "glTestFenceNV", glsym_func_uchar);
-   FINDSYM(glsym_glGetFenceivNV, "glGetFenceivNV", glsym_func_void);
-   FINDSYM(glsym_glFinishFenceNV, "glFinishFenceNV", glsym_func_void);
-   FINDSYM(glsym_glSetFenceNV, "glSetFenceNV", glsym_func_void);
-
-   if (glsym_glDeleteFencesNV) _gl_ext_entries[6].supported = 1;
-
-   /* GL_QCOM_driver_control */
-   FINDSYM(glsym_glGetDriverControlsQCOM, "glGetDriverControlsQCOM", glsym_func_void);
-   FINDSYM(glsym_glGetDriverControlStringQCOM, "glGetDriverControlStringQCOM", glsym_func_void);
-   FINDSYM(glsym_glEnableDriverControlQCOM, "glEnableDriverControlQCOM", glsym_func_void);
-   FINDSYM(glsym_glDisableDriverControlQCOM, "glDisableDriverControlQCOM", glsym_func_void);
-
-   if (glsym_glGetDriverControlsQCOM) _gl_ext_entries[7].supported = 1;
-
-   /* GL_QCOM_extended_get */
-   FINDSYM(glsym_glExtGetTexturesQCOM, "glExtGetTexturesQCOM", glsym_func_void);
-   FINDSYM(glsym_glExtGetBuffersQCOM, "glExtGetBuffersQCOM", glsym_func_void);
-   FINDSYM(glsym_glExtGetRenderbuffersQCOM, "glExtGetRenderbuffersQCOM", glsym_func_void);
-   FINDSYM(glsym_glExtGetFramebuffersQCOM, "glExtGetFramebuffersQCOM", glsym_func_void);
-   FINDSYM(glsym_glExtGetTexLevelParameterivQCOM, "glExtGetTexLevelParameterivQCOM", glsym_func_void);
-   FINDSYM(glsym_glExtTexObjectStateOverrideiQCOM, "glExtTexObjectStateOverrideiQCOM", glsym_func_void);
-   FINDSYM(glsym_glExtGetTexSubImageQCOM, "glExtGetTexSubImageQCOM", glsym_func_void);
-   FINDSYM(glsym_glExtGetBufferPointervQCOM, "glExtGetBufferPointervQCOM", glsym_func_void);
-
-   if (glsym_glExtGetTexturesQCOM) _gl_ext_entries[8].supported = 1;
-
-   /* GL_QCOM_extended_get2 */
-   FINDSYM(glsym_glExtGetShadersQCOM, "glExtGetShadersQCOM", glsym_func_void);
-   FINDSYM(glsym_glExtGetProgramsQCOM, "glExtGetProgramsQCOM", glsym_func_void);
-   FINDSYM(glsym_glExtIsProgramBinaryQCOM, "glExtIsProgramBinaryQCOM", glsym_func_uchar);
-   FINDSYM(glsym_glExtGetProgramBinarySourceQCOM, "glExtGetProgramBinarySourceQCOM", glsym_func_void);
-
-   if (glsym_glExtGetShadersQCOM) _gl_ext_entries[9].supported = 1;
-
-   /* GL_IMG_multisampled_render_to_texture */
-   FINDSYM(glsym_glRenderbufferStorageMultisample, "glRenderbufferStorageMultisampleIMG", glsym_func_void);
-   FINDSYM(glsym_glRenderbufferStorageMultisample, "glRenderbufferStorageMultisampleEXT", glsym_func_void);
-   FINDSYM(glsym_glFramebufferTexture2DMultisample, "glFramebufferTexture2DMultisampleIMG", glsym_func_void);
-   FINDSYM(glsym_glFramebufferTexture2DMultisample, "glFramebufferTexture2DMultisampleEXT", glsym_func_void);
 
-}
 
-static void
-_gl_ext_init(Render_Engine *re)
+static void *
+evgl_eng_native_window_create(void *data)
 {
-   int i, ext_len = 0;
-   const char *glexts, *evasglexts;
-
-   // GLES 2.0 Extensions
-   glexts = (const char*)glGetString(GL_EXTENSIONS);
+   Render_Engine *re = (Render_Engine *)data;
 
-   ext_len = strlen(glexts);
-   if (!ext_len)
+   if (!re)
      {
-        DBG("GL Get Extension string NULL: No extensions supported");
-        return;
+        ERR("Invalid Render Engine Data!");
+        _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+        return NULL;
      }
 
-   _gl_ext_string = calloc(1, sizeof(char) * ext_len * 2);
-   if (!_gl_ext_string)
-     {
-        ERR("Error allocating _gl_ext_string.");
-        return;
+   XSetWindowAttributes attr;
+   Window win;
+
+   attr.backing_store = NotUseful;
+   attr.override_redirect = True;
+   attr.border_pixel = 0;
+   attr.background_pixmap = None;
+   attr.bit_gravity = NorthWestGravity;
+   attr.win_gravity = NorthWestGravity;
+   attr.save_under = False;
+   attr.do_not_propagate_mask = NoEventMask;
+   attr.event_mask = 0;
+
+   win = XCreateWindow(re->info->info.display,
+                       DefaultRootWindow(re->info->info.display),
+                       0, 0, 2, 2, 0,
+                       CopyFromParent, InputOutput, CopyFromParent,
+                       CWBackingStore | CWOverrideRedirect |
+                       CWBorderPixel | CWBackPixmap |
+                       CWSaveUnder | CWDontPropagate |
+                       CWEventMask | CWBitGravity |
+                       CWWinGravity, &attr);
+   if (!win)
+     {
+        ERR("Creating native X window failed.");
+        _evgl_error_set(EVAS_GL_BAD_DISPLAY);
+        return NULL;
      }
 
-   DBG("--------GLES 2.0 Extensions--------");
-   for (i = 0; _gl_ext_entries[i].name != NULL; i++)
-     {
-        if ( (strstr(glexts, _gl_ext_entries[i].name) != NULL) ||
-             (strstr(glexts, _gl_ext_entries[i].real_name) != NULL) )
-          {
-             _gl_ext_entries[i].supported = 1;
-             strcat(_gl_ext_string, _gl_ext_entries[i].name);
-             strcat(_gl_ext_string, " ");
-             DBG("\t%s", _gl_ext_entries[i].name);
-          }
+   return (void*)win;
+}
 
-     }
-   DBG(" ");
+static int
+evgl_eng_native_window_destroy(void *data, void *native_window)
+{
+   Render_Engine *re = (Render_Engine *)data;
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   // EGL Extensions
-   if (glsym_eglQueryString)
+   if (!re)
      {
-        evasglexts = glsym_eglQueryString(re->win->egl_disp, EGL_EXTENSIONS);
-#else
-   if (glsym_glXQueryExtensionsString)
+        ERR("Invalid Render Engine Data!");
+        _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+        return 0;
+     }
+
+   if (!native_window)
      {
-        evasglexts = glXQueryExtensionsString(re->info->info.display,
-                                              re->info->info.screen);
-#endif
-        ext_len = strlen(evasglexts);
+        ERR("Inavlid native surface.");
+        _evgl_error_set(EVAS_GL_BAD_NATIVE_WINDOW);
+        return 0;
+     }
 
-        if (!ext_len) 
-          {
-             DBG("GL Get Extension string NULL: No extensions supported");
-             return;
-          }
+   XDestroyWindow(re->info->info.display, (Window)native_window);
 
-        _evasgl_ext_string = calloc(1, sizeof(char) * ext_len * 2);
-        if (!_evasgl_ext_string)
-          {
-             ERR("Error allocating _evasgl_ext_string.");
-             return;
-          }
+   native_window = NULL;
 
-        DBG("--------EvasGL Supported Extensions----------");
-        for (i = 0; _evasgl_ext_entries[i].name != NULL; i++)
-          {
-             if ( (strstr(evasglexts, _evasgl_ext_entries[i].name) != NULL) ||
-                  (strstr(evasglexts, _evasgl_ext_entries[i].real_name) != NULL) )
-               {
-                  _evasgl_ext_entries[i].supported = 1;
-                  strcat(_evasgl_ext_string, _evasgl_ext_entries[i].name);
-                  strcat(_evasgl_ext_string, " ");
-                  DBG("\t%s", _evasgl_ext_entries[i].name);
-               }
-          }
-        DBG(" ");
-     }
+   return 1;
 }
 
-int _evas_engine_GL_X11_log_dom = -1;
-/* function tables - filled in later (func and parent func) */
-static Evas_Func func, pfunc;
-
-/* Function table for GL APIs */
-static Evas_GL_API gl_funcs;
-/*
-struct xrdb_user
-{
-   time_t last_stat;
-   time_t last_mtime;
-   XrmDatabase db;
-};
-static struct xrdb_user xrdb_user = {0, 0, NULL};
 
-static Eina_Bool
-xrdb_user_query(const char *name, const char *cls, char **type, XrmValue *val)
+// Theoretically, we wouldn't need this functoin if the surfaceless context
+// is supported. But, until then...
+static void *
+evgl_eng_window_surface_create(void *data, void *native_window)
 {
-   time_t last = xrdb_user.last_stat, now = time(NULL);
+   Render_Engine *re = (Render_Engine *)data;
 
-   xrdb_user.last_stat = now;
-   if (last != now) // don't stat() more than once every second
+   if (!re)
      {
-       struct stat st;
-       const char *home = getenv("HOME");
-       char tmp[PATH_MAX];
-
-       if (!home) goto failed;
-       snprintf(tmp, sizeof(tmp), "%s/.Xdefaults", home);
-       if (stat(tmp, &st) != 0) goto failed;
-       if (xrdb_user.last_mtime != st.st_mtime)
-         {
-            if (xrdb_user.db) XrmDestroyDatabase(xrdb_user.db);
-            xrdb_user.db = XrmGetFileDatabase(tmp);
-            if (!xrdb_user.db) goto failed;
-            xrdb_user.last_mtime = st.st_mtime;
-         }
+        ERR("Invalid Render Engine Data!");
+        _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+        return NULL;
      }
 
-   if (!xrdb_user.db) return EINA_FALSE;
-   return XrmGetResource(xrdb_user.db, name, cls, type, val);
+#ifdef GL_GLES
+   EGLSurface surface = EGL_NO_SURFACE;
 
- failed:
-   if (xrdb_user.db)
+   // Create resource surface for EGL
+   surface = eglCreateWindowSurface(re->win->egl_disp,
+                                    re->win->egl_config,
+                                    (EGLNativeWindowType)native_window,
+                                    NULL);
+   if (!surface)
      {
-       XrmDestroyDatabase(xrdb_user.db);
-       xrdb_user.db = NULL;
+        int err = eglGetError();
+        _evgl_error_set(err - EGL_SUCCESS);
+        ERR("Creating window surface failed. Error: %#x.", err);
+        return NULL;
      }
-   xrdb_user.last_mtime = 0;
-   return EINA_FALSE;
-}
-*/
 
-static void *
-eng_info(Evas *e)
-{
-   Evas_Engine_Info_GL_X11 *info;
+   return (void*)surface;
+#else
+   /*
+   // We don't need to create new one for GLX
+   Window surface;
+
+   surface = re->win->win;
+
+   return (void *)surface;
+   */
+   return (void*)native_window;
+#endif
 
-   info = calloc(1, sizeof(Evas_Engine_Info_GL_X11));
-   info->magic.magic = rand();
-   info->func.best_visual_get = eng_best_visual_get;
-   info->func.best_colormap_get = eng_best_colormap_get;
-   info->func.best_depth_get = eng_best_depth_get;
-   info->render_mode = EVAS_RENDER_MODE_BLOCKING;
-   return info;
-   e = NULL;
-}
-
-static void
-eng_info_free(Evas *e __UNUSED__, void *info)
-{
-   Evas_Engine_Info_GL_X11 *in;
-// dont free! why bother? its not worth it
-//   eina_log_domain_unregister(_evas_engine_GL_X11_log_dom);
-   in = (Evas_Engine_Info_GL_X11 *)info;
-   free(in);
 }
 
 static int
-_re_wincheck(Render_Engine *re)
+evgl_eng_window_surface_destroy(void *data, void *surface)
 {
-   if (re->win->surf) return 1;
-   eng_window_resurf(re->win);
-   if (!re->win->surf)
+   Render_Engine *re = (Render_Engine *)data;
+
+   if (!re)
      {
-        ERR("GL engine can't re-create window surface!");
+        ERR("Invalid Render Engine Data!");
+        _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+        return 0;
      }
-   return 0;
-}
 
-static void
-_re_winfree(Render_Engine *re)
-{
-   if (!re->win->surf) return;
-   eng_window_unsurf(re->win);
+#ifdef GL_GLES
+   if (!surface)
+     {
+        ERR("Invalid surface.");
+        _evgl_error_set(EVAS_GL_BAD_SURFACE);
+        return 0;
+     }
+
+   eglDestroySurface(re->win->egl_disp, (EGLSurface)surface);
+#endif
+
+   return 1;
 }
 
-static Render_Engine_GL_Resource *
-_create_internal_glue_resources(void *data)
+static void *
+evgl_eng_context_create(void *data, void *share_ctx,
+                        Evas_GL_Context_Version version)
 {
    Render_Engine *re = (Render_Engine *)data;
-   Render_Engine_GL_Resource *rsc;
-
-   rsc = calloc(1, sizeof(Render_Engine_GL_Resource));
 
-   if (!rsc) return NULL;
+   if (!re)
+     {
+        ERR("Invalid Render Engine Data!");
+        _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+        return NULL;
+     }
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   // EGL
+#ifdef GL_GLES
+   EGLContext context = EGL_NO_CONTEXT;
    int context_attrs[3];
+
    context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
-   context_attrs[1] = 2;
+   context_attrs[1] = (int) version;
    context_attrs[2] = EGL_NONE;
 
-   if (eina_main_loop_is())
+   // Share context already assumes that it's sharing with evas' context
+   if (share_ctx)
      {
-        rsc->surface = re->win->egl_surface[0];
+        context = eglCreateContext(re->win->egl_disp,
+                                   re->win->egl_config,
+                                   (EGLContext)share_ctx,
+                                   context_attrs);
      }
-   else
+   else if (version == EVAS_GL_GLES_1_X)
      {
-        // Create resource surface for EGL
-        rsc->surface = eglCreateWindowSurface(re->win->egl_disp,
-                                              re->win->egl_config,
-                                              (EGLNativeWindowType)DefaultRootWindow(re->info->info.display),
-                                              NULL);
-        if (!rsc->surface)
-          {
-             ERR("Creating internal resource surface failed.");
-             free(rsc);
-             return NULL;
-          }
+        // This context will be used for DR only
+        context = eglCreateContext(re->win->egl_disp,
+                                   re->win->egl_config,
+                                   NULL, // no sharing between GLES1 and GLES2
+                                   context_attrs);
      }
-
-   // Create a resource context for EGL
-   rsc->context = eglCreateContext(re->win->egl_disp,
+   else
+     {
+        context = eglCreateContext(re->win->egl_disp,
                                    re->win->egl_config,
                                    re->win->egl_context[0], // Evas' GL Context
                                    context_attrs);
-   if (!rsc->context)
-     {
-        ERR("Internal Resource Context Creations Failed.");
-        free(rsc);
-        return NULL;
      }
 
-   // Add to the resource resource list for cleanup
-   LKL(resource_lock);
-   resource_list = eina_list_prepend(resource_list, rsc);
-   LKU(resource_lock);
-
-   // Set the resource in TLS
-   if (eina_tls_set(resource_key, (void*)rsc) == EINA_FALSE)
+   if (!context)
      {
-        ERR("Failed setting TLS Resource");
-        free(rsc);
+        int err = eglGetError();
+        ERR("Engine Context Creations Failed. Error: %#x.", err);
+        _evgl_error_set(err - EGL_SUCCESS);
         return NULL;
      }
 
+   return (void*)context;
 #else
-   // GLX
-   rsc->context = glXCreateContext(re->info->info.display,
+   GLXContext context = NULL;
+   (void) version;
+
+   // Share context already assumes that it's sharing with evas' context
+   if (share_ctx)
+     {
+        context = glXCreateContext(re->info->info.display,
                                    re->win->visualinfo,
-                                   re->win->context,      // Evas' GL Context
+                                   (GLXContext)share_ctx,
                                    1);
-   if (!rsc->context)
+     }
+   else
      {
-        ERR("Internal Resource Context Creations Failed.");
-        free(rsc);
-        return NULL;
+        context = glXCreateContext(re->info->info.display,
+                                   re->win->visualinfo,
+                                   re->win->context,      // Evas' GL Context
+                                   1);
      }
 
-   // Add to the resource resource list for cleanup
-   LKL(resource_lock);
-   resource_list = eina_list_prepend(resource_list, rsc);
-   LKU(resource_lock);
-
-   // Set the resource in TLS
-   if (eina_tls_set(resource_key, (void*)rsc) == EINA_FALSE)
+   if (!context)
      {
-        ERR("Failed setting TLS Resource");
-        free(rsc);
+        ERR("Internal Resource Context Creations Failed.");
+        if(!(re->info->info.display)) _evgl_error_set(EVAS_GL_BAD_DISPLAY);
+        if(!(re->win)) _evgl_error_set(EVAS_GL_BAD_NATIVE_WINDOW);
         return NULL;
      }
 
+   return (void*)context;
 #endif
 
-
-   return rsc;
 }
 
 static int
-_destroy_internal_glue_resources(void *data)
+evgl_eng_context_destroy(void *data, void *context)
 {
    Render_Engine *re = (Render_Engine *)data;
-   Eina_List *l;
-   Render_Engine_GL_Resource *rsc;
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   // Create internal resource context if it hasn't been created already
-   if ((rsc = eina_tls_get(resource_key)) == NULL)
+   if ((!re) || (!context))
      {
-        ERR("Error retrieving the TLS resources.");
+        ERR("Invalid Render Input Data. Engine: %p, Context: %p", data, context);
+        if (!re) _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+        if (!context) _evgl_error_set(EVAS_GL_BAD_CONTEXT);
         return 0;
      }
 
-   if (eina_main_loop_is()) rsc->surface = re->win->egl_surface[0];
-
-   // EGL
-   // Delete the Resources
-   LKL(resource_lock);
-   EINA_LIST_FOREACH(resource_list, l, rsc)
-     {
-        if ((rsc->surface) && (rsc->surface != re->win->egl_surface[0]))
-           eglDestroySurface(re->win->egl_disp, rsc->surface);
-        if (rsc->context)
-           eglDestroyContext(re->win->egl_disp, rsc->context);
-        free(rsc);
-     }
+#ifdef GL_GLES
+   eglDestroyContext(re->win->egl_disp, (EGLContext)context);
 #else
-   // GLX
-   // Delete the Resources
-   LKL(resource_lock);
-   EINA_LIST_FOREACH(resource_list, l, rsc)
-     {
-        if (rsc)
-          {
-             glXDestroyContext(re->info->info.display, rsc->context);
-             free(rsc);
-          }
-     }
+   glXDestroyContext(re->info->info.display, (GLXContext)context);
 #endif
-   eina_list_free(resource_list);
-   resource_list = NULL;
-   LKU(resource_lock);
 
-   // Destroy TLS
-   eina_tls_free(resource_key);
+   return 1;
+}
 
-   // Free the extension strings
-   if (_ext_initted)
-     {
-        if (_gl_ext_string)
-           free(_gl_ext_string);
-        if (_evasgl_ext_string)
-           free(_evasgl_ext_string);
+static const char *
+evgl_eng_string_get(void *data)
+{
+   Render_Engine *re = (Render_Engine *)data;
 
-        _gl_ext_string = NULL;
-        _evasgl_ext_string = NULL;
-        _ext_initted = 0;
+   if (!re)
+     {
+        ERR("Invalid Render Engine Data!");
+        _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+        return NULL;
      }
 
-   return 1;
+#ifdef GL_GLES
+   // EGL Extensions
+   return eglQueryString(re->win->egl_disp, EGL_EXTENSIONS);
+#else
+   return glXQueryExtensionsString(re->info->info.display,
+                                   re->info->info.screen);
+#endif
 }
 
+static void *
+evgl_eng_proc_address_get(const char *name)
+{
+#ifdef GL_GLES
+   if (glsym_eglGetProcAddress) return glsym_eglGetProcAddress(name);
+   return dlsym(RTLD_DEFAULT, name);
+#else
+   if (glsym_glXGetProcAddress) return glsym_glXGetProcAddress(name);
+   return dlsym(RTLD_DEFAULT, name);
+#endif
+}
 
 static int
-_internal_resources_make_current(void *data)
+evgl_eng_rotation_angle_get(void *data)
 {
    Render_Engine *re = (Render_Engine *)data;
-   Render_Engine_GL_Resource *rsc;
-   int ret = 0;
 
-   // Create internal resource context if it hasn't been created already
-   if ((rsc = eina_tls_get(resource_key)) == NULL)
+   if (!re)
      {
-        if ((rsc = _create_internal_glue_resources(re)) == NULL)
-          {
-             ERR("Error creating internal resources.");
-             return 0;
-          }
+        ERR("Invalid Render Engine Data!");
+        _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+        return 0;
      }
 
-   // Use resource surface/context to create surface resrouces
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   // Update the evas' window surface
-   if (eina_main_loop_is()) rsc->surface = re->win->egl_surface[0];
-
-   ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, rsc->surface, rsc->context);
-
-   if (!ret)
+   if ((re->win) && (re->win->gl_context))
      {
-        ERR("eglMakeCurrent() failed. Error Code: %#x", eglGetError());
+        // TODO: Check that pre-rotation is not enabled (not implemented yet).
+        if (_evgl_direct_enabled())
+          return re->win->gl_context->rot;
         return 0;
      }
-#else
-   ret = glXMakeCurrent(re->info->info.display, re->win->win, rsc->context);
-   if (!ret)
+   else
      {
-        ERR("glXMakeCurrent()!");
+        ERR("Unable to retrieve rotation angle.");
+        _evgl_error_set(EVAS_GL_BAD_CONTEXT);
         return 0;
      }
-#endif
-   return 1;
 }
 
-static int
-eng_setup(Evas *e, void *in)
+static void *
+evgl_eng_native_buffer_image_create(void *data, int tex, int target, void *native)
 {
-   Render_Engine *re;
-   Evas_Engine_Info_GL_X11 *info;
+#ifdef GL_GLES
+   Render_Engine *re = (Render_Engine *)data;
+   EGLSurface surface = EGL_NO_SURFACE;
+   int native_target = 0;
+   int err;
 
-   info = (Evas_Engine_Info_GL_X11 *)in;
-   if (!e->engine.data.output)
+   if (!re)
      {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-#else
-        int eb, evb;
-
-        if (!glXQueryExtension(info->info.display, &eb, &evb)) return 0;
-#endif
-        re = calloc(1, sizeof(Render_Engine));
-        if (!re) return 0;
-        re->info = info;
-        re->evas = e;
-        e->engine.data.output = re;
-        re->w = e->output.w;
-        re->h = e->output.h;
-        re->win = eng_window_new(re->info->info.display,
-                                 re->info->info.drawable,
-                                 re->info->info.screen,
-                                 re->info->info.visual,
-                                 re->info->info.colormap,
-                                 re->info->info.depth,
-                                 re->w,
-                                 re->h,
-                                 re->info->indirect,
-                                 re->info->info.destination_alpha,
-                                 re->info->info.rotation);
-        if (!re->win)
-          {
-             free(re);
-             e->engine.data.output = NULL;
-             return 0;
-          }
+        ERR("Invalid Render Engine Data!");
+        _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+        return NULL;
+     }
 
-        gl_wins++;
-/*
-          {
-             int status;
-             char *type = NULL;
-             XrmValue val;
-
-             re->xr.dpi = 75000; // dpy * 1000
-
-             status = xrdb_user_query("Xft.dpi", "Xft.Dpi", &type, &val);
-             if ((!status) || (!type))
-              {
-                 if (!re->xrdb) re->xrdb = XrmGetDatabase(re->info->info.display);
-                 if (re->xrdb)
-                   status = XrmGetResource(re->xrdb,
-                                           "Xft.dpi", "Xft.Dpi", &type, &val);
-              }
-
-             if ((status) && (type))
-               {
-                  if (!strcmp(type, "String"))
-                    {
-                       const char *str, *dp;
+   if (target == 1)
+      native_target = (int)EGL_NATIVE_PIXMAP_KHR;
+   else
+     {
+        ERR("Invalid native target");
+        _evgl_error_set(EVAS_GL_BAD_MATCH);
+        goto error;
+     }
 
-                       str = val.addr;
-                       dp = strchr(str, '.');
-                       if (!dp) dp = strchr(str, ',');
+   glBindTexture(GL_TEXTURE_2D, tex);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
-                       if (dp)
-                         {
-                            int subdpi, len, i;
-                            char *buf;
-
-                            buf = alloca(dp - str + 1);
-                            strncpy(buf, str, dp - str);
-                            buf[dp - str] = 0;
-                            len = strlen(dp + 1);
-                            subdpi = atoi(dp + 1);
-
-                            if (len < 3)
-                              {
-                                 for (i = len; i < 3; i++) subdpi *= 10;
-                              }
-                            else if (len > 3)
-                              {
-                                 for (i = len; i > 3; i--) subdpi /= 10;
-                              }
-                            re->xr.dpi = atoi(buf) * 1000;
-                         }
-                       else
-                         re->xr.dpi = atoi(str) * 1000;
-                       evas_common_font_dpi_set(re->xr.dpi / 1000);
-                    }
-               }
-          }
- */
-        if (!initted)
+   if (glsym_eglCreateImage)
+     {
+        surface = glsym_eglCreateImage(re->win->egl_disp,
+                                       EGL_NO_CONTEXT,
+                                       (EGLenum)native_target,
+                                       native,
+                                       NULL);
+        if (!surface)
           {
-             evas_common_cpu_init();
-
-             evas_common_blend_init();
-             evas_common_image_init();
-             evas_common_convert_init();
-             evas_common_scale_init();
-             evas_common_rectangle_init();
-             evas_common_polygon_init();
-             evas_common_line_init();
-             evas_common_font_init();
-             evas_common_draw_init();
-             evas_common_tilebuf_init();
+             ERR("eglCreateImage() for %p failed", native);
 
-             // Initialize TLS
-             if (eina_tls_new(&resource_key) == EINA_FALSE)
-                ERR("Error creating tls key");
-             DBG("TLS KEY create... %d", resource_key);
+             if ((err = eglGetError()) != EGL_SUCCESS)
+               {
+                  ERR("eglCreateImage failed: %x.", err);
+                  _evgl_error_set(err - EGL_SUCCESS);
+               }
 
-             initted = 1;
+             goto error;
           }
      }
    else
+      ERR("Try eglCreateImage on EGL with no support");
+
+   if (glsym_glEGLImageTargetTexture2DOES)
      {
-        re = e->engine.data.output;
-        if (_re_wincheck(re))
+        glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, surface);
+        if ((err = glGetError()) != GL_NO_ERROR)
           {
-             if ((re->info->info.display != re->win->disp) ||
-                 (re->info->info.drawable != re->win->win) ||
-                 (re->info->info.screen != re->win->screen) ||
-                 (re->info->info.visual != re->win->visual) ||
-                 (re->info->info.colormap != re->win->colormap) ||
-                 (re->info->info.depth != re->win->depth) ||
-                 (re->info->info.destination_alpha != re->win->alpha) ||
-                 (re->info->info.rotation != re->win->rot))
-               {
-                  int inc = 0;
-
-                  if (re->win)
-                    {
-                       re->win->gl_context->references++;
-                       eng_window_free(re->win);
-                       inc = 1;
-                       gl_wins--;
-                    }
-                  re->w = e->output.w;
-                  re->h = e->output.h;
-                  re->win = eng_window_new(re->info->info.display,
-                                           re->info->info.drawable,
-                                           re->info->info.screen,
-                                           re->info->info.visual,
-                                           re->info->info.colormap,
-                                           re->info->info.depth,
-                                           re->w,
-                                           re->h,
-                                           re->info->indirect,
-                                           re->info->info.destination_alpha,
-                                           re->info->info.rotation);
-                  eng_window_use(re->win);
-                  if (re->win) gl_wins++;
-                  if ((re->win) && (inc))
-                     re->win->gl_context->references--;
-               }
-             else if ((re->win->w != e->output.w) ||
-                      (re->win->h != e->output.h))
-               {
-                  re->w = e->output.w;
-                  re->h = e->output.h;
-                  re->win->w = e->output.w;
-                  re->win->h = e->output.h;
-                  eng_window_use(re->win);
-                  evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot);
-               }
+             ERR("glEGLImageTargetTexture2DOES() failed.");
+             goto error;
           }
      }
-   if (!re->win)
+   else
      {
-        free(re);
-        return 0;
+        ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
+        goto error;
      }
 
-   if (!e->engine.data.output)
+   glBindTexture(GL_TEXTURE_2D, 0);
+
+   return (void *)surface;
+
+error:
+   if (surface)
+      if (glsym_eglDestroyImage)
+         glsym_eglDestroyImage(re->win->egl_disp, surface);
+#else
+   _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+#endif
+
+   return NULL;
+}
+
+static int
+evgl_eng_native_buffer_image_destroy(void *data, void *native_image)
+{
+   Render_Engine *re = (Render_Engine *)data;
+   int err;
+
+   if (!re)
      {
-        if (re->win)
-          {
-             eng_window_free(re->win);
-             gl_wins--;
-          }
-        free(re);
+        ERR("Invalid Render Engine Data!");
+        _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
         return 0;
      }
-   re->tb = evas_common_tilebuf_new(re->win->w, re->win->h);
-   if (!re->tb)
+
+#ifdef GL_GLES
+   if (glsym_eglDestroyImage)
      {
-        if (re->win)
+        glsym_eglDestroyImage(re->win->egl_disp, (EGLSurface)native_image);
+        if ((err = eglGetError()) != EGL_SUCCESS)
           {
-             eng_window_free(re->win);
-             gl_wins--;
+             ERR("eglDestroyImage() failed.");
+             _evgl_error_set(err - EGL_SUCCESS);
           }
-        free(re);
+        native_image = NULL;
+        return 1;
+     }
+   else
+#endif
+     {
+        ERR("Try eglDestroyImage on EGL with no support");
+        _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
         return 0;
      }
-   evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
-
-   if (!e->engine.data.context)
-     e->engine.data.context =
-     e->engine.func->context_new(e->engine.data.output);
-   eng_window_use(re->win);
+}
 
-   re->vsync = 0;
+static int
+evgl_eng_texture_destroyed_cb(void *data, GLuint texid)
+{
+   Render_Engine *re = (Render_Engine *)data;
+   void *im;
 
-   if (!_ext_initted)
+   if (!re)
      {
-        _gl_ext_sym_init();
-        _gl_ext_init(re);
-        _ext_initted = 1 ;
+        ERR("Invalid Render Engine Data!");
+        _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+        return 0;
      }
 
+   im = eina_hash_find(re->win->gl_context->shared->native_tex_hash, &texid);
+   if (!im) return 0;
+
+   eina_hash_del(re->win->gl_context->shared->native_tex_hash, &texid, im);
    return 1;
 }
 
-static void
-eng_output_free(void *data)
+static void *
+evgl_eng_pbuffer_surface_create(void *data, EVGL_Surface *sfc,
+                                const int *attrib_list)
 {
-   Render_Engine *re;
+   Render_Engine *re = (Render_Engine *)data;
 
-   re = (Render_Engine *)data;
+   // TODO: Add support for surfaceless pbuffers (EGL_NO_TEXTURE)
+   // TODO: Add support for EGL_MIPMAP_TEXTURE??? (GLX doesn't support them)
 
-   if (re)
-     {
-// NOTE: XrmGetDatabase() result is shared per connection, do not free it.
-//   if (re->xrdb) XrmDestroyDatabase(re->xrdb);
+#ifdef GL_GLES
+   int config_attrs[20];
+   int surface_attrs[20];
+   EGLSurface egl_sfc;
+   EGLConfig egl_cfg;
+   int num_config, i = 0;
 
-#if 0
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-        // Destroy the resource surface
-        // Only required for EGL case
-        if (re->surface)
-           eglDestroySurface(re->win->egl_disp, re->surface);
-#endif
+   if (attrib_list)
+     WRN("This PBuffer implementation does not support extra attributes yet");
 
-        // Destroy the resource context
-        _destroy_internal_context(re, context);
-#endif
-        if (re->win)
+#if 0
+   // Choose framebuffer configuration
+   // DISABLED FOR NOW
+   if (sfc->pbuffer.color_fmt != EVAS_GL_NO_FBO)
+     {
+        config_attrs[i++] = EGL_RED_SIZE;
+        config_attrs[i++] = 1;
+        config_attrs[i++] = EGL_GREEN_SIZE;
+        config_attrs[i++] = 1;
+        config_attrs[i++] = EGL_BLUE_SIZE;
+        config_attrs[i++] = 1;
+
+        if (sfc->pbuffer.color_fmt == EVAS_GL_RGBA_8888)
           {
-             if ((initted == 1) && (gl_wins == 1))
-                  _destroy_internal_glue_resources(re);
-             eng_window_free(re->win);
-             gl_wins--;
+             config_attrs[i++] = EGL_ALPHA_SIZE;
+             config_attrs[i++] = 1;
+             //config_attrs[i++] = EGL_BIND_TO_TEXTURE_RGBA;
+             //config_attrs[i++] = EGL_TRUE;
+          }
+        else
+          {
+             //config_attrs[i++] = EGL_BIND_TO_TEXTURE_RGB;
+             //config_attrs[i++] = EGL_TRUE;
           }
-        evas_common_tilebuf_free(re->tb);
-        free(re);
      }
-   if ((initted == 1) && (gl_wins == 0))
+
+   if (sfc->depth_fmt || sfc->depth_stencil_fmt)
      {
-        evas_common_image_shutdown();
-        evas_common_font_shutdown();
-        initted = 0;
+        config_attrs[i++] = EGL_DEPTH_SIZE;
+        config_attrs[i++] = 1;
      }
-}
 
-static void
-eng_output_resize(void *data, int w, int h)
-{
-   Render_Engine *re;
+   if (sfc->stencil_fmt || sfc->depth_stencil_fmt)
+     {
+        config_attrs[i++] = EGL_STENCIL_SIZE;
+        config_attrs[i++] = 1;
+     }
 
-   re = (Render_Engine *)data;
-   re->win->w = w;
-   re->win->h = h;
-   eng_window_use(re->win);
-   evas_gl_common_context_resize(re->win->gl_context, w, h, re->win->rot);
-   evas_common_tilebuf_free(re->tb);
-   re->tb = evas_common_tilebuf_new(w, h);
-   if (re->tb)
-     evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
-}
+   config_attrs[i++] = EGL_RENDERABLE_TYPE;
+   config_attrs[i++] = EGL_OPENGL_ES2_BIT;
+   config_attrs[i++] = EGL_SURFACE_TYPE;
+   config_attrs[i++] = EGL_PBUFFER_BIT;
+   config_attrs[i++] = EGL_NONE;
+#else
+   // It looks like eglMakeCurrent might fail if we use a different config from
+   // the actual display surface. This is weird.
+   i = 0;
+   config_attrs[i++] = EGL_CONFIG_ID;
+   config_attrs[i++] = 0;
+   config_attrs[i++] = EGL_NONE;
+   eglQueryContext(re->win->egl_disp, re->win->egl_context[0], EGL_CONFIG_ID, &config_attrs[1]);
+#endif
 
-static void
-eng_output_tile_size_set(void *data, int w, int h)
-{
-   Render_Engine *re;
+   if (!eglChooseConfig(re->win->egl_disp, config_attrs, &egl_cfg, 1, &num_config)
+       || (num_config < 1))
+     {
+        int err = eglGetError();
+        _evgl_error_set(err - EGL_SUCCESS);
+        ERR("eglChooseConfig failed with error %x", err);
+        return NULL;
+     }
 
-   re = (Render_Engine *)data;
-   evas_common_tilebuf_set_tile_size(re->tb, w, h);
+   // Now, choose the config for the PBuffer
+   i = 0;
+   surface_attrs[i++] = EGL_WIDTH;
+   surface_attrs[i++] = sfc->w;
+   surface_attrs[i++] = EGL_HEIGHT;
+   surface_attrs[i++] = sfc->h;
+#if 0
+   // Adding these parameters will trigger EGL_BAD_ATTRIBUTE because
+   // the config also requires EGL_BIND_TO_TEXTURE_RGB[A]. But some drivers
+   // don't support those configs (eg. nvidia)
+   surface_attrs[i++] = EGL_TEXTURE_FORMAT;
+   if (sfc->pbuffer.color_fmt == EVAS_GL_RGB_888)
+     surface_attrs[i++] = EGL_TEXTURE_RGB;
+   else
+     surface_attrs[i++] = EGL_TEXTURE_RGBA;
+   surface_attrs[i++] = EGL_TEXTURE_TARGET;
+   surface_attrs[i++] = EGL_TEXTURE_2D;
+   surface_attrs[i++] = EGL_MIPMAP_TEXTURE;
+   surface_attrs[i++] = EINA_TRUE;
+#endif
+   surface_attrs[i++] = EGL_NONE;
+
+   egl_sfc = eglCreatePbufferSurface(re->win->egl_disp, egl_cfg, surface_attrs);
+   if (!egl_sfc)
+     {
+        int err = eglGetError();
+        _evgl_error_set(err - EGL_SUCCESS);
+        ERR("eglCreatePbufferSurface failed with error %x", err);
+        return NULL;
+     }
+
+   return egl_sfc;
+#else
+   //FIXME: PBuffer support is not implemented yet!
+#endif
 }
 
-static void
-eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
+// This function should create a surface that can be used for offscreen rendering
+// with GLES 1.x, and still be bindable to a texture in Evas main GL context.
+// For now, this will create an X pixmap... Ideally it should be able to create
+// a bindable pbuffer surface or just an FBO if that is supported and it can
+// be shared with Evas.
+static void *
+evgl_eng_gles1_surface_create(void *data, EVGL_Surface *evgl_sfc,
+                              Evas_GL_Config *cfg, int w, int h)
 {
-   Render_Engine *re;
+   Render_Engine *re = (Render_Engine *)data;
+   Eina_Bool alpha = EINA_FALSE;
+   int colordepth;
+   Pixmap px;
 
-   re = (Render_Engine *)data;
-   eng_window_use(re->win);
-   evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot);
-   evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
+   if (!re || !evgl_sfc || !cfg)
+     {
+        _evgl_error_set(EVAS_GL_BAD_PARAMETER);
+        return NULL;
+     }
 
-   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, re->win->w, re->win->h);
-   if ((w <= 0) || (h <= 0)) return;
-   if (!re->win->draw.redraw)
+   if ((w < 1) || (h < 1))
      {
-#if 1
-       re->win->draw.x1 = x;
-       re->win->draw.y1 = y;
-       re->win->draw.x2 = x + w - 1;
-       re->win->draw.y2 = y + h - 1;
-#else
-       re->win->draw.x1 = 0;
-       re->win->draw.y1 = 0;
-       re->win->draw.x2 = re->win->w - 1;
-       re->win->draw.y2 = re->win->h - 1;
-#endif
+        ERR("Inconsistent parameters, not creating any surface!");
+        _evgl_error_set(EVAS_GL_BAD_PARAMETER);
+        return NULL;
      }
+
+   /* Choose appropriate pixmap depth */
+   if (cfg->color_format == EVAS_GL_RGBA_8888)
+     {
+        alpha = EINA_TRUE;
+        colordepth = 32;
+     }
+   else if (cfg->color_format == EVAS_GL_RGB_888)
+     colordepth = 24;
+   else // this could also be XDefaultDepth but this case shouldn't happen
+     colordepth = 24;
+
+   px = XCreatePixmap(re->win->disp, re->win->win, w, h, colordepth);
+   if (!px)
+     {
+        ERR("Failed to create XPixmap!");
+        _evgl_error_set(EVAS_GL_BAD_ALLOC);
+        return NULL;
+     }
+
+#ifdef GL_GLES
+   EGLSurface egl_sfc;
+   EGLConfig egl_cfg;
+   int i, num = 0, best = 0;
+   EGLConfig configs[200];
+   int config_attrs[40];
+   Eina_Bool found = EINA_FALSE;
+   int msaa = 0, depth = 0, stencil = 0;
+   Visual *visual = NULL;
+   int val;
+
+   /* Now we need to iterate over all EGL configurations to check the compatible
+    * ones and finally check their visual ID. */
+
+   if ((cfg->depth_bits > EVAS_GL_DEPTH_NONE) &&
+       (cfg->depth_bits <= EVAS_GL_DEPTH_BIT_32))
+     depth = 8 * ((int) cfg->depth_bits);
+
+   if ((cfg->stencil_bits > EVAS_GL_STENCIL_NONE) &&
+       (cfg->stencil_bits <= EVAS_GL_STENCIL_BIT_16))
+     stencil = 1 << ((int) cfg->stencil_bits - 1);
+
+   if ((cfg->multisample_bits > EVAS_GL_MULTISAMPLE_NONE) &&
+       (cfg->multisample_bits <= EVAS_GL_MULTISAMPLE_HIGH))
+     msaa = evgl_engine->caps.msaa_samples[(int) cfg->multisample_bits - 1];
+
+   // The below code is similar to eng_best_visual_get() from EFL 1.12
+   i = 0;
+   config_attrs[i++] = EGL_SURFACE_TYPE;
+   config_attrs[i++] = EGL_PIXMAP_BIT;
+   config_attrs[i++] = EGL_RENDERABLE_TYPE;
+   if (cfg->gles_version == EVAS_GL_GLES_2_X)
+     config_attrs[i++] = EGL_OPENGL_ES2_BIT;
    else
+     config_attrs[i++] = EGL_OPENGL_ES_BIT;
+   if (alpha)
      {
-       if (x < re->win->draw.x1) re->win->draw.x1 = x;
-       if (y < re->win->draw.y1) re->win->draw.y1 = y;
-       if ((x + w - 1) > re->win->draw.x2) re->win->draw.x2 = x + w - 1;
-       if ((y + h - 1) > re->win->draw.y2) re->win->draw.y2 = y + h - 1;
+        config_attrs[i++] = EGL_ALPHA_SIZE;
+        config_attrs[i++] = 1; // should it be 8?
+        if (evgl_engine->api_debug_mode)
+          DBG("Requesting RGBA pixmap");
+     }
+   else
+     {
+        config_attrs[i++] = EGL_ALPHA_SIZE;
+        config_attrs[i++] = 0;
+     }
+   if (depth)
+     {
+        config_attrs[i++] = EGL_DEPTH_SIZE;
+        config_attrs[i++] = depth;
+        if (evgl_engine->api_debug_mode)
+          DBG("Requesting depth buffer size %d", depth);
+     }
+   if (stencil)
+     {
+        config_attrs[i++] = EGL_STENCIL_SIZE;
+        config_attrs[i++] = stencil;
+        if (evgl_engine->api_debug_mode)
+          DBG("Requesting stencil buffer size %d", stencil);
+     }
+   if (msaa)
+     {
+        config_attrs[i++] = EGL_SAMPLE_BUFFERS;
+        config_attrs[i++] = 1;
+        config_attrs[i++] = EGL_SAMPLES;
+        config_attrs[i++] = msaa;
+        if (evgl_engine->api_debug_mode)
+          DBG("Requesting MSAA buffer with %d samples", msaa);
+     }
+   config_attrs[i++] = EGL_NONE;
+   config_attrs[i++] = 0;
+
+   /* Note: We found some horrible problems on both Mali and Adreno drivers
+    * apparently related to the use of MSAA and RGBA. Therefore the following
+    * warning.
+    * What happened (wild guess here) is that while a pixmap with RGBA+MSAA
+    * should be sampled using MSAA, blending was not possible because MSAA
+    * would maybe use the alpha bits as a meta data bit field. So, it appears
+    * that MSAA and RGBA may be incompatible.
+    */
+   if (alpha && msaa)
+     WRN("Requested RGBA and MSAA(%d) for a Pixmap buffer.\nThis configuration "
+         "has been proven on various drivers to cause rendering artifacts when "
+         "sampling the Pixmap to draw it on the canvas.\nIf you really want "
+         "to proceed with this, you will need to disable blending.\nAt the "
+         "Evas level, this means disabling alpha on the object, or setting "
+         "the render_op to COPY.", msaa);
+
+   if (!eglChooseConfig(re->win->egl_disp, config_attrs, configs, 200, &num) || !num)
+     {
+        int err = eglGetError();
+        ERR("eglChooseConfig() can't find any configs, error: %x", err);
+        _evgl_error_set(err - EGL_SUCCESS);
+        XFreePixmap(re->win->disp, px);
+        return NULL;
      }
-   re->win->draw.redraw = 1;
-}
 
-static void
-eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
-{
-   Render_Engine *re;
+   if (evgl_engine->api_debug_mode)
+     DBG("Found %d potential configurations", num);
 
-   re = (Render_Engine *)data;
-   evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
-}
+   for (i = 0; (i < num) && !found; i++)
+     {
+        EGLint val = 0;
+        VisualID visid = 0;
+        XVisualInfo *xvi, vi_in;
+        XRenderPictFormat *fmt;
+        int nvi = 0, j;
 
-static void
-eng_output_redraws_clear(void *data)
-{
-   Render_Engine *re;
+        if (!eglGetConfigAttrib(re->win->egl_disp, configs[i],
+                                EGL_NATIVE_VISUAL_ID, &val))
+          continue;
 
-   re = (Render_Engine *)data;
-   evas_common_tilebuf_clear(re->tb);
-/*   re->win->draw.redraw = 0;*/
-//   INF("GL: finish update cycle!");
-}
+        // Find matching visuals. Only alpha & depth are really valid here.
+        visid = val;
+        vi_in.screen = re->win->screen;
+        vi_in.visualid = visid;
+        xvi = XGetVisualInfo(re->win->disp,
+                             VisualScreenMask | VisualIDMask,
+                             &vi_in, &nvi);
+        if (xvi)
+          {
+             for (j = 0; (j < nvi) && !found; j++)
+               {
+                  if (xvi[j].depth >= colordepth)
+                    {
+                       if (!best) best = i;
+                       if (alpha)
+                         {
+                            fmt = XRenderFindVisualFormat(re->win->disp, xvi[j].visual);
+                            if (fmt && (fmt->direct.alphaMask))
+                              found = EINA_TRUE;
+                         }
+                       else found = EINA_TRUE;
+                    }
+               }
+             if (found)
+               {
+                  egl_cfg = configs[i];
+                  visual = xvi[j].visual;
+                  if (evgl_engine->api_debug_mode)
+                    DBG("Found matching visual ID %d (cfg %d)", (int) visid, i);
 
-/* vsync games - not for now though */
-#define VSYNC_TO_SCREEN 1
+                  XFree(xvi);
+                  break;
+               }
+             XFree(xvi);
+          }
+     }
 
-static void *
-eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
-{
-   Render_Engine *re;
-   Tilebuf_Rect *rects;
+   if (!found)
+     {
+        // This config will probably not work, but we try anyways.
+        ERR("XGetVisualInfo failed. Trying with the EGL config #%d.", best);
+        if (num)
+          egl_cfg = configs[best];
+        else
+          egl_cfg = re->win->egl_config;
+     }
 
-   re = (Render_Engine *)data;
-   /* get the upate rect surface - return engine data as dummy */
-   rects = evas_common_tilebuf_get_render_rects(re->tb);
-   if (rects)
+   egl_sfc = eglCreatePixmapSurface(re->win->egl_disp, egl_cfg, px, NULL);
+   if (!egl_sfc)
      {
-/*
-        Tilebuf_Rect *r;
+        int err = eglGetError();
+        ERR("eglCreatePixmapSurface failed with error: %x", err);
+        _evgl_error_set(err - EGL_SUCCESS);
+        XFreePixmap(re->win->disp, px);
+        return NULL;
+     }
+
+   if (extn_have_y_inverted &&
+       eglGetConfigAttrib(re->win->egl_disp, egl_cfg,
+                          EGL_Y_INVERTED_NOK, &val))
+     evgl_sfc->yinvert = val;
+   else
+     evgl_sfc->yinvert = 1;
+
+   evgl_sfc->gles1_indirect = EINA_TRUE;
+   evgl_sfc->xpixmap = EINA_TRUE;
+   evgl_sfc->gles1_sfc = egl_sfc;
+   evgl_sfc->gles1_sfc_native = (void *)(intptr_t) px;
+   evgl_sfc->gles1_sfc_visual = visual;
+   evgl_sfc->gles1_sfc_config = egl_cfg;
+   DBG("Successfully created GLES1 surface: Pixmap %p EGLSurface %p", px, egl_sfc);
+   return evgl_sfc;
 
-        printf("REAAAAACCTS\n");
-        EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r)
-          {
-             printf("  %i %i %ix%i\n", r->x, r->y, r->w, r->h);
-          }
- */
-        evas_common_tilebuf_free_render_rects(rects);
-        evas_common_tilebuf_clear(re->tb);
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-        // dont need to for egl - eng_window_use() can check for other ctxt's
 #else
-        eng_window_use(NULL);
-#endif
-        eng_window_use(re->win);
-        if (!_re_wincheck(re)) return NULL;
-        evas_gl_common_context_flush(re->win->gl_context);
-        evas_gl_common_context_newframe(re->win->gl_context);
-        if (x) *x = 0;
-        if (y) *y = 0;
-        if (w) *w = re->win->w;
-        if (h) *h = re->win->h;
-        if (cx) *cx = 0;
-        if (cy) *cy = 0;
-        if (cw) *cw = re->win->w;
-        if (ch) *ch = re->win->h;
-        return re->win->gl_context->def_surface;
-     }
+#warning GLX support is not implemented for GLES 1.x
+   CRIT("Not implemented yet! (GLX for GLES 1)");
    return NULL;
-/*
-   if (!re->win->draw.redraw) return NULL;
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   // dont need to for egl - eng_window_use() can check for other ctxt's
-#else
-   eng_window_use(NULL);
 #endif
-   eng_window_use(re->win);
-   if (!_re_wincheck(re)) return NULL;
-   evas_gl_common_context_flush(re->win->gl_context);
-   evas_gl_common_context_newframe(re->win->gl_context);
-   if (x) *x = re->win->draw.x1;
-   if (y) *y = re->win->draw.y1;
-   if (w) *w = re->win->draw.x2 - re->win->draw.x1 + 1;
-   if (h) *h = re->win->draw.y2 - re->win->draw.y1 + 1;
-   if (cx) *cx = re->win->draw.x1;
-   if (cy) *cy = re->win->draw.y1;
-   if (cw) *cw = re->win->draw.x2 - re->win->draw.x1 + 1;
-   if (ch) *ch = re->win->draw.y2 - re->win->draw.y1 + 1;
-   return re->win->gl_context->def_surface;
- */
 }
 
-//#define FRAMECOUNT 1
-
-#ifdef FRAMECOUNT
-static double
-get_time(void)
+// This function should destroy the surface used for offscreen rendering
+// with GLES 1.x.This will also destroy the X pixmap...
+static int
+evgl_eng_gles1_surface_destroy(void *data, EVGL_Surface *evgl_sfc)
 {
-   struct timeval timev;
+   Render_Engine *re = (Render_Engine *)data;
 
-   gettimeofday(&timev, NULL);
-   return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
-}
-#endif
+   if (!re)
+     {
+        ERR("Invalid Render Engine Data!");
+        _evgl_error_set(EVAS_GL_NOT_INITIALIZED);
+        return 0;
+     }
 
-static int safe_native = -1;
+#ifdef GL_GLES
+   if ((!evgl_sfc) || (!evgl_sfc->gles1_sfc))
+     {
+        ERR("Invalid surface.");
+        _evgl_error_set(EVAS_GL_BAD_SURFACE);
+        return 0;
+     }
 
-static void
-eng_output_redraws_next_update_push(void *data, void *surface __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
-{
-   Render_Engine *re;
-#ifdef FRAMECOUNT
-   static double pt = 0.0;
-   double ta, tb;
+   eglDestroySurface(re->win->egl_disp, (EGLSurface)evgl_sfc->gles1_sfc);
+
+#else
+#warning GLX support is not implemented for GLES 1.x
+   CRIT("Not implemented yet! (GLX for GLES 1)");
+   return 0;
 #endif
 
-   re = (Render_Engine *)data;
-   /* put back update surface.. in this case just unflag redraw */
-   if (!_re_wincheck(re)) return;
-   re->win->draw.redraw = 0;
-   re->win->draw.drew = 1;
-   evas_gl_common_context_flush(re->win->gl_context);
-   if (safe_native == -1)
+   if (!evgl_sfc->gles1_sfc_native)
      {
-        const char *s = getenv("EVAS_GL_SAFE_NATIVE");
-        safe_native = 0;
-        if (s) safe_native = atoi(s);
-        else
-          {
-             s = (const char *)glGetString(GL_RENDERER);
-             if (s)
-               {
-                  if (strstr(s, "PowerVR SGX 540") ||
-                      strstr(s, "Mali-400 MP"))
-                    safe_native = 1;
-               }
-          }
+        ERR("Inconsistent parameters, not freeing XPixmap for gles1 surface!");
+        _evgl_error_set(EVAS_GL_BAD_PARAMETER);
+        return 0;
      }
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   // this is needed to make sure all previous rendering is flushed to
-   // buffers/surfaces
-#ifdef FRAMECOUNT
-   double t0 = get_time();
-   ta = t0 - pt;
-   pt = t0;
-#endif
-   // previous rendering should be done and swapped
-   if (!safe_native) eglWaitNative(EGL_CORE_NATIVE_ENGINE);
-#ifdef FRAMECOUNT
-   double t1 = get_time();
-   tb = t1 - t0;
-   printf("... %1.5f -> %1.5f | ", ta, tb);
-#endif
-//   if (eglGetError() != EGL_SUCCESS)
-//     {
-//        printf("Error:  eglWaitNative(EGL_CORE_NATIVE_ENGINE) fail.\n");
-//     }
-#else
-   // previous rendering should be done and swapped
-   if (!safe_native) glXWaitX();
-#endif
-//x//   printf("frame -> push\n");
+
+   XFreePixmap(re->win->disp, (Pixmap)evgl_sfc->gles1_sfc_native);
+
+   return 1;
 }
 
-static void
-eng_output_flush(void *data)
+static void *
+evgl_eng_gles1_context_create(void *data,
+                              EVGL_Context *share_ctx, EVGL_Surface *sfc)
 {
-   Render_Engine *re;
+   Render_Engine *re = data;
+   if (!re) return NULL;
 
-   re = (Render_Engine *)data;
-   if (!_re_wincheck(re)) return;
-   if (!re->win->draw.drew) return;
-//x//   printf("frame -> flush\n");
-   re->win->draw.drew = 0;
-   eng_window_use(re->win);
+#ifdef GL_GLES
+   EGLContext context = EGL_NO_CONTEXT;
+   int context_attrs[3];
+   EGLConfig config;
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-#ifdef FRAMECOUNT
-   double t0 = get_time();
-#endif
-   if (!re->vsync)
-     {
-        if (re->info->vsync) eglSwapInterval(re->win->egl_disp, 1);
-        else eglSwapInterval(re->win->egl_disp, 0);
-        re->vsync = 1;
-     }
-   if (re->info->callback.pre_swap)
+   context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
+   context_attrs[1] = share_ctx->version;
+   context_attrs[2] = EGL_NONE;
+
+   if (!sfc || !sfc->gles1_sfc_config)
      {
-        re->info->callback.pre_swap(re->info->callback.data, re->evas);
+        ERR("Surface is not set! Creating context anyways but eglMakeCurrent "
+            "might very well fail with EGL_BAD_MATCH (0x3009)");
+        config = re->win->egl_config;
      }
-   eglSwapBuffers(re->win->egl_disp, re->win->egl_surface[0]);
-   if (!safe_native) eglWaitGL();
-   if (re->info->callback.post_swap)
+   else config = sfc->gles1_sfc_config;
+
+   context = eglCreateContext(re->win->egl_disp, config,
+                              share_ctx->context,
+                              context_attrs);
+   if (!context)
      {
-        re->info->callback.post_swap(re->info->callback.data, re->evas);
+        int err = eglGetError();
+        ERR("eglCreateContext failed with error 0x%x", err);
+        _evgl_error_set(err - EGL_SUCCESS);
+        return NULL;
      }
-#ifdef FRAMECOUNT
-   double t1 = get_time();
-   printf("%1.5f\n", t1 - t0);
-#endif
-//   if (eglGetError() != EGL_SUCCESS)
-//     {
-//        printf("Error:  eglSwapBuffers() fail.\n");
-//     }
+
+   DBG("Successfully created context for GLES1 indirect rendering.");
+   return context;
 #else
-#ifdef VSYNC_TO_SCREEN
-   if ((re->info->vsync)/* || (1)*/)
+   CRIT("Support for GLES1 indirect rendering contexts is not implemented for GLX");
+   return NULL;
+#endif
+}
+
+static int
+evgl_eng_native_win_surface_config_check(void *data,
+                              int evgl_depth, int evgl_stencil, int evgl_msaa)
+{
+   Render_Engine *re = data;
+   if (!re) return NULL;
+
+   if ((re->win->detected.depth_buffer_size >= evgl_depth)
+       && (re->win->detected.stencil_buffer_size >= evgl_stencil)
+       && (re->win->detected.msaa >= evgl_msaa))
      {
-        if (glsym_glXSwapIntervalEXT)
-          {
-             if (!re->vsync)
-               {
-                  if (re->info->vsync) glsym_glXSwapIntervalEXT(re->win->disp, re->win->win, 1);
-                  else glsym_glXSwapIntervalEXT(re->win->disp, re->win->win, 0);
-                  re->vsync = 1;
-               }
+        DBG("Win cfg can support the Req Evas GL's config successfully");
+        return 1;
+     }
+   DBG("Win cfg can'n  support.win depth %d, stencil %d, msaa %d",
+                   re->win->detected.depth_buffer_size, re->win->detected.stencil_buffer_size,re->win->detected.msaa);
+   return 0;
+}
+
+static EVGL_Interface evgl_funcs =
+{
+   evgl_eng_display_get,
+   evgl_eng_evas_surface_get,
+   evgl_eng_native_window_create,
+   evgl_eng_native_window_destroy,
+   evgl_eng_window_surface_create,
+   evgl_eng_window_surface_destroy,
+   evgl_eng_context_create,
+   evgl_eng_context_destroy,
+   evgl_eng_make_current,
+   evgl_eng_proc_address_get,
+   evgl_eng_string_get,
+   evgl_eng_rotation_angle_get,
+   evgl_eng_native_buffer_image_create,
+   evgl_eng_native_buffer_image_destroy,
+   evgl_eng_texture_destroyed_cb,
+   evgl_eng_pbuffer_surface_create,
+   evgl_eng_gles1_surface_create,
+   evgl_eng_gles1_surface_destroy,
+   evgl_eng_gles1_context_create,
+   evgl_eng_native_win_surface_config_check,
+};
+
+//----------------------------------------------------------//
+
+
+static void
+gl_symbols(void)
+{
+   static int done = 0;
+
+   if (done) return;
+
+#define FINDSYM(dst, sym, typ) \
+      if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym);
+
+   FINDSYM(glsym_evgl_native_surface_buffer_get, "evgl_native_surface_buffer_get", glsym_func_void_ptr);
+   FINDSYM(glsym_evgl_native_surface_yinvert_get, "evgl_native_surface_yinvert_get", glsym_func_int);
+#undef FINDSYM
+
+#ifdef GL_GLES
+#define FINDSYM(dst, sym, typ) \
+   if (glsym_eglGetProcAddress) { \
+      if (!dst) dst = (typ)glsym_eglGetProcAddress(sym); \
+   } else { \
+      if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym); \
+   }
+
+   FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressKHR", glsym_func_eng_fn);
+   FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressEXT", glsym_func_eng_fn);
+   FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressARB", glsym_func_eng_fn);
+   FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddress", glsym_func_eng_fn);
+
+   FINDSYM(glsym_eglCreateImage, "eglCreateImageKHR", glsym_func_void_ptr);
+   FINDSYM(glsym_eglCreateImage, "eglCreateImageEXT", glsym_func_void_ptr);
+   FINDSYM(glsym_eglCreateImage, "eglCreateImageARB", glsym_func_void_ptr);
+   FINDSYM(glsym_eglCreateImage, "eglCreateImage", glsym_func_void_ptr);
+
+   FINDSYM(glsym_eglDestroyImage, "eglDestroyImageKHR", glsym_func_void);
+   FINDSYM(glsym_eglDestroyImage, "eglDestroyImageEXT", glsym_func_void);
+   FINDSYM(glsym_eglDestroyImage, "eglDestroyImageARB", glsym_func_void);
+   FINDSYM(glsym_eglDestroyImage, "eglDestroyImage", glsym_func_void);
+
+   FINDSYM(glsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", glsym_func_void);
+
+   FINDSYM(glsym_eglMapImageSEC, "eglMapImageSEC", glsym_func_void_ptr);
+   FINDSYM(glsym_eglUnmapImageSEC, "eglUnmapImageSEC", glsym_func_uint);
+
+   FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageEXT", glsym_func_void);
+   FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageINTEL", glsym_func_void);
+   FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamage", glsym_func_void);
+
+
+#else
+#define FINDSYM(dst, sym, typ) \
+   if (glsym_glXGetProcAddress) { \
+      if (!dst) dst = (typ)glsym_glXGetProcAddress(sym); \
+   } else { \
+      if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym); \
+   }
+
+   FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddressEXT", glsym_func_eng_fn);
+   FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddressARB", glsym_func_eng_fn);
+   FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddress", glsym_func_eng_fn);
+
+   FINDSYM(glsym_glXBindTexImage, "glXBindTexImageEXT", glsym_func_void);
+   FINDSYM(glsym_glXBindTexImage, "glXBindTexImageARB", glsym_func_void);
+   FINDSYM(glsym_glXBindTexImage, "glXBindTexImage", glsym_func_void);
+
+   FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageEXT", glsym_func_void);
+   FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageARB", glsym_func_void);
+   FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImage", glsym_func_void);
+
+   FINDSYM(glsym_glXGetVideoSync, "glXGetVideoSyncSGI", glsym_func_int);
+
+   FINDSYM(glsym_glXWaitVideoSync, "glXWaitVideoSyncSGI", glsym_func_int);
+
+   FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmapEXT", glsym_func_xid);
+   FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmapARB", glsym_func_xid);
+   FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmap", glsym_func_xid);
+
+   FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmapEXT", glsym_func_void);
+   FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmapARB", glsym_func_void);
+   FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmap", glsym_func_void);
+
+   FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawableEXT", glsym_func_void);
+   FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawableARB", glsym_func_void);
+   FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawable", glsym_func_void);
+
+   FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalMESA", glsym_func_int);
+   FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalSGI", glsym_func_int);
+
+   FINDSYM(glsym_glXSwapIntervalEXT, "glXSwapIntervalEXT", glsym_func_void);
+
+   FINDSYM(glsym_glXReleaseBuffersMESA, "glXReleaseBuffersMESA", glsym_func_void);
+
+   FINDSYM(glsym_glXQueryExtensionsString, "glXQueryExtensionsString", glsym_func_const_char_ptr);
+
+#endif
+
+   done = 1;
+}
+
+static void
+gl_extn_veto(Render_Engine *re)
+{
+   const char *str = NULL;
+#ifdef GL_GLES
+   str = eglQueryString(re->win->egl_disp, EGL_EXTENSIONS);
+   if (str)
+     {
+        const GLubyte *vendor = glGetString(GL_VENDOR);
+
+        if (getenv("EVAS_GL_INFO"))
+          printf("EGL EXTN:\n%s\n", str);
+
+        // Disable Partial Rendering
+        if (getenv("EVAS_GL_PARTIAL_DISABLE"))
+          {
+             extn_have_buffer_age = 0;
+             glsym_eglSwapBuffersWithDamage = NULL;
           }
-        if (glsym_glXSwapIntervalSGI)
+        // Special case for Qualcomm chipset as they don't expose the
+        // extension feature through eglQueryString. Don't ask me why
+        // they don't do it.
+        else if (!vendor || !strstr(vendor, "Qualcomm"))
           {
-             if (!re->vsync)
+             if (!strstr(str, "EGL_EXT_buffer_age"))
                {
-                  if (re->info->vsync) glsym_glXSwapIntervalSGI(1);
-                  else glsym_glXSwapIntervalSGI(0);
-                  re->vsync = 1;
+                  extn_have_buffer_age = 0;
+               }
+             if (!strstr(str, "swap_buffers_with_damage"))
+               {
+                  glsym_eglSwapBuffersWithDamage = NULL;
                }
           }
+        if (!strstr(str, "EGL_NOK_texture_from_pixmap"))
+          {
+             extn_have_y_inverted = 0;
+          }
         else
           {
-             if ((glsym_glXGetVideoSync) && (glsym_glXWaitVideoSync))
-               {
-                  unsigned int rc;
-
-                  glsym_glXGetVideoSync(&rc);
-                  glsym_glXWaitVideoSync(1, 0, &rc);
-               }
+             const GLubyte *renderer;
+
+             renderer = glGetString(GL_RENDERER);
+             // XXX: workaround mesa bug!
+             // looking for mesa and intel build which is known to
+             // advertise the EGL_NOK_texture_from_pixmap extension
+             // but not set it correctly. guessing vendor/renderer
+             // strings will be like the following:
+             // OpenGL vendor string: Intel Open Source Technology Center
+             // OpenGL renderer string: Mesa DRI Intel(R) Sandybridge Desktop
+             if (((vendor) && (strstr(vendor, "Intel"))) &&
+                 ((renderer) && (strstr(renderer, "Mesa"))) &&
+                 ((renderer) && (strstr(renderer, "Intel")))
+                )
+               extn_have_y_inverted = 0;
           }
      }
-# endif
-   if (re->info->callback.pre_swap)
+   else
      {
-        re->info->callback.pre_swap(re->info->callback.data, re->evas);
+        if (getenv("EVAS_GL_INFO"))
+          printf("NO EGL EXTN!\n");
+        extn_have_buffer_age = 0;
      }
-#if 1
-   if (1)
 #else
-   if ((re->win->draw.x1 == 0) && (re->win->draw.y1 == 0) && (re->win->draw.x2 == (re->win->w - 1)) && (re->win->draw.y2 == (re->win->h - 1)))
-#endif
+   if (glXQueryExtensionsString)
+     str = glsym_glXQueryExtensionsString(re->info->info.display,
+                                          re->info->info.screen);
+
+   if (str)
      {
-//        double t, t2 = 0.0;
-//        t = get_time();
-        glXSwapBuffers(re->win->disp, re->win->win);
-//        t = get_time() - t;
-//        if (!safe_native)
-//          {
-//             t2 = get_time();
-//             glXWaitGL();
-//             t2 = get_time() - t2;
-//          }
-//        printf("swap: %3.5f (%3.5fms), x wait gl: %3.5f (%3.5fms)\n",
-//               t, t * 1000.0, t2, t2 * 1000.0);
+        if (getenv("EVAS_GL_INFO"))
+          printf("GLX EXTN:\n%s\n", str);
+        if (!strstr(str, "_texture_from_pixmap"))
+          {
+             glsym_glXBindTexImage = NULL;
+             glsym_glXReleaseTexImage = NULL;
+          }
+        if (!strstr(str, "_video_sync"))
+          {
+             glsym_glXGetVideoSync = NULL;
+             glsym_glXWaitVideoSync = NULL;
+          }
+        if (!strstr(str, "GLX_EXT_buffer_age"))
+          {
+             extn_have_buffer_age = 0;
+          }
+        if (!strstr(str, "GLX_EXT_swap_control"))
+          {
+             glsym_glXSwapIntervalEXT = NULL;
+          }
+        if (!strstr(str, "GLX_SGI_swap_control"))
+          {
+             glsym_glXSwapIntervalSGI = NULL;
+          }
+        if (!strstr(str, "GLX_MESA_release_buffers"))
+          {
+             glsym_glXReleaseBuffersMESA = NULL;
+          }
      }
    else
      {
-// FIXME: this doesn't work.. why oh why?
-        /*
-        int sx, sy, sw, sh;
-
-        sx = re->win->draw.x1;
-        sy = re->win->draw.y1;
-        sw = (re->win->draw.x2 - re->win->draw.x1) + 1;
-        sh = (re->win->draw.y2 - re->win->draw.y1) + 1;
-        sy = re->win->h - sy - sh;
-
-        glBitmap(0, 0, 0, 0, sx, re->win->h - sy, NULL);
-        glEnable(GL_SCISSOR_TEST);
-        glScissor(sx, sy, sw, sh);
-        glDrawBuffer(GL_FRONT);
-        glCopyPixels(sx, sy, sw, sh, GL_COLOR);
-        glDrawBuffer(GL_BACK);
-        glDisable(GL_SCISSOR_TEST);
-        glBitmap(0, 0, 0, 0, 0, 0, NULL);
-        glFlush();
-        */
-        ERR("Need Fixing.  Temporarily Disabled.");
-     }
-   if (re->info->callback.post_swap)
-     {
-        re->info->callback.post_swap(re->info->callback.data, re->evas);
+        if (getenv("EVAS_GL_INFO"))
+          printf("NO GLX EXTN!\n");
+        glsym_glXBindTexImage = NULL;
+        glsym_glXReleaseTexImage = NULL;
+        glsym_glXGetVideoSync = NULL;
+        glsym_glXWaitVideoSync = NULL;
+        extn_have_buffer_age = 0;
+        glsym_glXSwapIntervalEXT = NULL;
+        glsym_glXSwapIntervalSGI = NULL;
+        glsym_glXReleaseBuffersMESA = NULL;
      }
 #endif
 }
 
-static void
-eng_output_idle_flush(void *data)
-{
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-}
+int _evas_engine_GL_X11_log_dom = -1;
+/* function tables - filled in later (func and parent func) */
+static Evas_Func func, pfunc;
 
-static void
-eng_output_dump(void *data)
+static void *
+eng_info(Evas *e)
 {
-   Render_Engine *re;
+   Evas_Engine_Info_GL_X11 *info;
 
-   re = (Render_Engine *)data;
-   evas_common_image_image_all_unload();
-   evas_common_font_font_all_unload();
-   evas_gl_common_image_all_unload(re->win->gl_context);
-   _re_winfree(re);
+   info = calloc(1, sizeof(Evas_Engine_Info_GL_X11));
+   info->magic.magic = rand();
+   info->func.best_visual_get = eng_best_visual_get;
+   info->func.best_colormap_get = eng_best_colormap_get;
+   info->func.best_depth_get = eng_best_depth_get;
+   info->render_mode = EVAS_RENDER_MODE_BLOCKING;
+   info->disable_sync_draw_done = EINA_TRUE; // TIZEN ONLY
+   return info;
+   e = NULL;
 }
 
 static void
-eng_context_cutout_add(void *data __UNUSED__, void *context, int x, int y, int w, int h)
+eng_info_free(Evas *e __UNUSED__, void *info)
 {
-//   Render_Engine *re;
-//
-//   re = (Render_Engine *)data;
-//   re->win->gl_context->dc = context;
-   evas_common_draw_context_add_cutout(context, x, y, w, h);
+   Evas_Engine_Info_GL_X11 *in;
+// dont free! why bother? its not worth it
+//   eina_log_domain_unregister(_evas_engine_GL_X11_log_dom);
+   in = (Evas_Engine_Info_GL_X11 *)info;
+   free(in);
 }
 
-static void
-eng_context_cutout_clear(void *data __UNUSED__, void *context)
+static int
+_re_wincheck(Render_Engine *re)
 {
-//   Render_Engine *re;
-//
-//   re = (Render_Engine *)data;
-//   re->win->gl_context->dc = context;
-   evas_common_draw_context_clear_cutouts(context);
+   if (re->win->surf) return 1;
+   eng_window_resurf(re->win);
+   re->lost_back = 1;
+   if (!re->win->surf)
+     {
+        ERR("GL engine can't re-create window surface!");
+     }
+   return 0;
 }
 
 static void
-eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h)
+_re_winfree(Render_Engine *re)
 {
-   Render_Engine *re;
+   if (!re->win->surf) return;
+   eng_window_unsurf(re->win, EINA_FALSE);
+}
 
-   re = (Render_Engine *)data;
-   eng_window_use(re->win);
-   evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
-   re->win->gl_context->dc = context;
-   evas_gl_common_rect_draw(re->win->gl_context, x, y, w, h);
+/*
+ * Set CARD32 (array) property
+ */
+EAPI void
+_evas_x_window_prop_card32_set(
+      unsigned int win,
+         unsigned int atom,
+      unsigned int *val,
+      unsigned int num)
+{
+#if SIZEOF_INT == SIZEOF_LONG
+   _ATOM_SET_CARD32( win, atom, val, num);
+#else /* if SIZEOF_INT == SIZEOF_LONG */
+   long *v2;
+   unsigned int i;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+   v2 = malloc(num * sizeof(long));
+   if (!v2)
+       return;
+
+   for (i = 0; i < num; i++)
+      v2[i] = val[i];
+   _ATOM_SET_CARD32( win, atom, v2, num);
+   free(v2);
+#endif /* if SIZEOF_INT == SIZEOF_LONG */
 }
 
-static void
-eng_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2)
-{
-   Render_Engine *re;
+/*
+ * Get CARD32 (array) property
+ *
+ * At most len items are returned in val.
+ * If the property was successfully fetched the number of items stored in
+ * val is returned, otherwise -1 is returned.
+ * Note: Return value 0 means that the property exists but has no elements.
+ */
+static int
+_evas_x_window_prop_card32_get(Display *disp,
+                               unsigned int win,
+                               unsigned int atom,
+                               unsigned int *val,
+                               unsigned int len)
+{
+   unsigned char *prop_ret;
+   Atom type_ret;
+   unsigned long bytes_after, num_ret;
+   int format_ret;
+   unsigned int i;
+   int num;
+
+   prop_ret = NULL;
+   if (XGetWindowProperty(disp, win, atom, 0, 0x7fffffff, False,
+                          XA_CARDINAL, &type_ret, &format_ret, &num_ret,
+                          &bytes_after, &prop_ret) != Success)
+     return -1;
+
+   if (type_ret != XA_CARDINAL || format_ret != 32)
+     num = -1;
+   else if (num_ret == 0 || !prop_ret)
+     num = 0;
+   else
+     {
+        if (num_ret < len)
+          len = num_ret;
 
-   re = (Render_Engine *)data;
-   eng_window_use(re->win);
-   evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
-   re->win->gl_context->dc = context;
-   evas_gl_common_line_draw(re->win->gl_context, x1, y1, x2, y2);
-}
+        for (i = 0; i < len; i++)
+          val[i] = ((unsigned long *)prop_ret)[i];
+        num = len;
+     }
 
-static void *
-eng_polygon_point_add(void *data, void *context __UNUSED__, void *polygon, int x, int y)
-{
-   Render_Engine *re;
+   if (prop_ret)
+     XFree(prop_ret);
 
-   re = (Render_Engine *)data;
-   return evas_gl_common_poly_point_add(polygon, x, y);
+   return num;
 }
 
-static void *
-eng_polygon_points_clear(void *data, void *context __UNUSED__, void *polygon)
+
+static Eina_Bool
+_evas_x_win_check_prerotation_support(Drawable win, unsigned int atom)
 {
-   Render_Engine *re;
+   if(!atom) return EINA_FALSE;
+   unsigned int transform_hint=0;
 
-   re = (Render_Engine *)data;
-   return evas_gl_common_poly_points_clear(polygon);
-}
+   _evas_x_window_prop_card32_get(_evas_x_disp, win, atom, &transform_hint, 1);
+   if(transform_hint == EVAS_X_WINDOW_PREROTATION_SUPPORT)
+      return EINA_TRUE;
 
+   return EINA_FALSE;
+}
 static void
-eng_polygon_draw(void *data, void *context, void *surface __UNUSED__, void *polygon, int x, int y)
+_evas_x_win_rotation_transform_hint_set(Drawable win, int angle, unsigned int atom)
 {
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-   eng_window_use(re->win);
-   evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
-   re->win->gl_context->dc = context;
-   evas_gl_common_poly_draw(re->win->gl_context, polygon, x, y);
-}
+   if(!atom) return;
 
-static int
-eng_image_alpha_get(void *data __UNUSED__, void *image)
-{
-//   Render_Engine *re;
-   Evas_GL_Image *im;
+   unsigned int transform_hint; // Evas_X_Window_Rotation_Transform_Hint
 
-//   re = (Render_Engine *)data;
-   if (!image) return 1;
-   im = image;
-   return im->alpha;
+   switch (angle)
+   {
+   case 270:
+      transform_hint = EVAS_X_WINDOW_ROTATION_TRANSFORM_HINT_90;
+      break;
+   case 180:
+      transform_hint = EVAS_X_WINDOW_ROTATION_TRANSFORM_HINT_180;
+      break;
+   case 90:
+      transform_hint = EVAS_X_WINDOW_ROTATION_TRANSFORM_HINT_270;
+      break;
+   case 0:
+      transform_hint = EVAS_X_WINDOW_ROTATION_TRANSFORM_HINT_0;
+      break;
+   case -1:
+      transform_hint = EVAS_X_WINDOW_PREROTATION_QUERY;
+      break;
+   default:
+      transform_hint = EVAS_X_WINDOW_ROTATION_TRANSFORM_HINT_0;
+      break;
+   }
+   // atom is ECORE_X_ATOM_E_WINDOW_ROTATION_TRANSFORM_HINT
+   _evas_x_window_prop_card32_set(win, atom, &transform_hint,  1);
 }
 
 static int
-eng_image_colorspace_get(void *data __UNUSED__, void *image)
+eng_setup(Evas *e, void *in)
 {
-//   Render_Engine *re;
-   Evas_GL_Image *im;
+   Render_Engine *re;
+   Evas_Engine_Info_GL_X11 *info;
+   const char *s;
 
-//   re = (Render_Engine *)data;
-   if (!image) return EVAS_COLORSPACE_ARGB8888;
-   im = image;
-   return im->cs.space;
-}
+   info = (Evas_Engine_Info_GL_X11 *)in;
+   EINA_LOG_DBG("[ evasgl_dbg ]: Evas_Engine Info -> GL_X11");
+   if (!e->engine.data.output)
+     {
+#ifdef GL_GLES
+#else
+        int eb, evb;
 
-static void
-eng_image_mask_create(void *data __UNUSED__, void *image)
-{
-   Evas_GL_Image *im;
+        if (!glXQueryExtension(info->info.display, &eb, &evb)) return 0;
+#endif
+        re = calloc(1, sizeof(Render_Engine));
+        if (!re) return 0;
 
-   if (!image) return;
-   im = image;
-   if (!im->im->image.data)
-      evas_cache_image_load_data(&im->im->cache_entry);
-   if (!im->tex)
-      im->tex = evas_gl_common_texture_new(im->gc, im->im);
-}
+        if (getenv("EVAS_GL_MAKE_CURRENT_OPTIMIZE_DISABLE"))
+           re->context_optimize = EINA_FALSE;
+        else
+           re->context_optimize = EINA_TRUE;
 
+        if (_check_compositor())
+          re->is_compositor = EINA_TRUE;
+        else
+          re->is_compositor = EINA_FALSE;
 
-static void *
-eng_image_alpha_set(void *data, void *image, int has_alpha)
-{
-   Render_Engine *re;
-   Evas_GL_Image *im;
+        re->context_current = EINA_FALSE;
+        re->info = info;
+        re->evas = e;
+        re->w = e->output.w;
+        re->h = e->output.h;
 
-   re = (Render_Engine *)data;
-   if (!image) return NULL;
-   im = image;
-   if (im->alpha == has_alpha) return image;
-   if (im->native.data)
-     {
-        im->alpha = has_alpha;
-        return image;
-     }
-   eng_window_use(re->win);
-   if ((im->tex) && (im->tex->pt->dyn.img))
-     {
-        im->alpha = has_alpha;
-        im->tex->alpha = im->alpha;
-        return image;
+        if (getenv("EVAS_GL_WIN_PREROTATION"))
+          {
+             _evas_x_disp = re->info->info.display; // for pre-rotation
+             re->is_prerotate = EINA_TRUE; // Set true if env is set
+             _evas_x_win_rotation_transform_hint_set(re->info->info.drawable, -1, re->info->atom);
+          }
+        re->win = eng_window_new(re->info->info.display,
+                                 re->info->info.drawable,
+                                 re->info->info.screen,
+                                 re->info->info.visual,
+                                 re->info->info.colormap,
+                                 re->info->info.depth,
+                                 re->w,
+                                 re->h,
+                                 re->info->indirect,
+                                 re->info->info.destination_alpha,
+                                 re->info->info.rotation,
+                                 re->info->depth_bits,
+                                 re->info->stencil_bits,
+                                 re->info->msaa_bits,
+                                 re->info->info.drawable_back);
+        re->atom = re->info->atom;
+
+        if (re->is_prerotate)
+          {
+             re->is_prerotate = _evas_x_win_check_prerotation_support(re->info->info.drawable,
+                                                                      re->info->atom);
+             _evas_x_win_rotation_transform_hint_set(re->info->info.drawable, 0, re->info->atom);
+          }
+
+        if (!re->win)
+          {
+             free(re);
+             return 0;
+          }
+        e->engine.data.output = re;
+        gl_wins++;
+
+        if (!initted)
+          {
+             gl_symbols();
+
+             eng_init();
+             evas_common_cpu_init();
+             evas_common_blend_init();
+             evas_common_image_init();
+             evas_common_convert_init();
+             evas_common_scale_init();
+             evas_common_rectangle_init();
+             evas_common_polygon_init();
+             evas_common_line_init();
+             evas_common_font_init();
+             evas_common_draw_init();
+             evas_common_tilebuf_init();
+             gl_extn_veto(re);
+             initted = 1;
+          }
      }
-   /* FIXME: can move to gl_common */
-   if (im->cs.space != EVAS_COLORSPACE_ARGB8888) return im;
-   if ((has_alpha) && (im->im->cache_entry.flags.alpha)) return image;
-   else if ((!has_alpha) && (!im->im->cache_entry.flags.alpha)) return image;
-   if (im->references > 1)
+   else
      {
-        Evas_GL_Image *im_new;
+        re = e->engine.data.output;
+        if (re->win && _re_wincheck(re))
+          {
+             if ((re->info->info.display != re->win->disp) ||
+                 (re->info->info.drawable != re->win->win) ||
+                 (re->info->info.screen != re->win->screen) ||
+                 (re->info->info.visual != re->win->visual) ||
+                 (re->info->info.colormap != re->win->colormap) ||
+                 (re->info->info.depth != re->win->depth) ||
+                 (re->info->info.destination_alpha != re->win->alpha) ||
+                 (re->info->depth_bits != re->win->depth_bits) ||
+                 (re->info->stencil_bits != re->win->stencil_bits) ||
+                 (re->info->msaa_bits != re->win->msaa_bits) ||
+                 (re->info->info.drawable_back != re->win->win_back))
+               {
+                  re->win->gl_context->references++;
+                  eng_window_free(re->win);
+                  gl_wins--;
 
-        im_new = evas_gl_common_image_new_from_copied_data
-           (im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
-               im->im->image.data,
-               eng_image_alpha_get(data, image),
-               eng_image_colorspace_get(data, image));
-        if (!im_new) return im;
-        evas_gl_common_image_free(im);
-        im = im_new;
+                  re->w = e->output.w;
+                  re->h = e->output.h;
+                  re->win = eng_window_new(re->info->info.display,
+                                           re->info->info.drawable,
+                                           re->info->info.screen,
+                                           re->info->info.visual,
+                                           re->info->info.colormap,
+                                           re->info->info.depth,
+                                           re->w,
+                                           re->h,
+                                           re->info->indirect,
+                                           re->info->info.destination_alpha,
+                                           re->info->info.rotation,
+                                           re->info->depth_bits,
+                                           re->info->stencil_bits,
+                                           re->info->msaa_bits,
+                                           re->info->info.drawable_back);
+                  re->atom = re->info->atom;
+
+                  eng_window_use(re->win);
+                  if (re->win)
+                    {
+                       gl_wins++;
+                       re->win->gl_context->references--;
+                    }
+               }
+             else if ((re->win->w != e->output.w) ||
+                      (re->win->h != e->output.h) ||
+                      (re->info->info.rotation != re->win->rot) ||
+                      (re->win->gl_context->pre_rotated)) // check for scenario when rotated back to 0
+               {
+                EVGL_Resource *rsc;
+                Eina_Bool is_direct = EINA_FALSE;
+                if((rsc = _evgl_tls_resource_get()))
+                    {
+                       if(rsc->current_ctx &&
+                          rsc->current_ctx->current_sfc &&
+                          rsc->current_ctx->current_sfc->direct_fb_opt)
+                          {
+                             is_direct = EINA_TRUE;
+                          }
+                    }
+#if 0
+                if((getenv("EVAS_GL_DIRECT_OVERRIDE") && getenv("EVAS_GL_DIRECT_MEM_OPT")))
+                    {
+                        is_direct = EINA_FALSE;
+                    }
+#endif
+                if (re->is_prerotate && evgl_initted && is_direct)
+                    {
+                       _evas_x_win_rotation_transform_hint_set(re->info->info.drawable, re->info->info.rotation, re->atom);
+
+                       // re->win's h & w are not modified
+                       re->win->rot = 0;
+
+                        /* There maybe bad frame due to mismatch of surface and
+                        * window size if orientation changes in the middle of
+                        * rendering pipeling, therefore recreate the surface.
+                        */
+                       eng_window_unsurf(re->win, EINA_TRUE);
+                       eng_window_resurf(re->win);
+                       re->win->gl_context->pre_rotated = EINA_TRUE;
+                    }
+                  else
+                    {
+                       re->w = e->output.w;
+                       re->h = e->output.h;
+                       re->win->w = e->output.w;
+                       re->win->h = e->output.h;
+                       re->win->rot = re->info->info.rotation;
+                       eng_window_use(re->win);
+                       evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot);
+                    }
+               }
+             else if (re->info->info.drawable_back && re->info->info.offscreen != re->win->offscreen)
+               {
+                  re->win->offscreen = re->info->info.offscreen;
+                  eng_window_use(re->win);
+               }
+          }
      }
-   else
-     evas_gl_common_image_dirty(im, 0, 0, 0, 0);
-   return evas_gl_common_image_alpha_set(im, has_alpha ? 1 : 0);
-//   im->im->cache_entry.flags.alpha = has_alpha ? 1 : 0;
-//   return image;
-}
 
-static void *
-eng_image_border_set(void *data __UNUSED__, void *image, int l __UNUSED__, int r __UNUSED__, int t __UNUSED__, int b __UNUSED__)
-{
-//   Render_Engine *re;
-//
-//   re = (Render_Engine *)data;
-   return image;
-}
 
-static void
-eng_image_border_get(void *data __UNUSED__, void *image __UNUSED__, int *l __UNUSED__, int *r __UNUSED__, int *t __UNUSED__, int *b __UNUSED__)
-{
-//   Render_Engine *re;
-//
-//   re = (Render_Engine *)data;
-}
+   if ((s = getenv("EVAS_GL_SWAP_MODE")))
+     {
+        if ((!strcasecmp(s, "full")) ||
+            (!strcasecmp(s, "f")))
+          re->mode = MODE_FULL;
+        else if ((!strcasecmp(s, "copy")) ||
+                 (!strcasecmp(s, "c")))
+          re->mode = MODE_COPY;
+        else if ((!strcasecmp(s, "double")) ||
+                 (!strcasecmp(s, "d")) ||
+                 (!strcasecmp(s, "2")))
+          re->mode = MODE_DOUBLE;
+        else if ((!strcasecmp(s, "triple")) ||
+                 (!strcasecmp(s, "t")) ||
+                 (!strcasecmp(s, "3")))
+          re->mode = MODE_TRIPLE;
+        else if ((!strcasecmp(s, "quadruple")) ||
+                 (!strcasecmp(s, "q")) ||
+                 (!strcasecmp(s, "4")))
+          re->mode = MODE_QUADRUPLE;
+     }
+   else
+     {
+// in most gl implementations - egl and glx here that we care about the TEND
+// to either swap or copy backbuffer and front buffer, but strictly that is
+// not true. technically backbuffer content is totally undefined after a swap
+// and thus you MUST re-render all of it, thus MODE_FULL
+        re->mode = MODE_FULL;
+// BUT... reality is that lmost every implementation copies or swaps so
+// triple buffer mode can be used as it is a superset of double buffer and
+// copy (though using those explicitly is more efficient). so let's play with
+// triple buffer mdoe as a default and see.
+//        re->mode = MODE_TRIPLE;
+// XXX: note - the above seems to break on some older intel chipsets and
+// drivers. it seems we CANT depend on backbuffer staying around. bugger!
+        switch (info->swap_mode)
+          {
+           case EVAS_ENGINE_GL_X11_SWAP_MODE_FULL:
+             re->mode = MODE_FULL;
+             break;
+           case EVAS_ENGINE_GL_X11_SWAP_MODE_COPY:
+             re->mode = MODE_COPY;
+             break;
+           case EVAS_ENGINE_GL_X11_SWAP_MODE_DOUBLE:
+             re->mode = MODE_DOUBLE;
+             break;
+           case EVAS_ENGINE_GL_X11_SWAP_MODE_TRIPLE:
+             re->mode = MODE_TRIPLE;
+             break;
+           case EVAS_ENGINE_GL_X11_SWAP_MODE_QUADRUPLE:
+             re->mode = MODE_QUADRUPLE;
+             break;
+           default:
+             break;
+          }
+     }
+   if (!re->win)
+     {
+        free(re);
+        return 0;
+     }
 
-static char *
-eng_image_comment_get(void *data __UNUSED__, void *image, char *key __UNUSED__)
-{
-//   Render_Engine *re;
-   Evas_GL_Image *im;
+   if (!e->engine.data.output)
+     {
+        if (re->win)
+          {
+             eng_window_free(re->win);
+             gl_wins--;
+          }
+        free(re);
+        return 0;
+     }
+   if (re->tb) evas_common_tilebuf_free(re->tb);
+   re->tb = evas_common_tilebuf_new(re->win->w, re->win->h);
+   if (!re->tb)
+     {
+        if (re->win)
+          {
+             eng_window_free(re->win);
+             gl_wins--;
+          }
+        free(re);
+        return 0;
+     }
+   evas_common_tilebuf_set_tile_size(re->tb, EVAS_GL_UPDATE_TILE_SIZE, EVAS_GL_UPDATE_TILE_SIZE);
+   evas_common_tilebuf_tile_strict_set(re->tb, EINA_TRUE);
 
-//   re = (Render_Engine *)data;
-   if (!image) return NULL;
-   im = image;
-   if (!im->im) return NULL;
-   return im->im->info.comment;
-}
+   if (!e->engine.data.context)
+     e->engine.data.context =
+     e->engine.func->context_new(e->engine.data.output);
+   eng_window_use(re->win);
 
-static char *
-eng_image_format_get(void *data __UNUSED__, void *image)
-{
-//   Render_Engine *re;
-   Evas_GL_Image *im;
+   re->vsync = 0;
 
-//   re = (Render_Engine *)data;
-   im = image;
-   return NULL;
+   return 1;
 }
 
 static void
-eng_image_colorspace_set(void *data, void *image, int cspace)
+eng_output_free(void *data)
 {
    Render_Engine *re;
-   Evas_GL_Image *im;
 
    re = (Render_Engine *)data;
-   if (!image) return;
-   im = image;
-   if (im->native.data) return;
-   /* FIXME: can move to gl_common */
-   if (im->cs.space == cspace) return;
-   eng_window_use(re->win);
-   evas_cache_image_colorspace(&im->im->cache_entry, cspace);
-   switch (cspace)
+
+   if (re)
      {
-      case EVAS_COLORSPACE_ARGB8888:
-         if (im->cs.data)
-           {
-              if (!im->cs.no_free) free(im->cs.data);
-              im->cs.data = NULL;
-              im->cs.no_free = 0;
-           }
-         break;
-      case EVAS_COLORSPACE_YCBCR422P601_PL:
-      case EVAS_COLORSPACE_YCBCR422P709_PL:
-      case EVAS_COLORSPACE_YCBCR422601_PL:
-      case EVAS_COLORSPACE_YCBCR420NV12601_PL:
-      case EVAS_COLORSPACE_YCBCR420TM12601_PL:
-         if (im->tex) evas_gl_common_texture_free(im->tex);
-         im->tex = NULL;
-         if (im->cs.data)
-           {
-              if (!im->cs.no_free) free(im->cs.data);
-           }
-         if (im->im->cache_entry.h > 0)
-           im->cs.data =
-              calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
-         else
-           im->cs.data = NULL;
-         im->cs.no_free = 0;
-         break;
-      default:
-         abort();
-         break;
-     }
-   im->cs.space = cspace;
-}
-
-/////////////////////////////////////////////////////////////////////////
-//
-//
-typedef struct _Native Native;
-
-struct _Native
-{
-   Evas_Native_Surface ns;
-   Pixmap     pixmap;
-   Visual    *visual;
+#if 0
+#ifdef GL_GLES
+        // Destroy the resource surface
+        // Only required for EGL case
+        if (re->surface)
+           eglDestroySurface(re->win->egl_disp, re->surface);
+#endif
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   void      *egl_surface;
+        // Destroy the resource context
+        _destroy_internal_context(re, context);
+#endif
+        if (re->win)
+          {
+             if ((gl_wins == 1) && (evgl_initted == 1))
+               {
+                  evgl_engine_shutdown(re);
+                  evgl_initted = 0;
+               }
+#ifdef GL_GLES
+             eng_window_free(re->win);
 #else
-   void  *fbc;
-   XID    glx_pixmap;
+             Display *disp = re->win->disp;
+             Window win = re->win->win;
+             eng_window_free(re->win);
+             if (glsym_glXReleaseBuffersMESA)
+               glsym_glXReleaseBuffersMESA(disp, win);
 #endif
-};
+             gl_wins--;
+          }
 
-// FIXME: this is enabled so updates happen - but its SLOOOOOOOOOOOOOOOW
-// (i am sure this is the reason)  not to mention seemingly superfluous. but
-// i need to enable it for it to work on fglrx at least. havent tried nvidia.
-//
-// why is this the case? does anyone know? has anyone tried it on other gfx
-// drivers?
-//
-//#define GLX_TEX_PIXMAP_RECREATE 1
+        evas_common_tilebuf_free(re->tb);
+        if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
+        if (re->rects_prev[0]) evas_common_tilebuf_free_render_rects(re->rects_prev[0]);
+        if (re->rects_prev[1]) evas_common_tilebuf_free_render_rects(re->rects_prev[1]);
+        if (re->rects_prev[2]) evas_common_tilebuf_free_render_rects(re->rects_prev[2]);
+        if (re->rects_prev[3]) evas_common_tilebuf_free_render_rects(re->rects_prev[3]);
+
+        free(re);
+     }
+   if ((initted == 1) && (gl_wins == 0))
+     {
+        evas_common_image_shutdown();
+        evas_common_font_shutdown();
+        initted = 0;
+     }
+}
 
 static void
-_native_bind_cb(void *data, void *image)
+eng_output_resize(void *data, int w, int h)
 {
-   Evas_GL_Image *im = image;
-   Native *n = im->native.data;
-
-  if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
-    {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-      if (n->egl_surface)
-        {
-          if (glsym_glEGLImageTargetTexture2DOES)
-            {
-              glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->egl_surface);
-              if (eglGetError() != EGL_SUCCESS)
-                ERR("glEGLImageTargetTexture2DOES() failed.");
-            }
-          else
-            ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
-        }
-#else
-# ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
-      Render_Engine *re = data;
+   Render_Engine *re;
 
-      if (glsym_glXBindTexImage)
-        {
-          glsym_glXBindTexImage(re->win->disp, n->glx_pixmap,
-                                GLX_FRONT_LEFT_EXT, NULL);
-          GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-        }
-      else
-        ERR("Try glXBindTexImage on GLX with no support");
-# endif
-#endif
-    }
-  else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
-    {
-      glBindTexture(GL_TEXTURE_2D, n->ns.data.opengl.texture_id);
-      GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-    }
-   return;
-   data = NULL;
+   re = (Render_Engine *)data;
+   re->win->w = w;
+   re->win->h = h;
+   eng_window_use(re->win);
+   evas_gl_common_context_resize(re->win->gl_context, w, h, re->win->rot);
+   evas_common_tilebuf_free(re->tb);
+   re->tb = evas_common_tilebuf_new(w, h);
+   if (re->tb)
+     {
+        evas_common_tilebuf_set_tile_size(re->tb, EVAS_GL_UPDATE_TILE_SIZE, EVAS_GL_UPDATE_TILE_SIZE);
+        evas_common_tilebuf_tile_strict_set(re->tb, EINA_TRUE);
+     }
 }
 
 static void
-_native_unbind_cb(void *data, void *image)
+eng_output_tile_size_set(void *data, int w, int h)
 {
-  Evas_GL_Image *im = image;
-  Native *n = im->native.data;
+   Render_Engine *re;
 
-  if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
-    {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-      // nothing
-#else
-# ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
-      Render_Engine *re = data;
+   re = (Render_Engine *)data;
+   evas_common_tilebuf_set_tile_size(re->tb, w, h);
+}
 
-      if (glsym_glXReleaseTexImage)
-        {
-          glsym_glXReleaseTexImage(re->win->disp, n->glx_pixmap,
-                                   GLX_FRONT_LEFT_EXT);
-          GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-        }
-      else
-        ERR("Try glXReleaseTexImage on GLX with no support");
-# endif
-#endif
-    }
-  else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
-    {
-      glBindTexture(GL_TEXTURE_2D, 0);
-      GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-    }
-   return;
-   data = NULL;
+static void
+eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
+{
+   Render_Engine *re;
+
+   re = (Render_Engine *)data;
+   eng_window_use(re->win);
+   evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot);
+   evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
 }
 
 static void
-_native_free_cb(void *data, void *image)
+eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
 {
-  Render_Engine *re = data;
-  Evas_GL_Image *im = image;
-  Native *n = im->native.data;
-  uint32_t pmid, texid;
+   Render_Engine *re;
 
-  if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
-    {
-      pmid = n->pixmap;
-      eina_hash_del(re->win->gl_context->shared->native_pm_hash, &pmid, im);
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-      if (n->egl_surface)
-        {
-          if (glsym_eglDestroyImage)
-            {
-              glsym_eglDestroyImage(re->win->egl_disp,
-                                    n->egl_surface);
-              if (eglGetError() != EGL_SUCCESS)
-                ERR("eglDestroyImage() failed.");
-            }
-          else
-            ERR("Try eglDestroyImage on EGL with no support");
-        }
-#else
-# ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
-      if (n->glx_pixmap)
-        {
-          if (im->native.loose)
-            {
-              if (glsym_glXReleaseTexImage)
-                {
-                  glsym_glXReleaseTexImage(re->win->disp, n->glx_pixmap,
-                                           GLX_FRONT_LEFT_EXT);
-                  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-                }
-              else
-                ERR("Try glXReleaseTexImage on GLX with no support");
-            }
-          if (glsym_glXDestroyPixmap)
-            {
-              glsym_glXDestroyPixmap(re->win->disp, n->glx_pixmap);
-              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-            }
-          else
-            ERR("Try glXDestroyPixmap on GLX with no support");
-          n->glx_pixmap = 0;
-        }
-# endif
-#endif
-    }
-  else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
-    {
-      texid = n->ns.data.opengl.texture_id;
-      eina_hash_del(re->win->gl_context->shared->native_tex_hash, &texid, im);
-    }
-  im->native.data        = NULL;
-  im->native.func.data   = NULL;
-  im->native.func.bind   = NULL;
-  im->native.func.unbind = NULL;
-  im->native.func.free   = NULL;
-  free(n);
+   re = (Render_Engine *)data;
+   evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
 }
 
-static void *
-eng_image_native_set(void *data, void *image, void *native)
+static void
+eng_output_redraws_clear(void *data)
 {
-  Render_Engine *re = (Render_Engine *)data;
-  Evas_Native_Surface *ns = native;
-  Evas_GL_Image *im = image, *im2 = NULL;
-  Visual *vis = NULL;
-  Pixmap pm = 0;
-  Native *n = NULL;
-  uint32_t pmid, texid;
-  unsigned int tex = 0;
-  unsigned int fbo = 0;
+   Render_Engine *re;
 
-  if (!im)
-    {
-       if ((!ns) && (ns->type == EVAS_NATIVE_SURFACE_OPENGL))
-         {
-            im = evas_gl_common_image_new_from_data(re->win->gl_context,
-                                                    ns->data.opengl.w,
-                                                    ns->data.opengl.h,
-                                                    NULL, 1,
-                                                    EVAS_COLORSPACE_ARGB8888);
-         }
-       else
-           return NULL;
-    }
+   re = (Render_Engine *)data;
+   evas_common_tilebuf_clear(re->tb);
+//   INF("GL: finish update cycle!");
+}
 
-  if (ns)
-    {
-      if (ns->type == EVAS_NATIVE_SURFACE_X11)
-        {
-          vis = ns->data.x11.visual;
-          pm = ns->data.x11.pixmap;
-          if (im->native.data)
-            {
-              Evas_Native_Surface *ens = im->native.data;
-              if ((ens->data.x11.visual == vis) &&
-                  (ens->data.x11.pixmap == pm))
-                return im;
-            }
-        }
-      else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
-        {
-          tex = ns->data.opengl.texture_id;
-          fbo = ns->data.opengl.framebuffer_id;
-          if (im->native.data)
-            {
-              Evas_Native_Surface *ens = im->native.data;
-              if ((ens->data.opengl.texture_id == tex) &&
-                  (ens->data.opengl.framebuffer_id == fbo))
-                return im;
-            }
-        }
-    }
-  if ((!ns) && (!im->native.data)) return im;
-
-  eng_window_use(re->win);
+static Tilebuf_Rect *
+_merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3, Tilebuf_Rect *r4)
+{
+   Tilebuf_Rect *r, *rects;
+   Evas_Point p1, p2;
 
-  if (im->native.data)
-    {
-      if (im->native.func.free)
-        im->native.func.free(im->native.func.data, im);
-      evas_gl_common_image_native_disable(im);
-    }
+   if (r1)
+     {
+        EINA_INLIST_FOREACH(EINA_INLIST_GET(r1), r)
+          {
+             evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
+          }
+     }
+   if (r2)
+     {
+        EINA_INLIST_FOREACH(EINA_INLIST_GET(r2), r)
+          {
+             evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
+          }
+     }
+   if (r3)
+     {
+        EINA_INLIST_FOREACH(EINA_INLIST_GET(r3), r)
+          {
+             evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
+          }
+     }
+   if (r4)
+     {
+        EINA_INLIST_FOREACH(EINA_INLIST_GET(r4), r)
+          {
+             evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
+          }
+     }
+   rects = evas_common_tilebuf_get_render_rects(tb);
 
-  if (!ns) return im;
+   if (partial_rect_union_mode == -1)
+     {
+        const char *s = getenv("EVAS_GL_PARTIAL_MERGE");
+        if (s)
+          {
+             if ((!strcmp(s, "bounding")) ||
+                 (!strcmp(s, "b")))
+               partial_rect_union_mode = MERGE_BOUNDING;
+             else if ((!strcmp(s, "full")) ||
+                      (!strcmp(s, "f")))
+               partial_rect_union_mode = MERGE_FULL;
+          }
+        else
+          partial_rect_union_mode = MERGE_BOUNDING;
+     }
+   if (partial_rect_union_mode == MERGE_BOUNDING)
+     {
+// bounding box -> make a bounding box single region update of all regions.
+// yes we could try and be smart and figure out size of regions, how far
+// apart etc. etc. to try and figure out an optimal "set". this is a tradeoff
+// between multiple update regions to render and total pixels to render.
+        if (rects)
+          {
+             p1.x = rects->x; p1.y = rects->y;
+             p2.x = rects->x + rects->w; p2.y = rects->y + rects->h;
+             EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r)
+               {
+                  if (r->x < p1.x) p1.x = r->x;
+                  if (r->y < p1.y) p1.y = r->y;
+                  if ((r->x + r->w) > p2.x) p2.x = r->x + r->w;
+                  if ((r->y + r->h) > p2.y) p2.y = r->y + r->h;
+               }
+             evas_common_tilebuf_free_render_rects(rects);
+             rects = calloc(1, sizeof(Tilebuf_Rect));
+             if (rects)
+               {
+                  rects->x = p1.x;
+                  rects->y = p1.y;
+                  rects->w = p2.x - p1.x;
+                  rects->h = p2.y - p1.y;
+               }
+          }
+     }
+   evas_common_tilebuf_clear(tb);
+   return rects;
+}
 
-  if (ns->type == EVAS_NATIVE_SURFACE_X11)
-    {
-      pmid = pm;
-      im2 = eina_hash_find(re->win->gl_context->shared->native_pm_hash, &pmid);
-      if (im2 == im) return im;
-      if (im2)
-        {
-           n = im2->native.data;
-           if (n)
-             {
-                evas_gl_common_image_ref(im2);
-                evas_gl_common_image_free(im);
-                return im2;
-             }
-        }
-    }
-  else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
-    {
-       texid = tex;
-       im2 = eina_hash_find(re->win->gl_context->shared->native_tex_hash, &texid);
-       if (im2 == im) return im;
-       if (im2)
-         {
-            n = im2->native.data;
-            if (n)
-              {
-                 evas_gl_common_image_ref(im2);
-                 evas_gl_common_image_free(im);
-                 return im2;
-              }
-         }
+/* vsync games - not for now though */
+#define VSYNC_TO_SCREEN 1
 
-    }
-  im2 = evas_gl_common_image_new_from_data(re->win->gl_context,
-                                           im->w, im->h, NULL, im->alpha,
-                                           EVAS_COLORSPACE_ARGB8888);
-  evas_gl_common_image_free(im);
-  im = im2;
-  if (ns->type == EVAS_NATIVE_SURFACE_X11)
-    {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-      if (native)
-        {
-          n = calloc(1, sizeof(Native));
-          if (n)
-            {
-              EGLConfig egl_config;
-              int config_attrs[20];
-              int num_config, i = 0;
+static void _post_process_rect(Tilebuf *tb, Tilebuf_Rect *rect, int rot)
+{
+   int x1, x2, y1, y2;
+   int x, y, w, h;
 
-              eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im);
+   if (rect == NULL)
+      return;
 
-              config_attrs[i++] = EGL_RED_SIZE;
-              config_attrs[i++] = 8;
-              config_attrs[i++] = EGL_GREEN_SIZE;
-              config_attrs[i++] = 8;
-              config_attrs[i++] = EGL_BLUE_SIZE;
-              config_attrs[i++] = 8;
-              config_attrs[i++] = EGL_ALPHA_SIZE;
-              config_attrs[i++] = 8;
-              config_attrs[i++] = EGL_DEPTH_SIZE;
-              config_attrs[i++] = 0;
-              config_attrs[i++] = EGL_STENCIL_SIZE;
-              config_attrs[i++] = 0;
-              config_attrs[i++] = EGL_RENDERABLE_TYPE;
-              config_attrs[i++] = EGL_OPENGL_ES2_BIT;
-              config_attrs[i++] = EGL_SURFACE_TYPE;
-              config_attrs[i++] = EGL_PIXMAP_BIT;
-              config_attrs[i++] = EGL_NONE;
+   if (rot == 0 || rot == 180)
+      return;
 
-              if (!eglChooseConfig(re->win->egl_disp, config_attrs,
-                                   &egl_config, 1, &num_config))
-                ERR("eglChooseConfig() failed for pixmap 0x%x, num_config = %i", (unsigned int)pm, num_config);
-              memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
-              n->pixmap = pm;
-              n->visual = vis;
-              if (glsym_eglCreateImage)
-                n->egl_surface = glsym_eglCreateImage(re->win->egl_disp,
-                                                      EGL_NO_CONTEXT,
-                                                      EGL_NATIVE_PIXMAP_KHR,
-                                                      (void *)pm,
-                                                      NULL);
-              else
-                ERR("Try eglCreateImage on EGL with no support");
-              if (!n->egl_surface)
-                ERR("eglCreatePixmapSurface() for 0x%x failed", (unsigned int)pm);
-              im->native.yinvert     = 1;
-              im->native.loose       = 0;
-              im->native.data        = n;
-              im->native.func.data   = re;
-              im->native.func.bind   = _native_bind_cb;
-              im->native.func.unbind = _native_unbind_cb;
-              im->native.func.free   = _native_free_cb;
-              im->native.target      = GL_TEXTURE_2D;
-              im->native.mipmap      = 0;
-              evas_gl_common_image_native_enable(im);
-            }
-        }
-#else
-# ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
-      if (native)
-        {
-          int dummy;
-          unsigned int w, h, depth = 32, border;
-          Window wdummy;
+   // For 90 or 270 rotation, merged rect should be rounded up to tb->tile_size.w and tb->tile_size.h
+   // AFTER rotated to 0 rotation, then rotated back to original rotation
 
-          // fixme: round trip :(
-          XGetGeometry(re->win->disp, pm, &wdummy, &dummy, &dummy,
-                       &w, &h, &border, &depth);
-          n = calloc(1, sizeof(Native));
-          if (n)
-            {
-              int pixmap_att[20];
-              unsigned int target = 0;
-              unsigned int i = 0;
+   x = rect->x;
+   y = rect->y;
+   w = rect->w;
+   h = rect->h;
 
-              eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im);
-              if ((re->win->depth_cfg[depth].tex_target &
-                   GLX_TEXTURE_2D_BIT_EXT)
-                  //                 && (1) // we assume npo2 for now
-                  // size is pow2 || mnpo2 supported
-                 )
-                target = GLX_TEXTURE_2D_EXT;
-              else if ((re->win->depth_cfg[depth].tex_target &
-                        GLX_TEXTURE_RECTANGLE_BIT_EXT))
-                {
-                  ERR("rect!!! (not handled)");
-                  target = GLX_TEXTURE_RECTANGLE_EXT;
-                }
-              if (!target)
-                {
-                  ERR("broken text-from-pixmap");
-                  if (!(re->win->depth_cfg[depth].tex_target &
-                        GLX_TEXTURE_2D_BIT_EXT))
-                    target = GLX_TEXTURE_RECTANGLE_EXT;
-                  else if (!(re->win->depth_cfg[depth].tex_target &
-                             GLX_TEXTURE_RECTANGLE_BIT_EXT))
-                    target = GLX_TEXTURE_2D_EXT;
-                }
+   // STEP 1. rotate the merged rect to rotation 0
+   switch (rot)
+     {
+      case 90:
+        rect->x = y;
+        rect->y = tb->outbuf_w - (x + w);
+        rect->w = h;
+        rect->h = w;
+        break;
+      case 270:
+        rect->x = tb->outbuf_h - (y + h);
+        rect->y = x;
+        rect->w = h;
+        rect->h = w;
+        break;
+      default:
+        break;
+     }
+
+   // STEP 2. round up rects
+   x1 = rect->x;
+   x2 = x1 + rect->w;
+   y1 = rect->y;
+   y2 = y1 + rect->h;
+   x1 = tb->tile_size.w * (x1 / tb->tile_size.w);
+   y1 = tb->tile_size.h * (y1 / tb->tile_size.h);
+   x2 = tb->tile_size.w * ((x2 + tb->tile_size.w - 1) / tb->tile_size.w);
+   y2 = tb->tile_size.h * ((y2 + tb->tile_size.h - 1) / tb->tile_size.h);
+
+   x = x1; y = y1; w = x2 - x1; h = y2 - y1;
+   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_h, tb->outbuf_w);
+
+   // STEP 3. rotate the rect back to original rotation
+   switch (rot)
+     {
+      case 90:
+        rect->x = tb->outbuf_w - (y + h);
+        rect->y = x;
+        rect->w = h;
+        rect->h = w;
+        break;
+      case 270:
+        rect->x = y;
+        rect->y = tb->outbuf_h - (x + w);
+        rect->w = h;
+        rect->h = w;
+        break;
+      default:
+        break;
+     }
+}
 
+static void *
+eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
+{
+   Render_Engine *re;
+   Tilebuf_Rect *rect;
+   Eina_Bool first_rect = EINA_FALSE;
 
-              pixmap_att[i++] = GLX_TEXTURE_FORMAT_EXT;
-              pixmap_att[i++] = re->win->depth_cfg[depth].tex_format;
-              pixmap_att[i++] = GLX_MIPMAP_TEXTURE_EXT;
-              pixmap_att[i++] = re->win->depth_cfg[depth].mipmap;
+#define CLEAR_PREV_RECTS(x) \
+   do { \
+      if (re->rects_prev[x]) \
+        evas_common_tilebuf_free_render_rects(re->rects_prev[x]); \
+      re->rects_prev[x] = NULL; \
+   } while (0)
 
-              if (target)
-                {
-                  pixmap_att[i++] = GLX_TEXTURE_TARGET_EXT;
-                  pixmap_att[i++] = target;
-                }
+   re = (Render_Engine *)data;
+   /* get the upate rect surface - return engine data as dummy */
+   if (re->end)
+     {
+        re->end = 0;
+        return NULL;
+     }
+   if (!re->rects)
+     {
+        re->rects = evas_common_tilebuf_get_render_rects(re->tb);
+        if (re->rects)
+          {
+             if (re->info->swap_mode == EVAS_ENGINE_GL_X11_SWAP_MODE_AUTO)
+               {
+                  if (extn_have_buffer_age)
+                    {
+#ifdef GL_GLES
+                       EGLint age = 0;
 
-              pixmap_att[i++] = 0;
+                       if (!eglQuerySurface(re->win->egl_disp,
+                                            re->win->egl_surface[0],
+                                            EGL_BUFFER_AGE_EXT, &age))
+                         age = 0;
+#else
+                       unsigned int age = 0;
 
-              memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
-              n->pixmap = pm;
-              n->visual = vis;
-              n->fbc = re->win->depth_cfg[depth].fbc;
-              if (glsym_glXCreatePixmap)
-                n->glx_pixmap = glsym_glXCreatePixmap(re->win->disp,
-                                                      n->fbc,
-                                                      n->pixmap,
-                                                      pixmap_att);
-              else
-                ERR("Try glXCreatePixmap on GLX with no support");
-              if (n->glx_pixmap)
-                {
-//                  printf("%p: new native texture for %x | %4i x %4i @ %2i = %p\n",
-//                         n, pm, w, h, depth, n->glx_pixmap);
-                  if (!target)
-                    {
-                      ERR("no target :(");
-                      if (glsym_glXQueryDrawable)
-                        glsym_glXQueryDrawable(re->win->disp,
-                                               n->pixmap,
-                                               GLX_TEXTURE_TARGET_EXT,
-                                               &target);
-                    }
-                  if (target == GLX_TEXTURE_2D_EXT)
-                    {
-                      im->native.target = GL_TEXTURE_2D;
-                      im->native.mipmap = re->win->depth_cfg[depth].mipmap;
-                    }
-#  ifdef GL_TEXTURE_RECTANGLE_ARB
-                  else if (target == GLX_TEXTURE_RECTANGLE_EXT)
-                    {
-                      im->native.target = GL_TEXTURE_RECTANGLE_ARB;
-                      im->native.mipmap = 0;
+                       if (glsym_glXQueryDrawable)
+                         {
+                            if (re->win->glxwin)
+                              glsym_glXQueryDrawable(re->win->disp,
+                                                     re->win->glxwin,
+                                                     GLX_BACK_BUFFER_AGE_EXT,
+                                                     &age);
+                            else
+                              glsym_glXQueryDrawable(re->win->disp,
+                                                     re->win->win,
+                                                     GLX_BACK_BUFFER_AGE_EXT,
+                                                     &age);
+                         }
+#endif
+                       if (age == 1) re->mode = MODE_COPY;
+                       else if (age == 2) re->mode = MODE_DOUBLE;
+                       else if (age == 3) re->mode = MODE_TRIPLE;
+                       else if (age == 4) re->mode = MODE_QUADRUPLE;
+                       else re->mode = MODE_FULL;
+                       if ((int)age != re->prev_age) re->mode = MODE_FULL;
+                       re->prev_age = age;
                     }
-#  endif
                   else
                     {
-                      im->native.target = GL_TEXTURE_2D;
-                      im->native.mipmap = 0;
-                      ERR("still unknown target");
+                       re->mode = MODE_FULL;
                     }
-                }
-              else
-                ERR("GLX Pixmap create fail");
-              im->native.yinvert     = re->win->depth_cfg[depth].yinvert;
-              im->native.loose       = re->win->detected.loose_binding;
-              im->native.data        = n;
-              im->native.func.data   = re;
-              im->native.func.bind   = _native_bind_cb;
-              im->native.func.unbind = _native_unbind_cb;
-              im->native.func.free   = _native_free_cb;
+               }
 
-              evas_gl_common_image_native_enable(im);
-            }
-        }
-# endif
-#endif
-    }
-  else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
-    {
-      if (native)
-        {
-          n = calloc(1, sizeof(Native));
-          if (n)
-            {
-              memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
+             if ( (re->lost_back) || (re->mode == MODE_FULL) )
+               {
+                  /* if we lost our backbuffer since the last frame redraw all */
+                  re->lost_back = 0;
+                  evas_common_tilebuf_add_redraw(re->tb, 0, 0, re->win->w, re->win->h);
+                  evas_common_tilebuf_free_render_rects(re->rects);
+                  re->rects = evas_common_tilebuf_get_render_rects(re->tb);
+               }
+             /* ensure we get rid of previous rect lists we dont need if mode
+              * changed/is appropriate */
+             evas_common_tilebuf_clear(re->tb);
+             CLEAR_PREV_RECTS(3);
+             re->rects_prev[3] = re->rects_prev[2];
+             re->rects_prev[2] = re->rects_prev[1];
+             re->rects_prev[1] = re->rects_prev[0];
+             re->rects_prev[0] = re->rects;
+             re->rects = NULL;
+             switch (re->mode)
+               {
+                case MODE_FULL:
+                case MODE_COPY: // no prev rects needed
+                  re->rects = _merge_rects(re->tb, re->rects_prev[0], NULL, NULL, NULL);
+                  break;
+                case MODE_DOUBLE: // double mode - only 1 level of prev rect
+                  re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], NULL, NULL);
+                  break;
+                case MODE_TRIPLE: // triple mode - 2 levels of prev rect
+                  re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2], NULL);
+                  break;
+                case MODE_QUADRUPLE: // keep all
+                  re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2], re->rects_prev[3]);
+                  break;
+                default:
+                  break;
+               }
+             if ((extn_have_buffer_age != 0)
+                 && (glsym_eglSwapBuffersWithDamage)
+                 && (re->mode != MODE_FULL))
+                _post_process_rect(re->tb, re->rects, re->win->rot);
+             first_rect = EINA_TRUE;
+          }
+        evas_common_tilebuf_clear(re->tb);
+        re->cur_rect = EINA_INLIST_GET(re->rects);
+     }
+   if (!re->cur_rect) return NULL;
+   rect = (Tilebuf_Rect *)re->cur_rect;
+   if (re->rects)
+     {
+        re->win->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM;
 
-              eina_hash_add(re->win->gl_context->shared->native_tex_hash, &texid, im);
+        switch (re->mode)
+          {
+           case MODE_COPY:
+           case MODE_DOUBLE:
+           case MODE_TRIPLE:
+           case MODE_QUADRUPLE:
+             rect = (Tilebuf_Rect *)re->cur_rect;
+             *x = rect->x;
+             *y = rect->y;
+             *w = rect->w;
+             *h = rect->h;
+             *cx = rect->x;
+             *cy = rect->y;
+             *cw = rect->w;
+             *ch = rect->h;
+             re->cur_rect = re->cur_rect->next;
+             re->win->gl_context->master_clip.enabled = EINA_TRUE;
+             re->win->gl_context->master_clip.x = rect->x;
+             re->win->gl_context->master_clip.y = rect->y;
+             re->win->gl_context->master_clip.w = rect->w;
+             re->win->gl_context->master_clip.h = rect->h;
+             break;
+           case MODE_FULL:
+             re->cur_rect = NULL;
+             if (x) *x = 0;
+             if (y) *y = 0;
+             if (w) *w = re->win->w;
+             if (h) *h = re->win->h;
+             if (cx) *cx = 0;
+             if (cy) *cy = 0;
+             if (cw) *cw = re->win->w;
+             if (ch) *ch = re->win->h;
+             re->win->gl_context->master_clip.enabled = EINA_FALSE;
+             break;
+           default:
+             break;
+          }
 
-              n->pixmap = 0;
-              n->visual = 0;
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-              n->egl_surface = 0;
+        if (first_rect)
+          {
+#ifdef GL_GLES
+             // dont need to for egl - eng_window_use() can check for other ctxt's
 #else
-              n->fbc = 0;
-              n->glx_pixmap = 0;
+             eng_window_use(NULL);
 #endif
+             eng_window_use(re->win);
+             if (!_re_wincheck(re)) return NULL;
 
-              im->native.yinvert     = 0;
-              im->native.loose       = 0;
-              im->native.data        = n;
-              im->native.func.data   = re;
-              im->native.func.bind   = _native_bind_cb;
-              im->native.func.unbind = _native_unbind_cb;
-              im->native.func.free   = _native_free_cb;
-              im->native.target      = GL_TEXTURE_2D;
-              im->native.mipmap      = 0;
-
-              // FIXME: need to implement mapping sub texture regions
-              // x, y, w, h for possible texture atlasing
-
-              evas_gl_common_image_native_enable(im);
-            }
-        }
+             evas_gl_common_context_flush(re->win->gl_context);
+             evas_gl_common_context_newframe(re->win->gl_context);
 
-    }
-   return im;
+             if (partial_render_debug == -1)
+               {
+                  if (getenv("EVAS_GL_PARTIAL_DEBUG")) partial_render_debug = 1;
+                  else partial_render_debug = 0;
+               }
+             if (partial_render_debug == 1)
+               {
+                  if (re->is_compositor == EINA_TRUE) glClearColor(1.0, 0.0, 0.2, 1.0);
+                  else glClearColor(0.2, 0.5, 1.0, 1.0);
+                  glClear(GL_COLOR_BUFFER_BIT);
+               }
+          }
+        if (!re->cur_rect)
+          {
+             re->end = 1;
+          }
+        return re->win->gl_context->def_surface;
+     }
+   return NULL;
 }
 
-static void *
-eng_image_native_get(void *data __UNUSED__, void *image)
+static int safe_native = -1;
+
+static void
+eng_output_redraws_next_update_push(void *data, void *surface __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
 {
-   Evas_GL_Image *im = image;
-   Native *n;
-   if (!im) return NULL;
-   n = im->native.data;
-   if (!n) return NULL;
-   return &(n->ns);
+   Render_Engine *re;
+
+   re = (Render_Engine *)data;
+   /* put back update surface.. in this case just unflag redraw */
+   if (!_re_wincheck(re)) return;
+   re->win->draw.drew = 1;
+   evas_gl_common_context_flush(re->win->gl_context);
+   if (safe_native == -1)
+     {
+        const char *s = getenv("EVAS_GL_SAFE_NATIVE");
+        safe_native = 0;
+        if (s) safe_native = atoi(s);
+        else
+          {
+             s = (const char *)glGetString(GL_RENDERER);
+             if (s)
+               {
+                  if (strstr(s, "PowerVR SGX 540") ||
+                      strstr(s, "Mali-400 MP"))
+                    safe_native = 1;
+               }
+          }
+     }
+#ifdef GL_GLES
+   // this is needed to make sure all previous rendering is flushed to
+   // buffers/surfaces
+   // previous rendering should be done and swapped
+//xx   if (!safe_native) eglWaitNative(EGL_CORE_NATIVE_ENGINE);
+//   if (eglGetError() != EGL_SUCCESS)
+//     {
+//        printf("Error:  eglWaitNative(EGL_CORE_NATIVE_ENGINE) fail.\n");
+//     }
+#else
+   // previous rendering should be done and swapped
+//xx   if (!safe_native) glXWaitX();
+#endif
 }
 
-#if 0 // filtering disabled
 static void
-eng_image_draw_filtered(void *data, void *context, void *surface,
-                        void *image, Evas_Filter_Info *filter)
+eng_output_flush(void *data)
 {
-   Render_Engine *re = data;
+   Render_Engine *re;
+   static char *dname = NULL;
 
-   if (!image) return;
+   re = (Render_Engine *)data;
+   if (!_re_wincheck(re)) return;
+   if (!re->win->draw.drew) return;
+
+   re->context_current = EINA_FALSE;
+
+   re->win->draw.drew = 0;
    eng_window_use(re->win);
-   evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
-   re->win->gl_context->dc = context;
 
-   evas_gl_common_filter_draw(re->win->gl_context, image, filter);
+   evas_gl_common_context_done(re->win->gl_context);
+
+   // Save contents of the framebuffer to a file
+   if (swap_buffer_debug_mode == -1)
+     {
+        if ((dname = getenv("EVAS_GL_SWAP_BUFFER_DEBUG_DIR")))
+          {
+             int stat;
+             // Create a directory with 0775 permission
+             stat = mkdir(dname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
+             if ((!stat) || errno == EEXIST) swap_buffer_debug_mode = 1;
+          }
+        else
+           swap_buffer_debug_mode = 0;
+     }
+
+   if (swap_buffer_debug_mode == 1)
+     {
+        // Set this env var to dump files every frame
+        // Or set the global var in gdb to 1|0 to turn it on and off
+        if (getenv("EVAS_GL_SWAP_BUFFER_DEBUG_ALWAYS"))
+           swap_buffer_debug = 1;
+
+        if (swap_buffer_debug)
+          {
+             char fname[100];
+             char suffix[100];
+             int ret = 0;
+
+             sprintf(fname, "%p", (void*)re->win);
+
+             ret = evas_gl_common_buffer_dump(re->win->gl_context,
+                                              (const char*)dname,
+                                              (const char*)fname,
+                                              re->frame_cnt,
+                                              suffix);
+             if (!ret) swap_buffer_debug_mode = 0;
+          }
+     }
+
+#ifdef GL_GLES
+   if (!re->vsync && !re->info->info.drawable_back)
+     {
+        if (re->info->vsync) eglSwapInterval(re->win->egl_disp, 1);
+        else eglSwapInterval(re->win->egl_disp, 0);
+        re->vsync = 1;
+     }
+   if (re->info->callback.pre_swap)
+     {
+        re->info->callback.pre_swap(re->info->callback.data, re->evas);
+     }
+   if (re->info->info.drawable_back)
+     {
+        glFlush();
+     }
+   else
+     {
+        // XXX: if partial swaps can be done use re->rects
+        if ((extn_have_buffer_age != 0)
+            && (glsym_eglSwapBuffersWithDamage)
+            && (re->mode != MODE_FULL))
+          {
+             EGLint num = 0, *rects = NULL, i;
+             Tilebuf_Rect *r;
+
+             // if partial swaps can be done use re->rects
+             EINA_INLIST_FOREACH(EINA_INLIST_GET(re->rects), r) num++;
+             if (num > 0) rects = malloc(sizeof(EGLint) * 4 * num);
+             if (rects)
+               {
+                  i = 0;
+                  EINA_INLIST_FOREACH(EINA_INLIST_GET(re->rects), r)
+                    {
+                       int gw, gh;
+
+                       gw = re->win->gl_context->w;
+                       gh = re->win->gl_context->h;
+                       switch (re->win->rot)
+                         {
+                          case 0:
+                            rects[i + 0] = r->x;
+                            rects[i + 1] = gh - (r->y + r->h);
+                            rects[i + 2] = r->w;
+                            rects[i + 3] = r->h;
+                            break;
+                          case 90:
+                            rects[i + 0] = r->y;
+                            rects[i + 1] = r->x;
+                            rects[i + 2] = r->h;
+                            rects[i + 3] = r->w;
+                            break;
+                          case 180:
+                            rects[i + 0] = gw - (r->x + r->w);
+                            rects[i + 1] = r->y;
+                            rects[i + 2] = r->w;
+                            rects[i + 3] = r->h;
+                            break;
+                          case 270:
+                            rects[i + 0] = gh - (r->y + r->h);
+                            rects[i + 1] = gw - (r->x + r->w);
+                            rects[i + 2] = r->h;
+                            rects[i + 3] = r->w;
+                            break;
+                          default:
+                            rects[i + 0] = r->x;
+                            rects[i + 1] = gh - (r->y + r->h);
+                            rects[i + 2] = r->w;
+                            rects[i + 3] = r->h;
+                            break;
+                         }
+                       i += 4;
+                    }
+
+                    glsym_eglSwapBuffersWithDamage(re->win->egl_disp,
+                                                   re->win->egl_surface[0],
+                                                   rects, num);
+                  free(rects);
+               }
+          }
+        else
+          {
+             eglSwapBuffers(re->win->egl_disp, re->win->egl_surface[0]);
+          }
+     }
+   //xx   if (!safe_native) eglWaitGL();
+   if (re->info->callback.post_swap)
+     {
+        re->info->callback.post_swap(re->info->callback.data, re->evas);
+     }
+//   if (eglGetError() != EGL_SUCCESS)
+//     {
+//        printf("Error:  eglSwapBuffers() fail.\n");
+//     }
+#else
+#ifdef VSYNC_TO_SCREEN
+   if (re->info->vsync)
+     {
+        if (glsym_glXSwapIntervalEXT)
+          {
+             if (!re->vsync)
+               {
+                  if (re->info->vsync) glsym_glXSwapIntervalEXT(re->win->disp, re->win->win, 1);
+                  else glsym_glXSwapIntervalEXT(re->win->disp, re->win->win, 0);
+                  re->vsync = 1;
+               }
+          }
+        else if (glsym_glXSwapIntervalSGI)
+          {
+             if (!re->vsync)
+               {
+                  if (re->info->vsync) glsym_glXSwapIntervalSGI(1);
+                  else glsym_glXSwapIntervalSGI(0);
+                  re->vsync = 1;
+               }
+          }
+        else
+          {
+             if ((glsym_glXGetVideoSync) && (glsym_glXWaitVideoSync))
+               {
+                  unsigned int rc;
+
+                  glsym_glXGetVideoSync(&rc);
+                  glsym_glXWaitVideoSync(1, 0, &rc);
+               }
+          }
+     }
+#endif
+   if (re->info->callback.pre_swap)
+     {
+        re->info->callback.pre_swap(re->info->callback.data, re->evas);
+     }
+   // XXX: if partial swaps can be done use re->rects
+   glXSwapBuffers(re->win->disp, re->win->win);
+   if (re->info->callback.post_swap)
+     {
+        re->info->callback.post_swap(re->info->callback.data, re->evas);
+     }
+#endif
+
+   // clear out rects after swap as we may use them during swap
+   if (re->rects)
+     {
+        evas_common_tilebuf_free_render_rects(re->rects);
+        re->rects = NULL;
+     }
+
+   re->frame_cnt++;
 }
 
-static Filtered_Image *
-eng_image_filtered_get(void *im, uint8_t *key, size_t keylen)
+static void
+eng_output_idle_flush(void *data)
 {
-   return evas_gl_common_image_filtered_get(im, key, keylen);
+   Render_Engine *re;
+
+   re = (Render_Engine *)data;
 }
 
-static Filtered_Image *
-eng_image_filtered_save(void *im, void *fim, uint8_t *key, size_t keylen)
+static void
+eng_output_dump(void *data)
 {
-   return evas_gl_common_image_filtered_save(im, fim, key, keylen);
+   Render_Engine *re;
+
+   re = (Render_Engine *)data;
+   evas_common_image_image_all_unload();
+   evas_common_font_font_all_unload();
+   evas_gl_common_image_all_unload(re->win->gl_context);
+   _re_winfree(re);
 }
 
 static void
-eng_image_filtered_free(void *im, Filtered_Image *fim)
+eng_context_cutout_add(void *data __UNUSED__, void *context, int x, int y, int w, int h)
 {
-   evas_gl_common_image_filtered_free(im, fim);
+//   Render_Engine *re;
+//
+//   re = (Render_Engine *)data;
+//   re->win->gl_context->dc = context;
+   evas_common_draw_context_add_cutout(context, x, y, w, h);
 }
-#endif
 
-
-//
+static void
+eng_context_cutout_clear(void *data __UNUSED__, void *context)
+{
+//   Render_Engine *re;
 //
-/////////////////////////////////////////////////////////////////////////
+//   re = (Render_Engine *)data;
+//   re->win->gl_context->dc = context;
+   evas_common_draw_context_clear_cutouts(context);
+}
 
-static void *
-eng_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
+static void
+eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h)
 {
    Render_Engine *re;
 
    re = (Render_Engine *)data;
-   *error = EVAS_LOAD_ERROR_NONE;
-   eng_window_use(re->win);
-   return evas_gl_common_image_load(re->win->gl_context, file, key, lo, error);
+
+   if (re->context_optimize)
+     {
+        if (!re->context_current)
+          {
+             re->context_current = EINA_TRUE;
+             eng_window_use(re->win);
+          }
+     }
+   else
+      eng_window_use(re->win);
+
+   evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
+   re->win->gl_context->dc = context;
+   evas_gl_common_rect_draw(re->win->gl_context, x, y, w, h);
 }
 
-static void *
-eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
+static void
+eng_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2)
 {
    Render_Engine *re;
 
    re = (Render_Engine *)data;
-   eng_window_use(re->win);
-   return evas_gl_common_image_new_from_data(re->win->gl_context, w, h, image_data, alpha, cspace);
+
+   if (re->context_optimize)
+     {
+        if (!re->context_current)
+          {
+             re->context_current = EINA_TRUE;
+             eng_window_use(re->win);
+          }
+     }
+   else
+      eng_window_use(re->win);
+
+   evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
+   re->win->gl_context->dc = context;
+   evas_gl_common_line_draw(re->win->gl_context, x1, y1, x2, y2);
 }
 
 static void *
-eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
+eng_polygon_point_add(void *data, void *context __UNUSED__, void *polygon, int x, int y)
 {
    Render_Engine *re;
 
    re = (Render_Engine *)data;
-   eng_window_use(re->win);
-   return evas_gl_common_image_new_from_copied_data(re->win->gl_context, w, h, image_data, alpha, cspace);
+   return evas_gl_common_poly_point_add(polygon, x, y);
 }
 
-static void
-eng_image_free(void *data, void *image)
+static void *
+eng_polygon_points_clear(void *data, void *context __UNUSED__, void *polygon)
 {
    Render_Engine *re;
 
    re = (Render_Engine *)data;
-   if (!image) return;
-   eng_window_use(re->win);
-   evas_gl_common_image_free(image);
+   return evas_gl_common_poly_points_clear(polygon);
 }
 
 static void
-eng_image_size_get(void *data __UNUSED__, void *image, int *w, int *h)
-{
-   if (!image)
-     {
-        *w = 0;
-        *h = 0;
-        return;
-     }
-   if (w) *w = ((Evas_GL_Image *)image)->w;
-   if (h) *h = ((Evas_GL_Image *)image)->h;
-}
-
-static void *
-eng_image_size_set(void *data, void *image, int w, int h)
+eng_polygon_draw(void *data, void *context, void *surface __UNUSED__, void *polygon, int x, int y)
 {
    Render_Engine *re;
-   Evas_GL_Image *im = image;
-   Evas_GL_Image *im_old;
 
    re = (Render_Engine *)data;
-   if (!im) return NULL;
-   if (im->native.data)
+
+   if (re->context_optimize)
      {
-        im->w = w;
-        im->h = h;
-        return image;
-     }
-   eng_window_use(re->win);
-   if ((im->tex) && (im->tex->pt->dyn.img))
-     {
-        evas_gl_common_texture_free(im->tex);
-        im->tex = NULL;
-        im->w = w;
-        im->h = h;
-        im->tex = evas_gl_common_texture_dynamic_new(im->gc, im);
-        return image;
+        if (!re->context_current)
+          {
+             re->context_current = EINA_TRUE;
+             eng_window_use(re->win);
+          }
      }
-   im_old = image;
+   else
+      eng_window_use(re->win);
 
-   switch (eng_image_colorspace_get(data, image))
-     {
-      case EVAS_COLORSPACE_YCBCR422P601_PL:
-      case EVAS_COLORSPACE_YCBCR422P709_PL:
-      case EVAS_COLORSPACE_YCBCR422601_PL:
-      case EVAS_COLORSPACE_YCBCR420NV12601_PL:
-      case EVAS_COLORSPACE_YCBCR420TM12601_PL:
-         w &= ~0x1;
-         break;
-     }
+   evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
+   re->win->gl_context->dc = context;
+   evas_gl_common_poly_draw(re->win->gl_context, polygon, x, y);
+}
 
-   if ((im_old) &&
-       ((int)im_old->im->cache_entry.w == w) &&
-       ((int)im_old->im->cache_entry.h == h))
-     return image;
-   if (im_old)
-     {
-        im = evas_gl_common_image_new(re->win->gl_context, w, h,
-                                      eng_image_alpha_get(data, image),
-                                      eng_image_colorspace_get(data, image));
-        /*
-       evas_common_load_image_data_from_file(im_old->im);
-       if (im_old->im->image->data)
-         {
-            evas_common_blit_rectangle(im_old->im, im->im, 0, 0, w, h, 0, 0);
-            evas_common_cpu_end_opt();
-         }
- */
-        evas_gl_common_image_free(im_old);
-     }
-   else
-     im = evas_gl_common_image_new(re->win->gl_context, w, h, 1, EVAS_COLORSPACE_ARGB8888);
-   return im;
+static int
+eng_image_alpha_get(void *data __UNUSED__, void *image)
+{
+//   Render_Engine *re;
+   Evas_GL_Image *im;
+
+//   re = (Render_Engine *)data;
+   if (!image) return 1;
+   im = image;
+   return im->alpha;
 }
 
-static void *
-eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h)
+static int
+eng_image_colorspace_get(void *data __UNUSED__, void *image)
 {
-   Render_Engine *re;
-   Evas_GL_Image *im = image;
+//   Render_Engine *re;
+   Evas_GL_Image *im;
 
-   re = (Render_Engine *)data;
-   if (!image) return NULL;
-   if (im->native.data) return image;
-   eng_window_use(re->win);
-   evas_gl_common_image_dirty(image, x, y, w, h);
-   return image;
+//   re = (Render_Engine *)data;
+   if (!image) return EVAS_COLORSPACE_ARGB8888;
+   im = image;
+   return im->cs.space;
 }
 
+static void
+eng_image_mask_create(void *data __UNUSED__, void *image)
+{
+   Evas_GL_Image *im;
+
+   if (!image) return;
+   im = image;
+   if (!im->im->image.data)
+      evas_cache_image_load_data(&im->im->cache_entry);
+   if (!im->tex)
+      im->tex = evas_gl_common_texture_new(im->gc, im->im);
+}
+
+
 static void *
-eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, int *err)
+eng_image_alpha_set(void *data, void *image, int has_alpha)
 {
    Render_Engine *re;
    Evas_GL_Image *im;
-   int error;
 
    re = (Render_Engine *)data;
-   if (!image)
-     {
-        *image_data = NULL;
-        if (err) *err = EVAS_LOAD_ERROR_GENERIC;
-        return NULL;
-     }
+   if (!image) return NULL;
    im = image;
+   if (im->alpha == has_alpha) return image;
    if (im->native.data)
      {
-        *image_data = NULL;
-        if (err) *err = EVAS_LOAD_ERROR_NONE;
-        return im;
+        im->alpha = has_alpha;
+        return image;
      }
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
    eng_window_use(re->win);
-
-   if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.img) && (im->cs.space == EVAS_COLORSPACE_ARGB8888))
+   if ((im->tex) && (im->tex->pt->dyn.img))
      {
-        if (im->tex->pt->dyn.checked_out > 0)
-          {
-             im->tex->pt->dyn.checked_out++;
-             *image_data = im->tex->pt->dyn.data;
-             if (err) *err = EVAS_LOAD_ERROR_NONE;
-             return im;
-          }
-        *image_data = im->tex->pt->dyn.data = glsym_eglMapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img);
-
-        if (!im->tex->pt->dyn.data)
-          {
-             if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
-             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-             return im;
-          }
-        im->tex->pt->dyn.checked_out++;
-
-        if (err) *err = EVAS_LOAD_ERROR_NONE;
-        return im;
+        im->alpha = has_alpha;
+        im->tex->alpha = im->alpha;
+        return image;
      }
-#else
-   if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data))
+   /* FIXME: can move to gl_common */
+   if (im->cs.space != EVAS_COLORSPACE_ARGB8888) return im;
+   if ((has_alpha) && (im->im->cache_entry.flags.alpha)) return image;
+   else if ((!has_alpha) && (!im->im->cache_entry.flags.alpha)) return image;
+   if (im->references > 1)
      {
-        *image_data = im->tex->pt->dyn.data;
-        if (err) *err = EVAS_LOAD_ERROR_NONE;
-        return im;
+        Evas_GL_Image *im_new;
+
+        if (!im->im->image.data)
+          evas_cache_image_load_data(&im->im->cache_entry);
+        evas_gl_common_image_alloc_ensure(im);
+        im_new = evas_gl_common_image_new_from_copied_data
+           (im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
+               im->im->image.data,
+               eng_image_alpha_get(data, image),
+               eng_image_colorspace_get(data, image));
+        if (!im_new) return im;
+        evas_gl_common_image_free(im);
+        im = im_new;
      }
+   else
+     evas_gl_common_image_dirty(im, 0, 0, 0, 0);
+   return evas_gl_common_image_alpha_set(im, has_alpha ? 1 : 0);
+//   im->im->cache_entry.flags.alpha = has_alpha ? 1 : 0;
+//   return image;
+}
 
-   eng_window_use(re->win);
-#endif
+static void *
+eng_image_border_set(void *data __UNUSED__, void *image, int l __UNUSED__, int r __UNUSED__, int t __UNUSED__, int b __UNUSED__)
+{
+//   Render_Engine *re;
+//
+//   re = (Render_Engine *)data;
+   return image;
+}
 
-   /* Engine can be fail to create texture after cache drop like eng_image_content_hint_set function,
-        so it is need to add code which check im->im's NULL value*/
+static void
+eng_image_border_get(void *data __UNUSED__, void *image __UNUSED__, int *l __UNUSED__, int *r __UNUSED__, int *t __UNUSED__, int *b __UNUSED__)
+{
+//   Render_Engine *re;
+//
+//   re = (Render_Engine *)data;
+}
 
-   if (!im->im)
-    {
-       *image_data = NULL;
-       if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
-       return NULL;
-    }
+static char *
+eng_image_comment_get(void *data __UNUSED__, void *image, char *key __UNUSED__)
+{
+//   Render_Engine *re;
+   Evas_GL_Image *im;
 
-   error = evas_cache_image_load_data(&im->im->cache_entry);
-   switch (im->cs.space)
+//   re = (Render_Engine *)data;
+   if (!image) return NULL;
+   im = image;
+   if (!im->im) return NULL;
+   return im->im->info.comment;
+}
+
+static char *
+eng_image_format_get(void *data __UNUSED__, void *image)
+{
+//   Render_Engine *re;
+   Evas_GL_Image *im;
+
+//   re = (Render_Engine *)data;
+   im = image;
+   return NULL;
+}
+
+static void
+eng_image_colorspace_set(void *data, void *image, int cspace)
+{
+   Render_Engine *re;
+   Evas_GL_Image *im;
+
+   re = (Render_Engine *)data;
+   if (!image) return;
+   im = image;
+   if (im->native.data) return;
+   /* FIXME: can move to gl_common */
+   if (im->cs.space == cspace) return;
+   eng_window_use(re->win);
+   evas_gl_common_image_alloc_ensure(im);
+   evas_cache_image_colorspace(&im->im->cache_entry, cspace);
+   switch (cspace)
      {
       case EVAS_COLORSPACE_ARGB8888:
-         if (to_write)
+         if (im->cs.data)
            {
-              if (im->references > 1)
-                {
-                   Evas_GL_Image *im_new;
-
-                   im_new = evas_gl_common_image_new_from_copied_data
-                      (im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
-                       im->im->image.data,
-                       eng_image_alpha_get(data, image),
-                       eng_image_colorspace_get(data, image));
-                   if (!im_new)
-                     {
-                        *image_data = NULL;
-                        if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
-                        return NULL;
-                     }
-                   evas_gl_common_image_free(im);
-                   im = im_new;
-                }
-              else
-                evas_gl_common_image_dirty(im, 0, 0, 0, 0);
+              if (!im->cs.no_free) free(im->cs.data);
+              im->cs.data = NULL;
+              im->cs.no_free = 0;
            }
-         *image_data = im->im->image.data;
          break;
       case EVAS_COLORSPACE_YCBCR422P601_PL:
       case EVAS_COLORSPACE_YCBCR422P709_PL:
       case EVAS_COLORSPACE_YCBCR422601_PL:
       case EVAS_COLORSPACE_YCBCR420NV12601_PL:
       case EVAS_COLORSPACE_YCBCR420TM12601_PL:
-         *image_data = im->cs.data;
-         break;
-      default:
-         abort();
+         if (im->tex) evas_gl_common_texture_free(im->tex);
+         im->tex = NULL;
+         if (im->cs.data)
+           {
+              if (!im->cs.no_free) free(im->cs.data);
+           }
+         if (im->im->cache_entry.h > 0)
+           im->cs.data =
+              calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
+         else
+           im->cs.data = NULL;
+         im->cs.no_free = 0;
+         break;
+      default:
+         abort();
          break;
      }
-   if (err) *err = error;
-   return im;
+   im->cs.space = cspace;
 }
 
-static void *
-eng_image_data_put(void *data, void *image, DATA32 *image_data)
+/////////////////////////////////////////////////////////////////////////
+//
+//
+typedef struct _Native Native;
+
+struct _Native
 {
-   Render_Engine *re;
-   Evas_GL_Image *im, *im2;
+   Evas_Native_Surface ns;
+   Pixmap     pixmap;
+   Visual    *visual;
+   void      *buffer;
+   unsigned int recreate : 1;
 
-   re = (Render_Engine *)data;
-   if (!image) return NULL;
-   im = image;
-   if (im->native.data) return image;
-   eng_window_use(re->win);
-   if ((im->tex) && (im->tex->pt)
-       && (im->tex->pt->dyn.data)
-       && (im->cs.space == EVAS_COLORSPACE_ARGB8888))
-     {
-        if (im->tex->pt->dyn.data == image_data)
-          {
-             if (im->tex->pt->dyn.checked_out > 0)
-               {
-                 im->tex->pt->dyn.checked_out--;
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-                 if (im->tex->pt->dyn.checked_out == 0)
-                   glsym_eglUnmapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img);
+   void      *config;
+   void      *surface;
+};
+
+// FIXME: this is enabled so updates happen - but its SLOOOOOOOOOOOOOOOW
+// (i am sure this is the reason)  not to mention seemingly superfluous. but
+// i need to enable it for it to work on fglrx at least. havent tried nvidia.
+//
+// why is this the case? does anyone know? has anyone tried it on other gfx
+// drivers?
+//
+//#define GLX_TEX_PIXMAP_RECREATE 1
+
+static void
+_native_bind_cb(void *data, void *image)
+{
+   Evas_GL_Image *im = image;
+   Native *n = im->native.data;
+   int err;
+
+  if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
+    {
+#ifdef GL_GLES
+      if (n->surface)
+        {
+           Render_Engine *re = data;
+           if ((n->recreate) && (re->is_compositor == EINA_TRUE))
+             {
+                if (glsym_eglDestroyImage)
+                  {
+                     glsym_eglDestroyImage(re->win->egl_disp, n->surface);
+                     if ((err = eglGetError()) != EGL_SUCCESS)
+                       {
+                          ERR("eglDestroyImage() failed.");
+                          _evgl_error_set(err - EGL_SUCCESS);
+                       }
+                  }
+                else
+                  ERR("Try eglDestroyImage on EGL with no support");
+                if (glsym_eglCreateImage)
+                  {
+                     n->surface = glsym_eglCreateImage(re->win->egl_disp,
+                                                           EGL_NO_CONTEXT,
+                                                           EGL_NATIVE_PIXMAP_KHR,
+                                                           (void *)n->pixmap,
+                                                           NULL);
+                     if (!n->surface)
+                       ERR("eglCreateImage() for 0x%x failed", (unsigned int)n->pixmap);
+                  }
+                else
+                  ERR("Try eglCreateImage on EGL with no support");
+             }
+           if (glsym_glEGLImageTargetTexture2DOES)
+             {
+                glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->surface);
+                if ((err = eglGetError()) != EGL_SUCCESS)
+                  {
+                     ERR("glEGLImageTargetTexture2DOES() failed.");
+                     _evgl_error_set(err - EGL_SUCCESS);
+                  }
+             }
+           else
+             ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
+        }
+#else
+# ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
+      Render_Engine *re = data;
+
+      if (glsym_glXBindTexImage)
+        {
+          glsym_glXBindTexImage(re->win->disp, (XID)n->surface,
+                                GLX_FRONT_LEFT_EXT, NULL);
+          GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        }
+      else
+        ERR("Try glXBindTexImage on GLX with no support");
+# endif
 #endif
-               }
+    }
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
+    {
+      glBindTexture(GL_TEXTURE_2D, n->ns.data.opengl.texture_id);
+      GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+    }
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_TIZEN)
+    {
+#ifdef GL_GLES
+#ifdef HAVE_NATIVE_BUFFER
+      if (n->egl_surface)
+            {
+               if (n->recreate)
+                 {
+                    Render_Engine *re = data;
+                    if (glsym_eglDestroyImage)
+                      {
+                         glsym_eglDestroyImage(re->win->egl_disp, n->egl_surface);
+                         if ((err = eglGetError()) != EGL_SUCCESS)
+                           {
+                              ERR("eglDestroyImage() failed.");
+                              _evgl_error_set(err - EGL_SUCCESS);
+                           }
+                      }
+                    else
+                      ERR("Try eglDestroyImage on EGL with no support");
+                    if (glsym_eglCreateImage)
+                      {
+                         int attr[] =
+                           {
+                             EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
+                             EGL_NONE,
+                           };
+                         n->egl_surface = glsym_eglCreateImage(re->win->egl_disp,
+                                                               EGL_NO_CONTEXT,
+                                                               EGL_NATIVE_BUFFER_TIZEN,
+                                                               (void *)n->buffer,
+                                                               attr);
+                         if (!n->egl_surface)
+                           ERR("eglCreateImage() for 0x%x failed", (unsigned int)n->buffer);
+                      }
+                    else
+                      ERR("Try eglCreateImage on EGL with no support");
+                 }
+               if (glsym_glEGLImageTargetTexture2DOES)
+                 {
+                    glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, n->egl_surface);
+                    if ((err = eglGetError()) != EGL_SUCCESS)
+                      {
+                         ERR("glEGLImageTargetTexture2DOES() failed.");
+                         _evgl_error_set(err - EGL_SUCCESS);
+                      }
+                 }
+               else
+                 ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
+            }
+#endif
+#endif
+    }
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_TBM)
+    {
+       if (n->surface)
+         {
+            if (n->recreate)
+              {
+                 Render_Engine *re = data;
+                 if (glsym_eglDestroyImage)
+                   {
+                      glsym_eglDestroyImage(re->win->egl_disp, n->surface);
+                      if ((err = eglGetError()) != EGL_SUCCESS)
+                        {
+                           ERR("eglDestroyImage() failed.");
+                           _evgl_error_set(err - EGL_SUCCESS);
+                        }
+                   }
+                 else
+                   ERR("Try eglDestroyImage on EGL with no support");
+                 if (glsym_eglCreateImage)
+                   {
+                      int attr[] =
+                        {
+                          EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
+                          EGL_NONE,
+                        };
+                      n->surface = glsym_eglCreateImage(re->win->egl_disp,
+                                                            EGL_NO_CONTEXT,
+                                                            EGL_NATIVE_SURFACE_TIZEN,
+                                                            (void *)n->buffer,
+                                                            attr);
+                      if (!n->surface)
+                        ERR("eglCreateImage() for %p failed", n->buffer);
+                   }
+                 else
+                   ERR("Try eglCreateImage on EGL with no support");
+              }
+            if (glsym_glEGLImageTargetTexture2DOES)
+              {
+                 glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, n->surface);
+                 if ((err = eglGetError()) != EGL_SUCCESS)
+                   {
+                      ERR("glEGLImageTargetTexture2DOES() failed.");
+                      _evgl_error_set(err - EGL_SUCCESS);
+                   }
+              }
+            else
+              ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
+         }
+      }
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
+    {
+#ifdef GL_GLES
+       if (n->surface)
+         {
+            void *surface = glsym_evgl_native_surface_buffer_get(n->surface);
+            if (glsym_glEGLImageTargetTexture2DOES)
+              {
+                 glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, surface);
+                 if ((err = eglGetError()) != EGL_SUCCESS)
+                   {
+                      ERR("glEGLImageTargetTexture2DOES() failed.");
+                      _evgl_error_set(err - EGL_SUCCESS);
+                   }
+              }
+            else
+              ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
+         }
+#endif
+      }
 
-             return image;
-          }
-        im2 = eng_image_new_from_data(data, im->w, im->h, image_data,
-                                      eng_image_alpha_get(data, image),
-                                      eng_image_colorspace_get(data, image));
-        if (!im2) return im;
-        evas_gl_common_image_free(im);
-        im = im2;
-        evas_gl_common_image_dirty(im, 0, 0, 0, 0);
-        return im;
-     }
-   switch (im->cs.space)
-     {
-      case EVAS_COLORSPACE_ARGB8888:
-         if ((!im->im) || (image_data != im->im->image.data))
-           {
-              im2 = eng_image_new_from_data(data, im->w, im->h, image_data,
-                                            eng_image_alpha_get(data, image),
-                                            eng_image_colorspace_get(data, image));
-              if (!im2) return im;
-              evas_gl_common_image_free(im);
-              im = im2;
-           }
-         break;
-      case EVAS_COLORSPACE_YCBCR422P601_PL:
-      case EVAS_COLORSPACE_YCBCR422P709_PL:
-      case EVAS_COLORSPACE_YCBCR422601_PL:
-      case EVAS_COLORSPACE_YCBCR420NV12601_PL:
-      case EVAS_COLORSPACE_YCBCR420TM12601_PL:
-         if (image_data != im->cs.data)
-           {
-              if (im->cs.data)
-                {
-                   if (!im->cs.no_free) free(im->cs.data);
-                }
-              im->cs.data = image_data;
-           }
-         evas_gl_common_image_dirty(im, 0, 0, 0, 0);
-         break;
-      default:
-         abort();
-         break;
-     }
-   return im;
+   return;
+   data = NULL;
 }
 
 static void
-eng_image_data_preload_request(void *data __UNUSED__, void *image, const void *target)
+_native_unbind_cb(void *data, void *image)
 {
-   Evas_GL_Image *gim = image;
-   RGBA_Image *im;
+  Evas_GL_Image *im = image;
+  Native *n = im->native.data;
 
-   if (!gim) return;
-   if (gim->native.data) return;
-   im = (RGBA_Image *)gim->im;
-   if (!im) return;
-   evas_cache_image_preload_data(&im->cache_entry, target);
+  if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
+    {
+#ifdef GL_GLES
+      // nothing
+#else
+# ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
+      Render_Engine *re = data;
+
+      if (glsym_glXReleaseTexImage)
+        {
+          glsym_glXReleaseTexImage(re->win->disp, (XID)n->surface,
+                                   GLX_FRONT_LEFT_EXT);
+          GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        }
+      else
+        ERR("Try glXReleaseTexImage on GLX with no support");
+# endif
+#endif
+    }
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
+    {
+      glBindTexture(GL_TEXTURE_2D, 0);
+      GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+    }
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_TIZEN)
+    {
+      // nothing
+    }
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_TBM)
+    {
+      // nothing
+    }
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
+    {
+      // nothing
+    }
+
+   return;
+   data = NULL;
+}
+
+static void
+_native_free_cb(void *data, void *image)
+{
+  Render_Engine *re = data;
+  Evas_GL_Image *im = image;
+  Native *n = im->native.data;
+  uint32_t pmid, texid;
+  int err;
+
+  if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
+    {
+      pmid = n->pixmap;
+      eina_hash_del(re->win->gl_context->shared->native_pm_hash, &pmid, im);
+#ifdef GL_GLES
+      if (n->surface)
+        {
+          if (glsym_eglDestroyImage)
+            {
+              glsym_eglDestroyImage(re->win->egl_disp,
+                                    n->surface);
+              if ((err = eglGetError()) != EGL_SUCCESS)
+                {
+                  ERR("eglDestroyImage() failed.");
+                  _evgl_error_set(err - EGL_SUCCESS);
+                }
+            }
+          else
+            ERR("Try eglDestroyImage on EGL with no support");
+        }
+#else
+# ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
+      if (n->surface)
+        {
+          if (im->native.loose)
+            {
+              if (glsym_glXReleaseTexImage)
+                {
+                  glsym_glXReleaseTexImage(re->win->disp, (XID)n->surface,
+                                           GLX_FRONT_LEFT_EXT);
+                  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                }
+              else
+                ERR("Try glXReleaseTexImage on GLX with no support");
+            }
+          if (glsym_glXDestroyPixmap)
+            {
+              glsym_glXDestroyPixmap(re->win->disp, n->glx_pixmap);
+              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+            }
+          else
+            ERR("Try glXDestroyPixmap on GLX with no support");
+          n->glx_pixmap = 0;
+        }
+# endif
+#endif
+    }
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
+    {
+      texid = n->ns.data.opengl.texture_id;
+      eina_hash_del(re->win->gl_context->shared->native_tex_hash, &texid, im);
+    }
+#ifdef GL_GLES
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_TIZEN)
+    {
+      eina_hash_del(re->win->gl_context->shared->native_buffer_hash, &n->buffer, im);
+      if (n->surface)
+        {
+          if (glsym_eglDestroyImage)
+            {
+              glsym_eglDestroyImage(re->win->egl_disp,
+                                    n->surface);
+              if ((err = eglGetError()) != EGL_SUCCESS)
+                {
+                  ERR("eglDestroyImage() failed.");
+                  _evgl_error_set(err - EGL_SUCCESS);
+                }
+            }
+          else
+            ERR("Try eglDestroyImage on EGL with no support");
+        }
+        }
+#endif
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_TBM)
+    {
+      eina_hash_del(re->win->gl_context->shared->native_tbm_hash, &n->buffer, im);
+      if (n->surface)
+        {
+          if (glsym_eglDestroyImage)
+            {
+              glsym_eglDestroyImage(re->win->egl_disp,
+                                    n->surface);
+              if ((err = eglGetError()) != EGL_SUCCESS)
+                {
+                  ERR("eglDestroyImage() failed.");
+                  _evgl_error_set(err - EGL_SUCCESS);
+                }
+            }
+          else
+            ERR("Try eglDestroyImage on EGL with no support");
+        }
+    }
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
+    {
+      eina_hash_del(re->win->gl_context->shared->native_evasgl_hash, &n->ns.data.evasgl.surface, im);
+    }
+
+  im->native.data        = NULL;
+  im->native.func.data   = NULL;
+  im->native.func.bind   = NULL;
+  im->native.func.unbind = NULL;
+  im->native.func.free   = NULL;
+  free(n);
+}
+
+static int
+_native_yinvert_cb(void *data, void *image)
+{
+   Render_Engine *re = data;
+   Evas_GL_Image *im = image;
+   Native *n = im->native.data;
+   int yinvert = 0, val;
+
+   // Yinvert callback should only be used for EVAS_NATIVE_SURFACE_EVASGL type now,
+   // as yinvert value is not changed for other types.
+   if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
+     {
+#if GL_GLES
+        if (extn_have_y_inverted &&
+            eglGetConfigAttrib(re->win->egl_disp, n->config,
+                               EGL_Y_INVERTED_NOK, &val))
+          yinvert = val;
+#else
+        glXGetFBConfigAttrib(re->win->egl_disp, n->config,
+                             GLX_Y_INVERTED_EXT, &val);
+          yinvert = val;
+#endif
+     }
+   else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
+     {
+        yinvert = 0;
+     }
+   else if (n->ns.type == EVAS_NATIVE_SURFACE_TBM)
+     {
+        yinvert = 1;
+     }
+   else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
+     {
+        yinvert = glsym_evgl_native_surface_yinvert_get(n->surface);
+     }
+
+   return yinvert;
+}
+
+static void *
+eng_image_native_set(void *data, void *image, void *native)
+{
+  Render_Engine *re = (Render_Engine *)data;
+  Evas_Native_Surface *ns = native;
+  Evas_GL_Image *im = image, *im2 = NULL;
+  Visual *vis = NULL;
+  Pixmap pm = 0;
+  Native *n = NULL;
+  uint32_t pmid, texid;
+  unsigned int tex = 0;
+  unsigned int fbo = 0;
+  void *buffer = NULL;
+  int err;
+
+  if (!im)
+    {
+       if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_OPENGL))
+         {
+            im = evas_gl_common_image_new_from_data(re->win->gl_context,
+                                                    ns->data.opengl.w,
+                                                    ns->data.opengl.h,
+                                                    NULL, 1,
+                                                    EVAS_COLORSPACE_ARGB8888);
+         }
+       else
+         return NULL;
+    }
+
+  if (ns)
+    {
+      if (ns->type == EVAS_NATIVE_SURFACE_X11)
+        {
+          vis = ns->data.x11.visual;
+          pm = ns->data.x11.pixmap;
+          if (im->native.data)
+            {
+              Native *ens = im->native.data;
+              if ((ens->ns.data.x11.visual == vis) &&
+                  (ens->ns.data.x11.pixmap == pm))
+                return im;
+            }
+        }
+      else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
+        {
+          tex = ns->data.opengl.texture_id;
+          fbo = ns->data.opengl.framebuffer_id;
+          if (im->native.data)
+            {
+              Native *ens = im->native.data;
+              if ((ens->ns.data.opengl.texture_id == tex) &&
+                  (ens->ns.data.opengl.framebuffer_id == fbo))
+                return im;
+            }
+        }
+#ifdef HAVE_NATIVE_BUFFER
+      else if (ns->type == EVAS_NATIVE_SURFACE_TIZEN)
+        {
+           buffer = ns->data.tizen.buffer;
+           if (im->native.data)
+             {
+                Native *ens = im->native.data;
+                if (ens->ns.data.tizen.buffer == buffer)
+                  {
+                     ens->ns.data.tizen.rot = im->native.rot = ns->data.tizen.rot;
+                     ens->ns.data.tizen.ratio = im->native.ratio = ns->data.tizen.ratio;
+                     ens->ns.data.tizen.flip = im->native.flip = ns->data.tizen.flip;
+                     return im;
+                  }
+             }
+        }
+#endif
+      else if (ns->type == EVAS_NATIVE_SURFACE_TBM)
+        {
+           buffer = ns->data.tizen.buffer;
+           if (im->native.data)
+             {
+                Native *ens = im->native.data;
+                if (ens->ns.data.tizen.buffer == buffer)
+                  {
+                     ens->ns.data.tizen.rot = im->native.rot = ns->data.tizen.rot;
+                     ens->ns.data.tizen.ratio = im->native.ratio = ns->data.tizen.ratio;
+                     ens->ns.data.tizen.flip = im->native.flip = ns->data.tizen.flip;
+                     return im;
+                  }
+             }
+        }
+      else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
+        {
+           buffer = ns->data.evasgl.surface;
+           if (im->native.data)
+             {
+                Native *ens = im->native.data;
+                if (ens->ns.data.evasgl.surface == buffer)
+                  return im;
+             }
+        }
+    }
+  if ((!ns) && (!im->native.data)) return im;
+
+  eng_window_use(re->win);
+
+  if (im->native.data)
+    {
+      if (im->native.func.free)
+        im->native.func.free(im->native.func.data, im);
+      evas_gl_common_image_native_disable(im);
+    }
+
+  if (!ns) return im;
+
+  if (ns->type == EVAS_NATIVE_SURFACE_X11)
+    {
+      pmid = pm;
+      im2 = eina_hash_find(re->win->gl_context->shared->native_pm_hash, &pmid);
+      if (im2 == im) return im;
+      if (im2)
+        {
+           n = im2->native.data;
+           if (n)
+             {
+                evas_gl_common_image_ref(im2);
+                evas_gl_common_image_free(im);
+                return im2;
+             }
+        }
+    }
+  else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
+    {
+       texid = tex;
+       im2 = eina_hash_find(re->win->gl_context->shared->native_tex_hash, &texid);
+       if (im2 == im) return im;
+       if (im2)
+         {
+            n = im2->native.data;
+            if (n)
+              {
+                 evas_gl_common_image_ref(im2);
+                 evas_gl_common_image_free(im);
+                 return im2;
+              }
+         }
+
+    }
+#ifdef HAVE_NATIVE_BUFFER
+  else if (ns->type == EVAS_NATIVE_SURFACE_TIZEN)
+    {
+       im2 = eina_hash_find(re->win->gl_context->shared->native_buffer_hash, &buffer);
+       if (im2 == im) return im;
+       if (im2)
+         {
+            n = im2->native.data;
+            if (n)
+             {
+                evas_gl_common_image_ref(im2);
+                evas_gl_common_image_free(im);
+                return im2;
+             }
+        }
+    }
+#endif
+  else if (ns->type == EVAS_NATIVE_SURFACE_TBM)
+    {
+       im2 = eina_hash_find(re->win->gl_context->shared->native_tbm_hash, &buffer);
+       if (im2 == im) return im;
+       if (im2)
+         {
+            n = im2->native.data;
+            if (n)
+             {
+                evas_gl_common_image_ref(im2);
+                evas_gl_common_image_free(im);
+                return im2;
+             }
+        }
+    }
+  else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
+    {
+       im2 = eina_hash_find(re->win->gl_context->shared->native_evasgl_hash, &buffer);
+       if (im2 == im) return im;
+       if (im2)
+         {
+            n = im2->native.data;
+            if (n)
+             {
+                evas_gl_common_image_ref(im2);
+                evas_gl_common_image_free(im);
+                return im2;
+             }
+        }
+    }
+  im2 = evas_gl_common_image_new_from_data(re->win->gl_context,
+                                           im->w, im->h, NULL, im->alpha,
+                                           EVAS_COLORSPACE_ARGB8888);
+  evas_gl_common_image_free(im);
+  im = im2;
+  if (!im) return NULL;
+  if (ns->type == EVAS_NATIVE_SURFACE_X11)
+    {
+#ifdef GL_GLES
+      if (native)
+        {
+          n = calloc(1, sizeof(Native));
+          if (n)
+            {
+              EGLConfig egl_config;
+              int config_attrs[20];
+              int num_config, i = 0;
+              const char *vendor;
+              int yinvert = 1;
+
+              eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im);
+
+              // assume 32bit pixmap! :)
+              config_attrs[i++] = EGL_RED_SIZE;
+              config_attrs[i++] = 8;
+              config_attrs[i++] = EGL_GREEN_SIZE;
+              config_attrs[i++] = 8;
+              config_attrs[i++] = EGL_BLUE_SIZE;
+              config_attrs[i++] = 8;
+              config_attrs[i++] = EGL_ALPHA_SIZE;
+              config_attrs[i++] = 8;
+              config_attrs[i++] = EGL_DEPTH_SIZE;
+              config_attrs[i++] = 0;
+              config_attrs[i++] = EGL_STENCIL_SIZE;
+              config_attrs[i++] = 0;
+              config_attrs[i++] = EGL_RENDERABLE_TYPE;
+              config_attrs[i++] = EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES_BIT;
+              config_attrs[i++] = EGL_SURFACE_TYPE;
+              config_attrs[i++] = EGL_PIXMAP_BIT;
+              config_attrs[i++] = EGL_NONE;
+
+              if (!eglChooseConfig(re->win->egl_disp, config_attrs,
+                                   &egl_config, 1, &num_config))
+                {
+                  err = eglGetError();
+                  ERR("eglChooseConfig() failed for pixmap 0x%x, num_config = %i with error %d",
+                                                         (unsigned int)pm, num_config, err);
+                  _evgl_error_set(err - EGL_SUCCESS);
+                }
+              else
+                {
+                  int val;
+                  if (extn_have_y_inverted &&
+                      eglGetConfigAttrib(re->win->egl_disp, egl_config,
+                                         EGL_Y_INVERTED_NOK, &val))
+                        yinvert = val;
+                }
+
+              memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
+              n->pixmap = pm;
+              n->visual = vis;
+              if (glsym_eglCreateImage)
+                n->surface = glsym_eglCreateImage(re->win->egl_disp,
+                                                      EGL_NO_CONTEXT,
+                                                      EGL_NATIVE_PIXMAP_KHR,
+                                                      (void *)pm,
+                                                      NULL);
+              else
+                ERR("Try eglCreateImage on EGL with no support");
+              if (!n->surface)
+                ERR("eglCreateImage() for 0x%x failed", (unsigned int)pm);
+              vendor = (const char *)glGetString(GL_VENDOR);
+              if (vendor && strstr (vendor, "Qualcomm") != NULL)
+                n->recreate = 1;
+              n->config = (void *)egl_config;
+
+              im->native.yinvert     = yinvert;
+              im->native.loose       = 0;
+              im->native.data        = n;
+              im->native.func.data   = re;
+              im->native.func.bind   = _native_bind_cb;
+              im->native.func.unbind = _native_unbind_cb;
+              im->native.func.free   = _native_free_cb;
+              im->native.target      = GL_TEXTURE_2D;
+              im->native.mipmap      = 0;
+              evas_gl_common_image_native_enable(im);
+            }
+        }
+#else
+# ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
+       if (native)
+         {
+            int dummy;
+            unsigned int w, h, depth = 32, border;
+            Window wdummy;
+
+            // fixme: round trip :(
+            XGetGeometry(re->win->disp, pm, &wdummy, &dummy, &dummy,
+                         &w, &h, &border, &depth);
+            if (depth <= 32)
+              {
+                 n = calloc(1, sizeof(Native));
+                 if (n)
+                   {
+                      int pixmap_att[20], i;
+                      int config_attrs[40], num = 0;
+                      int tex_format = 0, tex_target = 0, yinvert = 0, mipmap = 0;
+                      unsigned int target = 0;
+                      GLXFBConfig *configs;
+
+                      i = 0;
+                      config_attrs[i++] = GLX_BUFFER_SIZE;
+                      config_attrs[i++] = depth;
+                      if (depth == 32)
+                        {
+                           config_attrs[i++] = GLX_BIND_TO_TEXTURE_RGBA_EXT;
+                           config_attrs[i++] = 1;
+                        }
+                      else
+                        {
+                           config_attrs[i++] = GLX_BIND_TO_TEXTURE_RGB_EXT;
+                           config_attrs[i++] = 1;
+                        }
+
+#ifndef GLX_VISUAL_ID
+# define GLX_VISUAL_ID 0x800b
+#endif
+                      config_attrs[i++] = GLX_VISUAL_ID;
+                      config_attrs[i++] = XVisualIDFromVisual(vis);
+#ifndef GLX_SAMPLE_BUFFERS
+# define GLX_SAMPLE_BUFFERS 0x186a0
+#endif
+                      config_attrs[i++] = GLX_SAMPLE_BUFFERS;
+                      config_attrs[i++] = 0;
+                      config_attrs[i++] = GLX_DEPTH_SIZE;
+                      config_attrs[i++] = 0;
+                      config_attrs[i++] = GLX_STENCIL_SIZE;
+                      config_attrs[i++] = 0;
+                      config_attrs[i++] = GLX_AUX_BUFFERS;
+                      config_attrs[i++] = 0;
+                      config_attrs[i++] = GLX_STEREO;
+                      config_attrs[i++] = 0;
+
+                      config_attrs[i++] = 0;
+
+                      configs = glXChooseFBConfig(re->win->disp,
+                                                  re->win->screen,
+                                                  config_attrs,
+                                                  &num);
+                      if (configs)
+                        {
+                           int j = 0, val = 0;
+
+                           tex_format = GLX_TEXTURE_FORMAT_RGB_EXT;
+                           glXGetFBConfigAttrib(re->win->disp, configs[j],
+                                                GLX_ALPHA_SIZE, &val);
+                           if (val > 0)
+                             {
+                                glXGetFBConfigAttrib(re->win->disp, configs[j],
+                                                     GLX_BIND_TO_TEXTURE_RGBA_EXT, &val);
+                                if (val) tex_format = GLX_TEXTURE_FORMAT_RGBA_EXT;
+                             }
+                           else
+                             {
+                                glXGetFBConfigAttrib(re->win->disp, configs[j],
+                                                     GLX_BIND_TO_TEXTURE_RGB_EXT, &val);
+                                if (val) tex_format = GLX_TEXTURE_FORMAT_RGB_EXT;
+                             }
+                           glXGetFBConfigAttrib(re->win->disp, configs[j],
+                                                GLX_Y_INVERTED_EXT, &val);
+                           yinvert = val;
+                           glXGetFBConfigAttrib(re->win->disp, configs[j],
+                                                GLX_BIND_TO_TEXTURE_TARGETS_EXT,
+                                                &val);
+                           tex_target = val;
+                           glXGetFBConfigAttrib(re->win->disp, configs[j],
+                                                GLX_BIND_TO_MIPMAP_TEXTURE_EXT, &val);
+                           mipmap = val;
+                           n->config = configs[j];
+                           XFree(configs);
+                        }
+
+                      eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im);
+                      if ((tex_target & GLX_TEXTURE_2D_BIT_EXT))
+                        target = GLX_TEXTURE_2D_EXT;
+                      else if ((target & GLX_TEXTURE_RECTANGLE_BIT_EXT))
+                        {
+                           ERR("rect!!! (not handled)");
+                           target = GLX_TEXTURE_RECTANGLE_EXT;
+                        }
+                      if (!target)
+                        {
+                           ERR("broken tex-from-pixmap");
+                           if (!(tex_target & GLX_TEXTURE_2D_BIT_EXT))
+                             target = GLX_TEXTURE_RECTANGLE_EXT;
+                           else if (!(tex_target & GLX_TEXTURE_RECTANGLE_BIT_EXT))
+                             target = GLX_TEXTURE_2D_EXT;
+                        }
+
+                      i = 0;
+                      pixmap_att[i++] = GLX_TEXTURE_FORMAT_EXT;
+                      pixmap_att[i++] = tex_format;
+                      pixmap_att[i++] = GLX_MIPMAP_TEXTURE_EXT;
+                      pixmap_att[i++] = mipmap;
+                      if (target)
+                        {
+                           pixmap_att[i++] = GLX_TEXTURE_TARGET_EXT;
+                           pixmap_att[i++] = target;
+                        }
+                      pixmap_att[i++] = 0;
+
+                      memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
+                      n->pixmap = pm;
+                      n->visual = vis;
+                      if (glsym_glXCreatePixmap)
+                        n->surface = (void *)glsym_glXCreatePixmap(re->win->disp,
+                                                              n->config,
+                                                              n->pixmap,
+                                                              pixmap_att);
+                      else
+                        ERR("Try glXCreatePixmap on GLX with no support");
+                      if (n->surface)
+                        {
+//                           printf("%p: new native texture for %x | %4i x %4i @ %2i = %p\n",
+//                                  n, pm, w, h, depth, n->surface);
+                           if (!target)
+                             {
+                                ERR("no target :(");
+                                if (glsym_glXQueryDrawable)
+                                  glsym_glXQueryDrawable(re->win->disp,
+                                                         n->pixmap,
+                                                         GLX_TEXTURE_TARGET_EXT,
+                                                         &target);
+                             }
+                           if (target == GLX_TEXTURE_2D_EXT)
+                             {
+                                im->native.target = GL_TEXTURE_2D;
+                                im->native.mipmap = mipmap;
+                             }
+#  ifdef GL_TEXTURE_RECTANGLE_ARB
+                           else if (target == GLX_TEXTURE_RECTANGLE_EXT)
+                             {
+                                im->native.target = GL_TEXTURE_RECTANGLE_ARB;
+                                im->native.mipmap = 0;
+                             }
+#  endif
+                           else
+                             {
+                                im->native.target = GL_TEXTURE_2D;
+                                im->native.mipmap = 0;
+                                ERR("still unknown target");
+                             }
+                        }
+                      else
+                        ERR("GLX Pixmap create fail");
+                      im->native.yinvert     = yinvert;
+                      im->native.loose       = re->win->detected.loose_binding;
+                      im->native.data        = n;
+                      im->native.func.data   = re;
+                      im->native.func.bind   = _native_bind_cb;
+                      im->native.func.unbind = _native_unbind_cb;
+                      im->native.func.free   = _native_free_cb;
+
+                      evas_gl_common_image_native_enable(im);
+                   }
+              }
+         }
+# endif
+#endif
+    }
+  else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
+    {
+      if (native)
+        {
+          n = calloc(1, sizeof(Native));
+          if (n)
+            {
+              memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
+
+              eina_hash_add(re->win->gl_context->shared->native_tex_hash, &texid, im);
+
+              n->pixmap = 0;
+              n->visual = 0;
+              n->config = 0;
+              n->surface = 0;
+
+              im->native.yinvert     = 0;
+              im->native.loose       = 0;
+              im->native.data        = n;
+              im->native.func.data   = re;
+              im->native.func.bind   = _native_bind_cb;
+              im->native.func.unbind = _native_unbind_cb;
+              im->native.func.free   = _native_free_cb;
+              im->native.target      = GL_TEXTURE_2D;
+              im->native.mipmap      = 0;
+
+              // FIXME: need to implement mapping sub texture regions
+              // x, y, w, h for possible texture atlasing
+
+              evas_gl_common_image_native_enable(im);
+            }
+        }
+
+    }
+  else if (ns->type == EVAS_NATIVE_SURFACE_TIZEN)
+    {
+#ifdef GL_GLES
+#ifdef HAVE_NATIVE_BUFFER
+       if (native)
+         {
+            n = calloc(1, sizeof(Native));
+            if (n)
+              {
+                 EGLConfig egl_config;
+                 int config_attrs[20];
+                 int num_config, i = 0;
+                 const char *vendor;
+
+                 eina_hash_add(re->win->gl_context->shared->native_buffer_hash, &buffer, im);
+
+                 memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
+                 n->pixmap = 0;
+                 n->visual = 0;
+                 n->buffer = buffer;
+                 if (glsym_eglCreateImage)
+                   n->egl_surface = glsym_eglCreateImage(re->win->egl_disp,
+                                                         EGL_NO_CONTEXT,
+                                                         EGL_NATIVE_BUFFER_TIZEN,
+                                                         (void *)buffer,
+                                                         NULL);
+                 else
+                   ERR("Try eglCreateImage on EGL with no support");
+                 if (!n->egl_surface)
+                   ERR("eglCreateImage() for 0x%x failed", (unsigned int)buffer);
+                 vendor = (const char *)glGetString(GL_VENDOR);
+                 if (vendor && strstr (vendor, "Qualcomm") != NULL)
+                   n->recreate = 1;
+                 im->native.yinvert     = 1;
+                 im->native.loose       = 0;
+                 im->native.data        = n;
+                 im->native.func.data   = re;
+                 im->native.func.bind   = _native_bind_cb;
+                 im->native.func.unbind = _native_unbind_cb;
+                 im->native.func.free   = _native_free_cb;
+                 im->native.target      = GL_TEXTURE_EXTERNAL_OES;
+                 im->native.mipmap      = 0;
+                 im->native.rot         = ns->data.tizen.rot;
+                 im->native.ratio       = ns->data.tizen.ratio;
+                 im->native.flip        = ns->data.tizen.flip;
+                 evas_gl_common_image_native_enable(im);
+              }
+         }
+#endif
+#endif
+    }
+  else if (ns->type == EVAS_NATIVE_SURFACE_TBM)
+    {
+       if (native)
+         {
+            n = calloc(1, sizeof(Native));
+            if (n)
+              {
+                 EGLConfig egl_config;
+                 int config_attrs[20];
+                 int num_config, i = 0;
+                 const char *vendor;
+
+                 eina_hash_add(re->win->gl_context->shared->native_tbm_hash, &buffer, im);
+
+                 memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
+                 n->pixmap = 0;
+                 n->visual = 0;
+                 n->buffer = buffer;
+                 if (glsym_eglCreateImage)
+                   n->surface = glsym_eglCreateImage(re->win->egl_disp,
+                                                         EGL_NO_CONTEXT,
+                                                         EGL_NATIVE_SURFACE_TIZEN,
+                                                         (void *)buffer,
+                                                         NULL);
+                 else
+                   ERR("Try eglCreateImage on EGL with no support");
+                 if (!n->surface)
+                   ERR("eglCreateImage() for %p failed", buffer);
+                 vendor = (const char *)glGetString(GL_VENDOR);
+                 if (vendor && strstr (vendor, "Qualcomm") != NULL)
+                   n->recreate = 1;
+                 im->native.yinvert     = 1;
+                 im->native.loose       = 0;
+                 im->native.data        = n;
+                 im->native.func.data   = re;
+                 im->native.func.bind   = _native_bind_cb;
+                 im->native.func.unbind = _native_unbind_cb;
+                 im->native.func.free   = _native_free_cb;
+                 im->native.target      = GL_TEXTURE_EXTERNAL_OES;
+                 im->native.mipmap      = 0;
+                 im->native.rot         = ns->data.tizen.rot;
+                 im->native.ratio       = ns->data.tizen.ratio;
+                 im->native.flip        = ns->data.tizen.flip;
+                 evas_gl_common_image_native_enable(im);
+              }
+         }
+    }
+  else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
+    {
+       if (native)
+         {
+            n = calloc(1, sizeof(Native));
+            if (n)
+              {
+                 memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
+                 eina_hash_add(re->win->gl_context->shared->native_evasgl_hash, &buffer, im);
+
+                 n->pixmap = 0;
+                 n->visual = 0;
+                 n->surface = ns->data.evasgl.surface;
+
+                 im->native.yinvert     = 0;
+                 im->native.loose       = 0;
+                 im->native.data        = n;
+                 im->native.func.data   = re;
+                 im->native.func.bind   = _native_bind_cb;
+                 im->native.func.unbind = _native_unbind_cb;
+                 im->native.func.free   = _native_free_cb;
+                 im->native.func.yinvert = _native_yinvert_cb;
+                 im->native.target      = GL_TEXTURE_2D;
+                 im->native.mipmap      = 0;
+
+                 // FIXME: need to implement mapping sub texture regions
+                 // x, y, w, h for possible texture atlasing
+
+                 evas_gl_common_image_native_enable(im);
+              }
+         }
+    }
+  return im;
 }
 
-static void
-eng_image_data_preload_cancel(void *data __UNUSED__, void *image, const void *target)
+static void *
+eng_image_native_get(void *data __UNUSED__, void *image)
 {
-   Evas_GL_Image *gim = image;
-   RGBA_Image *im;
+   Evas_GL_Image *im = image;
+   Native *n;
+   if (!im) return NULL;
+   n = im->native.data;
+   if (!n) return NULL;
+   return &(n->ns);
+}
 
-   if (!gim) return;
-   if (gim->native.data) return;
-   im = (RGBA_Image *)gim->im;
-   if (!im) return;
-   evas_cache_image_preload_cancel(&im->cache_entry, target);
+static Eina_Bool
+eng_image_direct_get(void *data __UNUSED__, void *image)
+{
+   Evas_GL_Image *im = image;
+   if (!im) return EINA_FALSE;
+   return im->direct;
 }
 
 static void
-eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth)
+eng_image_direct_set(void *data, void *image, int direct)
 {
    Render_Engine *re;
    re = (Render_Engine *)data;
-   if (!image) return;
-
-   if ((gl_direct_img_obj) && (gl_direct_enabled))
-     {
-        DBG("Rendering Directly to the window");
-        evas_object_image_pixels_dirty_set(gl_direct_img_obj, EINA_TRUE);
-     }
-   else
-     {
-        eng_window_use(re->win);
-        evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
-        re->win->gl_context->dc = context;
-        evas_gl_common_image_draw(re->win->gl_context, image,
-                                  src_x, src_y, src_w, src_h,
-                                  dst_x, dst_y, dst_w, dst_h,
-                                  smooth);
-     }
-}
+   Evas_GL_Image *im = image;
+   Native *n;
 
-static void
-eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint)
-{
-   if (image) evas_gl_common_image_scale_hint_set(image, hint);
-}
+   if (!im) return;
+   n = im->native.data;
 
-static int
-eng_image_scale_hint_get(void *data __UNUSED__, void *image)
-{
-   Evas_GL_Image *gim = image;
-   if (!gim) return EVAS_IMAGE_SCALE_HINT_NONE;
-   return gim->scale_hint;
+   if ( (n) &&
+        (direct) &&
+        (re->func.get_pixels) )
+     im->direct = EINA_TRUE;
+   else
+     im->direct = EINA_FALSE;
 }
 
+#if 0 // filtering disabled
 static void
-eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level)
+eng_image_draw_filtered(void *data, void *context, void *surface,
+                        void *image, Evas_Filter_Info *filter)
 {
-   Evas_GL_Image *gim = image;
-   Render_Engine *re;
+   Render_Engine *re = data;
 
-   re = (Render_Engine *)data;
    if (!image) return;
    eng_window_use(re->win);
    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
    re->win->gl_context->dc = context;
-   if (m->count != 4)
-     {
-        // FIXME: nash - you didn't fix this
-        abort();
-     }
-   if ((m->pts[0].x == m->pts[3].x) &&
-       (m->pts[1].x == m->pts[2].x) &&
-       (m->pts[0].y == m->pts[1].y) &&
-       (m->pts[3].y == m->pts[2].y) &&
-       (m->pts[0].x <= m->pts[1].x) &&
-       (m->pts[0].y <= m->pts[2].y) &&
-       (m->pts[0].u == 0) &&
-       (m->pts[0].v == 0) &&
-       (m->pts[1].u == (gim->w << FP)) &&
-       (m->pts[1].v == 0) &&
-       (m->pts[2].u == (gim->w << FP)) &&
-       (m->pts[2].v == (gim->h << FP)) &&
-       (m->pts[3].u == 0) &&
-       (m->pts[3].v == (gim->h << FP)) &&
-       (m->pts[0].col == 0xffffffff) &&
-       (m->pts[1].col == 0xffffffff) &&
-       (m->pts[2].col == 0xffffffff) &&
-       (m->pts[3].col == 0xffffffff))
-     {
-        int dx, dy, dw, dh;
 
-        dx = m->pts[0].x >> FP;
-        dy = m->pts[0].y >> FP;
-        dw = (m->pts[2].x >> FP) - dx;
-        dh = (m->pts[2].y >> FP) - dy;
-        eng_image_draw(data, context, surface, image,
-                       0, 0, gim->w, gim->h, dx, dy, dw, dh, smooth);
-     }
-   else
-     {
-        evas_gl_common_image_map_draw(re->win->gl_context, image, m->count, &m->pts[0],
-                                      smooth, level);
-     }
+   evas_gl_common_filter_draw(re->win->gl_context, image, filter);
 }
 
-static void
-eng_image_map_clean(void *data, RGBA_Map *m)
+static Filtered_Image *
+eng_image_filtered_get(void *im, uint8_t *key, size_t keylen)
 {
+   return evas_gl_common_image_filtered_get(im, key, keylen);
 }
 
-static void *
-eng_image_map_surface_new(void *data, int w, int h, int alpha)
+static Filtered_Image *
+eng_image_filtered_save(void *im, void *fim, uint8_t *key, size_t keylen)
 {
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-   return evas_gl_common_image_surface_new(re->win->gl_context, w, h, alpha);
+   return evas_gl_common_image_filtered_save(im, fim, key, keylen);
 }
 
 static void
-eng_image_map_surface_free(void *data __UNUSED__, void *surface)
+eng_image_filtered_free(void *im, Filtered_Image *fim)
 {
-   evas_gl_common_image_free(surface);
+   evas_gl_common_image_filtered_free(im, fim);
 }
+#endif
 
-static void
-eng_image_content_hint_set(void *data __UNUSED__, void *image, int hint)
-{
-   if (image) evas_gl_common_image_content_hint_set(image, hint);
-}
 
-static int
-eng_image_content_hint_get(void *data __UNUSED__, void *image)
-{
-   Evas_GL_Image *gim = image;
-   if (!gim) return EVAS_IMAGE_CONTENT_HINT_NONE;
-   return gim->content_hint;
-}
+//
+//
+/////////////////////////////////////////////////////////////////////////
 
-static void
-eng_image_cache_flush(void *data)
+static void *
+eng_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
 {
    Render_Engine *re;
-   int tmp_size;
 
    re = (Render_Engine *)data;
-
-   tmp_size = evas_common_image_get_cache();
-   evas_common_image_set_cache(0);
-   evas_common_rgba_image_scalecache_flush();
-   evas_gl_common_image_cache_flush(re->win->gl_context);
-   evas_common_image_set_cache(tmp_size);
+   *error = EVAS_LOAD_ERROR_NONE;
+   eng_window_use(re->win);
+   return evas_gl_common_image_load(re->win->gl_context, file, key, lo, error);
 }
 
-static void
-eng_image_cache_set(void *data, int bytes)
+static void *
+eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
 {
    Render_Engine *re;
 
    re = (Render_Engine *)data;
-   evas_common_image_set_cache(bytes);
-   evas_common_rgba_image_scalecache_size_set(bytes);
-   evas_gl_common_image_cache_flush(re->win->gl_context);
-}
-
-static int
-eng_image_cache_get(void *data __UNUSED__)
-{
-   return evas_common_image_get_cache();
+   eng_window_use(re->win);
+   return evas_gl_common_image_new_from_data(re->win->gl_context, w, h, image_data, alpha, cspace);
 }
 
-static void
-eng_image_stride_get(void *data __UNUSED__, void *image, int *stride)
+static void *
+eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
 {
-   Evas_GL_Image *im = image;
+   Render_Engine *re;
 
-   if ((im->tex) && (im->tex->pt->dyn.img))
-     *stride = im->tex->pt->dyn.stride;
-   else
-     *stride = im->w * 4;
+   re = (Render_Engine *)data;
+   eng_window_use(re->win);
+   return evas_gl_common_image_new_from_copied_data(re->win->gl_context, w, h, image_data, alpha, cspace);
 }
 
 static void
-eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font __UNUSED__, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, Evas_Text_Props *intl_props)
+eng_image_free(void *data, void *image)
 {
    Render_Engine *re;
 
    re = (Render_Engine *)data;
+   if (!image) return;
    eng_window_use(re->win);
-   evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
-   re->win->gl_context->dc = context;
-     {
-        // FIXME: put im into context so we can free it
-        static RGBA_Image *im = NULL;
-
-        if (!im)
-          im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
-        im->cache_entry.w = re->win->gl_context->shared->w;
-        im->cache_entry.h = re->win->gl_context->shared->h;
-
-        evas_common_draw_context_font_ext_set(context,
-                                              re->win->gl_context,
-                                              evas_gl_font_texture_new,
-                                              evas_gl_font_texture_free,
-                                              evas_gl_font_texture_draw);
-        evas_common_font_draw_prepare(intl_props);
-        evas_common_font_draw(im, context, x, y, intl_props);
-        evas_common_draw_context_font_ext_set(context,
-                                              NULL,
-                                              NULL,
-                                              NULL,
-                                              NULL);
-     }
-}
-
-static Eina_Bool
-eng_canvas_alpha_get(void *data, void *info __UNUSED__)
-{
-   Render_Engine *re = (Render_Engine *)data;
-   return re->win->alpha;
+   evas_gl_common_image_free(image);
 }
 
-
-// Unfortunately, there is no query function to figure out which surface formats work.
-// So, this is one way to test for surface config capability.
-static int
-_check_gl_surface_format(GLint int_fmt, GLenum fmt, GLenum attachment, GLenum attach_fmt, int mult_samples)
+static void
+eng_image_size_get(void *data __UNUSED__, void *image, int *w, int *h)
 {
-   GLuint fbo, tex, rb, ds_tex;
-   int w, h, fb_status;
-
-   // Initialize Variables
-   fbo = tex = rb = ds_tex = 0;
-
-   // Width/Heith for test purposes
-   w = h = 2;
-
-   // Gen FBO
-   glGenFramebuffers(1, &fbo);
-   glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-
-   // Render Target Texture
-   if (int_fmt)
-     {
-        glGenTextures(1, &tex);
-        glBindTexture(GL_TEXTURE_2D, tex );
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-        glTexImage2D(GL_TEXTURE_2D, 0, int_fmt, w, h, 0, fmt, GL_UNSIGNED_BYTE, NULL);
-        glBindTexture(GL_TEXTURE_2D, 0);
-
-        if (mult_samples)
-           glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0, mult_samples);
-        else
-           glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
-     }
-
-   // Render Target Attachment (Stencil or Depth)
-   if (attachment)
-     {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-        // This is a little hacky but this is how we'll have to do for now.
-        if (attach_fmt == GL_DEPTH_STENCIL_OES)
-          {
-             glGenTextures(1, &ds_tex);
-             glBindTexture(GL_TEXTURE_2D, ds_tex);
-             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-             glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL_OES, w, h,
-                          0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES, NULL);
-             if (mult_samples)
-               {
-                  glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-                                                          GL_TEXTURE_2D, ds_tex, 0, mult_samples);
-                  glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
-                                                          GL_TEXTURE_2D, ds_tex, 0, mult_samples);
-               }
-             else
-               {
-                  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-                                         GL_TEXTURE_2D, ds_tex, 0);
-                  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
-                                         GL_TEXTURE_2D, ds_tex, 0);
-               }
-             glBindTexture(GL_TEXTURE_2D, 0);
-          }
-        else
-#endif
-          {
-             glGenRenderbuffers(1, &rb);
-             glBindRenderbuffer(GL_RENDERBUFFER, rb);
-             if (mult_samples)
-                glsym_glRenderbufferStorageMultisample(GL_RENDERBUFFER, mult_samples, attach_fmt, w, h);
-             else
-                glRenderbufferStorage(GL_RENDERBUFFER, attach_fmt, w, h);
-             glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, rb);
-             glBindRenderbuffer(GL_RENDERBUFFER, 0);
-          }
-
-     }
-
-   // Check FBO for completeness
-   fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-
-
-   // Delete Created Resources
-   glBindFramebuffer(GL_FRAMEBUFFER, 0);
-   if (fbo) glDeleteFramebuffers(1, &fbo);
-   if (tex) glDeleteTextures(1, &tex);
-   if (ds_tex) glDeleteTextures(1, &ds_tex);
-   if (rb) glDeleteRenderbuffers(1, &rb);
-
-   if (fb_status != GL_FRAMEBUFFER_COMPLETE)
-      return 0;
-   else
+   if (!image)
      {
-        if ((attachment) && (!mult_samples))
-           return attach_fmt;
-        else
-           return 1;
+        *w = 0;
+        *h = 0;
+        return;
      }
+   if (w) *w = ((Evas_GL_Image *)image)->w;
+   if (h) *h = ((Evas_GL_Image *)image)->h;
 }
 
-static void
-_print_gl_surface_info(Render_Engine_GL_Surface *sfc, int error)
-{
-#define PRINT_LOG(...) \
-   if (error) \
-      ERR(__VA_ARGS__); \
-   else \
-      DBG(__VA_ARGS__);
-
-   PRINT_LOG("----------Surface Info------------");
-   PRINT_LOG("     [Surface] %x", (unsigned int)sfc);
-   PRINT_LOG("         Width:  %d", sfc->w);
-   PRINT_LOG("         Height: %d", sfc->h);
-   PRINT_LOG("         Direct Surface: %x", (unsigned int)sfc->direct_sfc);
-   PRINT_LOG("         Current Context: %x", (unsigned int)sfc->current_ctx);
-   PRINT_LOG("         [-------Config-------]");
-   PRINT_LOG("            Depth Bits      : %d", sfc->depth_bits);
-   PRINT_LOG("            Stencil Bits    : %d", sfc->stencil_bits);
-   PRINT_LOG("            Direct FB Opt   : %d", sfc->direct_fb_opt);
-   PRINT_LOG("            Multisample Bits: %d", sfc->multisample_bits);
-   PRINT_LOG("            MSAA Samples    : %d", sfc->rt_msaa_samples);
-   PRINT_LOG("         [-------Internal-----]");
-   PRINT_LOG("            RenderTarget Texture             : %d", sfc->rt_tex);
-   PRINT_LOG("            RenderTarget Internal Format     : %x", sfc->rt_internal_fmt);
-   PRINT_LOG("            RenderTaret Format               : %x", sfc->rt_fmt);
-   PRINT_LOG("            RenderBuffer Depth               : %x", sfc->rb_depth);
-   PRINT_LOG("            RenderBuffer Depth Format        : %x", sfc->rb_depth_fmt);
-   PRINT_LOG("            RenderBuffer Stencil             : %d", sfc->rb_stencil);
-   PRINT_LOG("            RenderBuffer Stencil Format      : %x", sfc->rb_stencil_fmt);
-   PRINT_LOG("            RenderBuffer Depth Stencil       : %x", sfc->rb_depth_stencil);
-   PRINT_LOG("            RenderBuffer Depth Stencil Format: %x", sfc->rb_depth_stencil_fmt);
-   PRINT_LOG("--------------------------------------");
-
-#undef PRINT_LOG
-}
-
-static void
-_print_gl_surface_cap(Render_Engine *re, int error)
-{
-#define PRINT_LOG(...) \
-   if (error) \
-      ERR(__VA_ARGS__); \
-   else \
-      DBG(__VA_ARGS__);
-
-   PRINT_LOG("----------------------------------------------------");
-   PRINT_LOG("           EvasGL Supported Surface Format          ");
-   PRINT_LOG("                                                    ");
-   PRINT_LOG(" [Max Renderbuffer Size]  : %d", re->gl_cap.max_rb_size);
-   PRINT_LOG(" [Multisample Support  ]  : %d", re->gl_cap.msaa_support);
-   PRINT_LOG("          [Low  Samples]  : %d", re->gl_cap.msaa_samples[1]);
-   PRINT_LOG("          [Med  Samples]  : %d", re->gl_cap.msaa_samples[2]);
-   PRINT_LOG("          [High Samples]  : %d", re->gl_cap.msaa_samples[3]);
-   PRINT_LOG("                                  [--Multisamples--]   ");
-   PRINT_LOG("                           [Norm] [Low] [Med] [High]");
-   PRINT_LOG(" [RGB  Format]            : %4x    %d     %d     %d", re->gl_cap.rgb_888[0], re->gl_cap.rgb_888[1], re->gl_cap.rgb_888[2], re->gl_cap.rgb_888[3]);
-   PRINT_LOG(" [RGBA Format]            : %4x    %d     %d     %d", re->gl_cap.rgba_8888[0], re->gl_cap.rgba_8888[1], re->gl_cap.rgba_8888[2], re->gl_cap.rgba_8888[3]);
-   PRINT_LOG(" [Depth  8 Bits]          : %4x    %d     %d     %d", re->gl_cap.depth_8[0], re->gl_cap.depth_8[1], re->gl_cap.depth_8[2], re->gl_cap.depth_8[3]);
-   PRINT_LOG(" [Depth 16 Bits]          : %4x    %d     %d     %d", re->gl_cap.depth_16[0], re->gl_cap.depth_16[1], re->gl_cap.depth_16[2], re->gl_cap.depth_16[3]);
-   PRINT_LOG(" [Depth 24 Bits]          : %4x    %d     %d     %d", re->gl_cap.depth_24[0], re->gl_cap.depth_24[1], re->gl_cap.depth_24[2], re->gl_cap.depth_24[3]);
-   PRINT_LOG(" [Depth 32 Bits]          : %4x    %d     %d     %d", re->gl_cap.depth_32[0], re->gl_cap.depth_32[1], re->gl_cap.depth_32[2], re->gl_cap.depth_32[3]);
-   PRINT_LOG(" [Stencil  1 Bits]        : %4x    %d     %d     %d", re->gl_cap.stencil_1[0], re->gl_cap.stencil_1[1], re->gl_cap.stencil_1[2], re->gl_cap.stencil_1[3]);
-   PRINT_LOG(" [Stencil  2 Bits]        : %4x    %d     %d     %d", re->gl_cap.stencil_2[0], re->gl_cap.stencil_2[1], re->gl_cap.stencil_2[2], re->gl_cap.stencil_2[3]);
-   PRINT_LOG(" [Stencil  4 Bits]        : %4x    %d     %d     %d", re->gl_cap.stencil_4[0], re->gl_cap.stencil_4[1], re->gl_cap.stencil_4[2], re->gl_cap.stencil_4[3]);
-   PRINT_LOG(" [Stencil  8 Bits]        : %4x    %d     %d     %d", re->gl_cap.stencil_8[0], re->gl_cap.stencil_8[1], re->gl_cap.stencil_8[2], re->gl_cap.stencil_8[3]);
-   PRINT_LOG(" [Stencil 16 Bits]        : %4x    %d     %d     %d", re->gl_cap.stencil_16[0], re->gl_cap.stencil_16[1], re->gl_cap.stencil_16[2], re->gl_cap.stencil_16[3]);
-   PRINT_LOG(" [Depth 24 Stencil 8 Bits]: %4x    %d     %d     %d", re->gl_cap.depth_24_stencil_8[0], re->gl_cap.depth_24_stencil_8[1], re->gl_cap.depth_24_stencil_8[2], re->gl_cap.depth_24_stencil_8[3]);
-   PRINT_LOG("----------------------------------------------------");
-#undef PRINT_LOG
-}
-
-static void
-_set_gl_surface_cap(Render_Engine *re)
+static void *
+eng_image_size_set(void *data, void *image, int w, int h)
 {
-   GLuint fbo, tex, depth, stencil;
-   int w, h;
-
-   int i, count;
-
-   if (!re) return;
-   if (re->gl_cap_initted) return;
-
-   // Width/Heith for test purposes
-   w = h = 2;
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   int max_samples = 0;
-
-   glGetIntegerv(GL_MAX_SAMPLES_IMG, &max_samples);
+   Render_Engine *re;
+   Evas_GL_Image *im = image;
+   Evas_GL_Image *im_old;
 
-   // Check if msaa_support is supported
-   if ((max_samples) &&
-       (glsym_glFramebufferTexture2DMultisample) &&
-       (glsym_glRenderbufferStorageMultisample))
+   re = (Render_Engine *)data;
+   if (!im) return NULL;
+   if (im->native.data)
      {
-        re->gl_cap.msaa_support = 1;
-
-        re->gl_cap.msaa_samples[3] = max_samples;
-        re->gl_cap.msaa_samples[2] = max_samples/2;
-        re->gl_cap.msaa_samples[1] = max_samples/4;
-        re->gl_cap.msaa_samples[0] = 0;
-
-        if (!re->gl_cap.msaa_samples[2]) re->gl_cap.msaa_samples[3];
-        if (!re->gl_cap.msaa_samples[1]) re->gl_cap.msaa_samples[2];
+        im->w = w;
+        im->h = h;
+        return image;
      }
-   else
+   eng_window_use(re->win);
+   if ((im->tex) && (im->tex->pt->dyn.img))
      {
-        re->gl_cap.msaa_support = 0;
+        evas_gl_common_texture_free(im->tex);
+        im->tex = NULL;
+        im->w = w;
+        im->h = h;
+        im->tex = evas_gl_common_texture_dynamic_new(im->gc, im);
+        return image;
      }
+   im_old = image;
 
-#endif
-
-   glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &re->gl_cap.max_rb_size);
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   count = (re->gl_cap.msaa_support) ? 4 : 1;
-
-   for (i = 0; i < count; i++)
+   switch (eng_image_colorspace_get(data, image))
      {
-        re->gl_cap.rgb_888[i]   = _check_gl_surface_format(GL_RGB, GL_RGB, 0, 0, re->gl_cap.msaa_samples[i]);
-        re->gl_cap.rgba_8888[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, 0, 0, re->gl_cap.msaa_samples[i]);
-
-        re->gl_cap.depth_8[i]   = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, re->gl_cap.msaa_samples[i]);
-        re->gl_cap.depth_16[i]  = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16, re->gl_cap.msaa_samples[i]);
-        re->gl_cap.depth_24[i]  = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24_OES, re->gl_cap.msaa_samples[i]);
-        re->gl_cap.depth_32[i]  = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32_OES, re->gl_cap.msaa_samples[i]);
-
-        re->gl_cap.stencil_1[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX1_OES, re->gl_cap.msaa_samples[i]);
-        re->gl_cap.stencil_4[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX4_OES, re->gl_cap.msaa_samples[i]);
-        re->gl_cap.stencil_8[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8, re->gl_cap.msaa_samples[i]);
-
-        re->gl_cap.depth_24_stencil_8[i]  = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_STENCIL_OES, GL_DEPTH_STENCIL_OES, re->gl_cap.msaa_samples[i]);
+      case EVAS_COLORSPACE_YCBCR422P601_PL:
+      case EVAS_COLORSPACE_YCBCR422P709_PL:
+      case EVAS_COLORSPACE_YCBCR422601_PL:
+      case EVAS_COLORSPACE_YCBCR420NV12601_PL:
+      case EVAS_COLORSPACE_YCBCR420TM12601_PL:
+         w &= ~0x1;
+         break;
      }
 
-#else
-   count = (re->gl_cap.msaa_support) ? 4 : 1;
-
-   for (i = 0; i < count; i++)
+   evas_gl_common_image_alloc_ensure(im);
+   if ((im_old) &&
+       (im_old->im) &&
+       ((int)im_old->im->cache_entry.w == w) &&
+       ((int)im_old->im->cache_entry.h == h))
+     return image;
+   if (im_old)
      {
-        re->gl_cap.rgb_888[i]   = _check_gl_surface_format(GL_RGB, GL_RGB, 0, 0, re->gl_cap.msaa_samples[i]);
-        re->gl_cap.rgba_8888[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, 0, 0, re->gl_cap.msaa_samples[i]);
-
-        re->gl_cap.depth_8[i]   = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, re->gl_cap.msaa_samples[i]);
-        re->gl_cap.depth_16[i]  = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16, re->gl_cap.msaa_samples[i]);
-        re->gl_cap.depth_24[i]  = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24, re->gl_cap.msaa_samples[i]);
-        re->gl_cap.depth_32[i]  = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32, re->gl_cap.msaa_samples[i]);
-
-        re->gl_cap.stencil_1[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX1, re->gl_cap.msaa_samples[i]);
-        re->gl_cap.stencil_4[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX4, re->gl_cap.msaa_samples[i]);
-        re->gl_cap.stencil_8[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8, re->gl_cap.msaa_samples[i]);
-
-        re->gl_cap.depth_24_stencil_8[i]  = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH24_STENCIL8, re->gl_cap.msaa_samples[i]);
+        im = evas_gl_common_image_new(re->win->gl_context, w, h,
+                                      eng_image_alpha_get(data, image),
+                                      eng_image_colorspace_get(data, image));
+        /*
+       evas_common_load_image_data_from_file(im_old->im);
+       if (im_old->im->image->data)
+         {
+            evas_common_blit_rectangle(im_old->im, im->im, 0, 0, w, h, 0, 0);
+            evas_common_cpu_end_opt();
+         }
+ */
+        evas_gl_common_image_free(im_old);
      }
-#endif
+   else
+     im = evas_gl_common_image_new(re->win->gl_context, w, h, 1, EVAS_COLORSPACE_ARGB8888);
+   return im;
+}
 
-   _print_gl_surface_cap(re, 0);
+static void *
+eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h)
+{
+   Render_Engine *re;
+   Evas_GL_Image *im = image;
 
-   re->gl_cap_initted = 1;
+   re = (Render_Engine *)data;
+   if (!image) return NULL;
+   if (im->native.data) return image;
+   eng_window_use(re->win);
+   evas_gl_common_image_dirty(image, x, y, w, h);
+   return image;
 }
 
-static int
-_set_internal_config(Render_Engine *re, Render_Engine_GL_Surface *sfc, Evas_GL_Config *cfg)
+static void *
+eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, int *err)
 {
-   // Check if color formats are supported
-   switch((int)cfg->color_format)
-     {
-      case EVAS_GL_RGB_888:
-         if (re->gl_cap.rgb_888[0])
-           {
-              sfc->rt_fmt          = GL_RGB;
-              sfc->rt_internal_fmt = GL_RGB;
-              break;
-           }
-      case EVAS_GL_RGBA_8888:
-         if (re->gl_cap.rgba_8888[0])
-           {
-              sfc->rt_fmt          = GL_RGBA;
-              sfc->rt_internal_fmt = GL_RGBA;
-              cfg->color_format    = EVAS_GL_RGBA_8888;
-              break;
-           }
-      default:
-         ERR("Color Format Not Supported: %d", cfg->color_format);
-         _print_gl_surface_cap(re, 1);
-         return 0;
-     }
+   Render_Engine *re;
+   Evas_GL_Image *im;
+   int error;
 
-   switch((int)cfg->depth_bits)
+   re = (Render_Engine *)data;
+   if (!image)
      {
-      case EVAS_GL_DEPTH_NONE:
-         break;
-      case EVAS_GL_DEPTH_BIT_8:
-         if (re->gl_cap.depth_8[0])
-           {
-              sfc->rb_depth_fmt = re->gl_cap.depth_8[0];
-              cfg->depth_bits   = EVAS_GL_DEPTH_BIT_8;
-              break;
-           }
-      case EVAS_GL_DEPTH_BIT_16:
-         if (re->gl_cap.depth_16[0])
-           {
-              sfc->rb_depth_fmt = re->gl_cap.depth_16[0];
-              cfg->depth_bits   = EVAS_GL_DEPTH_BIT_16;
-              break;
-           }
-      case EVAS_GL_DEPTH_BIT_24:
-         if (re->gl_cap.depth_24[0])
-           {
-              sfc->rb_depth_fmt = re->gl_cap.depth_24[0];
-              cfg->depth_bits   = EVAS_GL_DEPTH_BIT_24;
-              break;
-           }
-         else if (re->gl_cap.depth_24_stencil_8[0])
-           {
-              sfc->rb_depth_stencil_fmt = re->gl_cap.depth_24_stencil_8[0];
-              sfc->rb_depth_fmt         = re->gl_cap.depth_24_stencil_8[0];
-              cfg->depth_bits           = EVAS_GL_DEPTH_BIT_24;
-              break;
-           }
-      case EVAS_GL_DEPTH_BIT_32:
-         if (re->gl_cap.depth_32[0])
-           {
-              sfc->rb_depth_fmt = re->gl_cap.depth_32[0];
-              cfg->depth_bits   = EVAS_GL_DEPTH_BIT_32;
-              break;
-           }
-      default:
-         ERR("Unsupported Depth Bits Format: %d", cfg->depth_bits);
-         _print_gl_surface_cap(re, 1);
-         return 0;
+        *image_data = NULL;
+        if (err) *err = EVAS_LOAD_ERROR_GENERIC;
+        return NULL;
      }
-
-   switch((int)cfg->stencil_bits)
+   im = image;
+   if (im->native.data)
      {
-      case EVAS_GL_STENCIL_NONE:
-         break;
-      case EVAS_GL_STENCIL_BIT_1:
-         if (re->gl_cap.stencil_1[0])
-           {
-              sfc->rb_stencil_fmt = re->gl_cap.stencil_1[0];
-              cfg->stencil_bits   = EVAS_GL_STENCIL_BIT_1;
-              break;
-           }
-      case EVAS_GL_STENCIL_BIT_2:
-         if (re->gl_cap.stencil_2[0])
-           {
-              sfc->rb_stencil_fmt = re->gl_cap.stencil_2[0];
-              cfg->stencil_bits   = EVAS_GL_STENCIL_BIT_2;
-              break;
-           }
-      case EVAS_GL_STENCIL_BIT_4:
-         if (re->gl_cap.stencil_4[0])
-           {
-              sfc->rb_stencil_fmt = re->gl_cap.stencil_4[0];
-              cfg->stencil_bits   = EVAS_GL_STENCIL_BIT_4;
-              break;
-           }
-      case EVAS_GL_STENCIL_BIT_8:
-         if ((sfc->rb_depth_fmt == re->gl_cap.depth_24_stencil_8[0]) ||
-             (sfc->rb_depth_fmt == re->gl_cap.depth_24[0]) ||
-             (!(re->gl_cap.stencil_8[0]) && (re->gl_cap.depth_24_stencil_8[0])))
-           {
-              sfc->rb_depth_stencil_fmt = re->gl_cap.depth_24_stencil_8[0];
-              sfc->rb_stencil_fmt       = re->gl_cap.depth_24_stencil_8[0];
-              cfg->stencil_bits         = EVAS_GL_STENCIL_BIT_8;
-              break;
-           }
-         else if (re->gl_cap.stencil_8[0])
-           {
-              sfc->rb_stencil_fmt = re->gl_cap.stencil_8[0];
-              cfg->stencil_bits   = EVAS_GL_STENCIL_BIT_8;
-              break;
-           }
-      case EVAS_GL_STENCIL_BIT_16:
-         if (re->gl_cap.stencil_16[0])
-           {
-              sfc->rb_stencil_fmt = re->gl_cap.stencil_16[0];
-              cfg->stencil_bits   = EVAS_GL_STENCIL_BIT_16;
-              break;
-           }
-      default:
-         ERR("Unsupported Stencil Bits Format: %d", cfg->stencil_bits);
-         _print_gl_surface_cap(re, 1);
-         return 0;
+        *image_data = NULL;
+        if (err) *err = EVAS_LOAD_ERROR_NONE;
+        return im;
      }
 
-   if (cfg->options_bits)
-     {
-        if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT)
-          {
-             sfc->direct_fb_opt       = 1;
-             DBG("########################################################");
-             DBG("######### [Evas] Direct option bit is enabled ##########");
-             DBG("########################################################");
-          }
-        // Add other options here...
-     }
+#ifdef GL_GLES
+   eng_window_use(re->win);
 
-   // Multisample bit
-   if (re->gl_cap.msaa_support)
+   if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.img) && (im->cs.space == EVAS_COLORSPACE_ARGB8888))
      {
-        if ( ((int)(cfg->multisample_bits) > (int)EVAS_GL_MULTISAMPLE_HIGH) ||
-             ((int)(cfg->multisample_bits) < 0) )
-          {
-             ERR("Unsupported Multisample Bits Format!");
-             _print_gl_surface_cap(re, 1);
-             return 0;
-          }
-        else
+        if (im->tex->pt->dyn.checked_out > 0)
           {
-             sfc->rt_msaa_samples = re->gl_cap.msaa_samples[(int)cfg->multisample_bits];
+             im->tex->pt->dyn.checked_out++;
+             *image_data = im->tex->pt->dyn.data;
+             if (err) *err = EVAS_LOAD_ERROR_NONE;
+             return im;
           }
-     }
-
-   return 1;
-}
-
-static int
-_attach_fbo_surface(Render_Engine *data __UNUSED__,
-                    Render_Engine_GL_Surface *sfc,
-                    int fbo)
-{
-   int fb_status, curr_tex, curr_rb;
-
-   glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-
-   // Detach any previously attached buffers
-   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
-   glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
-   glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
-   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
-#else
-   glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
-#endif
-
-
-   // Render Target Texture
-   if (sfc->rt_tex)
-     {
-        curr_tex = 0;
-        glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_tex);
-        glBindTexture(GL_TEXTURE_2D, sfc->rt_tex );
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sfc->w, sfc->h, 0,
-                     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-        glBindTexture(GL_TEXTURE_2D, curr_tex);
-
-        if (sfc->rt_msaa_samples)
-           glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER,
-                                                   GL_COLOR_ATTACHMENT0,
-                                                   GL_TEXTURE_2D, sfc->rt_tex,
-                                                   0, sfc->rt_msaa_samples);
-        else
-           glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                                  GL_TEXTURE_2D, sfc->rt_tex, 0);
-     }
-
-   // Depth Stencil RenderBuffer - Attach it to FBO
-   if (sfc->rb_depth_stencil)
-     {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-        curr_tex = 0;
-        glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_tex);
-        glBindTexture(GL_TEXTURE_2D, sfc->rb_depth_stencil);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL_OES, sfc->w, sfc->h,
-                     0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES, NULL);
-        if (sfc->rt_msaa_samples)
+        if (im->gc->shared->info.sec_tbm_surface)
           {
-             glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER,
-                                                     GL_DEPTH_ATTACHMENT,
-                                                     GL_TEXTURE_2D,
-                                                     sfc->rb_depth_stencil,
-                                                     0, sfc->rt_msaa_samples);
-             glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER,
-                                                     GL_STENCIL_ATTACHMENT,
-                                                     GL_TEXTURE_2D,
-                                                     sfc->rb_depth_stencil,
-                                                     0, sfc->rt_msaa_samples);
+             tbm_surface_info_s info;
+             secsym_tbm_surface_map(im->tex->pt->dyn.buffer,
+                             TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE,
+                             &info);
+             *image_data = im->tex->pt->dyn.data = info.planes[0].ptr;
           }
-        else
+        else if (im->gc->shared->info.sec_image_map)
+          *image_data = im->tex->pt->dyn.data = glsym_eglMapImageSEC(re->win->egl_disp,
+                                                                     im->tex->pt->dyn.img,
+                                                                     EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC,
+                                                                     EGL_MAP_GL_TEXTURE_OPTION_WRITE_SEC);
+        if (!im->tex->pt->dyn.data)
           {
-        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-                               GL_TEXTURE_2D, sfc->rb_depth_stencil, 0);
-        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
-                               GL_TEXTURE_2D, sfc->rb_depth_stencil, 0);
+             if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+             GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+             return im;
           }
-        glBindTexture(GL_TEXTURE_2D, curr_tex);
-
-#else
-        curr_rb = 0;
-        glGetIntegerv(GL_RENDERBUFFER_BINDING, &curr_rb);
-        glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth_stencil);
-        glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_depth_stencil_fmt,
-                              sfc->w, sfc->h);
-        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
-                                  GL_RENDERBUFFER, sfc->rb_depth_stencil);
-        glBindRenderbuffer(GL_RENDERBUFFER, curr_rb);
-#endif
-     }
-
-   // Depth RenderBuffer - Attach it to FBO
-   if (sfc->rb_depth)
-     {
-        curr_rb = 0;
-        glGetIntegerv(GL_RENDERBUFFER_BINDING, &curr_rb);
-
-        glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth);
-
-        if (sfc->rt_msaa_samples)
-           glsym_glRenderbufferStorageMultisample(GL_RENDERBUFFER,
-                                                  sfc->rt_msaa_samples,
-                                                  sfc->rb_depth_fmt,
-                                                  sfc->w, sfc->h);
-        else
-           glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_depth_fmt,
-                                 sfc->w, sfc->h);
-        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-                                  GL_RENDERBUFFER, sfc->rb_depth);
-        glBindRenderbuffer(GL_RENDERBUFFER, curr_rb);
-     }
-
-   // Stencil RenderBuffer - Attach it to FBO
-   if (sfc->rb_stencil)
-     {
-        curr_rb = 0;
-        glGetIntegerv(GL_RENDERBUFFER_BINDING, &curr_rb);
-
-        glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_stencil);
-
-        if (sfc->rt_msaa_samples)
-           glsym_glRenderbufferStorageMultisample(GL_RENDERBUFFER,
-                                                  sfc->rt_msaa_samples,
-                                                  sfc->rb_stencil_fmt,
-                                                  sfc->w, sfc->h);
-        else
-           glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_stencil_fmt,
-                                 sfc->w, sfc->h);
-        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
-                                  GL_RENDERBUFFER, sfc->rb_stencil);
-        glBindRenderbuffer(GL_RENDERBUFFER, curr_rb);
-     }
+        im->tex->pt->dyn.checked_out++;
 
-   // Check FBO for completeness
-   fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-   if (fb_status != GL_FRAMEBUFFER_COMPLETE)
-     {
-        ERR("FBO not complete. Error Code: %x!", fb_status);
-        _print_gl_surface_info(sfc, 1);
-        return 0;
+        if (err) *err = EVAS_LOAD_ERROR_NONE;
+        return im;
      }
-
-   return 1;
-}
-
-static int
-_create_rt_buffers(Render_Engine *data __UNUSED__,
-                   Render_Engine_GL_Surface *sfc)
-{
-   int ret = 0;
-   GLuint fbo = 0, curr_fbo = 0;
-
-   //------------------------------------//
-   // Render Target texture
-   if (sfc->rt_fmt)
+#else
+   if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data))
      {
-        glGenTextures(1, &sfc->rt_tex);
+        *image_data = im->tex->pt->dyn.data;
+        if (err) *err = EVAS_LOAD_ERROR_NONE;
+        return im;
      }
 
-   // First check if packed buffer is to be used.
-   if (sfc->rb_depth_stencil_fmt)
-     {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-        glGenTextures(1, &sfc->rb_depth_stencil);
-#else
-        glGenRenderbuffers(1, &sfc->rb_depth_stencil);
+   eng_window_use(re->win);
 #endif
-     }
-   else
-     {
-        // Depth RenderBuffer - Create storage here...
-        if (sfc->rb_depth_fmt)
-           glGenRenderbuffers(1, &sfc->rb_depth);
 
-        // Stencil RenderBuffer - Create Storage here...
-        if (sfc->rb_stencil_fmt)
-           glGenRenderbuffers(1, &sfc->rb_stencil);
-     }
-   //------------------------------------//
-   // Try attaching the given configuration
-   glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo);
-   glGenFramebuffers(1 ,&fbo);
-
-   ret = _attach_fbo_surface(NULL, sfc, fbo);
+   /* Engine can be fail to create texture after cache drop like eng_image_content_hint_set function,
+        so it is need to add code which check im->im's NULL value*/
 
-   if (fbo) glDeleteFramebuffers(1, &fbo);
-   glBindFramebuffer(GL_FRAMEBUFFER, curr_fbo);
+   if (!im->im)
+    {
+       *image_data = NULL;
+       if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+       return NULL;
+    }
 
-   if (!ret)
+   error = evas_cache_image_load_data(&im->im->cache_entry);
+   evas_gl_common_image_alloc_ensure(im);
+   switch (im->cs.space)
      {
-        if (sfc->rt_tex) glDeleteTextures(1, &sfc->rt_tex);
-        if (sfc->rb_depth) glDeleteRenderbuffers(1, &sfc->rb_depth);
-        if (sfc->rb_stencil) glDeleteRenderbuffers(1, &sfc->rb_stencil);
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-        if (sfc->rb_depth_stencil) glDeleteTextures(1, &sfc->rb_depth_stencil);
-#else
-        if (sfc->rb_depth_stencil) glDeleteRenderbuffers(1, &sfc->rb_depth_stencil);
-#endif
-        ERR("_attach_fbo_surface() failed.");
-        return 0;
+      case EVAS_COLORSPACE_ARGB8888:
+      case EVAS_COLORSPACE_AGRY88:
+      case EVAS_COLORSPACE_GRY8:
+         if (to_write)
+           {
+              if (im->references > 1)
+                {
+                   Evas_GL_Image *im_new;
+
+                   im_new = evas_gl_common_image_new_from_copied_data
+                      (im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
+                       im->im->image.data,
+                       eng_image_alpha_get(data, image),
+                       eng_image_colorspace_get(data, image));
+                   if (!im_new)
+                     {
+                        *image_data = NULL;
+                        if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+                        return NULL;
+                     }
+                   evas_gl_common_image_free(im);
+                   im = im_new;
+                }
+              else
+                evas_gl_common_image_dirty(im, 0, 0, 0, 0);
+           }
+         *image_data = im->im->image.data;
+         break;
+      case EVAS_COLORSPACE_YCBCR422P601_PL:
+      case EVAS_COLORSPACE_YCBCR422P709_PL:
+      case EVAS_COLORSPACE_YCBCR422601_PL:
+      case EVAS_COLORSPACE_YCBCR420NV12601_PL:
+      case EVAS_COLORSPACE_YCBCR420TM12601_PL:
+         *image_data = im->cs.data;
+         break;
+      case EVAS_COLORSPACE_ETC1:
+      case EVAS_COLORSPACE_RGB8_ETC2:
+      case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+      case EVAS_COLORSPACE_ETC1_ALPHA:
+         ERR("This image is encoded in ETC1 or ETC2, not returning any data");
+         error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+         *image_data = NULL;
+         break;
+      default:
+         abort();
+         break;
      }
-   else
-      return 1;
+   if (err) *err = error;
+   return im;
 }
 
-
 static void *
-eng_gl_surface_create(void *data, void *config, int w, int h)
+eng_image_data_put(void *data, void *image, DATA32 *image_data)
 {
    Render_Engine *re;
-   Render_Engine_GL_Surface *sfc;
-   Render_Engine_GL_Resource *rsc;
-   Evas_GL_Config *cfg;
-   void *ret = NULL;
-   int res;
-
-   re  = (Render_Engine *)data;
-   cfg = (Evas_GL_Config *)config;
-
-   // Allocate surface and fill in values
-   sfc = calloc(1, sizeof(Render_Engine_GL_Surface));
-   if (!sfc)
-     {
-        ERR("Surface allocation failed.");
-        goto finish;
-     }
-
-   sfc->w            = w;
-   sfc->h            = h;
-   sfc->depth_bits   = cfg->depth_bits;
-   sfc->stencil_bits = cfg->stencil_bits;
-
-   // Allow alpha for evas gl direct rendering override
-   // FIXME!!!: A little out of place but for now...
-   if (!gl_direct_override)
-      if (getenv("EVAS_GL_DIRECT_OVERRIDE")) gl_direct_override = 1;
+   Evas_GL_Image *im, *im2;
 
-   // Set the internal format based on the config
-   if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT)
+   re = (Render_Engine *)data;
+   if (!image) return NULL;
+   im = image;
+   if (im->native.data) return image;
+   eng_window_use(re->win);
+   evas_gl_common_image_alloc_ensure(im);
+   if ((im->tex) && (im->tex->pt)
+       && (im->tex->pt->dyn.data)
+       && (im->cs.space == EVAS_COLORSPACE_ARGB8888))
      {
-        DBG("Enabling Direct rendering to the Evas' window.");
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-        sfc->direct_sfc = re->win->egl_surface[0];
-#else
-        sfc->direct_sfc = re->win->win;
+        if (im->tex->pt->dyn.data == image_data)
+          {
+             if (im->tex->pt->dyn.checked_out > 0)
+               {
+                 im->tex->pt->dyn.checked_out--;
+#ifdef GL_GLES
+                 if (im->tex->pt->dyn.checked_out == 0)
+                   {
+                      if (im->gc->shared->info.sec_tbm_surface) secsym_tbm_surface_unmap(im->tex->pt->dyn.buffer);
+                      else if (im->gc->shared->info.sec_image_map) glsym_eglUnmapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img, EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC);
+                   }
 #endif
-     }
-
-   // Use resource surface/context to do a make current
-   if (!_internal_resources_make_current(re))
-     {
-        ERR("Error doing a make current with the internal resources.");
-        goto finish;
-     }
-
-   // Set the engine surface capability first if it hasn't been set
-   if (!re->gl_cap_initted) _set_gl_surface_cap(re);
+                }
 
-   // Check the size of the surface
-   if ( (w > re->gl_cap.max_rb_size) || (h > re->gl_cap.max_rb_size) )
-     {
-        ERR("Surface size greater than the supported size. Max Surface Size: %d", re->gl_cap.max_rb_size);
-        goto finish;
+             return image;
+          }
+        im2 = eng_image_new_from_data(data, im->w, im->h, image_data,
+                                      eng_image_alpha_get(data, image),
+                                      eng_image_colorspace_get(data, image));
+        if (!im2) return im;
+        evas_gl_common_image_free(im);
+        im = im2;
+        evas_gl_common_image_dirty(im, 0, 0, 0, 0);
+        return im;
      }
-
-   // Set the internal config value
-   if (!_set_internal_config(re, sfc, cfg))
+   switch (im->cs.space)
      {
-        ERR("Unsupported Format!");
-        goto finish;
+      case EVAS_COLORSPACE_ARGB8888:
+         if ((!im->im) || (image_data != im->im->image.data))
+           {
+              im2 = eng_image_new_from_data(data, im->w, im->h, image_data,
+                                            eng_image_alpha_get(data, image),
+                                            eng_image_colorspace_get(data, image));
+              if (!im2) return im;
+              evas_gl_common_image_free(im);
+              im = im2;
+           }
+         break;
+      case EVAS_COLORSPACE_YCBCR422P601_PL:
+      case EVAS_COLORSPACE_YCBCR422P709_PL:
+      case EVAS_COLORSPACE_YCBCR422601_PL:
+      case EVAS_COLORSPACE_YCBCR420NV12601_PL:
+      case EVAS_COLORSPACE_YCBCR420TM12601_PL:
+         if (image_data != im->cs.data)
+           {
+              if (im->cs.data)
+                {
+                   if (!im->cs.no_free) free(im->cs.data);
+                }
+              im->cs.data = image_data;
+           }
+         evas_gl_common_image_dirty(im, 0, 0, 0, 0);
+         break;
+      default:
+         abort();
+         break;
      }
+   return im;
+}
 
-   // Create Render texture
-   if (!_create_rt_buffers(re, sfc))
-     {
-        ERR("Unable Create Specificed Surfaces.  Unsupported format!");
-        goto finish;
-     };
-
-   ret = sfc;
+static void
+eng_image_data_preload_request(void *data __UNUSED__, void *image, const void *target)
+{
+   Evas_GL_Image *gim = image;
+   RGBA_Image *im;
 
-finish:
+   if (!gim) return;
+   if (gim->native.data) return;
+   im = (RGBA_Image *)gim->im;
+   if (!im) return;
+   evas_cache_image_preload_data(&im->cache_entry, target);
+}
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   res = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-#else
-   res = glXMakeCurrent(re->info->info.display, None, NULL);
-#endif
-   if (!res)
-     {
-        ERR("xxxMakeCurrent() (NULL, NULL) Error!");
-     }
+static void
+eng_image_data_preload_cancel(void *data __UNUSED__, void *image, const void *target)
+{
+   Evas_GL_Image *gim = image;
+   RGBA_Image *im;
 
-   if (!ret)
-     {
-        if (sfc) free(sfc);
-     }
-   return ret;
+   if (!gim) return;
+   if (gim->native.data) return;
+   im = (RGBA_Image *)gim->im;
+   if (!im) return;
+   evas_cache_image_preload_cancel(&im->cache_entry, target);
 }
 
-static int
-eng_gl_surface_destroy(void *data, void *surface)
+static void
+eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth)
 {
    Render_Engine *re;
-   Render_Engine_GL_Surface *sfc;
-   Render_Engine_GL_Resource *rsc;
-   int ret;
-
-   re  = (Render_Engine *)data;
-   sfc = (Render_Engine_GL_Surface*)surface;
+   re = (Render_Engine *)data;
+   Evas_GL_Image *im = image;
+   Evas_GL_Image *surf = surface;
+   Native *n;
 
-   if (!sfc) return 0;
+   if (!im) return;
+   n = im->native.data;
 
-   // Use resource surface/context to create surface resrouces
-   if (!_internal_resources_make_current(re))
+   if (eng_image_direct_get(data, image))
      {
-        ERR("Error doing a make current with the internal resources.");
-        return 0;
-     }
+        int map_tex = 0;
+        void *direct_surface = NULL;
+        //DBG("Rendering Directly to the window: %p", data);
 
-   // Reset the Framebuffer binding point
-   if ((current_evgl_ctx) && (current_evgl_ctx->current_fbo == current_evgl_ctx->context_fbo))
-     {
-        //glBindFramebuffer(GL_FRAMEBUFFER, 0);
-        current_evgl_ctx->current_fbo = 0;
-        current_evgl_ctx->current_sfc = NULL;
-     }
+        re->win->gl_context->dc = context;
+        if (surface != re->win->gl_context->def_surface)
+          {
+             map_tex = surf->tex->pt->texture;
+             dst_y = re->win->gl_context->h - dst_y - dst_h;
+          }
 
-   // Clear direct rendering flag
-   gl_direct_enabled = 0;
+        // Call end tile if it's being used
+        if ((re->win->gl_context->master_clip.enabled) &&
+            (re->win->gl_context->master_clip.w > 0) &&
+            (re->win->gl_context->master_clip.h > 0))
+          {
+             // Pass the preserve flag info the evas_gl
+             evgl_direct_partial_info_set(re->win->gl_context->preserve_bit);
+          }
 
-   // Delete FBO/RBO and Texture here
-   if (sfc->rt_tex)
-      glDeleteTextures(1, &sfc->rt_tex);
+        re->func.x = re->win->gl_context->dc->clip.x;
+        re->func.y = re->win->gl_context->dc->clip.y;
+        re->func.w = re->win->gl_context->dc->clip.w;
+        re->func.h = re->win->gl_context->dc->clip.h;
 
-   if (sfc->rb_depth)
-      glDeleteRenderbuffers(1, &sfc->rb_depth);
+        if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
+          direct_surface = n->ns.data.evasgl.surface;
+        else
+          {
+             ERR("This native surface type is not supported for direct rendering");
+             return;
+          }
 
-   if (sfc->rb_stencil)
-      glDeleteRenderbuffers(1, &sfc->rb_stencil);
+        // Set necessary info for direct rendering
+        evgl_direct_info_set(re->win->gl_context->w,
+                             re->win->gl_context->h,
+                             map_tex?0:re->win->gl_context->rot,
+                             map_tex,
+                             dst_x, dst_y, dst_w, dst_h,
+                             re->win->gl_context->dc->clip.x,
+                             re->win->gl_context->dc->clip.y,
+                             re->win->gl_context->dc->clip.w,
+                             re->win->gl_context->dc->clip.h,
+                             direct_surface);
+
+        // Call pixel get function
+        re->func.get_pixels(re->func.get_pixels_data, re->func.obj);
+        re->context_current = EINA_FALSE;
+
+        // Call end tile if it's being used
+        if ((re->win->gl_context->master_clip.enabled) &&
+            (re->win->gl_context->master_clip.w > 0) &&
+            (re->win->gl_context->master_clip.h > 0))
+          {
+             evgl_direct_partial_render_end();
+             evgl_direct_partial_info_clear();
+             re->win->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM;
+          }
 
-   if (sfc->rb_depth_stencil)
-     {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-        glDeleteTextures(1, &sfc->rb_depth_stencil);
-#else
-        glDeleteRenderbuffers(1, &sfc->rb_depth_stencil);
-#endif
+        // Reset direct rendering info
+        evgl_direct_info_clear();
      }
-
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-#else
-   ret = glXMakeCurrent(re->info->info.display, None, NULL);
-#endif
-   if (!ret)
+   else
      {
-        ERR("xxxMakeCurrent() failed!");
-        free(sfc);
-        return 0;
+        if (re->context_optimize)
+          {
+             if (!re->context_current)
+               {
+                  re->context_current = EINA_TRUE;
+                  eng_window_use(re->win);
+               }
+          }
+        else
+           eng_window_use(re->win);
+
+        evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
+        re->win->gl_context->dc = context;
+        re->win->gl_context->depth = re->win->depth;
+        evas_gl_common_image_draw(re->win->gl_context, image,
+                                  src_x, src_y, src_w, src_h,
+                                  dst_x, dst_y, dst_w, dst_h,
+                                  smooth);
      }
+}
 
-   free(sfc);
-   surface = NULL;
+static void
+eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint)
+{
+   if (image) evas_gl_common_image_scale_hint_set(image, hint);
+}
 
-   return 1;
+static int
+eng_image_scale_hint_get(void *data __UNUSED__, void *image)
+{
+   Evas_GL_Image *gim = image;
+   if (!gim) return EVAS_IMAGE_SCALE_HINT_NONE;
+   return gim->scale_hint;
 }
 
-static void *
-eng_gl_context_create(void *data, void *share_context)
+static void
+eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level)
 {
+   Evas_GL_Image *gim = image;
    Render_Engine *re;
-   Render_Engine_GL_Context *ctx;
-   Render_Engine_GL_Context *share_ctx;
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   int context_attrs[3];
-#endif
-
-   ctx = calloc(1, sizeof(Render_Engine_GL_Context));
-
-   if (!ctx) return NULL;
 
    re = (Render_Engine *)data;
-   share_ctx = (Render_Engine_GL_Context *)share_context;
-
-   // Set the share context to Evas' GL context if share_context is NULL.
-   // Otherwise set it to the given share_context.
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   // EGL
-   context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
-   context_attrs[1] = 2;
-   context_attrs[2] = EGL_NONE;
+   if (!image) return;
 
-   if (share_ctx)
+   if (re->context_optimize)
      {
-        ctx->context = eglCreateContext(re->win->egl_disp,
-                                        re->win->egl_config,
-                                        share_ctx->context,      // Share Context
-                                        context_attrs);
+        if (!re->context_current)
+          {
+             re->context_current = EINA_TRUE;
+             eng_window_use(re->win);
+          }
      }
    else
-     {
-        ctx->context = eglCreateContext(re->win->egl_disp,
-                                        re->win->egl_config,
-                                        re->win->egl_context[0], // Evas' GL Context
-                                        context_attrs);
-     }
+      eng_window_use(re->win);
 
-   if (!ctx->context)
+   evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
+   re->win->gl_context->dc = context;
+   if (m->count != 4)
      {
-        ERR("eglCreateContext() fail. code=%#x", eglGetError());
-        return NULL;
+        // FIXME: nash - you didn't fix this
+        abort();
      }
-#else
-   // GLX
-   if (share_context)
+   if ((m->pts[0].x == m->pts[3].x) &&
+       (m->pts[1].x == m->pts[2].x) &&
+       (m->pts[0].y == m->pts[1].y) &&
+       (m->pts[3].y == m->pts[2].y) &&
+       (m->pts[0].x <= m->pts[1].x) &&
+       (m->pts[0].y <= m->pts[2].y) &&
+       (m->pts[0].u == 0) &&
+       (m->pts[0].v == 0) &&
+       (m->pts[1].u == (gim->w << FP)) &&
+       (m->pts[1].v == 0) &&
+       (m->pts[2].u == (gim->w << FP)) &&
+       (m->pts[2].v == (gim->h << FP)) &&
+       (m->pts[3].u == 0) &&
+       (m->pts[3].v == (gim->h << FP)) &&
+       (m->pts[0].col == 0xffffffff) &&
+       (m->pts[1].col == 0xffffffff) &&
+       (m->pts[2].col == 0xffffffff) &&
+       (m->pts[3].col == 0xffffffff))
      {
-        ctx->context = glXCreateContext(re->info->info.display,
-                                        re->win->visualinfo,
-                                        share_ctx->context,    // Share Context
-                                        1);
+        int dx, dy, dw, dh;
+
+        dx = m->pts[0].x >> FP;
+        dy = m->pts[0].y >> FP;
+        dw = (m->pts[2].x >> FP) - dx;
+        dh = (m->pts[2].y >> FP) - dy;
+
+        eng_image_draw(data, context, surface, image,
+                       0, 0, gim->w, gim->h, dx, dy, dw, dh, smooth);
      }
    else
      {
-        ctx->context = glXCreateContext(re->info->info.display,
-                                        re->win->visualinfo,
-                                        re->win->context,      // Evas' GL Context
-                                        1);
+        evas_gl_common_image_map_draw(re->win->gl_context, image, m->count, &m->pts[0],
+                                      smooth, level);
      }
+}
 
-   if (!ctx->context)
-     {
-        ERR("glXCreateContext() fail.");
-        return NULL;
-     }
-#endif
+static void
+eng_image_map_clean(void *data __UNUSED__, RGBA_Map *m __UNUSED__)
+{
+}
 
-   ctx->initialized = 0;
-   ctx->context_fbo = 0;
-   ctx->current_sfc = NULL;
+static void *
+eng_image_map_surface_new(void *data, int w, int h, int alpha)
+{
+   Render_Engine *re;
 
-   return ctx;
+   re = (Render_Engine *)data;
+   eng_window_use(re->win);
+   return evas_gl_common_image_surface_new(re->win->gl_context, w, h, alpha);
 }
 
-static int
-eng_gl_context_destroy(void *data, void *context)
+static void
+eng_image_map_surface_free(void *data, void *surface)
 {
    Render_Engine *re;
-   Render_Engine_GL_Context *ctx;
-   Render_Engine_GL_Resource *rsc;
-   int ret;
 
-   re  = (Render_Engine *)data;
-   ctx = (Render_Engine_GL_Context*)context;
+   re = (Render_Engine *)data;
+   eng_window_use(re->win);
+   evas_gl_common_image_free(surface);
+}
+
+static void *
+eng_image_scaled_update(void *data EINA_UNUSED, void *scaled, void *image,
+                        int dst_w, int dst_h,
+                        Eina_Bool smooth, Eina_Bool alpha,
+                        Evas_Colorspace cspace EINA_UNUSED)
+{
+   Evas_GL_Image *dst = scaled;
+   Evas_GL_Image *src = image;
+   Evas_Engine_GL_Context *gc;
+   Eina_Bool reffed = EINA_FALSE;
+
+   if (!src) return NULL;
 
-   if (!ctx) return 0;
+   gc = src->gc;
+   if (dst && (dst->scaled.origin == src) &&
+       (dst->scaled.w == dst_w) && (dst->scaled.h == dst_h))
+     return dst;
 
-   // Use resource surface/context to create surface resrouces
-   if (!_internal_resources_make_current(re))
+   if (dst)
      {
-        ERR("Error doing a make current with the internal resources.");
-        return 0;
+        if (dst->scaled.origin == src)
+          {
+             src->references++;
+             reffed = EINA_TRUE;
+          }
+        evas_gl_common_image_free(dst);
+     }
+   evas_gl_common_image_update(gc, src);
+   if (!src->tex)
+     {
+        ERR("No source texture.");
+        return NULL;
      }
 
-   // Delete the FBO
-   if (ctx->context_fbo)
-      glDeleteFramebuffers(1, &ctx->context_fbo);
+   dst = calloc(1, sizeof(Evas_GL_Image));
+   if (!dst) return NULL;
 
-   // Destroy the Context
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   eglDestroyContext(re->win->egl_disp, ctx->context);
+   dst->references = 1;
+   dst->gc = gc;
+   dst->cs.space = src->cs.space;
+   dst->alpha = alpha;
+   dst->w = src->w;
+   dst->h = src->h;
+   dst->tex = src->tex;
+   dst->tex->references++;
+   dst->tex_only = 1;
 
-   ctx->context = EGL_NO_CONTEXT;
+   if (!reffed) src->references++;
+   dst->scaled.origin = src;
+   dst->scaled.w = dst_w;
+   dst->scaled.h = dst_h;
+   dst->scaled.smooth = smooth;
 
-   ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE,
-                        EGL_NO_SURFACE, EGL_NO_CONTEXT);
-#else
-   glXDestroyContext(re->info->info.display, ctx->context);
-
-   ctx->context = 0;
-
-   ret = glXMakeCurrent(re->info->info.display, None, NULL);
-#endif
-   if (!ret)
-     {
-        ERR("xxxMakeCurrent() failed!");
-        return 0;
-     }
-
-   if (ctx == current_evgl_ctx)
-     current_evgl_ctx = NULL;
+   return dst;
+}
 
-   free(ctx);
-   context = NULL;
+static void
+eng_image_content_hint_set(void *data, void *image, int hint)
+{
+   Render_Engine *re;
+   re = (Render_Engine *)data;
 
-   return 1;
+   if (re) eng_window_use(re->win);
+   if (image) evas_gl_common_image_content_hint_set(image, hint);
 }
 
 static int
-eng_gl_make_current(void *data __UNUSED__, void *surface, void *context)
+eng_image_content_hint_get(void *data __UNUSED__, void *image)
 {
-   Render_Engine *re;
-   Render_Engine_GL_Surface *sfc;
-   Render_Engine_GL_Context *ctx;
-   int ret = 0;
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   Render_Engine_GL_Resource *rsc;
-#endif
+   Evas_GL_Image *gim = image;
+   if (!gim) return EVAS_IMAGE_CONTENT_HINT_NONE;
+   return gim->content_hint;
+}
 
-   re  = (Render_Engine *)data;
-   sfc = (Render_Engine_GL_Surface*)surface;
-   ctx = (Render_Engine_GL_Context*)context;
+static void
+eng_image_cache_flush(void *data)
+{
+   Render_Engine *re;
+   int tmp_size;
 
-   current_engine = re;
+   re = (Render_Engine *)data;
 
-   // Unset surface/context
-   if ((!sfc) || (!ctx))
-     {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-        ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE,
-                             EGL_NO_SURFACE, EGL_NO_CONTEXT);
-#else
-        ret = glXMakeCurrent(re->info->info.display, None, NULL);
-#endif
-        if (!ret)
-          {
-             ERR("xxxMakeCurrent() failed!");
-             return 0;
-          }
+   eng_window_use(re->win);
 
-        if (ctx) ctx->current_sfc = NULL;
-        if (sfc) sfc->current_ctx = NULL;
-        current_evgl_ctx = NULL;
-        return 1;
-     }
+   tmp_size = evas_common_image_get_cache();
+   evas_common_image_set_cache(0);
+   evas_common_rgba_image_scalecache_flush();
+   evas_gl_common_image_cache_flush(re->win->gl_context);
+   evas_common_image_set_cache(tmp_size);
+}
 
-   // Check if direct rendering is possible:
-   //    It's possible when direct_fb_opt is on and either current image
-   //    object is valid or gl_direct_override is on.  Override allows
-   //    rendering outside of pixel getter but it doesn't guarantee
-   //    correct rendering.
-   if ((sfc->direct_fb_opt) && (gl_direct_img_obj || gl_direct_override))
-     {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-        sfc->direct_sfc = re->win->egl_surface[0];
-#else
-        sfc->direct_sfc = re->win->win;
-#endif
-        gl_direct_enabled = 1;
-     }
-   else
-      gl_direct_enabled = 0;
+static void
+eng_image_cache_set(void *data, int bytes)
+{
+   Render_Engine *re;
 
-   if (gl_direct_enabled)
-     {
-        int curr_fbo = 0;
+   re = (Render_Engine *)data;
 
-        // Do a make current only if it's not already current
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-        if ((eglGetCurrentContext() != ctx->context) ||
-            (eglGetCurrentSurface(EGL_READ) != sfc->direct_sfc) ||
-            (eglGetCurrentSurface(EGL_DRAW) != sfc->direct_sfc) )
-          {
-             DBG("Rendering Directly to the window\n");
+   eng_window_use(re->win);
 
-             // Flush remainder of what's in Evas' pipeline
-             eng_window_use(NULL);
+   evas_common_image_set_cache(bytes);
+   evas_common_rgba_image_scalecache_size_set(bytes);
+   evas_gl_common_image_cache_flush(re->win->gl_context);
+}
 
-             // Do a make current
-             ret = eglMakeCurrent(re->win->egl_disp, sfc->direct_sfc,
-                                  sfc->direct_sfc, ctx->context);
-             if (!ret)
-               {
-                  ERR("xxxMakeCurrent() failed! code=%#x", eglGetError());
-                  //ERR("xxxMakeCurrent() failed!");
-                  return 0;
-               }
-          }
-#else
-        if ((glXGetCurrentContext() != ctx->context))
-          {
-             // Flush remainder of what's in Evas' pipeline
-             eng_window_use(NULL);
+static int
+eng_image_cache_get(void *data __UNUSED__)
+{
+   return evas_common_image_get_cache();
+}
 
-             // Do a make current
-             ret = glXMakeCurrent(re->info->info.display, sfc->direct_sfc, ctx->context);
-             if (!ret)
-               {
-                  ERR("xxxMakeCurrent() failed!");
-                  return 0;
-               }
-          }
-#endif
-        glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo);
-        if (ctx->context_fbo == curr_fbo)
-          {
-             ctx->current_fbo = 0;
-             glBindFramebuffer(GL_FRAMEBUFFER, 0);
-          }
+static void
+eng_image_stride_get(void *data __UNUSED__, void *image, int *stride)
+{
+   Evas_GL_Image *im = image;
 
-     }
+   if ((im->tex) && (im->tex->pt->dyn.img))
+     *stride = im->tex->pt->dyn.stride;
    else
      {
-        // Do a make current only if it's not already current
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-        if (eina_main_loop_is())
+        switch (im->cs.space)
           {
-             if ((eglGetCurrentContext() != ctx->context) ||
-                 (eglGetCurrentSurface(EGL_READ) != re->win->egl_surface[0]) ||
-                 (eglGetCurrentSurface(EGL_DRAW) != re->win->egl_surface[0]) )
-               {
-
-                  // Flush remainder of what's in Evas' pipeline
-                  eng_window_use(NULL);
-
-                  // Do a make current
-                  ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0],
-                                             re->win->egl_surface[0], ctx->context);
-                  if (!ret)
-                    {
-                       ERR("xxxMakeCurrent() failed! code=%#x", eglGetError());
-                       return 0;
-                    }
-               }
+           case EVAS_COLORSPACE_ARGB8888:
+             *stride = im->w * 4;
+             return;
+           case EVAS_COLORSPACE_AGRY88:
+             *stride = im->w * 2;
+             return;
+           case EVAS_COLORSPACE_GRY8:
+             *stride = im->w * 1;
+             return;
+           case EVAS_COLORSPACE_YCBCR422P601_PL:
+           case EVAS_COLORSPACE_YCBCR422P709_PL:
+           case EVAS_COLORSPACE_YCBCR422601_PL:
+           case EVAS_COLORSPACE_YCBCR420NV12601_PL:
+           case EVAS_COLORSPACE_YCBCR420TM12601_PL:
+             *stride = im->w * 1;
+             return;
+           default:
+             ERR("Requested stride on an invalid format %d", im->cs.space);
+             *stride = 0;
+             return;
           }
-        else
-          {
-             if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0;
-
-             if ((eglGetCurrentContext() != ctx->context) ||
-                 (eglGetCurrentSurface(EGL_READ) != rsc->surface) ||
-                 (eglGetCurrentSurface(EGL_DRAW) != rsc->surface) )
-               {
-                  // Flush remainder of what's in Evas' pipeline
-                  eng_window_use(NULL);
+     }
+}
 
-                  // Do a make current
-                  ret = eglMakeCurrent(re->win->egl_disp, rsc->surface,
-                                             rsc->surface, ctx->context);
-                  if (!ret)
-                    {
-                       ERR("xxxMakeCurrent() failed!");
-                       return 0;
-                    }
-               }
-          }
-#else
-        if ((glXGetCurrentContext() != ctx->context) ||
-            (glXGetCurrentDrawable() != re->win->win) )
-          {
-             // Flush remainder of what's in Evas' pipeline
-             eng_window_use(NULL);
+static void
+eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font __UNUSED__, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, Evas_Text_Props *intl_props)
+{
+   Render_Engine *re;
 
-             // Do a make current
-             ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context);
-             if (!ret)
-               {
-                  ERR("xxxMakeCurrent() failed!");
-                  return 0;
-               }
-          }
-#endif
+   re = (Render_Engine *)data;
 
-        // Create FBO if not already created
-        if (!ctx->initialized)
+   if (re->context_optimize)
+     {
+        if (!re->context_current)
           {
-             glGenFramebuffers(1, &ctx->context_fbo);
-             ctx->initialized = 1;
+             re->context_current = EINA_TRUE;
+             eng_window_use(re->win);
           }
+     }
+   else
+      eng_window_use(re->win);
 
-        // Attach FBO if it hasn't been attached or if surface changed
-        if ((!sfc->fbo_attached) || (ctx->current_sfc != sfc))
-          {
-             if (!_attach_fbo_surface(re, sfc, ctx->context_fbo))
-               {
-                  ERR("_attach_fbo_surface() failed.");
-                  _print_gl_surface_info(sfc, 1);
-                  return 0;
-               }
+   evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
+   re->win->gl_context->dc = context;
+     {
+        // FIXME: put im into context so we can free it
+        static RGBA_Image *im = NULL;
 
-             if (ctx->current_fbo)
-                // Bind to the previously bound buffer
-                glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
-             else
-                // Bind FBO
-                glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo);
+        if (!im)
+          im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
+        im->cache_entry.w = re->win->gl_context->shared->w;
+        im->cache_entry.h = re->win->gl_context->shared->h;
 
-             sfc->fbo_attached = 1;
-          }
+        evas_common_draw_context_font_ext_set(context,
+                                              re->win->gl_context,
+                                              evas_gl_font_texture_new,
+                                              evas_gl_font_texture_free,
+                                              evas_gl_font_texture_draw);
+        evas_common_font_draw_prepare(intl_props);
+        evas_common_font_draw(im, context, x, y, intl_props);
+        evas_common_draw_context_font_ext_set(context,
+                                              NULL,
+                                              NULL,
+                                              NULL,
+                                              NULL);
      }
+}
 
-   // Set the current surface/context
-   ctx->current_sfc = sfc;
-   sfc->current_ctx = ctx;
-   current_evgl_ctx = ctx;
-   current_engine = re;
-
-   return 1;
+static Eina_Bool
+eng_canvas_alpha_get(void *data, void *info __UNUSED__)
+{
+   Render_Engine *re = (Render_Engine *)data;
+   return re->win->alpha;
 }
 
+//--------------------------------//
+// Evas GL Related Code
 static void *
-eng_gl_string_query(void *data __UNUSED__, int name)
+eng_gl_surface_create(void *data, void *config, int w, int h)
 {
-   switch(name)
+   Evas_GL_Config *cfg = (Evas_GL_Config *)config;
+   const GLubyte *vendor = glGetString(GL_VENDOR);
+
+   // TIZEN_ONLY : disable partial rendering during direct rendering
+   prev_extn_have_buffer_age = extn_have_buffer_age;
+   if ((cfg->options_bits & EVAS_GL_OPTIONS_DIRECT)
+        && (!getenv("EVAS_GL_PARTIAL_DISABLE")))
      {
-      case EVAS_GL_EXTENSIONS:
-         return (void*)_evasgl_ext_string;
-      default:
-         return NULL;
-     };
+        extn_have_buffer_age = 0;
+     }
+
+   return evgl_surface_create(data, cfg, 0, NULL, w, h);
 }
 
 static void *
-eng_gl_proc_address_get(void *data __UNUSED__, const char *name)
+eng_gl_pbuffer_surface_create(void *data, void *config, int w, int h, const int *attrib_list)
 {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   if (glsym_eglGetProcAddress) return glsym_eglGetProcAddress(name);
-   return dlsym(RTLD_DEFAULT, name);
-#else
-   if (glsym_glXGetProcAddress) return glsym_glXGetProcAddress(name);
-   return dlsym(RTLD_DEFAULT, name);
-#endif
+   Evas_GL_Config *cfg = (Evas_GL_Config *)config;
+
+   return evgl_pbuffer_surface_create(data, cfg, w, h, attrib_list);
 }
 
 static int
-eng_gl_native_surface_get(void *data __UNUSED__, void *surface, void *native_surface)
+eng_gl_surface_destroy(void *data, void *surface)
 {
-   Render_Engine_GL_Surface *sfc;
-   Evas_Native_Surface *ns;
-
-   sfc = (Render_Engine_GL_Surface*)surface;
-   ns  = (Evas_Native_Surface*)native_surface;
+   EVGL_Surface  *sfc = (EVGL_Surface *)surface;
+   Render_Engine *re = (Render_Engine *)data;
 
-   if (sfc->direct_fb_opt)
-     {
-        ns->type = EVAS_NATIVE_SURFACE_OPENGL;
-        ns->version = EVAS_NATIVE_SURFACE_VERSION;
-        ns->data.opengl.texture_id = sfc->rt_tex;
-        ns->data.opengl.framebuffer_id = 0;
-        ns->data.opengl.x = 0;
-        ns->data.opengl.y = 0;
-        ns->data.opengl.w = sfc->w;
-        ns->data.opengl.h = sfc->h;
-     }
-   else
+   if ((extn_have_buffer_age  != 1)
+        && (extn_have_buffer_age != prev_extn_have_buffer_age)
+        && (!getenv("EVAS_GL_PARTIAL_DISABLE")))
      {
-        ns->type = EVAS_NATIVE_SURFACE_OPENGL;
-        ns->version = EVAS_NATIVE_SURFACE_VERSION;
-        ns->data.opengl.texture_id = sfc->rt_tex;
-        ns->data.opengl.framebuffer_id = sfc->rt_tex;
-        ns->data.opengl.x = 0;
-        ns->data.opengl.y = 0;
-        ns->data.opengl.w = sfc->w;
-        ns->data.opengl.h = sfc->h;
+        extn_have_buffer_age = prev_extn_have_buffer_age;
      }
 
-   return 1;
+   return evgl_surface_destroy(data, sfc);
 }
 
+static void *
+eng_gl_context_create(void *data, void *share_context,
+                      int version)
+{
+   EVGL_Context  *sctx = (EVGL_Context *)share_context;
+
+   return evgl_context_create(data, sctx, version);
+}
 
-static const GLubyte *
-evgl_glGetString(GLenum name)
+static int
+eng_gl_context_destroy(void *data, void *context)
 {
-   if (name == GL_EXTENSIONS)
-      return (GLubyte *)_gl_ext_string; //glGetString(GL_EXTENSIONS);
-   else
-      return glGetString(name);
+   EVGL_Context  *ctx = (EVGL_Context *)context;
+
+   return evgl_context_destroy(data, ctx);
 }
 
-static void
-evgl_glBindFramebuffer(GLenum target, GLuint framebuffer)
+static int
+eng_gl_make_current(void *data, void *surface, void *context)
 {
-   Render_Engine_GL_Context *ctx = current_evgl_ctx;
+   Render_Engine *re  = (Render_Engine *)data;
+   EVGL_Surface  *sfc = (EVGL_Surface *)surface;
+   EVGL_Context  *ctx = (EVGL_Context *)context;
 
-   if (!ctx)
-     {
-        ERR("No current context set.");
-        return;
-     }
+   EVGL_Resource *rsc = _evgl_tls_resource_get();
 
-   // Take care of BindFramebuffer 0 issue
-   if (framebuffer==0)
+   if ((sfc) && (ctx) && (rsc) && (rsc->id == evgl_engine->main_tid))
      {
-        if (gl_direct_enabled)
-           glBindFramebuffer(target, 0);
-        else
-           glBindFramebuffer(target, ctx->context_fbo);
-        ctx->current_fbo = 0;
+        if ((re->win->gl_context->havestuff) ||
+            (re->win->gl_context->master_clip.used))
+          {
+             eng_window_use(re->win);
+             evas_gl_common_context_flush(re->win->gl_context);
+             if (re->win->gl_context->master_clip.used)
+                evas_gl_common_context_done(re->win->gl_context);
+          }
      }
-   else
-     {
-        glBindFramebuffer(target, framebuffer);
 
-        // Save this for restore when doing make current
-        ctx->current_fbo = framebuffer;
-     }
+   return evgl_make_current(data, sfc, ctx);
 }
 
-static void
-evgl_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+static void *
+eng_gl_current_context_get(void *data EINA_UNUSED)
 {
-   // Add logic to take care when renderbuffer=0
-   // On a second thought we don't need this
-   glBindRenderbuffer(target, renderbuffer);
-}
-
-// Transform from Evas Coordinat to GL Coordinate
-// returns: oc[4] original image object dimension in gl coord
-// returns: nc[4] tranformed  (x, y, width, heigth) in gl coord
-static void
-compute_gl_coordinates(Evas_Object *obj, int rot, int clip,
-                       int x, int y, int width, int height,
-                       int imgc[4], int objc[4])
-{
-   if (rot == 0)
-     {
-        // oringinal image object coordinate in gl coordinate
-        imgc[0] = obj->cur.geometry.x;
-        imgc[1] = obj->layer->evas->output.h - obj->cur.geometry.y - obj->cur.geometry.h;
-        imgc[2] = imgc[0] + obj->cur.geometry.w;
-        imgc[3] = imgc[1] + obj->cur.geometry.h;
-
-        // transformed (x,y,width,height) in gl coordinate
-        objc[0] = imgc[0] + x;
-        objc[1] = imgc[1] + y;
-        objc[2] = objc[0] + width;
-        objc[3] = objc[1] + height;
-     }
-   else if (rot == 180)
-     {
-        // oringinal image object coordinate in gl coordinate
-        imgc[0] = obj->layer->evas->output.w - obj->cur.geometry.x - obj->cur.geometry.w;
-        imgc[1] = obj->cur.geometry.y;
-        imgc[2] = imgc[0] + obj->cur.geometry.w;
-        imgc[3] = imgc[1] + obj->cur.geometry.h;
-
-        // transformed (x,y,width,height) in gl coordinate
-        objc[0] = imgc[0] + obj->cur.geometry.w - x - width;
-        objc[1] = imgc[1] + obj->cur.geometry.h - y - height;
-        objc[2] = objc[0] + width;
-        objc[3] = objc[1] + height;
-
-     }
-   else if (rot == 90)
-     {
-        // oringinal image object coordinate in gl coordinate
-        imgc[0] = obj->cur.geometry.y;
-        imgc[1] = obj->cur.geometry.x;
-        imgc[2] = imgc[0] + obj->cur.geometry.h;
-        imgc[3] = imgc[1] + obj->cur.geometry.w;
-
-        // transformed (x,y,width,height) in gl coordinate
-        objc[0] = imgc[0] + obj->cur.geometry.h - y - height;
-        objc[1] = imgc[1] + x;
-        objc[2] = objc[0] + height;
-        objc[3] = objc[1] + width;
-     }
-   else if (rot == 270)
-     {
-        // oringinal image object coordinate in gl coordinate
-        imgc[0] = obj->layer->evas->output.h - obj->cur.geometry.y - obj->cur.geometry.h;
-        imgc[1] = obj->layer->evas->output.w - obj->cur.geometry.x - obj->cur.geometry.w;
-        imgc[2] = imgc[0] + obj->cur.geometry.h;
-        imgc[3] = imgc[1] + obj->cur.geometry.w;
-
-        // transformed (x,y,width,height) in gl coordinate
-        objc[0] = imgc[0] + y;
-        objc[1] = imgc[1] + obj->cur.geometry.w - x - width;
-        objc[2] = objc[0] + height;
-        objc[3] = objc[1] + width;
-     }
-   else
-     {
-        ERR("Invalid rotation angle %d.", rot);
-        return;
-     }
-
-   if (clip)
-     {
-        // Clip against original image object
-        if (objc[0] < imgc[0]) objc[0] = imgc[0];
-        if (objc[0] > imgc[2]) objc[0] = 0;
+   EVGL_Context *ctx;
+   EVGL_Resource *rsc;
+   EVGLNative_Context context;
 
-        if (objc[1] < imgc[1]) objc[1] = imgc[1];
-        if (objc[1] > imgc[3]) objc[1] = 0;
+   ctx = _evgl_current_context_get();
+   if (!ctx)
+     return NULL;
 
-        if (objc[2] < imgc[0]) objc[0] = 0;
-        if (objc[2] > imgc[2]) objc[2] = imgc[2];
+   context = ctx->context;
+   rsc = _evgl_tls_resource_get();
 
-        if (objc[3] < imgc[1]) objc[1] = 0;
-        if (objc[3] > imgc[3]) objc[3] = imgc[3];
-     }
+#ifdef GL_GLES
+   if ((ctx->pixmap_image_supported) && (!rsc->direct.rendered))
+     context = ctx->gles1_context;
 
-   imgc[2] = imgc[2]-imgc[0];     // width
-   imgc[3] = imgc[3]-imgc[1];     // height
+   if (eglGetCurrentContext() == context)
+     return ctx;
+#else
+   if (glXGetCurrentContext() == context)
+     return ctx;
+#endif
 
-   objc[2] = objc[2]-objc[0];     // width
-   objc[3] = objc[3]-objc[1];     // height
+   return NULL;
 }
 
-static void
-evgl_glClear(GLbitfield mask)
+static void *
+eng_gl_current_surface_get(void *data EINA_UNUSED)
 {
-   Render_Engine_GL_Context *ctx = current_evgl_ctx;
-   int rot = 0;
-   int oc[4], nc[4];
+   EVGL_Context *ctx;
 
-   if ((gl_direct_img_obj) && (gl_direct_enabled) && (ctx) && (!ctx->current_fbo))
-     {
-        if ((current_engine) && (current_engine->win) && (current_engine->win->gl_context))
-           rot = current_engine->win->gl_context->rot;
-        else
-           ERR("Unable to retrieve rotation angle: %d", rot);
+   ctx = _evgl_current_context_get();
+   if (!ctx)
+     return NULL;
 
-        compute_gl_coordinates(gl_direct_img_obj, rot, 0, 0, 0, 0, 0, oc, nc);
-        glScissor(oc[0], oc[1], oc[2], oc[3]);
-        glClear(mask);
-     }
-   else
-      glClear(mask);
+   // Note: We could verify with a call to eglGetCurrentSurface
+
+   return ctx->current_sfc;
 }
 
-static void
-evgl_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+static int
+eng_gl_rotation_angle_get(void *data)
 {
-   glClearColor(red, green, blue, alpha);
+   if (!evgl_engine->funcs->rotation_angle_get) return 0;
+   return evgl_engine->funcs->rotation_angle_get(data);
 }
 
-static void
-evgl_glEnable(GLenum cap)
+static const char *
+eng_gl_string_query(void *data __UNUSED__, int name)
+{
+   return evgl_string_query(name);
+}
+
+static void *
+eng_gl_proc_address_get(void *data EINA_UNUSED, Evas_GL_Ext *ext, const char *name)
 {
-   Render_Engine_GL_Context *ctx = current_evgl_ctx;
+   void *func = NULL;
+   int i = 0;
+
+   // Evas GL extensions
+   while (ext[i].name != NULL)
+     {
+        if (!strcmp(ext[i].name, name))
+           return ext[i].func;
+        ++i;
+     }
+
+   // Allowed GL extensions
+   if (!evgl_safe_extension_get(name, &func))
+     {
+        DBG("The extension '%s' is not safe to use with Evas GL or is not "
+            "supported on this platform.", name);
+        return NULL;
+     }
+
+   if (func)
+     return func;
 
-   if (cap == GL_SCISSOR_TEST)
-      if (ctx) ctx->scissor_enabled = 1;
-   glEnable(cap);
+   if (evgl_funcs.proc_address_get)
+     return evgl_funcs.proc_address_get(name);
+
+   return NULL;
 }
 
-static void
-evgl_glDisable(GLenum cap)
+static int
+eng_gl_native_surface_get(void *data __UNUSED__, void *surface, void *native_surface)
 {
-   Render_Engine_GL_Context *ctx = current_evgl_ctx;
+   EVGL_Surface  *sfc = (EVGL_Surface *)surface;
+   Evas_Native_Surface *ns = (Evas_Native_Surface *)native_surface;
 
-   if (cap == GL_SCISSOR_TEST)
-      if (ctx) ctx->scissor_enabled = 0;
-   glDisable(cap);
+   return evgl_native_surface_get(sfc, ns);
 }
 
+static void *
+eng_gl_api_get(void *data __UNUSED__, int version)
+{
+   return evgl_api_get(version);
+}
 
 static void
-evgl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
+eng_gl_direct_override_get(void *data __UNUSED__, int *override, int *force_off)
 {
-   Render_Engine_GL_Context *ctx = current_evgl_ctx;
-   int rot = 0;
-   int oc[4], nc[4];
-
-   if ((gl_direct_img_obj) && (gl_direct_enabled) && (ctx) && (!ctx->current_fbo))
-     {
-        if ((current_engine) && (current_engine->win) && (current_engine->win->gl_context))
-           rot = current_engine->win->gl_context->rot;
-        else
-           ERR("Unable to retrieve rotation angle: %d", rot);
-
-        compute_gl_coordinates(gl_direct_img_obj, rot, 1, x, y, width, height, oc, nc);
-        glReadPixels(nc[0], nc[1], nc[2], nc[3], format, type, pixels);
-     }
-   else
-      glReadPixels(x, y, width, height, format, type, pixels);
+   evgl_direct_override_get(override, force_off);
 }
 
-static void
-evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+static Eina_Bool
+eng_gl_surface_direct_renderable_get(void *data, Evas_Native_Surface *ns, Eina_Bool *direct_override)
 {
-   Render_Engine_GL_Context *ctx = current_evgl_ctx;
-   int rot = 0;
-   int oc[4], nc[4];
+   Render_Engine *re = data;
+   Eina_Bool direct_render, client_side_rotation;
 
-   if ((gl_direct_img_obj) && (gl_direct_enabled) && (ctx) && (!ctx->current_fbo))
-     {
-        if ((current_engine) && (current_engine->win) && (current_engine->win->gl_context))
-           rot = current_engine->win->gl_context->rot;
-        else
-           ERR("Unable to retrieve rotation angle: %d", rot);
+   if (!re || !ns) return EINA_FALSE;
+   if (!evgl_native_surface_direct_opts_get(ns, &direct_render, &client_side_rotation, direct_override))
+     return EINA_FALSE;
 
-        compute_gl_coordinates(gl_direct_img_obj, rot, 1, x, y, width, height, oc, nc);
-        glScissor(nc[0], nc[1], nc[2], nc[3]);
-        ctx->scissor_upated = 1;
-     }
-   else
-      glScissor(x, y, width, height);
+   if (!direct_render)
+     return EINA_FALSE;
+
+   if ((re->win->gl_context->rot != 0) && (!client_side_rotation))
+     return EINA_FALSE;
+
+   return EINA_TRUE;
 }
 
 static void
-evgl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+eng_gl_get_pixels_set(void *data, void *get_pixels, void *get_pixels_data, void *obj)
 {
-   Render_Engine_GL_Context *ctx = current_evgl_ctx;
-   int rot = 0;
-   int oc[4], nc[4];
+   Render_Engine *re = (Render_Engine *)data;
 
-   if ((gl_direct_img_obj) && (gl_direct_enabled) && (ctx) && (!ctx->current_fbo))
-     {
-        if ((current_engine) && (current_engine->win) && (current_engine->win->gl_context))
-           rot = current_engine->win->gl_context->rot;
-        else
-           ERR("Unable to retrieve rotation angle: %d", rot);
+   re->func.get_pixels = get_pixels;
+   re->func.get_pixels_data = get_pixels_data;
+   re->func.obj = (Evas_Object*)obj;
 
-        compute_gl_coordinates(gl_direct_img_obj, rot, 0, x, y, width, height, oc, nc);
-        glEnable(GL_SCISSOR_TEST);
-        glScissor(oc[0], oc[1], oc[2], oc[3]);
-        glViewport(nc[0], nc[1], nc[2], nc[3]);
-     }
+   if (re->func.get_pixels)
+      re->func.clip = 1;
    else
-      glViewport(x, y, width, height);
-
+      re->func.clip = 0;
 }
 
 
-//----------------------------------------------//
 
-static void
-evgl_glClearDepthf(GLclampf depth)
+static Eina_Bool
+eng_gl_surface_lock(void *data, void *surface)
 {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   glClearDepthf(depth);
-#else
-   glClearDepth(depth);
-#endif
+   Render_Engine *re = data;
+   Evas_GL_Image *im = surface;
+
+   if (!im->tex || !im->tex->pt)
+     {
+        ERR("Can not lock image that is not a surface!");
+        return EINA_FALSE;
+     }
+
+   evas_gl_common_context_flush(im->gc);
+   im->locked = EINA_TRUE;
+   return EINA_TRUE;
 }
 
-static void
-evgl_glDepthRangef(GLclampf zNear, GLclampf zFar)
+static Eina_Bool
+eng_gl_surface_unlock(void *data, void *surface)
 {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   glDepthRangef(zNear, zFar);
-#else
-   glDepthRange(zNear, zFar);
-#endif
+   Render_Engine *re = data;
+   Evas_GL_Image *im = surface;
+
+   im->locked = EINA_FALSE;
+   return EINA_TRUE;
 }
 
-static void
-evgl_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+static Eina_Bool
+eng_gl_surface_read_pixels(void *data, void *surface,
+                           int x, int y, int w, int h,
+                           Evas_Colorspace cspace, void *pixels)
 {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
-#else
-   if (range)
+   Render_Engine *re = data;
+   Evas_GL_Image *im = surface;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(pixels, EINA_FALSE);
+
+   if (!im->locked)
      {
-        range[0] = -126; // floor(log2(FLT_MIN))
-        range[1] = 127; // floor(log2(FLT_MAX))
+        // For now, this is useless, but let's force clients to lock :)
+        ERR("The surface must be locked before reading its pixels!");
+        return EINA_FALSE;
      }
-   if (precision)
+
+   if (cspace != EVAS_COLORSPACE_ARGB8888)
      {
-        precision[0] = 24; // floor(-log2((1.0/16777218.0)));
+        ERR("Conversion to colorspace %d is not supported!", (int) cspace);
+        return EINA_FALSE;
      }
-   return;
-#endif
-}
 
-static void
-evgl_glReleaseShaderCompiler(void)
-{
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   glReleaseShaderCompiler();
+#ifdef GL_GLES
+# ifndef GL_FRAMEBUFFER
+#  define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
+# endif
 #else
+# ifndef GL_FRAMEBUFFER
+#  define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
+# endif
 #endif
-}
 
-static void
-evgl_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length)
-{
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   glShaderBinary(n, shaders, binaryformat, binary, length);
-#else
-// FIXME: need to dlsym/getprocaddress for this
-   return;
-   n = binaryformat = length = 0;
-   shaders = binary = 0;
-#endif
-}
+   /* Since this is an FBO, the pixels are already in the right Y order.
+    * But some devices don't support GL_BGRA, so we still need to convert.
+    */
 
-//--------------------------------//
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-// EGL Extensions
-static void *
-evgl_evasglCreateImage(int target, void* buffer, int *attrib_list)
-{
-   if (current_engine)
-     {
-        return glsym_eglCreateImage(current_engine->win->egl_disp,
-                                    EGL_NO_CONTEXT,
-                                    target,
-                                    buffer,
-                                    attrib_list);
-     }
+   glsym_glBindFramebuffer(GL_FRAMEBUFFER, im->tex->pt->fb);
+   if (im->tex->pt->format == GL_BGRA)
+     glReadPixels(x, y, w, h, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
    else
      {
-        ERR("Invalid Engine... (Can't acccess EGL Display)\n");
-        return NULL;
+        DATA32 *ptr = pixels;
+        int k;
+
+        glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+        for (k = w * h; k; --k)
+          {
+             const DATA32 v = *ptr;
+             *ptr++ = (v & 0xFF00FF00)
+                   | ((v & 0x00FF0000) >> 16)
+                   | ((v & 0x000000FF) << 16);
+          }
      }
-}
+   glsym_glBindFramebuffer(GL_FRAMEBUFFER, 0);
 
-static void
-evgl_evasglDestroyImage(EvasGLImage image)
-{
-   if (current_engine)
-        glsym_eglDestroyImage(current_engine->win->egl_disp, image);
-   else
-      ERR("Invalid Engine... (Can't acccess EGL Display)\n");
-}
+   evas_common_convert_argb_premul(pixels, w * h);
 
-static void
-evgl_glEvasGLImageTargetTexture2DOES(GLenum target, EvasGLImage image)
-{
-   glsym_glEGLImageTargetTexture2DOES(target, image);
+   return EINA_TRUE;
 }
 
-static void
-evgl_glEvasGLImageTargetRenderbufferStorageOES(GLenum target, EvasGLImage image)
+static int
+eng_gl_error_get(void *data __UNUSED__)
 {
-   glsym_glEGLImageTargetTexture2DOES(target, image);
-}
-#else
-#endif
+   int err;
 
-//--------------------------------//
+   if ((err = _evgl_error_get()) != EVAS_GL_SUCCESS) goto end;
 
+#ifdef GL_GLES
+   err = eglGetError() - EGL_SUCCESS;
+#else
+   Render_Engine *re = data;
 
-static void *
-eng_gl_api_get(void *data)
-{
-   Render_Engine *re;
+   if(!(re->win))
+     {
+        err = EVAS_GL_BAD_DISPLAY;
+        goto end;
+     }
 
-   re  = (Render_Engine *)data;
-
-   gl_funcs.version = EVAS_GL_API_VERSION;
-
-#define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, )
-   // GLES 2.0
-   ORD(glActiveTexture);
-   ORD(glAttachShader);
-   ORD(glBindAttribLocation);
-   ORD(glBindBuffer);
-   ORD(glBindTexture);
-   ORD(glBlendColor);
-   ORD(glBlendEquation);
-   ORD(glBlendEquationSeparate);
-   ORD(glBlendFunc);
-   ORD(glBlendFuncSeparate);
-   ORD(glBufferData);
-   ORD(glBufferSubData);
-   ORD(glCheckFramebufferStatus);
-//   ORD(glClear);
-//   ORD(glClearColor);
-//   ORD(glClearDepthf);
-   ORD(glClearStencil);
-   ORD(glColorMask);
-   ORD(glCompileShader);
-   ORD(glCompressedTexImage2D);
-   ORD(glCompressedTexSubImage2D);
-   ORD(glCopyTexImage2D);
-   ORD(glCopyTexSubImage2D);
-   ORD(glCreateProgram);
-   ORD(glCreateShader);
-   ORD(glCullFace);
-   ORD(glDeleteBuffers);
-   ORD(glDeleteFramebuffers);
-   ORD(glDeleteProgram);
-   ORD(glDeleteRenderbuffers);
-   ORD(glDeleteShader);
-   ORD(glDeleteTextures);
-   ORD(glDepthFunc);
-   ORD(glDepthMask);
-//   ORD(glDepthRangef);
-   ORD(glDetachShader);
-//   ORD(glDisable);
-   ORD(glDisableVertexAttribArray);
-   ORD(glDrawArrays);
-   ORD(glDrawElements);
-//   ORD(glEnable);
-   ORD(glEnableVertexAttribArray);
-   ORD(glFinish);
-   ORD(glFlush);
-   ORD(glFramebufferRenderbuffer);
-   ORD(glFramebufferTexture2D);
-   ORD(glFrontFace);
-   ORD(glGenBuffers);
-   ORD(glGenerateMipmap);
-   ORD(glGenFramebuffers);
-   ORD(glGenRenderbuffers);
-   ORD(glGenTextures);
-   ORD(glGetActiveAttrib);
-   ORD(glGetActiveUniform);
-   ORD(glGetAttachedShaders);
-   ORD(glGetAttribLocation);
-   ORD(glGetBooleanv);
-   ORD(glGetBufferParameteriv);
-   ORD(glGetError);
-   ORD(glGetFloatv);
-   ORD(glGetFramebufferAttachmentParameteriv);
-   ORD(glGetIntegerv);
-   ORD(glGetProgramiv);
-   ORD(glGetProgramInfoLog);
-   ORD(glGetRenderbufferParameteriv);
-   ORD(glGetShaderiv);
-   ORD(glGetShaderInfoLog);
-//   ORD(glGetShaderPrecisionFormat);
-   ORD(glGetShaderSource);
-//   ORD(glGetString);
-   ORD(glGetTexParameterfv);
-   ORD(glGetTexParameteriv);
-   ORD(glGetUniformfv);
-   ORD(glGetUniformiv);
-   ORD(glGetUniformLocation);
-   ORD(glGetVertexAttribfv);
-   ORD(glGetVertexAttribiv);
-   ORD(glGetVertexAttribPointerv);
-   ORD(glHint);
-   ORD(glIsBuffer);
-   ORD(glIsEnabled);
-   ORD(glIsFramebuffer);
-   ORD(glIsProgram);
-   ORD(glIsRenderbuffer);
-   ORD(glIsShader);
-   ORD(glIsTexture);
-   ORD(glLineWidth);
-   ORD(glLinkProgram);
-   ORD(glPixelStorei);
-   ORD(glPolygonOffset);
-   ORD(glReadPixels);
-//   ORD(glReleaseShaderCompiler);
-   ORD(glRenderbufferStorage);
-   ORD(glSampleCoverage);
-//   ORD(glScissor);
-//   ORD(glShaderBinary);
-   ORD(glShaderSource);
-   ORD(glStencilFunc);
-   ORD(glStencilFuncSeparate);
-   ORD(glStencilMask);
-   ORD(glStencilMaskSeparate);
-   ORD(glStencilOp);
-   ORD(glStencilOpSeparate);
-   ORD(glTexImage2D);
-   ORD(glTexParameterf);
-   ORD(glTexParameterfv);
-   ORD(glTexParameteri);
-   ORD(glTexParameteriv);
-   ORD(glTexSubImage2D);
-   ORD(glUniform1f);
-   ORD(glUniform1fv);
-   ORD(glUniform1i);
-   ORD(glUniform1iv);
-   ORD(glUniform2f);
-   ORD(glUniform2fv);
-   ORD(glUniform2i);
-   ORD(glUniform2iv);
-   ORD(glUniform3f);
-   ORD(glUniform3fv);
-   ORD(glUniform3i);
-   ORD(glUniform3iv);
-   ORD(glUniform4f);
-   ORD(glUniform4fv);
-   ORD(glUniform4i);
-   ORD(glUniform4iv);
-   ORD(glUniformMatrix2fv);
-   ORD(glUniformMatrix3fv);
-   ORD(glUniformMatrix4fv);
-   ORD(glUseProgram);
-   ORD(glValidateProgram);
-   ORD(glVertexAttrib1f);
-   ORD(glVertexAttrib1fv);
-   ORD(glVertexAttrib2f);
-   ORD(glVertexAttrib2fv);
-   ORD(glVertexAttrib3f);
-   ORD(glVertexAttrib3fv);
-   ORD(glVertexAttrib4f);
-   ORD(glVertexAttrib4fv);
-   ORD(glVertexAttribPointer);
-//   ORD(glViewport);
-#undef ORD
-
-#define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, glsym_)
-   // Extensions
-   ORD(glGetProgramBinaryOES);
-   ORD(glProgramBinaryOES);
-   ORD(glMapBufferOES);
-   ORD(glUnmapBufferOES);
-   ORD(glGetBufferPointervOES);
-   ORD(glTexImage3DOES);
-   ORD(glTexSubImage3DOES);
-   ORD(glCopyTexSubImage3DOES);
-   ORD(glCompressedTexImage3DOES);
-   ORD(glCompressedTexSubImage3DOES);
-   ORD(glFramebufferTexture3DOES);
-   ORD(glGetPerfMonitorGroupsAMD);
-   ORD(glGetPerfMonitorCountersAMD);
-   ORD(glGetPerfMonitorGroupStringAMD);
-   ORD(glGetPerfMonitorCounterStringAMD);
-   ORD(glGetPerfMonitorCounterInfoAMD);
-   ORD(glGenPerfMonitorsAMD);
-   ORD(glDeletePerfMonitorsAMD);
-   ORD(glSelectPerfMonitorCountersAMD);
-   ORD(glBeginPerfMonitorAMD);
-   ORD(glEndPerfMonitorAMD);
-   ORD(glGetPerfMonitorCounterDataAMD);
-   ORD(glDiscardFramebufferEXT);
-   ORD(glMultiDrawArraysEXT);
-   ORD(glMultiDrawElementsEXT);
-   ORD(glDeleteFencesNV);
-   ORD(glGenFencesNV);
-   ORD(glIsFenceNV);
-   ORD(glTestFenceNV);
-   ORD(glGetFenceivNV);
-   ORD(glFinishFenceNV);
-   ORD(glSetFenceNV);
-   ORD(glGetDriverControlsQCOM);
-   ORD(glGetDriverControlStringQCOM);
-   ORD(glEnableDriverControlQCOM);
-   ORD(glDisableDriverControlQCOM);
-   ORD(glExtGetTexturesQCOM);
-   ORD(glExtGetBuffersQCOM);
-   ORD(glExtGetRenderbuffersQCOM);
-   ORD(glExtGetFramebuffersQCOM);
-   ORD(glExtGetTexLevelParameterivQCOM);
-   ORD(glExtTexObjectStateOverrideiQCOM);
-   ORD(glExtGetTexSubImageQCOM);
-   ORD(glExtGetBufferPointervQCOM);
-   ORD(glExtGetShadersQCOM);
-   ORD(glExtGetProgramsQCOM);
-   ORD(glExtIsProgramBinaryQCOM);
-   ORD(glExtGetProgramBinarySourceQCOM);
-#undef ORD
-
-// Override functions wrapped by Evas_GL
-#define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, evgl_)
-   ORD(glBindFramebuffer);
-   ORD(glBindRenderbuffer);
-
-   ORD(glClear);
-   ORD(glClearColor);
-   ORD(glEnable);
-   ORD(glDisable);
-   ORD(glReadPixels);
-   ORD(glScissor);
-   ORD(glViewport);
-
-   // GLES2.0 API compat on top of desktop gl
-   ORD(glClearDepthf);
-   ORD(glDepthRangef);
-   ORD(glGetShaderPrecisionFormat);
-   ORD(glReleaseShaderCompiler);
-   ORD(glShaderBinary);
-
-   ORD(glGetString);
-
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   // GLES 2.0 Extensions that needs wrapping
-   ORD(evasglCreateImage);
-   ORD(evasglDestroyImage);
-   ORD(glEvasGLImageTargetTexture2DOES);
-   ORD(glEvasGLImageTargetRenderbufferStorageOES);
+   if(!(re->info))
+     {
+        err = EVAS_GL_BAD_SURFACE;
+     }
 #endif
 
-#undef ORD
-
-   return &gl_funcs;
+end:
+    _evgl_error_set(EVAS_GL_SUCCESS);
+   return err;
 }
 
-static void
-eng_gl_img_obj_set(void *data, void *image, int has_alpha)
+static Eina_Bool
+eng_gl_surface_query(void *data, void *surface, int attr, void *value)
 {
-   Render_Engine *re = (Render_Engine *)data;
-
-   gl_direct_img_obj = NULL;
+   Render_Engine *re  = (Render_Engine *)data;
+   EVGL_Surface  *sfc = (EVGL_Surface *)surface;
 
-   // Normally direct rendering isn't allowed if alpha is on and
-   // rotation is not 0.  BUT, if override is on, allow it.
-   if ((has_alpha) || (re->win->gl_context->rot!=0))
+#ifdef GL_GLES
+   if (sfc->pbuffer.is_pbuffer)
      {
-        if (gl_direct_override)
-           gl_direct_img_obj = image;
+        // This is a real EGL surface, let's just call EGL directly
+        int val;
+        Eina_Bool ok;
+
+        ok = eglQuerySurface(re->win->egl_disp, sfc->pbuffer.native_surface, attr, &val);
+        if (!ok) return EINA_FALSE;
+        switch (attr)
+          {
+           case EVAS_GL_TEXTURE_FORMAT:
+             if (val == EGL_TEXTURE_RGB)
+               *((int *) value) = EVAS_GL_RGB_888;
+             else if (val == EGL_TEXTURE_RGBA)
+               *((int *) value) = EVAS_GL_RGBA_8888;
+             else // if (val == EGL_NO_TEXTURE)
+               *((int *) value) = EVAS_GL_NO_FBO;
+             break;
+           case EVAS_GL_TEXTURE_TARGET:
+             if (val == EGL_TEXTURE_2D)
+               *((int *) value) = val;
+             else
+               *((int *) value) = 0;
+             break;
+           default:
+             *((int *) value) = val;
+             break;
+          }
+        return EINA_TRUE;
      }
    else
-      gl_direct_img_obj = image;
+     {
+        // Since this is a fake surface (shared with evas), we must filter the
+        // queries...
+        switch (attr)
+          {
+           // TODO: Add support for whole config get
+           /*
+           case EVAS_GL_CONFIG_ID:
+             *((int *) value) = sfc->cfg_index;
+             return EINA_TRUE;
+             */
+           case EVAS_GL_WIDTH:
+             *((int *) value) = sfc->w;
+             return EINA_TRUE;
+           case EVAS_GL_HEIGHT:
+             *((int *) value) = sfc->h;
+             return EINA_TRUE;
+           case EVAS_GL_TEXTURE_FORMAT:
+             // FIXME: Check the possible color formats
+             if (sfc->color_buf)
+               {
+                  if ((sfc->color_fmt == GL_RGBA) || (sfc->color_fmt == GL_BGRA))
+                    {
+                       *((Evas_GL_Color_Format *) value) = EVAS_GL_RGBA_8888;
+                       return EINA_TRUE;
+                    }
+                  else if (sfc->color_fmt == GL_RGB)
+                    {
+                       *((Evas_GL_Color_Format *) value) = EVAS_GL_RGB_888;
+                       return EINA_TRUE;
+                    }
+               }
+             *((Evas_GL_Color_Format *) value) = EVAS_GL_NO_FBO;
+             return EINA_TRUE;
+           case EVAS_GL_TEXTURE_TARGET:
+             if (sfc->color_buf)
+               *((int *) value) = EVAS_GL_TEXTURE_2D;
+             else
+               *((int *) value) = 0;
+             return EINA_TRUE;
+           // TODO: Add support for this:
+           /*
+           case EVAS_GL_MULTISAMPLE_RESOLVE:
+             *((int *) value) = sfc->msaa_samples;
+             return EINA_TRUE;
+             */
+           // TODO: Add support for mipmaps
+           /*
+           case EVAS_GL_MIPMAP_TEXTURE:
+           case EVAS_GL_MIPMAP_LEVEL:
+             return eglQuerySurface(re->win->egl_disp, re->win->egl_surface[0],
+                                    attr, (int *) value);
+             */
+           default: break;
+          }
+        _evgl_error_set(EVAS_GL_BAD_ATTRIBUTE);
+        return EINA_FALSE;
+     }
+#else
+   ERR("GLX support for surface_query is not implemented!");
+   return EINA_FALSE;
+#endif
 }
 
+//--------------------------------//
+
 static int
 eng_image_load_error_get(void *data __UNUSED__, void *image)
 {
@@ -4877,6 +5472,272 @@ eng_image_max_size_get(void *data, int *maxw, int *maxh)
    if (maxh) *maxh = re->win->gl_context->shared->info.max_texture_size;
 }
 
+static Eina_Bool
+eng_pixel_alpha_get(void *image, int x, int y, DATA8 *alpha,
+                 int src_region_x, int src_region_y, int src_region_w, int src_region_h,
+                 int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h)
+{
+   Evas_GL_Image *im = image;
+   int px, py, dx, dy, sx, sy, src_w, src_h;
+   double scale_w, scale_h;
+
+   if (!im) return EINA_FALSE;
+
+   if ((dst_region_x > x) || (x >= (dst_region_x + dst_region_w)) ||
+       (dst_region_y > y) || (y >= (dst_region_y + dst_region_h)))
+     {
+        *alpha = 0;
+        return EINA_FALSE;
+     }
+
+   evas_gl_common_image_alloc_ensure(im);
+   src_w = im->im->cache_entry.w;
+   src_h = im->im->cache_entry.h;
+   if ((src_w == 0) || (src_h == 0))
+     {
+        *alpha = 0;
+        return EINA_TRUE;
+     }
+
+   EINA_SAFETY_ON_TRUE_GOTO(src_region_x < 0, error_oob);
+   EINA_SAFETY_ON_TRUE_GOTO(src_region_y < 0, error_oob);
+   EINA_SAFETY_ON_TRUE_GOTO(src_region_x + src_region_w > src_w, error_oob);
+   EINA_SAFETY_ON_TRUE_GOTO(src_region_y + src_region_h > src_h, error_oob);
+
+   scale_w = (double)dst_region_w / (double)src_region_w;
+   scale_h = (double)dst_region_h / (double)src_region_h;
+
+   /* point at destination */
+   dx = x - dst_region_x;
+   dy = y - dst_region_y;
+
+   /* point at source */
+   sx = dx / scale_w;
+   sy = dy / scale_h;
+
+   /* pixel point (translated) */
+   px = src_region_x + sx;
+   py = src_region_y + sy;
+   EINA_SAFETY_ON_TRUE_GOTO(px >= src_w, error_oob);
+   EINA_SAFETY_ON_TRUE_GOTO(py >= src_h, error_oob);
+
+   switch (im->im->cache_entry.space)
+     {
+     case EVAS_COLORSPACE_ARGB8888:
+       {
+          DATA32 *pixel;
+
+          evas_cache_image_load_data(&im->im->cache_entry);
+          if (!im->im->cache_entry.flags.loaded)
+            {
+               ERR("im %p has no pixels loaded yet", im);
+               return EINA_FALSE;
+            }
+          pixel = im->im->image.data;
+          pixel += ((py * src_w) + px);
+          *alpha = ((*pixel) >> 24) & 0xff;
+       }
+       break;
+
+     default:
+        ERR("Colorspace %d not supported.", im->im->cache_entry.space);
+        *alpha = 0;
+     }
+   return EINA_TRUE;
+
+ error_oob:
+   ERR("Invalid region src=(%d, %d, %d, %d), dst=(%d, %d, %d, %d), image=%dx%d",
+       src_region_x, src_region_y, src_region_w, src_region_h,
+       dst_region_x, dst_region_y, dst_region_w, dst_region_h,
+       src_w, src_h);
+   *alpha = 0;
+   return EINA_TRUE;
+}
+
+static void
+eng_context_flush(void *data)
+{
+   Render_Engine *re;
+   re = (Render_Engine *)data;
+
+   if ((re->win->gl_context->havestuff) ||
+     (re->win->gl_context->master_clip.used))
+   {
+      eng_window_use(re->win);
+      evas_gl_common_context_flush(re->win->gl_context);
+      if (re->win->gl_context->master_clip.used)
+         evas_gl_common_context_done(re->win->gl_context);
+   }
+}
+
+static void
+eng_context_clip_image_unset(void *data EINA_UNUSED, void *context)
+{
+   RGBA_Draw_Context *ctx = context;
+   Evas_GL_Image *im = ctx->clip.mask;
+
+   if (im)
+     evas_gl_common_image_free(im);
+
+   ctx->clip.mask = NULL;
+}
+
+static void
+eng_context_clip_image_set(void *data EINA_UNUSED, void *context, void *surface, int x, int y)
+{
+   RGBA_Draw_Context *ctx = context;
+   Evas_GL_Image *im = surface;
+   Eina_Bool noinc = EINA_FALSE;
+
+   if (ctx->clip.mask)
+     {
+        if (ctx->clip.mask != surface)
+          eng_context_clip_image_unset(data, context);
+        else
+          noinc = EINA_TRUE;
+     }
+
+   ctx->clip.mask = surface;
+   ctx->clip.mask_x = x;
+   ctx->clip.mask_y = y;
+
+   if (im)
+     {
+        if (!noinc) evas_gl_common_image_ref(im);
+        RECTS_CLIP_TO_RECT(ctx->clip.x, ctx->clip.y, ctx->clip.w, ctx->clip.h,
+                           x, y, im->w, im->h);
+     }
+}
+
+static void
+eng_context_clip_image_get(void *data EINA_UNUSED, void *context, void **ie, int *x, int *y)
+{
+   RGBA_Draw_Context *ctx = context;
+
+   if (ie) *ie = ctx->clip.mask;
+   if (x) *x = ctx->clip.mask_x;
+   if (y) *y = ctx->clip.mask_y;
+}
+
+static void
+eng_context_free(void *data, void *context)
+{
+   RGBA_Draw_Context *ctx = context;
+
+   if (!ctx) return;
+   if (ctx->clip.mask)
+     eng_context_clip_image_unset(data, context);
+   evas_common_draw_context_free(context);
+}
+
+static int
+eng_gl_ext_buffer_age_get(void *data)
+{
+   Render_Engine *re;
+   re = (Render_Engine *)(data);
+
+   if (!re)
+     {
+        ERR("No valid engine set yet.");
+        return 0;
+     }
+
+   return re->prev_age;
+}
+
+
+static int
+eng_gl_ext_update_region_get(void *data, int *x, int *y, int *w, int *h)
+{
+   Render_Engine *re;
+   re = (Render_Engine *)(data);
+
+   if (!re)
+     {
+        ERR("No valid engine set yet.");
+        return 0;
+     }
+
+   if (re->func.clip)
+     {
+        *x = re->func.x;
+        *y = re->func.y;
+        *w = re->func.w;
+        *h = re->func.h;
+
+        ERR(" Update Region: [%d %d %d %d]", *x, *y, *w, *h);
+        return 1;
+     }
+   else
+      return 0;
+}
+
+static void *
+eng_gl_ext_surface_from_native_create(void *data, void *config, int target, void *native)
+{
+   int w = 0, h = 0;
+   Render_Engine *re = (Render_Engine *)data;
+   Evas_GL_Config *cfg = (Evas_GL_Config *)config;
+   const GLubyte *vendor = glGetString(GL_VENDOR);
+
+   // Check the validity of the target and retrive width, height
+   if (!eng_native_config_check(re->info->info.display, cfg, target, native, &w, &h))
+     {
+        ERR("Error retrieving pixmap infomration native depth");
+        _evgl_error_set(EVAS_GL_BAD_NATIVE_PIXMAP);
+        return NULL;
+     }
+
+   // TIZEN_ONLY : disable partial rendering during direct rendering
+   prev_extn_have_buffer_age = extn_have_buffer_age;
+   if ((cfg->options_bits & EVAS_GL_OPTIONS_DIRECT)
+        && (!getenv("EVAS_GL_PARTIAL_DISABLE")))
+     {
+        extn_have_buffer_age = 0;
+     }
+
+   return evgl_surface_create(data, cfg, target, native, w, h);
+}
+
+static int
+eng_gl_ext_surface_is_texture(void *data, void *surface)
+{
+   Render_Engine *re = (Render_Engine *)data;
+   EVGL_Surface  *sfc = (EVGL_Surface *)surface;
+
+   if (!re)
+     {
+        ERR("No valid engine set yet.");
+        return 0;
+     }
+
+   return evgl_surface_is_texture(data, sfc);
+}
+
+static void
+eng_get_pixels_render_post(void *data)
+{
+   Render_Engine *re;
+
+   re = (Render_Engine *)data;
+   re->context_current = EINA_FALSE;
+}
+
+static void
+eng_gl_engine_init(void *data)
+{
+   Render_Engine *re;
+
+   re = (Render_Engine *)data;
+
+   if (!evgl_initted)
+     {
+        eng_window_use(re->win);
+        evgl_engine_init(re, &evgl_funcs);
+        evgl_initted = 1;
+     }
+}
+
 static int
 module_open(Evas_Module *em)
 {
@@ -4900,16 +5761,6 @@ module_open(Evas_Module *em)
         return 0;
      }
 
-
-   /* Allow alpha for evas gl direct rendering */
-   if (getenv("EVAS_GL_DIRECT_OVERRIDE"))
-     {
-        gl_direct_override = 1;
-        DBG("########################################################");
-        DBG("######### [Evas] Direct overriding is enabled ##########");
-        DBG("########################################################");
-     }
-
    /* store it for later use */
    func = pfunc;
    /* now to override methods */
@@ -4937,6 +5788,11 @@ module_open(Evas_Module *em)
    ORD(polygon_points_clear);
    ORD(polygon_draw);
 
+   ORD(context_clip_image_set);
+   ORD(context_clip_image_unset);
+   ORD(context_clip_image_get);
+   ORD(context_free);
+
    ORD(image_load);
    ORD(image_new_from_data);
    ORD(image_new_from_copied_data);
@@ -4978,6 +5834,7 @@ module_open(Evas_Module *em)
    ORD(image_map_surface_new);
    ORD(image_map_surface_free);
    ORD(image_map_clean);
+   ORD(image_scaled_update);
 
    ORD(image_content_hint_set);
    ORD(image_content_hint_get);
@@ -4987,6 +5844,7 @@ module_open(Evas_Module *em)
    ORD(image_cache_get);
 
    ORD(gl_surface_create);
+   ORD(gl_pbuffer_surface_create);
    ORD(gl_surface_destroy);
    ORD(gl_context_create);
    ORD(gl_context_destroy);
@@ -4995,7 +5853,17 @@ module_open(Evas_Module *em)
    ORD(gl_proc_address_get);
    ORD(gl_native_surface_get);
    ORD(gl_api_get);
-   ORD(gl_img_obj_set);
+   ORD(gl_direct_override_get);
+   ORD(gl_surface_direct_renderable_get);
+   ORD(gl_get_pixels_set);
+   ORD(gl_surface_lock);
+   ORD(gl_surface_read_pixels);
+   ORD(gl_surface_unlock);
+   ORD(gl_error_get);
+   ORD(gl_surface_query);
+   ORD(gl_current_context_get);
+   ORD(gl_current_surface_get);
+   ORD(gl_rotation_angle_get);
 
    ORD(image_load_error_get);
 
@@ -5009,6 +5877,21 @@ module_open(Evas_Module *em)
 
    ORD(image_max_size_get);
 
+   ORD(context_flush);
+
+   ORD(gl_ext_buffer_age_get);
+   ORD(gl_ext_update_region_get);
+   ORD(gl_ext_surface_from_native_create);
+   ORD(gl_ext_surface_is_texture);
+
+   ORD(get_pixels_render_post);
+   ORD(pixel_alpha_get);
+
+   ORD(gl_engine_init);
+
+   ORD(image_direct_set);
+   ORD(image_direct_get);
+
    /* now advertise out own api */
    em->functions = (void *)(&func);
    return 1;
@@ -5018,15 +5901,6 @@ static void
 module_close(Evas_Module *em __UNUSED__)
 {
     eina_log_domain_unregister(_evas_engine_GL_X11_log_dom);
-/*
-    if (xrdb_user.db)
-      {
-        XrmDestroyDatabase(xrdb_user.db);
-        xrdb_user.last_stat = 0;
-        xrdb_user.last_mtime = 0;
-        xrdb_user.db = NULL;
-      }
- */
     evas_gl_common_module_close();
 }
 
old mode 100644 (file)
new mode 100755 (executable)
index 4f62c58..4c37255
 
 #define GL_GLEXT_PROTOTYPES
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-# if defined(GLES_VARIETY_S3C6410)
-#  include <EGL/egl.h>
-#  include <GLES2/gl2.h>
-#  include <X11/Xlib.h>
-#  include <X11/Xatom.h>
-#  include <X11/Xutil.h>
-#  include <X11/extensions/Xrender.h>
-#  include <X11/Xresource.h> // xres - dpi
-# elif defined(GLES_VARIETY_SGX)
-#  define SUPPORT_X11 1
-#  include <EGL/egl.h>
-#  include <GLES2/gl2.h>
-#  include <GLES2/gl2ext.h>
-#  include <X11/Xlib.h>
-#  include <X11/Xatom.h>
-#  include <X11/Xutil.h>
-#  include <X11/extensions/Xrender.h>
-#  include <X11/Xresource.h> // xres - dpi
-# endif
+#ifdef GL_GLES
+# define SUPPORT_X11 1
+# include <EGL/egl.h>
+# include <GLES2/gl2.h>
+# include <GLES2/gl2ext.h>
+# include <X11/Xlib.h>
+# include <X11/Xatom.h>
+# include <X11/Xutil.h>
+# include <X11/extensions/Xrender.h>
+# include <X11/Xresource.h> // xres - dpi
 #else
 # include <X11/Xlib.h>
 # include <X11/Xatom.h>
@@ -41,6 +31,9 @@
 # include <GL/glx.h>
 #endif
 
+#define EVAS_GL_NO_GL_H_CHECK 1
+#include "Evas_GL.h"
+
 extern int _evas_engine_GL_X11_log_dom ;
 #ifdef ERR
 # undef ERR
@@ -72,7 +65,8 @@ typedef struct _Evas_GL_X11_Window Evas_GL_X11_Window;
 struct _Evas_GL_X11_Window
 {
    Display         *disp;
-   Window           win;
+   Drawable         win;
+   Drawable         win_back;
    int              w, h;
    int              screen;
    XVisualInfo     *visualinfo;
@@ -81,46 +75,49 @@ struct _Evas_GL_X11_Window
    int              depth;
    int              alpha;
    int              rot;
+   int              depth_bits;
+   int              stencil_bits;
+   int              msaa_bits;
+   int              offscreen;
    Evas_Engine_GL_Context *gl_context;
    struct {
-      int              redraw : 1;
-      int              drew : 1;
-      int              x1, y1, x2, y2;
+      int           drew : 1;
    } draw;
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
    EGLContext       egl_context[1];
-   EGLSurface       egl_surface[1];
+   EGLSurface       egl_surface[2];
    EGLConfig        egl_config;
    EGLDisplay       egl_disp;
 #else
    GLXContext       context;
    GLXWindow        glxwin;
-   struct {
-      GLXFBConfig   fbc;
-      int           tex_format;
-      int           tex_target;
-      int           mipmap;
-      unsigned char yinvert : 1;
-   } depth_cfg[33]; // config for all 32 possible depths!
+#endif
 
    struct {
-      unsigned int loose_binding : 1;
-   } detected;
+      unsigned char depth_buffer_size;
+      unsigned char stencil_buffer_size;
+      unsigned char msaa;
+#ifndef GL_GLES
+      unsigned char loose_binding : 1;
 #endif
-   int             surf : 1;
+   } detected;
+   unsigned char    surf : 1;
 };
 
-Evas_GL_X11_Window *eng_window_new(Display *disp, Window win, int screen,
+Evas_GL_X11_Window *eng_window_new(Display *disp, Drawable win, int screen,
                                    Visual *vis, Colormap cmap,
                                    int depth, int w, int h, int indirect,
-                                   int alpha, int rot);
+                                   int alpha, int rot, int depth_bits, int stencil_bits, int msaa_bits,
+                                   Drawable offscreen);
 void      eng_window_free(Evas_GL_X11_Window *gw);
 void      eng_window_use(Evas_GL_X11_Window *gw);
-void      eng_window_unsurf(Evas_GL_X11_Window *gw);
+void      eng_window_unsurf(Evas_GL_X11_Window *gw, Eina_Bool pre_rotation_resurf);
 void      eng_window_resurf(Evas_GL_X11_Window *gw);
 
 Visual   *eng_best_visual_get(Evas_Engine_Info_GL_X11 *einfo);
 Colormap  eng_best_colormap_get(Evas_Engine_Info_GL_X11 *einfo);
 int       eng_best_depth_get(Evas_Engine_Info_GL_X11 *einfo);
+int       eng_native_config_check(Display *disp, void *cfg, int target, void *pixmap, int *w, int *h);
+Eina_Bool eng_init(void);
 
 #endif
old mode 100644 (file)
new mode 100755 (executable)
index 852a603..e21d913
@@ -1,12 +1,14 @@
 #include "evas_engine.h"
 
-static Evas_GL_X11_Window *_evas_gl_x11_window = NULL;
+static Eina_TLS _evas_gl_x11_window_key = 0;
+static Eina_TLS _context_key = 0;
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-static EGLContext context = EGL_NO_CONTEXT;
+#ifdef GL_GLES
+typedef EGLContext GLContext;
 #else
+#warning FIXME TLS Thread safety code not implemented for GLX!!!
 // FIXME: this will only work for 1 display connection (glx land can have > 1)
-static GLXContext context = 0;
+typedef GLXContext GLContext;
 static GLXContext rgba_context = 0;
 static GLXFBConfig fbconf = 0;
 static GLXFBConfig rgba_fbconf = 0;
@@ -20,31 +22,93 @@ static XVisualInfo *_evas_gl_x11_rgba_vi = NULL;
 static Colormap     _evas_gl_x11_cmap = 0;
 static Colormap     _evas_gl_x11_rgba_cmap = 0;
 
+// FIXME: This should use an atomic int. But it's a useless variable...
 static int win_count = 0;
+static Eina_Bool initted = EINA_FALSE;
+
+Eina_Bool
+eng_init(void)
+{
+   if (initted)
+     return EINA_TRUE;
+
+   // FIXME: These resources are never released
+   if (!eina_tls_new(&_evas_gl_x11_window_key))
+     goto error;
+   if (!eina_tls_new(&_context_key))
+     goto error;
+
+   eina_tls_set(_evas_gl_x11_window_key, NULL);
+   eina_tls_set(_context_key, NULL);
+
+   initted = EINA_TRUE;
+   return EINA_TRUE;
+
+error:
+   ERR("Could not create TLS key!");
+   return EINA_FALSE;
+}
+
+static inline Evas_GL_X11_Window *
+_tls_evas_gl_x11_window_get(void)
+{
+   if (!initted) eng_init();
+   return eina_tls_get(_evas_gl_x11_window_key);
+}
+
+static inline Eina_Bool
+_tls_evas_gl_x11_window_set(Evas_GL_X11_Window *xwin)
+{
+   if (!initted) eng_init();
+   return eina_tls_set(_evas_gl_x11_window_key, xwin);
+}
+
+static inline GLContext
+_tls_context_get(void)
+{
+   if (!initted) eng_init();
+   return eina_tls_get(_context_key);
+}
+
+static inline Eina_Bool
+_tls_context_set(GLContext ctx)
+{
+   if (!initted) eng_init();
+   return eina_tls_set(_context_key, ctx);
+}
 
 Evas_GL_X11_Window *
 eng_window_new(Display *disp,
-              Window   win,
-              int      screen,
-              Visual  *vis,
-              Colormap cmap,
-              int      depth,
-              int      w,
-              int      h,
+               Drawable win,
+               int      screen,
+               Visual  *vis,
+               Colormap cmap,
+               int      depth,
+               int      w,
+               int      h,
                int      indirect,
                int      alpha,
-               int      rot)
+               int      rot,
+               int      depth_bits,
+               int      stencil_bits,
+               int      msaa_bits,
+               Drawable offscreen)
 {
    Evas_GL_X11_Window *gw;
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+   GLContext context;
+
+#ifdef GL_GLES
    int context_attrs[3];
    int config_attrs[40];
+   EGLConfig configs[200];
    int major_version, minor_version;
-   int num_config, n = 0;
+   int i, num, idx;
+   Eina_Bool found;
+   const char *s;
+//   XVisualInfo xVisual_info;
 #endif
-   XVisualInfo *vi_use;
    const GLubyte *vendor, *renderer, *version;
-   int blacklist = 0;
+   int blacklist = 0, val = 0;
 
    if (!_evas_gl_x11_vi) return NULL;
 
@@ -62,160 +126,252 @@ eng_window_new(Display *disp,
    gw->w = w;
    gw->h = h;
    gw->rot = rot;
+   gw->depth_bits = depth_bits;
+   gw->stencil_bits = stencil_bits;
+   gw->msaa_bits = msaa_bits;
+   gw->win_back = offscreen;
 
-   vi_use = _evas_gl_x11_vi;
-   if (gw->alpha)
+   if (gw->alpha && _evas_gl_x11_rgba_vi)
+     gw->visualinfo = _evas_gl_x11_rgba_vi;
+   else
+     gw->visualinfo = _evas_gl_x11_vi;
+
+// EGL / GLES
+#ifdef GL_GLES
+   gw->egl_disp = eglGetDisplay((EGLNativeDisplayType)(gw->disp));
+   if (!gw->egl_disp)
      {
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-        if (_evas_gl_x11_rgba_vi)
-          {
-             vi_use = _evas_gl_x11_rgba_vi;
-          }
-#else
-//#ifdef NEWGL
-        if (_evas_gl_x11_rgba_vi)
-          {
-             vi_use = _evas_gl_x11_rgba_vi;
-          }
-//#endif
-#endif
+        ERR("eglGetDisplay() fail. code=%#x", eglGetError());
+        eng_window_free(gw);
+        return NULL;
+     }
+   if (!eglInitialize(gw->egl_disp, &major_version, &minor_version))
+     {
+        ERR("eglInitialize() fail. code=%#x", eglGetError());
+        eng_window_free(gw);
+        return NULL;
+     }
+   if (eglBindAPI(EGL_OPENGL_ES_API) != EGL_TRUE)
+     {
+        ERR("eglBindAPI() fail. code=%#x", eglGetError());
+        eng_window_free(gw);
+        return NULL;
      }
-   gw->visualinfo = vi_use;
+   /* Find matching config & visual */
+try_again:
+   i = 0;
 
-// EGL / GLES
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
    context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
    context_attrs[1] = 2;
    context_attrs[2] = EGL_NONE;
 
-# if defined(GLES_VARIETY_S3C6410)
-   if (gw->visualinfo->depth == 16) // 16bpp
-     {
-        config_attrs[n++] = EGL_SURFACE_TYPE;
-        config_attrs[n++] = EGL_WINDOW_BIT;
-        config_attrs[n++] = EGL_RENDERABLE_TYPE;
-        config_attrs[n++] = EGL_OPENGL_ES2_BIT;
-        config_attrs[n++] = EGL_RED_SIZE;
-        config_attrs[n++] = 5;
-        config_attrs[n++] = EGL_GREEN_SIZE;
-        config_attrs[n++] = 6;
-        config_attrs[n++] = EGL_BLUE_SIZE;
-        config_attrs[n++] = 5;
-        config_attrs[n++] = EGL_DEPTH_SIZE;
-        config_attrs[n++] = 0;
-        config_attrs[n++] = EGL_STENCIL_SIZE;
-        config_attrs[n++] = 0;
-        config_attrs[n++] = EGL_NONE;
-     }
-   else // 24/32bit. no one does 8bpp anymore. and 15bpp... dead
-     {
-        config_attrs[n++] = EGL_SURFACE_TYPE;
-        config_attrs[n++] = EGL_WINDOW_BIT;
-        config_attrs[n++] = EGL_RENDERABLE_TYPE;
-        config_attrs[n++] = EGL_OPENGL_ES2_BIT;
-        config_attrs[n++] = EGL_RED_SIZE;
-        config_attrs[n++] = 8;
-        config_attrs[n++] = EGL_GREEN_SIZE;
-        config_attrs[n++] = 8;
-        config_attrs[n++] = EGL_BLUE_SIZE;
-        config_attrs[n++] = 8;
-        config_attrs[n++] = EGL_DEPTH_SIZE;
-        config_attrs[n++] = 0;
-        config_attrs[n++] = EGL_STENCIL_SIZE;
-        config_attrs[n++] = 0;
-        config_attrs[n++] = EGL_NONE;
-     }
-# elif defined(GLES_VARIETY_SGX)
-   config_attrs[n++] = EGL_SURFACE_TYPE;
-   config_attrs[n++] = EGL_WINDOW_BIT;
-   config_attrs[n++] = EGL_RENDERABLE_TYPE;
-   config_attrs[n++] = EGL_OPENGL_ES2_BIT;
-#if 0
+   config_attrs[i++] = EGL_SURFACE_TYPE;
+   if (gw->win_back)
+     config_attrs[i++] = EGL_PIXMAP_BIT;
+   else
+     config_attrs[i++] = EGL_WINDOW_BIT;
+   config_attrs[i++] = EGL_RENDERABLE_TYPE;
+   config_attrs[i++] = EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES_BIT;
+# if 0
 // FIXME: n900 - omap3 sgx libs break here
-   config_attrs[n++] = EGL_RED_SIZE;
-   config_attrs[n++] = 1;
-   config_attrs[n++] = EGL_GREEN_SIZE;
-   config_attrs[n++] = 1;
-   config_attrs[n++] = EGL_BLUE_SIZE;
-   config_attrs[n++] = 1;
+   config_attrs[i++] = EGL_RED_SIZE;
+   config_attrs[i++] = 1;
+   config_attrs[i++] = EGL_GREEN_SIZE;
+   config_attrs[i++] = 1;
+   config_attrs[i++] = EGL_BLUE_SIZE;
+   config_attrs[i++] = 1;
 // FIXME: end n900 breakage
-#endif
-   if (gw->alpha)
+# endif
+
+   if (gw->alpha || gw->win_back)
+     {
+        config_attrs[i++] = EGL_ALPHA_SIZE;
+        config_attrs[i++] = 1;
+     }
+
+   // Direct Rendering Option for widget (e.g. WEBKIT)
+   /*
+     * Sometimes, Tizen Widget uses Evas GL with Direct Rendering.
+     * This widget also runs with depth/stencil.
+     * Unfortunately, Application can not know this widget uses Evas GL that runs with DR, Depth/Stencil buffer.
+     * Although application does not set depth/stencil buffer size,
+     * evas gl render engine should set depth/stencil buffer size with minimum.
+     * This is HACK code for tizen platform.
+     */
+
+   if (depth_bits)
      {
-        config_attrs[n++] = EGL_ALPHA_SIZE;
-        config_attrs[n++] = 1;
+        config_attrs[i++] = EGL_DEPTH_SIZE;
+        config_attrs[i++] = depth_bits;
      }
    else
      {
-        config_attrs[n++] = EGL_ALPHA_SIZE;
-        config_attrs[n++] = 0;
+        config_attrs[i++] = EGL_DEPTH_SIZE;
+        config_attrs[i++] = 1;
      }
-   config_attrs[n++] = EGL_DEPTH_SIZE;
-   config_attrs[n++] = 0;
-   config_attrs[n++] = EGL_STENCIL_SIZE;
-   config_attrs[n++] = 0;
-   config_attrs[n++] = EGL_NONE;
-# endif
 
-   gw->egl_disp = eglGetDisplay((EGLNativeDisplayType)(gw->disp));
-   if (!gw->egl_disp)
+   if (stencil_bits)
      {
-        ERR("eglGetDisplay() fail. code=%#x", eglGetError());
-       eng_window_free(gw);
-        return NULL;
+        config_attrs[i++] = EGL_STENCIL_SIZE;
+        config_attrs[i++] = stencil_bits;
      }
-   if (!eglInitialize(gw->egl_disp, &major_version, &minor_version))
+   else
      {
-        ERR("eglInitialize() fail. code=%#x", eglGetError());
-       eng_window_free(gw);
-        return NULL;
+        config_attrs[i++] = EGL_STENCIL_SIZE;
+        config_attrs[i++] = 1;
      }
-   eglBindAPI(EGL_OPENGL_ES_API);
-   if (eglGetError() != EGL_SUCCESS)
+
+   if (msaa_bits)
      {
-        ERR("eglBindAPI() fail. code=%#x", eglGetError());
-       eng_window_free(gw);
-        return NULL;
+        config_attrs[i++] = EGL_SAMPLE_BUFFERS;
+        config_attrs[i++] = 1;
+        config_attrs[i++] = EGL_SAMPLES;
+        config_attrs[i++] = msaa_bits;
      }
+   config_attrs[i++] = EGL_NONE;
 
-   num_config = 0;
-   if (!eglChooseConfig(gw->egl_disp, config_attrs, &gw->egl_config,
-                        1, &num_config) || (num_config != 1))
+   num = 0;
+   if ((!eglChooseConfig(gw->egl_disp, config_attrs, configs, 200, &num))
+       || (num < 1))
      {
-        ERR("eglChooseConfig() fail. code=%#x", eglGetError());
-       eng_window_free(gw);
+        ERR("eglChooseConfig() can't find any configs (alpha: %d, depth: %d, stencil: %d, msaa: %d, num %d)",
+            alpha, depth_bits, stencil_bits, gw->msaa_bits,num);
+        if ((depth_bits > 24) || (stencil_bits > 8))
+          {
+             WRN("Please note that your driver might not support 32-bit depth or "
+                 "16-bit stencil buffers, so depth24, stencil8 are the maximum "
+                 "recommended values.");
+             if (depth_bits > 24) depth_bits = 24;
+             if (stencil_bits > 8) stencil_bits = 8;
+             DBG("Trying again with depth:%d, stencil:%d", depth_bits, stencil_bits);
+             goto try_again;
+          }
+        else if (msaa_bits)
+          {
+             msaa_bits /= 2;
+             DBG("Trying again with msaa_samples: %d", msaa_bits);
+             goto try_again;
+          }
+        else if (depth_bits || stencil_bits)
+          {
+             depth_bits = 0;
+             stencil_bits = 0;
+             DBG("Trying again without any depth or stencil buffer");
+             goto try_again;
+          }
+        free(gw);
         return NULL;
      }
-   gw->egl_surface[0] = eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
-                                               (EGLNativeWindowType)gw->win,
-                                               NULL);
-   if (gw->egl_surface[0] == EGL_NO_SURFACE)
+
+   found = EINA_FALSE;
+   for (i = 0; (i < num) && (!found); i++)
      {
-        ERR("eglCreateWindowSurface() fail for %#x. code=%#x",
-            (unsigned int)gw->win, eglGetError());
-       eng_window_free(gw);
-        return NULL;
+        EGLint val = 0;
+        VisualID visid = 0;
+        XVisualInfo *xvi, vi_in;
+        int nvi, j;
+
+        if (!eglGetConfigAttrib(gw->egl_disp, configs[i],
+                                EGL_NATIVE_VISUAL_ID, &val))
+          continue;
+        visid = vis;
+        vi_in.screen = screen;
+        vi_in.visualid = visid;
+        xvi = XGetVisualInfo(disp,
+                             VisualScreenMask |
+                             VisualIDMask,
+                             &vi_in, &nvi);
+        for (j = 0; j < nvi; j++)
+          {
+             if (!alpha)
+               {
+                  if (xvi[j].depth == depth)
+                    {
+                       gw->egl_config = configs[i];
+                       found = EINA_TRUE;
+                       break;
+                    }
+               }
+             else
+               {
+                  XRenderPictFormat *fmt;
+
+                  fmt = XRenderFindVisualFormat
+                        (disp, xvi[j].visual);
+                  if ((fmt->direct.alphaMask > 0) &&
+                      (fmt->type == PictTypeDirect))
+                    {
+                       gw->egl_config = configs[i];
+                       found = EINA_TRUE;
+                       break;
+                    }
+               }
+          }
+        if (xvi) XFree(xvi);
      }
-   if (context == EGL_NO_CONTEXT)
-     context = eglCreateContext(gw->egl_disp, gw->egl_config, NULL,
-                                context_attrs);
-   gw->egl_context[0] = context;
+   if (!found)
+     {
+        // this is a less correct fallback if the above fails to
+        // find the right visuals/configs
+        gw->egl_config = configs[0];
+     }
+   if (gw->win_back)
+     {
+        gw->egl_surface[0] = eglCreatePixmapSurface(gw->egl_disp, gw->egl_config,
+                                                    (EGLNativePixmapType)gw->win,
+                                                    NULL);
+        if (gw->egl_surface[0] == EGL_NO_SURFACE)
+          {
+             ERR("eglCreatePixmapSurface() fail for %#x. code=%#x",
+                 (unsigned int)gw->win, eglGetError());
+             eng_window_free(gw);
+             return NULL;
+          }
+
+        gw->egl_surface[1] = eglCreatePixmapSurface(gw->egl_disp, gw->egl_config,
+                                                    (EGLNativePixmapType)gw->win_back,
+                                                    NULL);
+        if (gw->egl_surface[1] == EGL_NO_SURFACE)
+          {
+             ERR("eglCreatePixmapSurface() fail for %#x. code=%#x",
+                 (unsigned int)gw->win_back, eglGetError());
+             eng_window_free(gw);
+             return NULL;
+          }
+     }
+   else
+     {
+        gw->egl_surface[0] = eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
+                                                    (EGLNativeWindowType)gw->win,
+                                                    NULL);
+        if (gw->egl_surface[0] == EGL_NO_SURFACE)
+          {
+             ERR("eglCreateWindowSurface() fail for %#x. code=%#x",
+                 (unsigned int)gw->win, eglGetError());
+             eng_window_free(gw);
+             return NULL;
+          }
+     }
+   context = _tls_context_get();
+   gw->egl_context[0] = eglCreateContext
+     (gw->egl_disp, gw->egl_config, context, context_attrs);
    if (gw->egl_context[0] == EGL_NO_CONTEXT)
      {
         ERR("eglCreateContext() fail. code=%#x", eglGetError());
-       eng_window_free(gw);
+        eng_window_free(gw);
         return NULL;
      }
+   if (context == EGL_NO_CONTEXT)
+     _tls_context_set(gw->egl_context[0]);
    if (eglMakeCurrent(gw->egl_disp,
                       gw->egl_surface[0],
                       gw->egl_surface[0],
                       gw->egl_context[0]) == EGL_FALSE)
      {
         ERR("eglMakeCurrent() fail. code=%#x", eglGetError());
-       eng_window_free(gw);
+        eng_window_free(gw);
         return NULL;
      }
-
    vendor = glGetString(GL_VENDOR);
    renderer = glGetString(GL_RENDERER);
    version = glGetString(GL_VERSION);
@@ -236,7 +392,9 @@ eng_window_new(Display *disp,
      }
    if (strstr((const char *)renderer, "softpipe"))
      blacklist = 1;
-   if (blacklist)
+   if (strstr((const char *)renderer, "llvmpipe"))
+     blacklist = 1;
+   if ((blacklist) && (!getenv("EVAS_GL_NO_BLACKLIST")))
      {
         ERR("OpenGL Driver blacklisted:");
         ERR("Vendor: %s", (const char *)vendor);
@@ -245,8 +403,16 @@ eng_window_new(Display *disp,
         eng_window_free(gw);
         return NULL;
      }
+
+   eglGetConfigAttrib(gw->egl_disp, gw->egl_config, EGL_DEPTH_SIZE, &val);
+   gw->detected.depth_buffer_size = val;
+   eglGetConfigAttrib(gw->egl_disp, gw->egl_config, EGL_STENCIL_SIZE, &val);
+   gw->detected.stencil_buffer_size = val;
+   eglGetConfigAttrib(gw->egl_disp, gw->egl_config, EGL_SAMPLES, &val);
+   gw->detected.msaa = val;
 // GLX
 #else
+   context = _tls_context_get();
    if (!context)
      {
 #ifdef NEWGL
@@ -283,7 +449,7 @@ eng_window_new(Display *disp,
      gw->glxwin = glXCreateWindow(gw->disp, fbconf, gw->win, NULL);
    if (!gw->glxwin)
      {
-       eng_window_free(gw);
+        eng_window_free(gw);
         return NULL;
      }
 
@@ -295,14 +461,11 @@ eng_window_new(Display *disp,
 
    if (!gw->context)
      {
-       eng_window_free(gw);
+        eng_window_free(gw);
         return NULL;
      }
    if (gw->context)
      {
-        int i, j,  num;
-        GLXFBConfig *fbc;
-
         if (gw->glxwin)
           {
              if (!glXMakeContextCurrent(gw->disp, gw->glxwin, gw->glxwin,
@@ -398,12 +561,14 @@ eng_window_new(Display *disp,
           }
         if (strstr((const char *)renderer, "softpipe"))
            blacklist = 1;
-        if (blacklist)
+        if (strstr((const char *)renderer, "llvmpipe"))
+          blacklist = 1;
+        if ((blacklist) && (!getenv("EVAS_GL_NO_BLACKLIST")))
           {
-             ERR("OpenGL Driver blacklisted:");
-             ERR("Vendor: %s", (const char *)vendor);
-             ERR("Renderer: %s", (const char *)renderer);
-             ERR("Version: %s", (const char *)version);
+             fprintf(stderr,"OpenGL Driver blacklisted:");
+             fprintf(stderr,"Vendor: %s", (const char *)vendor);
+             fprintf(stderr,"Renderer: %s", (const char *)renderer);
+             fprintf(stderr,"Version: %s", (const char *)version);
              eng_window_free(gw);
              return NULL;
           }
@@ -432,98 +597,22 @@ eng_window_new(Display *disp,
           {
              // noothing yet. add more cases and options over time
           }
-
-        fbc = glXGetFBConfigs(gw->disp, screen, &num);
-        if (!fbc)
-          {
-             ERR("glXGetFBConfigs() returned no fb configs");
-             eng_window_free(gw);
-             return NULL;
-          }
-        for (i = 0; i <= 32; i++)
-          {
-             for (j = 0; j < num; j++)
-               {
-                  XVisualInfo *vi;
-                  int vd;
-                  int alph, val, dbuf, stencil, tdepth;
-                  int rgba;
-
-                  vi = glXGetVisualFromFBConfig(gw->disp, fbc[j]);
-                  if (!vi) continue;
-                  vd = vi->depth;
-                  XFree(vi);
-
-                  if (vd != i) continue;
-
-                  glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_ALPHA_SIZE, &alph);
-                  glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BUFFER_SIZE, &val);
-
-                  if ((val != i) && ((val - alph) != i)) continue;
-
-                  val = 0;
-                  rgba = 0;
-
-                  if (i == 32)
-                    {
-                       glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BIND_TO_TEXTURE_RGBA_EXT, &val);
-                       if (val)
-                         {
-                            rgba = 1;
-                            gw->depth_cfg[i].tex_format = GLX_TEXTURE_FORMAT_RGBA_EXT;
-                         }
-                    }
-                  if (!val)
-                    {
-                       if (rgba) continue;
-                       glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BIND_TO_TEXTURE_RGB_EXT, &val);
-                       if (!val) continue;
-                       gw->depth_cfg[i].tex_format = GLX_TEXTURE_FORMAT_RGB_EXT;
-                    }
-
-                  dbuf = 0x7fff;
-                  glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_DOUBLEBUFFER, &val);
-                  if (val > dbuf) continue;
-                  dbuf = val;
-
-                  stencil = 0x7fff;
-                  glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_STENCIL_SIZE, &val);
-                  if (val > stencil) continue;
-                  stencil = val;
-
-                  tdepth = 0x7fff;
-                  glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_DEPTH_SIZE, &val);
-                  if (val > tdepth) continue;
-                  tdepth = val;
-
-                  glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BIND_TO_MIPMAP_TEXTURE_EXT, &val);
-                  if (val < 0) continue;
-                  gw->depth_cfg[i].mipmap = val;
-
-                  glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_Y_INVERTED_EXT, &val);
-                  gw->depth_cfg[i].yinvert = val;
-
-                  glXGetFBConfigAttrib(gw->disp, fbc[j], GLX_BIND_TO_TEXTURE_TARGETS_EXT, &val);
-                  gw->depth_cfg[i].tex_target = val;
-
-                  gw->depth_cfg[i].fbc = fbc[j];
-               }
-          }
-        XFree(fbc);
-        if (!gw->depth_cfg[DefaultDepth(gw->disp, screen)].fbc)
-          {
-             WRN("texture from pixmap not going to work");
-          }
+        glXGetConfig(gw->disp, gw->visualinfo, GLX_DEPTH_SIZE, &val);
+        gw->detected.depth_buffer_size = val;
+        glXGetConfig(gw->disp, gw->visualinfo, GLX_STENCIL_SIZE, &val);
+        gw->detected.stencil_buffer_size = val;
+        glXGetConfig(gw->disp, gw->visualinfo, GLX_SAMPLES, &val);
+        gw->detected.msaa = val;
      }
 #endif
 
    gw->gl_context = evas_gl_common_context_new();
    if (!gw->gl_context)
      {
-       eng_window_free(gw);
-       return NULL;
+        eng_window_free(gw);
+        return NULL;
      }
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
    gw->gl_context->egldisp = gw->egl_disp;
 #endif
    eng_window_use(gw);
@@ -536,33 +625,44 @@ eng_window_new(Display *disp,
 void
 eng_window_free(Evas_GL_X11_Window *gw)
 {
+   Evas_GL_X11_Window *xwin;
+   GLContext context;
    int ref = 0;
+
    win_count--;
    eng_window_use(gw);
-   if (gw == _evas_gl_x11_window) _evas_gl_x11_window = NULL;
+
+   context = _tls_context_get();
+   xwin = _tls_evas_gl_x11_window_get();
+
+   if (gw == xwin) _tls_evas_gl_x11_window_set(NULL);
    if (gw->gl_context)
      {
         ref = gw->gl_context->references - 1;
         evas_gl_common_context_free(gw->gl_context);
      }
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
+   eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    if (gw->egl_surface[0] != EGL_NO_SURFACE)
       eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
-   eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+   if (gw->egl_surface[1] != EGL_NO_SURFACE)
+      eglDestroySurface(gw->egl_disp, gw->egl_surface[1]);
+   if (gw->egl_context[0] != context)
+     eglDestroyContext(gw->egl_disp, gw->egl_context[0]);
    if (ref == 0)
      {
         if (context) eglDestroyContext(gw->egl_disp, context);
         eglTerminate(gw->egl_disp);
-        context = EGL_NO_CONTEXT;
+        eglReleaseThread();
+        _tls_context_set(EGL_NO_CONTEXT);
      }
-   eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
 #else
    if (gw->glxwin) glXDestroyWindow(gw->disp, gw->glxwin);
    if (ref == 0)
      {
         if (context) glXDestroyContext(gw->disp, context);
         if (rgba_context) glXDestroyContext(gw->disp, rgba_context);
-        context = 0;
+        _tls_context_set(0);
         rgba_context = 0;
         fbconf = 0;
         rgba_fbconf = 0;
@@ -575,42 +675,48 @@ void
 eng_window_use(Evas_GL_X11_Window *gw)
 {
    Eina_Bool force_use = EINA_FALSE;
+   Evas_GL_X11_Window *xwin;
+
+   xwin = _tls_evas_gl_x11_window_get();
 
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   if (_evas_gl_x11_window)
+#ifdef GL_GLES
+   if (xwin)
      {
-        if ((eglGetCurrentContext() !=
-             _evas_gl_x11_window->egl_context[0]) ||
+        if ((eglGetCurrentDisplay() !=
+             xwin->egl_disp) ||
+               (eglGetCurrentContext() !=
+             xwin->egl_context[0]) ||
             (eglGetCurrentSurface(EGL_READ) !=
-                _evas_gl_x11_window->egl_surface[0]) ||
+                xwin->egl_surface[xwin->offscreen]) ||
             (eglGetCurrentSurface(EGL_DRAW) !=
-                _evas_gl_x11_window->egl_surface[0]))
+                xwin->egl_surface[xwin->offscreen]))
            force_use = EINA_TRUE;
      }
 #else
-   if (_evas_gl_x11_window)
+   if (xwin)
      {
-        if (glXGetCurrentContext() != _evas_gl_x11_window->context)
+        if (glXGetCurrentContext() != xwin->context)
            force_use = EINA_TRUE;
      }
 #endif
-   if ((_evas_gl_x11_window != gw) || (force_use))
+   if ((xwin != gw) || (force_use))
      {
-        if (_evas_gl_x11_window)
+        if (xwin)
           {
-             evas_gl_common_context_use(_evas_gl_x11_window->gl_context);
-             evas_gl_common_context_flush(_evas_gl_x11_window->gl_context);
+             evas_gl_common_context_use(xwin->gl_context);
+             evas_gl_common_context_flush(xwin->gl_context);
+             xwin->gl_context->pipe[0].shader.surface = NULL;
           }
-        _evas_gl_x11_window = gw;
+        _tls_evas_gl_x11_window_set(gw);
         if (gw)
           {
 // EGL / GLES
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-           if (gw->egl_surface[0] != EGL_NO_SURFACE)
+#ifdef GL_GLES
+           if (gw->egl_surface[gw->offscreen] != EGL_NO_SURFACE)
              {
                 if (eglMakeCurrent(gw->egl_disp,
-                                   gw->egl_surface[0],
-                                   gw->egl_surface[0],
+                                   gw->egl_surface[gw->offscreen],
+                                   gw->egl_surface[gw->offscreen],
                                    gw->egl_context[0]) == EGL_FALSE)
                   {
                      ERR("eglMakeCurrent() failed!");
@@ -640,22 +746,29 @@ eng_window_use(Evas_GL_X11_Window *gw)
 }
 
 void
-eng_window_unsurf(Evas_GL_X11_Window *gw)
+eng_window_unsurf(Evas_GL_X11_Window *gw, Eina_Bool pre_rotation_resurf)
 {
    if (!gw->surf) return;
-   if (!getenv("EVAS_GL_WIN_RESURF")) return;
+   if (!getenv("EVAS_GL_WIN_RESURF") && !pre_rotation_resurf) return;
    if (getenv("EVAS_GL_INFO"))
       printf("unsurf %p\n", gw);
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   if (_evas_gl_x11_window)
-      evas_gl_common_context_flush(_evas_gl_x11_window->gl_context);
-   if (_evas_gl_x11_window == gw)
+
+#ifdef GL_GLES
+   Evas_GL_X11_Window *xwin;
+
+   xwin = _tls_evas_gl_x11_window_get();
+   if (xwin)
+      evas_gl_common_context_flush(xwin->gl_context);
+   if (xwin == gw || pre_rotation_resurf)
      {
         eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
         if (gw->egl_surface[0] != EGL_NO_SURFACE)
            eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
         gw->egl_surface[0] = EGL_NO_SURFACE;
-        _evas_gl_x11_window = NULL;
+        if (gw->egl_surface[1] != EGL_NO_SURFACE)
+           eglDestroySurface(gw->egl_disp, gw->egl_surface[1]);
+        gw->egl_surface[1] = EGL_NO_SURFACE;
+        _tls_evas_gl_x11_window_set(NULL);
      }
 #else
    if (gw->glxwin)
@@ -675,19 +788,46 @@ eng_window_resurf(Evas_GL_X11_Window *gw)
    if (gw->surf) return;
    if (getenv("EVAS_GL_INFO"))
       printf("resurf %p\n", gw);
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
-   gw->egl_surface[0] = eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
-                                                     (EGLNativeWindowType)gw->win,
-                                                     NULL);
-   if (gw->egl_surface[0] == EGL_NO_SURFACE)
+#ifdef GL_GLES
+   if (gw->win_back)
+     {
+        gw->egl_surface[0] = eglCreatePixmapSurface(gw->egl_disp, gw->egl_config,
+                                                        (EGLNativePixmapType)gw->win,
+                                                        NULL);
+        if (gw->egl_surface[0] == EGL_NO_SURFACE)
+          {
+             ERR("eglCreatePixmapSurface() fail for %#x. code=%#x",
+                 (unsigned int)gw->win, eglGetError());
+             return;
+          }
+        ERR("%x = eglCreatePixmapSurface(pixmap %x)", gw->egl_surface[0], gw->win);
+
+        gw->egl_surface[1] = eglCreatePixmapSurface(gw->egl_disp, gw->egl_config,
+                                                        (EGLNativePixmapType)gw->win_back,
+                                                        NULL);
+        if (gw->egl_surface[1] == EGL_NO_SURFACE)
+          {
+             ERR("eglCreatePixmapSurface() fail for %#x. code=%#x",
+                 (unsigned int)gw->win_back, eglGetError());
+             return;
+          }
+        ERR("%x = eglCreatePixmapSurface(pixmap %x)", gw->egl_surface[1], gw->win_back);
+     }
+   else
      {
-        ERR("eglCreateWindowSurface() fail for %#x. code=%#x",
-            (unsigned int)gw->win, eglGetError());
-        return;
+        gw->egl_surface[0] = eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
+                                                        (EGLNativeWindowType)gw->win,
+                                                        NULL);
+        if (gw->egl_surface[0] == EGL_NO_SURFACE)
+          {
+             ERR("eglCreateWindowSurface() fail for %#x. code=%#x",
+                 (unsigned int)gw->win, eglGetError());
+             return;
+          }
      }
    if (eglMakeCurrent(gw->egl_disp,
-                      gw->egl_surface[0],
-                      gw->egl_surface[0],
+                      gw->egl_surface[gw->offscreen],
+                      gw->egl_surface[gw->offscreen],
                       gw->egl_context[0]) == EGL_FALSE)
      {
         ERR("eglMakeCurrent() failed!");
@@ -723,7 +863,7 @@ eng_best_visual_get(Evas_Engine_Info_GL_X11 *einfo)
         int alpha;
 
 // EGL / GLES
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
         for (alpha = 0; alpha < 2; alpha++)
           {
              int depth = DefaultDepth(einfo->info.display,
@@ -785,7 +925,7 @@ eng_best_visual_get(Evas_Engine_Info_GL_X11 *einfo)
              config_attrs[i++] = GLX_RED_SIZE;
              config_attrs[i++] = 1;
              config_attrs[i++] = GLX_GREEN_SIZE;
-             config_attrs[i++] =1;
+             config_attrs[i++] = 1;
              config_attrs[i++] = GLX_BLUE_SIZE;
              config_attrs[i++] = 1;
              if (alpha)
@@ -811,7 +951,7 @@ eng_best_visual_get(Evas_Engine_Info_GL_X11 *einfo)
              config_attrs[i++] = GLX_TRANSPARENT_TYPE;
              config_attrs[i++] = GLX_NONE;//GLX_NONE;//GLX_TRANSPARENT_INDEX//GLX_TRANSPARENT_RGB;
              config_attrs[i++] = 0;
-             
+
              configs = glXChooseFBConfig(einfo->info.display,
                                          einfo->info.screen,
                                          config_attrs, &num);
@@ -865,7 +1005,7 @@ eng_best_visual_get(Evas_Engine_Info_GL_X11 *einfo)
    if (einfo->info.destination_alpha)
      {
 // EGL / GLES
-#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
+#ifdef GL_GLES
         if (_evas_gl_x11_rgba_vi) return _evas_gl_x11_rgba_vi->visual;
 #else
 //# ifdef NEWGL
@@ -917,3 +1057,40 @@ eng_best_depth_get(Evas_Engine_Info_GL_X11 *einfo)
      }
    return _evas_gl_x11_vi->depth;
 }
+
+int
+eng_native_config_check(Display *disp, void *config , int target, void *pixmap, int *w, int *h)
+{
+   Window root;
+   int x, y;
+   unsigned int border;
+   unsigned int depth;
+   int ret = 0;
+   Evas_GL_Config *cfg = config;
+
+   // Check target
+   if (target!=1) // EGL_NATIVE_PIXMAP_KHR
+     {
+        ERR("Invalid native target");
+        return 0;
+     }
+
+   // Retrive pixmap information
+   ret = XGetGeometry(disp, (Drawable)pixmap, &root, &x, &y, w, h, &border, &depth);
+   if (!ret)
+     {
+        ERR("Unable to retrieve pixmap information");
+        return 0;
+     }
+
+   // Check the validity of the depth of the target
+   if ( ((cfg->color_format==EVAS_GL_RGB_888)   && (depth != 24)) ||
+        ((cfg->color_format==EVAS_GL_RGBA_8888) && (depth != 32)) )
+     {
+        ERR("Unsupported native depth");
+        return 0;
+     }
+
+   DBG("Pixmap Width [%d] Height [%d] Depth [%d]", *w, *h, depth);
+   return 1;
+}
index 557e51c..306ad03 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/modules/engines \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_engine_psl1ght_cflags@
 
@@ -29,7 +29,7 @@ if !EVAS_STATIC_BUILD_PSL1GHT
 pkgdir = $(libdir)/evas/modules/engines/psl1ght/$(MODULE_ARCH)
 pkg_LTLIBRARIES = module.la
 module_la_SOURCES = $(PSL1GHT_SOURCES)
-module_la_LIBADD = @EINA_LIBS@ $(PSL1GHT_LIBADD) $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ $(PSL1GHT_LIBADD) $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
diff --git a/src/modules/engines/software_16/Makefile.am b/src/modules/engines/software_16/Makefile.am
deleted file mode 100644 (file)
index fec60ac..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-
-MAINTAINERCLEANFILES = Makefile.in
-
-AM_CPPFLAGS = \
--I. \
--I$(top_srcdir)/src/lib \
--I$(top_srcdir)/src/lib/include \
--I$(top_srcdir)/src/modules/engines \
-@FREETYPE_CFLAGS@ \
-@PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@
-
-if BUILD_ENGINE_SOFTWARE_16
-
-SOFTWARE_16_SOURCES = evas_engine.c
-
-
-if !EVAS_STATIC_BUILD_SOFTWARE_16
-
-pkgdir = $(libdir)/evas/modules/engines/software_16/$(MODULE_ARCH)
-pkg_LTLIBRARIES = module.la
-module_la_SOURCES = $(SOFTWARE_16_SOURCES)
-module_la_LIBADD = @EINA_LIBS@ $(top_builddir)/src/lib/libevas.la
-module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
-module_la_LIBTOOLFLAGS = --tag=disable-static
-
-else
-
-noinst_LTLIBRARIES = libevas_engine_software_16.la
-
-libevas_engine_software_16_la_SOURCES = $(SOFTWARE_16_SOURCES)
-
-endif
-endif
-
-EXTRA_DIST = \
-evas_engine.c
diff --git a/src/modules/engines/software_16/evas_engine.c b/src/modules/engines/software_16/evas_engine.c
deleted file mode 100644 (file)
index ecb8d55..0000000
+++ /dev/null
@@ -1,400 +0,0 @@
-#include "evas_common.h"/* Also includes international specific stuff */
-#include "evas_common_soft16.h"
-
-/*
- *****
- **
- ** ENGINE ROUTINES
- **
- *****
- */
-int _evas_soft16_log_dom = -1;
-/* function tables - filled in later (func and parent func) */
-static Evas_Func func, pfunc;
-#ifdef ERR
-#undef ERR
-#endif
-#define ERR(...) EINA_LOG_DOM_ERR( _evas_soft16_log_dom, __VA_ARGS__)
-
-#ifdef DBG
-#undef DBG
-#endif
-#define DBG(...) EINA_LOG_DOM_DBG(_evas_soft16_log_dom, __VA_ARGS__)
-
-#ifdef INF
-#undef INF
-#endif
-#define INF(...) EINA_LOG_DOM_INFO(_evas_soft16_log_dom, __VA_ARGS__)
-
-#ifdef WRN
-#undef WRN
-#endif
-#define WRN(...) EINA_LOG_DOM_WARN(_evas_soft16_log_dom, __VA_ARGS__)
-
-#ifdef CRIT
-#undef CRIT
-#endif
-#define CRIT(...) EINA_LOG_DOM_CRIT(_evas_soft16_log_dom, __VA_ARGS__)
-
-#define NOT_IMPLEMENTED()                                               \
-  WRN("NOT_IMPLEMENTED: %s() at %s:%d",                                \
-           __FUNCTION__, __FILE__, __LINE__)
-
-static void
-eng_rectangle_draw(void *data __UNUSED__, void *context, void *surface, int x, int y, int w, int h)
-{
-   evas_common_soft16_rectangle_draw(surface, context, x, y, w, h);
-}
-
-static void
-eng_line_draw(void *data __UNUSED__, void *context, void *surface, int x1, int y1, int x2, int y2)
-{
-   evas_common_soft16_line_draw(surface, context, x1, y1, x2, y2);
-}
-
-static void
-eng_polygon_draw(void *data __UNUSED__, void *context, void *surface, void *polygon, int x, int y)
-{
-   evas_common_soft16_polygon_draw(surface, context, polygon, x, y);
-}
-
-static int
-eng_image_alpha_get(void *data __UNUSED__, void *image)
-{
-   Soft16_Image *im;
-
-   if (!image) return 0;
-   im = image;
-   return im->cache_entry.flags.alpha;
-}
-
-static void *
-eng_image_alpha_set(void *data __UNUSED__, void *image, int have_alpha)
-{
-   if (!image) return NULL;
-   have_alpha = !!have_alpha;
-   image = evas_common_soft16_image_alpha_set(image, have_alpha);
-   return image;
-}
-
-static char *
-eng_image_comment_get(void *data __UNUSED__, void *image __UNUSED__, char *key __UNUSED__)
-{
-   return NULL;
-}
-
-static char *
-eng_image_format_get(void *data __UNUSED__, void *image __UNUSED__)
-{
-   NOT_IMPLEMENTED();
-   return NULL;
-}
-
-static int
-eng_image_colorspace_get(void *data __UNUSED__, void *image __UNUSED__)
-{
-   return EVAS_COLORSPACE_RGB565_A5P;
-}
-
-
-static void
-eng_image_colorspace_set(void *data __UNUSED__, void *image __UNUSED__, int cspace __UNUSED__)
-{
-   NOT_IMPLEMENTED();
-}
-
-static void *
-eng_image_native_set(void *data __UNUSED__, void *image __UNUSED__, void *native __UNUSED__)
-{
-   NOT_IMPLEMENTED();
-   return NULL;
-}
-
-static void *
-eng_image_native_get(void *data __UNUSED__, void *image __UNUSED__)
-{
-   NOT_IMPLEMENTED();
-   return NULL;
-}
-
-static void *
-eng_image_load(void *data __UNUSED__, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
-{
-   return evas_cache_image_request(evas_common_soft16_image_cache_get(), file, key, lo, error);
-}
-
-static void *
-eng_image_new_from_data(void *data __UNUSED__, int w, int h, DATA32 *image_data, int alpha, int cspace)
-{
-   if ((image_data) && (cspace != EVAS_COLORSPACE_RGB565_A5P))
-     {
-       WRN("Unsupported colorspace %d in %s() (%s:%d)",
-               cspace, __FUNCTION__, __FILE__, __LINE__);
-       return NULL;
-     }
-   return evas_cache_image_data(evas_common_soft16_image_cache_get(), w, h, image_data, alpha, EVAS_COLORSPACE_RGB565_A5P);
-}
-
-static void *
-eng_image_new_from_copied_data(void *data __UNUSED__, int w, int h, DATA32 *image_data, int alpha, int cspace)
-{
-   if ((image_data) && (cspace != EVAS_COLORSPACE_RGB565_A5P))
-     {
-       WRN("Unsupported colorspace %d in %s() (%s:%d)",
-               cspace, __FUNCTION__, __FILE__, __LINE__);
-       return NULL;
-     }
-   return evas_cache_image_copied_data(evas_common_soft16_image_cache_get(), w, h, image_data, alpha, EVAS_COLORSPACE_RGB565_A5P);
-}
-
-static void
-eng_image_size_get(void *data __UNUSED__, void *image, int *w, int *h)
-{
-   Soft16_Image *im;
-
-   if (w) *w = 0;
-   if (h) *h = 0;
-   if (!image) return;
-   im = image;
-   if (w) *w = im->cache_entry.w;
-   if (h) *h = im->cache_entry.h;
-}
-
-static void *
-eng_image_size_set(void *data __UNUSED__, void *image, int w, int h)
-{
-   if (!image) return NULL;
-   if ((w <= 0) || (h <= 0))
-     {
-        evas_cache_image_drop((Image_Entry *) image);
-       return NULL;
-     }
-   return evas_cache_image_size_set((Image_Entry *) image, w, h);
-}
-
-static void
-eng_image_stride_get(void *data __UNUSED__, void *image, int *stride)
-{
-   Soft16_Image *im;
-
-   if (stride) *stride = 0;
-   if (!image) return;
-   im = image;
-   if (stride) *stride = im->stride;
-}
-
-static void *
-eng_image_dirty_region(void *data __UNUSED__, void *image, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
-{
-   /* FIXME: is this required? */
-   //NOT_IMPLEMENTED();
-   return image;
-}
-
-static void *
-eng_image_data_get(void *data __UNUSED__, void *image, int to_write, DATA32 **image_data, int *err)
-{
-   Soft16_Image *im;
-   int error;
-
-   if (!image)
-     {
-       *image_data = NULL;
-       return NULL;
-     }
-
-   im = image;
-   error = evas_cache_image_load_data(&im->cache_entry);
-
-   if (to_write)
-     im = (Soft16_Image *) evas_cache_image_alone(&im->cache_entry);
-
-   if (image_data) *image_data = (DATA32 *) im->pixels;
-
-   if (err) *err = error;
-   return im;
-}
-
-static void *
-eng_image_data_put(void *data __UNUSED__, void *image, DATA32 *image_data)
-{
-   Soft16_Image *old_im, *new_im;
-
-   if (!image) return NULL;
-
-   old_im = image;
-   if ((DATA16 *)image_data == old_im->pixels) return old_im;
-
-   new_im = (Soft16_Image *) evas_cache_image_data(evas_common_soft16_image_cache_get(), old_im->cache_entry.w, old_im->cache_entry.h, image_data, old_im->cache_entry.flags.alpha, EVAS_COLORSPACE_RGB565_A5P);
-   evas_cache_image_drop(&old_im->cache_entry);
-   return new_im;
-}
-
-static void
-eng_image_data_preload_request(void *data __UNUSED__, void *image, const void *target)
-{
-   Soft16_Image *im = image;
-
-   if (!im) return ;
-   evas_cache_image_preload_data(&im->cache_entry, target);
-}
-
-static void
-eng_image_data_preload_cancel(void *data __UNUSED__, void *image, const void *target)
-{
-   Soft16_Image *im = image;
-
-   if (!im) return ;
-   evas_cache_image_preload_cancel(&im->cache_entry, target);
-}
-
-static void
-eng_image_draw(void *data __UNUSED__, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth)
-{
-   Soft16_Image *im;
-
-   im = (Soft16_Image *) image;
-
-   evas_cache_image_load_data(&im->cache_entry);
-   evas_common_soft16_image_draw(im, surface, context,
-                    src_x, src_y, src_w, src_h,
-                    dst_x, dst_y, dst_w, dst_h,
-                    smooth);
-}
-
-static void
-eng_image_scale_hint_set(void *data __UNUSED__, void *image __UNUSED__, int hint __UNUSED__)
-{
-}
-
-static int
-eng_image_scale_hint_get(void *data __UNUSED__, void *image __UNUSED__)
-{
-   return EVAS_IMAGE_SCALE_HINT_NONE;
-}
-
-static void
-eng_image_cache_flush(void *data __UNUSED__)
-{
-   evas_cache_image_flush(evas_common_soft16_image_cache_get());
-}
-
-static void
-eng_image_cache_set(void *data __UNUSED__, int bytes)
-{
-   evas_cache_image_set(evas_common_soft16_image_cache_get(), bytes);
-}
-
-static int
-eng_image_cache_get(void *data __UNUSED__)
-{
-   return evas_cache_image_get(evas_common_soft16_image_cache_get());
-}
-
-static void
-eng_font_draw(void *data __UNUSED__, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, Evas_Text_Props *text_props)
-{
-   static RGBA_Image    *im = NULL;
-   Soft16_Image         *dst = surface;
-
-   if (!im)
-     im = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get());
-   evas_cache_image_surface_alloc(&im->cache_entry, dst->cache_entry.w, dst->cache_entry.h);
-   evas_common_draw_context_font_ext_set(context,
-                                        surface,
-                                        evas_common_soft16_font_glyph_new,
-                                        evas_common_soft16_font_glyph_free,
-                                        evas_common_soft16_font_glyph_draw);
-   evas_common_font_draw_prepare(text_props);
-   evas_common_font_draw(im, context, x, y, text_props);
-   evas_common_draw_context_font_ext_set(context,
-                                        NULL,
-                                        NULL,
-                                        NULL,
-                                        NULL);
-}
-
-/*
- *****
- **
- ** MODULE ACCESSIBLE API API
- **
- *****
- */
-
-static int
-module_open(Evas_Module *em)
-{
-   if (!em) return 0;
-   if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
-   _evas_soft16_log_dom = eina_log_domain_register
-     ("evas-software_16", EVAS_DEFAULT_LOG_COLOR);
-   if (_evas_soft16_log_dom < 0)
-     {
-        EINA_LOG_ERR("Can not create a module log domain.");
-        return 0;
-     }
-   /* store it for later use */
-   func = pfunc;
-   /* now to override methods */
-   EVAS_API_RESET(info, &func);
-   EVAS_API_RESET(info_free, &func);
-   EVAS_API_RESET(setup, &func);
-#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
-   ORD(rectangle_draw);
-   ORD(line_draw);
-   ORD(polygon_draw);
-   ORD(image_load);
-   ORD(image_new_from_data);
-   ORD(image_new_from_copied_data);
-   ORD(image_size_get);
-   ORD(image_size_set);
-   ORD(image_stride_get);
-   ORD(image_dirty_region);
-   ORD(image_data_get);
-   ORD(image_data_put);
-   ORD(image_data_preload_request);
-   ORD(image_data_preload_cancel);
-   ORD(image_alpha_set);
-   ORD(image_alpha_get);
-   ORD(image_draw);
-   ORD(image_comment_get);
-   ORD(image_format_get);
-   ORD(image_colorspace_set);
-   ORD(image_colorspace_get);
-   ORD(image_native_set);
-   ORD(image_native_get);
-   ORD(image_cache_flush);
-   ORD(image_cache_set);
-   ORD(image_cache_get);
-   ORD(font_draw);
-   ORD(image_scale_hint_set);
-   ORD(image_scale_hint_get);
-
-   em->functions = (void *)(&func);
-   
-   return 1;
-}
-
-static void
-module_close(Evas_Module *em __UNUSED__)
-{
-   eina_log_domain_unregister(_evas_soft16_log_dom);
-}
-
-static Evas_Module_Api evas_modapi =
-{
-  EVAS_MODULE_API_VERSION,
-  "software_16",
-  "none",
-  {
-    module_open,
-    module_close
-  }
-};
-
-EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, software_16);
-
-#ifndef EVAS_STATIC_BUILD_SOFTWARE_16
-EVAS_EINA_MODULE_DEFINE(engine, software_16);
-#endif
diff --git a/src/modules/engines/software_16_sdl/Evas_Engine_SDL_16.h b/src/modules/engines/software_16_sdl/Evas_Engine_SDL_16.h
deleted file mode 100644 (file)
index 5a133fe..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef         _EVAS_ENGINE_SDL_16_H
-# define        _EVAS_ENGINE_SDL_16_H
-
-#include <SDL/SDL.h>
-
-typedef struct _Evas_Engine_Info_SDL_16 Evas_Engine_Info_SDL_16;
-struct _Evas_Engine_Info_SDL_16
-{
-  /* PRIVATE - don't mess with this baby or evas will poke its tongue out */
-  /* at you and make nasty noises */
-  Evas_Engine_Info magic;
-
-  struct {
-    int                         rotation;
-    int                         fullscreen : 1;
-    int                         hwsurface : 1;
-    int                         noframe : 1;
-    int                         alpha : 1;
-  } info;
-
-   /* non-blocking or blocking mode */
-   Evas_Engine_Render_Mode render_mode;
-};
-
-#endif
diff --git a/src/modules/engines/software_16_sdl/Makefile.am b/src/modules/engines/software_16_sdl/Makefile.am
deleted file mode 100644 (file)
index 64ce6d6..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-AUTOMAKE_OPTIONS     = 1.4 foreign
-
-MAINTAINERCLEANFILES = Makefile.in
-
-INCLUDES = -I. -I$(top_srcdir)/src/lib -I$(top_srcdir)/src/lib/include \
-@FREETYPE_CFLAGS@ \
-@PIXMAN_CFLAGS@ \
-@SDL_CFLAGS@ \
-@EINA_CFLAGS@ \
-@FRIBIDI_CFLAGS@
-
-if BUILD_ENGINE_SOFTWARE_16_SDL
-
-SOFTWARE_SDL_SOURCES = \
-evas_engine.c \
-evas_engine.h
-
-
-includes_HEADERS = Evas_Engine_SDL_16.h
-includesdir = $(includedir)/evas-@VMAJ@
-
-if !EVAS_STATIC_BUILD_SOFTWARE_16_SDL
-
-pkgdir = $(libdir)/evas/modules/engines/software_16_sdl/$(MODULE_ARCH)
-pkg_LTLIBRARIES = module.la
-
-module_la_SOURCES = $(SOFTWARE_SDL_SOURCES)
-
-module_la_LIBADD = @EINA_LIBS@ @SDL_LIBS@ $(top_builddir)/src/lib/libevas.la
-module_la_LDFLAGS = -no-undefined -module -avoid-version -L$(top_builddir)/src/lib -L$(top_builddir)/src/lib/.libs
-
-else
-
-noinst_LTLIBRARIES = libevas_engine_software_16_sdl.la
-
-libevas_engine_software_16_sdl_la_SOURCES = $(SOFTWARE_SDL_SOURCES)
-libevas_engine_software_16_sdl_la_LIBADD = @SDL_LIBS@
-
-endif
-endif
-
-EXTRA_DIST = \
-evas_engine.c \
-evas_engine.h \
-Evas_Engine_SDL_16.h
diff --git a/src/modules/engines/software_16_sdl/evas_engine.c b/src/modules/engines/software_16_sdl/evas_engine.c
deleted file mode 100644 (file)
index bdd731a..0000000
+++ /dev/null
@@ -1,1338 +0,0 @@
-#include <assert.h>
-#include <math.h>
-#include <string.h>
-#include <sys/time.h>
-#include <time.h>
-#include <SDL/SDL.h>
-
-#include "evas_common.h"/* Also includes international specific stuff */
-#include "evas_engine.h"
-int _evas_engine_soft16_sdl_log_dom = -1;
-
-/* function tables - filled in later (func and parent func) */
-static Evas_Func func, pfunc;
-
-static Engine_Image_Entry       *_sdl16_image_alloc       (void);
-static void                      _sdl16_image_delete      (Engine_Image_Entry *eim);
-
-static int                       _sdl16_image_constructor (Engine_Image_Entry *ie, void* data);
-static void                      _sdl16_image_destructor  (Engine_Image_Entry *eim);
-
-static void                      _sdl16_image_dirty_region(Engine_Image_Entry *eim, unsigned int x, unsigned int y, unsigned int w, unsigned int h);
-
-static int                       _sdl16_image_dirty       (Engine_Image_Entry *dst, const Engine_Image_Entry *src);
-
-static int                       _sdl16_image_size_set    (Engine_Image_Entry *dst, const Engine_Image_Entry *src);
-
-static int                       _sdl16_image_update_data (Engine_Image_Entry* dst, void* engine_data);
-
-static void                      _sdl16_image_load        (Engine_Image_Entry *eim, const Image_Entry* im);
-static int                       _sdl16_image_mem_size_get(Engine_Image_Entry *eim);
-
-#ifdef DEBUG_SDL
-static void                      _sdl16_image_debug       (const char* context, Engine_Image_Entry* im);
-#endif
-
-static const Evas_Cache_Engine_Image_Func       _sdl16_cache_engine_image_cb = {
-  NULL /* key */,
-  _sdl16_image_alloc /* alloc */,
-  _sdl16_image_delete /* dealloc */,
-  _sdl16_image_constructor /* constructor */,
-  _sdl16_image_destructor /* destructor */,
-  _sdl16_image_dirty_region /* dirty_region */,
-  _sdl16_image_dirty /* dirty */,
-  _sdl16_image_size_set /* size_set */,
-  _sdl16_image_update_data /* update_data */,
-  _sdl16_image_load /* load */,
-  _sdl16_image_mem_size_get /* mem_size_get */,
-#ifdef DEBUG_SDL  /* debug */
-  _sdl16_image_debug
-#else
-  NULL
-#endif
-};
-
-#define _SDL_UPDATE_PIXELS(EIM)                                 \
-  ((Soft16_Image *) EIM->cache_entry.src)->pixels = EIM->surface->pixels;
-
-#define RMASK565 0xf800
-#define GMASK565 0x07e0
-#define BMASK565 0x001f
-#define AMASK565 0x0000
-
-/* engine api this module provides */
-static void *
-evas_engine_sdl16_info(Evas *e __UNUSED__)
-{
-   Evas_Engine_Info_SDL_16      *info;
-   info = calloc(1, sizeof(Evas_Engine_Info_SDL_16));
-   if (!info) return NULL;
-   info->magic.magic = rand();
-   return info;
-}
-
-static void
-evas_engine_sdl16_info_free(Evas *e __UNUSED__, void *info)
-{
-   Evas_Engine_Info_SDL_16 *in;
-   in = (Evas_Engine_Info_SDL_16 *)info;
-   free(in);
-}
-
-static void
-_tmp_out_alloc(Render_Engine *re)
-{
-   Tilebuf_Rect *r;
-   unsigned int w = 0, h = 0;
-
-   EINA_INLIST_FOREACH(re->rects, r)
-     {
-       if (r->w > (int)w) w = r->w;
-       if (r->h > (int)h) h = r->h;
-     }
-
-   if (re->tmp_out)
-     {
-       if ((re->tmp_out->cache_entry.w < w) || (re->tmp_out->cache_entry.h < h))
-         {
-             evas_cache_image_drop(&re->tmp_out->cache_entry);
-            re->tmp_out = NULL;
-         }
-     }
-
-   if (!re->tmp_out)
-     {
-       Soft16_Image *im;
-
-        im = (Soft16_Image *) evas_cache_image_empty(evas_common_soft16_image_cache_get());
-        im->cache_entry.flags.alpha = 0;
-        evas_cache_image_surface_alloc(&im->cache_entry, w, h);
-
-       re->tmp_out = im;
-     }
-}
-
-static void*
-_sdl16_output_setup(int w, int h, int rotation, int fullscreen, int noframe, int hwsurface)
-{
-   Render_Engine       *re;
-   SDL_Surface          *surface;
-
-   re = calloc(1, sizeof(Render_Engine));
-   if (!re)
-     return NULL;
-   /* if we haven't initialized - init (automatic abort if already done) */
-   evas_common_cpu_init();
-   evas_common_blend_init();
-   evas_common_image_init();
-   evas_common_convert_init();
-   evas_common_scale_init();
-   evas_common_rectangle_init();
-   evas_common_polygon_init();
-   evas_common_line_init();
-   evas_common_font_init();
-   evas_common_draw_init();
-   evas_common_tilebuf_init();
-   evas_common_soft16_image_init();
-
-   if (w <= 0) w = 640;
-   if (h <= 0) h = 480;
-
-   re->cache = evas_cache_engine_image_init(&_sdl16_cache_engine_image_cb, evas_common_soft16_image_cache_get());
-   if (!re->cache)
-     {
-        ERR("Evas_Cache_Engine_Image allocation failed!");
-        free(re);
-        return NULL;
-     }
-
-   re->tb = evas_common_tilebuf_new(w, h);
-   /* in preliminary tests 16x16 gave highest framerates */
-   evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
-   re->w = w;
-   re->h = h;
-   re->rot = rotation;
-   re->flags.hwsurface = hwsurface;
-   re->flags.fullscreen = fullscreen;
-   re->flags.noframe = noframe;
-   re->flags.end = 0;
-
-   re->update_rects_count = 0;
-   re->update_rects_limit = 0;
-   re->update_rects = NULL;
-
-   surface = SDL_SetVideoMode(w, h, 16,
-                              (hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE)
-                              | (fullscreen ? SDL_FULLSCREEN : 0)
-                              | (noframe ? SDL_NOFRAME : 0));
-   if (!surface)
-     {
-        ERR("SDL_SetVideoMode [ %i x %i x 16 ] failed", w, h);
-        evas_cache_engine_image_shutdown(re->cache);
-        free(re);
-        return NULL;
-     }
-
-   SDL_SetAlpha(surface, SDL_RLEACCEL, 0);
-   SDL_FillRect(surface, NULL, 0);
-
-   re->soft16_engine_image = (SDL_Engine_Image_Entry *) evas_cache_engine_image_engine(re->cache, surface);
-   if (!re->soft16_engine_image)
-     {
-        ERR("Soft16_Image allocation from SDL failed");
-        evas_cache_engine_image_shutdown(re->cache);
-        free(re);
-        return NULL;
-     }
-
-   return re;
-}
-
-
-static int
-evas_engine_sdl16_setup(Evas *e, void *in)
-{
-   Evas_Engine_Info_SDL_16      *info = (Evas_Engine_Info_SDL_16 *) in;
-
-   if (evas_output_method_get(e) != evas_render_method_lookup("software_16_sdl"))
-     return 0;
-
-   SDL_Init(SDL_INIT_NOPARACHUTE);
-
-   if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
-     {
-        ERR("SDL_Init failed with %s", SDL_GetError());
-        SDL_Quit();
-        return 0;
-     }
-
-   e->engine.data.output = _sdl16_output_setup(e->output.w, e->output.h,
-                                               info->info.rotation,
-                                               info->info.fullscreen,
-                                               info->info.noframe,
-                                               info->info.hwsurface);
-   if (!e->engine.data.output)
-     return 0;
-
-   e->engine.func = &func;
-   e->engine.data.context = e->engine.func->context_new(e->engine.data.output);
-
-   return 1;
-}
-
-static void
-evas_engine_sdl16_output_free(void *data)
-{
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-   if (re->tb) evas_common_tilebuf_free(re->tb);
-   if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
-   if (re->tmp_out) evas_cache_image_drop(&re->tmp_out->cache_entry);
-   if (re->soft16_engine_image)
-     evas_cache_engine_image_drop(&re->soft16_engine_image->cache_entry);
-   if (re->cache) evas_cache_engine_image_shutdown(re->cache);
-
-   if (re->update_rects)
-     free(re->update_rects);
-   free(re);
-
-   evas_common_font_shutdown();
-   evas_common_image_shutdown();
-   evas_common_soft16_image_shutdown();
-
-   SDL_QuitSubSystem(SDL_INIT_VIDEO);
-}
-
-static void
-evas_engine_sdl16_output_resize(void *data, int w, int h)
-{
-   Render_Engine        *re = data;
-   SDL_Surface          *surface;
-
-   if ((re->tb->outbuf_w == w) && (re->tb->outbuf_h == h)) return;
-
-   evas_cache_engine_image_drop(&re->soft16_engine_image->cache_entry);
-
-   evas_common_tilebuf_free(re->tb);
-   re->w = w;
-   re->h = h;
-   re->tb = evas_common_tilebuf_new(w, h);
-   if (re->tb)
-     evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
-
-   surface = SDL_SetVideoMode(w, h, 16,
-                              (re->flags.hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE)
-                              | (re->flags.fullscreen ? SDL_FULLSCREEN : 0)
-                              | (re->flags.noframe ? SDL_NOFRAME : 0));
-   if (!surface)
-     {
-        ERR("Unable to change the resolution to : %ix%i", w, h);
-        exit(-1);
-     }
-   re->soft16_engine_image = (SDL_Engine_Image_Entry *) evas_cache_engine_image_engine(re->cache, surface);
-   if (!re->soft16_engine_image)
-     {
-       ERR("RGBA_Image allocation from SDL failed");
-       exit(-1);
-     }
-
-   SDL_FillRect(surface, NULL, 0);
-
-   if (re->tmp_out)
-     {
-        evas_cache_image_drop(&re->tmp_out->cache_entry);
-       re->tmp_out = NULL;
-     }
-}
-
-static void
-evas_engine_sdl16_output_tile_size_set(void *data, int w, int h)
-{
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-   evas_common_tilebuf_set_tile_size(re->tb, w, h);
-}
-
-static void
-evas_engine_sdl16_output_redraws_rect_add(void *data, int x, int y, int w, int h)
-{
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-   evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
-}
-
-static void
-evas_engine_sdl16_output_redraws_rect_del(void *data, int x, int y, int w, int h)
-{
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-   evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
-}
-
-static void
-evas_engine_sdl16_output_redraws_clear(void *data)
-{
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-   evas_common_tilebuf_clear(re->tb);
-}
-
-static void *
-evas_engine_sdl16_output_redraws_next_update_get(void *data,
-                                                 int *x, int *y, int *w, int *h,
-                                                 int *cx, int *cy, int *cw, int *ch)
-{
-   Render_Engine        *re = data;
-   Tilebuf_Rect         *tb_rect;
-   SDL_Rect              rect;
-
-   if (re->flags.end)
-     {
-       re->flags.end = 0;
-       return NULL;
-     }
-   if (!re->rects)
-     {
-       re->rects = evas_common_tilebuf_get_render_rects(re->tb);
-       re->cur_rect = re->rects;
-       if (re->rot != 0) _tmp_out_alloc(re); /* grows if required */
-     }
-
-   if (!re->cur_rect)
-     {
-       if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
-       re->rects = NULL;
-       return NULL;
-     }
-
-   tb_rect = re->cur_rect;
-   *cx = *x = tb_rect->x;
-   *cy = *y = tb_rect->y;
-   *cw = *w = tb_rect->w;
-   *ch = *h = tb_rect->h;
-   re->cur_rect = (Tilebuf_Rect *)((EINA_INLIST_GET(re->cur_rect))->next);
-   if (!re->cur_rect)
-     {
-        evas_common_tilebuf_free_render_rects(re->rects);
-        re->rects = NULL;
-        re->flags.end = 1;
-     }
-
-   if (re->rot != 0)
-     {
-        *cx = 0;
-        *cy = 0;
-     }
-
-   rect.x = *x;
-   rect.y = *y;
-   rect.w = *w;
-   rect.h = *h;
-
-   /* Return the "fake" surface so it is passed to the drawing routines. */
-   return re->soft16_engine_image;
-}
-
-static void
-_blit_rot_90(Soft16_Image *dst, const Soft16_Image *src,
-            int out_x, int out_y, int w, int h)
-{
-   DATA16 *dp, *sp;
-   int x, y;
-
-   sp = src->pixels;
-   dp = dst->pixels + (out_x +
-                      (w + out_y - 1) * dst->stride);
-
-   for (y = 0; y < h; y++)
-     {
-       DATA16 *dp_itr, *sp_itr;
-
-       sp_itr = sp;
-       dp_itr = dp;
-
-       for (x = 0; x < w; x++)
-         {
-            *dp_itr = *sp_itr;
-
-            sp_itr++;
-            dp_itr -= dst->stride;
-         }
-       sp += src->stride;
-       dp++;
-     }
-}
-
-static void
-_blit_rot_180(Soft16_Image *dst, const Soft16_Image *src,
-             int out_x, int out_y, int w, int h)
-{
-   DATA16 *dp, *sp;
-   int x, y;
-
-   sp = src->pixels;
-   dp = dst->pixels + ((w + out_x - 1) +
-                      (h + out_y - 1) * dst->stride);
-
-   for (y = 0; y < h; y++)
-     {
-       DATA16 *dp_itr, *sp_itr;
-
-       sp_itr = sp;
-       dp_itr = dp;
-
-       for (x = 0; x < w; x++)
-         {
-            *dp_itr = *sp_itr;
-
-            sp_itr++;
-            dp_itr--;
-         }
-       sp += src->stride;
-       dp -= dst->stride;
-     }
-}
-
-static void
-_blit_rot_270(Soft16_Image *dst, const Soft16_Image *src,
-             int out_x, int out_y, int w, int h)
-{
-   DATA16 *dp, *sp;
-   int x, y;
-
-   sp = src->pixels;
-   dp = dst->pixels + ((h + out_x - 1) +
-                      out_y * dst->stride);
-
-   for (y = 0; y < h; y++)
-     {
-       DATA16 *dp_itr, *sp_itr;
-
-       sp_itr = sp;
-       dp_itr = dp;
-
-       for (x = 0; x < w; x++)
-         {
-            *dp_itr = *sp_itr;
-
-            sp_itr++;
-            dp_itr += dst->stride;
-         }
-       sp += src->stride;
-       dp--;
-     }
-}
-
-static void
-_tmp_out_process(Render_Engine *re, int out_x, int out_y, int w, int h)
-{
-   Soft16_Image *d, *s;
-
-   d = (Soft16_Image *) re->soft16_engine_image->cache_entry.src;
-   s = re->tmp_out;
-
-   if ((w < 1) || (h < 1) ||
-       (out_x >= (int)d->cache_entry.w) || (out_y >= (int)d->cache_entry.h))
-     return;
-
-   if (re->rot == 90)
-     _blit_rot_90(d, s, out_x, out_y, w, h);
-   else if (re->rot == 180)
-     _blit_rot_180(d, s, out_x, out_y, w, h);
-   else if (re->rot == 270)
-     _blit_rot_270(d, s, out_x, out_y, w, h);
-}
-
-static void
-evas_engine_sdl16_output_redraws_next_update_push(void *data, void *surface __UNUSED__,
-                                                  int x, int y, int w, int h)
-{
-   Render_Engine        *re = data;
-   SDL_Rect              rect;
-
-   if (re->update_rects_count + 1 > re->update_rects_limit)
-     {
-        re->update_rects_limit += 8;
-        re->update_rects = realloc(re->update_rects, sizeof (SDL_Rect) * re->update_rects_limit);
-     }
-
-   rect.x = x;
-   rect.y = y;
-   rect.w = w;
-   rect.h = h;
-
-   switch (re->rot)
-     {
-      case 0:
-         break;
-      case 90:
-         rect.x = y;
-         rect.y = re->w - w - x;
-         rect.w = h;
-         rect.h = w;
-         break;
-      case 180:
-         rect.x = re->w - w - x;
-         rect.y = re->h - h - y;
-         break;
-      case 270:
-         rect.x = re->h - h - y;
-         rect.y = x;
-         rect.w = h;
-         rect.h = w;
-         break;
-      default:
-         abort();
-     }
-
-   re->update_rects[re->update_rects_count] = rect;
-
-   if (re->rot != 0)
-     _tmp_out_process(re, rect.x, rect.y, w, h);
-
-   ++re->update_rects_count;
-
-   evas_common_cpu_end_opt();
-}
-
-static void
-evas_engine_sdl16_output_flush(void *data)
-{
-   Render_Engine        *re = data;
-
-   if (re->update_rects_count > 0)
-     SDL_UpdateRects(re->soft16_engine_image->surface, re->update_rects_count, re->update_rects);
-
-   re->update_rects_count = 0;
-}
-
-static void
-evas_engine_sdl16_output_idle_flush(void *data)
-{
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-   if (re->tmp_out)
-     {
-       evas_cache_image_drop(&re->tmp_out->cache_entry);
-       re->tmp_out = NULL;
-     }
-}
-
-static void*
-evas_engine_sdl16_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
-{
-   Render_Engine*      re = (Render_Engine*) data;;
-
-   *error = 0;
-   return evas_cache_engine_image_request(re->cache, file, key, lo, NULL, error);
-}
-
-static int
-evas_engine_sdl16_image_alpha_get(void *data __UNUSED__, void *image)
-{
-   SDL_Engine_Image_Entry       *eim = image;
-   Soft16_Image                 *im;
-
-   if (!eim) return 1;
-   im = (Soft16_Image *) eim->cache_entry.src;
-   switch (eim->cache_entry.src->space)
-     {
-     case EVAS_COLORSPACE_ARGB8888:
-        if (im->cache_entry.flags.alpha) return 1;
-     default:
-        break;
-     }
-   return 0;
-}
-
-static void
-evas_engine_sdl16_image_size_get(void *data __UNUSED__, void *image, int *w, int *h)
-{
-   SDL_Engine_Image_Entry       *eim;
-
-   eim = image;
-   if (w) *w = eim->cache_entry.src->w;
-   if (h) *h = eim->cache_entry.src->h;
-}
-
-static int
-evas_engine_sdl16_image_colorspace_get(void *data __UNUSED__, void *image __UNUSED__)
-{
-   SDL_Engine_Image_Entry       *eim = image;
-
-   if (!eim) return EVAS_COLORSPACE_RGB565_A5P;
-   return eim->cache_entry.src->space;
-}
-
-static void
-evas_engine_sdl16_image_colorspace_set(void *data __UNUSED__, void *image __UNUSED__, int cspace __UNUSED__)
-{
-   SDL_Engine_Image_Entry       *eim = image;
-
-   if (!eim) return;
-   if (eim->cache_entry.src->space == cspace) return;
-
-   evas_cache_engine_image_colorspace(&eim->cache_entry, cspace, NULL);
-}
-
-static void*
-evas_engine_sdl16_image_new_from_copied_data(void *data,
-                                             int w, int h,
-                                             DATA32* image_data,
-                                             int alpha, int cspace)
-{
-   Render_Engine       *re = data;
-
-   if (cspace != EVAS_COLORSPACE_RGB565_A5P)
-     {
-        WRN("Unsupported colorspace %d in %s() (%s:%d)",
-                cspace, __FUNCTION__, __FILE__, __LINE__);
-        return NULL;
-     }
-
-   WRN("s image_data: %p", image_data);
-
-   return evas_cache_engine_image_copied_data(re->cache,
-                                              w, h,
-                                              image_data,
-                                              alpha, cspace, NULL);
-}
-
-static void*
-evas_engine_sdl16_image_new_from_data(void *data, int w, int h, DATA32* image_data, int alpha, int cspace)
-{
-   Render_Engine       *re = data;
-
-   if (cspace != EVAS_COLORSPACE_RGB565_A5P)
-     {
-        WRN("Unsupported colorspace %d in %s() (%s:%d)",
-                cspace, __FUNCTION__, __FILE__, __LINE__);
-        return NULL;
-     }
-
-   return evas_cache_engine_image_data(re->cache,
-                                       w, h,
-                                       image_data,
-                                       alpha, cspace, NULL);
-}
-
-static void
-evas_engine_sdl16_image_free(void *data __UNUSED__, void *image)
-{
-   SDL_Engine_Image_Entry       *eim = image;
-
-   evas_cache_engine_image_drop(&eim->cache_entry);
-}
-
-static void*
-evas_engine_sdl16_image_size_set(void *data __UNUSED__, void *image, int w, int h)
-{
-   SDL_Engine_Image_Entry       *eim = image;
-
-   return evas_cache_engine_image_size_set(&eim->cache_entry, w, h);
-}
-
-static void*
-evas_engine_sdl16_image_dirty_region(void *data __UNUSED__,
-                                     void *image,
-                                     int x, int y, int w, int h)
-{
-   SDL_Engine_Image_Entry       *eim = image;
-
-   return evas_cache_engine_image_dirty(&eim->cache_entry, x, y, w, h);
-}
-
-static void*
-evas_engine_sdl16_image_data_get(void *data __UNUSED__, void *image,
-                                 int to_write, DATA32** image_data, int *err)
-{
-   SDL_Engine_Image_Entry       *eim = image;
-   Soft16_Image                 *im;
-   int                           error;
-
-   if (!eim)
-     {
-        *image_data = NULL;
-        if (err) *err = EVAS_LOAD_ERROR_GENERIC;
-        return NULL;
-     }
-   im = (Soft16_Image *) eim->cache_entry.src;
-
-   if (to_write)
-     eim = (SDL_Engine_Image_Entry *) evas_cache_engine_image_dirty(&eim->cache_entry,
-         0, 0, eim->cache_entry.src->w, eim->cache_entry.src->h);
-
-   error = evas_cache_image_load_data(&im->cache_entry);
-   /* FIXME: Handle colorspace conversion correctly. */
-   if (image_data) *image_data = (DATA32 *) im->pixels;
-
-   if (err) *err = error;
-   return eim;
-}
-
-static void*
-evas_engine_sdl16_image_data_put(void *data, void *image, DATA32* image_data)
-{
-   SDL_Engine_Image_Entry       *eim = image;
-   SDL_Engine_Image_Entry       *eim_new;
-   Render_Engine                *re = data;
-   Soft16_Image                 *im;
-
-   if (!eim) return NULL;
-   im = (Soft16_Image *) eim->cache_entry.src;
-
-   /* FIXME: Handle colorspace conversion correctly. */
-   if ((DATA16 *) image_data == im->pixels) return eim;
-
-   eim_new = (SDL_Engine_Image_Entry *) evas_cache_engine_image_data(re->cache,
-                                                                     eim->cache_entry.w, eim->cache_entry.h,
-                                                                     image_data,
-                                                                     func.image_alpha_get(data, eim),
-                                                                     func.image_colorspace_get(data, eim),
-                                                                     NULL);
-   evas_cache_engine_image_drop(&eim->cache_entry);
-
-   return eim_new;
-}
-
-static void
-evas_engine_sdl16_image_data_preload_request(void *data __UNUSED__, void *image, const void *target)
-{
-   SDL_Engine_Image_Entry       *eim = image;
-   Soft16_Image                 *im;
-
-   if (!eim) return ;
-   im = (Soft16_Image *) eim->cache_entry.src;
-   if (!im) return ;
-   evas_cache_image_preload_data(&im->cache_entry, target);
-}
-
-static void
-evas_engine_sdl16_image_data_preload_cancel(void *data __UNUSED__, void *image, const void *target)
-{
-   SDL_Engine_Image_Entry       *eim = image;
-   Soft16_Image                 *im;
-
-   if (!eim) return ;
-   im = (Soft16_Image *) eim->cache_entry.src;
-   if (!im) return ;
-   evas_cache_image_preload_cancel(&im->cache_entry, target);
-}
-
-static void*
-evas_engine_sdl16_image_alpha_set(void *data __UNUSED__, void *image, int has_alpha)
-{
-   SDL_Engine_Image_Entry       *eim = image;
-   Soft16_Image                 *im;
-
-   if (!eim) return NULL;
-
-   im = (Soft16_Image *) eim->cache_entry.src;
-
-   if (im->cache_entry.flags.alpha == has_alpha) return eim;
-
-   //eim = (SDL_Engine_Image_Entry *) evas_cache_engine_image_alone(&eim->cache_entry,  NULL);
-   //im = (Soft16_Image *) eim->cache_entry.src;
-
-   im->cache_entry.flags.alpha = has_alpha;
-   eim = (SDL_Engine_Image_Entry *) evas_cache_engine_image_dirty(&eim->cache_entry, 0, 0, eim->cache_entry.w, eim->cache_entry.h);
-
-   return eim;
-}
-
-static void*
-evas_engine_sdl16_image_border_set(void *data __UNUSED__, void *image, int l __UNUSED__, int r __UNUSED__, int t __UNUSED__, int b __UNUSED__)
-{
-   return image;
-}
-
-static void
-evas_engine_sdl16_image_border_get(void *data __UNUSED__, void *image __UNUSED__, int *l __UNUSED__, int *r __UNUSED__, int *t __UNUSED__, int *b __UNUSED__)
-{
-   /* FIXME: need to know what evas expect from this call */
-}
-
-static void
-evas_engine_sdl16_image_draw(void *data __UNUSED__, void *context, void *surface, void *image,
-                             int src_region_x, int src_region_y, int src_region_w, int src_region_h,
-                             int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h,
-                             int smooth)
-{
-   SDL_Engine_Image_Entry       *eim = image;
-   SDL_Engine_Image_Entry       *dst = surface;
-   int                           mustlock_im = 0;
-   int                           mustlock_dst = 0;
-
-   evas_cache_engine_image_load_data(&eim->cache_entry);
-
-   /* Fallback to software method */
-   if (SDL_MUSTLOCK(dst->surface))
-     {
-        mustlock_dst = 1;
-       SDL_LockSurface(dst->surface);
-       _SDL_UPDATE_PIXELS(dst);
-     }
-
-   if (eim->surface && SDL_MUSTLOCK(eim->surface))
-     {
-        mustlock_im = 1;
-       SDL_LockSurface(eim->surface);
-       _SDL_UPDATE_PIXELS(eim);
-     }
-
-   evas_common_soft16_image_draw((Soft16_Image *) eim->cache_entry.src,
-                     (Soft16_Image *) dst->cache_entry.src,
-                     context,
-                     src_region_x, src_region_y, src_region_w, src_region_h,
-                     dst_region_x, dst_region_y, dst_region_w, dst_region_h,
-                     smooth);
-
-   evas_common_cpu_end_opt ();
-   if (mustlock_im)
-     SDL_UnlockSurface(eim->surface);
-
-   if (mustlock_dst)
-     SDL_UnlockSurface(dst->surface);
-}
-
-static void
-evas_engine_sdl16_image_map_draw(void *data __UNUSED__, void *context __UNUSED__, void *surface __UNUSED__, void *image __UNUSED__, RGBA_Map *m __UNUSED__, int smooth __UNUSED__, int level __UNUSED__)
-{
-}
-
-static void
-evas_engine_sdl16_image_scale_hint_set(void *data __UNUSED__, void *image __UNUSED__, int hint __UNUSED__)
-{
-}
-
-static int
-evas_engine_sdl16_image_scale_hint_get(void *data __UNUSED__, void *image __UNUSED__)
-{
-   return EVAS_IMAGE_SCALE_HINT_NONE;
-}
-
-
-static void
-evas_engine_sdl16_image_cache_flush(void *data)
-{
-   Render_Engine        *re = (Render_Engine*) data;
-   int                   size;
-
-   size = evas_cache_engine_image_get(re->cache);
-   evas_cache_engine_image_set(re->cache, 0);
-   evas_cache_engine_image_set(re->cache, size);
-}
-
-static void
-evas_engine_sdl16_image_cache_set(void *data, int bytes)
-{
-   Render_Engine        *re = (Render_Engine*) data;
-
-   evas_cache_engine_image_set(re->cache, bytes);
-}
-
-static int
-evas_engine_sdl16_image_cache_get(void *data)
-{
-   Render_Engine        *re = (Render_Engine*) data;
-
-   return evas_cache_engine_image_get(re->cache);
-}
-
-static char*
-evas_engine_sdl16_image_comment_get(void *data __UNUSED__, void *image __UNUSED__, char *key __UNUSED__)
-{
-   return NULL;
-}
-
-static char*
-evas_engine_sdl16_image_format_get(void *data __UNUSED__, void *image __UNUSED__)
-{
-   /* FIXME: need to know what evas expect from this call */
-   return NULL;
-}
-
-static void
-evas_engine_sdl16_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, Evas_Text_Props *intl_props)
-{
-   static RGBA_Image            *im = NULL;
-   SDL_Engine_Image_Entry       *eim = surface;
-   Soft16_Image                 *dst = (Soft16_Image *) eim->cache_entry.src;
-   int                           mustlock_im = 0;
-
-   if (eim->surface && SDL_MUSTLOCK(eim->surface))
-     {
-        mustlock_im = 1;
-       SDL_LockSurface(eim->surface);
-       _SDL_UPDATE_PIXELS(eim);
-     }
-   evas_common_draw_context_font_ext_set(context,
-                                         dst,
-                                         evas_common_soft16_font_glyph_new,
-                                         evas_common_soft16_font_glyph_free,
-                                         evas_common_soft16_font_glyph_draw);
-   evas_common_font_draw_prepare(intl_props);
-   evas_common_font_draw((RGBA_Image *) eim->cache_entry.src, context, x, y, intl_props);
-   evas_common_draw_context_font_ext_set(context,
-                                         NULL,
-                                         NULL,
-                                         NULL,
-                                         NULL);
-
-   if (mustlock_im)
-     SDL_UnlockSurface(eim->surface);
-}
-
-static void
-evas_engine_sdl16_line_draw(void *data __UNUSED__, void *context, void *surface, int x1, int y1, int x2, int y2)
-{
-   SDL_Engine_Image_Entry       *eim = surface;
-   int                           mustlock_im = 0;
-
-   if (eim->surface && SDL_MUSTLOCK(eim->surface))
-     {
-        mustlock_im = 1;
-       SDL_LockSurface(eim->surface);
-       _SDL_UPDATE_PIXELS(eim);
-     }
-
-   evas_common_soft16_line_draw((Soft16_Image *) eim->cache_entry.src,
-                    context,
-                    x1, y1, x2, y2);
-   evas_common_cpu_end_opt();
-
-   if (mustlock_im)
-     SDL_UnlockSurface(eim->surface);
-}
-
-static void
-evas_engine_sdl16_rectangle_draw(void *data __UNUSED__, void *context, void *surface, int x, int y, int w, int h)
-{
-   SDL_Engine_Image_Entry       *eim = surface;
-#if ENGINE_SDL_PRIMITIVE
-   RGBA_Draw_Context            *dc = context;
-#endif
-   Soft16_Image                 *im;
-   int                           mustlock_im = 0;
-
-#if ENGINE_SDL_PRIMITIVE
-   if (A_VAL(&dc->col.col) != 0x00)
-     {
-        if (A_VAL(&dc->col.col) != 0xFF)
-          {
-#endif
-             if (eim->surface && SDL_MUSTLOCK(eim->surface))
-               {
-                  mustlock_im = 1;
-                  SDL_LockSurface(eim->surface);
-                  _SDL_UPDATE_PIXELS(eim);
-               }
-
-             im = (Soft16_Image *) eim->cache_entry.src;
-
-             evas_common_soft16_rectangle_draw(im, context, x, y, w, h);
-             evas_common_cpu_end_opt();
-
-             if (mustlock_im)
-               SDL_UnlockSurface(eim->surface);
-#if ENGINE_SDL_PRIMITIVE
-          }
-        else
-          {
-             SDL_Rect        dstrect;
-
-             if (dc->clip.use)
-               {
-                  SDL_Rect   cliprect;
-
-                  cliprect.x = dc->clip.x;
-                  cliprect.y = dc->clip.y;
-                  cliprect.w = dc->clip.w;
-                  cliprect.h = dc->clip.h;
-
-                  SDL_SetClipRect(eim->surface, &cliprect);
-               }
-
-             dstrect.x = x;
-             dstrect.y = y;
-             dstrect.w = w;
-             dstrect.h = h;
-
-             SDL_FillRect(eim->surface, &dstrect, SDL_MapRGBA(eim->surface->format, R_VAL(&dc->col.col), G_VAL(&dc->col.col), B_VAL(&dc->col.col), 0xFF));
-
-             if (dc->clip.use)
-               SDL_SetClipRect(eim->surface, NULL);
-          }
-     }
-#endif
-}
-
-static void
-evas_engine_sdl16_polygon_draw(void *data __UNUSED__, void *context, void *surface, void *polygon, int x, int y)
-{
-   SDL_Engine_Image_Entry       *eim = surface;
-   int                           mustlock_im = 0;
-
-   if (eim->surface && SDL_MUSTLOCK(eim->surface))
-     {
-        mustlock_im = 1;
-       SDL_LockSurface(eim->surface);
-       _SDL_UPDATE_PIXELS(eim);
-     }
-
-   evas_common_soft16_polygon_draw((Soft16_Image *) eim->cache_entry.src, context, polygon, x, y);
-   evas_common_cpu_end_opt();
-
-   if (mustlock_im)
-     SDL_UnlockSurface(eim->surface);
-}
-
-static void
-evas_engine_sdl16_image_stride_get(void *data __UNUSED__, void *image, int *stride)
-{
-   SDL_Engine_Image_Entry       *eim = image;
-
-   if (stride) *stride = 0;
-   if (!image) return;
-   if (stride) *stride = ((Soft16_Image*) eim->cache_entry.src)->stride;
-}
-
-static Eina_Bool
-evas_engine_sdl16_canvas_alpha_get(void *data __UNUSED__, void *context __UNUSED__)
-{
-   return EINA_FALSE;
-}
-
-/* module advertising code */
-static int
-module_open(Evas_Module *em)
-{
-   if (!em) return 0;
-   /* get whatever engine module we inherit from */
-   if (!_evas_module_engine_inherit(&pfunc, "software_16")) return 0;
-   _evas_engine_soft16_sdl_log_dom = eina_log_domain_register
-     ("evas-software_16_sdl", EVAS_DEFAULT_LOG_COLOR);
-   if (_evas_engine_soft16_sdl_log_dom < 0)
-     {
-        EINA_LOG_ERR("Can not create a module log domain.");
-        return 0;
-     }
-
-   /* store it for later use */
-   func = pfunc;
-   /* now to override methods */
-#define ORD(f) EVAS_API_OVERRIDE(f, &func, evas_engine_sdl16_)
-   ORD(info);
-   ORD(info_free);
-   ORD(setup);
-   ORD(canvas_alpha_get);
-   ORD(output_free);
-   ORD(output_resize);
-   ORD(output_tile_size_set);
-   ORD(output_redraws_rect_add);
-   ORD(output_redraws_rect_del);
-   ORD(output_redraws_clear);
-   ORD(output_redraws_next_update_get);
-   ORD(output_redraws_next_update_push);
-   ORD(output_flush);
-   ORD(output_idle_flush);
-   ORD(image_load);
-   ORD(image_alpha_get);
-   ORD(image_size_get);
-   ORD(image_colorspace_get);
-   ORD(image_colorspace_set);
-   ORD(image_new_from_copied_data);
-   ORD(image_new_from_data);
-   ORD(image_free);
-   ORD(image_size_set);
-   ORD(image_dirty_region);
-   ORD(image_data_get);
-   ORD(image_data_put);
-   ORD(image_data_preload_request);
-   ORD(image_data_preload_cancel);
-   ORD(image_alpha_set);
-   ORD(image_border_set);
-   ORD(image_border_get);
-   ORD(image_draw);
-   ORD(image_map_draw);
-   ORD(image_cache_flush);
-   ORD(image_cache_set);
-   ORD(image_cache_get);
-   ORD(image_comment_get);
-   ORD(image_format_get);
-   ORD(image_stride_get);
-   ORD(font_draw);
-   ORD(line_draw);
-   ORD(rectangle_draw);
-   ORD(polygon_draw);
-   
-   ORD(image_scale_hint_set);
-   ORD(image_scale_hint_get);
-   
-   /* now advertise out own api */
-   em->functions = (void *)(&func);
-   return 1;
-}
-
-static void
-module_close(Evas_Module *em __UNUSED__)
-{
-  eina_log_domain_unregister(_evas_engine_soft16_sdl_log_dom);
-}
-
-static Evas_Module_Api evas_modapi =
-{
-   EVAS_MODULE_API_VERSION,
-   "software_16_sdl",
-   "none",
-   {
-     module_open,
-     module_close
-   }
-};
-
-EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, software_16_sdl);
-
-#ifndef EVAS_STATIC_BUILD_SOFTWARE_SDL
-EVAS_EINA_MODULE_DEFINE(engine, software_16_sdl);
-#endif
-
-static Engine_Image_Entry*
-_sdl16_image_alloc(void)
-{
-   SDL_Engine_Image_Entry       *new;
-
-   new = calloc(1, sizeof (SDL_Engine_Image_Entry));
-
-   return (Engine_Image_Entry *) new;
-}
-
-static void
-_sdl16_image_delete(Engine_Image_Entry *eim)
-{
-   free(eim);
-}
-
-static int
-_sdl16_image_constructor(Engine_Image_Entry *ie, void* data __UNUSED__)
-{
-   SDL_Surface                  *sdl = NULL;
-   SDL_Engine_Image_Entry       *eim = (SDL_Engine_Image_Entry *) ie;
-   Soft16_Image                 *im;
-
-   im = (Soft16_Image *) ie->src;
-
-   if (im)
-     {
-        evas_cache_image_load_data(&im->cache_entry);
-
-        if (im->pixels)
-          {
-            /* FIXME: Take care of CSPACE */
-            sdl = SDL_CreateRGBSurfaceFrom(im->pixels,
-                                           ie->w, ie->h,
-                                           16, ie->w * 2,
-                                           RMASK565, GMASK565, BMASK565, AMASK565);
-            eim->surface = sdl;
-            eim->flags.engine_surface = 0;
-          }
-     }
-
-   return EVAS_LOAD_ERROR_NONE;
-}
-
-static void
-_sdl16_image_destructor(Engine_Image_Entry *eim)
-{
-   SDL_Engine_Image_Entry       *seie = (SDL_Engine_Image_Entry *) eim;
-
-   if (seie->surface && !seie->flags.engine_surface)
-     SDL_FreeSurface(seie->surface);
-   seie->surface = NULL;
-}
-
-static void
-_sdl16_image_dirty_region(Engine_Image_Entry *eim, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
-{
-   SDL_Engine_Image_Entry       *dst;
-   RGBA_Image *im;
-
-   dst = (SDL_Engine_Image_Entry *) eim;
-
-   SDL_UpdateRect(dst->surface, x, y, w, h);
-
-   im = (RGBA_Image *)eim->src;
-   im->flags |= RGBA_IMAGE_IS_DIRTY;
-}
-
-static int
-_sdl16_image_dirty(Engine_Image_Entry *dst, const Engine_Image_Entry *src __UNUSED__)
-{
-   SDL_Engine_Image_Entry       *eim = (SDL_Engine_Image_Entry *) dst;
-   SDL_Surface                  *sdl = NULL;
-   Soft16_Image                 *im;
-
-   im = (Soft16_Image *) dst->src;
-
-   /* FIXME: Take care of CSPACE */
-   sdl = SDL_CreateRGBSurfaceFrom(im->pixels,
-                                  dst->w, dst->h,
-                                  16, dst->w * 2,
-                                  RMASK565, GMASK565, BMASK565, AMASK565);
-   eim->surface = sdl;
-   eim->flags.engine_surface = 0;
-
-   return 0;
-}
-
-static int
-_sdl16_image_size_set(Engine_Image_Entry *dst, const Engine_Image_Entry *src __UNUSED__)
-{
-   SDL_Engine_Image_Entry       *eim = (SDL_Engine_Image_Entry *) dst;
-   SDL_Surface                  *sdl;
-   Soft16_Image                 *im;
-
-   im = (Soft16_Image *) dst->src;
-
-   /* FIXME: handle im == NULL */
-   sdl = SDL_CreateRGBSurfaceFrom(im->pixels,
-                                  dst->w, dst->h,
-                                  16, dst->w * 2,
-                                  RMASK565, GMASK565, BMASK565, AMASK565);
-
-   eim->surface = sdl;
-
-   return 0;
-}
-
-static int
-_sdl16_image_update_data(Engine_Image_Entry* dst, void* engine_data)
-{
-   SDL_Engine_Image_Entry       *eim = (SDL_Engine_Image_Entry *) dst;
-   SDL_Surface                  *sdl = NULL;
-   Soft16_Image                 *im;
-
-   im = (Soft16_Image *) dst->src;
-
-   if (engine_data)
-     {
-        sdl = engine_data;
-
-        if (im)
-          {
-             im->pixels = sdl->pixels;
-             im->stride = sdl->pitch / 2;
-             im->flags.free_pixels = 0;
-/*              im->alpha = calloc(1, sizeof (DATA8) * _calc_stride(sdl->w) * sdl->h); */
-/*              im->flags.free_alpha = 0; */
-/*              im->flags.have_alpha = 1; */
-             im->alpha = NULL;
-             im->flags.free_alpha = 0;
-             im->cache_entry.flags.alpha = 0;
-
-             dst->src->w = sdl->w;
-             dst->src->h = sdl->h;
-          }
-        dst->w = sdl->w;
-        dst->h = sdl->h;
-     }
-   else
-     {
-        SDL_FreeSurface(eim->surface);
-        /* FIXME: Take care of CSPACE */
-        sdl = SDL_CreateRGBSurfaceFrom(im->pixels,
-                                       dst->w, dst->h,
-                                       16, dst->w * 2,
-                                       RMASK565, GMASK565, BMASK565, AMASK565);
-     }
-
-   eim->surface = sdl;
-
-   return 0;
-}
-
-static void
-_sdl16_image_load(Engine_Image_Entry *eim, const Image_Entry* ie_im)
-{
-   SDL_Engine_Image_Entry       *load = (SDL_Engine_Image_Entry *) eim;
-   SDL_Surface                  *sdl;
-
-   if (!load->surface)
-     {
-        Soft16_Image            *im;
-
-        im = (Soft16_Image *) ie_im;
-
-        sdl = SDL_CreateRGBSurfaceFrom(im->pixels,
-                                       eim->w, eim->h,
-                                       16, eim->w * 2,
-                                       RMASK565, GMASK565, BMASK565, AMASK565);
-        load->surface = sdl;
-     }
-}
-
-static int
-_sdl16_image_mem_size_get(Engine_Image_Entry *eim)
-{
-   SDL_Engine_Image_Entry       *seie = (SDL_Engine_Image_Entry *) eim;
-   int                           size = 0;
-
-   /* FIXME: Count surface size. */
-   if (seie->surface)
-     size = sizeof (SDL_Surface) + sizeof (SDL_PixelFormat);
-
-   return size;
-}
-
-#ifdef DEBUG_SDL
-static void
-_sdl16_image_debug(const char* context, Engine_Image_Entry* im)
-{
-}
-#endif
diff --git a/src/modules/engines/software_16_sdl/evas_engine.h b/src/modules/engines/software_16_sdl/evas_engine.h
deleted file mode 100644 (file)
index a1b0ee0..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-#ifndef EVAS_ENGINE_SDL_16_H
-#define EVAS_ENGINE_SDL_16_H
-
-#include "evas_common.h"
-#include "evas_private.h"
-#include "evas_common_soft16.h"
-#include "Evas_Engine_SDL_16.h"
-extern int _evas_engine_soft16_sdl_log_dom ;
-#ifdef ERR
-# undef ERR
-#endif
-#define ERR(...) EINA_LOG_DOM_ERR(_evas_engine_soft16_sdl_log_dom, __VA_ARGS__)
-
-#ifdef DBG
-# undef DBG
-#endif
-#define DBG(...) EINA_LOG_DOM_DBG(_evas_engine_soft16_sdl_log_dom, __VA_ARGS__)
-
-#ifdef INF
-# undef INF
-#endif
-#define INF(...) EINA_LOG_DOM_INFO(_evas_engine_soft16_sdl_log_dom, __VA_ARGS__)
-
-#ifdef WRN
-# undef WRN
-#endif
-#define WRN(...) EINA_LOG_DOM_WARN(_evas_engine_soft16_sdl_log_dom, __VA_ARGS__)
-
-#ifdef CRIT
-# undef CRIT
-#endif
-#define CRIT(...) EINA_LOG_DOM_CRIT(_evas_engine_soft16_sdl_log_dom, __VA_ARGS__)
-
-typedef struct _SDL_Engine_Image_Entry SDL_Engine_Image_Entry;
-struct _SDL_Engine_Image_Entry
-{
-  Engine_Image_Entry     cache_entry;
-
-  SDL_Surface           *surface;
-
-  struct
-  {
-    unsigned int         engine_surface : 1;
-  } flags;
-};
-
-
-typedef struct _Render_Engine Render_Engine;
-struct _Render_Engine
-{
-  SDL_Engine_Image_Entry        *soft16_engine_image;
-
-  Evas_Cache_Engine_Image       *cache;
-
-  Soft16_Image                  *tmp_out;
-
-  int                            w;
-  int                            h;
-  int                            rot;
-
-  Tilebuf                       *tb;
-  Tilebuf_Rect                  *rects;
-  Tilebuf_Rect                  *cur_rect;
-
-  SDL_Rect                      *update_rects;
-  int                            update_rects_count;
-  int                            update_rects_limit;
-
-  struct
-  {
-    unsigned int                 fullscreen : 1;
-    unsigned int                 noframe : 1;
-    unsigned int                 alpha : 1;
-    unsigned int                 hwsurface : 1;
-    unsigned int                 end : 1;
-  } flags;
-};
-
-#endif
diff --git a/src/modules/engines/software_16_wince/Evas_Engine_Software_16_WinCE.h b/src/modules/engines/software_16_wince/Evas_Engine_Software_16_WinCE.h
deleted file mode 100644 (file)
index e94b7c2..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef __EVAS_ENGINE_SOFTWARE_16_WINCE_H__
-#define __EVAS_ENGINE_SOFTWARE_16_WINCE_H__
-
-
-#include <windows.h>
-
-
-typedef struct _Evas_Engine_Info_Software_16_WinCE Evas_Engine_Info_Software_16_WinCE;
-
-struct _Evas_Engine_Info_Software_16_WinCE
-{
-   /* PRIVATE - don't mess with this baby or evas will poke its tongue out */
-   /* at you and make nasty noises */
-   Evas_Engine_Info magic;
-
-   struct {
-      HWND         window;
-      int          width;
-      int          height;
-      int          backend; /* 0: auto, 1: raw, 2: gapi, 3: ddraw, 4: gdi */
-      int          rotation;
-      unsigned int fullscreen : 1;
-   } info;
-   /* engine specific function calls to query stuff about messages */
-   struct {
-      int   (*suspend) (int backend);
-      int   (*resume)  (int backend);
-   } func;
-
-   /* non-blocking or blocking mode */
-   Evas_Engine_Render_Mode render_mode;
-};
-
-
-#endif /* __EVAS_ENGINE_SOFTWARE_16_WINCE_H__ */
diff --git a/src/modules/engines/software_16_wince/Makefile.am b/src/modules/engines/software_16_wince/Makefile.am
deleted file mode 100644 (file)
index b8a3076..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-
-MAINTAINERCLEANFILES = Makefile.in
-
-AM_CPPFLAGS = \
--I. \
--I$(top_srcdir)/src/lib \
--I$(top_srcdir)/src/lib/include \
--I$(top_srcdir)/src/modules/engines \
--I$(top_srcdir)/src/modules/engines/software_16 \
-@EINA_CFLAGS@ \
-@FREETYPE_CFLAGS@ \
-@PIXMAN_CFLAGS@ \
-@FRIBIDI_CFLAGS@ \
-@evas_engine_software_16_wince_cflags@
-
-if BUILD_ENGINE_SOFTWARE_16_WINCE
-
-SOFTWARE_16_WINCE_SOURCE = \
-evas_engine.c \
-evas_wince_ddraw_buffer.cpp \
-evas_wince_fb_buffer.c \
-evas_wince_gapi_buffer.c \
-evas_wince_gdi_buffer.c
-
-SOFTWARE_16_WINCE_LIBADD = @evas_engine_software_16_wince_libs@
-
-
-includes_HEADERS = Evas_Engine_Software_16_WinCE.h
-includesdir = $(includedir)/evas-@VMAJ@
-
-if !EVAS_STATIC_BUILD_SOFTWARE_16_WINCE
-
-pkgdir = $(libdir)/evas/modules/engines/software_16_wince/$(MODULE_ARCH)
-pkg_LTLIBRARIES        = module.la
-
-module_la_SOURCES = $(SOFTWARE_16_WINCE_SOURCE)
-module_la_CXXFLAGS = -fno-rtti -fno-exceptions
-module_la_LIBADD = @EINA_LIBS@ $(top_builddir)/src/lib/libevas.la $(SOFTWARE_16_WINCE_LIBADD)
-module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
-module_la_LIBTOOLFLAGS = --tag=disable-static
-
-else
-
-noinst_LTLIBRARIES = libevas_engine_software_16_wince.la
-
-libevas_engine_software_16_wince_la_SOURCES = $(SOFTWARE_16_WINCE_SOURCE)
-libevas_engine_software_16_wince_la_LIBADD = $(SOFTWARE_16_WINCE_LIBADD)
-
-endif
-endif
-
-EXTRA_DIST = evas_engine.h
diff --git a/src/modules/engines/software_16_wince/evas_engine.c b/src/modules/engines/software_16_wince/evas_engine.c
deleted file mode 100644 (file)
index 74d56e6..0000000
+++ /dev/null
@@ -1,770 +0,0 @@
-#include "evas_common.h"
-#include "evas_private.h"
-#include "evas_engine.h"
-#include "Evas_Engine_Software_16_WinCE.h"
-#include "evas_common_soft16.h"
-
-int _evas_engine_soft16_wince_log_dom = -1;
-
-typedef enum
-{
-  EVAS_ENGINE_WINCE_FB,
-  EVAS_ENGINE_WINCE_GAPI,
-  EVAS_ENGINE_WINCE_DDRAW,
-  EVAS_ENGINE_WINCE_GDI
-} Evas_Engine_WinCE_Backend;
-
-
-/* function tables - filled in later (func and parent func) */
-static Evas_Func func, pfunc;
-
-/* engine struct data */
-typedef struct _Render_Engine Render_Engine;
-
-struct _Render_Engine
-{
-   Evas_Engine_WinCE_Backend backend; /* 1: raw, 2: gapi, 3: ddraw, 4: GDI */
-   void               *backend_priv;
-   void              (*backend_shutdown)(void *priv);
-   FB_Output_Buffer *(*backend_output_buffer_new)(void *priv,
-                                                  int width,
-                                                  int height);
-   void              (*backend_output_buffer_free)(FB_Output_Buffer *fbob);
-   void              (*backend_output_buffer_paste)(FB_Output_Buffer *fbob);
-   void              (*backend_surface_resize)(FB_Output_Buffer *fbob);
-
-   int               width;
-   int               height;
-   int               rotation;
-   Tilebuf          *tb;
-   Tilebuf_Rect     *rects;
-   Tilebuf_Rect     *cur_rect;
-   FB_Output_Buffer *fbob;
-   Soft16_Image     *tmp_out; /* used by indirect render, like rotation */
-   HRGN              clip_rects;
-   unsigned char     end : 1;
-};
-
-/* prototypes we will use here */
-
-static void *eng_info(Evas *e);
-static void eng_info_free(Evas *e, void *info);
-static int eng_setup(Evas *e, void *info);
-static void eng_output_free(void *data);
-static void eng_output_resize(void *data, int w, int h);
-static void eng_output_tile_size_set(void *data, int w, int h);
-static void eng_output_redraws_rect_add(void *data, int x, int y, int w, int h);
-static void eng_output_redraws_rect_del(void *data, int x, int y, int w, int h);
-static void eng_output_redraws_clear(void *data);
-static void *eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch);
-static void eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h);
-static void eng_output_flush(void *data);
-static void eng_output_idle_flush(void *data);
-
-static int
-_suspend(int backend)
-{
-   switch (backend)
-     {
-      case 2: /* gapi */
-         return evas_software_wince_gapi_suspend();
-      default: /* other engines do not need it */
-         return 0;
-     }
-}
-
-static int
-_resume(int backend)
-{
-   switch (backend)
-     {
-      case 2: /* gapi */
-         return evas_software_wince_gapi_resume();
-      default: /* other engines do not need it */
-         return 0;
-     }
-}
-
-/* engine api this module provides */
-static void *
-eng_info(Evas *e)
-{
-   Evas_Engine_Info_Software_16_WinCE *info;
-   info = calloc(1, sizeof(Evas_Engine_Info_Software_16_WinCE));
-   if (!info) return NULL;
-   info->magic.magic = rand();
-   info->func.suspend = _suspend;
-   info->func.resume = _resume;
-   info->render_mode = EVAS_RENDER_MODE_BLOCKING;
-   return info;
-   e = NULL;
-}
-
-static void
-eng_info_free(Evas *e, void *info)
-{
-   Evas_Engine_Info_Software_16_WinCE *in;
-   in = (Evas_Engine_Info_Software_16_WinCE *)info;
-   free(in);
-}
-
-static void
-_tmp_out_alloc(Render_Engine *re)
-{
-   Tilebuf_Rect *r;
-   int w = 0, h = 0;
-
-   EINA_INLIST_FOREACH(re->rects, r)
-     {
-       if (r->w > w) w = r->w;
-       if (r->h > h) h = r->h;
-     }
-
-   if (re->tmp_out)
-     {
-       if ((re->tmp_out->cache_entry.w < w) || (re->tmp_out->cache_entry.h < h))
-         {
-             evas_cache_image_drop(&re->tmp_out->cache_entry);
-            re->tmp_out = NULL;
-         }
-     }
-
-   if (!re->tmp_out)
-     {
-       Soft16_Image *im;
-
-        im = (Soft16_Image *) evas_cache_image_empty(evas_common_soft16_image_cache_get());
-        im->cache_entry.flags.alpha = 0;
-        evas_cache_image_surface_alloc(&im->cache_entry, w, h);
-
-       re->tmp_out = im;
-     }
-}
-
-
-static int
-eng_setup(Evas *e, void *in)
-{
-   Render_Engine                      *re;
-   Evas_Engine_Info_Software_16_WinCE *info;
-
-   info = (Evas_Engine_Info_Software_16_WinCE *)in;
-   if (!e->engine.data.output)
-     {
-       /* do common routine init - we wil at least use it for core
-        * image loading and font loading/glyph rendering & placement */
-       evas_common_cpu_init();
-
-       evas_common_blend_init();
-       evas_common_image_init();
-       evas_common_convert_init();
-       evas_common_scale_init();
-       evas_common_rectangle_init();
-       evas_common_polygon_init();
-       evas_common_line_init();
-       evas_common_font_init();
-       evas_common_draw_init();
-       evas_common_tilebuf_init();
-       evas_common_soft16_image_init();
-
-       /* render engine specific data */
-       re = calloc(1, sizeof(Render_Engine));
-        if (!re)
-          return 0;
-       e->engine.data.output = re;
-
-        switch(info->info.backend)
-          {
-           case 1: /* FB */
-              re->backend = EVAS_ENGINE_WINCE_FB;
-              re->backend_priv = evas_software_wince_fb_init(info->info.window, info->info.width, info->info.height);
-              if (!re->backend_priv)
-                {
-                   free(re);
-                   return 0;
-                }
-              re->backend_shutdown = evas_software_wince_fb_shutdown;
-              re->backend_output_buffer_new = evas_software_wince_fb_output_buffer_new;
-              re->backend_output_buffer_free = evas_software_wince_fb_output_buffer_free;
-              re->backend_output_buffer_paste = evas_software_wince_fb_output_buffer_paste;
-              re->backend_surface_resize = evas_software_wince_fb_surface_resize;
-              break;
-           case 2: /* GAPI */
-              re->backend = EVAS_ENGINE_WINCE_GAPI;
-              re->backend_priv = evas_software_wince_gapi_init(info->info.window, info->info.width, info->info.height);
-              if (!re->backend_priv)
-                {
-                   free(re);
-                   return 0;
-                }
-              re->backend_shutdown = evas_software_wince_gapi_shutdown;
-              re->backend_output_buffer_new = evas_software_wince_gapi_output_buffer_new;
-              re->backend_output_buffer_free = evas_software_wince_gapi_output_buffer_free;
-              re->backend_output_buffer_paste = evas_software_wince_gapi_output_buffer_paste;
-              re->backend_surface_resize = evas_software_wince_gapi_surface_resize;
-              break;
-           case 3: /* DirectDraw */
-              re->backend = EVAS_ENGINE_WINCE_DDRAW;
-              re->backend_priv = evas_software_wince_ddraw_init(info->info.window, info->info.width, info->info.height);
-              if (!re->backend_priv)
-                {
-                   free(re);
-                   return 0;
-                }
-              re->backend_shutdown = evas_software_wince_ddraw_shutdown;
-              re->backend_output_buffer_new = evas_software_wince_ddraw_output_buffer_new;
-              re->backend_output_buffer_free = evas_software_wince_ddraw_output_buffer_free;
-              re->backend_output_buffer_paste = evas_software_wince_ddraw_output_buffer_paste;
-              re->backend_surface_resize = evas_software_wince_ddraw_surface_resize;
-              break;
-           case 4: /* GDI */
-              re->backend = EVAS_ENGINE_WINCE_GDI;
-              re->backend_priv = evas_software_wince_gdi_init(info->info.window, info->info.width, info->info.height, info->info.fullscreen);
-              if (!re->backend_priv)
-                {
-                   free(re);
-                   return 0;
-                }
-              re->backend_shutdown = evas_software_wince_gdi_shutdown;
-              re->backend_output_buffer_new = evas_software_wince_gdi_output_buffer_new;
-              re->backend_output_buffer_free = evas_software_wince_gdi_output_buffer_free;
-              re->backend_output_buffer_paste = evas_software_wince_gdi_output_buffer_paste;
-              re->backend_surface_resize = evas_software_wince_gdi_surface_resize;
-              break;
-           default:
-              free(re);
-              return 0;
-          }
-
-       re->width = e->output.w;
-       re->height = e->output.h;
-       re->rotation = info->info.rotation;
-       re->tb = evas_common_tilebuf_new(e->output.w, e->output.h);
-       if (re->tb)
-         evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
-     }
-   else
-     {
-       re = e->engine.data.output;
-       if (re->tb) evas_common_tilebuf_free(re->tb);
-
-        switch(info->info.backend)
-          {
-           case 1: /* FB */
-              re->backend = EVAS_ENGINE_WINCE_FB;
-              re->backend_priv = evas_software_wince_fb_init(info->info.window, info->info.width, info->info.height);
-              if (!re->backend_priv)
-                {
-                   free(re);
-                   return 0;
-                }
-              re->backend_shutdown = evas_software_wince_fb_shutdown;
-              re->backend_output_buffer_new = evas_software_wince_fb_output_buffer_new;
-              re->backend_output_buffer_free = evas_software_wince_fb_output_buffer_free;
-              re->backend_output_buffer_paste = evas_software_wince_fb_output_buffer_paste;
-              re->backend_surface_resize = evas_software_wince_fb_surface_resize;
-              break;
-           case 2: /* GAPI */
-              re->backend = EVAS_ENGINE_WINCE_GAPI;
-              re->backend_priv = evas_software_wince_gapi_init(info->info.window, info->info.width, info->info.height);
-              if (!re->backend_priv)
-                {
-                   free(re);
-                   return 0;
-                }
-              re->backend_shutdown = evas_software_wince_gapi_shutdown;
-              re->backend_output_buffer_new = evas_software_wince_gapi_output_buffer_new;
-              re->backend_output_buffer_free = evas_software_wince_gapi_output_buffer_free;
-              re->backend_output_buffer_paste = evas_software_wince_gapi_output_buffer_paste;
-              re->backend_surface_resize = evas_software_wince_gapi_surface_resize;
-              break;
-           case 3: /* DirectDraw */
-              re->backend = EVAS_ENGINE_WINCE_DDRAW;
-              re->backend_priv = evas_software_wince_ddraw_init(info->info.window, info->info.width, info->info.height);
-              if (!re->backend_priv)
-                {
-                   free(re);
-                   return 0;
-                }
-              re->backend_shutdown = evas_software_wince_ddraw_shutdown;
-              re->backend_output_buffer_new = evas_software_wince_ddraw_output_buffer_new;
-              re->backend_output_buffer_free = evas_software_wince_ddraw_output_buffer_free;
-              re->backend_output_buffer_paste = evas_software_wince_ddraw_output_buffer_paste;
-              re->backend_surface_resize = evas_software_wince_ddraw_surface_resize;
-              break;
-           case 4: /* GDI */
-              re->backend = EVAS_ENGINE_WINCE_GDI;
-              re->backend_priv = evas_software_wince_gdi_init(info->info.window, info->info.width, info->info.height, info->info.fullscreen);
-              if (!re->backend_priv)
-                {
-                   free(re);
-                   return 0;
-                }
-              re->backend_shutdown = evas_software_wince_gdi_shutdown;
-              re->backend_output_buffer_new = evas_software_wince_gdi_output_buffer_new;
-              re->backend_output_buffer_free = evas_software_wince_gdi_output_buffer_free;
-              re->backend_output_buffer_paste = evas_software_wince_gdi_output_buffer_paste;
-              re->backend_surface_resize = evas_software_wince_gdi_surface_resize;
-              break;
-           default:
-              free(re);
-              return 0;
-          }
-
-       re->width = e->output.w;
-       re->height = e->output.h;
-       re->rotation = info->info.rotation;
-       re->tb = evas_common_tilebuf_new(e->output.w, e->output.h);
-       if (re->tb)
-         evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
-       if (re->tmp_out)
-         {
-             evas_cache_image_drop(&re->tmp_out->cache_entry);
-            re->tmp_out = NULL;
-         }
-     }
-   if (!e->engine.data.output) return 0;
-   /* add a draw context if we dont have one */
-   if (!e->engine.data.context)
-     e->engine.data.context =
-     e->engine.func->context_new(e->engine.data.output);
-
-   return 1;
-}
-
-static void
-eng_output_free(void *data)
-{
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-   if (re->fbob) re->backend_output_buffer_free(re->backend_priv);
-   re->backend_shutdown(re->backend_priv);
-   if (re->clip_rects) DeleteObject(re->clip_rects);
-   if (re->tb) evas_common_tilebuf_free(re->tb);
-   if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
-   if (re->tmp_out) evas_cache_image_drop(&re->tmp_out->cache_entry);
-   free(re);
-
-   evas_common_font_shutdown();
-   evas_common_image_shutdown();
-   evas_common_soft16_image_shutdown();
-}
-
-static void
-eng_output_resize(void *data, int w, int h)
-{
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-
-   if ((re->width == w) && (re->height == h)) return;
-
-   /* FIXME: is it needed ?? */
-   if (re->fbob)
-     re->backend_surface_resize(re->fbob);
-
-   evas_common_tilebuf_free(re->tb);
-   re->width = w;
-   re->height = h;
-   re->tb = evas_common_tilebuf_new(w, h);
-   if (re->tb)
-     evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
-   if (re->fbob)
-     {
-        re->backend_output_buffer_free(re->fbob);
-       re->fbob = NULL;
-     }
-   if (re->clip_rects)
-     {
-       DeleteObject(re->clip_rects);
-       re->clip_rects = NULL;
-     }
-   if (re->tmp_out)
-     {
-       evas_cache_image_drop(&re->tmp_out->cache_entry);
-       re->tmp_out = NULL;
-     }
-}
-
-static void
-eng_output_tile_size_set(void *data, int w, int h)
-{
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-   evas_common_tilebuf_set_tile_size(re->tb, w, h);
-}
-
-static void
-eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
-{
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-   evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
-}
-
-static void
-eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
-{
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-   evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
-}
-
-static void
-eng_output_redraws_clear(void *data)
-{
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-   evas_common_tilebuf_clear(re->tb);
-}
-
-static inline void
-_output_buffer_alloc(Render_Engine *re)
-{
-   int width;
-   int height;
-
-   if (re->fbob) return;
-
-   if ((re->rotation == 0) || (re->rotation == 180))
-     {
-       width = re->width;
-       height = re->height;
-     }
-   else
-     {
-       width = re->height;
-       height = re->width;
-     }
-
-   re->fbob = re->backend_output_buffer_new(re->backend_priv,
-                                            width,
-                                            height);
-}
-
-static void *
-eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
-{
-   Render_Engine *re;
-   Tilebuf_Rect *rect;
-   int ux, uy, uw, uh;
-
-   re = (Render_Engine *)data;
-   if (re->end)
-     {
-       re->end = 0;
-       return NULL;
-     }
-   if (!re->rects)
-     {
-       re->rects = evas_common_tilebuf_get_render_rects(re->tb);
-       if (!re->rects) return NULL;
-
-       re->cur_rect = re->rects;
-       _output_buffer_alloc(re);
-       if (re->rotation != 0) _tmp_out_alloc(re); /* grows if required */
-     }
-   if (!re->cur_rect)
-     {
-       if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
-       re->rects = NULL;
-       return NULL;
-     }
-   rect = re->cur_rect;
-   ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h;
-   re->cur_rect = (Tilebuf_Rect *)((EINA_INLIST_GET(re->cur_rect))->next);
-   if (!re->cur_rect)
-     {
-       evas_common_tilebuf_free_render_rects(re->rects);
-       re->rects = NULL;
-       re->end = 1;
-     }
-
-   *x = ux; *y = uy; *w = uw; *h = uh;
-   if (re->rotation == 0)
-     {
-       *cx = ux; *cy = uy; *cw = uw; *ch = uh;
-       return re->fbob->im;
-     }
-   else
-     {
-       *cx = 0; *cy = 0; *cw = uw; *ch = uh;
-       return re->tmp_out;
-     }
-}
-
-static void
-_blit_rot_90(Soft16_Image *dst, const Soft16_Image *src,
-            int out_x, int out_y, int w, int h)
-{
-   DATA16 *dp, *sp;
-   int x, y;
-
-   sp = src->pixels;
-   dp = dst->pixels + (out_x +
-                      (w + out_y - 1) * dst->stride);
-
-   for (y = 0; y < h; y++)
-     {
-       DATA16 *dp_itr, *sp_itr;
-
-       sp_itr = sp;
-       dp_itr = dp;
-
-       for (x = 0; x < w; x++)
-         {
-            *dp_itr = *sp_itr;
-
-            sp_itr++;
-            dp_itr -= dst->stride;
-         }
-       sp += src->stride;
-       dp++;
-     }
-}
-
-static void
-_blit_rot_180(Soft16_Image *dst, const Soft16_Image *src,
-             int out_x, int out_y, int w, int h)
-{
-   DATA16 *dp, *sp;
-   int x, y;
-
-   sp = src->pixels;
-   dp = dst->pixels + ((w + out_x - 1) +
-                      (h + out_y - 1) * dst->stride);
-
-   for (y = 0; y < h; y++)
-     {
-       DATA16 *dp_itr, *sp_itr;
-
-       sp_itr = sp;
-       dp_itr = dp;
-
-       for (x = 0; x < w; x++)
-         {
-            *dp_itr = *sp_itr;
-
-            sp_itr++;
-            dp_itr--;
-         }
-       sp += src->stride;
-       dp -= dst->stride;
-     }
-}
-
-static void
-_blit_rot_270(Soft16_Image *dst, const Soft16_Image *src,
-             int out_x, int out_y, int w, int h)
-{
-   DATA16 *dp, *sp;
-   int x, y;
-
-   sp = src->pixels;
-   dp = dst->pixels + ((h + out_x - 1) +
-                      out_y * dst->stride);
-
-   for (y = 0; y < h; y++)
-     {
-       DATA16 *dp_itr, *sp_itr;
-
-       sp_itr = sp;
-       dp_itr = dp;
-
-       for (x = 0; x < w; x++)
-         {
-            *dp_itr = *sp_itr;
-
-            sp_itr++;
-            dp_itr += dst->stride;
-         }
-       sp += src->stride;
-       dp--;
-     }
-}
-
-static void
-_tmp_out_process(Render_Engine *re, int out_x, int out_y, int w, int h)
-{
-   Soft16_Image *d, *s;
-
-   d = re->fbob->im;
-   s = re->tmp_out;
-
-   if ((w < 1) || (h < 1) || (out_x >= d->cache_entry.w) || (out_y >= d->cache_entry.h))
-     return;
-
-   if (re->rotation == 90)
-     _blit_rot_90(d, s, out_x, out_y, w, h);
-   else if (re->rotation == 180)
-     _blit_rot_180(d, s, out_x, out_y, w, h);
-   else if (re->rotation == 270)
-     _blit_rot_270(d, s, out_x, out_y, w, h);
-}
-
-static void
-eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
-{
-   Render_Engine *re;
-   HRGN           region;
-   int            xx;
-   int            yy;
-   int            width;
-   int            height;
-
-   re = (Render_Engine *)data;
-
-   if (!re->clip_rects)
-      re->clip_rects = CreateRectRgn(0, 0, 0, 0);
-
-   if (re->rotation == 0)
-     {
-       xx = x;
-       yy = y;
-       width = w;
-       height = h;
-     }
-   else if (re->rotation == 90)
-     {
-       xx = y;
-       yy = re->width - w - x;
-       width = h;
-       height = w;
-     }
-   else if (re->rotation == 180)
-     {
-       xx = re->width - w - x;
-       yy = re->height - h - y;
-       width = w;
-       height = h;
-     }
-   else if (re->rotation == 270)
-     {
-       xx = re->height - h - y;
-       yy = x;
-       width = h;
-       height = w;
-     }
-
-   region = CreateRectRgn(xx, yy, xx + width, yy + height);
-
-   if (re->rotation != 0)
-     _tmp_out_process(re, xx, yy, w, h);
-   CombineRgn(re->clip_rects, re->clip_rects, region, RGN_OR);
-}
-
-static void
-eng_output_flush(void *data)
-{
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-   if (re->clip_rects)
-     {
-        /* FIXME : i have to manage that */
-/*     XSetRegion(re->disp, re->gc, re->clip_rects); */
-       DeleteObject(re->clip_rects);
-       re->clip_rects = NULL;
-     }
-   else return;
-
-   re->backend_output_buffer_paste(re->fbob);
-
-   /* FIXME : i have to manage that */
-/*    XSetClipMask(re->disp, re->gc, None); */
-}
-
-static void
-eng_output_idle_flush(void *data)
-{
-   Render_Engine *re;
-
-   re = (Render_Engine *)data;
-   if (re->fbob)
-     {
-       re->backend_output_buffer_free(re->fbob);
-       re->fbob = NULL;
-     }
-   if (re->clip_rects)
-     {
-       DeleteObject(re->clip_rects);
-       re->clip_rects = NULL;
-     }
-   if (re->tmp_out)
-     {
-       evas_cache_image_drop(&re->tmp_out->cache_entry);
-       re->tmp_out = NULL;
-     }
-}
-
-static Eina_Bool
-eng_canvas_alpha_get(void *data, void *context)
-{
-   return EINA_FALSE;
-}
-
-/* module advertising code */
-static int
-module_open(Evas_Module *em)
-{
-   if (!em) return 0;
-   /* get whatever engine module we inherit from */
-   if (!_evas_module_engine_inherit(&pfunc, "software_16")) return 0;
-   _evas_engine_soft16_wince_log_dom = eina_log_domain_register
-     ("evas-software_16_wince", EVAS_DEFAULT_LOG_COLOR);
-   if (_evas_engine_soft16_wince_log_dom < 0)
-     {
-        EINA_LOG_ERR("Can not create a module log domain.");
-        return 0;
-     }
-
-   /* store it for later use */
-   func = pfunc;
-   /* now to override methods */
-#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
-   ORD(info);
-   ORD(info_free);
-   ORD(setup);
-   ORD(canvas_alpha_get);
-   ORD(output_free);
-   ORD(output_resize);
-   ORD(output_tile_size_set);
-   ORD(output_redraws_rect_add);
-   ORD(output_redraws_rect_del);
-   ORD(output_redraws_clear);
-   ORD(output_redraws_next_update_get);
-   ORD(output_redraws_next_update_push);
-   ORD(output_flush);
-   ORD(output_idle_flush);
-   /* now advertise out own api */
-   em->functions = (void *)(&func);
-   return 1;
-}
-
-static void
-module_close(Evas_Module *em)
-{
-  eina_log_domain_unregister(_evas_engine_soft16_wince_log_dom);
-}
-
-static Evas_Module_Api evas_modapi =
-{
-   EVAS_MODULE_API_VERSION,
-   "software_16_wince",
-   "none",
-   {
-     module_open,
-     module_close
-   }
-};
-
-EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, software_16_wince);
-
-#ifndef EVAS_STATIC_BUILD_SOFTWARE_16_WINCE
-EVAS_EINA_MODULE_DEFINE(engine, software_16_wince);
-#endif
diff --git a/src/modules/engines/software_16_wince/evas_engine.h b/src/modules/engines/software_16_wince/evas_engine.h
deleted file mode 100644 (file)
index 344e7b9..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-#ifndef __EVAS_ENGINE_H__
-#define __EVAS_ENGINE_H__
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
-#include "evas_common.h"
-#include "evas_common_soft16.h"
-
-extern int _evas_engine_soft16_wince_log_dom;
-#ifdef ERR
-# undef ERR
-#endif
-#define ERR(...) EINA_LOG_DOM_ERR(_evas_engine_soft16_wince_log_dom, __VA_ARGS__)
-
-#ifdef DBG
-# undef DBG
-#endif
-#define DBG(...) EINA_LOG_DOM_DBG(_evas_engine_soft16_wince_log_dom, __VA_ARGS__)
-
-#ifdef INF
-# undef INF
-#endif
-#define INF(...) EINA_LOG_DOM_INFO(_evas_engine_soft16_wince_log_dom, __VA_ARGS__)
-
-#ifdef WRN
-# undef WRN
-#endif
-#define WRN(...) EINA_LOG_DOM_WARN(_evas_engine_soft16_wince_log_dom, __VA_ARGS__)
-
-#ifdef CRIT
-# undef CRIT
-#endif
-#define CRIT(...) EINA_LOG_DOM_CRIT(_evas_engine_soft16_wince_log_dom, __VA_ARGS__)
-
-typedef struct _FB_Output_Buffer FB_Output_Buffer;
-
-struct _FB_Output_Buffer
-{
-   Soft16_Image *im;
-   void         *priv;
-};
-
-
-/* Raw FrameBuffer */
-
-void             *evas_software_wince_fb_init (HWND window,
-                                               int  width,
-                                               int  height);
-FB_Output_Buffer *evas_software_wince_fb_output_buffer_new (void *priv,
-                                                            int   width,
-                                                            int   height);
-void              evas_software_wince_fb_shutdown(void *priv);
-void              evas_software_wince_fb_output_buffer_free (FB_Output_Buffer *fbob);
-void              evas_software_wince_fb_output_buffer_paste (FB_Output_Buffer *fbob);
-
-void              evas_software_wince_fb_surface_resize(FB_Output_Buffer *fbob);
-
-
-/* GAPI */
-
-void             *evas_software_wince_gapi_init (HWND window,
-                                                 int  width,
-                                                 int  height);
-FB_Output_Buffer *evas_software_wince_gapi_output_buffer_new (void *priv,
-                                                              int   width,
-                                                              int   height);
-void              evas_software_wince_gapi_shutdown(void *priv);
-void              evas_software_wince_gapi_output_buffer_free (FB_Output_Buffer *fbob);
-void              evas_software_wince_gapi_output_buffer_paste (FB_Output_Buffer *fbob);
-
-void              evas_software_wince_gapi_surface_resize(FB_Output_Buffer *fbob);
-
-void             *evas_software_wince_gapi_default_keys(void);
-int               evas_software_wince_gapi_suspend(void);
-int               evas_software_wince_gapi_resume(void);
-
-
-/* DirectDraw */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-void             *evas_software_wince_ddraw_init (HWND window,
-                                                  int  width,
-                                                  int  height);
-FB_Output_Buffer *evas_software_wince_ddraw_output_buffer_new (void *priv,
-                                                               int   width,
-                                                               int   height);
-void              evas_software_wince_ddraw_shutdown(void *priv);
-void              evas_software_wince_ddraw_output_buffer_free (FB_Output_Buffer *fbob);
-void              evas_software_wince_ddraw_output_buffer_paste (FB_Output_Buffer *fbob);
-
-void              evas_software_wince_ddraw_surface_resize(FB_Output_Buffer *fbob);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/* GDI */
-
-void             *evas_software_wince_gdi_init (HWND window,
-                                                int  width,
-                                                int  height,
-                                                int  fullscreen);
-FB_Output_Buffer *evas_software_wince_gdi_output_buffer_new (void *priv,
-                                                             int   width,
-                                                             int   height);
-void              evas_software_wince_gdi_shutdown(void *priv);
-void              evas_software_wince_gdi_output_buffer_free (FB_Output_Buffer *fbob);
-void              evas_software_wince_gdi_output_buffer_paste (FB_Output_Buffer *fbob);
-
-void              evas_software_wince_gdi_surface_resize(FB_Output_Buffer *fbob);
-
-
-#endif /* __EVAS_ENGINE_H__ */
diff --git a/src/modules/engines/software_16_wince/evas_wince_ddraw_buffer.cpp b/src/modules/engines/software_16_wince/evas_wince_ddraw_buffer.cpp
deleted file mode 100644 (file)
index 944ed53..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-
-#include <cstdio>
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
-#include <ddraw.h>
-
-#include "evas_common.h"
-#include "evas_engine.h"
-
-
-typedef LONG (*fct_DirectDrawCreate)(LPGUID, LPUNKNOWN *, LPUNKNOWN *);
-
-fct_DirectDrawCreate lib_DirectDrawCreate;
-
-typedef struct Evas_Engine_WinCE_DDraw_Priv Evas_Engine_WinCE_DDraw_Priv;
-
-struct Evas_Engine_WinCE_DDraw_Priv
-{
-   HMODULE             module;
-   LPDIRECTDRAW        object;
-   LPDIRECTDRAWSURFACE surface;
-   int                 width;
-   int                 height;
-   int                 stride;
-};
-
-void *
-evas_software_wince_ddraw_init(HWND window,
-                               int  width,
-                               int  height)
-{
-   DDSURFACEDESC                 surface_desc;
-   Evas_Engine_WinCE_DDraw_Priv *priv;
-   HRESULT                       res;
-
-   priv = (Evas_Engine_WinCE_DDraw_Priv *)malloc(sizeof(Evas_Engine_WinCE_DDraw_Priv));
-   if (!priv)
-     return NULL;
-   
-   priv->module = LoadLibrary(L"ddraw.dll");
-   if (!priv->module)
-     {
-        fprintf(stderr, "[Engine] [WinCE DDraw] Can not load ddraw.dll\n");
-        goto free_priv;
-     }
-
-   lib_DirectDrawCreate = (fct_DirectDrawCreate)GetProcAddress(priv->module, L"DirectDrawCreate");
-   if (!lib_DirectDrawCreate)
-     {
-        fprintf(stderr, "[Engine] [WinCE DDraw] Can not initialize DirectDraw\n");
-        goto free_lib;
-     }
-
-   res = lib_DirectDrawCreate(NULL, (IUnknown**)&priv->object, NULL);
-   if (FAILED(res))
-     {
-        fprintf(stderr, "[Engine] [WinCE DDraw] Can not create DirectDraw object\n");
-        goto free_lib;
-     }
-
-   res = priv->object->SetCooperativeLevel(window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
-   if (FAILED(res))
-     {
-        fprintf(stderr, "[Engine] [WinCE DDraw] Can not set window to fullscreen\n");
-        goto release_object;
-     }
-
-   memset(&surface_desc, 0, sizeof(surface_desc));
-   surface_desc.dwSize = sizeof(surface_desc);
-   surface_desc.dwFlags = DDSD_CAPS;
-   surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
-
-   res = priv->object->CreateSurface(&surface_desc, &priv->surface, NULL);
-   if (FAILED(res))
-     {
-        fprintf(stderr, "[Engine] [WinCE DDraw] Can not create surface\n");
-        goto release_object;
-     }
-
-   memset(&surface_desc, 0, sizeof(surface_desc));
-   surface_desc.dwSize = sizeof(surface_desc);
-   res = priv->surface->Lock(NULL, &surface_desc, DDLOCK_READONLY, NULL);
-   if (FAILED(res))
-     {
-        fprintf(stderr, "[Evas] [Engine] [WinCE DDraw] Can not lock surface\n");
-        goto release_surface;
-     }
-
-   priv->width = surface_desc.dwWidth;
-   priv->height = surface_desc.dwHeight;
-   priv->stride = surface_desc.lPitch / 2;
-
-   if ((priv->width != width) ||
-       (priv->height != height))
-     {
-        fprintf(stderr, "[Engine] [WinCE DDraw] Size mismatch\n");
-        fprintf(stderr, "[Engine] [WinCE DDraw] asked : %dx%d\n", width, height);
-        fprintf(stderr, "[Engine] [WinCE DDraw] got   : %dx%d\n", priv->width, priv->height);
-        goto release_surface;
-     }
-
-   res = priv->surface->Unlock(NULL);
-   if (FAILED(res))
-     {
-        fprintf(stderr, "[Engine] [WinCE DDraw] Can not unlock surface\n");
-        goto release_surface;
-     }
-
-   return priv;
-
- release_surface:
-   priv->surface->Release();
- release_object:
-   priv->object->Release();
- free_lib:
-   FreeLibrary(priv->module);
- free_priv:
-   free(priv);
-
-  return 0;
-}
-
-void
-evas_software_wince_ddraw_shutdown(void *priv)
-{
-   ((Evas_Engine_WinCE_DDraw_Priv *)priv)->surface->Release();
-   ((Evas_Engine_WinCE_DDraw_Priv *)priv)->object->Release();
-   FreeLibrary(((Evas_Engine_WinCE_DDraw_Priv *)priv)->module);
-   free(priv);
-}
-
-
-FB_Output_Buffer *
-evas_software_wince_ddraw_output_buffer_new(void *priv,
-                                            int   width,
-                                            int   height)
-{
-   FB_Output_Buffer *fbob;
-   void             *buffer;
-
-   fbob = (FB_Output_Buffer *)calloc(1, sizeof(FB_Output_Buffer));
-   if (!fbob) return NULL;
-
-   buffer = malloc (width * height * 2); /* we are sure to have 16bpp */
-   if (!buffer)
-     {
-        free(fbob);
-        return NULL;
-     }
-
-   fbob->priv = priv;
-
-   fbob->im = (Soft16_Image *) evas_cache_image_data(evas_common_soft16_image_cache_get(), width, height, (DATA32 *)buffer, 0, EVAS_COLORSPACE_RGB565_A5P);
-   if (fbob->im)
-     fbob->im->stride = ((Evas_Engine_WinCE_DDraw_Priv *)priv)->stride;
-
-   return fbob;
-}
-
-void
-evas_software_wince_ddraw_output_buffer_free(FB_Output_Buffer *fbob)
-{
-   free(fbob->im->pixels);
-   free(fbob);
-}
-
-void
-evas_software_wince_ddraw_output_buffer_paste(FB_Output_Buffer *fbob)
-{
-   DDSURFACEDESC                 surface_desc;
-   Evas_Engine_WinCE_DDraw_Priv *priv;
-   HRESULT                       res;
-
-   priv = (Evas_Engine_WinCE_DDraw_Priv *)fbob->priv;
-
-   memset(&surface_desc, 0, sizeof(surface_desc));
-   surface_desc.dwSize = sizeof(surface_desc);
-   res = priv->surface->Lock(NULL, &surface_desc, DDLOCK_WRITEONLY, NULL);
-   if (FAILED(res))
-     return;
-
-   if ((fbob->im->cache_entry.w == surface_desc.dwWidth) &&
-       (fbob->im->cache_entry.h == surface_desc.dwHeight))
-     memcpy(surface_desc.lpSurface, fbob->im->pixels,
-            surface_desc.dwWidth * surface_desc.dwHeight * 2);
-
-   priv->surface->Unlock(NULL);
-}
-
-void
-evas_software_wince_ddraw_surface_resize(FB_Output_Buffer *fbob)
-{
-}
diff --git a/src/modules/engines/software_16_wince/evas_wince_fb_buffer.c b/src/modules/engines/software_16_wince/evas_wince_fb_buffer.c
deleted file mode 100644 (file)
index 6a81bf4..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-#include "evas_common.h"
-#include "evas_engine.h"
-
-
-#define GETGXINFO 0x00020000
-
-typedef struct GXDeviceInfo
-{
-    long Version;               //00 (should filled with 100 before calling ExtEscape)
-    void *pvFrameBuffer;        //04
-    unsigned long cbStride;     //08
-    unsigned long cxWidth;      //0c
-    unsigned long cyHeight;     //10
-    unsigned long cBPP;         //14
-    unsigned long ffFormat;     //18
-    char Unused[0x84 - 7 * 4];
-} GXDeviceInfo;
-
-
-#define GETRAWFRAMEBUFFER 0x00020001
-
-typedef struct _RawFrameBufferInfo
-{
-   WORD  wFormat;
-   WORD  wBPP;
-   VOID *pFramePointer;
-   int   cxStride;
-   int   cyStride;
-   int   cxPixels;
-   int   cyPixels;
-} RawFrameBufferInfo;
-
-
-typedef struct Evas_Engine_WinCE_FB_Priv Evas_Engine_WinCE_FB_Priv;
-
-struct Evas_Engine_WinCE_FB_Priv
-{
-   int   width;
-   int   height;
-   void *buffer;
-};
-
-static int
-_evas_software_wince_gxinfo_init(HDC dc, int *width, int *height, void **buffer)
-{
-   GXDeviceInfo gxInfo = { 0 };
-   int          result;
-
-   gxInfo.Version = 100;
-   result = ExtEscape(dc, GETGXINFO, 0, NULL, sizeof(gxInfo),
-                      (char *) &gxInfo);
-   if (result <= 0)
-     {
-        ERR("ExtEscape() with GETGXINFO failed");
-        return 0;
-     }
-
-   *width = gxInfo.cyHeight;
-   *height = gxInfo.cxWidth;
-   *buffer = gxInfo.pvFrameBuffer;
-
-   return 1;
-}
-
-void *
-evas_software_wince_fb_init(HWND window,
-                            int  width,
-                            int  height)
-{
-   WCHAR                      oemstr[100];
-   RawFrameBufferInfo         rfbi;
-   HDC                        dc;
-   Evas_Engine_WinCE_FB_Priv *priv;
-
-   priv = (Evas_Engine_WinCE_FB_Priv *)malloc(sizeof(Evas_Engine_WinCE_FB_Priv));
-   if (!priv)
-     return NULL;
-
-   dc = GetDC (window);
-   if (!dc)
-     {
-        ERR("Can not get DC");
-        free(priv);
-        return NULL;
-     }
-
-   SystemParametersInfo (SPI_GETOEMINFO, sizeof (oemstr), oemstr, 0);
-   if (((oemstr[12] == 'H') &&
-        (oemstr[13] == '3') &&
-        (oemstr[14] == '8')) ||
-       ((oemstr[12] == 'H') &&
-        (oemstr[13] == '3') &&
-        (oemstr[14] == '9')))
-     {
-       if (!_evas_software_wince_gxinfo_init(dc, &priv->width, &priv->height, &priv->buffer))
-          {
-             ReleaseDC(window, dc);
-             free(priv);
-             return NULL;
-          }
-
-       if ((priv->width != width) ||
-           (priv->height != height))
-         {
-            ERR("Size mismatch: asked: %dx%d, got: %dx%d",
-                width, height, priv->width, priv->height);
-            ReleaseDC(window, dc);
-            free(priv);
-            return NULL;
-         }
-
-        ReleaseDC(window, dc);
-
-        return priv;
-     }
-
-   if (!ExtEscape(dc, GETRAWFRAMEBUFFER, 0, 0, sizeof(rfbi), (char *) &rfbi)||
-       (rfbi.wBPP != 16) ||
-       (rfbi.wFormat != 1))
-     {
-        ERR("ExtEscape() with GETRAWFRAMEBUFFER failed. "
-            "Trying ExtEscape() with GETGXINFO");
-        if (!_evas_software_wince_gxinfo_init(dc, &priv->width, &priv->height, &priv->buffer))
-          {
-             ReleaseDC(window, dc);
-             free(priv);
-             return NULL;
-          }
-
-        ReleaseDC(window, dc);
-        return priv;
-     }
-
-  priv->width = rfbi.cxPixels;
-  priv->height = rfbi.cyPixels;
-  priv->buffer = rfbi.pFramePointer;
-
-  if ((priv->width != width) ||
-      (priv->height != height))
-    {
-        ERR("Size mismatch: asked: %dx%d, got: %dx%d",
-            width, height, priv->width, priv->height);
-       ReleaseDC(window, dc);
-       free(priv);
-       return NULL;
-    }
-
-  ReleaseDC(window, dc);
-
-  return priv;
-}
-
-void
-evas_software_wince_fb_shutdown(void *priv)
-{
-   free(priv);
-}
-
-
-FB_Output_Buffer *
-evas_software_wince_fb_output_buffer_new(void *priv,
-                                         int   width,
-                                         int   height)
-{
-   FB_Output_Buffer *fbob;
-   void             *buffer;
-
-   fbob = calloc(1, sizeof(FB_Output_Buffer));
-   if (!fbob) return NULL;
-
-   buffer = malloc (width * height * 2); /* we are sure to have 16bpp */
-   if (!buffer)
-     {
-        free(fbob);
-        return NULL;
-     }
-
-   fbob->priv = priv;
-
-   fbob->im = (Soft16_Image *) evas_cache_image_data(evas_common_soft16_image_cache_get(), width, height, (DATA32 *)buffer, 0, EVAS_COLORSPACE_RGB565_A5P);
-   if (fbob->im)
-     fbob->im->stride = width;
-
-   return fbob;
-}
-
-void
-evas_software_wince_fb_output_buffer_free(FB_Output_Buffer *fbob)
-{
-   free(fbob->im->pixels);
-   free(fbob);
-}
-
-void
-evas_software_wince_fb_output_buffer_paste(FB_Output_Buffer *fbob)
-{
-   Evas_Engine_WinCE_FB_Priv *priv;
-
-   priv = (Evas_Engine_WinCE_FB_Priv *)fbob->priv;
-
-   if ((fbob->im->cache_entry.w == priv->width) &&
-       (fbob->im->cache_entry.h == priv->height))
-     memcpy(priv->buffer, fbob->im->pixels,
-            priv->width * priv->height * 2);
-}
-
-void
-evas_software_wince_fb_surface_resize(FB_Output_Buffer *fbob)
-{
-}
diff --git a/src/modules/engines/software_16_wince/evas_wince_gapi_buffer.c b/src/modules/engines/software_16_wince/evas_wince_gapi_buffer.c
deleted file mode 100644 (file)
index c23c863..0000000
+++ /dev/null
@@ -1,341 +0,0 @@
-#include "evas_common.h"
-#include "evas_engine.h"
-
-
-typedef int (*evas_engine_wince_close_display)();
-
-typedef struct Evas_Engine_WinCE_GAPI_Priv Evas_Engine_WinCE_GAPI_Priv;
-
-
-#define GETGXINFO 0x00020000
-
-typedef struct
-{
-    long Version;               //00 (should filled with 100 before calling ExtEscape)
-    void *pvFrameBuffer;        //04
-    unsigned long cbStride;     //08
-    unsigned long cxWidth;      //0c
-    unsigned long cyHeight;     //10
-    unsigned long cBPP;         //14
-    unsigned long ffFormat;     //18
-    char Unused[0x84 - 7 * 4];
-} _GXDeviceInfo;
-
-
-#define LINK(type,name,import) \
-  name = (gapi_##type)GetProcAddress (gapi_lib, import)
-
-#define GX_FULLSCREEN 0x01
-#define GX_NORMALKEYS 0x02
-
-#define kfDirect555   0x40
-#define kfDirect565   0x80
-
-
-typedef struct
-{
-   DWORD cxWidth;
-   DWORD cyHeight;
-   LONG  cbxPitch;
-   LONG  cbyPitch;
-   LONG  cBPP;
-   DWORD ffFormat;
-} _GAPI_Display_Properties;
-
-typedef int                      (*gapi_display_open)(HWND hWnd, DWORD dwFlags);
-typedef int                      (*gapi_display_close)();
-typedef _GAPI_Display_Properties (*gapi_display_properties_get)(void);
-typedef void*                    (*gapi_draw_begin)(void);
-typedef int                      (*gapi_draw_end)(void);
-typedef int                      (*gapi_suspend)(void);
-typedef int                      (*gapi_resume)(void);
-
-gapi_suspend          suspend = NULL;
-gapi_resume           resume = NULL;
-
-int
-evas_software_wince_gapi_suspend(void)
-{
-   if (suspend)
-     return suspend();
-   else
-     return 0;
-}
-
-int
-evas_software_wince_gapi_resume(void)
-{
-   if (resume)
-     return resume();
-   else
-     return 0;
-}
-
-
-struct Evas_Engine_WinCE_GAPI_Priv
-{
-   HMODULE            lib;
-   gapi_display_close close_display;
-   gapi_draw_begin    draw_begin;
-   gapi_draw_end      draw_end;
-   void              *buffer;
-   int                width;
-   int                height;
-   int                stride;
-};
-
-void *
-evas_software_wince_gapi_init(HWND window,
-                              int  width,
-                              int  height)
-{
-   WCHAR                        oemstr[100];
-   _GAPI_Display_Properties     prop;
-   HMODULE                      gapi_lib;
-   Evas_Engine_WinCE_GAPI_Priv *priv;
-
-   gapi_display_open            display_open = NULL;
-   gapi_display_close           display_close = NULL;
-   gapi_display_properties_get  display_properties_get = NULL;
-   gapi_draw_begin              draw_begin = NULL;
-   gapi_draw_end                draw_end = NULL;
-
-   priv = (Evas_Engine_WinCE_GAPI_Priv *)malloc(sizeof(Evas_Engine_WinCE_GAPI_Priv));
-   if (!priv)
-     return NULL;
-
-   gapi_lib = LoadLibrary(L"\\Windows\\gx.dll");
-   if (!gapi_lib)
-     {
-        gapi_lib = LoadLibrary(L"gx.dll");
-        if (!gapi_lib)
-          {
-             ERR("[Engine] [WinCE GAPI] Can not load gx.dll");
-             goto free_priv;
-          }
-     }
-
-   LINK(display_open, display_open, L"?GXOpenDisplay@@YAHPAUHWND__@@K@Z");
-   LINK(display_close, display_close, L"?GXCloseDisplay@@YAHXZ");
-   LINK(display_properties_get, display_properties_get, L"?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ");
-   LINK(draw_begin, draw_begin, L"?GXBeginDraw@@YAPAXXZ");
-   LINK(draw_end, draw_end, L"?GXEndDraw@@YAHXZ");
-   LINK(suspend, suspend, L"?GXSuspend@@YAHXZ" );
-   LINK(resume, resume, L"?GXResume@@YAHXZ" );
-
-   if (!display_open ||
-       !display_close ||
-       !display_properties_get ||
-       !draw_begin ||
-       !draw_end ||
-       !suspend ||
-       !resume)
-     {
-       ERR("[Engine] [WinCE GAPI] Can not find valid symbols");
-        goto free_lib;
-     }
-
-   if (!display_open(window, GX_FULLSCREEN))
-     {
-       ERR("[Engine] [WinCE GAPI] Can not open display");
-        goto free_lib;
-     }
-
-   prop = display_properties_get();
-
-   // verify pixel format
-   if(!(prop.ffFormat & kfDirect565) || (prop.cBPP != 16))
-     {
-        ERR("display format mismatch");
-        goto close_display;
-     }
-
-   // verify we have a vga device
-   if ((GetSystemMetrics(SM_CXSCREEN) != (int)prop.cxWidth) ||
-       (GetSystemMetrics(SM_CYSCREEN) != (int)prop.cyHeight))
-     {
-        ERR("display size mismatch");
-        goto close_display;
-     }
-
-   priv->lib = gapi_lib;
-   priv->close_display = display_close;
-   priv->draw_begin = draw_begin;
-   priv->draw_end = draw_end;
-
-   /* GAPI on Ipaq H38** and H39** is completely buggy */
-   /* They are detected as portrait device (width = 240 and height = 320) */
-   /* but the framebuffer is managed like a landscape device : */
-   /*
-     240
- +---------+
- |         |
- |         |
- |         |
- |         |
- |         | 320
- | ^^^     |
- | |||     |
- | |||     |
- | |||     |
- +---------+
-  ---->
-
-   */
-   /* So these devices are considered as landscape devices */
-   /* and width and height are switched. */
-   /* Other devices are managed normally : */
-   /*
-     240
-  +---------+
-| |--->     |
-| |--->     |
-| |--->     |
-v |         |
-  |         | 320
-  |         |
-  |         |
-  |         |
-  |         |
-  +---------+
-
-    */
-
-   SystemParametersInfo (SPI_GETOEMINFO, sizeof (oemstr), oemstr, 0);
-
-   if (((oemstr[12] == 'H') &&
-        (oemstr[13] == '3') &&
-        (oemstr[14] == '8')) ||
-       ((oemstr[12] == 'H') &&
-        (oemstr[13] == '3') &&
-        (oemstr[14] == '9')))
-     {
-        _GXDeviceInfo gxInfo = { 0 };
-        HDC           dc;
-        int           result;
-
-        priv->width = prop.cyHeight;
-        priv->height = prop.cxWidth;
-        priv->stride = prop.cbxPitch;
-
-        dc = GetDC (window);
-        if (!dc)
-          {
-             ERR("Can not get device");
-             goto close_display;
-          }
-
-        gxInfo.Version = 100;
-        result = ExtEscape(dc, GETGXINFO, 0, NULL, sizeof(gxInfo),
-                           (char *) &gxInfo);
-        if (result <= 0)
-          {
-             ERR("ExtEscape failed");
-             ReleaseDC(window, dc);
-             goto close_display;
-          }
-
-        priv->buffer = gxInfo.pvFrameBuffer;
-        ReleaseDC(window, dc);
-     }
-   else
-     {
-        priv->width = prop.cxWidth;
-        priv->height = prop.cyHeight;
-        priv->stride = prop.cbyPitch;
-        priv->buffer = NULL;
-     }
-
-   if ((priv->width != width) ||
-       (priv->height != height))
-     {
-        ERR("Size mismatch: asked: %dx%d, got: %dx%d",
-            width, height, priv->width, priv->height);
-        goto close_display;
-     }
-
-   return priv;
-
- close_display:
-   display_close();
- free_lib:
-   FreeLibrary(gapi_lib);
- free_priv:
-   free(priv);
-   return NULL;
-}
-
-void
-evas_software_wince_gapi_shutdown(void *priv)
-{
-   Evas_Engine_WinCE_GAPI_Priv *p;
-
-   p = (Evas_Engine_WinCE_GAPI_Priv *)priv;
-   p->close_display();
-   suspend = NULL;
-   resume = NULL;
-   FreeLibrary(p->lib);
-   free(p);
-}
-
-
-FB_Output_Buffer *
-evas_software_wince_gapi_output_buffer_new(void *priv,
-                                           int   width,
-                                           int   height)
-{
-   FB_Output_Buffer *fbob;
-   void             *buffer;
-
-   fbob = calloc(1, sizeof(FB_Output_Buffer));
-   if (!fbob) return NULL;
-
-   buffer = malloc (width * height * 2); /* we are sure to have 16bpp */
-   if (!buffer)
-     {
-        free(fbob);
-        return NULL;
-     }
-
-   fbob->priv = priv;
-
-   fbob->im = (Soft16_Image *) evas_cache_image_data(evas_common_soft16_image_cache_get(), width, height, (DATA32 *)buffer, 0, EVAS_COLORSPACE_RGB565_A5P);
-   if (fbob->im)
-     fbob->im->stride = ((Evas_Engine_WinCE_GAPI_Priv *)priv)->stride >> 1;
-
-   return fbob;
-}
-
-void
-evas_software_wince_gapi_output_buffer_free(FB_Output_Buffer *fbob)
-{
-   free(fbob->im->pixels);
-   free(fbob);
-}
-
-void
-evas_software_wince_gapi_output_buffer_paste(FB_Output_Buffer *fbob)
-{
-   Evas_Engine_WinCE_GAPI_Priv *priv;
-   void                        *buffer;
-
-   priv = (Evas_Engine_WinCE_GAPI_Priv *)fbob->priv;
-
-   buffer = priv->draw_begin();
-   if (!buffer)
-     return;
-
-   if (priv->buffer) buffer = priv->buffer;
-
-   if ((fbob->im->cache_entry.w == priv->width) &&
-       (fbob->im->cache_entry.h == priv->height))
-     memcpy(buffer, fbob->im->pixels,
-            priv->width * priv->height * 2);
-
-   priv->draw_end();
-}
-
-void
-evas_software_wince_gapi_surface_resize(FB_Output_Buffer *fbob)
-{
-}
diff --git a/src/modules/engines/software_16_wince/evas_wince_gdi_buffer.c b/src/modules/engines/software_16_wince/evas_wince_gdi_buffer.c
deleted file mode 100644 (file)
index f32db4a..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-#include "evas_common.h"
-#include "evas_engine.h"
-
-
-typedef struct BITMAPINFO_16bpp BITMAPINFO_16bpp;
-typedef struct Evas_Engine_WinCE_GDI_Priv Evas_Engine_WinCE_GDI_Priv;
-
-struct BITMAPINFO_16bpp
-{
-   BITMAPINFOHEADER bih;
-   DWORD            masks[3];
-};
-
-struct Evas_Engine_WinCE_GDI_Priv
-{
-   HWND              window;
-   HDC               dc;
-   BITMAPINFO_16bpp *bitmap_info;
-   HBITMAP           bitmap;
-   int               width;
-   int               height;
-};
-
-void *
-evas_software_wince_gdi_init(HWND window,
-                             int  width,
-                             int  height,
-                             int  fullscreen)
-{
-   Evas_Engine_WinCE_GDI_Priv *priv;
-
-   priv = (Evas_Engine_WinCE_GDI_Priv *)malloc(sizeof(Evas_Engine_WinCE_GDI_Priv));
-   if (!priv)
-     return NULL;
-
-   priv->window = window;
-   priv->dc = GetDC(window);
-   if (!priv->dc)
-     {
-        ERR("Can not get DC");
-        free(priv);
-        return NULL;
-     }
-
-   if (fullscreen)
-     {
-        priv->width = GetSystemMetrics(SM_CXSCREEN);
-        priv->height = GetSystemMetrics(SM_CYSCREEN);
-     }
-   else
-     {
-        priv->width = width;
-        priv->height = height;
-     }
-
-   priv->bitmap_info = (BITMAPINFO_16bpp *)malloc(sizeof(BITMAPINFO_16bpp));
-   if (!priv->bitmap_info)
-     {
-        ERR("Can not allocate bitmap info");
-        ReleaseDC(window, priv->dc);
-        free(priv);
-        return NULL;
-     }
-
-   priv->bitmap_info->bih.biSize = sizeof(BITMAPINFOHEADER);
-   priv->bitmap_info->bih.biWidth = priv->width;
-   priv->bitmap_info->bih.biHeight = -priv->height;
-   priv->bitmap_info->bih.biPlanes = 1;
-   priv->bitmap_info->bih.biSizeImage = 2 * priv->width * priv->height;
-   priv->bitmap_info->bih.biXPelsPerMeter = 0;
-   priv->bitmap_info->bih.biYPelsPerMeter = 0;
-   priv->bitmap_info->bih.biClrUsed = 0;
-   priv->bitmap_info->bih.biClrImportant = 0;
-   priv->bitmap_info->bih.biBitCount = 16;
-   priv->bitmap_info->bih.biCompression = BI_BITFIELDS;
-   priv->bitmap_info->masks[0] = 0x0000f800;
-   priv->bitmap_info->masks[1] = 0x000007e0;
-   priv->bitmap_info->masks[2] = 0x0000001f;
-
-   return priv;
-}
-
-void
-evas_software_wince_gdi_shutdown(void *priv)
-{
-   free(((Evas_Engine_WinCE_GDI_Priv *)priv)->bitmap_info);
-   ReleaseDC(((Evas_Engine_WinCE_GDI_Priv *)priv)->window, ((Evas_Engine_WinCE_GDI_Priv *)priv)->dc);
-   free(priv);
-}
-
-
-FB_Output_Buffer *
-evas_software_wince_gdi_output_buffer_new(void *priv,
-                                          int   width,
-                                          int   height)
-{
-   Evas_Engine_WinCE_GDI_Priv *priv2;
-   FB_Output_Buffer           *fbob;
-   void                       *buffer;
-
-   fbob = calloc(1, sizeof(FB_Output_Buffer));
-   if (!fbob) return NULL;
-
-   fbob->priv = priv;
-
-   priv2 = (Evas_Engine_WinCE_GDI_Priv *)fbob->priv;
-
-   priv2->bitmap = CreateDIBSection(priv2->dc,
-                                    (const BITMAPINFO *)priv2->bitmap_info,
-                                    DIB_RGB_COLORS,
-                                    (void **)(&buffer),
-                                    NULL,
-                                    0);
-   if (!priv2->bitmap)
-     {
-        free(fbob);
-        return NULL;
-     }
-
-   fbob->im = (Soft16_Image *) evas_cache_image_data(evas_common_soft16_image_cache_get(), width, height, (DATA32 *)buffer, 0, EVAS_COLORSPACE_RGB565_A5P);
-   if (fbob->im)
-     fbob->im->stride = width;
-
-   return fbob;
-}
-
-void
-evas_software_wince_gdi_output_buffer_free(FB_Output_Buffer *fbob)
-{
-   Evas_Engine_WinCE_GDI_Priv *priv;
-
-   priv = (Evas_Engine_WinCE_GDI_Priv *)fbob->priv;
-   DeleteObject(priv->bitmap);
-   free(fbob);
-}
-
-void
-evas_software_wince_gdi_output_buffer_paste(FB_Output_Buffer *fbob)
-{
-   Evas_Engine_WinCE_GDI_Priv *priv;
-
-   priv = (Evas_Engine_WinCE_GDI_Priv *)fbob->priv;
-
-   if ((fbob->im->cache_entry.w == priv->width) &&
-       (fbob->im->cache_entry.h == priv->height))
-     {
-        HDC dc;
-
-        dc = CreateCompatibleDC(priv->dc);
-        SelectObject(dc, priv->bitmap);
-        BitBlt(priv->dc,
-               0, 0,
-               priv->width, priv->height,
-               dc,
-               0, 0,
-               SRCCOPY);
-        DeleteDC(dc);
-
-     }
-}
-
-void
-evas_software_wince_gdi_surface_resize(FB_Output_Buffer *fbob)
-{
-}
index 4ca894a..68be014 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/modules/engines \
 -I$(top_srcdir)/src/modules/engines/software_16 \
 @FREETYPE_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_engine_software_16_x11_cflags@
@@ -31,7 +31,7 @@ pkgdir = $(libdir)/evas/modules/engines/software_16_x11/$(MODULE_ARCH)
 pkg_LTLIBRARIES        = module.la
 
 module_la_SOURCES = $(SOFTWARE_16_X11_SOURCES)
-module_la_LIBADD = @EINA_LIBS@ $(SOFTWARE_16_X11_LIBADD) $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ $(SOFTWARE_16_X11_LIBADD) $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 5378972..a52fec7 100644 (file)
@@ -7,52 +7,6 @@
 int _evas_engine_soft16_x11_log_dom = -1;
 /* function tables - filled in later (func and parent func) */
 static Evas_Func func, pfunc;
-/*
-struct xrdb_user
-{
-   time_t last_stat;
-   time_t last_mtime;
-   XrmDatabase db;
-};
-static struct xrdb_user xrdb_user = {0, 0, NULL};
-
-static Eina_Bool
-xrdb_user_query(const char *name, const char *cls, char **type, XrmValue *val)
-{
-   time_t last = xrdb_user.last_stat, now = time(NULL);
-
-   xrdb_user.last_stat = now;
-   if (last != now) // don't stat() more than once every second
-     {
-       struct stat st;
-       const char *home = getenv("HOME");
-       char tmp[PATH_MAX];
-
-       if (!home) goto failed;
-       snprintf(tmp, sizeof(tmp), "%s/.Xdefaults", home);
-       if (stat(tmp, &st) != 0) goto failed;
-       if (xrdb_user.last_mtime != st.st_mtime)
-         {
-            if (xrdb_user.db) XrmDestroyDatabase(xrdb_user.db);
-            xrdb_user.db = XrmGetFileDatabase(tmp);
-            if (!xrdb_user.db) goto failed;
-            xrdb_user.last_mtime = st.st_mtime;
-         }
-     }
-
-   if (!xrdb_user.db) return EINA_FALSE;
-   return XrmGetResource(xrdb_user.db, name, cls, type, val);
-
- failed:
-   if (xrdb_user.db)
-     {
-       XrmDestroyDatabase(xrdb_user.db);
-       xrdb_user.db = NULL;
-     }
-   xrdb_user.last_mtime = 0;
-   return EINA_FALSE;
-}
-*/
 
 /* engine struct data */
 typedef struct _Render_Engine Render_Engine;
@@ -66,12 +20,6 @@ struct _Render_Engine
    Tilebuf          *tb;
    Tilebuf_Rect     *rects;
    Tilebuf_Rect     *cur_rect;
-/*   
-   XrmDatabase   xrdb; // xres - dpi
-   struct { // xres - dpi
-      int        dpi; // xres - dpi
-   } xr; // xres - dpi
- */
    X_Output_Buffer  *shbuf;
    Soft16_Image     *tmp_out; /* used by indirect render, like rotation */
    Region            clip_rects;
@@ -228,62 +176,6 @@ eng_setup(Evas *e, void *in)
      }
    if (!e->engine.data.output) return 0;
    
-/*   
-     {   
-        int status;
-        char *type = NULL;
-        XrmValue val;
-        
-        re->xr.dpi = 75000; // dpy * 1000
-
-       status = xrdb_user_query("Xft.dpi", "Xft.Dpi", &type, &val);
-       if ((!status) || (!type))
-         {
-            if (!re->xrdb) re->xrdb = XrmGetDatabase(re->disp);
-            if (re->xrdb)
-              status = XrmGetResource(re->xrdb,
-                                      "Xft.dpi", "Xft.Dpi", &type, &val);
-         }
-
-        if ((status) && (type))
-          {
-             if (!strcmp(type, "String"))
-               {
-                  const char *str, *dp;
-                  
-                  str = val.addr;
-                  dp = strchr(str, '.');
-                  if (!dp) dp = strchr(str, ',');
-                  
-                  if (dp)
-                    {
-                       int subdpi, len, i;
-                       char *buf;
-                       
-                       buf = alloca(dp - str + 1);
-                       strncpy(buf, str, dp - str);
-                       buf[dp - str] = 0;
-                       len = strlen(dp + 1);
-                       subdpi = atoi(dp + 1);
-                       
-                       if (len < 3)
-                         {
-                            for (i = len; i < 3; i++) subdpi *= 10;
-                         }
-                       else if (len > 3)
-                         {
-                            for (i = len; i > 3; i--) subdpi /= 10;
-                         }
-                       re->xr.dpi = atoi(buf) * 1000;
-                    }
-                  else
-                    re->xr.dpi = atoi(str) * 1000;
-               }
-          }
-        evas_common_font_dpi_set(re->xr.dpi / 1000);
-     }
- */
-   
    /* add a draw context if we dont have one */
    if (!e->engine.data.context)
      e->engine.data.context =
@@ -301,9 +193,6 @@ eng_output_free(void *data)
 
    re = (Render_Engine *)data;
    
-// NOTE: XrmGetDatabase() result is shared per connection, do not free it.
-//   if (re->xrdb) XrmDestroyDatabase(re->xrdb);
-   
    if (re->shbuf) evas_software_16_x11_x_output_buffer_free(re->shbuf, 0);
    if (re->clip_rects) XDestroyRegion(re->clip_rects);
    if (re->gc) XFreeGC(re->disp, re->gc);
@@ -711,15 +600,6 @@ static void
 module_close(Evas_Module *em __UNUSED__)
 {
   eina_log_domain_unregister(_evas_engine_soft16_x11_log_dom);
-/*   
-  if (xrdb_user.db)
-    {
-       XrmDestroyDatabase(xrdb_user.db);
-       xrdb_user.last_stat = 0;
-       xrdb_user.last_mtime = 0;
-       xrdb_user.db = NULL;
-    }
- */
 }
 
 static Evas_Module_Api evas_modapi =
index 46637fb..d69505e 100644 (file)
@@ -8,7 +8,8 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/modules/engines \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@
+@FRIBIDI_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@
 
 if BUILD_ENGINE_SOFTWARE_8
 
@@ -20,7 +21,7 @@ if !EVAS_STATIC_BUILD_SOFTWARE_8_X11
 pkgdir = $(libdir)/evas/modules/engines/software_8/$(MODULE_ARCH)
 pkg_LTLIBRARIES = module.la
 module_la_SOURCES = $(SOFTWARE_8_SOURCES)
-module_la_LIBADD = @EINA_LIBS@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index aac2b2c..700b63c 100644 (file)
@@ -9,7 +9,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/modules/engines/software_8 \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_engine_software_8_x11_cflags@
 
@@ -31,7 +31,7 @@ pkgdir = $(libdir)/evas/modules/engines/software_8_x11/$(MODULE_ARCH)
 pkg_LTLIBRARIES        = module.la
 
 module_la_SOURCES = $(SOFTWARE_8_X11_SOURCES)
-module_la_LIBADD = @EINA_LIBS@ $(SOFTWARE_8_X11_LIBADD) $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ $(SOFTWARE_8_X11_LIBADD) $(top_builddir)/src/lib/libevas.la
 #-lxcb-image -lxcb-shm -lxcb -lpixman-1
 module_la_LDFLAGS = -no-undefined -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
index ac8a9fe..c8e1090 100644 (file)
@@ -6,7 +6,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib \
 -I$(top_srcdir)/src/lib/include \
 -I$(top_srcdir)/src/modules/engines \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
@@ -32,7 +32,7 @@ pkgdir = $(libdir)/evas/modules/engines/software_ddraw/$(MODULE_ARCH)
 pkg_LTLIBRARIES = module.la
 module_la_SOURCES = $(SOFTWARE_DDRAW_SOURCES)
 module_la_CXXFLAGS = -fno-rtti -fno-exceptions
-module_la_LIBADD = @EINA_LIBS@ $(SOFTWARE_DDRAW_LIBADD) $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ $(SOFTWARE_DDRAW_LIBADD) $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = @lt_enable_auto_import@ -no-undefined -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index b5981af..296f141 100644 (file)
@@ -6,7 +6,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib \
 -I$(top_srcdir)/src/lib/include \
 -I$(top_srcdir)/src/modules/engines \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
@@ -31,7 +31,7 @@ if !EVAS_STATIC_BUILD_SOFTWARE_GDI
 pkgdir = $(libdir)/evas/modules/engines/software_gdi/$(MODULE_ARCH)
 pkg_LTLIBRARIES = module.la
 module_la_SOURCES = $(SOFTWARE_GDI_SOURCES)
-module_la_LIBADD = $(top_builddir)/src/lib/libevas.la @EINA_LIBS@ $(SOFTWARE_GDI_LIBADD)
+module_la_LIBADD = $(top_builddir)/src/lib/libevas.la @EVAS_GENERAL_LIBS@ $(SOFTWARE_GDI_LIBADD)
 module_la_LDFLAGS = @lt_enable_auto_import@ -no-undefined -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index f31810e..a8d56be 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 -I$(top_srcdir)/src/lib/cserve2 \
 -I$(top_srcdir)/src/modules/engines \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@
@@ -22,7 +22,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES  = $(SOFTWARE_GENERIC_SOURCES)
 
-module_la_LIBADD = @EINA_LIBS@ @dlopen_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @dlopen_libs@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
old mode 100644 (file)
new mode 100755 (executable)
index 9e1ff4b..7cc9118
@@ -297,15 +297,77 @@ eng_context_new(void *data __UNUSED__)
 }
 
 static void
-eng_context_free(void *data __UNUSED__, void *context)
+eng_context_clip_set(void *data __UNUSED__, void *context, int x, int y, int w, int h)
 {
-   evas_common_draw_context_free(context);
+   evas_common_draw_context_set_clip(context, x, y, w, h);
 }
 
 static void
-eng_context_clip_set(void *data __UNUSED__, void *context, int x, int y, int w, int h)
+eng_context_clip_image_unset(void *data __UNUSED__, void *context)
 {
-   evas_common_draw_context_set_clip(context, x, y, w, h);
+   RGBA_Draw_Context *ctx = context;
+
+   if (ctx->clip.mask)
+     {
+        Image_Entry *ie = ctx->clip.mask;
+#ifdef EVAS_CSERVE2
+        if (evas_cserve2_use_get())
+          evas_cache2_image_close(ie);
+        else
+#endif
+          evas_cache_image_drop(ie);
+        // Is the above code safe? Hmmm...
+        //evas_unref_queue_image_put(EVAS???, &ctx->clip.ie->cache_entry);
+        ctx->clip.mask = NULL;
+     }
+}
+
+static void
+eng_context_clip_image_set(void *data __UNUSED__, void *context, void *surface, int x, int y)
+{
+   RGBA_Draw_Context *ctx = context;
+   Eina_Bool noinc = EINA_FALSE;
+
+   if (ctx->clip.mask)
+     {
+        if (ctx->clip.mask != surface)
+          eng_context_clip_image_unset(data, context);
+        else
+          noinc = EINA_TRUE;
+     }
+
+   ctx->clip.mask = surface;
+   ctx->clip.mask_x = x;
+   ctx->clip.mask_y = y;
+
+   if (surface)
+     {
+        Image_Entry *ie = surface;
+        if (!noinc) ie->references++;
+        RECTS_CLIP_TO_RECT(ctx->clip.x, ctx->clip.y, ctx->clip.w, ctx->clip.h,
+                           x, y, ie->w, ie->h);
+     }
+}
+
+static void
+eng_context_clip_image_get(void *data EINA_UNUSED, void *context, void **ie, int *x, int *y)
+{
+   RGBA_Draw_Context *ctx = context;
+
+   if (ie) *ie = ctx->clip.mask;
+   if (x) *x = ctx->clip.mask_x;
+   if (y) *y = ctx->clip.mask_y;
+}
+
+static void
+eng_context_free(void *data, void *context)
+{
+   RGBA_Draw_Context *ctx = context;
+
+   if (!ctx) return;
+   if (ctx->clip.mask)
+     eng_context_clip_image_unset(data, context);
+   evas_common_draw_context_free(context);
 }
 
 static void
@@ -369,25 +431,6 @@ eng_context_multiplier_get(void *data __UNUSED__, void *context, int *r, int *g,
 }
 
 static void
-eng_context_mask_set(void *data __UNUSED__, void *context, void *mask, int x, int y, int w, int h)
-{
-   evas_common_draw_context_set_mask(context, mask, x, y, w, h);
-}
-
-static void
-eng_context_mask_unset(void *data __UNUSED__, void *context)
-{
-   evas_common_draw_context_unset_mask(context);
-}
-/*
-static void *
-eng_context_mask_get(void *data __UNUSED__, void *context)
-{
-   return ((RGBA_Draw_Context *)context)->mask.mask;
-}
-*/
-
-static void
 eng_context_cutout_add(void *data __UNUSED__, void *context, int x, int y, int w, int h)
 {
    evas_common_draw_context_add_cutout(context, x, y, w, h);
@@ -569,6 +612,7 @@ eng_image_alpha_set(void *data __UNUSED__, void *image, int has_alpha)
        im->cache_entry.flags.alpha = 0;
        return im;
      }
+   if (!im->image.data) evas_cache_image_load_data(&im->cache_entry);
    im = (RGBA_Image *) evas_cache_image_alone(&im->cache_entry);
    im->cache_entry.flags.alpha = has_alpha ? 1 : 0;
    evas_common_image_colorspace_dirty(im);
@@ -622,27 +666,13 @@ eng_image_native_set(void *data __UNUSED__, void *image, void *native __UNUSED__
    Evas_Native_Surface *ns = native;
    Image_Entry *im = image, *im2 = NULL;
 
-   if (!im)
-     {
-        if ((!ns) && (ns->data.x11.visual))
-          {
-             im = evas_cache_image_data(evas_common_image_cache_get(),
-                                        im->w, im->h,
-                                        ns->data.x11.visual, 1,
-                                        EVAS_COLORSPACE_ARGB8888);
-             return im;
-          }
-        else
-           return NULL;
-     }
-
-   if ((!ns) && (!im)) return im;
+   if (!im || !ns) return im;
 
    if (!ns) return im;
 
    im2 = evas_cache_image_data(evas_common_image_cache_get(),
                                im->w, im->h,
-                               ns->data.x11.visual, 1,
+                               NULL, 1,
                                EVAS_COLORSPACE_ARGB8888);
    evas_cache_image_drop(im);
    im = im2;
@@ -961,13 +991,18 @@ evas_software_image_map_draw(void *data, void *context, RGBA_Image *surface, RGB
        (m->pts[2 + offset].v == (int)(im->cache_entry.h << FP)) &&
        (m->pts[3 + offset].u == 0) &&
        (m->pts[3 + offset].v == (int)(im->cache_entry.h << FP)) &&
-       (m->pts[0 + offset].col == 0xffffffff) &&
-       (m->pts[1 + offset].col == 0xffffffff) &&
-       (m->pts[2 + offset].col == 0xffffffff) &&
-       (m->pts[3 + offset].col == 0xffffffff))
+       (m->pts[0 + offset].col == m->pts[1 + offset].col) &&
+       (m->pts[1 + offset].col == m->pts[2 + offset].col) &&
+       (m->pts[2 + offset].col == m->pts[3 + offset].col))  
      {
+        DATA32 col;
+        int a, r, g, b;
         int dx, dy, dw, dh;
 
+        eng_context_color_get(data, context, &r, &g, &b, &a);
+        col = MUL4_256(a, r, g, b, m->pts[0 + offset].col);
+        eng_context_color_set(data, context, R_VAL(&col), G_VAL(&col), B_VAL(&col), A_VAL(&col));
+
         dx = m->pts[0 + offset].x >> FP;
         dy = m->pts[0 + offset].y >> FP;
         dw = (m->pts[2 + offset].x >> FP) - dx;
@@ -976,6 +1011,8 @@ evas_software_image_map_draw(void *data, void *context, RGBA_Image *surface, RGB
           (data, context, surface, im,
            0, 0, im->cache_entry.w, im->cache_entry.h,
            dx, dy, dw, dh, smooth);
+
+        eng_context_color_set(data, context, r, g, b, a);
      }
    else
      {
@@ -1159,6 +1196,76 @@ eng_image_cache_get(void *data __UNUSED__)
    return evas_common_image_get_cache();
 }
 
+static Eina_Bool
+eng_pixel_alpha_get(RGBA_Image *im, int x, int y, DATA8 *alpha,
+                 int src_region_x, int src_region_y, int src_region_w, int src_region_h,
+                 int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h)
+{
+   int px, py, dx, dy, sx, sy, src_w, src_h;
+   double scale_w, scale_h;
+
+   if ((dst_region_x > x) || (x >= (dst_region_x + dst_region_w)) ||
+       (dst_region_y > y) || (y >= (dst_region_y + dst_region_h)))
+     {
+        *alpha = 0;
+        return EINA_FALSE;
+     }
+
+   src_w = im->cache_entry.w;
+   src_h = im->cache_entry.h;
+   if ((src_w == 0) || (src_h == 0))
+     {
+        *alpha = 0;
+        return EINA_TRUE;
+     }
+
+   EINA_SAFETY_ON_TRUE_GOTO(src_region_x < 0, error_oob);
+   EINA_SAFETY_ON_TRUE_GOTO(src_region_y < 0, error_oob);
+   EINA_SAFETY_ON_TRUE_GOTO(src_region_x + src_region_w > src_w, error_oob);
+   EINA_SAFETY_ON_TRUE_GOTO(src_region_y + src_region_h > src_h, error_oob);
+
+   scale_w = (double)dst_region_w / (double)src_region_w;
+   scale_h = (double)dst_region_h / (double)src_region_h;
+
+   /* point at destination */
+   dx = x - dst_region_x;
+   dy = y - dst_region_y;
+
+   /* point at source */
+   sx = dx / scale_w;
+   sy = dy / scale_h;
+
+   /* pixel point (translated) */
+   px = src_region_x + sx;
+   py = src_region_y + sy;
+   EINA_SAFETY_ON_TRUE_GOTO(px >= src_w, error_oob);
+   EINA_SAFETY_ON_TRUE_GOTO(py >= src_h, error_oob);
+
+   switch (im->cache_entry.space)
+     {
+     case EVAS_COLORSPACE_ARGB8888:
+       {
+          DATA32 *pixel = im->image.data;
+          pixel += ((py * src_w) + px);
+          *alpha = ((*pixel) >> 24) & 0xff;
+       }
+       break;
+
+     default:
+        ERR("Colorspace %d not supported.", im->cache_entry.space);
+        *alpha = 0;
+     }
+   return EINA_TRUE;
+
+ error_oob:
+   ERR("Invalid region src=(%d, %d, %d, %d), dst=(%d, %d, %d, %d), image=%dx%d",
+       src_region_x, src_region_y, src_region_w, src_region_h,
+       dst_region_x, dst_region_y, dst_region_w, dst_region_h,
+       src_w, src_h);
+   *alpha = 0;
+   return EINA_TRUE;
+}
+
 static Evas_Font_Set *
 eng_font_load(void *data __UNUSED__, const char *name, int size,
       Font_Rend_Flags wanted_rend)
@@ -1562,7 +1669,7 @@ eng_gl_surface_destroy(void *data __UNUSED__, void *surface)
 }
 
 static void *
-eng_gl_context_create(void *data __UNUSED__, void *share_context)
+eng_gl_context_create(void *data __UNUSED__, void *share_context, int version)
 {
 #ifdef EVAS_GL
    Render_Engine_GL_Context *ctx;
@@ -1690,14 +1797,14 @@ eng_gl_make_current(void *data __UNUSED__, void *surface, void *context)
 }
 
 // FIXME!!! Implement later
-static void *
+static const char *
 eng_gl_string_query(void *data __UNUSED__, int name __UNUSED__)
 {
    return NULL;
 }
 
 static void *
-eng_gl_proc_address_get(void *data __UNUSED__, const char *name)
+eng_gl_proc_address_get(void *data __UNUSED__, Evas_GL_Ext *ext __UNUSED__, const char *name)
 {
 #ifdef EVAS_GL
    if (_sym_OSMesaGetProcAddress) return _sym_OSMesaGetProcAddress(name);
@@ -1734,10 +1841,13 @@ eng_gl_native_surface_get(void *data __UNUSED__, void *surface, void *native_sur
 
 
 static void *
-eng_gl_api_get(void *data __UNUSED__)
+eng_gl_api_get(void *data __UNUSED__, int version)
 {
 #ifdef EVAS_GL
-   return &gl_funcs;
+   if (version == EVAS_GL_GLES_2_X)
+     return &gl_funcs;
+   else
+     return NULL;
 #else
    return NULL;
 #endif
@@ -1775,11 +1885,14 @@ static Evas_Func func =
      eng_canvas_alpha_get,
      eng_context_free,
      eng_context_clip_set,
+     eng_context_clip_image_set,
+     eng_context_clip_image_unset,
+     eng_context_clip_image_get,
      eng_context_clip_clip,
      eng_context_clip_unset,
      eng_context_clip_get,
-     eng_context_mask_set,
-     eng_context_mask_unset,
+     NULL, // deprecated old mask
+     NULL, // deprecated old mask
      eng_context_color_set,
      eng_context_color_get,
      eng_context_multiplier_set,
@@ -1863,6 +1976,7 @@ static Evas_Func func =
      eng_image_map_surface_new,
      eng_image_map_surface_free,
      eng_image_map_clean,
+     NULL, // eng_image_scaled_get - used for live scaling in GL only (fastpath)
      NULL, // eng_image_content_hint_set - software doesn't use it
      NULL, // eng_image_content_hint_get - software doesn't use it
      eng_font_pen_coords_get,
@@ -1875,6 +1989,7 @@ static Evas_Func func =
      eng_image_filtered_free,
 #endif   
      NULL, // need software mesa for gl rendering <- gl_surface_create
+     NULL, // need software mesa for gl rendering <- gl_pbuffer_surface_create
      NULL, // need software mesa for gl rendering <- gl_surface_destroy
      NULL, // need software mesa for gl rendering <- gl_context_create
      NULL, // need software mesa for gl rendering <- gl_context_destroy
@@ -1883,7 +1998,17 @@ static Evas_Func func =
      NULL, // need software mesa for gl rendering <- gl_proc_address_get
      NULL, // need software mesa for gl rendering <- gl_native_surface_get
      NULL, // need software mesa for gl rendering <- gl_api_get
-     NULL, // need software mesa for gl rendering <- gl_img_obj_set
+     NULL, // need software mesa for gl rendering <- gl_direct_override
+     NULL, // need software mesa for gl rendering <- gl_get_pixels_set
+     NULL, // need software mesa for gl rendering <- gl_surface_lock
+     NULL, // need software mesa for gl rendering <- gl_surface_read_pixel
+     NULL, // need software mesa for gl rendering <- gl_surface_unlock
+     NULL, // need software mesa for gl rendering <- gl_error_get
+     NULL, // need software mesa for gl rendering <- gl_current_context_get
+     NULL, // need software mesa for gl rendering <- gl_current_surface_get
+     NULL, // need software mesa for gl rendering <- gl_rotation_angle_get
+     NULL, // need software mesa for gl rendering <- gl_surface_query
+     NULL, // need software mesa for gl rendering <- gl_surface_direct_renderable_get
      eng_image_load_error_get,
      eng_font_run_font_end_get,
      eng_image_animated_get,
@@ -1892,7 +2017,17 @@ static Evas_Func func =
      eng_image_animated_loop_count_get,
      eng_image_animated_frame_duration_get,
      eng_image_animated_frame_set,
-     NULL
+     NULL, // image_max_size_get
+     NULL, // eng_context_flush - software doesn't use it
+     NULL, // eng_gl_ext_buffer_age_get
+     NULL, // eng_gl_ext_update_region_get
+     NULL, // eng_gl_ext_surface_from_native_create
+     NULL, // eng_gl_ext_surface_is_texture
+     NULL, // get_pixels_render_post - opengl_x11, wayland only use it
+     NULL, // gl_engine_init
+     NULL, // gl_engine_shutdown
+     NULL, // image_direct_set
+     NULL, // image_direct_get
    /* FUTURE software generic calls go here */
 };
 
@@ -2521,25 +2656,34 @@ patch_gles_shader(const char *source, int length, int *patched_len)
           {
              if (!strncmp(p, "gl_MaxVertexUniformVectors", 26))
                {
-                  p = "(gl_MaxVertexUniformComponents / 4)";
+                  free(p);
+                  p = strdup("(gl_MaxVertexUniformComponents / 4)");
                }
              else if (!strncmp(p, "gl_MaxFragmentUniformVectors", 28))
                {
-                  p = "(gl_MaxFragmentUniformComponents / 4)";
+                  free(p);
+                  p = strdup("(gl_MaxFragmentUniformComponents / 4)");
                }
              else if (!strncmp(p, "gl_MaxVaryingVectors", 20))
                {
-                  p = "(gl_MaxVaryingFloats / 4)";
+                  free(p);
+                  p = strdup("(gl_MaxVaryingFloats / 4)");
                }
 
              int new_len = strlen(p);
              if (*patched_len + new_len > patched_size)
                {
-                  patched_size *= 2;
-                  patched = realloc(patched, patched_size + 1);
+                  char *tmp;
 
-                  if (!patched)
-                     return NULL;
+                  patched_size *= 2;
+                  tmp = realloc(patched, patched_size + 1);
+                  if (!tmp)
+                    {
+                       free(patched);
+                       free(p);
+                       return NULL;
+                    }
+                  patched = tmp;
                }
 
              memcpy(patched + *patched_len, p, new_len);
@@ -2827,7 +2971,15 @@ gl_lib_init(void)
 {
 #ifdef EVAS_GL
    // dlopen OSMesa
-   gl_lib_handle = dlopen("libOSMesa.so.1", RTLD_NOW);
+   gl_lib_handle = dlopen("libOSMesa.so.9", RTLD_NOW);
+   if (!gl_lib_handle) gl_lib_handle = dlopen("libOSMesa.so.8", RTLD_NOW);
+   if (!gl_lib_handle) gl_lib_handle = dlopen("libOSMesa.so.7", RTLD_NOW);
+   if (!gl_lib_handle) gl_lib_handle = dlopen("libOSMesa.so.6", RTLD_NOW);
+   if (!gl_lib_handle) gl_lib_handle = dlopen("libOSMesa.so.5", RTLD_NOW);
+   if (!gl_lib_handle) gl_lib_handle = dlopen("libOSMesa.so.4", RTLD_NOW);
+   if (!gl_lib_handle) gl_lib_handle = dlopen("libOSMesa.so.3", RTLD_NOW);
+   if (!gl_lib_handle) gl_lib_handle = dlopen("libOSMesa.so.2", RTLD_NOW);
+   if (!gl_lib_handle) gl_lib_handle = dlopen("libOSMesa.so.1", RTLD_NOW);
    if (!gl_lib_handle) gl_lib_handle = dlopen("libOSMesa.so", RTLD_NOW);
    if (!gl_lib_handle)
      {
index e42c10a..b6efc21 100644 (file)
@@ -47,6 +47,15 @@ struct _Evas_Engine_Info_Software_X11
 
    /* non-blocking or blocking mode */
    Evas_Engine_Render_Mode render_mode;
+
+   /* TIZEN ONLY
+    * Disable sync draw done from application side when it is needed.
+    * Currently this is set true when a back-end engine uses DRI2.
+    * This depends on engine so we need to check it from evas engine.
+    */
+   Eina_Bool disable_sync_draw_done : 1;
+
+   unsigned int atom;
 };
 
 #endif
index 7c15a27..32a31e9 100644 (file)
@@ -3,7 +3,12 @@ MAINTAINERCLEANFILES = Makefile.in
 
 if BUILD_ENGINE_SOFTWARE_X11
 
-SOFTWARE_X11_SOURCES = evas_engine.c
+SOFTWARE_X11_SOURCES = \
+evas_engine.c \
+evas_x_egl.c \
+evas_native_buffer.c \
+evas_native_tbm.c \
+evas_x_egl.h
 
 if BUILD_ENGINE_SOFTWARE_XLIB
 
@@ -15,7 +20,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/modules/engines \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_engine_software_xlib_cflags@
 
@@ -23,9 +28,15 @@ SOFTWARE_X11_SOURCES += \
 evas_xlib_outbuf.c \
 evas_xlib_buffer.c \
 evas_xlib_color.c \
-evas_xlib_main.c
+evas_xlib_image.c \
+evas_xlib_image.h \
+evas_xlib_main.c \
+evas_xlib_swapbuf.c \
+evas_xlib_swapbuf.h \
+evas_xlib_swapper.c \
+evas_xlib_swapper.h
 
-SOFTWARE_X11_LIBADD = @FREETYPE_LIBS@ @EINA_LIBS@ @evas_engine_software_xlib_libs@
+SOFTWARE_X11_LIBADD = @FREETYPE_LIBS@ @EVAS_GENERAL_LIBS@ @evas_engine_software_xlib_libs@ @dlopen_libs@
 
 endif
 
@@ -39,7 +50,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/modules/engines \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @evas_engine_software_xcb_cflags@
 
 SOFTWARE_X11_SOURCES += \
@@ -49,7 +60,7 @@ evas_xcb_buffer.c \
 evas_xcb_color.c \
 evas_xcb_main.c
 
-SOFTWARE_X11_LIBADD = @FREETYPE_LIBS@ @PIXMAN_LIBS@ @EINA_LIBS@ @evas_engine_software_xcb_libs@
+SOFTWARE_X11_LIBADD = @FREETYPE_LIBS@ @PIXMAN_LIBS@ @EVAS_GENERAL_LIBS@ @evas_engine_software_xcb_libs@ @dlopen_libs@
 
 endif
 
old mode 100644 (file)
new mode 100755 (executable)
index 94e78ac..c5a448a
@@ -6,7 +6,9 @@
 
 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
 # include "evas_xlib_outbuf.h"
+# include "evas_xlib_swapbuf.h"
 # include "evas_xlib_color.h"
+# include "evas_xlib_image.h"
 #endif
 
 #ifdef BUILD_ENGINE_SOFTWARE_XCB
 # include "evas_xcb_xdefaults.h"
 #endif
 
+#include "evas_x_egl.h"
+
 int _evas_engine_soft_x11_log_dom = -1;
 
 /* function tables - filled in later (func and parent func) */
 static Evas_Func func, pfunc;
 
-#ifdef BUILD_ENGINE_SOFTWARE_XLIB
-/*
-struct xrdb_user
-{
-   time_t last_stat;
-   time_t last_mtime;
-   XrmDatabase db;
-};
-static struct xrdb_user xrdb_user = {0, 0, NULL};
-
-static Eina_Bool
-xrdb_user_query(const char *name, const char *cls, char **type, XrmValue *val)
-{
-   time_t last, now;
-
-   last = xrdb_user.last_stat;
-   now = time(NULL);
-
-   xrdb_user.last_stat = now;
-   if (last != now) // don't stat() more than once every second
-     {
-       struct stat st;
-       const char *home;
-       char tmp[PATH_MAX];
-
-        if (!(home = getenv("HOME"))) 
-          goto failed;
-
-       snprintf(tmp, sizeof(tmp), "%s/.Xdefaults", home);
-       if (stat(tmp, &st) != 0) goto failed;
-       if (xrdb_user.last_mtime != st.st_mtime)
-         {
-            if (xrdb_user.db) XrmDestroyDatabase(xrdb_user.db);
-            xrdb_user.db = XrmGetFileDatabase(tmp);
-            if (!xrdb_user.db) goto failed;
-            xrdb_user.last_mtime = st.st_mtime;
-         }
-     }
-
-   if (!xrdb_user.db) return EINA_FALSE;
-   return XrmGetResource(xrdb_user.db, name, cls, type, val);
-
- failed:
-   if (xrdb_user.db)
-     {
-       XrmDestroyDatabase(xrdb_user.db);
-       xrdb_user.db = NULL;
-     }
-   xrdb_user.last_mtime = 0;
-   return EINA_FALSE;
-}
-*/
-#endif
-
 /* engine struct data */
 typedef struct _Render_Engine Render_Engine;
 
@@ -82,17 +32,11 @@ struct _Render_Engine
    Tilebuf *tb;
    Outbuf *ob;
    Tilebuf_Rect *rects;
+   Tilebuf_Rect *rects_prev[4];
    Eina_Inlist *cur_rect;
+   short mode;
    unsigned char end : 1;
-/*
-#ifdef BUILD_ENGINE_SOFTWARE_XLIB
-   XrmDatabase xrdb;
-#endif
-   struct 
-     {
-        int dpi;
-     } xr;
- */
+   unsigned char lost_back : 1;
    void (*outbuf_free)(Outbuf *ob);
    void (*outbuf_reconfigure)(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth);
    int (*outbuf_get_rot)(Outbuf *ob);
@@ -101,7 +45,14 @@ struct _Render_Engine
    void (*outbuf_free_region_for_update)(Outbuf *ob, RGBA_Image *update);
    void (*outbuf_flush)(Outbuf *ob);
    void (*outbuf_idle_flush)(Outbuf *ob);
+   int (*outbuf_swap_mode_get)(Outbuf *ob);
    Eina_Bool (*outbuf_alpha_get)(Outbuf *ob);
+   
+   struct {
+      void *disp;
+      void *config;
+      void *surface;
+   } egl;
 };
 
 /* prototypes we will use here */
@@ -122,10 +73,88 @@ static void *eng_output_redraws_next_update_get(void *data, int *x, int *y, int
 static void eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h);
 static void eng_output_flush(void *data);
 static void eng_output_idle_flush(void *data);
+static void *eng_image_native_set(void *data, void *image, void *native);
+static void *eng_image_native_get(void *data __UNUSED__, void *image);
+static void eng_image_draw(void *data, void *context, void *surface, void *image,
+                           int src_x, int src_y, int src_w, int src_h,
+                           int dst_x, int dst_y, int dst_w, int dst_h,
+                           int smooth);
 
 /* internal engine routines */
 
 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
+
+/*
+static void *
+_output_egl_setup(int w, int h, int rot, Display *disp, Drawable draw,
+                  Visual *vis, Colormap cmap, int depth, int debug,
+                  int grayscale, int max_colors, Pixmap mask,
+                  int shape_dither, int destination_alpha)
+{
+   Render_Engine *re;
+   void *ptr;
+   int stride = 0;
+   
+   if (depth != 32) return NULL;
+   if (mask) return NULL;
+   if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL;
+   re->egl.disp = _egl_x_disp_get(disp);
+   if (!re->egl.disp)
+     {
+        free(re);
+        return NULL;
+     }
+   re->egl.config = _egl_x_disp_choose_config(re->egl.disp);
+   if (!re->egl.config)
+     {
+        _egl_x_disp_terminate(re->egl.disp);
+        free(re);
+        return NULL;
+     }
+   re->egl.surface = _egl_x_win_surf_new(re->egl.disp, draw, re->egl.config);
+   if (!re->egl.surface)
+     {
+        _egl_x_disp_terminate(re->egl.disp);
+        free(re);
+        return NULL;
+     }
+   ptr = _egl_x_surf_map(re->egl.disp, re->egl.surface, &stride);
+   if (!ptr)
+     {
+        _egl_x_win_surf_free(re->egl.disp, re->egl.surface);
+        _egl_x_disp_terminate(re->egl.disp);
+        free(re);
+        return NULL;
+     }
+   _egl_x_surf_unmap(re->egl.disp, re->egl.surface);
+   
+   re->ob = 
+     evas_software_egl_outbuf_setup_x(w, h, rot, OUTBUF_DEPTH_INHERIT, disp, 
+                                       draw, vis, cmap, depth, grayscale,
+                                       max_colors, mask, shape_dither,
+                                       destination_alpha);
+   
+   re->tb = evas_common_tilebuf_new(w, h);
+   if (!re->tb)
+     {
+       evas_software_xlib_outbuf_free(re->ob);
+       free(re);
+       return NULL;
+     }
+   evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
+   
+   return re;
+}
+*/
+   
+static void
+_output_egl_shutdown(Render_Engine *re)
+{
+   if (!re->egl.disp) return;
+   _egl_x_win_surf_free(re->egl.disp, re->egl.surface);
+   _egl_x_disp_terminate(re->egl.disp);
+}
+
 static void *
 _output_xlib_setup(int w, int h, int rot, Display *disp, Drawable draw,
                    Visual *vis, Colormap cmap, int depth, int debug,
@@ -133,66 +162,13 @@ _output_xlib_setup(int w, int h, int rot, Display *disp, Drawable draw,
                    int shape_dither, int destination_alpha)
 {
    Render_Engine *re;
-//   int status;
-//   char *type = NULL;
-//   XrmValue val;
 
    if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL;
 
    evas_software_xlib_x_init();
    evas_software_xlib_x_color_init();
    evas_software_xlib_outbuf_init();
-/*
-   re->xr.dpi = 75000; // dpy * 1000
 
-   status = xrdb_user_query("Xft.dpi", "Xft.Dpi", &type, &val);
-   if ((!status) || (!type))
-     {
-        if (!re->xrdb) re->xrdb = XrmGetDatabase(disp);
-        if (re->xrdb)
-          status = XrmGetResource(re->xrdb,
-                                  "Xft.dpi", "Xft.Dpi", &type, &val);
-     }
-
-   if ((status) && (type))
-     {
-        if (!strcmp(type, "String"))
-          {
-             const char *str, *dp;
-                  
-             str = val.addr;
-             dp = strchr(str, '.');
-             if (!dp) dp = strchr(str, ',');
-
-             if (dp)
-               {
-                  int subdpi, len, i;
-                  char *buf;
-                       
-                  buf = alloca(dp - str + 1);
-                  strncpy(buf, str, dp - str);
-                  buf[dp - str] = 0;
-                  len = strlen(dp + 1);
-                  subdpi = atoi(dp + 1);
-
-                  if (len < 3)
-                    {
-                       for (i = len; i < 3; i++) 
-                         subdpi *= 10;
-                    }
-                  else if (len > 3)
-                    {
-                       for (i = len; i > 3; i--) 
-                         subdpi /= 10;
-                    }
-                  re->xr.dpi = atoi(buf) * 1000;
-               }
-             else
-               re->xr.dpi = atoi(str) * 1000;
-             evas_common_font_dpi_set(re->xr.dpi / 1000);
-          }
-     }
- */
    re->ob = 
      evas_software_xlib_outbuf_setup_x(w, h, rot, OUTBUF_DEPTH_INHERIT, disp, 
                                        draw, vis, cmap, depth, grayscale,
@@ -227,6 +203,44 @@ _output_xlib_setup(int w, int h, int rot, Display *disp, Drawable draw,
    evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
    return re;
 }
+
+static void *
+_output_swapbuf_setup(int w, int h, int rot, Display *disp, Drawable draw,
+                      Visual *vis, Colormap cmap, int depth,
+                      int debug EINA_UNUSED,
+                      int grayscale, int max_colors, Pixmap mask,
+                      int shape_dither, int destination_alpha)
+{
+   Render_Engine *re;
+
+   if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL;
+
+   evas_software_xlib_x_init();
+   evas_software_xlib_x_color_init();
+   evas_software_xlib_swapbuf_init();
+   
+   re->ob = 
+     evas_software_xlib_swapbuf_setup_x(w, h, rot, OUTBUF_DEPTH_INHERIT, disp, 
+                                        draw, vis, cmap, depth, grayscale,
+                                        max_colors, mask, shape_dither,
+                                        destination_alpha);
+   if (!re->ob)
+     {
+       free(re);
+       return NULL;
+     }
+
+   re->tb = evas_common_tilebuf_new(w, h);
+   if (!re->tb)
+     {
+       evas_software_xlib_swapbuf_free(re->ob);
+       free(re);
+       return NULL;
+     }
+
+   evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
+   return re;
+}
 #endif
 
 #ifdef BUILD_ENGINE_SOFTWARE_XCB
@@ -238,23 +252,12 @@ _output_xcb_setup(int w, int h, int rot, xcb_connection_t *conn,
                   int shape_dither, int destination_alpha)
 {
    Render_Engine *re;
-//   int v = 0;
 
    if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL;
 
    evas_software_xcb_init();
    evas_software_xcb_color_init();
    evas_software_xcb_outbuf_init();
-/*
-   // FIXME: re->xrdb
-   _evas_xcb_xdefaults_init();
-   v = _evas_xcb_xdefaults_int_get("Xft", "dpi");
-   _evas_xcb_xdefaults_shutdown();
-   if (v) re->xr.dpi = (v * 1000);
-   else re->xr.dpi = 75000; // dpy * 1000
-
-   evas_common_font_dpi_set(re->xr.dpi / 1000);
- */
    re->ob = 
      evas_software_xcb_outbuf_setup(w, h, rot, OUTBUF_DEPTH_INHERIT, conn, 
                                     screen, draw, vis, cmap, depth,
@@ -436,6 +439,7 @@ eng_setup(Evas *e, void *in)
    Render_Engine *re = NULL;
 
    info = (Evas_Engine_Info_Software_X11 *)in;
+   EINA_LOG_DBG("[ evasgl_dbg ]: Evas_Engine Info -> Software_X11");
    if (!e->engine.data.output)
      {
         /* if we haven't initialized - init (automatic abort if already done) */
@@ -454,28 +458,61 @@ eng_setup(Evas *e, void *in)
 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
         if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
           {
-             re = _output_xlib_setup(e->output.w, e->output.h,
-                                     info->info.rotation, info->info.connection,
-                                     info->info.drawable, info->info.visual,
-                                     info->info.colormap,
-                                     info->info.depth, info->info.debug,
-                                     info->info.alloc_grayscale,
-                                     info->info.alloc_colors_max,
-                                     info->info.mask, info->info.shape_dither,
-                                     info->info.destination_alpha);
-
-             re->outbuf_free = evas_software_xlib_outbuf_free;
-             re->outbuf_reconfigure = evas_software_xlib_outbuf_reconfigure;
-             re->outbuf_get_rot = evas_software_xlib_outbuf_get_rot;
-             re->outbuf_new_region_for_update = 
-               evas_software_xlib_outbuf_new_region_for_update;
-             re->outbuf_push_updated_region = 
-               evas_software_xlib_outbuf_push_updated_region;
-             re->outbuf_free_region_for_update = 
-               evas_software_xlib_outbuf_free_region_for_update;
-             re->outbuf_flush = evas_software_xlib_outbuf_flush;
-             re->outbuf_idle_flush = evas_software_xlib_outbuf_idle_flush;
-            re->outbuf_alpha_get = evas_software_xlib_outbuf_alpha_get;
+             static int try_swapbuf = -1;
+             
+             if (try_swapbuf == -1)
+               {
+                  if (getenv("EVAS_NO_DRI_SWAPBUF")) try_swapbuf = 0;
+                  else try_swapbuf = 1;
+               }
+             if (try_swapbuf)
+               re = _output_swapbuf_setup(e->output.w, e->output.h,
+                                          info->info.rotation, info->info.connection,
+                                          info->info.drawable, info->info.visual,
+                                          info->info.colormap,
+                                          info->info.depth, info->info.debug,
+                                          info->info.alloc_grayscale,
+                                          info->info.alloc_colors_max,
+                                          info->info.mask, info->info.shape_dither,
+                                          info->info.destination_alpha);
+             if (re)
+               {
+                  info->disable_sync_draw_done      = EINA_TRUE; // TIZEN ONLY
+                  re->outbuf_free                   = evas_software_xlib_swapbuf_free;
+                  re->outbuf_reconfigure            = evas_software_xlib_swapbuf_reconfigure;
+                  re->outbuf_get_rot                = evas_software_xlib_swapbuf_get_rot;
+                  re->outbuf_new_region_for_update  = evas_software_xlib_swapbuf_new_region_for_update;
+                  re->outbuf_push_updated_region    = evas_software_xlib_swapbuf_push_updated_region;
+                  re->outbuf_free_region_for_update = evas_software_xlib_swapbuf_free_region_for_update;
+                  re->outbuf_flush                  = evas_software_xlib_swapbuf_flush;
+                  re->outbuf_idle_flush             = evas_software_xlib_swapbuf_idle_flush;
+                  re->outbuf_alpha_get              = evas_software_xlib_swapbuf_alpha_get;
+                  re->outbuf_swap_mode_get          = evas_software_xlib_swapbuf_buffer_state_get;
+               }
+
+             if (!re)
+               {
+                  re = _output_xlib_setup(e->output.w, e->output.h,
+                                          info->info.rotation, info->info.connection,
+                                          info->info.drawable, info->info.visual,
+                                          info->info.colormap,
+                                          info->info.depth, info->info.debug,
+                                          info->info.alloc_grayscale,
+                                          info->info.alloc_colors_max,
+                                          info->info.mask, info->info.shape_dither,
+                                          info->info.destination_alpha);
+                  
+                  re->outbuf_free                   = evas_software_xlib_outbuf_free;
+                  re->outbuf_reconfigure            = evas_software_xlib_outbuf_reconfigure;
+                  re->outbuf_get_rot                = evas_software_xlib_outbuf_get_rot;
+                  re->outbuf_new_region_for_update  = evas_software_xlib_outbuf_new_region_for_update;
+                  re->outbuf_push_updated_region    = evas_software_xlib_outbuf_push_updated_region;
+                  re->outbuf_free_region_for_update = evas_software_xlib_outbuf_free_region_for_update;
+                  re->outbuf_flush                  = evas_software_xlib_outbuf_flush;
+                  re->outbuf_idle_flush             = evas_software_xlib_outbuf_idle_flush;
+                  re->outbuf_alpha_get              = evas_software_xlib_outbuf_alpha_get;
+                  re->outbuf_swap_mode_get          = NULL;
+               }
           }
 #endif
 
@@ -492,18 +529,16 @@ eng_setup(Evas *e, void *in)
                                     info->info.mask, info->info.shape_dither,
                                     info->info.destination_alpha);
 
-             re->outbuf_free = evas_software_xcb_outbuf_free;
-             re->outbuf_reconfigure = evas_software_xcb_outbuf_reconfigure;
-             re->outbuf_get_rot = evas_software_xcb_outbuf_rotation_get;
-             re->outbuf_new_region_for_update = 
-               evas_software_xcb_outbuf_new_region_for_update;
-             re->outbuf_push_updated_region = 
-               evas_software_xcb_outbuf_push_updated_region;
-             re->outbuf_free_region_for_update = 
-               evas_software_xcb_outbuf_free_region_for_update;
-             re->outbuf_flush = evas_software_xcb_outbuf_flush;
-             re->outbuf_idle_flush = evas_software_xcb_outbuf_idle_flush;
-            re->outbuf_alpha_get = evas_software_xcb_outbuf_alpha_get;
+             re->outbuf_free                   = evas_software_xcb_outbuf_free;
+             re->outbuf_reconfigure            = evas_software_xcb_outbuf_reconfigure;
+             re->outbuf_get_rot                = evas_software_xcb_outbuf_rotation_get;
+             re->outbuf_new_region_for_update  = evas_software_xcb_outbuf_new_region_for_update;
+             re->outbuf_push_updated_region    = evas_software_xcb_outbuf_push_updated_region;
+             re->outbuf_free_region_for_update = evas_software_xcb_outbuf_free_region_for_update;
+             re->outbuf_flush                  = evas_software_xcb_outbuf_flush;
+             re->outbuf_idle_flush             = evas_software_xcb_outbuf_idle_flush;
+            re->outbuf_alpha_get              = evas_software_xcb_outbuf_alpha_get;
+             re->outbuf_swap_mode_get          = NULL;
           }
 #endif
 
@@ -514,28 +549,49 @@ eng_setup(Evas *e, void *in)
        int ponebuf = 0;
 
        re = e->engine.data.output;
-       ponebuf = re->ob->onebuf;
+        if ((re) && (re->ob)) ponebuf = re->ob->onebuf;
 
 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
         if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
           {
-             evas_software_xlib_outbuf_free(re->ob);
-             re->ob = 
-               evas_software_xlib_outbuf_setup_x(e->output.w, e->output.h,
-                                                 info->info.rotation,
-                                                 OUTBUF_DEPTH_INHERIT,
-                                                 info->info.connection,
-                                                 info->info.drawable,
-                                                 info->info.visual,
-                                                 info->info.colormap,
-                                                 info->info.depth,
-                                                 info->info.alloc_grayscale,
-                                                 info->info.alloc_colors_max,
-                                                 info->info.mask,
-                                                 info->info.shape_dither,
-                                                 info->info.destination_alpha);
-
-             evas_software_xlib_outbuf_debug_set(re->ob, info->info.debug);
+             // XXX
+             re->outbuf_free(re->ob);
+
+             if (re->outbuf_free == evas_software_xlib_swapbuf_free)
+               {
+                  re->ob = 
+                    evas_software_xlib_swapbuf_setup_x(e->output.w, e->output.h,
+                                                       info->info.rotation,
+                                                       OUTBUF_DEPTH_INHERIT,
+                                                       info->info.connection,
+                                                       info->info.drawable,
+                                                       info->info.visual,
+                                                       info->info.colormap,
+                                                       info->info.depth,
+                                                       info->info.alloc_grayscale,
+                                                       info->info.alloc_colors_max,
+                                                       info->info.mask,
+                                                       info->info.shape_dither,
+                                                       info->info.destination_alpha);
+               }
+             else
+               {
+                  re->ob = 
+                    evas_software_xlib_outbuf_setup_x(e->output.w, e->output.h,
+                                                      info->info.rotation,
+                                                      OUTBUF_DEPTH_INHERIT,
+                                                      info->info.connection,
+                                                      info->info.drawable,
+                                                      info->info.visual,
+                                                      info->info.colormap,
+                                                      info->info.depth,
+                                                      info->info.alloc_grayscale,
+                                                      info->info.alloc_colors_max,
+                                                      info->info.mask,
+                                                      info->info.shape_dither,
+                                                      info->info.destination_alpha);
+                  evas_software_xlib_outbuf_debug_set(re->ob, info->info.debug);
+               }
           }
 #endif
 
@@ -558,11 +614,10 @@ eng_setup(Evas *e, void *in)
                                               info->info.mask,
                                               info->info.shape_dither,
                                               info->info.destination_alpha);
-
              evas_software_xcb_outbuf_debug_set(re->ob, info->info.debug);
           }
 #endif
-       re->ob->onebuf = ponebuf;
+        if ((re) && (re->ob)) re->ob->onebuf = ponebuf;
      }
    if (!e->engine.data.output) return 0;
    if (!e->engine.data.context) 
@@ -581,16 +636,16 @@ eng_output_free(void *data)
 {
    Render_Engine *re;
 
-#ifdef BUILD_ENGINE_SOFTWARE_XLIB
-// NOTE: XrmGetDatabase() result is shared per connection, do not free it.
-//   if (re->xrdb) XrmDestroyDatabase(re->xrdb);
-#endif
-
    if ((re = (Render_Engine *)data))
      {
         re->outbuf_free(re->ob);
         evas_common_tilebuf_free(re->tb);
         if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
+        if (re->rects_prev[0]) evas_common_tilebuf_free_render_rects(re->rects_prev[0]);
+        if (re->rects_prev[1]) evas_common_tilebuf_free_render_rects(re->rects_prev[1]);
+        if (re->rects_prev[2]) evas_common_tilebuf_free_render_rects(re->rects_prev[2]);
+        if (re->rects_prev[3]) evas_common_tilebuf_free_render_rects(re->rects_prev[3]);
+        _output_egl_shutdown(re);
         free(re);
      }
 
@@ -648,41 +703,198 @@ eng_output_redraws_clear(void *data)
    evas_common_tilebuf_clear(re->tb);
 }
 
+static Tilebuf_Rect *
+_merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3, Tilebuf_Rect *r4)
+{
+   Tilebuf_Rect *r, *rects;
+//   int px1, py1, px2, py2;
+   
+   if (r1)
+     {
+        EINA_INLIST_FOREACH(EINA_INLIST_GET(r1), r)
+          {
+             evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
+          }
+     }
+   if (r2)
+     {
+        EINA_INLIST_FOREACH(EINA_INLIST_GET(r2), r)
+          {
+             evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
+          }
+     }
+   if (r3)
+     {
+        EINA_INLIST_FOREACH(EINA_INLIST_GET(r3), r)
+          {
+             evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
+          }
+     }
+
+   if (r4)
+     {
+        EINA_INLIST_FOREACH(EINA_INLIST_GET(r4), r)
+          {
+             evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
+          }
+     }
+
+   rects = evas_common_tilebuf_get_render_rects(tb);
+
+/*   
+   // bounding box -> make a bounding box single region update of all regions.
+   // yes we could try and be smart and figure out size of regions, how far
+   // apart etc. etc. to try and figure out an optimal "set". this is a tradeoff
+   // between multiple update regions to render and total pixels to render.
+   if (rects)
+     {
+        px1 = rects->x; py1 = rects->y;
+        px2 = rects->x + rects->w; py2 = rects->y + rects->h;
+        EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r)
+          {
+             if (r->x < x1) px1 = r->x;
+             if (r->y < y1) py1 = r->y;
+             if ((r->x + r->w) > x2) px2 = r->x + r->w;
+             if ((r->y + r->h) > y2) py2 = r->y + r->h;
+          }
+        evas_common_tilebuf_free_render_rects(rects);
+        rects = calloc(1, sizeof(Tilebuf_Rect));
+        if (rects)
+          {
+             rects->x = px1;
+             rects->y = py1;
+             rects->w = px2 - px1;
+             rects->h = py2 - py1;
+          }
+     }
+ */
+   evas_common_tilebuf_clear(tb);
+   return rects;
+}
+
+
 static void *
 eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
 {
    Render_Engine *re;
    RGBA_Image *surface;
    Tilebuf_Rect *rect;
-   int ux, uy, uw, uh;
-
+   Eina_Bool first_rect = EINA_FALSE;
+
+#define CLEAR_PREV_RECTS(x) \
+   do { \
+      if (re->rects_prev[x]) \
+        evas_common_tilebuf_free_render_rects(re->rects_prev[x]); \
+      re->rects_prev[x] = NULL; \
+   } while (0)
+   
    re = (Render_Engine *)data;
    if (re->end)
      {
        re->end = 0;
        return NULL;
      }
+   
    if (!re->rects)
      {
+        int mode = MODE_COPY;
+
        re->rects = evas_common_tilebuf_get_render_rects(re->tb);
-       re->cur_rect = EINA_INLIST_GET(re->rects);
+        if (re->rects)
+          {
+             if (re->lost_back)
+               {
+                  /* if we lost our backbuffer since the last frame redraw all */
+                  re->lost_back = 0;
+                  evas_common_tilebuf_add_redraw(re->tb, 0, 0, re->ob->w, re->ob->h);
+                  evas_common_tilebuf_free_render_rects(re->rects);
+                  re->rects = evas_common_tilebuf_get_render_rects(re->tb);
+               }
+             /* ensure we get rid of previous rect lists we dont need if mode
+              * changed/is appropriate */
+             evas_common_tilebuf_clear(re->tb);
+             CLEAR_PREV_RECTS(3);
+             re->rects_prev[3] = re->rects_prev[2];
+             re->rects_prev[2] = re->rects_prev[1];
+             re->rects_prev[1] = re->rects_prev[0];
+             re->rects_prev[0] = re->rects;
+             re->rects = NULL;
+             if (re->outbuf_swap_mode_get) mode = re->outbuf_swap_mode_get(re->ob);
+             re->mode = mode;
+
+             switch (re->mode)
+               {
+                case MODE_FULL:
+                case MODE_COPY: // no prev rects needed
+                  re->rects = _merge_rects(re->tb, re->rects_prev[0], NULL, NULL, NULL);
+                  break;
+                case MODE_DOUBLE: // double mode - only 1 level of prev rect
+                  re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], NULL, NULL);
+                  break;
+                case MODE_TRIPLE: // triple mode - 2 levels of prev rect
+                  re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2], NULL);
+                  break;
+                case MODE_QUADRUPLE: // keep all
+                  re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2], re->rects_prev[3]);
+                  break;
+                default:
+                  break;
+               }
+             first_rect = EINA_TRUE;
+          }
+        evas_common_tilebuf_clear(re->tb);
+        re->cur_rect = EINA_INLIST_GET(re->rects);
      }
    if (!re->cur_rect) return NULL;
    rect = (Tilebuf_Rect *)re->cur_rect;
-   ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h;
-   re->cur_rect = re->cur_rect->next;
-   if (!re->cur_rect)
+   if (re->rects)
      {
-       evas_common_tilebuf_free_render_rects(re->rects);
-       re->rects = NULL;
-       re->end = 1;
+        switch (re->mode)
+          {
+           case MODE_COPY:
+           case MODE_DOUBLE:
+           case MODE_TRIPLE:
+           case MODE_QUADRUPLE:
+             rect = (Tilebuf_Rect *)re->cur_rect;
+             *x = rect->x;
+             *y = rect->y;
+             *w = rect->w;
+             *h = rect->h;
+             *cx = rect->x;
+             *cy = rect->y;
+             *cw = rect->w;
+             *ch = rect->h;
+             re->cur_rect = re->cur_rect->next;
+             break;
+           case MODE_FULL:
+             re->cur_rect = NULL;
+             *x = 0;
+             *y = 0;
+             *w = re->ob->w;
+             *h = re->ob->h;
+             if (cx) *cx = 0;
+             if (cy) *cy = 0;
+             if (cw) *cw = re->ob->w;
+             if (ch) *ch = re->ob->h;
+             break;
+           default:
+             break;
+          }
+        if (first_rect)
+          {
+             // do anything needed fir the first frame
+          }
+        surface = 
+          re->outbuf_new_region_for_update(re->ob,
+                                           *x, *y, *w, *h,
+                                           cx, cy, cw, ch);
+        if (!re->cur_rect)
+          {
+             re->end = 1;
+          }
+        return surface;
      }
-
-   surface = 
-     re->outbuf_new_region_for_update(re->ob, ux, uy, uw, uh, cx, cy, cw, ch);
-
-   *x = ux; *y = uy; *w = uw; *h = uh;
-   return surface;
+   return NULL;
 }
 
 static void
@@ -694,7 +906,6 @@ eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int
 #if defined(BUILD_PIPE_RENDER)
    evas_common_pipe_map_begin(surface);
 #endif /* BUILD_PIPE_RENDER */
-
    re->outbuf_push_updated_region(re->ob, surface, x, y, w, h);
    re->outbuf_free_region_for_update(re->ob, surface);
    evas_common_cpu_end_opt();
@@ -707,6 +918,11 @@ eng_output_flush(void *data)
 
    re = (Render_Engine *)data;
    re->outbuf_flush(re->ob);
+   if (re->rects)
+     {
+        evas_common_tilebuf_free_render_rects(re->rects);
+        re->rects = NULL;
+     }
 }
 
 static void
@@ -727,21 +943,248 @@ eng_canvas_alpha_get(void *data, void *context __UNUSED__)
    return (re->ob->priv.destination_alpha) || (re->outbuf_alpha_get(re->ob));
 }
 
+static void
+evas_software_image_map_draw(void *data, void *context, RGBA_Image *surface, RGBA_Image *im, RGBA_Map *m, int smooth, int level, int offset)
+{
+   if (m->count - offset < 3) return;
+
+   //Fully Transparency. Skip this.
+   if (!(m->pts[0 + offset].col & 0xff000000) &&
+       !(m->pts[1 + offset].col & 0xff000000) &&
+       !(m->pts[2 + offset].col & 0xff000000) &&
+       !(m->pts[3 + offset].col & 0xff000000))
+     return;
+
+   if ((m->pts[0 + offset].x == m->pts[3 + offset].x) &&
+       (m->pts[1 + offset].x == m->pts[2 + offset].x) &&
+       (m->pts[0 + offset].y == m->pts[1 + offset].y) &&
+       (m->pts[3 + offset].y == m->pts[2 + offset].y) &&
+       (m->pts[0 + offset].x <= m->pts[1 + offset].x) &&
+       (m->pts[0 + offset].y <= m->pts[2 + offset].y) &&
+       (m->pts[0 + offset].u == 0) &&
+       (m->pts[0 + offset].v == 0) &&
+       (m->pts[1 + offset].u == (int)(im->cache_entry.w << FP)) &&
+       (m->pts[1 + offset].v == 0) &&
+       (m->pts[2 + offset].u == (int)(im->cache_entry.w << FP)) &&
+       (m->pts[2 + offset].v == (int)(im->cache_entry.h << FP)) &&
+       (m->pts[3 + offset].u == 0) &&
+       (m->pts[3 + offset].v == (int)(im->cache_entry.h << FP)) &&
+       (m->pts[0 + offset].col == m->pts[1 + offset].col) &&
+       (m->pts[1 + offset].col == m->pts[2 + offset].col) &&
+       (m->pts[2 + offset].col == m->pts[3 + offset].col))
+     {
+        DATA32 col;
+        int a, r, g, b;
+        int dx, dy, dw, dh;
+        int mul;
+
+        mul = func.context_multiplier_get(data, context, &r, &g, &b, &a);
+        if (mul) col = MUL4_256(a, r, g, b, m->pts[0 + offset].col);
+        else col = m->pts[0 + offset].col;
+        func.context_multiplier_set(data, context, R_VAL(&col), G_VAL(&col), B_VAL(&col), A_VAL(&col));
+
+        dx = m->pts[0 + offset].x >> FP;
+        dy = m->pts[0 + offset].y >> FP;
+        dw = (m->pts[2 + offset].x >> FP) - dx;
+        dh = (m->pts[2 + offset].y >> FP) - dy;
+        eng_image_draw
+          (data, context, surface, im,
+           0, 0, im->cache_entry.w, im->cache_entry.h,
+           dx, dy, dw, dh, smooth);
+        if (mul) func.context_multiplier_set(data, context, r, g, b, a);
+        else  func.context_multiplier_unset(data, context);
+     }
+   else
+     {
+#ifdef BUILD_PIPE_RENDER
+        if ((cpunum > 1))
+          {
+             evas_common_pipe_map_draw(im, surface, context, m, smooth, level);
+             return ;
+          }
+        else
+#endif
+          {
+             evas_common_map_rgba(im, surface, context, m->count - offset, &m->pts[offset], smooth, level);
+          }
+     }
+   evas_common_cpu_end_opt();
 
-/* module advertising code */
-static int
-module_open(Evas_Module *em)
+   if (m->count > 4)
+     {
+        evas_software_image_map_draw(data, context, surface, im, m, smooth, level, offset + 2);
+     }
+}
+
+static void
+eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level)
 {
+
+   RGBA_Image *im;
+   Native *n = NULL;
+
+   if (!image) return;
+   if (m->count < 3) return;
+
+   im = image;
+   if (im->native.data)
+     n = im->native.data;
+   if ((n) && (n->ns.type == EVAS_NATIVE_SURFACE_X11))
+     {
 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
-   static Eina_Bool xrm_inited = EINA_FALSE;
+        if(evas_xlib_image_shm_copy(im))
+          {
+             evas_common_image_colorspace_dirty(im);
+          }
+#endif
+     }
+   evas_software_image_map_draw(data, context, surface, image, m, smooth, level, 0);
+}
+
+static void *
+eng_image_native_set(void *data, void *image, void *native)
+{
+   //return image;
+   Render_Engine *re = (Render_Engine *)data;
+   Evas_Native_Surface *ns = native;
+   RGBA_Image *im = image, *im2;
+   Image_Entry *ie = image;
 
-   if (!xrm_inited)
+   if (!im) return im;
+
+   if (ns)
      {
-       xrm_inited = EINA_TRUE;
-       XrmInitialize();
+        if (ns->type == EVAS_NATIVE_SURFACE_X11)
+          {
+             if (im->native.data)
+               {
+                  //image have native surface already
+                  Evas_Native_Surface *ens = im->native.data;
+
+                  if ((ens->type == ns->type) &&
+                      (ens->data.x11.visual == ns->data.x11.visual) &&
+                      (ens->data.x11.pixmap == ns->data.x11.pixmap))
+                     return im;
+                }
+           }
+         else if (ns->type == EVAS_NATIVE_SURFACE_TIZEN)
+           {
+              if (im->native.data)
+                {
+                   //image have native surface already
+                   Evas_Native_Surface *ens = im->native.data;
+
+                   if ((ens->type == ns->type) &&
+                       (ens->data.tizen.buffer == ns->data.tizen.buffer))
+                      return im;
+                }
+            }
+         else if (ns->type == EVAS_NATIVE_SURFACE_TBM)
+           {
+              if (im->native.data)
+                {
+                   //image have native surface already
+                   Evas_Native_Surface *ens = im->native.data;
+
+                   if ((ens->type == ns->type) &&
+                       (ens->data.tizen.buffer == ns->data.tizen.buffer))
+                      return im;
+                }
+            }
+    else
+      {
+         return im;
+      }
+     }
+   if ((!ns) && (!im->native.data)) return im;
+
+   //create new im and clean already existed im even though ns = NULL
+   im2 = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(),
+                                             ie->w, ie->h, NULL, ie->flags.alpha,
+                                             EVAS_COLORSPACE_ARGB8888);
+   if (im->native.data)
+     {
+        if (im->native.func.free)
+          im->native.func.free(im->native.func.data, im);
+     }
+
+   evas_cache_image_drop(&im->cache_entry);
+   im = im2;
+
+   if (!ns) return im;
+
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+   if (ns->type == EVAS_NATIVE_SURFACE_X11)
+     {
+        return evas_xlib_image_native_set(re->ob, im, ns);
      }
 #endif
+   if (ns->type == EVAS_NATIVE_SURFACE_TIZEN)
+     {
+        return evas_native_buffer_image_set(re->ob, im, ns);
+     }
+   if (ns->type == EVAS_NATIVE_SURFACE_TBM)
+     {
+        return evas_native_tbm_image_set(re->ob, im, ns);
+     }
 
+   return im;
+}
+
+static void *
+eng_image_native_get(void *data __UNUSED__, void *image)
+{
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+   RGBA_Image *im = image;
+   Native *n;
+   if (!im) return NULL;
+   n = im->native.data;
+   if (!n) return NULL;
+   return &(n->ns);
+#endif
+   return NULL;
+}
+
+static void
+eng_image_draw(void *data __UNUSED__, void *context, void *surface, void *image,
+               int src_x, int src_y, int src_w, int src_h,
+               int dst_x, int dst_y, int dst_w, int dst_h,
+               int smooth)
+{
+   RGBA_Image *im = image;
+   Native *n = NULL;
+
+   if (!im) return;
+   if (im->native.data)
+     n = im->native.data;
+   if ((n) && (n->ns.type == EVAS_NATIVE_SURFACE_X11))
+     {
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+        if(evas_xlib_image_shm_copy(im))
+          {
+             evas_common_image_colorspace_dirty(im);
+          }
+#endif
+     }
+   else if ((n) && (n->ns.type == EVAS_NATIVE_SURFACE_TIZEN))
+     {
+#ifdef HAVE_NATIVE_BUFFER
+        evas_common_image_colorspace_dirty(im);
+#endif
+     }
+   evas_common_rgba_image_scalecache_prepare(&im->cache_entry, surface, context, smooth,
+           src_x, src_y, src_w, src_h,
+           dst_x, dst_y, dst_w, dst_h);
+   evas_common_rgba_image_scalecache_do(&im->cache_entry, surface, context, smooth,
+           src_x, src_y, src_w, src_h,
+           dst_x, dst_y, dst_w, dst_h);
+   evas_common_cpu_end_opt();
+}
+
+/* module advertising code */
+static int
+module_open(Evas_Module *em)
+{
    if (!em) return 0;
 
    /* get whatever engine module we inherit from */
@@ -776,6 +1219,10 @@ module_open(Evas_Module *em)
    ORD(output_flush);
    ORD(output_idle_flush);
 
+   ORD(image_map_draw);
+   ORD(image_draw);
+   ORD(image_native_set);
+   ORD(image_native_get);
    /* now advertise out own api */
    em->functions = (void *)(&func);
    return 1;
@@ -785,17 +1232,6 @@ static void
 module_close(Evas_Module *em __UNUSED__)
 {
   eina_log_domain_unregister(_evas_engine_soft_x11_log_dom);
-#ifdef BUILD_ENGINE_SOFTWARE_XLIB
-/*   
-  if (xrdb_user.db)
-    {
-       XrmDestroyDatabase(xrdb_user.db);
-       xrdb_user.last_stat = 0;
-       xrdb_user.last_mtime = 0;
-       xrdb_user.db = NULL;
-    }
- */
-#endif
 }
 
 static Evas_Module_Api evas_modapi =
old mode 100644 (file)
new mode 100755 (executable)
index 73a62bc..ea01679
@@ -60,6 +60,14 @@ enum _Outbuf_Depth
    OUTBUF_DEPTH_LAST
 };
 
+enum {
+   MODE_FULL,
+   MODE_COPY,
+   MODE_DOUBLE,
+   MODE_TRIPLE,
+   MODE_QUADRUPLE
+};
+
 typedef struct _Outbuf Outbuf;
 
 struct _Outbuf
@@ -82,7 +90,7 @@ struct _Outbuf
                   Pixmap mask;
                   Visual *vis;
                   Colormap cmap;
-                  int depth, shm;
+                  int depth, imdepth, shm;
                   GC gc, gcm;
                   unsigned char swap : 1;
                   unsigned char bit_swap : 1;
@@ -97,7 +105,7 @@ struct _Outbuf
                   xcb_pixmap_t mask;
                   xcb_visualtype_t *visual;
                   xcb_colormap_t cmap;
-                  int depth, shm;
+                  int depth, imdepth, shm;
                   xcb_gcontext_t gc, gcm;
                   unsigned char swap : 1;
                   unsigned char bit_swap : 1;
@@ -112,6 +120,8 @@ struct _Outbuf
         /* 1 big buffer for updates - flush on idle_flush */
         RGBA_Image *onebuf;
         Eina_Array  onebuf_regions;
+        
+        void *swapper;
 
         /* a list of pending regions to write to the target */
         Eina_List *pending_writes;
@@ -129,4 +139,7 @@ struct _Outbuf
 void evas_software_xlib_x_init(void);
 void evas_software_xcb_init(void);
 
+void *evas_native_buffer_image_set(void *data, void *image, void *native);
+void *evas_native_tbm_image_set(void *data, void *image, void *native);
+
 #endif
diff --git a/src/modules/engines/software_x11/evas_native_buffer.c b/src/modules/engines/software_x11/evas_native_buffer.c
new file mode 100755 (executable)
index 0000000..c3cd985
--- /dev/null
@@ -0,0 +1,322 @@
+#include "evas_common.h"
+#include "evas_xlib_image.h"
+#include "evas_private.h"
+
+#include "Evas_Engine_Software_X11.h"
+#include "evas_engine.h"
+
+#ifdef HAVE_DLSYM
+# include <dlfcn.h>      /* dlopen,dlclose,etc */
+#else
+# error evas_native_buffer should not get compiled if dlsym is not found on the system!
+#endif
+
+#define EVAS_ROUND_UP_4(num) (((num)+3) & ~3)
+#define EVAS_ROUND_UP_8(num) (((num)+7) & ~7)
+
+typedef struct native_buffer native_buffer_t;
+
+typedef enum {
+    STATUS_SUCCESS = 0,             /**< Success */
+    STATUS_ERROR,                   /**< Error */
+    STATUS_NO_MEMORY,               /**< Error: no memory */
+    STATUS_NULL_POINTER,            /**< Error: NULL pointer */
+    STATUS_EMPTY_POOL,              /**< Error: empty pool */
+    STATUS_EGL_ERROR,               /**< Error: EGL error */
+    STATUS_INVALID_BUFFER_STATE,    /**< Error: invalid buffer state */
+} status_t;
+
+typedef enum {
+    NATIVE_BUFFER_FORMAT_INVALID,   /**< Invalid buffer format */
+    NATIVE_BUFFER_FORMAT_RGBA_8888, /**< RGBA8888 */
+    NATIVE_BUFFER_FORMAT_RGBX_8888, /**< RGBX8888 */
+    NATIVE_BUFFER_FORMAT_RGB_888,   /**< RGB888 */
+    NATIVE_BUFFER_FORMAT_RGB_565,   /**< RGB565 */
+    NATIVE_BUFFER_FORMAT_BGRA_8888, /**< BGRA8888 */
+    NATIVE_BUFFER_FORMAT_A_8,       /**< A8 */
+    NATIVE_BUFFER_FORMAT_YV12,      /**< YV12 - 8bit Y plane followed by 8bit 2x2 subsampled V, U planes */
+    NATIVE_BUFFER_FORMAT_I420,      /**< I420 - 8bit Y plane followed by 8bit 2x2 subsampled U, V planes */
+    NATIVE_BUFFER_FORMAT_NV12,      /**< NV12 - 8bit Y plane followed by an interleaved U/V plane with 2x2 subsampling */
+    NATIVE_BUFFER_FORMAT_NV21,      /**< NV21 - 8bit Y plane followed by an interleaved V/U plane with 2x2 subsampling */
+    NATIVE_BUFFER_FORMAT_NV12T,     /**< NV12T - NV12, but use specified tile size */
+    /* ... these formats will be extended over time from this point on */
+} native_buffer_format_t;
+
+typedef enum {
+    NATIVE_BUFFER_USAGE_DEFAULT     = 0x00000000, /**< To get default handle */
+    NATIVE_BUFFER_USAGE_CPU         = 0x00000001, /**< Can be read from to or written by the CPU */
+    NATIVE_BUFFER_USAGE_2D          = 0x00000002, /**< Can be accessed by the 2D accelerator as either a source or a destination */
+    NATIVE_BUFFER_USAGE_3D_TEXTURE  = 0x00000004, /**< Can be accessed by the 3D accelerator as a source texture buffer */
+    NATIVE_BUFFER_USAGE_3D_RENDER   = 0x00000008, /**< Can be accessed by the 3D accelerator as a destination buffer */
+    NATIVE_BUFFER_USAGE_MM          = 0x00000010, /**< Can be accessed by video codec decode or encode hardware */
+    NATIVE_BUFFER_USAGE_DISPLAY     = 0x00000020, /**< Can be scanned out by the display */
+    /* ... these usages will be extended over time from this point on */
+} native_buffer_usage_t;
+
+typedef enum {
+    NATIVE_BUFFER_ACCESS_OPTION_READ  = (1 << 0),   /**< Buffer can be locked for reading */
+    NATIVE_BUFFER_ACCESS_OPTION_WRITE = (1 << 1)    /**< Buffer can be locked for writing */
+} native_buffer_access_option_t;
+
+static status_t (*sym_native_buffer_lock) (native_buffer_t *buffer, int usage, int option, void** addr) = NULL;
+static status_t (*sym_native_buffer_unlock) (native_buffer_t *buffer) = NULL;
+static int (*sym_native_buffer_get_width) (const native_buffer_t *buffer) = NULL;
+static int (*sym_native_buffer_get_height) (const native_buffer_t *buffer) = NULL;
+static int (*sym_native_buffer_get_stride) (const native_buffer_t *buffer) = NULL;
+static native_buffer_format_t (*sym_native_buffer_get_format) (const native_buffer_t *buffer) = NULL;
+
+static void *native_buffer_lib = NULL;
+
+static Eina_Bool
+native_buffer_init(void)
+{
+   static int done = 0;
+
+   if (done) return EINA_TRUE;
+
+   const char *native_buffer_libs[] =
+   {
+      "libnative-buffer.so.0.1.0",
+      "libnative-buffer.so.0.0.0",
+      NULL,
+   };
+   int i, fail;
+#define SYM(lib, xx)                            \
+  do {                                          \
+       sym_ ## xx = dlsym(lib, #xx);            \
+       if (!(sym_ ## xx)) {                     \
+            ERR("%s", dlerror()); \
+            fail = 1;                           \
+         }                                      \
+    } while (0)
+
+   if (native_buffer_lib) return EINA_TRUE;
+   for (i = 0; native_buffer_libs[i]; i++)
+     {
+        native_buffer_lib = dlopen(native_buffer_libs[i], RTLD_LOCAL | RTLD_LAZY);
+        if (native_buffer_lib)
+          {
+             fail = 0;
+             SYM(native_buffer_lib, native_buffer_lock);
+             SYM(native_buffer_lib, native_buffer_unlock);
+             SYM(native_buffer_lib, native_buffer_get_width);
+             SYM(native_buffer_lib, native_buffer_get_height);
+             SYM(native_buffer_lib, native_buffer_get_stride);
+             SYM(native_buffer_lib, native_buffer_get_format);
+             if (fail)
+               {
+                  dlclose(native_buffer_lib);
+                  native_buffer_lib = NULL;
+               }
+             else break;
+          }
+     }
+   if (!native_buffer_lib) return EINA_FALSE;
+
+   done = 1;
+   return EINA_TRUE;
+}
+
+static void
+native_buffer_shutdown(void)
+{
+   if (native_buffer_lib)
+   {
+      dlclose(native_buffer_lib);
+      native_buffer_lib = NULL;
+   }
+}
+
+static void
+_evas_video_yv12(unsigned char *evas_data, const unsigned char *source_data, unsigned int w, unsigned int h, unsigned int output_height)
+{
+   const unsigned char **rows;
+   unsigned int i, j;
+   unsigned int rh;
+   unsigned int stride_y, stride_uv;
+
+   rh = output_height;
+
+   rows = (const unsigned char **)evas_data;
+
+   stride_y = EVAS_ROUND_UP_4(w);
+   stride_uv = EVAS_ROUND_UP_8(w) / 2;
+
+   for (i = 0; i < rh; i++)
+     rows[i] = &source_data[i * stride_y];
+
+   for (j = 0; j < (rh / 2); j++, i++)
+     rows[i] = &source_data[h * stride_y +
+                            (rh / 2) * stride_uv +
+                            j * stride_uv];
+
+   for (j = 0; j < (rh / 2); j++, i++)
+     rows[i] = &source_data[h * stride_y + j * stride_uv];
+}
+
+static void
+_evas_video_i420(unsigned char *evas_data, const unsigned char *source_data, unsigned int w, unsigned int h, unsigned int output_height)
+{
+   const unsigned char **rows;
+   unsigned int i, j;
+   unsigned int rh;
+   unsigned int stride_y, stride_uv;
+
+   rh = output_height;
+
+   rows = (const unsigned char **)evas_data;
+
+   stride_y = EVAS_ROUND_UP_4(w);
+   stride_uv = EVAS_ROUND_UP_8(w) / 2;
+
+   for (i = 0; i < rh; i++)
+     rows[i] = &source_data[i * stride_y];
+
+   for (j = 0; j < (rh / 2); j++, i++)
+     rows[i] = &source_data[h * stride_y + j * stride_uv];
+
+   for (j = 0; j < (rh / 2); j++, i++)
+     rows[i] = &source_data[h * stride_y +
+                            (rh / 2) * stride_uv +
+                            j * stride_uv];
+}
+
+static void
+_evas_video_nv12(unsigned char *evas_data, const unsigned char *source_data, unsigned int w, unsigned int h EINA_UNUSED, unsigned int output_height)
+{
+   const unsigned char **rows;
+   unsigned int i, j;
+   unsigned int rh;
+
+   rh = output_height;
+
+   rows = (const unsigned char **)evas_data;
+
+   for (i = 0; i < rh; i++)
+     rows[i] = &source_data[i * w];
+
+   for (j = 0; j < (rh / 2); j++, i++)
+     rows[i] = &source_data[rh * w + j * w];
+}
+
+static void
+_native_free_cb(void *data EINA_UNUSED, void *image)
+{
+   RGBA_Image *im = image;
+   Evas_Native_Surface *n = im->native.data;
+
+   im->native.data        = NULL;
+   im->native.func.data   = NULL;
+   im->native.func.free   = NULL;
+
+   free(n);
+
+   native_buffer_shutdown();
+}
+
+static void
+_evas_rgba_image_data_alloc(RGBA_Image *im, unsigned int w, unsigned int h)
+{
+   if (im->image.data) free(im->image.data);
+
+   im->image.data = calloc(1, w * h * sizeof(DATA32));
+   if (!im->image.data) return;
+
+   ((Image_Entry *)im)->allocated.w = w;
+   ((Image_Entry *)im)->allocated.h = h;
+}
+
+void *
+evas_native_buffer_image_set(void *data EINA_UNUSED, void *image, void *native)
+{
+   Evas_Native_Surface *ns = native;
+   RGBA_Image *im = image;
+   /* Outbuf *ob = (Outbuf *)data; */
+
+   void *pixels_data;
+   int w, h, stride;
+   native_buffer_format_t format;
+
+   if (!native_buffer_init())
+     {
+        ERR("Could not initialize native buffer!");
+        return NULL;
+     }
+
+   w = sym_native_buffer_get_width(ns->data.tizen.buffer);
+   h = sym_native_buffer_get_height(ns->data.tizen.buffer);
+   stride = sym_native_buffer_get_stride(ns->data.tizen.buffer);
+   format = sym_native_buffer_get_format(ns->data.tizen.buffer);
+
+   if (sym_native_buffer_lock(ns->data.tizen.buffer, NATIVE_BUFFER_USAGE_CPU,
+                          NATIVE_BUFFER_ACCESS_OPTION_READ, &pixels_data) != STATUS_SUCCESS)
+     return im;
+
+   im->cache_entry.w = stride;
+   im->cache_entry.h = h;
+
+   // Handle all possible format here :"(
+   switch (format)
+     {
+      case NATIVE_BUFFER_FORMAT_RGBA_8888:
+      case NATIVE_BUFFER_FORMAT_RGBX_8888:
+      case NATIVE_BUFFER_FORMAT_BGRA_8888:
+         im->cache_entry.w /= 4;
+         evas_cache_image_colorspace(&im->cache_entry, EVAS_COLORSPACE_ARGB8888);
+         im->cache_entry.flags.alpha = format == NATIVE_BUFFER_FORMAT_RGBX_8888 ? 0 : 1;
+         im->image.data = pixels_data;
+         break;
+         /* borrowing code from emotion here */
+      case NATIVE_BUFFER_FORMAT_YV12: /* EVAS_COLORSPACE_YCBCR422P601_PL */
+         evas_cache_image_colorspace(&im->cache_entry, EVAS_COLORSPACE_YCBCR422P601_PL);
+         _evas_video_yv12(im->cs.data, pixels_data, w, h, h);
+         _evas_rgba_image_data_alloc(im, w, h);
+         evas_common_image_colorspace_dirty(im);
+         break;
+      case NATIVE_BUFFER_FORMAT_I420: /* EVAS_COLORSPACE_YCBCR422P601_PL */
+         evas_cache_image_colorspace(&im->cache_entry, EVAS_COLORSPACE_YCBCR422P601_PL);
+         _evas_video_i420(im->cs.data, pixels_data, w, h, h);
+         _evas_rgba_image_data_alloc(im, w, h);
+         evas_common_image_colorspace_dirty(im);
+         break;
+      case NATIVE_BUFFER_FORMAT_NV12: /* EVAS_COLORSPACE_YCBCR420NV12601_PL */
+         evas_cache_image_colorspace(&im->cache_entry, EVAS_COLORSPACE_YCBCR420NV12601_PL);
+         _evas_video_nv12(im->cs.data, pixels_data, w, h, h);
+         _evas_rgba_image_data_alloc(im, w, h);
+         evas_common_image_colorspace_dirty(im);
+         break;
+      case NATIVE_BUFFER_FORMAT_NV12T: /* EVAS_COLORSPACE_YCBCR420TM12601_PL */
+         evas_cache_image_colorspace(&im->cache_entry, EVAS_COLORSPACE_YCBCR420TM12601_PL);
+         /* How to figure out plan ?!? */
+         _evas_rgba_image_data_alloc(im, w, h);
+         evas_common_image_colorspace_dirty(im);
+         break;
+
+         /* Not planning to handle those in software */
+      case NATIVE_BUFFER_FORMAT_NV21: /* Same as NATIVE_BUFFER_FORMAT_NV12, but with U/V reversed */
+      case NATIVE_BUFFER_FORMAT_RGB_888:
+      case NATIVE_BUFFER_FORMAT_RGB_565:
+      case NATIVE_BUFFER_FORMAT_A_8:
+      default:
+         sym_native_buffer_unlock(ns->data.tizen.buffer);
+         return im;
+     }
+
+   if (ns)
+     {
+        Native *n;
+
+        n = calloc(1, sizeof(Native));
+        if (n)
+          {
+             memcpy(n, ns, sizeof(Evas_Native_Surface));
+             im->native.data = n;
+             im->native.func.data = pixels_data;
+             im->native.func.free = _native_free_cb;
+          }
+     }
+
+   sym_native_buffer_unlock(ns->data.tizen.buffer);
+   return im;
+}
+
diff --git a/src/modules/engines/software_x11/evas_native_tbm.c b/src/modules/engines/software_x11/evas_native_tbm.c
new file mode 100755 (executable)
index 0000000..c5bd0eb
--- /dev/null
@@ -0,0 +1,293 @@
+#include "evas_common.h"
+#include "evas_xlib_image.h"
+#include "evas_private.h"
+
+#include "Evas_Engine_Software_X11.h"
+#include "evas_engine.h"
+
+#ifdef HAVE_DLSYM
+# include <dlfcn.h>      /* dlopen,dlclose,etc */
+#else
+# error native_tbm should not get compiled if dlsym is not found on the system!
+#endif
+
+#define EVAS_ROUND_UP_4(num) (((num)+3) & ~3)
+#define EVAS_ROUND_UP_8(num) (((num)+7) & ~7)
+
+#define TBM_SURF_PLANE_MAX 4 /**< maximum number of the planes  */
+
+/* option to map the tbm_surface */
+#define TBM_SURF_OPTION_READ      (1 << 0) /**< access option to read  */
+#define TBM_SURF_OPTION_WRITE     (1 << 1) /**< access option to write */
+
+#define __tbm_fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
+                             ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+
+#define TBM_FORMAT_RGBX8888    __tbm_fourcc_code('R', 'X', '2', '4') /* [31:0] R:G:B:x 8:8:8:8 little endian */
+#define TBM_FORMAT_RGBA8888    __tbm_fourcc_code('R', 'A', '2', '4') /* [31:0] R:G:B:A 8:8:8:8 little endian */
+#define TBM_FORMAT_BGRA8888    __tbm_fourcc_code('B', 'A', '2', '4') /* [31:0] B:G:R:A 8:8:8:8 little endian */
+#define TBM_FORMAT_NV12                __tbm_fourcc_code('N', 'V', '1', '2') /* 2x2 subsampled Cr:Cb plane */
+#define TBM_FORMAT_YUV420      __tbm_fourcc_code('Y', 'U', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes */
+#define TBM_FORMAT_YVU420      __tbm_fourcc_code('Y', 'V', '1', '2') /* 2x2 subsampled Cr (1) and Cb (2) planes */
+
+static void *tbm_lib = NULL;
+
+typedef struct _tbm_surface * tbm_surface_h;
+typedef uint32_t tbm_format;
+typedef struct _tbm_surface_info
+{
+    uint32_t width; /**< tbm surface width */
+    uint32_t height; /**< tbm surface height */
+    tbm_format format; /**<  tbm surface foramt*/
+    uint32_t bpp; /**< tbm surface bbp */
+    uint32_t size; /**< tbm surface size */
+
+    uint32_t num_planes; /**< the number of planes */
+
+    struct {
+        unsigned char *ptr; /**< plane pointer */
+        uint32_t size; /**< plane size */
+        uint32_t offset; /**< plane offset */
+        uint32_t stride; /**< plane stride */
+
+        void *reserved1;
+        void *reserved2;
+        void *reserved3;
+    } planes[TBM_SURF_PLANE_MAX]; /**< array of planes */
+
+    void *reserved4;
+    void *reserved5;
+    void *reserved6;
+} tbm_surface_info_s;
+
+/* returns 0 on success */
+static int (*sym_tbm_surface_map) (tbm_surface_h surface, int opt, tbm_surface_info_s *info) = NULL;
+static int (*sym_tbm_surface_unmap) (tbm_surface_h surface) = NULL;
+static int (*sym_tbm_surface_get_info) (tbm_surface_h surface, tbm_surface_info_s *info) = NULL;
+
+static Eina_Bool
+tbm_init(void)
+{
+   static int done = 0;
+
+   if (done) return EINA_TRUE;
+
+   const char *tbm_libs[] =
+   {
+      "libtbm.so.1",
+      "libtbm.so.0",
+      NULL,
+   };
+   int i, fail;
+#define SYM(lib, xx)                            \
+  do {                                          \
+       sym_ ## xx = dlsym(lib, #xx);            \
+       if (!(sym_ ## xx)) {                     \
+            ERR("%s", dlerror()); \
+            fail = 1;                           \
+         }                                      \
+    } while (0)
+
+   if (tbm_lib) return EINA_TRUE;
+   for (i = 0; tbm_libs[i]; i++)
+     {
+        tbm_lib = dlopen(tbm_libs[i], RTLD_LOCAL | RTLD_LAZY);
+        if (tbm_lib)
+          {
+             fail = 0;
+             SYM(tbm_lib, tbm_surface_map);
+             SYM(tbm_lib, tbm_surface_unmap);
+             SYM(tbm_lib, tbm_surface_get_info);
+             if (fail)
+               {
+                  dlclose(tbm_lib);
+                  tbm_lib = NULL;
+               }
+             else break;
+          }
+     }
+   if (!tbm_lib) return EINA_FALSE;
+
+   done = 1;
+   return EINA_TRUE;
+}
+
+static void
+tbm_shutdown(void)
+{
+   if (tbm_lib)
+   {
+      dlclose(tbm_lib);
+      tbm_lib = NULL;
+   }
+}
+
+static void
+_evas_video_yv12(unsigned char *evas_data, const unsigned char *source_data, unsigned int w, unsigned int h, unsigned int output_height)
+{
+   const unsigned char **rows;
+   unsigned int i, j;
+   unsigned int rh;
+   unsigned int stride_y, stride_uv;
+
+   rh = output_height;
+
+   rows = (const unsigned char **)evas_data;
+
+   stride_y = EVAS_ROUND_UP_4(w);
+   stride_uv = EVAS_ROUND_UP_8(w) / 2;
+
+   for (i = 0; i < rh; i++)
+     rows[i] = &source_data[i * stride_y];
+
+   for (j = 0; j < (rh / 2); j++, i++)
+     rows[i] = &source_data[h * stride_y +
+                            (rh / 2) * stride_uv +
+                            j * stride_uv];
+
+   for (j = 0; j < (rh / 2); j++, i++)
+     rows[i] = &source_data[h * stride_y + j * stride_uv];
+}
+
+static void
+_evas_video_i420(unsigned char *evas_data, const unsigned char *source_data, unsigned int w, unsigned int h, unsigned int output_height)
+{
+   const unsigned char **rows;
+   unsigned int i, j;
+   unsigned int rh;
+   unsigned int stride_y, stride_uv;
+
+   rh = output_height;
+
+   rows = (const unsigned char **)evas_data;
+
+   stride_y = EVAS_ROUND_UP_4(w);
+   stride_uv = EVAS_ROUND_UP_8(w) / 2;
+
+   for (i = 0; i < rh; i++)
+     rows[i] = &source_data[i * stride_y];
+
+   for (j = 0; j < (rh / 2); j++, i++)
+     rows[i] = &source_data[h * stride_y + j * stride_uv];
+
+   for (j = 0; j < (rh / 2); j++, i++)
+     rows[i] = &source_data[h * stride_y +
+                            (rh / 2) * stride_uv +
+                            j * stride_uv];
+}
+
+static void
+_evas_video_nv12(unsigned char *evas_data, const unsigned char *source_data, unsigned int w, unsigned int h EINA_UNUSED, unsigned int output_height)
+{
+   const unsigned char **rows;
+   unsigned int i, j;
+   unsigned int rh;
+
+   rh = output_height;
+
+   rows = (const unsigned char **)evas_data;
+
+   for (i = 0; i < rh; i++)
+     rows[i] = &source_data[i * w];
+
+   for (j = 0; j < (rh / 2); j++, i++)
+     rows[i] = &source_data[rh * w + j * w];
+}
+
+static void
+_native_free_cb(void *data EINA_UNUSED, void *image)
+{
+   RGBA_Image *im = image;
+   Native *n = im->native.data;
+
+   im->native.data        = NULL;
+   im->native.func.data   = NULL;
+   im->native.func.free   = NULL;
+   im->image.data         = NULL;
+
+   free(n);
+
+   tbm_shutdown();
+}
+
+void *
+evas_native_tbm_image_set(void *data EINA_UNUSED, void *image, void *native)
+{
+   Evas_Native_Surface *ns = native;
+   RGBA_Image *im = image;
+   /* Outbuf *ob = (Outbuf *)data; */
+
+   void *pixels_data;
+   int w, h, stride;
+   tbm_format format;
+   tbm_surface_info_s info;
+
+   if (!tbm_init())
+     {
+        ERR("Could not initialize TBM!");
+        return NULL;
+     }
+
+   if (!ns) return;
+
+   sym_tbm_surface_get_info(ns->data.tizen.buffer, &info);
+   w = info.width;
+   h = info.height;
+   stride = info.planes[0].stride;
+   format = info.format;
+
+   if (sym_tbm_surface_map(ns->data.tizen.buffer, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info))
+     return im;
+
+   pixels_data = info.planes[0].ptr;
+   im->cache_entry.w = stride;
+   im->cache_entry.h = h;
+
+   // Handle all possible format here :"(
+   switch (format)
+     {
+      case TBM_FORMAT_RGBA8888:
+      case TBM_FORMAT_RGBX8888:
+      case TBM_FORMAT_BGRA8888:
+         im->cache_entry.w /= 4;
+         evas_cache_image_colorspace(&im->cache_entry, EVAS_COLORSPACE_ARGB8888);
+         im->cache_entry.flags.alpha = format == TBM_FORMAT_RGBX8888 ? 0 : 1;
+         im->image.data = pixels_data;
+         break;
+         /* borrowing code from emotion here */
+      case TBM_FORMAT_YVU420: /* EVAS_COLORSPACE_YCBCR422P601_PL */
+         evas_cache_image_colorspace(&im->cache_entry, EVAS_COLORSPACE_YCBCR422P601_PL);
+         _evas_video_yv12(im->cs.data, pixels_data, w, h, h);
+         evas_common_image_colorspace_dirty(im);
+         break;
+      case TBM_FORMAT_YUV420: /* EVAS_COLORSPACE_YCBCR422P601_PL */
+         evas_cache_image_colorspace(&im->cache_entry, EVAS_COLORSPACE_YCBCR422P601_PL);
+         _evas_video_i420(im->cs.data, pixels_data, w, h, h);
+         evas_common_image_colorspace_dirty(im);
+         break;
+      case TBM_FORMAT_NV12: /* EVAS_COLORSPACE_YCBCR420NV12601_PL */
+         evas_cache_image_colorspace(&im->cache_entry, EVAS_COLORSPACE_YCBCR420NV12601_PL);
+         _evas_video_nv12(im->cs.data, pixels_data, w, h, h);
+         evas_common_image_colorspace_dirty(im);
+         break;
+         /* Not planning to handle those in software */
+      default:
+         sym_tbm_surface_unmap(ns->data.tizen.buffer);
+         return im;
+     }
+
+   Native *n;
+
+   n = calloc(1, sizeof(Native));
+   if (n)
+     {
+        memcpy(n, ns, sizeof(Evas_Native_Surface));
+        im->native.data = n;
+        im->native.func.data = pixels_data;
+        im->native.func.free = _native_free_cb;
+     }
+
+   sym_tbm_surface_unmap(ns->data.tizen.buffer);
+   return im;
+}
+
diff --git a/src/modules/engines/software_x11/evas_x_egl.c b/src/modules/engines/software_x11/evas_x_egl.c
new file mode 100755 (executable)
index 0000000..eb59a21
--- /dev/null
@@ -0,0 +1,284 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef EVAS_CSERVE2
+#include "evas_cs2_private.h"
+#endif
+#include "evas_common.h"
+#include "evas_macros.h"
+#include "evas_x_egl.h"
+
+#ifdef HAVE_DLSYM
+# include <dlfcn.h>      /* dlopen,dlclose,etc */
+#else
+# undef BUILD_ENGINE_SOFTWARE_XLIB
+#endif
+
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+
+#define EGL_SURFACE_TYPE                0x3033
+#define EGL_PIXMAP_BIT                  0x0002
+#define EGL_WINDOW_BIT                  0x0004
+#define EGL_RENDERABLE_TYPE             0x3040
+#define EGL_ALPHA_SIZE                  0x3021
+#define EGL_BLUE_SIZE                   0x3022
+#define EGL_GREEN_SIZE                  0x3023
+#define EGL_RED_SIZE                    0x3024
+#define EGL_DEPTH_SIZE                  0x3025
+#define EGL_STENCIL_SIZE                0x3026
+#define EGL_SAMPLES                     0x3031
+#define EGL_SAMPLE_BUFFERS              0x3032
+#define EGL_SURFACE_TYPE                0x3033
+#define EGL_NONE                        0x3038
+#define EGL_FALSE                       0
+#define EGL_TRUE                        1
+
+#define EGL_LOCK_SURFACE_BIT_KHR              0x0080
+#define EGL_OPTIMAL_FORMAT_BIT_KHR            0x0100
+#define EGL_MATCH_FORMAT_KHR                  0x3043
+#define EGL_FORMAT_RGB_565_EXACT_KHR          0x30C0
+#define EGL_FORMAT_RGB_565_KHR                0x30C1
+#define EGL_FORMAT_RGBA_8888_EXACT_KHR        0x30C2
+#define EGL_FORMAT_RGBA_8888_KHR              0x30C3
+#define EGL_MAP_PRESERVE_PIXELS_KHR           0x30C4
+#define EGL_LOCK_USAGE_HINT_KHR               0x30C5
+#define EGL_READ_SURFACE_BIT_KHR              0x0001
+#define EGL_WRITE_SURFACE_BIT_KHR             0x0002
+#define EGL_BITMAP_POINTER_KHR                0x30C6
+#define EGL_BITMAP_PITCH_KHR                  0x30C7
+#define EGL_BITMAP_ORIGIN_KHR                 0x30C8
+#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR       0x30C9
+#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR     0x30CA
+#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR      0x30CB
+#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR     0x30CC
+#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD
+#define EGL_LOWER_LEFT_KHR                    0x30CE
+#define EGL_UPPER_LEFT_KHR                    0x30CF
+
+static int egl_found = -1;
+static void *egl_lib = NULL;
+
+static struct {
+   void *       (*GetProcAddress)      (const char *name);
+   void *       (*GetDisplay)          (void *d);
+   unsigned int (*Initialize)          (void *ed, int *vmaj, int *vmin);
+   unsigned int (*Terminate)           (void *ed);
+   const char * (*QueryString)         (void *ed, int name);
+   unsigned int (*ChooseConfig)        (void *ed, int *attr, void **configs, int config_size, int *num_config);
+   unsigned int (*GetConfigAttrib)     (void *ed, void *config, int attr, int *val);
+   unsigned int (*QuerySurface)        (void *ed, void *surf, int attr, int *val);
+   void *       (*CreateWindowSurface) (void *ed, void *config, Window win, int *attr);
+   unsigned int (*DestroySurface)      (void *ed, void *surf);
+   unsigned int (*SwapBuffers)         (void *ed, void *surf);
+   unsigned int (*SwapInterval)        (void *ed, int interval);
+   
+   unsigned int (*LockSurface)         (void *ed, void *surf, int *attr);
+   unsigned int (*UnlockSurface)       (void *ed, void *surf);
+} egl;
+
+static int
+_egl_find(void)
+{
+   if (egl_found == 0) return 0;
+   if (!egl_lib) egl_lib = dlopen("libEGL.so.1", RTLD_NOW | RTLD_LOCAL);
+   if (!egl_lib)
+     {
+        egl_found = 0;
+        return 0;
+     }
+   if (!(egl.GetProcAddress = dlsym(egl_lib, "eglGetProcAddress"))) goto err;
+
+#define SYM(x, y) if (!(egl.x = egl.GetProcAddress(y))) goto err
+// core syms used
+   SYM(GetDisplay ,         "eglGetDisplay");
+   SYM(Initialize,          "eglInitialize");
+   SYM(Terminate,           "eglTerminate");
+   SYM(QueryString,         "eglQueryString");
+   SYM(ChooseConfig,        "eglChooseConfig");
+   SYM(UnlockSurface,       "eglGetConfigAttrib");
+   SYM(QuerySurface,        "eglQuerySurface");
+   SYM(CreateWindowSurface, "eglCreateWindowSurface");
+   SYM(DestroySurface,      "eglDestroySurface");
+   SYM(SwapBuffers,         "eglSwapBuffers");
+   SYM(SwapInterval,        "eglSwapInterval");
+
+#undef SYM
+#define SYM(x, y) egl.x = egl.GetProcAddress(y)
+// extns   
+   SYM(LockSurface, "eglLockSurface");
+   if (!egl.LockSurface) SYM(LockSurface, "eglLockSurfaceKHR");
+   SYM(UnlockSurface, "eglUnlockSurface");
+   if (!egl.UnlockSurface) SYM(UnlockSurface, "eglUnlockSurfaceKHR");
+   
+   if (!egl.LockSurface) goto err;
+   if (!egl.UnlockSurface) goto err;
+   
+   egl_found = 1;
+   return 1;
+err:
+   if (egl_lib) dlclose(egl_lib);
+   egl_lib = NULL;
+   return 0;
+}
+#endif
+
+void *
+_egl_x_disp_get(void *d)
+{
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+   if (!_egl_find()) return NULL;
+   return egl.GetDisplay(d);
+#else
+   return NULL;
+#endif
+}
+
+void
+_egl_x_disp_terminate(void *ed)
+{
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+   if (!_egl_find()) return;
+   egl.Terminate(ed);
+#endif
+}
+
+int
+_egl_x_disp_init(void *ed)
+{
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+   int vmaj = 0, vmin = 0;
+   if (!_egl_find()) return 0;
+   if (!egl.Initialize(ed, &vmaj, &vmin)) return 0;
+   return 1;
+#else
+   return 0;
+#endif
+}
+
+void *
+_egl_x_disp_choose_config(void *ed)
+{
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+   int config_attrs[40], n = 0, num_config = 0;
+   void *eglconfig = NULL;
+   
+   if (!_egl_find()) return NULL;
+   config_attrs[n++] = EGL_SURFACE_TYPE;
+   config_attrs[n++] = EGL_WINDOW_BIT;
+   config_attrs[n++] = EGL_RED_SIZE;
+   config_attrs[n++] = 8;
+   config_attrs[n++] = EGL_GREEN_SIZE;
+   config_attrs[n++] = 8;
+   config_attrs[n++] = EGL_BLUE_SIZE;
+   config_attrs[n++] = 8;
+   config_attrs[n++] = EGL_ALPHA_SIZE;
+   config_attrs[n++] = 8;
+   config_attrs[n++] = EGL_DEPTH_SIZE;
+   config_attrs[n++] = 0;
+   config_attrs[n++] = EGL_STENCIL_SIZE;
+   config_attrs[n++] = 0;
+   config_attrs[n++] = EGL_SURFACE_TYPE;
+   config_attrs[n++] = EGL_LOCK_SURFACE_BIT_KHR;
+   config_attrs[n++] = EGL_MATCH_FORMAT_KHR;
+   config_attrs[n++] = EGL_FORMAT_RGBA_8888_KHR;
+   
+   config_attrs[n++] = EGL_NONE;
+   
+   if (!egl.ChooseConfig(ed, config_attrs, &eglconfig, 1, &num_config))
+     return NULL;
+   return eglconfig;
+#else
+   return NULL;
+#endif
+}
+
+void *
+_egl_x_win_surf_new(void *ed, Window win, void *config)
+{
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+   if (!_egl_find()) return NULL;
+   return egl.CreateWindowSurface(ed, config, win, NULL);
+#else
+   return NULL;
+#endif
+}
+
+void
+_egl_x_win_surf_free(void *ed, void *surf)
+{
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+   if (!_egl_find()) return;
+   egl.DestroySurface(ed, surf);
+#endif
+}
+
+void *
+_egl_x_surf_map(void *ed, void *surf, int *stride)
+{
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+   int config_attrs[40], n = 0;
+   void *ptr = NULL;
+   int pitch = 0,  origin = 0;
+   int r_offset = 0, g_offset = 0, b_offset = 0;
+   
+   if (!_egl_find()) return NULL;
+   
+   config_attrs[n++] = EGL_MAP_PRESERVE_PIXELS_KHR;
+   config_attrs[n++] = EGL_TRUE;
+   config_attrs[n++] = EGL_LOCK_USAGE_HINT_KHR;
+   config_attrs[n++] = EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR;
+   config_attrs[n++] = EGL_NONE;
+   
+   if (!egl.LockSurface(ed, surf, config_attrs)) return NULL;
+   if (!egl.QuerySurface(ed, surf, EGL_BITMAP_POINTER_KHR, (int *)&ptr)) goto err;
+   if (!egl.QuerySurface(ed, surf, EGL_BITMAP_PITCH_KHR, &pitch)) goto err;
+   if (!egl.QuerySurface(ed, surf, EGL_BITMAP_ORIGIN_KHR, &origin)) goto err;
+   if (!egl.QuerySurface(ed, surf, EGL_BITMAP_PIXEL_RED_OFFSET_KHR, &r_offset)) goto err;
+   if (!egl.QuerySurface(ed, surf, EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR, &g_offset)) goto err;
+   if (!egl.QuerySurface(ed, surf, EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR, &b_offset)) goto err;
+   
+   if (!ptr) goto err;
+   if (pitch <= 0) goto err;
+   // must be top-left to bottom-right ordered
+   if (origin != EGL_UPPER_LEFT_KHR) goto err;
+   // must be xRGB
+   if (!((b_offset == 0) && (g_offset == 8) && (r_offset == 16))) goto err;
+   // return stride
+   *stride = pitch; // pitch is in bytes
+   return ptr;
+err:
+   egl.UnlockSurface(ed, surf);
+   return NULL;
+#else
+   return NULL;
+#endif
+}
+
+void
+_egl_x_surf_unmap(void *ed, void *surf)
+{
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+   egl.UnlockSurface(ed, surf);
+#endif   
+}
+
+void
+_egl_x_surf_swap(void *ed, void *surf, int vsync)
+{
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+   if (vsync) egl.SwapInterval(ed, 1);
+   else egl.SwapInterval(ed, 0);
+   egl.SwapBuffers(ed, surf);
+#endif   
+}
+
+Outbuf *
+evas_software_egl_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
+                                 Display *disp, Drawable draw, Visual *vis,
+                                 Colormap cmap, int x_depth,
+                                 int grayscale, int max_colors, Pixmap mask,
+                                 int shape_dither, int destination_alpha)
+{
+   return NULL;
+}
diff --git a/src/modules/engines/software_x11/evas_x_egl.h b/src/modules/engines/software_x11/evas_x_egl.h
new file mode 100644 (file)
index 0000000..3807b03
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef EVAS_X_EGL_H
+#define EVAS_X_EGL_H
+
+#include "evas_engine.h"
+
+void *_egl_x_disp_get(void *d);
+void _egl_x_disp_terminate(void *ed);
+int _egl_x_disp_init(void *ed);
+void *_egl_x_disp_choose_config(void *ed);
+void *_egl_x_win_surf_new(void *ed, Window win, void *config);
+void _egl_x_win_surf_free(void *ed, void *surf);
+void *_egl_x_surf_map(void *ed, void *surf, int *stride);
+void _egl_x_surf_unmap(void *ed, void *surf);
+void _egl_x_surf_swap(void *ed, void *surf, int vsync);
+
+Outbuf *
+evas_software_egl_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
+                                 Display *disp, Drawable draw, Visual *vis,
+                                 Colormap cmap, int x_depth,
+                                 int grayscale, int max_colors, Pixmap mask,
+                                 int shape_dither, int destination_alpha);
+
+#endif
index 3ed6037..f451fa1 100644 (file)
@@ -65,13 +65,13 @@ x_color_alloc_rgb(int               nr,
                  int                      val;
                   int                      dr, dg, db;
 
-                  val = (int)((((double)r) / ((nr) - 1)) * 255);
+                  val = (int)(((r * 255) / ((nr) - 1)));
                   val = (val << 8) | val;
                  xcl.red = (uint16_t)(val);
-                 val = (int)((((double)g) / ((ng) - 1)) * 255);
+                 val = (int)(((g * 255) / ((ng) - 1)));
                   val = (val << 8) | val;
                  xcl.green = (uint16_t)(val);
-                 val = (int)((((double)b) / ((nb) - 1)) * 255);
+                 val = (int)(((b * 255) / ((nb) - 1)));
                   val = (val << 8) | val;
                  xcl.blue = (uint16_t)(val);
                  xcl_in = xcl;
@@ -154,7 +154,7 @@ x_color_alloc_gray(int               ng,
        int                      val;
        xcb_alloc_color_reply_t *rep;
 
-       val = (int)((((double)g) / ((ng) - 1)) * 255);
+       val = (int)(((g * 255) / ((ng) - 1)));
         val = (val << 8) | val;
        xcl.red = (uint16_t)(val);
        xcl.green = (uint16_t)(val);
index b84ee16..086ec7c 100644 (file)
@@ -87,7 +87,8 @@ Outbuf *
 evas_software_xcb_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, xcb_connection_t *conn, xcb_screen_t *screen, xcb_drawable_t draw, xcb_visualtype_t *vis, xcb_colormap_t cmap, int xdepth, Eina_Bool grayscale, int max_colors, xcb_drawable_t mask, Eina_Bool shape_dither, Eina_Bool alpha) 
 {
    Outbuf *buf = NULL;
-   Gfx_Func_Convert func_conv= NULL;
+   Gfx_Func_Convert func_conv = NULL;
+   Xcb_Output_Buffer *xob;
    const xcb_setup_t *setup;
 
    if (!(buf = calloc(1, sizeof(Outbuf)))) 
@@ -108,6 +109,27 @@ evas_software_xcb_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, xcb_co
    buf->priv.destination_alpha = alpha;
    buf->priv.x11.xcb.shm = evas_software_xcb_can_do_shm(conn, screen);
 
+   xob = 
+     evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
+                                         buf->priv.x11.xcb.visual, 
+                                         buf->priv.x11.xcb.depth, 
+                                         1, 1, buf->priv.x11.xcb.shm, 
+                                         NULL);
+   if (!xob) buf->priv.x11.xcb.shm = 0;
+   xob = 
+     evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
+                                         buf->priv.x11.xcb.visual, 
+                                         buf->priv.x11.xcb.depth, 
+                                         1, 1, buf->priv.x11.xcb.shm, 
+                                         NULL);
+   if (!xob) 
+     {
+        free(buf);
+        return NULL;
+     }
+   buf->priv.x11.xcb.imdepth = evas_software_xcb_output_buffer_depth(xob);
+   evas_software_xcb_output_buffer_free(xob, EINA_FALSE);
+   
    eina_array_step_set(&buf->priv.onebuf_regions, sizeof(Eina_Array), 8);
 
 #ifdef WORDS_BIGENDIAN
@@ -259,7 +281,8 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
              return NULL;
           }
 
-        if (!eina_array_push(&buf->priv.onebuf_regions, rect))
+        if ((eina_array_push(&buf->priv.onebuf_regions, rect)) &&
+            (buf->priv.onebuf))
           {
              if (cx) *cx = x;
              if (cy) *cy = y;
@@ -284,8 +307,11 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
         alpha = ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha));
         use_shm = buf->priv.x11.xcb.shm;
 
-        if ((buf->rot == 0) && (buf->priv.mask.r == 0xff0000) && 
-            (buf->priv.mask.g == 0x00ff00) && (buf->priv.mask.b == 0x0000ff)) 
+        if ((buf->rot == 0) &&
+            (buf->priv.x11.xcb.imdepth == 32) &&
+            (buf->priv.mask.r == 0xff0000) &&
+            (buf->priv.mask.g == 0x00ff00) &&
+            (buf->priv.mask.b == 0x0000ff))
           {
              obr->xcbob = 
                evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
@@ -424,8 +450,11 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
 
    use_shm = buf->priv.x11.xcb.shm;
    alpha = ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha));
-   if ((buf->rot == 0) && (buf->priv.mask.r == 0xff0000) && 
-       (buf->priv.mask.g == 0x00ff00) && (buf->priv.mask.b == 0x0000ff)) 
+   if ((buf->rot == 0) &&
+       (buf->priv.x11.xcb.imdepth == 32) &&
+       (buf->priv.mask.r == 0xff0000) && 
+       (buf->priv.mask.g == 0x00ff00) &&
+       (buf->priv.mask.b == 0x0000ff)) 
      {
         obr->xcbob = 
           _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, 
@@ -836,13 +865,35 @@ evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, in
    if (data != (unsigned char *)src_data) 
      {
         if (buf->priv.pal)
-          func_conv(src_data, data, update->cache_entry.w - w, 
-                    (bpl / (buf->depth / 8)) - obr->w, 
-                    obr->w, obr->h, x, y, buf->priv.pal->lookup);
+          {
+             func_conv(src_data, data, update->cache_entry.w - w, 
+                       bpl - obr->w, obr->w, obr->h, x, y,
+                       buf->priv.pal->lookup);
+          }
         else
-          func_conv(src_data, data, update->cache_entry.w - w, 
-                    (bpl / (buf->depth / 8)) - obr->w, 
-                    obr->w, obr->h, x, y, NULL);
+          {
+             int pixelb = evas_software_xcb_output_buffer_depth(obr->xcbob) / 8;
+             int run;
+             int dstjump;
+             
+             if (pixelb == 3)
+               {
+                  run = obr->w * pixelb;
+                  dstjump = bpl - run;
+               }
+             else if ((pixelb == 2) || (pixelb == 4))
+               {
+                  run = obr->w;
+                  dstjump = (bpl / pixelb) - run;
+               }
+             else
+               {
+                  run = obr->w;
+                  dstjump = bpl - run;
+               }
+             func_conv(src_data, data, update->cache_entry.w - w, dstjump,
+                       obr->w, obr->h, x, y, NULL);
+          }
      }
 #if 1
 #else
@@ -1065,13 +1116,14 @@ _find_xcbob(xcb_connection_t *conn, xcb_visualtype_t *vis, int depth, int w, int
      return evas_software_xcb_output_buffer_new(conn, vis, depth, w, h, 
                                                 shm, data);
 
-   lbytes = (((w + 31) / 32) * 4);
    if (depth > 1) 
      {
         bpp = (depth / 8);
         if (bpp == 3) bpp = 4;
         lbytes = ((((w * bpp) + 3) / 4) * 4);
      }
+   else
+     lbytes = (((w + 63) / 64) * 8);
 
    sz = (lbytes * h);
    SHMPOOL_LOCK();
@@ -1080,7 +1132,7 @@ _find_xcbob(xcb_connection_t *conn, xcb_visualtype_t *vis, int depth, int w, int
         int szdif = 0;
 
         if ((xcbob2->xim->depth != depth) || (xcbob2->visual != vis) || 
-            (xcbob2->connection != conn)) continue;
+            (xcbob2->connection != conn) || (xcbob2->w != w)) continue;
         szdif = (xcbob2->psize - sz);
         if (szdif < 0) continue;
         if (szdif == 0) 
@@ -1107,7 +1159,7 @@ have_xcbob:
    _shmpool = eina_list_remove_list(_shmpool, xl);
    xcbob->w = w;
    xcbob->h = h;
-   xcbob->bpl = lbytes;
+//   xcbob->bpl = lbytes;
    xcbob->xim->width = xcbob->w;
    xcbob->xim->height = xcbob->h;
    xcbob->xim->stride = xcbob->bpl;
index 756ffb7..5509e61 100644 (file)
@@ -340,7 +340,11 @@ evas_software_xlib_x_output_buffer_new(Display *d, Visual *v, int depth, int w,
          }
      }
 
-   if (try_shm > 1) return NULL;
+   if (try_shm > 1)
+     {
+        free(xob);
+        return NULL;
+     }
 
    xob->xim = XCreateImage(d, v, depth, ZPixmap, 0, data, w, h, 32, 0);
    if (!xob->xim)
index 1df0406..417b0b9 100644 (file)
@@ -61,15 +61,18 @@ x_color_alloc_rgb(int nr, int ng, int nb, Display *d, Colormap cmap, Visual *v)
                  Status ret;
                  int dr, dg, db;
 
-                  val = (int)((((double)r) / ((nr) - 1)) * 255);
+                  val = (int)(((r * 255) / ((nr) - 1)));
                  val = (val << 8) | val;
                  xcl.red = (unsigned short)(val);
-                 val = (int)((((double)g) / ((ng) - 1)) * 255);
+                 val = (int)(((g * 255) / ((ng) - 1)));
                  val = (val << 8) | val;
                  xcl.green = (unsigned short)(val);
-                 val = (int)((((double)b) / ((nb) - 1)) * 255);
+                 val = (int)(((b * 255) / ((nb) - 1)));
                  val = (val << 8) | val;
                  xcl.blue = (unsigned short)(val);
+                  xcl.pixel = 0;
+                  xcl.flags = 0;
+                  xcl.pad = 0;
                  xcl_in = xcl;
                  ret = XAllocColor(d, cmap, &xcl);
                  dr = (int)xcl_in.red - (int)xcl.red;
@@ -78,7 +81,7 @@ x_color_alloc_rgb(int nr, int ng, int nb, Display *d, Colormap cmap, Visual *v)
                  if (dg < 0) dg = -dg;
                  db = (int)xcl_in.blue - (int)xcl.blue;
                  if (db < 0) db = -db;
-/*
+/*                  
                  printf("ASK [%i]: %04x %04x %04x = %04x %04x %04x | dif = %04x / %04x\n",
                         ret,
                         xcl_in.red, xcl_in.green, xcl_in.blue,
@@ -134,11 +137,14 @@ x_color_alloc_gray(int ng, Display *d, Colormap cmap, Visual *v)
        int val;
        Status ret;
 
-       val = (int)((((double)g) / ((ng) - 1)) * 255);
+       val = (int)(((g * 255) / ((ng) - 1)));
        val = (val << 8) | val;
        xcl.red = (unsigned short)(val);
        xcl.green = (unsigned short)(val);
        xcl.blue = (unsigned short)(val);
+        xcl.pixel = 0;
+        xcl.flags = 0;
+        xcl.pad = 0;
        xcl_in = xcl;
        ret = XAllocColor(d, cmap, &xcl);
        if ((ret == 0) ||
@@ -336,9 +342,10 @@ evas_software_xlib_x_color_allocate(Display         *disp,
    palpriv->cmap = cmap;
    if (pal->colors == PAL_MODE_NONE)
      {
-       if (pal->lookup) free(pal->lookup);
-       free(pal);
-       return NULL;
+        if (pal->lookup) free(pal->lookup);
+        free(palpriv);
+        free(pal);
+        return NULL;
      }
    palettes = eina_list_append(palettes, pal);
    return pal;
diff --git a/src/modules/engines/software_x11/evas_xlib_image.c b/src/modules/engines/software_x11/evas_xlib_image.c
new file mode 100644 (file)
index 0000000..0c1df1d
--- /dev/null
@@ -0,0 +1,228 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "evas_common.h"
+#include "evas_xlib_image.h"
+#include "evas_xlib_outbuf.h"
+
+Eina_Bool
+evas_xlib_image_shm_copy(RGBA_Image *im)
+{
+   Native *n = NULL;
+   Display *d;
+   Evas_X_Image *exim;
+   Evas_Native_Surface *ns;
+
+   if (im->native.data)
+     n = im->native.data;
+   if (!n)
+     return EINA_FALSE;
+
+   exim = n->exim;
+   d = n->d;
+   ns = &(n->ns);
+   if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
+     {
+        XGrabServer(d);
+        if (!XShmGetImage(d, (Drawable)ns->data.x11.pixmap, exim->xim, 0, 0, 0xffffffff))
+          {
+             ERR("XShmGetImage failed.");
+             XUngrabServer(d);
+             return EINA_FALSE;
+          }
+        XUngrabServer(d);
+        XSync(d, 0);
+     }
+   im->image.data = exim->data;
+   return EINA_TRUE;
+}
+
+void
+evas_xlib_image_free(Evas_X_Image *exim)
+{
+   XShmDetach(exim->dis, &exim->shminfo);
+   XDestroyImage(exim->xim);
+   exim->xim = NULL;
+   shmdt(exim->shminfo.shmaddr);
+   shmctl(exim->shminfo.shmid, IPC_RMID, 0);
+   free(exim);
+}
+
+Evas_X_Image *
+evas_xlib_image_new(int w, int h, Visual *vis, int depth)
+{
+   Evas_X_Image *exim;
+
+   exim = calloc(1, sizeof(Evas_X_Image));
+   if (!exim)
+     return NULL;
+
+   exim->w = w;
+   exim->h = h;
+   exim->visual = vis;
+   exim->depth = depth;
+   return exim;
+}
+
+void
+evas_xlib_image_shm_create(Evas_X_Image *exim, Display *display)
+{
+   exim->xim = XShmCreateImage(display, exim->visual, exim->depth,
+                             ZPixmap, NULL, &(exim->shminfo),
+                             exim->w, exim->h);
+   if (!exim->xim)
+   {
+     ERR("XShmCreateImage failed.");
+     return;
+   }
+
+   exim->shminfo.shmid = shmget(IPC_PRIVATE,
+                              exim->xim->bytes_per_line * exim->xim->height,
+                              IPC_CREAT | 0666);
+   if (exim->shminfo.shmid == -1)
+     {
+        ERR("shmget failed.");
+        XDestroyImage(exim->xim);
+        exim->xim = NULL;
+        return;
+     }
+
+   exim->shminfo.readOnly = False;
+   exim->shminfo.shmaddr = shmat(exim->shminfo.shmid, 0, 0);
+   exim->xim->data = exim->shminfo.shmaddr;
+   if ((exim->xim->data == (char *)-1) ||
+       (!exim->xim->data))
+     {
+        ERR("shmat failed.");
+        shmdt(exim->shminfo.shmaddr);
+        shmctl(exim->shminfo.shmid, IPC_RMID, 0);
+        XDestroyImage(exim->xim);
+        exim->xim = NULL;
+        return;
+     }
+
+   XShmAttach(display, &exim->shminfo);
+   exim->data = (unsigned char *)exim->xim->data;
+
+   exim->bpl = exim->xim->bytes_per_line;
+   exim->rows = exim->xim->height;
+   if (exim->xim->bits_per_pixel <= 8)
+     exim->bpp = 1;
+   else if (exim->xim->bits_per_pixel <= 16)
+     exim->bpp = 2;
+   else
+     exim->bpp = 4;
+}
+
+void *
+evas_xlib_image_data_get(Evas_X_Image *exim,
+                         int *bpl,
+                         int *rows,
+                         int *bpp,
+                         Display *display)
+{
+   if (!exim->xim)
+     {
+        evas_xlib_image_shm_create(exim, display);
+     }
+   if (!exim->xim)
+     {
+        return NULL;
+     }
+   if (bpl) *bpl = exim->bpl;
+   if (rows) *rows = exim->rows;
+   if (bpp) *bpp = exim->bpp;
+   exim->dis = display;
+
+   return exim->data;
+}
+
+static void
+_native_free_cb(void *data EINA_UNUSED, void *image)
+{
+   RGBA_Image *im = image;
+   Native *n = im->native.data;
+
+   //TODO: deal with pixmap hash
+   if (n->exim)
+     {
+        evas_xlib_image_free(n->exim);
+        n->exim = NULL;
+     }
+   n->visual = NULL;
+   n->d = NULL;
+
+   im->native.data        = NULL;
+   im->native.func.data   = NULL;
+   im->native.func.free   = NULL;
+   im->image.data         = NULL;
+   free(n);
+}
+
+void *
+evas_xlib_image_native_set(void *data, void *image, void *native)
+{
+   Display *d = NULL;
+   Visual  *vis = NULL;
+   Pixmap   pm = 0;
+   Native  *n = NULL;
+   RGBA_Image *im = image;
+   int w, h;
+   Evas_X_Image *exim;
+   char* pix;
+   Evas_Native_Surface *ns = native;
+   Outbuf *ob = (Outbuf *)data;
+
+   Window wdum;
+   int idum;
+   unsigned int uidum, depth = 0;
+
+   d = ob->priv.x11.xlib.disp;
+
+   if (ns)
+     {
+        vis = ns->data.x11.visual;
+        pm = ns->data.x11.pixmap;
+     }
+
+   // fixme: round trip :(
+   // get pixmap depth info
+   XGetGeometry(d, pm, &wdum, &idum, &idum, &uidum, &uidum, &uidum, &depth);
+
+
+   //TODO: deal with pixmap cache
+   w = im->cache_entry.w;
+   h = im->cache_entry.h;
+
+   exim = evas_xlib_image_new(w, h, vis, depth);
+   if (!exim)
+     {
+        ERR("evas_xlib_image_new failed.");
+        return EINA_FALSE;
+     }
+
+   if (ns)
+     {
+        n = calloc(1, sizeof(Native));
+        if (n)
+          {
+             memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
+             n->pixmap = pm;
+             n->visual = vis;
+             n->d = d;
+             n->exim = exim;
+             im->native.data = n;
+             im->native.func.data = NULL;
+             im->native.func.free = _native_free_cb;
+          }
+     }
+
+   pix = evas_xlib_image_data_get(exim, NULL, NULL, NULL, d);
+   if (pix == NULL)
+   {
+      ERR("evas_xlib_image_data_get failed.");
+   }
+   evas_xlib_image_shm_copy(im);
+   return im;
+}
diff --git a/src/modules/engines/software_x11/evas_xlib_image.h b/src/modules/engines/software_x11/evas_xlib_image.h
new file mode 100644 (file)
index 0000000..b16f4bb
--- /dev/null
@@ -0,0 +1,34 @@
+#include "evas_engine.h"
+
+typedef struct _Evas_X_Image Evas_X_Image;
+typedef struct _Native Native;
+
+struct _Evas_X_Image
+{
+   Display         *dis;
+   Visual          *visual;
+   XImage          *xim;
+   XShmSegmentInfo  shminfo;
+   int              depth;
+   int              w, h;
+   int              bpl, bpp, rows;
+   unsigned char   *data;
+};
+
+struct _Native
+{
+   Evas_Native_Surface ns;
+   Pixmap              pixmap;
+   Visual             *visual;
+   Display            *d;
+
+   Evas_X_Image       *exim;
+};
+
+Evas_X_Image *evas_xlib_image_new(int w, int h, Visual *vis, int depth);
+
+void evas_xlib_image_free(Evas_X_Image *exim);
+void evas_xlib_image_shm_create(Evas_X_Image *exim, Display *display);
+Eina_Bool evas_xlib_image_shm_copy(RGBA_Image *im);
+void *evas_xlib_image_data_get(Evas_X_Image *exim, int *bpl, int *rows, int *bpp, Display *display);
+void *evas_xlib_image_native_set(void *data, void *image, void *native);
index ab4e777..89f6a8a 100644 (file)
@@ -53,7 +53,7 @@ _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
        lbytes = (((w * bpp) + 3) / 4) * 4;
      }
    else
-     lbytes = ((w + 31) / 32) * 4;
+     lbytes = ((w + 63) / 64) * 8;
    sz = lbytes * h;
    SHMPOOL_LOCK();
    EINA_LIST_FOREACH(shmpool, l, xob2)
@@ -61,7 +61,7 @@ _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
        int szdif;
 
        if ((xob2->xim->depth != depth) || (xob2->visual != v) ||
-           (xob2->display != d))
+           (xob2->display != d) || (xob2->w != w))
          continue;
        szdif = xob2->psize - sz;
        if (szdif < 0) continue;
@@ -89,7 +89,7 @@ _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
    shmpool = eina_list_remove_list(shmpool, xl);
    xob->w = w;
    xob->h = h;
-   xob->bpl = lbytes;
+//   xob->bpl = lbytes;
    xob->xim->width = xob->w;
    xob->xim->height = xob->h;
    xob->xim->bytes_per_line = xob->bpl;
@@ -223,7 +223,6 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
                                                  buf->priv.x11.xlib.vis,
                                                  buf->priv.x11.xlib.depth,
                                                  1, 1, buf->priv.x11.xlib.shm, NULL);
-
       conv_func = NULL;
       if (xob)
        {
@@ -300,6 +299,7 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
                                                                    pm);
                if (!buf->priv.pal)
                  {
+                     if (xob) evas_software_xlib_x_output_buffer_free(xob, 1);
                     free(buf);
                     return NULL;
                  }
@@ -340,7 +340,8 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
                                                             buf->priv.mask.b, PAL_MODE_NONE,
                                                             buf->rot);
             }
-          evas_software_xlib_x_output_buffer_free(xob, 1);
+           buf->priv.x11.xlib.imdepth = evas_software_xlib_x_output_buffer_depth(xob);
+           evas_software_xlib_x_output_buffer_free(xob, 1);
           if (!conv_func)
             {
                 ERR("At depth: %i, RGB format mask: %08x %08x %08x, "
@@ -373,16 +374,12 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
        Eina_Rectangle *rect;
 
        RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, buf->w, buf->h);
-       obr = calloc(1, sizeof(Outbuf_Region));
-        if (!obr) return NULL;
+
         rect = eina_rectangle_new(x, y, w, h);
-        if (!rect)
-          {
-             free(obr);
-             return NULL;
-          }
+        if (!rect) return NULL;
 
-        if (!eina_array_push(&buf->priv.onebuf_regions, rect))
+        if ((eina_array_push(&buf->priv.onebuf_regions, rect)) &&
+            (buf->priv.onebuf))
          {
             *cx = x;
             *cy = y;
@@ -395,6 +392,12 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
               }
             return buf->priv.onebuf;
          }
+
+        if (rect) eina_rectangle_free(rect);
+
+        obr = calloc(1, sizeof(Outbuf_Region));
+        if (!obr) return NULL;
+
        obr->x = 0;
        obr->y = 0;
        obr->w = buf->w;
@@ -408,6 +411,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
 
        use_shm = buf->priv.x11.xlib.shm;
        if ((buf->rot == 0) &&
+            (buf->priv.x11.xlib.imdepth == 32) &&
            (buf->priv.mask.r == 0xff0000) &&
            (buf->priv.mask.g == 0x00ff00) &&
            (buf->priv.mask.b == 0x0000ff))
@@ -563,6 +567,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
    alpha = ((buf->priv.x11.xlib.mask) || (buf->priv.destination_alpha));
 
    if ((buf->rot == 0) &&
+       (buf->priv.x11.xlib.imdepth == 32) &&
        (buf->priv.mask.r == 0xff0000) &&
        (buf->priv.mask.g == 0x00ff00) &&
        (buf->priv.mask.b == 0x0000ff))
@@ -1009,21 +1014,34 @@ evas_software_xlib_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, i
    if (buf->priv.pal)
      {
        if (data != (unsigned char *)src_data)
-         conv_func(src_data, data,
-                   update->cache_entry.w - w,
-                   bpl /
-                   ((evas_software_xlib_x_output_buffer_depth(obr->xob) /
-                     8)) - obr->w, obr->w, obr->h, x, y,
-                   buf->priv.pal->lookup);
+         conv_func(src_data, data, update->cache_entry.w - w,
+                    bpl - obr->w, obr->w, obr->h, x, y,
+                    buf->priv.pal->lookup);
      }
    else
      {
+        int pixelb = evas_software_xlib_x_output_buffer_depth(obr->xob) / 8;
+        int run;
+        int dstjump;
+        
+        if (pixelb == 3)
+          {
+             run = obr->w * pixelb;
+             dstjump = bpl - run;
+          }
+        else if ((pixelb == 2) || (pixelb == 4))
+          {
+             run = obr->w;
+             dstjump = (bpl / pixelb) - run;
+          }
+        else
+          {
+             run = obr->w;
+             dstjump = bpl - run;
+          }
        if (data != (unsigned char *)src_data)
-         conv_func(src_data, data,
-                   update->cache_entry.w - w,
-                   bpl /
-                   ((evas_software_xlib_x_output_buffer_depth(obr->xob) /
-                     8)) - obr->w, obr->w, obr->h, x, y, NULL);
+         conv_func(src_data, data, update->cache_entry.w - w, dstjump,
+                    obr->w, obr->h, x, y, NULL);
      }
 #if 1
 #else
diff --git a/src/modules/engines/software_x11/evas_xlib_swapbuf.c b/src/modules/engines/software_x11/evas_xlib_swapbuf.c
new file mode 100755 (executable)
index 0000000..69d5e4d
--- /dev/null
@@ -0,0 +1,621 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/time.h>
+#include <sys/utsname.h>
+
+#ifdef EVAS_CSERVE2
+#include "evas_cs2_private.h"
+#endif
+#include "evas_common.h"
+#include "evas_macros.h"
+
+#include "evas_xlib_swapbuf.h"
+#include "evas_xlib_color.h"
+#include "evas_xlib_swapper.h"
+
+typedef struct _Outbuf_Region   Outbuf_Region;
+
+struct _Outbuf_Region
+{
+   RGBA_Image      *im;
+   int              x;
+   int              y;
+   int              w;
+   int              h;
+};
+
+void
+evas_software_xlib_swapbuf_init(void)
+{
+}
+
+void
+evas_software_xlib_swapbuf_free(Outbuf *buf)
+{
+   evas_software_xlib_swapbuf_flush(buf);
+   evas_software_xlib_swapbuf_idle_flush(buf);
+   if (buf->priv.pal)
+     evas_software_xlib_x_color_deallocate
+     (buf->priv.x11.xlib.disp, buf->priv.x11.xlib.cmap,
+         buf->priv.x11.xlib.vis, buf->priv.pal);
+   evas_xlib_swapper_free(buf->priv.swapper);
+   eina_array_flush(&buf->priv.onebuf_regions);
+   free(buf);
+}
+
+Outbuf *
+evas_software_xlib_swapbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
+                                  Display *disp, Drawable draw, Visual *vis,
+                                  Colormap cmap, int x_depth,
+                                  int grayscale, int max_colors, Pixmap mask,
+                                  int shape_dither, int destination_alpha)
+{
+   Outbuf             *buf;
+   Gfx_Func_Convert    conv_func = NULL;
+   int                 d;
+   
+   buf = calloc(1, sizeof(Outbuf));
+   if (!buf) return NULL;
+
+   if (x_depth < 15) rot = 0;
+   
+   buf->onebuf = 1;
+   buf->w = w;
+   buf->h = h;
+   buf->depth = depth;
+   buf->rot = rot;
+   buf->priv.x11.xlib.disp = disp;
+   buf->priv.x11.xlib.win = draw;
+   buf->priv.x11.xlib.vis = vis;
+   buf->priv.x11.xlib.cmap = cmap;
+   buf->priv.x11.xlib.depth = x_depth;
+   buf->priv.mask_dither = shape_dither;
+   buf->priv.destination_alpha = destination_alpha;
+
+   if ((buf->rot == 0) || (buf->rot == 180))
+     buf->priv.swapper = evas_xlib_swapper_new(buf->priv.x11.xlib.disp,
+                                               buf->priv.x11.xlib.win,
+                                               buf->priv.x11.xlib.vis,
+                                               buf->priv.x11.xlib.depth,
+                                               buf->w, buf->h);
+   else if ((buf->rot == 90) || (buf->rot == 270))
+     buf->priv.swapper = evas_xlib_swapper_new(buf->priv.x11.xlib.disp,
+                                               buf->priv.x11.xlib.win,
+                                               buf->priv.x11.xlib.vis,
+                                               buf->priv.x11.xlib.depth,
+                                               buf->h, buf->w);
+   if (!buf->priv.swapper)
+     {
+        free(buf);
+        return NULL;
+     }
+   
+   eina_array_step_set(&buf->priv.onebuf_regions, sizeof (Eina_Array), 8);
+   
+#ifdef WORDS_BIGENDIAN
+   if (evas_xlib_swapper_byte_order_get(buf->priv.swapper) == LSBFirst)
+     buf->priv.x11.xlib.swap = 1;
+   if (evas_xlib_swapper_bit_order_get(buf->priv.swapper) == MSBFirst)
+     buf->priv.x11.xlib.bit_swap = 1;
+#else
+   if (evas_xlib_swapper_byte_order_get(buf->priv.swapper) == MSBFirst)
+     buf->priv.x11.xlib.swap = 1;
+   if (evas_xlib_swapper_bit_order_get(buf->priv.swapper) == MSBFirst)
+     buf->priv.x11.xlib.bit_swap = 1;
+#endif
+   if (((vis->class == TrueColor) || (vis->class == DirectColor)) &&
+       (x_depth > 8))
+     {
+        buf->priv.mask.r = (DATA32) vis->red_mask;
+        buf->priv.mask.g = (DATA32) vis->green_mask;
+        buf->priv.mask.b = (DATA32) vis->blue_mask;
+        if (buf->priv.x11.xlib.swap)
+          {
+             SWAP32(buf->priv.mask.r);
+             SWAP32(buf->priv.mask.g);
+             SWAP32(buf->priv.mask.b);
+          }
+     }
+   else if ((vis->class == PseudoColor) || (vis->class == StaticColor) ||
+            (vis->class == GrayScale) || (vis->class == StaticGray) ||
+            (x_depth <= 8))
+     {
+        Convert_Pal_Mode pm = PAL_MODE_RGB332;
+        
+        if ((vis->class == GrayScale) || (vis->class == StaticGray))
+          grayscale = 1;
+        if (grayscale)
+          {
+             if (max_colors >= 256) pm = PAL_MODE_GRAY256;
+             else if (max_colors >= 64) pm = PAL_MODE_GRAY64;
+             else if (max_colors >= 16) pm = PAL_MODE_GRAY16;
+             else if (max_colors >= 4) pm = PAL_MODE_GRAY4;
+             else pm = PAL_MODE_MONO;
+          }
+        else
+          {
+             if (max_colors >= 256) pm = PAL_MODE_RGB332;
+             else if (max_colors >= 216) pm = PAL_MODE_RGB666;
+             else if (max_colors >= 128) pm = PAL_MODE_RGB232;
+             else if (max_colors >= 64) pm = PAL_MODE_RGB222;
+             else if (max_colors >= 32) pm = PAL_MODE_RGB221;
+             else if (max_colors >= 16) pm = PAL_MODE_RGB121;
+             else if (max_colors >= 8) pm = PAL_MODE_RGB111;
+             else if (max_colors >= 4) pm = PAL_MODE_GRAY4;
+             else pm = PAL_MODE_MONO;
+          }
+        /* FIXME: only alloc once per display+cmap */
+        buf->priv.pal = evas_software_xlib_x_color_allocate
+          (disp, cmap, vis, pm);
+        if (!buf->priv.pal)
+          {
+             evas_xlib_swapper_free(buf->priv.swapper);
+             free(buf);
+             return NULL;
+          }
+     }
+   d = evas_xlib_swapper_depth_get(buf->priv.swapper);
+   if (buf->priv.pal)
+     {
+        
+        if (buf->rot == 0 || buf->rot == 180)
+          conv_func = evas_common_convert_func_get(0, buf->w, buf->h, d,
+                                                   buf->priv.mask.r,
+                                                   buf->priv.mask.g,
+                                                   buf->priv.mask.b,
+                                                   buf->priv.pal->colors,
+                                                   buf->rot);
+        else if (buf->rot == 90 || buf->rot == 270)
+          conv_func = evas_common_convert_func_get(0, buf->h, buf->w, d,
+                                                   buf->priv.mask.r,
+                                                   buf->priv.mask.g,
+                                                   buf->priv.mask.b,
+                                                   buf->priv.pal->colors,
+                                                   buf->rot);
+     }
+   else
+     {
+        if (buf->rot == 0 || buf->rot == 180)
+          conv_func = evas_common_convert_func_get(0, buf->w, buf->h, d,
+                                                   buf->priv.mask.r,
+                                                   buf->priv.mask.g,
+                                                   buf->priv.mask.b,
+                                                   PAL_MODE_NONE,
+                                                   buf->rot);
+        else if (buf->rot == 90 || buf->rot == 270)
+          conv_func = evas_common_convert_func_get(0, buf->h, buf->w, d,
+                                                   buf->priv.mask.r,
+                                                   buf->priv.mask.g,
+                                                   buf->priv.mask.b,
+                                                   PAL_MODE_NONE,
+                                                   buf->rot);
+     }
+   if (!conv_func)
+     {
+        ERR("At depth: %i, RGB format mask: %08x %08x %08x, "
+            "Palette mode: %i. "
+            "Not supported by compiled in converters!",
+            buf->priv.x11.xlib.depth,
+            buf->priv.mask.r,
+            buf->priv.mask.g,
+            buf->priv.mask.b,
+            buf->priv.pal ? (int)buf->priv.pal->colors : -1);
+     }
+   return buf;
+}
+
+RGBA_Image *
+evas_software_xlib_swapbuf_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch)
+{
+   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, buf->w, buf->h);
+   if ((w <= 0) || (h <= 0)) return NULL;
+   // if rotation is 0, and 32bit argb, we can use the buffer directly
+   if ((buf->rot == 0) &&
+       (buf->priv.mask.r == 0xff0000) &&
+       (buf->priv.mask.g == 0x00ff00) &&
+       (buf->priv.mask.b == 0x0000ff))
+     {
+        RGBA_Image *im;
+        void *data;
+        int bpl = 0;
+        Eina_Rectangle *rect;
+
+        im = buf->priv.onebuf;
+        if (!im)
+          {
+             int ww = 0, hh = 0;
+             int d, bpp;
+
+             d = evas_xlib_swapper_depth_get(buf->priv.swapper);
+             bpp = d / 8;
+
+             data = evas_xlib_swapper_buffer_map(buf->priv.swapper, &bpl,   &(ww), &(hh));
+#ifdef EVAS_CSERVE2
+             if (evas_cserve2_use_get())
+               im = (RGBA_Image *)evas_cache2_image_data(evas_common_image_cache2_get(),
+                                                         bpl/bpp, hh, data,
+                                                         buf->priv.destination_alpha,
+                                                         EVAS_COLORSPACE_ARGB8888);
+             else
+#endif
+               im = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(),
+                                                        bpl/bpp, hh, data,
+                                                        buf->priv.destination_alpha,
+                                                        EVAS_COLORSPACE_ARGB8888);
+             buf->priv.onebuf = im;
+             if (!im) return NULL;
+          }
+        rect = eina_rectangle_new(x, y, w, h);
+        if (!eina_array_push(&buf->priv.onebuf_regions, rect))
+          {
+#ifdef EVAS_CSERVE2
+             if (evas_cserve2_use_get())
+               evas_cache2_image_close(&im->cache_entry);
+             else
+#endif
+               evas_cache_image_drop(&im->cache_entry);
+             eina_rectangle_free(rect);
+             return NULL;
+          }
+        
+        // the clip region of the onebuf to render
+        *cx = x;
+        *cy = y;
+        *cw = w;
+        *ch = h;
+        return im;
+     }
+   else
+     {
+        RGBA_Image         *im;
+        Eina_Rectangle *rect;
+        
+        rect = eina_rectangle_new(x, y, w, h);
+        if (!rect) return NULL;
+#ifdef EVAS_CSERVE2
+        if (evas_cserve2_use_get())
+          im = (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get());
+        else
+#endif
+          im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
+        if (!im)
+          {
+             eina_rectangle_free(rect);
+             return NULL;
+          }
+        im->cache_entry.flags.alpha |= buf->priv.destination_alpha ? 1 : 0;
+#ifdef EVAS_CSERVE2
+        if (evas_cserve2_use_get())
+          evas_cache2_image_surface_alloc(&im->cache_entry, w, h);
+        else
+#endif
+          evas_cache_image_surface_alloc(&im->cache_entry, w, h);
+        im->extended_info = rect;
+        buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im);
+        
+        // the region is the update image
+        *cx = 0;
+        *cy = 0;
+        *cw = w;
+        *ch = h;
+        return im;
+     }
+   return NULL;
+}
+
+void
+evas_software_xlib_swapbuf_free_region_for_update(Outbuf *buf EINA_UNUSED, RGBA_Image *update EINA_UNUSED)
+{
+   /* no need to do anything - they are cleaned up on flush */
+}
+
+void
+evas_software_xlib_swapbuf_flush(Outbuf *buf)
+{
+   int buf_w, buf_h, temp;
+   if (!buf->priv.pending_writes)
+     {
+        Eina_Rectangle *rects, *rect;
+        Eina_Array_Iterator it;
+        unsigned int n, i;
+        RGBA_Image *im;
+
+        n = eina_array_count_get(&buf->priv.onebuf_regions);
+        if (n == 0) return;
+        rects = alloca(n * sizeof(Eina_Rectangle));
+        EINA_ARRAY_ITER_NEXT(&buf->priv.onebuf_regions, i, rect, it)
+          {
+             rects[i] = *rect;
+             eina_rectangle_free(rect);
+          }
+        evas_xlib_swapper_buffer_unmap(buf->priv.swapper);
+        evas_xlib_swapper_buffer_size_get(buf->priv.swapper, &buf_w, &buf_h);
+        if ((buf->rot == 90) || (buf->rot == 270))
+          {
+             temp = buf_w;
+             buf_w = buf_h;
+             buf_h = temp;
+          }
+
+        if ((buf_w == buf->w) && (buf_h == buf->h))
+           evas_xlib_swapper_swap(buf->priv.swapper, rects, n);
+
+        eina_array_clean(&buf->priv.onebuf_regions);
+        im = buf->priv.onebuf;
+        buf->priv.onebuf = NULL;
+        if (im)
+          {
+#ifdef EVAS_CSERVE2
+             if (evas_cserve2_use_get())
+               evas_cache2_image_close(&im->cache_entry);
+             else
+#endif
+               evas_cache_image_drop(&im->cache_entry);
+          }
+     }
+   else
+     {
+        RGBA_Image *im;
+        Eina_Rectangle *rects;
+        unsigned int n, i = 0;
+        
+        n = eina_list_count(buf->priv.pending_writes);
+        if (n == 0) return;
+        rects = alloca(n * sizeof(Eina_Rectangle));
+        EINA_LIST_FREE(buf->priv.pending_writes, im)
+          {
+             Eina_Rectangle *rect = im->extended_info;
+             int x, y, w, h;
+             
+             x = rect->x; y = rect->y; w = rect->w; h = rect->h;
+             if (buf->rot == 0)
+               {
+                  rects[i].x = x;
+                  rects[i].y = y;
+               }
+             else if (buf->rot == 90)
+               {
+                  rects[i].x = y;
+                  rects[i].y = buf->w - x - w;
+               }
+             else if (buf->rot == 180)
+               {
+                  rects[i].x = buf->w - x - w;
+                  rects[i].y = buf->h - y - h;
+               }
+             else if (buf->rot == 270)
+               {
+                  rects[i].x = buf->h - y - h;
+                  rects[i].y = x;
+               }
+             if ((buf->rot == 0) || (buf->rot == 180))
+               {
+                  rects[i].w = w;
+                  rects[i].h = h;
+               }
+             else if ((buf->rot == 90) || (buf->rot == 270))
+               {
+                  rects[i].w = h;
+                  rects[i].h = w;
+               }
+             eina_rectangle_free(rect);
+#ifdef EVAS_CSERVE2
+             if (evas_cserve2_use_get())
+               evas_cache2_image_close(&im->cache_entry);
+             else
+#endif
+               evas_cache_image_drop(&im->cache_entry);
+             i++;
+          }
+        evas_xlib_swapper_buffer_unmap(buf->priv.swapper);
+        evas_xlib_swapper_buffer_size_get(buf->priv.swapper, &buf_w, &buf_h);
+        if ((buf->rot == 90) || (buf->rot == 270))
+          {
+             temp = buf_w;
+             buf_w = buf_h;
+             buf_h = temp;
+          }
+
+        if ((buf_w == buf->w) && (buf_h == buf->h))
+           evas_xlib_swapper_swap(buf->priv.swapper, rects, n);
+
+//        evas_xlib_swapper_swap(buf->priv.swapper, NULL, 0);
+     }
+}
+
+void
+evas_software_xlib_swapbuf_idle_flush(Outbuf *buf)
+{
+   return;
+   buf = NULL;
+}
+
+void
+evas_software_xlib_swapbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, int y, int w, int h)
+{
+   Gfx_Func_Convert conv_func = NULL;
+   Eina_Rectangle r = { 0, 0, 0, 0 }, pr;
+   int d, bpl = 0, wid, bpp, rx = 0, ry = 0, ww = 0, hh = 0;
+   DATA32 *src_data;
+   DATA8 *dst_data;
+
+   if (!buf->priv.pending_writes) return;
+   d = evas_xlib_swapper_depth_get(buf->priv.swapper);
+   bpp = d / 8;
+   if (bpp <= 0) return;
+
+   if (buf->priv.pal)
+     {
+       if ((buf->rot == 0) || (buf->rot == 180))
+         conv_func = evas_common_convert_func_get(0, w, h, d,
+                                                   buf->priv.mask.r,
+                                                  buf->priv.mask.g,
+                                                   buf->priv.mask.b,
+                                                  buf->priv.pal->colors,
+                                                   buf->rot);
+       else if ((buf->rot == 90) || (buf->rot == 270))
+         conv_func = evas_common_convert_func_get(0, h, w, d,
+                                                  buf->priv.mask.r,
+                                                  buf->priv.mask.g,
+                                                   buf->priv.mask.b,
+                                                  buf->priv.pal->colors,
+                                                   buf->rot);
+     }
+   else
+     {
+       if ((buf->rot == 0) || (buf->rot == 180))
+         conv_func = evas_common_convert_func_get(0, w, h, d,
+                                                  buf->priv.mask.r,
+                                                  buf->priv.mask.g,
+                                                   buf->priv.mask.b,
+                                                  PAL_MODE_NONE,
+                                                   buf->rot);
+       else if ((buf->rot == 90) || (buf->rot == 270))
+         conv_func = evas_common_convert_func_get(0, h, w, d,
+                                                  buf->priv.mask.r,
+                                                  buf->priv.mask.g,
+                                                   buf->priv.mask.b,
+                                                  PAL_MODE_NONE,
+                                                   buf->rot);
+     }
+   if (!conv_func) return;
+   if (buf->rot == 0)
+     {
+        r.x = x;
+        r.y = y;
+     }
+   else if (buf->rot == 90)
+     {
+        r.x = y;
+        r.y = buf->w - x - w;
+     }
+   else if (buf->rot == 180)
+     {
+        r.x = buf->w - x - w;
+        r.y = buf->h - y - h;
+     }
+   else if (buf->rot == 270)
+     {
+        r.x = buf->h - y - h;
+        r.y = x;
+     }
+   if ((buf->rot == 0) || (buf->rot == 180))
+     {
+        r.w = w;
+        r.h = h;
+     }
+   else if ((buf->rot == 90) || (buf->rot == 270))
+     {
+        r.w = h;
+        r.h = w;
+     }
+   src_data = update->image.data;
+   if (!src_data) return;
+    if ((buf->rot == 0) || (buf->rot == 180))
+     {
+        dst_data = evas_xlib_swapper_buffer_map(buf->priv.swapper, &bpl,
+                                                &(ww), &(hh));
+        if (!dst_data) return;
+        if (buf->rot == 0)
+          {
+             RECTS_CLIP_TO_RECT(r.x, r.y, r.w, r.h, 0, 0, ww, hh);
+             dst_data += (bpl * r.y) + (r.x * bpp);
+             w -= rx;
+          }
+        else if (buf->rot == 180)
+          {
+             pr = r;
+             RECTS_CLIP_TO_RECT(r.x, r.y, r.w, r.h, 0, 0, ww, hh);
+             rx = pr.w - r.w; ry = pr.h - r.h;
+             src_data += (update->cache_entry.w * ry) + rx;
+             w -= rx;
+          }
+     }
+   else
+     {
+        dst_data = evas_xlib_swapper_buffer_map(buf->priv.swapper, &bpl,
+                                                &(ww), &(hh));
+        if (!dst_data) return;
+        if (buf->rot == 90)
+          {
+             pr = r;
+             RECTS_CLIP_TO_RECT(r.x, r.y, r.w, r.h, 0, 0, ww, hh);
+             rx = pr.w - r.w; ry = pr.h - r.h;
+             src_data += ry;
+             w -= ry;
+          }
+        else if (buf->rot == 270)
+          {
+             pr = r;
+             RECTS_CLIP_TO_RECT(r.x, r.y, r.w, r.h, 0, 0, ww, hh);
+             rx = pr.w - r.w; ry = pr.h - r.h;
+             src_data += (update->cache_entry.w * rx);
+             w -= ry;
+          }
+     }
+ if ((r.w <= 0) || (r.h <= 0)) return;
+   wid = bpl / bpp;
+   dst_data += (bpl * r.y) + (r.x * bpp);
+   if (buf->priv.pal)
+     conv_func(src_data, dst_data, 
+               update->cache_entry.w - w,
+               wid - r.w,
+               r.w, r.h,
+                x + rx, y + ry,
+               buf->priv.pal->lookup);
+   else
+     conv_func(src_data, dst_data, 
+               update->cache_entry.w - w,
+               wid - r.w,
+               r.w, r.h,
+               x + rx, y + ry,
+               NULL);
+}
+
+void
+evas_software_xlib_swapbuf_reconfigure(Outbuf *buf, int w, int h, int rot,
+                                       Outbuf_Depth depth)
+{
+   if ((w == buf->w) && (h == buf->h) && (rot == buf->rot) &&
+       (depth == buf->depth))
+     return;
+   buf->w = w;
+   buf->h = h;
+   buf->rot = rot;
+   evas_xlib_swapper_free(buf->priv.swapper);
+   if ((buf->rot == 0) || (buf->rot == 180))
+     buf->priv.swapper = evas_xlib_swapper_new(buf->priv.x11.xlib.disp,
+                                               buf->priv.x11.xlib.win,
+                                               buf->priv.x11.xlib.vis,
+                                               buf->priv.x11.xlib.depth,
+                                               buf->w, buf->h);
+   else if ((buf->rot == 90) || (buf->rot == 270))
+     buf->priv.swapper = evas_xlib_swapper_new(buf->priv.x11.xlib.disp,
+                                               buf->priv.x11.xlib.win,
+                                               buf->priv.x11.xlib.vis,
+                                               buf->priv.x11.xlib.depth,
+                                               buf->h, buf->w);
+}
+
+int
+evas_software_xlib_swapbuf_get_rot(Outbuf * buf)
+{
+   return buf->rot;
+}
+
+Eina_Bool
+evas_software_xlib_swapbuf_alpha_get(Outbuf *buf)
+{
+   return buf->priv.destination_alpha;
+}
+
+int
+evas_software_xlib_swapbuf_buffer_state_get(Outbuf *buf)
+{
+   int mode;
+   if (!buf->priv.swapper) return MODE_FULL;
+   mode = evas_xlib_swapper_buffer_state_get(buf->priv.swapper);
+   return mode;
+}
diff --git a/src/modules/engines/software_x11/evas_xlib_swapbuf.h b/src/modules/engines/software_x11/evas_xlib_swapbuf.h
new file mode 100644 (file)
index 0000000..f8276a0
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef EVAS_XLIB_SWAPBUF_H
+#define EVAS_XLIB_SWAPBUF_H
+
+
+#include "evas_engine.h"
+
+
+void         evas_software_xlib_swapbuf_init(void);
+void         evas_software_xlib_swapbuf_free(Outbuf *buf);
+Outbuf      *evas_software_xlib_swapbuf_setup_x(int          w,
+                                                int          h,
+                                                int          rot,
+                                                Outbuf_Depth depth,
+                                                Display     *disp,
+                                                Drawable     draw,
+                                                Visual      *vis,
+                                                Colormap     cmap,
+                                                int          x_depth,
+                                                int          grayscale,
+                                                int          max_colors,
+                                                Pixmap       mask,
+                                                int          shape_dither,
+                                                int          destination_alpha);
+RGBA_Image  *evas_software_xlib_swapbuf_new_region_for_update(Outbuf *buf,
+                                                              int     x,
+                                                              int     y,
+                                                              int     w,
+                                                              int     h,
+                                                              int    *cx,
+                                                              int    *cy,
+                                                              int    *cw,
+                                                              int    *ch);
+void         evas_software_xlib_swapbuf_free_region_for_update(Outbuf     *buf,
+                                                               RGBA_Image *update);
+void         evas_software_xlib_swapbuf_flush(Outbuf *buf);
+void         evas_software_xlib_swapbuf_idle_flush(Outbuf *buf);
+void         evas_software_xlib_swapbuf_push_updated_region(Outbuf     *buf,
+                                                            RGBA_Image *update,
+                                                            int         x,
+                                                            int         y,
+                                                            int         w,
+                                                            int         h);
+void         evas_software_xlib_swapbuf_reconfigure(Outbuf      *buf,
+                                                    int          w,
+                                                    int          h,
+                                                    int          rot,
+                                                    Outbuf_Depth depth);
+int          evas_software_xlib_swapbuf_get_rot(Outbuf *buf);
+void         evas_software_xlib_swapbuf_rotation_set(Outbuf *buf,
+                                                     int     rot);
+Eina_Bool    evas_software_xlib_swapbuf_alpha_get(Outbuf *buf);
+int          evas_software_xlib_swapbuf_buffer_state_get(Outbuf *buf);
+#endif
diff --git a/src/modules/engines/software_x11/evas_xlib_swapper.c b/src/modules/engines/software_x11/evas_xlib_swapper.c
new file mode 100755 (executable)
index 0000000..91cfe50
--- /dev/null
@@ -0,0 +1,985 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "evas_common.h"
+#include "evas_macros.h"
+#include "evas_xlib_swapper.h"
+
+#ifdef HAVE_DLSYM
+# include <dlfcn.h>      /* dlopen,dlclose,etc */
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+
+#if 0
+// X(shm)image emulation of multiple buffers + swapping /////////////////////
+typedef struct
+{
+   XImage          *xim;
+   XShmSegmentInfo  shm_info;
+   void            *data;
+   int              w, h, bpl;
+   Eina_Bool        shm : 1;
+   Eina_Bool        valid : 1;
+} Buffer;
+
+struct _X_Swapper
+{
+   Display  *disp;
+   Drawable  draw;
+   Visual   *vis;
+   GC        gc;
+   Buffer    buf[3];
+   int       w, h, depth;
+   int       buf_cur, buf_num;
+   Eina_Bool mapped: 1;
+};
+
+static Eina_Bool _x_err = EINA_FALSE;
+
+static void
+_x_err_hand(Display *d EINA_UNUSED, XErrorEvent *ev EINA_UNUSED)
+{
+   _x_err = 1;
+   return;
+}
+
+static Eina_Bool
+_buf_new(X_Swapper *swp, Buffer *buf)
+{
+   buf->w = swp->w;
+   buf->h = swp->h;
+
+   // try shm first
+   buf->xim = XShmCreateImage(swp->disp, swp->vis, swp->depth, ZPixmap,
+                              NULL, &(buf->shm_info), buf->w, buf->h);
+   if (buf->xim)
+     {
+        buf->bpl = buf->xim->bytes_per_line;
+
+        buf->shm_info.shmid = shmget(IPC_PRIVATE, buf->bpl * buf->h,
+                                     IPC_CREAT | 0777);
+        if (buf->shm_info.shmid >= 0)
+          {
+             buf->shm_info.readOnly = False;
+             buf->shm_info.shmaddr = buf->data = buf->xim->data =
+               shmat(buf->shm_info.shmid, 0, 0);
+             if (buf->shm_info.shmaddr != ((void *)-1))
+               {
+                  XErrorHandler ph;
+
+                  XSync(swp->disp, False);
+                  _x_err = EINA_FALSE;
+                  ph = XSetErrorHandler((XErrorHandler)_x_err_hand);
+                  XShmAttach(swp->disp, &(buf->shm_info));
+                  XSync(swp->disp, False);
+                  XSetErrorHandler((XErrorHandler)ph);
+                  if (!_x_err)
+                    {
+                       buf->shm = EINA_TRUE;
+                    }
+                  else
+                    {
+                       shmdt(buf->shm_info.shmaddr);
+                       shmctl(buf->shm_info.shmid, IPC_RMID, 0);
+                       XDestroyImage(buf->xim);
+                       buf->xim = NULL;
+                    }
+               }
+             else
+               {
+                  shmdt(buf->shm_info.shmaddr);
+                  shmctl(buf->shm_info.shmid, IPC_RMID, 0);
+                  XDestroyImage(buf->xim);
+                  buf->xim = NULL;
+               }
+          }
+        else
+          {
+             XDestroyImage(buf->xim);
+             buf->xim = NULL;
+          }
+     }
+
+   if (!buf->xim) // shm failed - try normal ximage
+     {
+        buf->xim = XCreateImage(swp->disp, swp->vis, swp->depth, ZPixmap,
+                                0, NULL, buf->w, buf->h, 32, 0);
+        if (!buf->xim) return EINA_FALSE;
+        buf->bpl = buf->xim->bytes_per_line;
+        buf->data = buf->xim->data = malloc(buf->bpl * buf->h);
+        if (!buf->data)
+          {
+             XDestroyImage(buf->xim);
+             buf->xim = NULL;
+             return EINA_FALSE;
+          }
+     }
+   return EINA_TRUE;
+}
+
+static void
+_buf_free(X_Swapper *swp, Buffer *buf)
+{
+   if (!buf->xim) return;
+   if (buf->shm)
+     {
+        XShmDetach(swp->disp, &(buf->shm_info));
+        XDestroyImage(buf->xim);
+        shmdt(buf->shm_info.shmaddr);
+        shmctl(buf->shm_info.shmid, IPC_RMID, 0);
+     }
+   else
+     {
+        XDestroyImage(buf->xim);
+     }
+   buf->xim = NULL;
+   buf->shm = EINA_FALSE;
+}
+
+static void
+_buf_put(X_Swapper *swp, Buffer *buf, Eina_Rectangle *rects, int nrects)
+{
+   Region tmpr;
+   int i;
+
+   if (!buf->xim) return;
+   tmpr = XCreateRegion();
+   if (rects)
+     {
+        for (i = 0; i < nrects; i++)
+          {
+             XRectangle xr;
+
+             xr.x = rects[i].x; xr.y = rects[i].y;
+             xr.width = rects[i].w; xr.height = rects[i].h;
+             XUnionRectWithRegion(&xr, tmpr, tmpr);
+          }
+     }
+   else
+     {
+        XRectangle xr;
+
+        xr.x = 0; xr.y = 0;
+        xr.width = buf->w; xr.height = buf->h;
+        XUnionRectWithRegion(&xr, tmpr, tmpr);
+     }
+   XSetRegion(swp->disp, swp->gc, tmpr);
+   XDestroyRegion(tmpr);
+   if (buf->shm)
+     {
+        XShmPutImage(swp->disp, swp->draw, swp->gc, buf->xim, 0, 0, 0, 0,
+                     buf->w, buf->h, False);
+     }
+   else
+     {
+        XPutImage(swp->disp, swp->draw, swp->gc, buf->xim, 0, 0, 0, 0,
+                  buf->w, buf->h);
+     }
+   XSync(swp->disp, False);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+X_Swapper *
+evas_xlib_swapper_new(Display *disp, Drawable draw, Visual *vis,
+                      int depth, int w, int h)
+{
+   X_Swapper *swp;
+   XGCValues gcv;
+   int i;
+
+   int nbuf = 3; // pretend we are triple buffered
+
+   swp = calloc(1, sizeof(X_Swapper));
+   if (!swp) return NULL;
+   swp->disp = disp;
+   swp->draw = draw;
+   swp->vis = vis;
+   swp->depth = depth;
+   swp->w = w;
+   swp->h = h;
+   swp->buf_num = nbuf;
+   swp->gc = XCreateGC(swp->disp, swp->draw, 0, &gcv);
+   for (i = 0; i < swp->buf_num; i++)
+     {
+        if (!_buf_new(swp, &(swp->buf[i])))
+          {
+             evas_xlib_swapper_free(swp);
+             return NULL;
+          }
+     }
+   return swp;
+}
+
+void
+evas_xlib_swapper_free(X_Swapper *swp)
+{
+   int i;
+
+   for (i = 0; i < swp->buf_num; i++)
+     {
+        _buf_free(swp, &(swp->buf[i]));
+     }
+   XFreeGC(swp->disp, swp->gc);
+   free(swp);
+}
+
+void *
+evas_xlib_swapper_buffer_map(X_Swapper *swp, int *bpl, int *w, int *h)
+{
+   swp->mapped = EINA_TRUE;
+   if (bpl) *bpl = swp->buf[swp->buf_cur].bpl;
+   if (w) *w = swp->w;
+   if (h) *h = swp->h;
+   return swp->buf[swp->buf_cur].data;
+}
+
+void
+evas_xlib_swapper_buffer_unmap(X_Swapper *swp)
+{
+   swp->mapped = EINA_FALSE;
+}
+
+void
+evas_xlib_swapper_swap(X_Swapper *swp, Eina_Rectangle *rects, int nrects)
+{
+   int n;
+
+   n = swp->buf_cur;
+   _buf_put(swp, &(swp->buf[n]), rects, nrects);
+   swp->buf[n].valid = 1;
+   swp->buf_cur = (swp->buf_cur + 1) % swp->buf_num;
+}
+
+int
+evas_xlib_swapper_buffer_state_get(X_Swapper *swp)
+{
+   int i, n, count = 0;
+
+   for (i = 0; i < swp->buf_num; i++)
+     {
+        n = (swp->buf_num + swp->buf_cur - (i)) % swp->buf_num;
+        if (swp->buf[n].valid) count++;
+        else break;
+     }
+   if (count == swp->buf_num)
+     {
+        if (count == 1) return MODE_COPY;
+        else if (count == 2) return MODE_DOUBLE;
+        else if (count == 3) return MODE_TRIPLE;
+     }
+   return MODE_FULL;
+}
+
+int
+evas_xlib_swapper_depth_get(X_Swapper *swp)
+{
+   return swp->buf[0].xim->bits_per_pixel;
+}
+
+int
+evas_xlib_swapper_byte_order_get(X_Swapper *swp)
+{
+   return swp->buf[0].xim->byte_order;
+}
+
+int
+evas_xlib_swapper_bit_order_get(X_Swapper *swp)
+{
+   return swp->buf[0].xim->bitmap_bit_order;
+}
+
+#else
+
+
+
+
+
+
+
+
+// DRM/DRI buffer swapping+access (driver specific) /////////////////////
+
+static Eina_Bool tried = EINA_FALSE;
+////////////////////////////////////
+//libdrm.so.2
+static void *drm_lib = NULL;
+
+typedef unsigned int drm_magic_t;
+static int (*sym_drmGetMagic) (int fd, drm_magic_t *magic) = NULL;
+
+////////////////////////////////////
+// libtbm.so.1
+#define TBM_DEVICE_CPU 1
+#define TBM_OPTION_READ     (1 << 0)
+#define TBM_OPTION_WRITE    (1 << 1)
+static void *tbm_lib = NULL;
+
+typedef struct _tbm_bufmgr *tbm_bufmgr;
+typedef struct _tbm_bo *tbm_bo;
+
+typedef union _tbm_bo_handle
+{
+   void     *ptr;
+   int32_t  s32;
+   uint32_t u32;
+   int64_t  s64;
+   uint64_t u64;
+} tbm_bo_handle;
+
+static tbm_bo (*sym_tbm_bo_import) (tbm_bufmgr bufmgr, unsigned int key) = NULL;
+static tbm_bo_handle (*sym_tbm_bo_map) (tbm_bo bo, int device, int opt) = NULL;
+static int (*sym_tbm_bo_unmap)  (tbm_bo bo) = NULL;
+static void (*sym_tbm_bo_unref) (tbm_bo bo) = NULL;
+static tbm_bufmgr (*sym_tbm_bufmgr_init) (int fd) = NULL;
+static void (*sym_tbm_bufmgr_deinit) (tbm_bufmgr bufmgr) = NULL;
+////////////////////////////////////
+// libdri2.so.0
+#define DRI2BufferBackLeft 1
+static void *dri_lib = NULL;
+
+typedef unsigned long long CD64;
+
+typedef struct
+{
+   unsigned int attachment;
+   unsigned int name;
+   unsigned int pitch;
+   unsigned int cpp;
+   unsigned int flags;
+} DRI2Buffer;
+
+#define DRI2_BUFFER_TYPE_WINDOW 0x0
+#define DRI2_BUFFER_TYPE_PIXMAP 0x1
+#define DRI2_BUFFER_TYPE_FB     0x2
+
+typedef union
+{
+   unsigned int flags;
+   struct
+     {
+        unsigned int type:1;
+        unsigned int is_framebuffer:1;
+        unsigned int is_mapped:1;
+        unsigned int is_reused:1;
+        unsigned int idx_reuse:3;
+     }
+   data;
+} DRI2BufferFlags;
+
+static DRI2Buffer *(*sym_DRI2GetBuffers) (Display *display, XID drawable, int *width, int *height, unsigned int *attachments, int count, int *outCount) = NULL;
+static Bool (*sym_DRI2QueryExtension) (Display *display, int *eventBase, int *errorBase) = NULL;
+static Bool (*sym_DRI2QueryVersion) (Display *display, int *major, int *minor) = NULL;
+static Bool (*sym_DRI2Connect) (Display *display, XID window, char **driverName, char **deviceName) = NULL;
+static Bool (*sym_DRI2Authenticate) (Display *display, XID window, unsigned int magic) = NULL;
+static void (*sym_DRI2CreateDrawable) (Display *display, XID drawable) = NULL;
+static void (*sym_DRI2SwapBuffersWithRegion) (Display *display, XID drawable, XID region, CD64 *count) = NULL;
+static void (*sym_DRI2SwapBuffers) (Display *display, XID drawable, CD64 target_msc, CD64 divisor, CD64 remainder, CD64 *count) = NULL;
+static void (*sym_DRI2DestroyDrawable) (Display *display, XID handle) = NULL;
+static Bool (*sym_DRI2QeuryExtensionAndCheckVersion) (Display * dpy, int *eventBase, int *errorBase, int *major, int *minor, int check_major, int check_minor) = NULL;
+
+
+////////////////////////////////////
+// libXfixes.so.3
+static void *xfixes_lib = NULL;
+
+static Bool (*sym_XFixesQueryExtension) (Display *display, int *event_base_return, int *error_base_return) = NULL;
+static Status (*sym_XFixesQueryVersion) (Display *display, int *major_version_return, int *minor_version_return) = NULL;
+static XID (*sym_XFixesCreateRegion) (Display *display, XRectangle *rectangles, int nrectangles) = NULL;
+static void (*sym_XFixesDestroyRegion) (Display *dpy, XID region) = NULL;
+
+////////////////////////////////////////////////////////////////////////////
+#define MAX_BO_CACHE 4
+
+typedef struct
+{
+   unsigned int name;
+   tbm_bo   buf_bo;
+} Buffer;
+
+struct _X_Swapper
+{
+   Display    *disp;
+   Drawable    draw;
+   Visual     *vis;
+   int         w, h, depth;
+   tbm_bo  buf_bo;
+   DRI2Buffer *buf;
+   void       *buf_data;
+   int         buf_w, buf_h;
+   Eina_List  *buf_cache;
+   int         last_count;
+   Eina_Bool   mapped: 1;
+};
+
+static int inits = 0;
+static int xfixes_ev_base = 0, xfixes_err_base = 0;
+static int xfixes_major = 0, xfixes_minor = 0;
+static int dri2_ev_base = 0, dri2_err_base = 0;
+static int dri2_major = 0, dri2_minor = 0;
+static int dri2_check_major = 0, dri2_check_minor = 0;
+static int drm_fd = -1;
+static tbm_bufmgr bufmgr = NULL;
+static int swap_debug = -1;
+
+static Eina_Bool
+_drm_init(Display *disp, int scr)
+{
+   char *drv_name = NULL, *dev_name = NULL;
+   drm_magic_t magic = 0;
+
+   if (swap_debug == -1)
+     {
+        if (getenv("EVAS_SWAPPER_DEBUG")) swap_debug = 1;
+        else swap_debug = 0;
+     }
+
+   if (xfixes_lib) return EINA_TRUE;
+   if ((tried) && (!xfixes_lib)) return EINA_FALSE;
+   tried = EINA_TRUE;
+   drm_lib = dlopen("libdrm.so.2", RTLD_NOW | RTLD_LOCAL);
+   if (!drm_lib)
+     {
+        if (swap_debug) ERR("Can't load libdrm.so.2");
+        goto err;
+     }
+   tbm_lib = dlopen("libtbm.so.1", RTLD_NOW | RTLD_LOCAL);
+   if (!tbm_lib)
+     {
+        if (swap_debug) ERR("Can't load libtbm.so.1");
+        goto err;
+     }
+   dri_lib = dlopen("libdri2.so.0", RTLD_NOW | RTLD_LOCAL);
+   if (!dri_lib)
+     {
+        if (swap_debug) ERR("Can't load libdri2.so.0");
+        goto err;
+     }
+   xfixes_lib = dlopen("libXfixes.so.3", RTLD_NOW | RTLD_LOCAL);
+   if (!xfixes_lib)
+     {
+        if (swap_debug) ERR("Can't load libXfixes.so.3");
+        goto err;
+     }
+
+#define SYM(l, x) \
+   do { sym_ ## x = dlsym(l, #x); \
+      if (!sym_ ## x) { \
+         if (swap_debug) ERR("Can't load symbol "#x); \
+         goto err; \
+      } \
+   } while (0)
+
+   SYM(drm_lib, drmGetMagic);
+
+   SYM(tbm_lib, tbm_bo_import);
+   SYM(tbm_lib, tbm_bo_map);
+   SYM(tbm_lib, tbm_bo_unmap);
+   SYM(tbm_lib, tbm_bo_unref);
+   SYM(tbm_lib, tbm_bufmgr_init);
+   SYM(tbm_lib, tbm_bufmgr_deinit);
+
+   SYM(dri_lib, DRI2GetBuffers);
+   SYM(dri_lib, DRI2QueryExtension);
+   SYM(dri_lib, DRI2QueryVersion);
+   SYM(dri_lib, DRI2Connect);
+   SYM(dri_lib, DRI2Authenticate);
+   SYM(dri_lib, DRI2CreateDrawable);
+   SYM(dri_lib, DRI2SwapBuffersWithRegion);
+   SYM(dri_lib, DRI2SwapBuffers);
+   SYM(dri_lib, DRI2DestroyDrawable);
+   SYM(dri_lib, DRI2QeuryExtensionAndCheckVersion);
+
+   SYM(xfixes_lib, XFixesQueryExtension);
+   SYM(xfixes_lib, XFixesQueryVersion);
+   SYM(xfixes_lib, XFixesCreateRegion);
+   SYM(xfixes_lib, XFixesDestroyRegion);
+
+   if (!sym_XFixesQueryExtension(disp, &xfixes_ev_base, &xfixes_err_base))
+     {
+        if (swap_debug) ERR("XFixes extension not in xserver");
+        goto err;
+     }
+   sym_XFixesQueryVersion(disp, &xfixes_major, &xfixes_minor);
+
+#if 1
+   if (!sym_DRI2QeuryExtensionAndCheckVersion(disp, &dri2_ev_base, &dri2_err_base, &dri2_major, &dri2_minor, dri2_check_major, dri2_check_minor))
+     {
+        if (swap_debug) ERR("Not supported by DRI2 version(%i.%i). DRI2 version in Xserver(%i, %i)",
+                            dri2_check_major, dri2_check_minor, dri2_major, dri2_minor);
+        goto err;
+     }
+#else
+   if (!sym_DRI2QueryExtension(disp, &dri2_ev_base, &dri2_err_base))
+     {
+        if (swap_debug) ERR("DRI2 extension not in xserver");
+        goto err;
+     }
+   if (!sym_DRI2QueryVersion(disp, &dri2_major, &dri2_minor))
+     {
+        if (swap_debug) ERR("DRI2 query version failed");
+        goto err;
+     }
+   if (dri2_minor < 99)
+     {
+        if (swap_debug) ERR("Not supported by DRI2 version(%i.%i)",
+                            dri2_major, dri2_minor);
+        goto err;
+     }
+#endif
+   if (!sym_DRI2Connect(disp, RootWindow(disp, scr), &drv_name, &dev_name))
+     {
+        if (swap_debug) ERR("DRI2 connect failed on screen %i", scr);
+        goto err;
+     }
+   drm_fd = open(dev_name, O_RDWR);
+   if (drm_fd < 0)
+     {
+        if (swap_debug) ERR("DRM FD open of '%s' failed", dev_name);
+        goto err;
+     }
+   if (sym_drmGetMagic(drm_fd, &magic))
+     {
+        if (swap_debug) ERR("DRM get magic failed");
+        goto err;
+     }
+   if (!sym_DRI2Authenticate(disp, RootWindow(disp, scr),
+                             (unsigned int)magic))
+     {
+        if (swap_debug) ERR("DRI2 authenticate failed with magic 0x%x on screen %i", (unsigned int)magic, scr);
+        goto err;
+     }
+
+   if (!(bufmgr = sym_tbm_bufmgr_init(drm_fd)))
+     {
+        if (swap_debug) ERR("DRM bufmgr init failed");
+        goto err;
+     }
+   if (drv_name)
+     {
+        XFree(drv_name);
+     }
+   XFree(dev_name);
+   return EINA_TRUE;
+err:
+   if (drm_fd >= 0)
+     {
+        close(drm_fd);
+        drm_fd = -1;
+     }
+   if (drm_lib)
+     {
+        dlclose(drm_lib);
+        drm_lib = NULL;
+     }
+   if (tbm_lib)
+     {
+        dlclose(tbm_lib);
+        tbm_lib = NULL;
+     }
+   if (dri_lib)
+     {
+        dlclose(dri_lib);
+        dri_lib = NULL;
+     }
+   if (xfixes_lib)
+     {
+        dlclose(xfixes_lib);
+        xfixes_lib = NULL;
+     }
+   if (drv_name)
+     {
+        XFree(drv_name);
+     }
+   if (dev_name)
+     {
+        XFree(dev_name);
+     }
+   return EINA_FALSE;
+}
+
+static void
+_drm_shutdown(void)
+{
+   return;
+   // leave this here as notation on how to shut down stuff - never do it
+   // though, as once shut down, we have to re-init and this could be
+   // expensive especially if u have a single canvas that is changing config
+   // and being shut down and re-initted a few times.
+   if (bufmgr)
+     {
+        sym_tbm_bufmgr_deinit(bufmgr);
+        bufmgr = NULL;
+     }
+   if (drm_fd >= 0) close(drm_fd);
+   drm_fd = -1;
+   dlclose(tbm_lib);
+   tbm_lib = NULL;
+   dlclose(dri_lib);
+   dri_lib = NULL;
+   dlclose(xfixes_lib);
+   xfixes_lib = NULL;
+}
+
+static Eina_Bool
+_drm_setup(X_Swapper *swp)
+{
+   sym_DRI2CreateDrawable(swp->disp, swp->draw);
+   return EINA_TRUE;
+}
+
+static void
+_drm_cleanup(X_Swapper *swp)
+{
+   sym_DRI2DestroyDrawable(swp->disp, swp->draw);
+}
+
+X_Swapper *
+evas_xlib_swapper_new(Display *disp, Drawable draw, Visual *vis,
+                      int depth, int w, int h)
+{
+   X_Swapper *swp;
+
+   if (inits <= 0)
+     {
+        if (!_drm_init(disp, 0)) return NULL;
+     }
+   inits++;
+
+   swp = calloc(1, sizeof(X_Swapper));
+   if (!swp) return NULL;
+   swp->disp = disp;
+   swp->draw = draw;
+   swp->vis = vis;
+   swp->depth = depth;
+   swp->w = w;
+   swp->h = h;
+   swp->last_count = -1;
+   if (!_drm_setup(swp))
+     {
+        inits--;
+        if (inits == 0) _drm_shutdown();
+        free(swp);
+        return NULL;
+     }
+   if (swp->depth == 24)
+     { // need to adjust to 32bpp?? have to check
+        swp->depth = 32;
+     }
+   if (swap_debug) printf("Swapper allocated OK\n");
+   return swp;
+}
+
+void
+evas_xlib_swapper_free(X_Swapper *swp)
+{
+   Buffer *b;
+
+   if (swap_debug) printf("Swapper free\n");
+   if (swp->mapped) evas_xlib_swapper_buffer_unmap(swp);
+   EINA_LIST_FREE(swp->buf_cache, b)
+     {
+        if (swap_debug) printf("Cached buf name %i freed\n", b->name);
+        sym_tbm_bo_unref(b->buf_bo);
+        free(b);
+     }
+   _drm_cleanup(swp);
+   free(swp);
+   inits--;
+   if (inits == 0) _drm_shutdown();
+}
+
+void *
+evas_xlib_swapper_buffer_map(X_Swapper *swp, int *bpl, int *w, int *h)
+{
+   unsigned int attach = DRI2BufferBackLeft;
+   int num;
+   Eina_List *l;
+   Buffer *b;
+   DRI2BufferFlags *flags;
+
+   if (swp->mapped)
+     {
+        if (bpl)
+          {
+             if ((swp->buf) && (swp->buf->pitch > 0)) *bpl = swp->buf->pitch;
+             else *bpl = swp->w * 4;
+          }
+        if (w) *w = swp->w;
+        if (h) *h = swp->h;
+        return swp->buf_data;
+     }
+   swp->buf = sym_DRI2GetBuffers(swp->disp, swp->draw,
+                                 &(swp->buf_w), &(swp->buf_h),
+                                 &attach, 1, &num);
+   if (!swp->buf) return NULL;
+   if (!swp->buf->name) return NULL;
+   flags = (DRI2BufferFlags *)(&(swp->buf->flags));
+   if (!flags->data.is_reused)
+     {
+        if (swap_debug) printf("Buffer cache not reused - clear cache\n");
+        // buffer isnt recycled - nuke the buf cache
+        EINA_LIST_FREE(swp->buf_cache, b)
+          {
+             if (swap_debug) printf("Cached buf name %i freed\n", b->name);
+             sym_tbm_bo_unref(b->buf_bo);
+             free(b);
+          }
+     }
+   else
+     {
+        // find a cache buf entry
+        EINA_LIST_FOREACH(swp->buf_cache, l, b)
+          {
+             if (b->name == swp->buf->name)
+               {
+                  if (swap_debug) printf("Cached buf name %i found\n", b->name);
+                  swp->buf_bo = b->buf_bo;
+                  // LRU - least used at end. found item - promote to front
+                  swp->buf_cache = eina_list_promote_list(swp->buf_cache, l);
+                  break;
+               }
+          }
+     }
+   if (!swp->buf_bo)
+     {
+        swp->buf_bo = sym_tbm_bo_import(bufmgr, swp->buf->name);
+        if (!swp->buf_bo) return NULL;
+        // cache the buf entry
+        b = calloc(1, sizeof(Buffer));
+        b->name = swp->buf->name;
+        b->buf_bo = swp->buf_bo;
+        // put ah head of list
+        swp->buf_cache = eina_list_prepend(swp->buf_cache, b);
+        if (swap_debug) printf("Buffer cache added name %i\n", b->name);
+        // keep bo cache no more than its max size
+        while (eina_list_count(swp->buf_cache) > MAX_BO_CACHE)
+          {
+             if (swap_debug) printf("Buffer cache count %i more than max %i\n", eina_list_count(swp->buf_cache) , MAX_BO_CACHE);
+             l = eina_list_last(swp->buf_cache);
+             if (l)
+               {
+                  b = l->data;
+                  if (swap_debug) printf("Buffer cache overfull - free name %i\n", b->name);
+                  swp->buf_cache = eina_list_remove_list(swp->buf_cache, l);
+                  sym_tbm_bo_unref(b->buf_bo);
+                  free(b);
+               }
+          }
+     }
+
+   tbm_bo_handle bo_handle;
+
+   bo_handle = sym_tbm_bo_map (swp->buf_bo, TBM_DEVICE_CPU, TBM_OPTION_READ |TBM_OPTION_WRITE);
+   /* If device is DEFAULT, 2D, 3D, MM,then swp->buf_data = bo_handle.u32 */
+   swp->buf_data = bo_handle.ptr;
+
+   if (!swp->buf_data)
+     {
+        ERR("Buffer map name %i failed", swp->buf->name);
+        return NULL;
+     }
+   if (bpl) *bpl = swp->buf->pitch;
+   swp->mapped = EINA_TRUE;
+   if (swap_debug) printf("Mapped bufer name %i OK\n", swp->buf->name);
+   if ((swp->w != swp->buf_w) || (swp->h != swp->buf_h))
+     {
+        DBG("Evas software DRI swapper buffer size mismatch");
+     }
+   swp->w = swp->buf_w;
+   swp->h = swp->buf_h;
+   if (w) *w = swp->w;
+   if (h) *h = swp->h;
+   return swp->buf_data;
+}
+
+void
+evas_xlib_swapper_buffer_unmap(X_Swapper *swp)
+{
+   if (!swp->mapped) return;
+   sym_tbm_bo_unmap(swp->buf_bo);
+   if (swap_debug) printf("Unmap buffer name %i\n", swp->buf->name);
+   free(swp->buf);
+   swp->buf = NULL;
+   swp->buf_bo = NULL;
+   swp->buf_data = NULL;
+   swp->mapped = EINA_FALSE;
+}
+
+void
+evas_xlib_swapper_swap(X_Swapper *swp, Eina_Rectangle *rects, int nrects)
+{
+   XRectangle *xrects = alloca(nrects * sizeof(XRectangle));
+   XID region;
+   int i;
+   unsigned long long sbc_count = 0;
+
+   if (swap_debug) printf("Swap buffers\n");
+   for (i = 0; i < nrects; i++)
+     {
+        xrects[i].x = rects[i].x; xrects[i].y = rects[i].y;
+        xrects[i].width = rects[i].w; xrects[i].height = rects[i].h;
+     }
+   region = sym_XFixesCreateRegion(swp->disp, xrects, nrects);
+   sym_DRI2SwapBuffersWithRegion(swp->disp, swp->draw, region, &sbc_count);
+   sym_XFixesDestroyRegion(swp->disp, region);
+}
+
+int
+evas_xlib_swapper_buffer_state_get(X_Swapper *swp)
+{
+   DRI2BufferFlags *flags;
+
+   if (!swp->mapped) evas_xlib_swapper_buffer_map(swp, NULL, NULL, NULL);
+   if (!swp->mapped) return MODE_FULL;
+   flags = (DRI2BufferFlags *)(&(swp->buf->flags));
+   if (flags->data.idx_reuse != swp->last_count)
+     {
+        static int force_full_on_reuse_change = -1;
+
+        swp->last_count = flags->data.idx_reuse;
+        if (force_full_on_reuse_change == -1)
+          {
+             if (getenv("EVAS_FORCE_FULL_ON_REUSE_CHANGE")) force_full_on_reuse_change = 1;
+             else force_full_on_reuse_change = 0;
+          }
+        if (force_full_on_reuse_change)
+          {
+             if (swap_debug) printf("Reuse changed - force FULL\n");
+             return MODE_FULL;
+          }
+     }
+   if (swap_debug) printf("Swap state idx_reuse = %i (0=FULL, 1=COPY, 2=DOUBLE, 3=TRIPLE, 4=QUAD)\n", flags->data.idx_reuse);
+   if (flags->data.idx_reuse == 0) return MODE_FULL;
+   else if (flags->data.idx_reuse == 1) return MODE_COPY;
+   else if (flags->data.idx_reuse == 2) return MODE_DOUBLE;
+   else if (flags->data.idx_reuse == 3) return MODE_TRIPLE;
+   else if (flags->data.idx_reuse == 4) return MODE_QUADRUPLE;
+   return MODE_FULL;
+}
+
+int
+evas_xlib_swapper_depth_get(X_Swapper *swp)
+{
+   return swp->depth;
+}
+
+int
+evas_xlib_swapper_byte_order_get(X_Swapper *swp EINA_UNUSED)
+{
+   return LSBFirst;
+}
+
+int
+evas_xlib_swapper_bit_order_get(X_Swapper *swp EINA_UNUSED)
+{
+   return LSBFirst;
+}
+
+void
+evas_xlib_swapper_buffer_size_get(X_Swapper *swp, int *w, int *h)
+{
+   if (!swp) return;
+
+   *w = swp->buf_w;
+   *h = swp->buf_h;
+
+   return;
+}
+
+#endif
+
+#else
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+X_Swapper *
+evas_xlib_swapper_new(Display *disp EINA_UNUSED, Drawable draw EINA_UNUSED,
+                      Visual *vis EINA_UNUSED, int depth EINA_UNUSED,
+                      int w EINA_UNUSED, int h EINA_UNUSED)
+{
+   return NULL;
+}
+
+void
+evas_xlib_swapper_free(X_Swapper *swp EINA_UNUSED)
+{
+}
+
+void *
+evas_xlib_swapper_buffer_map(X_Swapper *swp EINA_UNUSED, int *bpl EINA_UNUSED, int *w EINA_UNUSED, int *h EINA_UNUSED)
+{
+   return NULL;
+}
+
+void
+evas_xlib_swapper_buffer_unmap(X_Swapper *swp EINA_UNUSED)
+{
+}
+
+void
+evas_xlib_swapper_swap(X_Swapper *swp EINA_UNUSED, Eina_Rectangle *rects EINA_UNUSED, int nrects EINA_UNUSED)
+{
+}
+
+int
+evas_xlib_swapper_buffer_state_get(X_Swapper *swp EINA_UNUSED)
+{
+   return MODE_FULL;
+}
+
+int
+evas_xlib_swapper_depth_get(X_Swapper *swp EINA_UNUSED)
+{
+   return 0;
+}
+
+int
+evas_xlib_swapper_byte_order_get(X_Swapper *swp EINA_UNUSED)
+{
+   return 0;
+}
+
+int
+evas_xlib_swapper_bit_order_get(X_Swapper *swp EINA_UNUSED)
+{
+   return 0;
+}
+#endif
diff --git a/src/modules/engines/software_x11/evas_xlib_swapper.h b/src/modules/engines/software_x11/evas_xlib_swapper.h
new file mode 100755 (executable)
index 0000000..18ad594
--- /dev/null
@@ -0,0 +1,16 @@
+#include "evas_engine.h"
+
+typedef struct _X_Swapper X_Swapper;
+
+X_Swapper *evas_xlib_swapper_new(Display *disp, Drawable draw, Visual *vis,
+                                 int depth, int w, int h);
+void evas_xlib_swapper_free(X_Swapper *swp);
+void *evas_xlib_swapper_buffer_map(X_Swapper *swp, int *bpl, int *w, int *h);
+void evas_xlib_swapper_buffer_unmap(X_Swapper *swp);
+void evas_xlib_swapper_swap(X_Swapper *swp, Eina_Rectangle *rects, int nrects);
+int evas_xlib_swapper_buffer_state_get(X_Swapper *swp);
+int evas_xlib_swapper_depth_get(X_Swapper *swp);
+int evas_xlib_swapper_byte_order_get(X_Swapper *swp);
+int evas_xlib_swapper_bit_order_get(X_Swapper *swp);
+void evas_xlib_swapper_buffer_size_get(X_Swapper *swp, int *w, int *h);
+    
index 520753a..ff5fcd8 100644 (file)
@@ -24,7 +24,8 @@ struct _Evas_Engine_Info_Wayland_Egl
       int          depth;
       int          screen;
       int          rotation;
-      unsigned int destination_alpha  : 1;
+      int          edges;
+      unsigned int destination_alpha : 1;
    } info;
    /* engine specific function calls to query stuff about the destination */
    /* engine (what visual & colormap & depth to use, performance info etc. */
index da6fcf7..3acf238 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/modules/engines/gl_common \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @GL_EET_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_engine_wayland_egl_cflags@
@@ -19,7 +19,7 @@ WAYLAND_EGL_SOURCES  = \
 evas_engine.c \
 evas_wl_main.c
 
-WAYLAND_EGL_LIBADD = @FREETYPE_LIBS@ @GL_EET_LIBS@ @EINA_LIBS@ @evas_engine_wayland_egl_libs@ @dlopen_libs@ $(top_builddir)/src/modules/engines/gl_common/libevas_engine_gl_common.la
+WAYLAND_EGL_LIBADD = @FREETYPE_LIBS@ @GL_EET_LIBS@ @EVAS_GENERAL_LIBS@ @evas_engine_wayland_egl_libs@ @dlopen_libs@ $(top_builddir)/src/modules/engines/gl_common/libevas_engine_gl_common.la
 
 includes_HEADERS = Evas_Engine_Wayland_Egl.h
 includesdir = $(includedir)/evas-@VMAJ@
old mode 100644 (file)
new mode 100755 (executable)
index f45c840..6090ab3
@@ -25,6 +25,34 @@ struct _Render_Engine
    int                      end;
    int w, h;
    int vsync;
+   struct
+     {
+        int max_rb_size;
+        int msaa_support;
+        int msaa_samples[4];
+
+        //---------//
+        int rgb_888[4];
+        int rgba_8888[4];
+
+        int depth_8[4];
+        int depth_16[4];
+        int depth_24[4];
+        int depth_32[4];
+
+        int stencil_1[4];
+        int stencil_2[4];
+        int stencil_4[4];
+        int stencil_8[4];
+        int stencil_16[4];
+
+        int depth_24_stencil_8[4];
+     } gl_cap;
+
+   int gl_cap_initted;
+
+   Eina_Bool context_current : 1;
+   Eina_Bool context_optimize : 1;
 };
 
 struct _Render_Engine_GL_Surface
@@ -35,6 +63,10 @@ struct _Render_Engine_GL_Surface
    int      depth_bits;
    int      stencil_bits;
 
+   int direct_fb_opt;
+
+   GLint    rt_msaa_samples;
+
    // Render target texture/buffers
    GLuint   rt_tex;
    GLint    rt_internal_fmt;
@@ -43,6 +75,10 @@ struct _Render_Engine_GL_Surface
    GLenum   rb_depth_fmt;
    GLuint   rb_stencil;
    GLenum   rb_stencil_fmt;
+   GLuint   rb_depth_stencil;
+   GLenum   rb_depth_stencil_fmt;
+
+   EGLSurface direct_sfc;
 
    Render_Engine_GL_Context   *current_ctx;
 };
@@ -54,6 +90,9 @@ struct _Render_Engine_GL_Context
    GLuint      context_fbo;
    GLuint      current_fbo;
 
+   int scissor_enabled;
+   int scissor_updated;
+
    Render_Engine_GL_Surface   *current_sfc;
 };
 
@@ -75,9 +114,13 @@ struct _Extension_Entry
 
 static int initted = 0;
 static int gl_wins = 0;
+static int gl_direct_override = 0;
+static int gl_direct_enabled = 0;
 static Render_Engine_GL_Context *current_evgl_ctx;
 static Render_Engine *current_engine;
+static Evas_Object *gl_direct_img_obj = NULL; /* NEW */
 
+static int _ext_initted = 0; /* NEW */
 static char _gl_ext_string[1024];
 static char _evasgl_ext_string[1024];
 
@@ -106,8 +149,8 @@ void    *(*glsym_eglCreateImage)               (EGLDisplay a, EGLContext b, EGLe
 void     (*glsym_eglDestroyImage)              (EGLDisplay a, void *b) = NULL;
 void     (*glsym_glEGLImageTargetTexture2DOES) (int a, void *b)  = NULL;
 void     (*glsym_glEGLImageTargetRenderbufferStorageOES) (int a, void *b)  = NULL;
-void          *(*glsym_eglMapImageSEC)         (void *a, void *b) = NULL;
-unsigned int   (*glsym_eglUnmapImageSEC)       (void *a, void *b) = NULL;
+void          *(*glsym_eglMapImageSEC)         (void *a, void *b, int c, int d) = NULL;
+unsigned int   (*glsym_eglUnmapImageSEC)       (void *a, void *b, int c) = NULL;
 const char    *(*glsym_eglQueryString)         (EGLDisplay a, int name) = NULL;
 
 unsigned int   (*glsym_eglLockSurface)          (EGLDisplay a, EGLSurface b, const int *attrib_list) = NULL;
@@ -146,6 +189,8 @@ unsigned char       (*glsym_glTestFenceNV) (GLuint fence) = NULL;
 void   (*glsym_glGetFenceivNV) (GLuint fence, GLenum pname, GLint* params) = NULL;
 void   (*glsym_glFinishFenceNV) (GLuint fence) = NULL;
 void   (*glsym_glSetFenceNV) (GLuint, GLenum) = NULL;
+void    (*glsym_glRenderbufferStorageMultisample) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) = NULL;
+void    (*glsym_glFramebufferTexture2DMultisample) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) = NULL;
 void   (*glsym_glGetDriverControlsQCOM) (GLint* num, GLsizei size, GLuint* driverControls) = NULL;
 void   (*glsym_glGetDriverControlStringQCOM) (GLuint driverControl, GLsizei bufSize, GLsizei* length, char* driverControlString) = NULL;
 void   (*glsym_glEnableDriverControlQCOM) (GLuint driverControl) = NULL;
@@ -473,7 +518,7 @@ static Evas_Func func, pfunc;
 static Evas_GL_API gl_funcs;
 
 static void *
-eng_info(Evas *e)
+eng_info(Evas *e __UNUSED__)
 {
    Evas_Engine_Info_Wayland_Egl *info;
 
@@ -481,8 +526,8 @@ eng_info(Evas *e)
    info->magic.magic = rand();
    info->func.best_depth_get = eng_best_depth_get;
    info->render_mode = EVAS_RENDER_MODE_BLOCKING;
+
    return info;
-   e = NULL;
 }
 
 static void
@@ -608,6 +653,14 @@ eng_setup(Evas *e, void *in)
      {
         re = calloc(1, sizeof(Render_Engine));
         if (!re) return 0;
+
+        if (getenv("EVAS_GL_MAKE_CURRENT_OPTIMIZE_DISABLE"))
+           re->context_optimize = EINA_FALSE;
+        else
+           re->context_optimize = EINA_TRUE;
+
+        re->context_current = EINA_FALSE;
+
         re->info = info;
         re->evas = e;
         e->engine.data.output = re;
@@ -766,8 +819,12 @@ eng_setup(Evas *e, void *in)
    eng_window_use(re->win);
 
    re->vsync = 0;
-   _sym_init();
-   _extensions_init(re);
+   if (!_ext_initted)
+     {
+        _sym_init();
+        _extensions_init(re);
+        _ext_initted = 1;
+     }
 
    // This is used in extensions.  Not pretty but can't get display otherwise.
    current_engine = re;
@@ -817,12 +874,29 @@ eng_output_resize(void *data, int w, int h)
    Render_Engine *re;
 
    re = (Render_Engine *)data;
+   if ((!re) || (!re->win)) return;
+
    re->win->w = w;
    re->win->h = h;
    eng_window_use(re->win);
 
    if (re->win->win)
-     wl_egl_window_resize(re->win->win, w, h, 0, 0);
+     {
+        int aw, ah, dx, dy;
+
+        wl_egl_window_get_attached_size(re->win->win, &aw, &ah);
+
+        if (re->info->info.edges & 4) // resize from left
+          dx = aw - w;
+        else
+          dx = 0;
+        if (re->info->info.edges & 1) // resize from top
+          dy = ah - h;
+        else
+          dy = 0;
+
+        wl_egl_window_resize(re->win->win, w, h, dx, dy);
+     }
 
    evas_gl_common_context_resize(re->win->gl_context, w, h, re->win->rot);
    evas_common_tilebuf_free(re->tb);
@@ -1008,6 +1082,7 @@ eng_output_flush(void *data)
    if (!_re_wincheck(re)) return;
    if (!re->win->draw.drew) return;
 //x//   printf("frame -> flush\n");
+   re->context_current = EINA_FALSE;
    re->win->draw.drew = 0;
    eng_window_use(re->win);
 
@@ -1041,11 +1116,11 @@ eng_output_flush(void *data)
 }
 
 static void
-eng_output_idle_flush(void *data)
+eng_output_idle_flush(void *data __UNUSED__)
 {
-   Render_Engine *re;
+   /* Render_Engine *re; */
 
-   re = (Render_Engine *)data;
+   /* re = (Render_Engine *)data; */
 }
 
 static void
@@ -1086,7 +1161,18 @@ eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w
    Render_Engine *re;
 
    re = (Render_Engine *)data;
-   eng_window_use(re->win);
+
+   if (re->context_optimize)
+     {
+        if (!re->context_current)
+          {
+             re->context_current = EINA_TRUE;
+             eng_window_use(re->win);
+          }
+     }
+   else
+      eng_window_use(re->win);
+
    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
    re->win->gl_context->dc = context;
    evas_gl_common_rect_draw(re->win->gl_context, x, y, w, h);
@@ -1098,27 +1184,38 @@ eng_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2,
    Render_Engine *re;
 
    re = (Render_Engine *)data;
-   eng_window_use(re->win);
+
+   if (re->context_optimize)
+     {
+        if (!re->context_current)
+          {
+             re->context_current = EINA_TRUE;
+             eng_window_use(re->win);
+          }
+     }
+   else
+      eng_window_use(re->win);
+
    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
    re->win->gl_context->dc = context;
    evas_gl_common_line_draw(re->win->gl_context, x1, y1, x2, y2);
 }
 
 static void *
-eng_polygon_point_add(void *data, void *context __UNUSED__, void *polygon, int x, int y)
+eng_polygon_point_add(void *data __UNUSED__, void *context __UNUSED__, void *polygon, int x, int y)
 {
-   Render_Engine *re;
+   /* Render_Engine *re; */
 
-   re = (Render_Engine *)data;
+   /* re = (Render_Engine *)data; */
    return evas_gl_common_poly_point_add(polygon, x, y);
 }
 
 static void *
-eng_polygon_points_clear(void *data, void *context __UNUSED__, void *polygon)
+eng_polygon_points_clear(void *data __UNUSED__, void *context __UNUSED__, void *polygon)
 {
-   Render_Engine *re;
+   /* Render_Engine *re; */
 
-   re = (Render_Engine *)data;
+   /* re = (Render_Engine *)data; */
    return evas_gl_common_poly_points_clear(polygon);
 }
 
@@ -1128,7 +1225,18 @@ eng_polygon_draw(void *data, void *context, void *surface __UNUSED__, void *poly
    Render_Engine *re;
 
    re = (Render_Engine *)data;
-   eng_window_use(re->win);
+
+   if (re->context_optimize)
+     {
+        if (!re->context_current)
+          {
+             re->context_current = EINA_TRUE;
+             eng_window_use(re->win);
+          }
+     }
+   else
+      eng_window_use(re->win);
+
    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
    re->win->gl_context->dc = context;
    evas_gl_common_poly_draw(re->win->gl_context, polygon, x, y);
@@ -1202,6 +1310,9 @@ eng_image_alpha_set(void *data, void *image, int has_alpha)
      {
         Evas_GL_Image *im_new;
 
+        if (!im->im->image.data)
+          evas_cache_image_load_data(&im->im->cache_entry);
+        evas_gl_common_image_alloc_ensure(im);
         im_new = evas_gl_common_image_new_from_copied_data
            (im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
                im->im->image.data,
@@ -1249,13 +1360,13 @@ eng_image_comment_get(void *data __UNUSED__, void *image, char *key __UNUSED__)
 }
 
 static char *
-eng_image_format_get(void *data __UNUSED__, void *image)
+eng_image_format_get(void *data __UNUSED__, void *image __UNUSED__)
 {
 //   Render_Engine *re;
-   Evas_GL_Image *im;
+   /* Evas_GL_Image *im; */
 
 //   re = (Render_Engine *)data;
-   im = image;
+   /* im = image; */
    return NULL;
 }
 
@@ -1272,6 +1383,7 @@ eng_image_colorspace_set(void *data, void *image, int cspace)
    /* FIXME: can move to gl_common */
    if (im->cs.space == cspace) return;
    eng_window_use(re->win);
+   evas_gl_common_image_alloc_ensure(im);
    evas_cache_image_colorspace(&im->im->cache_entry, cspace);
    switch (cspace)
      {
@@ -1330,17 +1442,69 @@ struct _Native
 //
 //#define GLX_TEX_PIXMAP_RECREATE 1
 
+static void
+_native_bind_cb(void *data __UNUSED__, void *image)
+{
+   Evas_GL_Image *im = image;
+   Native *n = im->native.data;
+
+   if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
+     {
+        glBindTexture(GL_TEXTURE_2D, n->ns.data.opengl.texture_id);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+     }
+}
+
+static void
+_native_unbind_cb(void *data __UNUSED__, void *image)
+{
+  Evas_GL_Image *im = image;
+  Native *n = im->native.data;
+
+  if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
+    {
+       glBindTexture(GL_TEXTURE_2D, 0);
+       GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+    }
+}
+
+static void
+_native_free_cb(void *data, void *image)
+{
+  Render_Engine *re = data;
+  Evas_GL_Image *im = image;
+  Native *n = im->native.data;
+  uint32_t texid;
+
+  if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
+    {
+       texid = n->ns.data.opengl.texture_id;
+       eina_hash_del(re->win->gl_context->shared->native_tex_hash, &texid, im);
+    }
+  im->native.data        = NULL;
+  im->native.func.data   = NULL;
+  im->native.func.bind   = NULL;
+  im->native.func.unbind = NULL;
+  im->native.func.free   = NULL;
+  free(n);
+}
+
 static void *
 eng_image_native_set(void *data, void *image, void *native)
 {
-   Render_Engine *re = (Render_Engine *)data;
-   Evas_Native_Surface *ns = native;
-   Evas_GL_Image *im = image, *im2 = NULL;
-   Native *n = NULL;
+  Render_Engine *re = (Render_Engine *)data;
+  Evas_Native_Surface *ns = native;
+  Evas_GL_Image *im = image, *im2 = NULL;
+  Native *n = NULL;
+  uint32_t texid;
+  unsigned int tex = 0;
+  unsigned int fbo = 0;
+
+  if (ns && ns->type != EVAS_NATIVE_SURFACE_OPENGL) return NULL;
 
   if (!im)
     {
-       if ((!ns) && (ns->type == EVAS_NATIVE_SURFACE_OPENGL))
+       if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_OPENGL))
          {
             im = evas_gl_common_image_new_from_data(re->win->gl_context,
                                                     ns->data.opengl.w,
@@ -1349,12 +1513,20 @@ eng_image_native_set(void *data, void *image, void *native)
                                                     EVAS_COLORSPACE_ARGB8888);
          }
        else
-           return NULL;
+         return NULL;
     }
 
   if (ns)
     {
-       if (im->native.data) return im;
+       tex = ns->data.opengl.texture_id;
+       fbo = ns->data.opengl.framebuffer_id;
+       if (im->native.data)
+         {
+            Evas_Native_Surface *ens = im->native.data;
+            if ((ens->data.opengl.texture_id == tex) &&
+                (ens->data.opengl.framebuffer_id == fbo))
+              return im;
+         }
     }
   if ((!ns) && (!im->native.data)) return im;
 
@@ -1362,31 +1534,60 @@ eng_image_native_set(void *data, void *image, void *native)
 
   if (im->native.data)
     {
-      if (im->native.func.free)
-        im->native.func.free(im->native.func.data, im);
-      evas_gl_common_image_native_disable(im);
+       if (im->native.func.free)
+         im->native.func.free(im->native.func.data, im);
+       evas_gl_common_image_native_disable(im);
     }
 
   if (!ns) return im;
 
-   if (im2 == im) return im;
-   if (im2)
-     {
-        n = im2->native.data;
-        if (n)
-          {
-             evas_gl_common_image_ref(im2);
-             evas_gl_common_image_free(im);
-             return im2;
-          }
-     }
-
-   im2 = evas_gl_common_image_new_from_data(re->win->gl_context,
-                                            im->w, im->h, NULL, im->alpha,
-                                            EVAS_COLORSPACE_ARGB8888);
-   evas_gl_common_image_free(im);
-   im = im2;
+  texid = tex;
+  im2 = eina_hash_find(re->win->gl_context->shared->native_tex_hash, &texid);
+  if (im2 == im) return im;
+  if (im2)
+    {
+       n = im2->native.data;
+       if (n)
+         {
+            evas_gl_common_image_ref(im2);
+            evas_gl_common_image_free(im);
+            return im2;
+         }
+    }
 
+  im2 = evas_gl_common_image_new_from_data(re->win->gl_context,
+                                           im->w, im->h, NULL, im->alpha,
+                                           EVAS_COLORSPACE_ARGB8888);
+  evas_gl_common_image_free(im);
+  im = im2;
+  if (native)
+    {
+       n = calloc(1, sizeof(Native));
+       if (n)
+         {
+            memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
+  
+            eina_hash_add(re->win->gl_context->shared->native_tex_hash, &texid, im);
+  
+            n->egl_surface = 0;
+            n->pixmap = 0;
+  
+            im->native.yinvert     = 0;
+            im->native.loose       = 0;
+            im->native.data        = n;
+            im->native.func.data   = re;
+            im->native.func.bind   = _native_bind_cb;
+            im->native.func.unbind = _native_unbind_cb;
+            im->native.func.free   = _native_free_cb;
+            im->native.target      = GL_TEXTURE_2D;
+            im->native.mipmap      = 0;
+  
+            // FIXME: need to implement mapping sub texture regions
+            // x, y, w, h for possible texture atlasing
+  
+            evas_gl_common_image_native_enable(im);
+         }
+    }
    return im;
 }
 
@@ -1527,6 +1728,7 @@ eng_image_size_set(void *data, void *image, int w, int h)
          break;
      }
 
+   evas_gl_common_image_alloc_ensure(im);
    if ((im_old) &&
        ((int)im_old->im->cache_entry.w == w) &&
        ((int)im_old->im->cache_entry.h == h))
@@ -1598,7 +1800,11 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
              if (err) *err = EVAS_LOAD_ERROR_NONE;
              return im;
           }
-        *image_data = im->tex->pt->dyn.data = glsym_eglMapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img);
+        *image_data = im->tex->pt->dyn.data = glsym_eglMapImageSEC
+                                                                              (re->win->egl_disp, 
+                                                                               im->tex->pt->dyn.img,
+                                                                               EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC,
+                                                                               EGL_MAP_GL_TEXTURE_OPTION_WRITE_SEC);
 
         if (!im->tex->pt->dyn.data)
           {
@@ -1623,6 +1829,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
     }
 
    error = evas_cache_image_load_data(&im->im->cache_entry);
+   evas_gl_common_image_alloc_ensure(im);
    switch (im->cs.space)
      {
       case EVAS_COLORSPACE_ARGB8888:
@@ -1677,6 +1884,7 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
    im = image;
    if (im->native.data) return image;
    eng_window_use(re->win);
+   evas_gl_common_image_alloc_ensure(im);
    if ((im->tex) && (im->tex->pt)
        && (im->tex->pt->dyn.data)
        && (im->cs.space == EVAS_COLORSPACE_ARGB8888))
@@ -1687,7 +1895,7 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
           {
              im->tex->pt->dyn.checked_out--;
              if (im->tex->pt->dyn.checked_out == 0)
-               glsym_eglUnmapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img);
+               glsym_eglUnmapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img, EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC);
              return image;
           }
 
@@ -1774,13 +1982,30 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
 
    re = (Render_Engine *)data;
    if (!image) return;
-   eng_window_use(re->win);
-   evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
-   re->win->gl_context->dc = context;
-   evas_gl_common_image_draw(re->win->gl_context, image,
-                             src_x, src_y, src_w, src_h,
-                             dst_x, dst_y, dst_w, dst_h,
-                             smooth);
+
+   if ((gl_direct_img_obj) && (gl_direct_enabled))
+     evas_object_image_pixels_dirty_set(gl_direct_img_obj, EINA_TRUE);
+   else
+     {
+
+        if (re->context_optimize)
+          {
+             if (!re->context_current)
+               {
+                  re->context_current = EINA_TRUE;
+                  eng_window_use(re->win);
+               }
+          }
+        else
+           eng_window_use(re->win);
+
+        evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
+        re->win->gl_context->dc = context;
+        evas_gl_common_image_draw(re->win->gl_context, image,
+                                  src_x, src_y, src_w, src_h,
+                                  dst_x, dst_y, dst_w, dst_h,
+                                  smooth);
+     }
 }
 
 static void
@@ -1805,7 +2030,18 @@ eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_M
 
    re = (Render_Engine *)data;
    if (!image) return;
-   eng_window_use(re->win);
+
+   if (re->context_optimize)
+     {
+        if (!re->context_current)
+          {
+             re->context_current = EINA_TRUE;
+             eng_window_use(re->win);
+          }
+     }
+   else
+      eng_window_use(re->win);
+
    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
    re->win->gl_context->dc = context;
    if (m->count != 4)
@@ -1854,18 +2090,27 @@ eng_image_map_surface_new(void *data, int w, int h, int alpha)
    Render_Engine *re;
 
    re = (Render_Engine *)data;
+   eng_window_use(re->win);
    return evas_gl_common_image_surface_new(re->win->gl_context, w, h, alpha);
 }
 
 static void
-eng_image_map_surface_free(void *data __UNUSED__, void *surface)
+eng_image_map_surface_free(void *data, void *surface)
 {
+   Render_Engine *re;
+
+   re = (Render_Engine *)data;
+   eng_window_use(re->win);
    evas_gl_common_image_free(surface);
 }
 
 static void
-eng_image_content_hint_set(void *data __UNUSED__, void *image, int hint)
+eng_image_content_hint_set(void *data, void *image, int hint)
 {
+   Render_Engine *re;
+   re = (Render_Engine *)data;
+
+   if (re) eng_window_use(re->win);
    if (image) evas_gl_common_image_content_hint_set(image, hint);
 }
 
@@ -1928,7 +2173,18 @@ eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font __UN
    Render_Engine *re;
 
    re = (Render_Engine *)data;
-   eng_window_use(re->win);
+
+   if (re->context_optimize)
+     {
+        if (!re->context_current)
+          {
+             re->context_current = EINA_TRUE;
+             eng_window_use(re->win);
+          }
+     }
+   else
+      eng_window_use(re->win);
+
    evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
    re->win->gl_context->dc = context;
      {
@@ -2016,88 +2272,389 @@ _set_internal_config(Render_Engine_GL_Surface *sfc, Evas_GL_Config *cfg)
 }
 
 static int
-_create_rt_buffers(Render_Engine *data __UNUSED__,
-                   Render_Engine_GL_Surface *sfc)
-{
-   // Render Target texture
-   glGenTextures(1, &sfc->rt_tex );
-
-   // Depth RenderBuffer - Create storage here...
-   if (sfc->depth_bits != EVAS_GL_DEPTH_NONE)
-      glGenRenderbuffers(1, &sfc->rb_depth);
-
-   // Stencil RenderBuffer - Create Storage here...
-   if (sfc->stencil_bits != EVAS_GL_STENCIL_NONE)
-      glGenRenderbuffers(1, &sfc->rb_stencil);
-
-   return 1;
-}
-
-static int
 _attach_fbo_surface(Render_Engine *data __UNUSED__,
-                    Render_Engine_GL_Surface *sfc,
-                    Render_Engine_GL_Context *ctx)
+                    Render_Engine_GL_Surface *sfc, int fbo)
 {
-   int fb_status;
+   int fb_status, curr_tex, curr_rb;
 
-   // Initialize Texture
-   glBindTexture(GL_TEXTURE_2D, sfc->rt_tex );
-   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sfc->w, sfc->h, 0,
-                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-   glBindTexture(GL_TEXTURE_2D, 0);
+   glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 
+   // Detach any previously attached buffers
+   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
+                          GL_TEXTURE_2D, 0, 0);
+   glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 
+                             GL_RENDERBUFFER, 0);
+   glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, 
+                             GL_RENDERBUFFER, 0);
+   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 
+                          GL_TEXTURE_2D, 0, 0);
+   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, 
+                          GL_TEXTURE_2D, 0, 0);
 
-   // Attach texture to FBO
-   glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo);
-   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                          GL_TEXTURE_2D, sfc->rt_tex, 0);
+   // Render Target Texture
+   if (sfc->rt_tex)
+     {
+        curr_tex = 0;
+        glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_tex);
+        glBindTexture(GL_TEXTURE_2D, sfc->rt_tex );
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sfc->w, sfc->h, 0,
+                     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+        glBindTexture(GL_TEXTURE_2D, curr_tex);
+
+        // Attach texture to FBO
+        if (sfc->rt_msaa_samples)
+           glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER,
+                                                   GL_COLOR_ATTACHMENT0,
+                                                   GL_TEXTURE_2D, sfc->rt_tex,
+                                                   0, sfc->rt_msaa_samples);
+        else
+           glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                  GL_TEXTURE_2D, sfc->rt_tex, 0);
+     }
+
+   // Depth Stencil RenderBuffer - Attach it to FBO
+   if (sfc->rb_depth_stencil)
+     {
+        curr_tex = 0;
+        glGetIntegerv(GL_TEXTURE_BINDING_2D, &curr_tex);
+        glBindTexture(GL_TEXTURE_2D, sfc->rb_depth_stencil);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL_OES, sfc->w, sfc->h,
+                     0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES, NULL);
+       if (sfc->rt_msaa_samples)
+          {
+             glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER,
+                                                     GL_DEPTH_ATTACHMENT,
+                                                     GL_TEXTURE_2D,
+                                                     sfc->rb_depth_stencil,
+                                                     0, sfc->rt_msaa_samples);
+             glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER,
+                                                     GL_STENCIL_ATTACHMENT,
+                                                     GL_TEXTURE_2D,
+                                                     sfc->rb_depth_stencil,
+                                                     0, sfc->rt_msaa_samples);
+          }
+        else
+          {
+             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                    GL_TEXTURE_2D, sfc->rb_depth_stencil, 0);
+             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+                                    GL_TEXTURE_2D, sfc->rb_depth_stencil, 0);
+          }
+        glBindTexture(GL_TEXTURE_2D, curr_tex);
+     }
 
    // Depth RenderBuffer - Attach it to FBO
-   if (sfc->depth_bits != EVAS_GL_DEPTH_NONE)
+   if (sfc->rb_depth)
      {
+        curr_rb = 0;
+        glGetIntegerv(GL_RENDERBUFFER_BINDING, &curr_rb);
+
         glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_depth);
-        glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_depth_fmt,
-                              sfc->w, sfc->h);
+
+        if (sfc->rt_msaa_samples)
+           glsym_glRenderbufferStorageMultisample(GL_RENDERBUFFER,
+                                                  sfc->rt_msaa_samples,
+                                                  sfc->rb_depth_fmt,
+                                                  sfc->w, sfc->h);
+        else
+           glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_depth_fmt,
+                                 sfc->w, sfc->h);
         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                                   GL_RENDERBUFFER, sfc->rb_depth);
-        glBindRenderbuffer(GL_RENDERBUFFER, 0);
+        glBindRenderbuffer(GL_RENDERBUFFER, curr_rb);
      }
 
    // Stencil RenderBuffer - Attach it to FBO
-   if (sfc->stencil_bits != EVAS_GL_STENCIL_NONE)
+   if (sfc->rb_stencil)
      {
+        curr_rb = 0;
+        glGetIntegerv(GL_RENDERBUFFER_BINDING, &curr_rb);
+
         glBindRenderbuffer(GL_RENDERBUFFER, sfc->rb_stencil);
-        glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_stencil_fmt,
-                              sfc->w, sfc->h);
+
+        if (sfc->rt_msaa_samples)
+           glsym_glRenderbufferStorageMultisample(GL_RENDERBUFFER,
+                                                  sfc->rt_msaa_samples,
+                                                  sfc->rb_stencil_fmt,
+                                                  sfc->w, sfc->h);
+        else
+           glRenderbufferStorage(GL_RENDERBUFFER, sfc->rb_stencil_fmt,
+                                 sfc->w, sfc->h);
         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
                                   GL_RENDERBUFFER, sfc->rb_stencil);
-        glBindRenderbuffer(GL_RENDERBUFFER, 0);
+        glBindRenderbuffer(GL_RENDERBUFFER, curr_rb);
      }
 
    // Check FBO for completeness
    fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (fb_status != GL_FRAMEBUFFER_COMPLETE)
      {
-        ERR("FBO not complete!");
+        ERR("FBO not complete. Error Code: %x!", fb_status);
+//        _print_gl_surface_info(sfc, 1);
         return 0;
      }
 
    return 1;
 }
 
+static int
+_create_rt_buffers(Render_Engine *data __UNUSED__,
+                   Render_Engine_GL_Surface *sfc)
+{
+   int ret = 0;
+   GLuint fbo = 0;
+   GLint curr_fbo = 0;
+
+   if (sfc->rt_fmt)
+     {
+        // Render Target texture
+        glGenTextures(1, &sfc->rt_tex );
+     }
+
+   // First check if packed buffer is to be used.
+   if (sfc->rb_depth_stencil_fmt)
+     glGenTextures(1, &sfc->rb_depth_stencil);
+   else
+     {
+        // Depth RenderBuffer - Create storage here...
+        if (sfc->rb_depth_fmt)
+           glGenRenderbuffers(1, &sfc->rb_depth);
+
+        // Stencil RenderBuffer - Create Storage here...
+        if (sfc->rb_stencil_fmt)
+           glGenRenderbuffers(1, &sfc->rb_stencil);
+     }
+   //------------------------------------//
+   // Try attaching the given configuration
+   glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo);
+   glGenFramebuffers(1 ,&fbo);
+
+   ret = _attach_fbo_surface(NULL, sfc, fbo);
+
+   if (fbo) glDeleteFramebuffers(1, &fbo);
+   glBindFramebuffer(GL_FRAMEBUFFER, (GLuint)curr_fbo);
+
+   if (!ret)
+     {
+        if (sfc->rt_tex) glDeleteTextures(1, &sfc->rt_tex);
+        if (sfc->rb_depth) glDeleteRenderbuffers(1, &sfc->rb_depth);
+        if (sfc->rb_stencil) glDeleteRenderbuffers(1, &sfc->rb_stencil);
+        if (sfc->rb_depth_stencil) glDeleteTextures(1, &sfc->rb_depth_stencil);
+        ERR("_attach_fbo_surface() failed.");
+        return 0;
+     }
+   else
+     return 1;
+}
+
+static int
+_internal_resources_make_current(void *data)
+{
+   Render_Engine *re = (Render_Engine *)data;
+   Render_Engine_GL_Resource *rsc;
+   int ret = 0;
+
+   // Create internal resource context if it hasn't been created already
+   if ((rsc = eina_tls_get(resource_key)) == NULL)
+     {
+        if ((rsc = _create_internal_glue_resources(re)) == NULL)
+          {
+             ERR("Error creating internal resources.");
+             return 0;
+          }
+     }
+
+   // Use resource surface/context to create surface resrouces
+   // Update the evas' window surface
+   if (eina_main_loop_is()) rsc->surface = re->win->egl_surface[0];
+
+   ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, rsc->surface, rsc->context);
+
+   if (!ret)
+     {
+        ERR("eglMakeCurrent() failed. Error Code: %#x", eglGetError());
+        return 0;
+     }
+   return 1;
+}
+
+// Unfortunately, there is no query function to figure out which surface formats work.
+// So, this is one way to test for surface config capability.
+static int
+_check_gl_surface_format(GLint int_fmt, GLenum fmt, GLenum attachment, GLenum attach_fmt, int mult_samples)
+{
+   GLuint fbo, tex, rb, ds_tex;
+   int w, h, fb_status;
+
+   // Initialize Variables
+   fbo = tex = rb = ds_tex = 0;
+
+   // Width/Heith for test purposes
+   w = h = 2;
+
+   // Gen FBO
+   glGenFramebuffers(1, &fbo);
+   glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+   // Render Target Texture
+   if (int_fmt)
+     {
+        glGenTextures(1, &tex);
+        glBindTexture(GL_TEXTURE_2D, tex );
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        glTexImage2D(GL_TEXTURE_2D, 0, int_fmt, w, h, 0, fmt, GL_UNSIGNED_BYTE, NULL);
+        glBindTexture(GL_TEXTURE_2D, 0);
+
+        if (mult_samples)
+           glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0, mult_samples);
+        else
+           glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
+     }
+
+   // Render Target Attachment (Stencil or Depth)
+   if (attachment)
+     {
+        // This is a little hacky but this is how we'll have to do for now.
+        if (attach_fmt == GL_DEPTH_STENCIL_OES)
+          {
+             glGenTextures(1, &ds_tex);
+             glBindTexture(GL_TEXTURE_2D, ds_tex);
+             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+             glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL_OES, w, h,
+                          0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES, NULL);
+             if (mult_samples)
+               {
+                  glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                                          GL_TEXTURE_2D, ds_tex, 0, mult_samples);
+                  glsym_glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+                                                          GL_TEXTURE_2D, ds_tex, 0, mult_samples);
+               }
+             else
+               {
+                  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                         GL_TEXTURE_2D, ds_tex, 0);
+                  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+                                         GL_TEXTURE_2D, ds_tex, 0);
+               }
+             glBindTexture(GL_TEXTURE_2D, 0);
+          }
+        else
+          {
+             glGenRenderbuffers(1, &rb);
+             glBindRenderbuffer(GL_RENDERBUFFER, rb);
+             if (mult_samples)
+                glsym_glRenderbufferStorageMultisample(GL_RENDERBUFFER, mult_samples, attach_fmt, w, h);
+             else
+                glRenderbufferStorage(GL_RENDERBUFFER, attach_fmt, w, h);
+             glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, rb);
+             glBindRenderbuffer(GL_RENDERBUFFER, 0);
+          }
+
+     }
+
+   // Check FBO for completeness
+   fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+   // Delete Created Resources
+   glBindFramebuffer(GL_FRAMEBUFFER, 0);
+   if (fbo) glDeleteFramebuffers(1, &fbo);
+   if (tex) glDeleteTextures(1, &tex);
+   if (ds_tex) glDeleteTextures(1, &ds_tex);
+   if (rb) glDeleteRenderbuffers(1, &rb);
+
+   if (fb_status != GL_FRAMEBUFFER_COMPLETE)
+      return 0;
+   else
+     {
+        if ((attachment) && (!mult_samples))
+           return attach_fmt;
+        else
+           return 1;
+     }
+}
+
+static void
+_set_gl_surface_cap(Render_Engine *re)
+{
+   int i, count;
+   int max_samples = 0;
+
+   if (!re) return;
+   if (re->gl_cap_initted) return;
+
+   glGetIntegerv(GL_MAX_SAMPLES_IMG, &max_samples);
+
+   // Check if msaa_support is supported
+   if ((max_samples) &&
+       (glsym_glFramebufferTexture2DMultisample) &&
+       (glsym_glRenderbufferStorageMultisample))
+     {
+        re->gl_cap.msaa_support = 1;
+
+        re->gl_cap.msaa_samples[3] = max_samples;
+        re->gl_cap.msaa_samples[2] = max_samples/2;
+        re->gl_cap.msaa_samples[1] = max_samples/4;
+        re->gl_cap.msaa_samples[0] = 0;
+
+        if (!re->gl_cap.msaa_samples[2])
+           re->gl_cap.msaa_samples[2] = re->gl_cap.msaa_samples[3];
+        if (!re->gl_cap.msaa_samples[1])
+           re->gl_cap.msaa_samples[1] = re->gl_cap.msaa_samples[2];
+     }
+   else
+     {
+        re->gl_cap.msaa_support = 0;
+     }
+
+
+   glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &re->gl_cap.max_rb_size);
+
+   count = (re->gl_cap.msaa_support) ? 4 : 1;
+
+   for (i = 0; i < count; i++)
+     {
+        re->gl_cap.rgb_888[i]   = _check_gl_surface_format(GL_RGB, GL_RGB, 0, 0, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.rgba_8888[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, 0, 0, re->gl_cap.msaa_samples[i]);
+
+        re->gl_cap.depth_8[i]   = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.depth_16[i]  = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.depth_24[i]  = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24_OES, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.depth_32[i]  = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32_OES, re->gl_cap.msaa_samples[i]);
+
+        re->gl_cap.stencil_1[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX1_OES, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.stencil_4[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX4_OES, re->gl_cap.msaa_samples[i]);
+        re->gl_cap.stencil_8[i] = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8, re->gl_cap.msaa_samples[i]);
+
+        re->gl_cap.depth_24_stencil_8[i]  = _check_gl_surface_format(GL_RGBA, GL_RGBA, GL_DEPTH_STENCIL_OES, GL_DEPTH_STENCIL_OES, re->gl_cap.msaa_samples[i]);
+     }
+
+//   _print_gl_surface_cap(re, 0);
+
+   re->gl_cap_initted = 1;
+}
 
 static void *
 eng_gl_surface_create(void *data, void *config, int w, int h)
 {
    Render_Engine *re;
    Render_Engine_GL_Surface *sfc;
-   Render_Engine_GL_Resource *rsc;
    Evas_GL_Config *cfg;
-   int ret;
+   void *ret = NULL;
+   int res;
 
    sfc = calloc(1, sizeof(Render_Engine_GL_Surface));
    if (!sfc) return NULL;
@@ -2115,55 +2672,64 @@ eng_gl_surface_create(void *data, void *config, int w, int h)
    sfc->rb_depth     = 0;
    sfc->rb_stencil   = 0;
 
+   // Allow alpha for evas gl direct rendering override
+   // FIXME!!!: A little out of place but for now...
+   if (!gl_direct_override)
+      if (getenv("EVAS_GL_DIRECT_OVERRIDE")) gl_direct_override = 1;
+
    // Set the internal format based on the config
-   if (!_set_internal_config(sfc, cfg))
+   if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT)
      {
-        ERR("Unsupported Format!");
-        free(sfc);
-        return NULL;
+        DBG("Enabling Direct rendering to the Evas' window.");
+        sfc->direct_sfc = re->win->egl_surface[0];
      }
 
-   // Create internal resource context if it hasn't been created already
-   if ((rsc = eina_tls_get(resource_key)) == NULL)
+   // Use resource surface/context to do a make current
+   if (!_internal_resources_make_current(re))
      {
-        if ((rsc = _create_internal_glue_resources(re)) == NULL)
-          {
-             ERR("Error creating internal resources.");
-             free(sfc);
-             return NULL;
-          }
+        ERR("Error doing a make current with the internal resources.");
+        goto finish;
      }
 
-   // I'm using evas's original context to create the render target texture
-   // This is to prevent awkwardness in using native_surface_get() function
-   // If the rt texture creation is deferred till the context is created and
-   // make_current called, the user can't call native_surface_get() right
-   // after the surface is created. hence this is done here using evas' context.
-   ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, rsc->surface, rsc->context);
-   if (!ret)
+   // Set the engine surface capability first if it hasn't been set
+   if (!re->gl_cap_initted) _set_gl_surface_cap(re);
+
+   // Check the size of the surface
+   if ( (w > re->gl_cap.max_rb_size) || (h > re->gl_cap.max_rb_size) )
      {
-        ERR("xxxMakeCurrent() failed!");
-        free(sfc);
-        return NULL;
+        ERR("Surface size greater than the supported size. Max Surface Size: %d", re->gl_cap.max_rb_size);
+        goto finish;
+     }
+
+   // Set the internal format based on the config
+   if (!_set_internal_config(sfc, cfg))
+     {
+        ERR("Unsupported Format!");
+        goto finish;
      }
 
    // Create Render texture
    if (!_create_rt_buffers(re, sfc))
      {
-        ERR("_create_rt_buffers() failed.");
-        free(sfc);
-        return NULL;
+        ERR("Unable Create Specificed Surfaces.  Unsupported format!");
+        goto finish;
+     };
+
+   ret = sfc;
+
+finish:
+
+   res = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+   if (!res)
+     {
+        ERR("xxxMakeCurrent() (NULL, NULL) Error!");
      }
 
-   ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    if (!ret)
      {
-        ERR("xxxMakeCurrent() failed!");
-        free(sfc);
-        return NULL;
+        if (sfc) free(sfc);
      }
-
-   return sfc;
+   return ret;
 }
 
 static int
@@ -2304,6 +2870,9 @@ eng_gl_context_destroy(void *data, void *context)
         return 0;
      }
 
+   if (current_evgl_ctx == ctx)
+      current_evgl_ctx = NULL;
+
    free(ctx);
    context = NULL;
 
@@ -2323,6 +2892,8 @@ eng_gl_make_current(void *data __UNUSED__, void *surface, void *context)
    sfc = (Render_Engine_GL_Surface*)surface;
    ctx = (Render_Engine_GL_Context*)context;
 
+   current_engine = re;
+
    // Unset surface/context
    if ((!sfc) || (!ctx))
      {
@@ -2340,50 +2911,107 @@ eng_gl_make_current(void *data __UNUSED__, void *surface, void *context)
         return 1;
      }
 
-   // Do a make current only if it's not already current
-   if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0;
+   if ((sfc->direct_fb_opt) && ((gl_direct_img_obj) || (gl_direct_override)))
+     {
+        sfc->direct_sfc = re->win->egl_surface[0];
+        gl_direct_enabled = EINA_TRUE;
+     }
+   else
+     gl_direct_enabled = EINA_FALSE;
 
-   if ((eglGetCurrentContext() != ctx->context) ||
-       (eglGetCurrentSurface(EGL_READ) != rsc->surface) ||
-       (eglGetCurrentSurface(EGL_DRAW) != rsc->surface) )
+   if (gl_direct_enabled)
      {
-        // Flush remainder of what's in Evas' pipeline
-        if (re->win) eng_window_use(NULL);
+        GLint cur_fbo = 0;
 
-        // Do a make current
-        ret = eglMakeCurrent(re->win->egl_disp, rsc->surface,
-                             rsc->surface, ctx->context);
-        if (!ret)
+        if ((eglGetCurrentContext() != ctx->context))
           {
-             ERR("xxxMakeCurrent() failed!");
-             return 0;
+             eng_window_use(NULL);
+             ret = eglMakeCurrent(re->win->egl_disp, sfc->direct_sfc, 
+                                  sfc->direct_sfc, ctx->context);
+             if (!ret) return 0;
+          }
+        glGetIntegerv(GL_FRAMEBUFFER_BINDING, &cur_fbo);
+        if (ctx->context_fbo == (GLuint)cur_fbo)
+          {
+             ctx->current_fbo = 0;
+             glBindFramebuffer(GL_FRAMEBUFFER, 0);
           }
      }
-
-   // Create FBO if not already created
-   if (!ctx->initialized)
+   else
      {
-        glGenFramebuffers(1, &ctx->context_fbo);
-        ctx->initialized = 1;
-     }
+        if (eina_main_loop_is())
+          {
+             if ((eglGetCurrentDisplay() != re->win->egl_disp) ||
+               (eglGetCurrentContext() != ctx->context) ||
+                 (eglGetCurrentSurface(EGL_READ) != re->win->egl_surface[0]) || 
+                 (eglGetCurrentSurface(EGL_DRAW) != re->win->egl_surface[0]))
+               {
+                  // Flush remainder of what's in Evas' pipeline
+                  eng_window_use(NULL);
 
-   // Attach FBO if it hasn't been attached or if surface changed
-   if ((!sfc->fbo_attached) || (ctx->current_sfc != sfc))
-     {
-        if (!_attach_fbo_surface(re, sfc, ctx))
+                  // Do a make current
+                  ret = eglMakeCurrent(re->win->egl_disp, 
+                                       re->win->egl_surface[0], 
+                                       re->win->egl_surface[0],
+                                       ctx->context);
+
+                  if (!ret)
+                    {
+                       ERR("xxxMakeCurrent() failed!");
+                       return 0;
+                    }
+               }
+          }
+        else
           {
-             ERR("_attach_fbo_surface() failed.");
-             return 0;
+             // Do a make current only if it's not already current
+             if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0;
+
+             if ((eglGetCurrentDisplay() != re->win->egl_disp) ||
+                (eglGetCurrentContext() != ctx->context) ||
+                 (eglGetCurrentSurface(EGL_READ) != rsc->surface) || 
+                 (eglGetCurrentSurface(EGL_DRAW) != rsc->surface))
+               {
+                  // Flush remainder of what's in Evas' pipeline
+                  eng_window_use(NULL);
+
+                  // Do a make current
+                  ret = eglMakeCurrent(re->win->egl_disp, rsc->surface,
+                                       rsc->surface, ctx->context);
+
+                  if (!ret)
+                    {
+                       ERR("xxxMakeCurrent() failed!");
+                       return 0;
+                    }
+               }
           }
 
-        if (ctx->current_fbo)
-           // Bind to the previously bound buffer
-           glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
-        else
-           // Bind FBO
-           glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo);
+        // Create FBO if not already created
+        if (!ctx->initialized)
+          {
+             glGenFramebuffers(1, &ctx->context_fbo);
+             ctx->initialized = 1;
+          }
+
+        // Attach FBO if it hasn't been attached or if surface changed
+        if ((!sfc->fbo_attached) || (ctx->current_sfc != sfc))
+          {
+             if (!_attach_fbo_surface(re, sfc, ctx->context_fbo))
+               {
+                  ERR("_attach_fbo_surface() failed.");
+                  return 0;
+               }
+
+             if (ctx->current_fbo)
+               // Bind to the previously bound buffer
+               glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
+             else
+               // Bind FBO
+               glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo);
 
-        sfc->fbo_attached = 1;
+             sfc->fbo_attached = 1;
+          }
      }
 
    // Set the current surface/context
@@ -2414,18 +3042,24 @@ eng_gl_proc_address_get(void *data __UNUSED__, const char *name)
 }
 
 static int
-eng_gl_native_surface_get(void *data, void *surface, void *native_surface)
+eng_gl_native_surface_get(void *data __UNUSED__, void *surface, void *native_surface)
 {
-   Render_Engine *re;
+   /* Render_Engine *re; */
    Render_Engine_GL_Surface *sfc;
    Evas_Native_Surface *ns;
 
-   re  = (Render_Engine *)data;
+   /* re  = (Render_Engine *)data; */
    sfc = (Render_Engine_GL_Surface*)surface;
    ns  = (Evas_Native_Surface*)native_surface;
 
    ns->type = EVAS_NATIVE_SURFACE_OPENGL;
    ns->version = EVAS_NATIVE_SURFACE_VERSION;
+
+   if (sfc->direct_fb_opt)
+     ns->data.opengl.framebuffer_id = 0;
+   else
+     ns->data.opengl.framebuffer_id = sfc->rt_tex;
+
    ns->data.opengl.texture_id = sfc->rt_tex;
    ns->data.opengl.x = 0;
    ns->data.opengl.y = 0;
@@ -2440,9 +3074,9 @@ static const GLubyte *
 evgl_glGetString(GLenum name)
 {
    if (name == GL_EXTENSIONS)
-      return (GLubyte *)_gl_ext_string; //glGetString(GL_EXTENSIONS); 
+     return (GLubyte *)_gl_ext_string; //glGetString(GL_EXTENSIONS); 
    else
-      return glGetString(name);
+     return glGetString(name);
 }
 
 static void
@@ -2450,22 +3084,24 @@ evgl_glBindFramebuffer(GLenum target, GLuint framebuffer)
 {
    Render_Engine_GL_Context *ctx = current_evgl_ctx;
 
+   if (!ctx) return;
+
    // Take care of BindFramebuffer 0 issue
    if (framebuffer==0)
      {
-        if (ctx)
-          {
-             glBindFramebuffer(target, ctx->context_fbo);
-             ctx->current_fbo = 0;
-          }
+        if (gl_direct_enabled)
+          glBindFramebuffer(target, 0);
+        else
+          glBindFramebuffer(target, ctx->context_fbo);
+
+        ctx->current_fbo = 0;
      }
    else
      {
         glBindFramebuffer(target, framebuffer);
 
         // Save this for restore when doing make current
-        if (ctx)
-           ctx->current_fbo = framebuffer;
+        ctx->current_fbo = framebuffer;
      }
 }
 
@@ -2477,6 +3113,215 @@ evgl_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
    glBindRenderbuffer(target, renderbuffer);
 }
 
+// Transform from Evas Coordinat to GL Coordinate
+// returns: oc[4] original image object dimension in gl coord
+// returns: nc[4] tranformed  (x, y, width, heigth) in gl coord
+static void
+compute_gl_coordinates(Evas_Object *obj, int rot, int clip,
+                       int x, int y, int width, int height,
+                       int imgc[4], int objc[4])
+{
+   if (rot == 0)
+     {
+        // oringinal image object coordinate in gl coordinate
+        imgc[0] = obj->cur.geometry.x;
+        imgc[1] = obj->layer->evas->output.h - obj->cur.geometry.y - obj->cur.geometry.h;
+        imgc[2] = imgc[0] + obj->cur.geometry.w;
+        imgc[3] = imgc[1] + obj->cur.geometry.h;
+
+        // transformed (x,y,width,height) in gl coordinate
+        objc[0] = imgc[0] + x;
+        objc[1] = imgc[1] + y;
+        objc[2] = objc[0] + width;
+        objc[3] = objc[1] + height;
+     }
+   else if (rot == 180)
+     {
+        // oringinal image object coordinate in gl coordinate
+        imgc[0] = obj->layer->evas->output.w - obj->cur.geometry.x - obj->cur.geometry.w;
+        imgc[1] = obj->cur.geometry.y;
+        imgc[2] = imgc[0] + obj->cur.geometry.w;
+        imgc[3] = imgc[1] + obj->cur.geometry.h;
+
+        // transformed (x,y,width,height) in gl coordinate
+        objc[0] = imgc[0] + obj->cur.geometry.w - x - width;
+        objc[1] = imgc[1] + obj->cur.geometry.h - y - height;
+        objc[2] = objc[0] + width;
+        objc[3] = objc[1] + height;
+
+     }
+   else if (rot == 90)
+     {
+        // oringinal image object coordinate in gl coordinate
+        imgc[0] = obj->cur.geometry.y;
+        imgc[1] = obj->cur.geometry.x;
+        imgc[2] = imgc[0] + obj->cur.geometry.h;
+        imgc[3] = imgc[1] + obj->cur.geometry.w;
+
+        // transformed (x,y,width,height) in gl coordinate
+        objc[0] = imgc[0] + obj->cur.geometry.h - y - height;
+        objc[1] = imgc[1] + x;
+        objc[2] = objc[0] + height;
+        objc[3] = objc[1] + width;
+     }
+   else if (rot == 270)
+     {
+        // oringinal image object coordinate in gl coordinate
+        imgc[0] = obj->layer->evas->output.h - obj->cur.geometry.y - obj->cur.geometry.h;
+        imgc[1] = obj->layer->evas->output.w - obj->cur.geometry.x - obj->cur.geometry.w;
+        imgc[2] = imgc[0] + obj->cur.geometry.h;
+        imgc[3] = imgc[1] + obj->cur.geometry.w;
+
+        // transformed (x,y,width,height) in gl coordinate
+        objc[0] = imgc[0] + y;
+        objc[1] = imgc[1] + obj->cur.geometry.w - x - width;
+        objc[2] = objc[0] + height;
+        objc[3] = objc[1] + width;
+     }
+   else
+     {
+        ERR("Invalid rotation angle %d.", rot);
+        return;
+     }
+
+   if (clip)
+     {
+        // Clip against original image object
+        if (objc[0] < imgc[0]) objc[0] = imgc[0];
+        if (objc[0] > imgc[2]) objc[0] = 0;
+
+        if (objc[1] < imgc[1]) objc[1] = imgc[1];
+        if (objc[1] > imgc[3]) objc[1] = 0;
+
+        if (objc[2] < imgc[0]) objc[0] = 0;
+        if (objc[2] > imgc[2]) objc[2] = imgc[2];
+
+        if (objc[3] < imgc[1]) objc[1] = 0;
+        if (objc[3] > imgc[3]) objc[3] = imgc[3];
+     }
+
+   imgc[2] = imgc[2]-imgc[0];     // width
+   imgc[3] = imgc[3]-imgc[1];     // height
+
+   objc[2] = objc[2]-objc[0];     // width
+   objc[3] = objc[3]-objc[1];     // height
+}
+
+static void 
+evgl_glClear(GLbitfield mask)
+{
+   Render_Engine_GL_Context *ctx;
+   int rot = 0;
+   int oc[4], nc[4];
+
+   ctx = current_evgl_ctx;
+   if ((gl_direct_img_obj) && (gl_direct_enabled) && (ctx) && (!ctx->current_fbo))
+     {
+        if ((current_engine) && (current_engine->win) && (current_engine->win->gl_context))
+          rot = current_engine->win->gl_context->rot;
+
+        compute_gl_coordinates(gl_direct_img_obj, rot, 0, 0, 0, 0, 0, oc, nc);
+        glScissor(oc[0], oc[1], oc[2], oc[3]);
+        glClear(mask);
+     }
+   else
+     glClear(mask);
+}
+
+static void 
+evgl_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+   glClearColor(red, green, blue, alpha);
+}
+
+static void 
+evgl_glEnable(GLenum cap)
+{
+   Render_Engine_GL_Context *ctx;
+
+   ctx = current_evgl_ctx;
+   if (cap == GL_SCISSOR_TEST)
+     if (ctx) ctx->scissor_enabled = 1;
+   glEnable(cap);
+}
+
+static void 
+evgl_glDisable(GLenum cap)
+{
+   Render_Engine_GL_Context *ctx;
+
+   ctx = current_evgl_ctx;
+   if (cap == GL_SCISSOR_TEST)
+     if (ctx) ctx->scissor_enabled = 0;
+   glDisable(cap);
+}
+
+static void
+evgl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
+{
+   Render_Engine_GL_Context *ctx = current_evgl_ctx;
+   int rot = 0;
+   int oc[4], nc[4];
+
+   if ((gl_direct_img_obj) && (gl_direct_enabled) && (ctx) && (!ctx->current_fbo))
+     {
+        if ((current_engine) && (current_engine->win) && (current_engine->win->gl_context))
+          rot = current_engine->win->gl_context->rot;
+        else
+          ERR("Unable to retrieve rotation angle: %d", rot);
+
+        compute_gl_coordinates(gl_direct_img_obj, rot, 1, x, y, width, height, oc, nc);
+        glReadPixels(nc[0], nc[1], nc[2], nc[3], format, type, pixels);
+     }
+   else
+     glReadPixels(x, y, width, height, format, type, pixels);
+}
+
+static void
+evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+   Render_Engine_GL_Context *ctx = current_evgl_ctx;
+   int rot = 0;
+   int oc[4], nc[4];
+
+   if ((gl_direct_img_obj) && (gl_direct_enabled) && (ctx) && (!ctx->current_fbo))
+     {
+        if ((current_engine) && (current_engine->win) && (current_engine->win->gl_context))
+          rot = current_engine->win->gl_context->rot;
+        else
+          ERR("Unable to retrieve rotation angle: %d", rot);
+
+        compute_gl_coordinates(gl_direct_img_obj, rot, 1, x, y, width, height, oc, nc);
+        glScissor(nc[0], nc[1], nc[2], nc[3]);
+        ctx->scissor_updated = 1;
+     }
+   else
+     glScissor(x, y, width, height);
+}
+
+static void
+evgl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+   Render_Engine_GL_Context *ctx = current_evgl_ctx;
+   int rot = 0;
+   int oc[4], nc[4];
+
+   if ((gl_direct_img_obj) && (gl_direct_enabled) && (ctx) && (!ctx->current_fbo))
+     {
+        if ((current_engine) && (current_engine->win) && (current_engine->win->gl_context))
+          rot = current_engine->win->gl_context->rot;
+        else
+          ERR("Unable to retrieve rotation angle: %d", rot);
+
+        compute_gl_coordinates(gl_direct_img_obj, rot, 0, x, y, width, height, oc, nc);
+        glEnable(GL_SCISSOR_TEST);
+        glScissor(oc[0], oc[1], oc[2], oc[3]);
+        glViewport(nc[0], nc[1], nc[2], nc[3]);
+     }
+   else
+     glViewport(x, y, width, height);
+}
+
 static void
 evgl_glClearDepthf(GLclampf depth)
 {
@@ -2508,7 +3353,6 @@ evgl_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const
 }
 
 //--------------------------------//
-//#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
 // EGL Extensions
 static void *
 evgl_evasglCreateImage(int target, void* buffer, int *attrib_list)
@@ -2553,11 +3397,11 @@ evgl_glEvasGLImageTargetRenderbufferStorageOES(GLenum target, EvasGLImage image)
 
 
 static void *
-eng_gl_api_get(void *data)
+eng_gl_api_get(void *data __UNUSED__)
 {
-   Render_Engine *re;
+   /* Render_Engine *re; */
 
-   re  = (Render_Engine *)data;
+   /* re  = (Render_Engine *)data; */
 
    gl_funcs.version = EVAS_GL_API_VERSION;
 
@@ -2576,8 +3420,8 @@ eng_gl_api_get(void *data)
    ORD(glBufferData);
    ORD(glBufferSubData);
    ORD(glCheckFramebufferStatus);
-   ORD(glClear);
-   ORD(glClearColor);
+//   ORD(glClear); /***/
+//   ORD(glClearColor);/***/
 //   ORD(glClearDepthf);
    ORD(glClearStencil);
    ORD(glColorMask);
@@ -2599,11 +3443,11 @@ eng_gl_api_get(void *data)
    ORD(glDepthMask);
 //   ORD(glDepthRangef);
    ORD(glDetachShader);
-   ORD(glDisable);
+//   ORD(glDisable);/***/
    ORD(glDisableVertexAttribArray);
    ORD(glDrawArrays);
    ORD(glDrawElements);
-   ORD(glEnable);
+//   ORD(glEnable);/***/
    ORD(glEnableVertexAttribArray);
    ORD(glFinish);
    ORD(glFlush);
@@ -2657,7 +3501,7 @@ eng_gl_api_get(void *data)
 //   ORD(glReleaseShaderCompiler);
    ORD(glRenderbufferStorage);
    ORD(glSampleCoverage);
-   ORD(glScissor);
+//   ORD(glScissor);/***/
 //   ORD(glShaderBinary);
    ORD(glShaderSource);
    ORD(glStencilFunc);
@@ -2702,7 +3546,7 @@ eng_gl_api_get(void *data)
    ORD(glVertexAttrib4f);
    ORD(glVertexAttrib4fv);
    ORD(glVertexAttribPointer);
-   ORD(glViewport);
+//   ORD(glViewport);/***/
 #undef ORD
 
 #define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, glsym_)
@@ -2762,6 +3606,14 @@ eng_gl_api_get(void *data)
    ORD(glBindFramebuffer);
    ORD(glBindRenderbuffer);
 
+   ORD(glClear);
+   ORD(glClearColor);
+   ORD(glEnable);
+   ORD(glDisable);
+   ORD(glReadPixels);
+   ORD(glScissor);
+   ORD(glViewport);
+
    // GLES2.0 API compat on top of desktop gl
    ORD(glClearDepthf);
    ORD(glDepthRangef);
@@ -2776,7 +3628,6 @@ eng_gl_api_get(void *data)
    ORD(evasglDestroyImage);
    ORD(glEvasGLImageTargetTexture2DOES);
    ORD(glEvasGLImageTargetRenderbufferStorageOES);
-
 #undef ORD
 
    return &gl_funcs;
@@ -2898,6 +3749,25 @@ eng_image_max_size_get(void *data, int *maxw, int *maxh)
    if (maxh) *maxh = re->win->gl_context->shared->info.max_texture_size;
 }
 
+static void
+eng_context_flush(void *data)
+{
+   Render_Engine *re;
+   re = (Render_Engine *)data;
+
+   eng_window_use(re->win);
+   evas_gl_common_context_flush(re->win->gl_context);
+}
+
+static void
+eng_get_pixels_render_post(void *data)
+{
+   Render_Engine *re;
+
+   re = (Render_Engine *)data;
+   re->context_current = EINA_FALSE;
+}
+
 static int
 module_open(Evas_Module *em)
 {
@@ -3020,6 +3890,9 @@ module_open(Evas_Module *em)
 
    ORD(image_max_size_get);
 
+   ORD(context_flush);
+   ORD(get_pixels_render_post);
+
    /* now advertise out own api */
    em->functions = (void *)(&func);
    return 1;
old mode 100644 (file)
new mode 100755 (executable)
index c5f9721..776516b
@@ -18,6 +18,7 @@ eng_window_new(struct wl_display *disp, struct wl_surface *surface, int screen,
    int config_attrs[40];
    int major_version, minor_version;
    int num_config, n = 0;
+   const char *s;
    const GLubyte *vendor, *renderer, *version;
 
    gw = calloc(1, sizeof(Evas_GL_Wl_Window));
@@ -38,44 +39,6 @@ eng_window_new(struct wl_display *disp, struct wl_surface *surface, int screen,
    context_attrs[1] = 2;
    context_attrs[2] = EGL_NONE;
 
-#if defined(GLES_VARIETY_S3C6410)
-   if (gw->visualinfo->depth == 16) // 16bpp
-     {
-        config_attrs[n++] = EGL_SURFACE_TYPE;
-        config_attrs[n++] = EGL_WINDOW_BIT;
-        config_attrs[n++] = EGL_RENDERABLE_TYPE;
-        config_attrs[n++] = EGL_OPENGL_ES2_BIT;
-        config_attrs[n++] = EGL_RED_SIZE;
-        config_attrs[n++] = 5;
-        config_attrs[n++] = EGL_GREEN_SIZE;
-        config_attrs[n++] = 6;
-        config_attrs[n++] = EGL_BLUE_SIZE;
-        config_attrs[n++] = 5;
-        config_attrs[n++] = EGL_DEPTH_SIZE;
-        config_attrs[n++] = 0;
-        config_attrs[n++] = EGL_STENCIL_SIZE;
-        config_attrs[n++] = 0;
-        config_attrs[n++] = EGL_NONE;
-     }
-   else // 24/32bit. no one does 8bpp anymore. and 15bpp... dead
-     {
-        config_attrs[n++] = EGL_SURFACE_TYPE;
-        config_attrs[n++] = EGL_WINDOW_BIT;
-        config_attrs[n++] = EGL_RENDERABLE_TYPE;
-        config_attrs[n++] = EGL_OPENGL_ES2_BIT;
-        config_attrs[n++] = EGL_RED_SIZE;
-        config_attrs[n++] = 8;
-        config_attrs[n++] = EGL_GREEN_SIZE;
-        config_attrs[n++] = 8;
-        config_attrs[n++] = EGL_BLUE_SIZE;
-        config_attrs[n++] = 8;
-        config_attrs[n++] = EGL_DEPTH_SIZE;
-        config_attrs[n++] = 0;
-        config_attrs[n++] = EGL_STENCIL_SIZE;
-        config_attrs[n++] = 0;
-        config_attrs[n++] = EGL_NONE;
-     }
-#elif defined(GLES_VARIETY_SGX)
    config_attrs[n++] = EGL_SURFACE_TYPE;
    config_attrs[n++] = EGL_WINDOW_BIT;
    config_attrs[n++] = EGL_RENDERABLE_TYPE;
@@ -104,8 +67,15 @@ eng_window_new(struct wl_display *disp, struct wl_surface *surface, int screen,
    config_attrs[n++] = 0;
    config_attrs[n++] = EGL_STENCIL_SIZE;
    config_attrs[n++] = 0;
+   if (s = getenv("EVAS_GL_MULTISAMPLE"))
+     {
+        int multisample_bits = atoi(s);
+        config_attrs[n++] = EGL_SAMPLE_BUFFERS;
+        config_attrs[n++] = 1;
+        config_attrs[n++] = EGL_SAMPLES;
+        config_attrs[n++] = multisample_bits;
+     }
    config_attrs[n++] = EGL_NONE;
-#endif
    
    gw->egl_disp = eglGetDisplay((EGLNativeDisplayType)(gw->disp));
    if (!gw->egl_disp)
@@ -137,7 +107,10 @@ eng_window_new(struct wl_display *disp, struct wl_surface *surface, int screen,
         return NULL;
      }
 
-   gw->win = wl_egl_window_create(gw->surface, gw->w, gw->h);
+   if ((gw->rot == 0) || (gw->rot == 180))
+     gw->win = wl_egl_window_create(gw->surface, gw->w, gw->h);
+   else if ((gw->rot == 90) || (gw->rot == 270))
+     gw->win = wl_egl_window_create(gw->surface, gw->h, gw->w);
 
    gw->egl_surface[0] = eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
                                                (EGLNativeWindowType)gw->win,
@@ -150,7 +123,9 @@ eng_window_new(struct wl_display *disp, struct wl_surface *surface, int screen,
         return NULL;
      }
 
-   gw->egl_context[0] = eglCreateContext(gw->egl_disp, gw->egl_config, share_context, context_attrs);
+   gw->egl_context[0] = 
+     eglCreateContext(gw->egl_disp, gw->egl_config, share_context, 
+                      context_attrs);
 
    if (gw->egl_context[0] == EGL_NO_CONTEXT)
      {
@@ -189,7 +164,9 @@ eng_window_new(struct wl_display *disp, struct wl_surface *surface, int screen,
        eng_window_free(gw);
        return NULL;
      }
+#ifdef GL_GLES
    gw->gl_context->egldisp = gw->egl_disp;
+#endif
    eng_window_use(gw);
    evas_gl_common_context_resize(gw->gl_context, w, h, rot);
    gw->surf = 1;
@@ -235,7 +212,12 @@ eng_window_use(Evas_GL_Wl_Window *gw)
 
    if (_evas_gl_wl_window)
      {
-        if ((eglGetCurrentContext() !=
+        if (
+#ifdef GL_GLES
+            (eglGetCurrentDisplay() !=
+             _evas_gl_x11_window->egl_disp) ||
+#endif
+            (eglGetCurrentContext() !=
              _evas_gl_wl_window->egl_context[0]) ||
             (eglGetCurrentSurface(EGL_READ) !=
                 _evas_gl_wl_window->egl_surface[0]) ||
@@ -317,12 +299,5 @@ eng_best_depth_get(Evas_Engine_Info_Wayland_Egl *einfo)
 {
    if (!einfo) return 0;
    if (!einfo->info.display) return 0;
-   return 32;
-   /* if (!_evas_gl_x11_vi) eng_best_visual_get(einfo); */
-   /* if (!_evas_gl_x11_vi) return 0; */
-   /* if (einfo->info.destination_alpha) */
-   /*   { */
-   /*      if (_evas_gl_x11_rgba_vi) return _evas_gl_x11_rgba_vi->depth; */
-   /*   } */
-   /* return _evas_gl_x11_vi->depth; */
+   return (einfo->info.depth ? einfo->info.depth : 32);
 }
index a40f187..63954f5 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _EVAS_ENGINE_WAYLAND_SHM_H
 # define _EVAS_ENGINE_WAYLAND_SHM_H
 
+#include <Evas.h>
 /*
  * Wayland supoprt is considered experimental as wayland itself is still
  * unstable and liable to change core protocol. If you use this api, it is
@@ -18,7 +19,6 @@ struct _Evas_Engine_Info_Wayland_Shm
         int rotation;
 
         Eina_Bool destination_alpha : 1;
-        Eina_Bool debug : 1;
      } info;
 
    Evas_Engine_Render_Mode render_mode;
index 6a180ab..9a1ea99 100644 (file)
@@ -9,7 +9,8 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/modules/engines \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
 @evas_engine_wayland_shm_cflags@
 
 if BUILD_ENGINE_WAYLAND_SHM
@@ -18,7 +19,7 @@ WAYLAND_SHM_SOURCES = \
 evas_engine.c \
 evas_outbuf.c
 
-WAYLAND_SHM_LIBADD = @FREETYPE_LIBS@ @PIXMAN_LIBS@ @EINA_LIBS@ @evas_engine_wayland_shm_libs@
+WAYLAND_SHM_LIBADD = @FREETYPE_LIBS@ @PIXMAN_LIBS@ @EVAS_GENERAL_LIBS@ @evas_engine_wayland_shm_libs@
 
 includes_HEADERS = Evas_Engine_Wayland_Shm.h
 includesdir = $(includedir)/evas-@VMAJ@
index dcf3aa1..4c7d943 100644 (file)
@@ -85,7 +85,6 @@ eng_info(Evas *evas __UNUSED__)
      return NULL;
 
    info->magic.magic = rand();
-   info->info.debug = EINA_FALSE;
    info->render_mode = EVAS_RENDER_MODE_BLOCKING;
 
    return info;
index b7ed9a5..5151455 100644 (file)
@@ -74,6 +74,12 @@ SUBDIRS += tga
 endif
 endif
 
+if BUILD_LOADER_TGV
+if !EVAS_STATIC_BUILD_TGV
+SUBDIRS += tgv
+endif
+endif
+
 if BUILD_LOADER_TIFF
 if !EVAS_STATIC_BUILD_TIFF
 SUBDIRS += tiff
@@ -86,6 +92,12 @@ SUBDIRS += wbmp
 endif
 endif
 
+if BUILD_LOADER_WEBP
+if !EVAS_STATIC_BUILD_WEBP
+SUBDIRS += webp
+endif
+endif
+
 if BUILD_LOADER_XPM
 if !EVAS_STATIC_BUILD_XPM
 SUBDIRS += xpm
index 1ab3128..06861e2 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @EVIL_CFLAGS@
 
 if BUILD_LOADER_BMP
@@ -19,7 +19,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_bmp.c
 
-module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ -lm $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@ -lm $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 9453ceb..dec54e1 100644 (file)
@@ -109,7 +109,7 @@ evas_image_load_file_head_bmp(Image_Entry *ie, const char *file, const char *key
    char hasa = 0;
    int w = 0, h = 0, bit_count = 0, image_size = 0, comp = 0;
    unsigned int offset, head_size, amask = 0;
-   int fsize = 0;
+   size_t fsize;
    unsigned int bmpsize;
    unsigned short res1, res2;
 
@@ -135,6 +135,7 @@ evas_image_load_file_head_bmp(Image_Entry *ie, const char *file, const char *key
    if (!read_ushort(map, fsize, &position, &res2)) goto close_file;
    if (!read_uint(map, fsize, &position, &offset)) goto close_file;
    if (!read_uint(map, fsize, &position, &head_size)) goto close_file;
+   if (offset > fsize) goto close_file;
    if (head_size == 12) // OS/2 V1 + Windows 3.0
      {
         short tmp;
@@ -392,7 +393,7 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
      rmask = 0, gmask = 0, bmask = 0, amask = 0;
    int right_way_up = 0;
    unsigned char r, g, b, a;
-   int fsize = 0;
+   size_t fsize;
    unsigned int bmpsize;
    unsigned short res1, res2;
 
@@ -424,6 +425,7 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
    if (!read_ushort(map, fsize, &position, &res2)) goto close_file;
    if (!read_uint(map, fsize, &position, &offset)) goto close_file;
    if (!read_uint(map, fsize, &position, &head_size)) goto close_file;
+   if (offset > fsize) goto close_file;
    image_size = fsize - offset;
    if (image_size < 1) goto close_file;
 
@@ -456,7 +458,7 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
         if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
         comp = tmp2; // compression method
         if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
-        image_size = tmp2; // bitmap data size
+        if (tmp2 <= image_size) image_size = tmp2; // bitmap data size, GIMP can handle image size error
         if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
         //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter
         if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
@@ -484,7 +486,7 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
         if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
         comp = tmp2; // compression method
         if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
-        image_size = tmp2; // bitmap data size
+        if (tmp2 <= image_size) image_size = tmp2; // bitmap data size, GIMP can handle image size error
         if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
         //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter
         if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
@@ -512,7 +514,7 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
         if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
         comp = tmp2; // compression method
         if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
-        image_size = tmp2; // bitmap data size
+        if (tmp2 <= image_size) image_size = tmp2; // bitmap data size, GIMP can handle image size error
         if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
         //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter
         if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
@@ -550,7 +552,7 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
         if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
         comp = tmp2; // compression method
         if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
-        image_size = tmp2; // bitmap data size
+        if (tmp2 <= image_size) image_size = tmp2; // bitmap data size, GIMP can handle image size error
         if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
         //hdpi = (tmp2 * 254) / 10000; // horizontal pixels/meter
         if (!read_int(map, fsize, &position, &tmp2)) goto close_file;
@@ -623,6 +625,8 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
      }
 
    row_size = ceil((double)(image_w * bit_count) / 32) * 4;
+   if (image_size != row_size * h)
+     image_size = row_size * h;
 
    if (bit_count < 16)
      {
@@ -659,7 +663,11 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
         position = offset;
 
         if ((scale_ratio == 1) || (comp !=0))
-          buffer = malloc(image_size + 8); // add 8 for padding to avoid checks
+          {
+             if (image_size < (int) fsize - position)
+               image_size = fsize - position;
+             buffer = malloc(image_size + 8); // add 8 for padding to avoid checks
+          }
         else
           {
              scale_surface = malloc(image_w * sizeof(DATA32)); //for one line decoding
index eeece3f..d74f3b7 100644 (file)
@@ -9,7 +9,7 @@ AM_CPPFLAGS = \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_image_loader_edb_cflags@ \
-@EINA_CFLAGS@
+@EVAS_GENERAL_CFLAGS@
 
 
 if BUILD_LOADER_EDB
@@ -20,7 +20,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_edb.c
 
-module_la_LIBADD = @evas_image_loader_edb_libs@ @EINA_LIBS@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @evas_image_loader_edb_libs@ @EVAS_GENERAL_LIBS@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 2a3f92f..7e954e9 100644 (file)
@@ -9,7 +9,7 @@ AM_CPPFLAGS = \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_image_loader_eet_cflags@ \
-@EINA_CFLAGS@
+@EVAS_GENERAL_CFLAGS@
 
 
 if BUILD_LOADER_EET
@@ -20,7 +20,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_eet.c
 
-module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_eet_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @evas_image_loader_eet_libs@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index f86246a..61100c7 100644 (file)
@@ -20,11 +20,33 @@ Evas_Image_Load_Func evas_image_load_eet_func =
   EINA_FALSE
 };
 
+static const Evas_Colorspace cspaces_etc1[2] = {
+  EVAS_COLORSPACE_ETC1,
+  EVAS_COLORSPACE_ARGB8888
+};
+
+static const Evas_Colorspace cspaces_etc2_rgb[2] = {
+  EVAS_COLORSPACE_RGB8_ETC2,
+  EVAS_COLORSPACE_ARGB8888
+};
+
+static const Evas_Colorspace cspaces_etc2_rgba[2] = {
+  EVAS_COLORSPACE_RGBA8_ETC2_EAC,
+  EVAS_COLORSPACE_ARGB8888
+};
+
+static const Evas_Colorspace cspaces_etc1_alpha[2] = {
+   EVAS_COLORSPACE_ETC1_ALPHA,
+   EVAS_COLORSPACE_ARGB8888
+};
+
 
 static Eina_Bool
 evas_image_load_file_head_eet(Image_Entry *ie, const char *file, const char *key, int *error)
 {
-   int                  alpha, compression, quality, lossy;
+   int                  alpha, compression, quality;
+   Eet_Image_Encoding   lossy;
+   const Eet_Colorspace *cspaces = NULL;
    unsigned int         w, h;
    Eet_File            *ef;
    int                  ok;
@@ -54,6 +76,39 @@ evas_image_load_file_head_eet(Image_Entry *ie, const char *file, const char *key
        *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
        goto on_error;
      }
+
+   if (eet_data_image_colorspace_get(ef, key, NULL, &cspaces))
+     {
+        if (cspaces)
+          {
+             unsigned int i;
+
+             for (i = 0; cspaces[i] != EET_COLORSPACE_ARGB8888; i++)
+               {
+                  if (cspaces[i] == EET_COLORSPACE_ETC1)
+                    {
+                       ie->cspaces = cspaces_etc1;
+                       break;
+                    }
+                  else if (cspaces[i] == EET_COLORSPACE_RGB8_ETC2)
+                    {
+                       ie->cspaces = cspaces_etc2_rgb;
+                       break;
+                    }
+                  else if (cspaces[i] == EET_COLORSPACE_RGBA8_ETC2_EAC)
+                    {
+                       ie->cspaces = cspaces_etc2_rgba;
+                       break;
+                    }
+                  else if (cspaces[i] == EET_COLORSPACE_ETC1_ALPHA)
+                    {
+                       ie->cspaces = cspaces_etc1_alpha;
+                       break;
+                    }
+               }
+          }
+     }
+
    if (alpha) ie->flags.alpha = 1;
    ie->w = w;
    ie->h = h;
@@ -69,11 +124,25 @@ Eina_Bool
 evas_image_load_file_data_eet(Image_Entry *ie, const char *file, const char *key, int *error)
 {
    unsigned int         w, h;
-   int                  alpha, compression, quality, lossy, ok;
+   int                  alpha, compression, quality, ok;
    Eet_File            *ef;
    DATA32              *body, *p, *end, *data;
    DATA32               nas = 0;
    Eina_Bool           res = EINA_FALSE;
+   Eet_Colorspace       cspace;
+   Eet_Image_Encoding   lossy;
+
+   switch (ie->space)
+     {
+      case EVAS_COLORSPACE_ETC1: cspace = EET_COLORSPACE_ETC1; break;
+      case EVAS_COLORSPACE_ETC1_ALPHA: cspace = EET_COLORSPACE_ETC1_ALPHA; break;
+      case EVAS_COLORSPACE_RGB8_ETC2: cspace = EET_COLORSPACE_RGB8_ETC2; break;
+      case EVAS_COLORSPACE_RGBA8_ETC2_EAC: cspace = EET_COLORSPACE_RGBA8_ETC2_EAC; break;
+      case EVAS_COLORSPACE_ARGB8888: cspace = EET_COLORSPACE_ARGB8888; break;
+      default:
+        *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+        return EINA_FALSE;
+     }
 
    if (!key)
      {
@@ -110,15 +179,17 @@ evas_image_load_file_data_eet(Image_Entry *ie, const char *file, const char *key
        *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
        goto on_error;
      }
-   ok = eet_data_image_read_to_surface(ef, key, 0, 0,
-                                      data, w, h, w * 4,
-                                      &alpha, &compression, &quality, &lossy);
+
+   ok = eet_data_image_read_to_cspace_surface_cipher(ef, key, NULL, 0, 0,
+                                                     data, w, h, w * 4,
+                                                     cspace,
+                                                     &alpha, &compression, &quality, &lossy);
    if (!ok)
      {
        *error = EVAS_LOAD_ERROR_GENERIC;
        goto on_error;
      }
-   if (alpha)
+   if (alpha && (cspace == EET_COLORSPACE_ARGB8888))
      {
        ie->flags.alpha = 1;
 
index 31975b8..6da5d91 100644 (file)
@@ -9,7 +9,7 @@ AM_CPPFLAGS = \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_image_loader_generic_cflags@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @EVIL_CFLAGS@
 
 
@@ -21,7 +21,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_generic.c
 
-module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_generic_libs@ @EFL_SHM_OPEN_LIBS@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @evas_image_loader_generic_libs@ @EFL_SHM_OPEN_LIBS@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index ee704d5..81df0ec 100644 (file)
@@ -151,18 +151,21 @@ _load(Image_Entry *ie, const char *file, const char *key, int *error, Eina_Bool
         // double extn not too long
         if (((end - dot2) <= 10) && (!illegal_char(dot2)))
           {
-             strcpy(&(decoders[decoders_num][0]), img_loader);
+             strncpy(&(decoders[decoders_num][0]), img_loader, 127);
+             decoders[decoders_num][127] = 0;
              dotcat(&(decoders[decoders_num][0]), dot2);
              decoders_num++;
           }
         // single extn not too long
         if (((end - dot1) <= 5) && (!illegal_char(dot1)))
           {
-             strcpy(&(decoders[decoders_num][0]), img_loader);
+             strncpy(&(decoders[decoders_num][0]), img_loader, 127);
+             decoders[decoders_num][127] = 0;
              dotcat(&(decoders[decoders_num][0]), dot1);
              decoders_num++;
           }
-        strcpy(decoders[decoders_num], img_loader);
+        strncpy(decoders[decoders_num], img_loader, 127);
+        decoders[decoders_num][127] = 0;
         decoders_num++;
      }
    else if (dot1)
@@ -170,16 +173,19 @@ _load(Image_Entry *ie, const char *file, const char *key, int *error, Eina_Bool
         // single extn not too long
         if (((end - dot1) <= 5) && (!illegal_char(dot1)))
           {
-             strcpy(&(decoders[decoders_num][0]), img_loader);
+             strncpy(&(decoders[decoders_num][0]), img_loader, 127);
+             decoders[decoders_num][127] = 0;
              dotcat(&(decoders[decoders_num][0]), dot1);
              decoders_num++;
           }
-        strcpy(decoders[decoders_num], img_loader);
+        strncpy(decoders[decoders_num], img_loader, 127);
+        decoders[decoders_num][127] = 0;
         decoders_num++;
      }
    else
      {
-        strcpy(decoders[decoders_num], img_loader);
+        strncpy(decoders[decoders_num], img_loader, 127);
+        decoders[decoders_num][127] = 0;
         decoders_num++;
      }
 
index aa5c240..cb666c1 100644 (file)
@@ -9,7 +9,7 @@ AM_CPPFLAGS = \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_image_loader_gif_cflags@ \
-@EINA_CFLAGS@
+@EVAS_GENERAL_CFLAGS@
 
 if BUILD_LOADER_GIF
 if !EVAS_STATIC_BUILD_GIF
@@ -19,7 +19,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_gif.c
 
-module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_gif_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @evas_image_loader_gif_libs@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 18a6e23..c840d13 100644 (file)
 
 #include <gif_lib.h>
 
-typedef struct _Gif_Frame Gif_Frame;
+#ifndef MIN
+# define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+#define byte2_to_int(a,b)         (((b)<<8)|(a))
+#define FRAME_MAX 1024
 
-typedef enum _Frame_Load_Type
-{
-   LOAD_FRAME_NONE = 0,
-   LOAD_FRAME_INFO = 1,
-   LOAD_FRAME_DATA = 2,
-   LOAD_FRAME_DATA_INFO = 3
-} Frame_Load_Type;
+#define LOADERR(x) \
+do { \
+   *error = (x); \
+     printf("loaderr\n"); \
+   goto on_error; \
+} while (0)
 
-struct _Gif_Frame
-{
-   struct {
-      /* Image descriptor */
-      int        x;
-      int        y;
-      int        w;
-      int        h;
-      int        interlace;
-   } image_des;
-
-   struct {
-      /* Graphic Control*/
-      int        disposal;
-      int        transparent;
-      int        delay;
-      int        input;
-   } frame_info;
-};
+#define PIX(_x, _y) rows[yin + _y][xin + _x]
+#define CMAP(_v) cmap->Colors[_v]
+#define PIXLK(_p) ARGB_JOIN(0xff, CMAP(_p).Red, CMAP(_p).Green, CMAP(_p).Blue)
 
-static Eina_Bool evas_image_load_file_data_gif_internal(Image_Entry *ie, Image_Entry_Frame *frame, int *error);
 
-static Eina_Bool evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
-static Eina_Bool evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
-static double evas_image_load_frame_duration_gif(Image_Entry *ie, const char *file, int start_frame, int frame_num) ;
-static Eina_Bool evas_image_load_specific_frame(Image_Entry *ie, const char *file, int frame_index, int *error);
+typedef struct _Frame_Info Frame_Info;
 
-static Evas_Image_Load_Func evas_image_load_gif_func =
+struct _Frame_Info
 {
-  EINA_TRUE,
-  evas_image_load_file_head_gif,
-  evas_image_load_file_data_gif,
-  evas_image_load_frame_duration_gif,
-  EINA_FALSE
+   int x, y, w, h;
+   unsigned short delay;
+   short transparent : 10;
+   short dispose : 6;
+   short interlace : 1;
 };
-#define byte2_to_int(a,b)         (((b)<<8)|(a))
 
-#define FRAME_MAX 1024
 
-/* find specific frame in image entry */
-static Eina_Bool
-_find_frame(Image_Entry *ie, int frame_index, Image_Entry_Frame **frame)
+static Image_Entry_Frame *
+_find_frame(Image_Entry *ie, int index)
 {
    Eina_List *l;
-   Image_Entry_Frame *hit_frame = NULL;
+   Image_Entry_Frame *frame;
 
    if (!ie) return EINA_FALSE;
    if (!ie->frames) return EINA_FALSE;
 
-   EINA_LIST_FOREACH(ie->frames, l, hit_frame)
+   EINA_LIST_FOREACH(ie->frames, l, frame)
+      if (frame->index == index) return frame;
+   return NULL;
+}
+
+// fill in am image with a specific rgba color value
+static void
+_fill_image(DATA32 *data, int rowpix, DATA32 val, int x, int y, int w, int h)
+{
+   int xx, yy;
+   DATA32 *p;
+
+   for (yy = 0; yy < h; yy++)
      {
-        if (hit_frame->index == frame_index)
+        p = data + ((y + yy) * rowpix) + x;
+        for (xx = 0; xx < w; xx++)
           {
-             *frame = hit_frame;
-             return EINA_TRUE;
+             *p = val;
+             p++;
           }
      }
-   return EINA_FALSE;
 }
 
-static Eina_Bool
-_find_close_frame(Image_Entry *ie, int frame_index, Image_Entry_Frame **frame)
+static void
+_clip_coords(int imw, int imh, int *xin, int *yin,
+             int x0, int y0, int w0, int h0,
+             int *x, int *y, int *w, int *h)
 {
-  int i;
-  Eina_Bool hit = EINA_FALSE;
-  i = frame_index -1;
-
-  if (!ie) return EINA_FALSE;
-  if (!ie->frames) return EINA_FALSE;
-
-  for (; i > 0; i--)
-    {
-       hit = _find_frame(ie, i, frame);
-       if (hit)
-         return  EINA_TRUE;
-    }
-  return EINA_FALSE;
+   if (x0 < 0)
+     {
+        w0 += x0;
+        *xin = -x0;
+        x0 = 0;
+     }
+   if ((x0 + w0) > imw) w0 = imw - x0;
+   if (y0 < 0)
+     {
+        h0 += y0;
+        *yin = -y0;
+        y0 = 0;
+     }
+   if ((y0 + h0) > imh) h0 = imh - y0;
+   *x = x0;
+   *y = y0;
+   *w = w0;
+   *h = h0;
 }
 
-static Eina_Bool
-_evas_image_skip_frame(GifFileType *gif, int frame)
+static void
+_fill_frame(DATA32 *data, int rowpix, GifFileType *gif, Frame_Info *finfo,
+            int x, int y, int w, int h)
 {
-   int                 remain_frame = 0;
-   GifRecordType       rec;
-
-   if (!gif) return EINA_FALSE;
-   if (frame == 0) return EINA_TRUE; /* no need to skip */
-   if (frame < 0 || frame > FRAME_MAX) return EINA_FALSE;
-
-   remain_frame = frame;
-
-   do
-     {
-        if (DGifGetRecordType(gif, &rec) == GIF_ERROR) return EINA_FALSE;
-
-        if (rec == EXTENSION_RECORD_TYPE)
-          {
-             int                 ext_code;
-             GifByteType        *ext;
-
-             ext = NULL;
-             DGifGetExtension(gif, &ext_code, &ext);
-             while (ext)
-               { /*skip extention */
-                  ext = NULL;
-                  DGifGetExtensionNext(gif, &ext);
-               }
-          }
-
-        if (rec == IMAGE_DESC_RECORD_TYPE)
-          {
-             int                 img_code;
-             GifByteType        *img;
-
-             if (DGifGetImageDesc(gif) == GIF_ERROR) return EINA_FALSE;
-
-             remain_frame --;
-             /* we have to count frame, so use DGifGetCode and skip decoding */
-             if (DGifGetCode(gif, &img_code, &img) == GIF_ERROR) return EINA_FALSE;
-
-             while (img)
-               {
-                  img = NULL;
-                  DGifGetCodeNext(gif, &img);
-               }
-             if (remain_frame < 1) return EINA_TRUE;
-          }
-        if (rec == TERMINATE_RECORD_TYPE) return EINA_FALSE;  /* end of file */
-
-     } while ((rec != TERMINATE_RECORD_TYPE) && (remain_frame > 0));
-   return EINA_FALSE;
+   // solid color fill for pre frame region
+   if (finfo->transparent < 0)
+     {
+        ColorMapObject *cmap;
+        int bg;
+
+        // work out color to use from cmap
+        if (gif->Image.ColorMap) cmap = gif->Image.ColorMap;
+        else cmap = gif->SColorMap;
+        bg = gif->SBackGroundColor;
+        // and do the fill
+        _fill_image
+          (data, rowpix,
+           ARGB_JOIN(0xff, CMAP(bg).Red, CMAP(bg).Green, CMAP(bg).Blue),
+           x, y, w, h);
+     }
+   // fill in region with 0 (transparent)
+   else
+     _fill_image(data, rowpix, 0, x, y, w, h);
 }
 
-static Eina_Bool
-_evas_image_load_frame_graphic_info(Image_Entry_Frame *frame, GifByteType  *ext)
+// store common fields from gif file info into frame info
+static void
+_store_frame_info(GifFileType *gif, Frame_Info *finfo)
 {
-   Gif_Frame *gif_frame = NULL;
-   if ((!frame) || (!ext)) return EINA_FALSE;
-
-   gif_frame = (Gif_Frame *) frame->info;
-
-   /* transparent */
-   if ((ext[1] & 0x1) != 0)
-     gif_frame->frame_info.transparent = ext[4];
-   else
-     gif_frame->frame_info.transparent = -1;
+   finfo->x = gif->Image.Left;
+   finfo->y = gif->Image.Top;
+   finfo->w = gif->Image.Width;
+   finfo->h = gif->Image.Height;
+   finfo->interlace = gif->Image.Interlace;
+}
 
-   gif_frame->frame_info.input = (ext[1] >>1) & 0x1;
-   gif_frame->frame_info.disposal = (ext[1] >>2) & 0x7;
-   gif_frame->frame_info.delay = byte2_to_int(ext[2], ext[3]);
-   return EINA_TRUE;
+// check if image fills "screen space" and if so, if it is transparent
+// at all then the image could be transparent - OR if image doesnt fill,
+// then it could be trasnparent (full coverage of screen). some gifs will
+// be recognized as solid here for faster rendering, but not all.
+static void
+_check_transparency(Eina_Bool *full, Frame_Info *finfo, int w, int h)
+{
+   if ((finfo->x == 0) && (finfo->y == 0) &&
+       (finfo->w == w) && (finfo->h == h))
+     {
+        if (finfo->transparent >= 0) *full = EINA_FALSE;
+     }
+   else *full = EINA_FALSE;
 }
 
-static Eina_Bool
-_evas_image_load_frame_image_des_info(GifFileType *gif, Image_Entry_Frame *frame)
+// allocate frame and frame info and append to list and store fields
+static Frame_Info *
+_new_frame(Image_Entry *ie,
+           int transparent, int dispose, int delay,
+           int index)
 {
-   Gif_Frame *gif_frame = NULL;
-   if ((!gif) || (!frame)) return EINA_FALSE;
-
-   gif_frame = (Gif_Frame *) frame->info;
-   gif_frame->image_des.x = gif->Image.Left;
-   gif_frame->image_des.y = gif->Image.Top;
-   gif_frame->image_des.w = gif->Image.Width;
-   gif_frame->image_des.h = gif->Image.Height;
-   gif_frame->image_des.interlace = gif->Image.Interlace;
-   return EINA_TRUE;
+   Image_Entry_Frame *frame;
+   Frame_Info *finfo;
+
+   // allocate frame and frame info data (MUSt be separate)
+   frame = calloc(1, sizeof(Image_Entry_Frame));
+   if (!frame) return NULL;
+   finfo = calloc(1, sizeof(Frame_Info));
+   if (!finfo)
+     {
+        free(frame);
+        return NULL;
+     }
+   // record transparent index to be used or -1 if none
+   // for this SPECIFIC frame
+   finfo->transparent = transparent;
+   // record dispose mode (3 bits)
+   finfo->dispose = dispose;
+   // record delay (2 bytes so max 65546 /100 sec)
+   finfo->delay = delay;
+   // record the index number we are at
+   frame->index = index;
+   // that frame is stored AT image/screen size
+   frame->info = finfo;
+   ie->frames = eina_list_append(ie->frames, frame);
+   return finfo;
 }
 
 static Eina_Bool
-_evas_image_load_frame_image_data(Image_Entry *ie, GifFileType *gif, Image_Entry_Frame *frame, int *error)
+_decode_image(GifFileType *gif, DATA32 *data, int rowpix, int xin, int yin,
+              int transparent, int x, int y, int w, int h, Eina_Bool fill)
 {
-   int                 w;
-   int                 h;
-   int                 x;
-   int                 y;
-   int                 i,j;
-   int                 bg;
-   int                 r;
-   int                 g;
-   int                 b;
-   int                 alpha;
-   double              per;
-   double              per_inc;
-   ColorMapObject     *cmap;
-   GifRowType         *rows;
-   GifPixelType       *tmp = NULL; /*for skip gif line */
-   int                 intoffset[] = { 0, 4, 2, 1 };
-   int                 intjump[] = { 8, 8, 4, 2 };
-   size_t              siz;
-   int                 cache_w;
-   int                 cache_h;
-   int                 cur_h;
-   int                 cur_w;
-   int                 disposal = 0;
-   int                 bg_val = 0;
-   DATA32             *ptr;
-   Gif_Frame          *gif_frame = NULL;
-   /* for scale down decoding */
-   int                 scale_ratio = 1;
-   int                 scale_w, scale_h, scale_x, scale_y;
-
-   if ((!gif) || (!frame)) return EINA_FALSE;
-
-   gif_frame = (Gif_Frame *) frame->info;
-   w = gif->Image.Width;
-   h = gif->Image.Height;
-   x = gif->Image.Left;
-   y = gif->Image.Top;
-   cache_w = ie->w;
-   cache_h = ie->h;
-
-   /* if user don't set scale down, default scale_ratio is 1 */
-   if (ie->load_opts.scale_down_by > 1) scale_ratio = ie->load_opts.scale_down_by;
-   scale_w = w / scale_ratio;
-   scale_h = h / scale_ratio;
-   scale_x = x / scale_ratio;
-   scale_y = y / scale_ratio;
-
-   rows = malloc(scale_h * sizeof(GifRowType *));
-
-   if (!rows)
-     {
-        *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
-        return EINA_FALSE;
-     }
-   for (i = 0; i < scale_h; i++)
-     {
-        rows[i] = NULL;
-     }
-   /* alloc memory according to scaled size */
-   for (i = 0; i < scale_h; i++)
-     {
-        rows[i] = malloc(w * sizeof(GifPixelType));
-        if (!rows[i])
-          {
-             for (i = 0; i < scale_h; i++)
-               {
-                  if (rows[i])
-                    {
-                       free(rows[i]);
-                    }
-               }
-             free(rows);
-             *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
-             return EINA_FALSE;
-          }
-     }
+   int intoffset[] = { 0, 4, 2, 1 };
+   int intjump[] = { 8, 8, 4, 2 };
+   int i, xx, yy, pix;
+   GifRowType *rows;
+   Eina_Bool ret = EINA_FALSE;
+   ColorMapObject *cmap;
+   DATA32 *p;
 
-   if (scale_ratio > 1)
+   // build a blob of memory to have pointers to rows of pixels
+   // AND store the decoded gif pixels (1 byte per pixel) as welll
+   rows = malloc((h * sizeof(GifRowType *)) + (w * h * sizeof(GifPixelType)));
+   if (!rows) goto on_error;
+
+   // fill in the pointers at the start
+   for (yy = 0; yy < h; yy++)
      {
-        tmp = malloc(w * sizeof(GifPixelType));
-        if (!tmp)
-          {
-             *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
-             goto error;
-          }
+        rows[yy] = ((unsigned char *)rows) + (h * sizeof(GifRowType *)) +
+          (yy * w * sizeof(GifPixelType));
      }
 
+   // if give is interlaced, walk interlace pattern and decode into rows
    if (gif->Image.Interlace)
      {
-        Eina_Bool multiple;
-        int scale_j;
         for (i = 0; i < 4; i++)
           {
-             for (j = intoffset[i]; j < h; j += intjump[i])
+             for (yy = intoffset[i]; yy < h; yy += intjump[i])
                {
-                  scale_j = j / scale_ratio;
-                  multiple = ((j % scale_ratio) ? EINA_FALSE : EINA_TRUE);
-
-                  if (multiple && (scale_j < scale_h))
-                    DGifGetLine(gif, rows[scale_j], w);
-                  else
-                    DGifGetLine(gif, tmp, w);
+                  if (DGifGetLine(gif, rows[yy], w) != GIF_OK)
+                    goto on_error;
                }
           }
      }
+   // normal top to bottom - decode into rows
    else
      {
-        for (i = 0; i < scale_h; i++)
+        for (yy = 0; yy < h; yy++)
           {
-             if (DGifGetLine(gif, rows[i], w) != GIF_OK)
-               {
-                  *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
-                  goto error;
-              }
-             if (scale_ratio > 1)
-               {
-                  /* we use down sample method for scale down, so skip other line */
-                  for (j = 0; j < (scale_ratio - 1); j++)
-                    {
-                       if (DGifGetLine(gif, tmp, w) != GIF_OK)
-                         {
-                            *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
-                            goto error;
-                         }
-                    }
-               }
+             if (DGifGetLine(gif, rows[yy], w) != GIF_OK)
+               goto on_error;
           }
      }
 
-   if (scale_ratio > 1)
-     {
-        if (tmp) free(tmp);
-        tmp = NULL;
-     }
+   // work out what colormap to use
+   if (gif->Image.ColorMap) cmap = gif->Image.ColorMap;
+   else cmap = gif->SColorMap;
 
-   alpha = gif_frame->frame_info.transparent;
-   siz = cache_w *cache_h * sizeof(DATA32);
-   frame->data = malloc(siz);
-   if (!frame->data)
+   // if we need to deal with transparent pixels at all...
+   if (transparent >= 0)
      {
-        *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
-        goto error;
-     }
-   ptr = frame->data;
-   bg = gif->SBackGroundColor;
-   cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
-
-   if (!cmap)
-     {
-        DGifCloseFile(gif);
-        for (i = 0; i < scale_h; i++)
-          {
-             free(rows[i]);
-          }
-        free(rows);
-        if (frame->data) free(frame->data);
-        *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
-        return EINA_FALSE;
-     }
-
-   /* get the background value */
-   r = cmap->Colors[bg].Red;
-   g = cmap->Colors[bg].Green;
-   b = cmap->Colors[bg].Blue;
-   bg_val =  ARGB_JOIN(0xff, r, g, b);
-
-   per_inc = 100.0 / (((double)w) * h);
-   cur_h = scale_h;
-   cur_w = scale_w;
-
-   if (cur_h > cache_h) cur_h = cache_h;
-   if (cur_w > cache_w) cur_w = cache_w;
-
-   if (frame->index > 1)
-     {
-        /* get previous frame only frame index is bigger than 1 */
-        DATA32            *ptr_src;
-        Image_Entry_Frame *new_frame = NULL;
-        int                cur_frame = frame->index;
-        int                start_frame = 1;
-
-        if (_find_close_frame(ie, cur_frame, &new_frame))
-          start_frame = new_frame->index + 1;
-
-        if ((start_frame < 1) || (start_frame > cur_frame))
+        // if we are told to FILL (overwrite with transparency kept)
+        if (fill)
           {
-             *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
-             goto error;
-          }
-        /* load previous frame of cur_frame */
-        for (j = start_frame; j < cur_frame ; j++)
-          {
-             if (!evas_image_load_specific_frame(ie, ie->file, j, error))
+             for (yy = 0; yy < h; yy++)
                {
-                  *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
-                  goto error;
+                  p = data + ((y + yy) * rowpix) + x;
+                  for (xx = 0; xx < w; xx++)
+                    {
+                       pix = PIX(xx, yy);
+                       if (pix != transparent) *p = PIXLK(pix);
+                       else *p = 0;
+                       p++;
+                    }
                }
           }
-        if (!_find_frame(ie, cur_frame - 1, &new_frame))
-          {
-             *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
-             goto error;
-          }
+        // paste on top with transparent pixels untouched
         else
           {
-             Gif_Frame *gif_frame2 = NULL;
-             ptr_src = new_frame->data;
-             if (new_frame->info)
-               {
-                  gif_frame2 = (Gif_Frame *)(new_frame->info);
-                  disposal = gif_frame2->frame_info.disposal;
-               }
-             switch(disposal) /* we only support disposal flag 0,1,2 */
+             for (yy = 0; yy < h; yy++)
                {
-                case 1: /* Do not dispose. need previous frame*/
-                  memcpy(ptr, ptr_src, siz);
-                  /* only decoding image descriptor's region */
-                  ptr = ptr + cache_w * scale_y;
-                  
-                  for (i = 0; i < cur_h; i++)
+                  p = data + ((y + yy) * rowpix) + x;
+                  for (xx = 0; xx < w; xx++)
                     {
-                       ptr = ptr + scale_x;
-                       for (j = 0; j < cur_w; j++)
-                         {
-                            if (rows[i][j * scale_ratio] == alpha)
-                              {
-                                 ptr++ ;
-                              }
-                            else
-                              {
-                                 r = cmap->Colors[rows[i][j * scale_ratio]].Red;
-                                 g = cmap->Colors[rows[i][j * scale_ratio]].Green;
-                                 b = cmap->Colors[rows[i][j * scale_ratio]].Blue;
-                                 *ptr++ = ARGB_JOIN(0xff, r, g, b);
-                              }
-                            per += per_inc;
-                         }
-                       ptr = ptr + (cache_w - (scale_x + cur_w));
-                    }
-                  break;
-                case 2: /* Restore to background color */
-                   memcpy(ptr, ptr_src, siz);
-                   /* composite frames */
-                   for (i = 0; i < cache_h; i++)
-                    {
-                       if ((i < scale_y) || (i >= (scale_y + cur_h)))
-                         {
-                            for (j = 0; j < cache_w; j++)
-                              {
-                                 *ptr = bg_val;
-                                 ptr++;
-                              }
-                         }
-                       else
-                         {
-                            int i1, j1;
-                            i1 = i - scale_y;
-                            
-                            for (j = 0; j < cache_w; j++)
-                              {
-                                 j1 = j - scale_x;
-                                 if ((j < scale_x) || (j >= (scale_x + cur_w)))
-                                   {
-                                      *ptr = bg_val;
-                                      ptr++;
-                                   }
-                                 else
-                                   {
-                                      r = cmap->Colors[rows[i1][j1 * scale_ratio]].Red;
-                                      g = cmap->Colors[rows[i1][j1 * scale_ratio]].Green;
-                                      b = cmap->Colors[rows[i1][j1 * scale_ratio]].Blue;
-                                      *ptr++ = ARGB_JOIN(0xff, r, g, b);
-                                   }
-                              }
-                         }
+                       pix = PIX(xx, yy);
+                       if (pix != transparent) *p = PIXLK(pix);
+                       p++;
                     }
-                   break;
-                case 0: /* No disposal specified */
-                default:
-                   memset(ptr, 0, siz);
-                   for (i = 0; i < cache_h; i++)
-                     {
-                        if ((i < scale_y) || (i >= (scale_y + cur_h)))
-                          {
-                             for (j = 0; j < cache_w; j++)
-                               {
-                                  *ptr = bg_val;
-                                  ptr++;
-                               }
-                          }
-                        else
-                          {
-                             int i1, j1;
-                             i1 = i - scale_y;
-
-                             for (j = 0; j < cache_w; j++)
-                               {
-                                  j1 = j - scale_x;
-                                  if ((j < scale_x) || (j >= (scale_x + cur_w)))
-                                    {
-                                       *ptr = bg_val;
-                                       ptr++;
-                                    }
-                                  else
-                                    {
-                                       r = cmap->Colors[rows[i1][j1 * scale_ratio]].Red;
-                                       g = cmap->Colors[rows[i1][j1 * scale_ratio]].Green;
-                                       b = cmap->Colors[rows[i1][j1 * scale_ratio]].Blue;
-                                       *ptr++ = ARGB_JOIN(0xff, r, g, b);
-                                    }
-                               }
-                          }
-                     }
-                   break;
                }
           }
      }
-   else /* first frame decoding */
+   else
      {
-        memset(ptr, 0, siz);
-
-        /* fill background color */
-        for (i = 0; i < cache_h; i++)
+        // walk pixels without worring about transparency at all
+        for (yy = 0; yy < h; yy++)
           {
-             /* the row's of logical screen not overap with frame */
-             if ((i < scale_y) || (i >= (scale_y + cur_h)))
+             p = data + ((y + yy) * rowpix) + x;
+             for (xx = 0; xx < w; xx++)
                {
-                  for (j = 0; j < cache_w; j++)
-                    {
-                       *ptr = bg_val;
-                       ptr++;
-                    }
-               }
-             else
-               {
-                  int i1, j1;
-                  i1 = i -scale_y;
-
-                  for (j = 0; j < cache_w; j++)
-                    {
-                       j1 = j - scale_x;
-                       if ((j < scale_x) || (j >= (scale_x + cur_w)))
-                         {
-                            *ptr = bg_val;
-                            ptr++;
-                         }
-                       else
-                         {
-                            if (rows[i1][j1] == alpha)
-                              {
-                                 ptr++;
-                              }
-                            else
-                              {
-                                 r = cmap->Colors[rows[i1][j1]].Red;
-                                 g = cmap->Colors[rows[i1][j1]].Green;
-                                 b = cmap->Colors[rows[i1][j1]].Blue;
-                                 *ptr++ = ARGB_JOIN(0xff, r, g, b);
-                              }
-                         }
-                    }
+                  pix = PIX(xx, yy);
+                  *p = PIXLK(pix);
+                  p++;
                }
           }
      }
+   ret = EINA_TRUE;
 
-   for (i = 0; i < scale_h; i++)
-     {
-        if (rows[i]) free(rows[i]);
-     }
-   if (rows) free(rows);
-   frame->loaded = EINA_TRUE;
-   return EINA_TRUE;
-error:
-   for (i = 0; i < scale_h; i++)
-     {
-        if (rows[i]) free(rows[i]);
-     }
-   if (rows) free(rows);
-   if (tmp) free(tmp);
-   return EINA_FALSE;
+on_error:
+   free(rows);
+   return ret;
 }
 
-static Eina_Bool
-_evas_image_load_frame(Image_Entry *ie, GifFileType *gif, Image_Entry_Frame *frame, Frame_Load_Type type, int *error)
+static void
+_flush_older_frames(Image_Entry *ie,
+                    int w, int h,
+                    Image_Entry_Frame *thisframe,
+                    Image_Entry_Frame *prevframe)
 {
-   GifRecordType       rec;
-   int                 gra_res = 0, img_res = 0;
-   Eina_Bool           res = EINA_FALSE;
-   Gif_Frame          *gif_frame = NULL;
-
-   if ((!gif) || (!frame)) return EINA_FALSE;
-   gif_frame = (Gif_Frame *) frame->info;
-
-   if (type > LOAD_FRAME_DATA_INFO) return EINA_FALSE;
-   
-   do
-     {
-        if (DGifGetRecordType(gif, &rec) == GIF_ERROR) return EINA_FALSE;
-        if (rec == IMAGE_DESC_RECORD_TYPE)
-          {
-             img_res++;
-             break;
-          }
-        else if (rec == EXTENSION_RECORD_TYPE)
+   Eina_List *l;
+   Image_Entry_Frame *frame;
+   // target is the amount of memory we want to be under for stored frames
+   int total = 0, target = 512 * 1024;
+
+   // total up the amount of memory used by stored frames for this image
+   EINA_LIST_FOREACH(ie->frames, l, frame)
+     {
+        if (frame->data) total++;
+     }
+   total *= (w * h * sizeof(DATA32));
+   // if we use less than target (512k) for frames - dont flush
+   if (total < target) return;
+   // clean oldest frames first and go until below target or until we loop
+   // around back to this frame (curent)
+   EINA_LIST_FOREACH(ie->frames, l, frame)
+     {
+        if (frame == thisframe) break;
+     }
+   if (!l) return;
+   // start on next frame after thisframe
+   l = l->next;
+   // handle wrap to start
+   if (!l) l = ie->frames;
+   // now walk until we hit thisframe again... then stop walk.
+   while (l)
+     {
+        frame = l->data;
+        if (frame == thisframe) break;
+        if (frame->data)
           {
-             int           ext_code;
-             GifByteType  *ext;
-
-             ext = NULL;
-             DGifGetExtension(gif, &ext_code, &ext);
-             while (ext)
+             if ((frame != thisframe) && (frame != prevframe))
                {
-                  if (ext_code == 0xf9) /* Graphic Control Extension */
-                    {
-                       gra_res++;
-                       /* fill frame info */
-                       if ((type == LOAD_FRAME_INFO) || (type == LOAD_FRAME_DATA_INFO))
-                         _evas_image_load_frame_graphic_info(frame,ext);
-                    }
-                  ext = NULL;
-                  DGifGetExtensionNext(gif, &ext);
+                  free(frame->data);
+                  frame->data = NULL;
+                  // subtract memory used and if below target - stop flush
+                  total -= (w * h * sizeof(DATA32));
+                  if (total < target) break;
                }
           }
-     } while ((rec != TERMINATE_RECORD_TYPE) && (img_res == 0));
-   if (img_res != 1) return EINA_FALSE;
-   if (DGifGetImageDesc(gif) == GIF_ERROR) return EINA_FALSE;
-   if ((type == LOAD_FRAME_INFO) || (type == LOAD_FRAME_DATA_INFO))
-     _evas_image_load_frame_image_des_info(gif, frame);
-
-   if ((type == LOAD_FRAME_DATA) || (type == LOAD_FRAME_DATA_INFO))
-     {
-        res = _evas_image_load_frame_image_data(ie, gif,frame, error);
-        if (!res) return EINA_FALSE;
-     }
-   return EINA_TRUE;
-}
-
-
-/* set frame data to cache entry's data */
-static Eina_Bool
-evas_image_load_file_data_gif_internal(Image_Entry *ie, Image_Entry_Frame *frame, int *error)
-{
-   int        w;
-   int        h;
-   int        dst_x;
-   int        dst_y;
-   DATA32    *dst;
-   DATA32    *src;
-   int        cache_w, cache_h;
-   size_t     siz;
-   Gif_Frame *gif_frame = NULL;
-
-   gif_frame = (Gif_Frame *) frame->info;
-   cache_w = ie->w;
-   cache_h = ie->h;
-   w = gif_frame->image_des.w;
-   h = gif_frame->image_des.h;
-   dst_x = gif_frame->image_des.x;
-   dst_y = gif_frame->image_des.y;
-
-   src = frame->data;
-
-   if (!evas_cache_image_pixels(ie))
-     {
-        evas_cache_image_surface_alloc(ie, cache_w, cache_h);
+        // go to next - handle wrap to start
+        l = l->next;
+        if (!l) l = ie->frames;
      }
-
-   if (!evas_cache_image_pixels(ie))
-     {
-        *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
-        return EINA_FALSE;
-     }
-
-   /* only copy real frame part */
-   siz = cache_w * cache_h *  sizeof(DATA32);
-   dst = evas_cache_image_pixels(ie);
-
-   memcpy(dst, src, siz);
-
-   evas_common_image_premul(ie);
-
-   *error = EVAS_LOAD_ERROR_NONE;
-   return EINA_TRUE;
 }
 
-static Eina_Bool
-evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
+static int
+_gif_file_open(const char *file, GifFileType **gif)
 {
-   int                 fd;
-   GifFileType        *gif;
-   GifRecordType       rec;
-   int                 w;
-   int                 h;
-   int                 alpha;
-   int                 loop_count = -1;
-
-   w = 0;
-   h = 0;
-   alpha = -1;
-
+   int fd;
 #ifndef __EMX__
    fd = open(file, O_RDONLY);
 #else
    fd = open(file, O_RDONLY | O_BINARY);
 #endif
-   if (fd < 0)
-     {
-        *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
-        return EINA_FALSE;
-     }
+   if (fd < 0) return EVAS_LOAD_ERROR_DOES_NOT_EXIST;
 
-   gif = DGifOpenFileHandle(fd);
-   if (!gif)
+   *gif = DGifOpenFileHandle(fd);
+   if (!(*gif))
      {
-        if (fd) close(fd);
-        *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
-        return EINA_FALSE;
+        return EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
      }
 
-   /* check logical screen size */
+   return EVAS_LOAD_ERROR_NONE;
+}
+
+static Eina_Bool
+evas_image_load_file_head_gif(Image_Entry *ie,
+                              const char *file,
+                              const char *key __UNUSED__,
+                              int *error)
+{
+   GifFileType *gif = NULL;
+   GifRecordType rec;
+   int w, h;
+   int loop_count = -1;
+   //it is possible which gif file have error midle of frames,
+   //in that case we should play gif file until meet error frame.
+   int image_count = 0;
+   Frame_Info *finfo = NULL;
+   Eina_Bool full = EINA_TRUE;
+   Eina_Bool ret = EINA_FALSE;
+
+   // 1. ask libgif to open the file
+   int err = _gif_file_open(file, &gif);
+   if (err) LOADERR(err);
+
+   // 2. get the gif screen size (the actual image size)
    w = gif->SWidth;
    h = gif->SHeight;
-   /* support scale down feture in gif*/
-   if (ie->load_opts.scale_down_by > 1)
-     {
-        w /= ie->load_opts.scale_down_by;
-        h /= ie->load_opts.scale_down_by;
-     }
 
+   // 3. if size is invalid - abort here
    if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
        IMG_TOO_BIG(w, h))
      {
-        DGifCloseFile(gif);
         if (IMG_TOO_BIG(w, h))
-          *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
-        else
-          *error = EVAS_LOAD_ERROR_GENERIC;
-        return EINA_FALSE;
+          LOADERR(EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED);
+        LOADERR(EVAS_LOAD_ERROR_GENERIC);
      }
+
    ie->w = w;
    ie->h = h;
 
+   // 4. get info
    do
      {
         if (DGifGetRecordType(gif, &rec) == GIF_ERROR)
           {
-             /* PrintGifError(); */
-             DGifCloseFile(gif);
-             *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
-             return EINA_FALSE;
+             if (image_count > 1) break;
+             LOADERR(EVAS_LOAD_ERROR_UNKNOWN_FORMAT);
           }
-
-        /* image descript info */
+        // get image description section
         if (rec == IMAGE_DESC_RECORD_TYPE)
           {
              int img_code;
              GifByteType *img;
 
              if (DGifGetImageDesc(gif) == GIF_ERROR)
-               {
-                  /* PrintGifError(); */
-                  DGifCloseFile(gif);
-                  *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
-                  return EINA_FALSE;
-               }
-             /* we have to count frame, so use DGifGetCode and skip decoding */
+               LOADERR(EVAS_LOAD_ERROR_UNKNOWN_FORMAT);
              if (DGifGetCode(gif, &img_code, &img) == GIF_ERROR)
-               {
-                  /* PrintGifError(); */
-                  DGifCloseFile(gif);
-                  *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
-                  return EINA_FALSE;
-               }
+               LOADERR(EVAS_LOAD_ERROR_UNKNOWN_FORMAT);
              while (img)
                {
                   img = NULL;
                   DGifGetCodeNext(gif, &img);
                }
+             if (finfo)
+               {
+                  _store_frame_info(gif, finfo);
+                  _check_transparency(&full, finfo, w, h);
+               }
+             else
+               {
+                  finfo = _new_frame(ie, -1, 0, 0, image_count + 1);
+                  if (!finfo)
+                    LOADERR(EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED);
+                  _store_frame_info(gif, finfo);
+                  _check_transparency(&full, finfo, w, h);
+               }
+             image_count++;
           }
         else if (rec == EXTENSION_RECORD_TYPE)
           {
-             int                 ext_code;
-             GifByteType        *ext;
+             int ext_code;
+             GifByteType *ext;
 
              ext = NULL;
              DGifGetExtension(gif, &ext_code, &ext);
@@ -779,7 +441,14 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
                {
                   if (ext_code == 0xf9) /* Graphic Control Extension */
                     {
-                       if ((ext[1] & 1) && (alpha < 0)) alpha = (int)ext[4];
+                       finfo = _new_frame
+                         (ie,
+                          (ext[1] & 1) ? ext[4] : -1, // transparency index
+                          (ext[1] >> 2) & 0x7, // dispose mode
+                          ((int)ext[3] << 8) | (int)ext[2], // delay
+                          image_count + 1);
+                       if (!finfo)
+                         LOADERR(EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED);
                     }
                   else if (ext_code == 0xff) /* application extension */
                     {
@@ -803,209 +472,245 @@ evas_image_load_file_head_gif(Image_Entry *ie, const char *file, const char *key
           }
    } while (rec != TERMINATE_RECORD_TYPE);
 
-   if (alpha >= 0) ie->flags.alpha = 1;
-
-   if (gif->ImageCount > 1)
+   if ((gif->ImageCount > 1) || (image_count > 1))
      {
         ie->flags.animated = 1;
         ie->loop_count = loop_count;
         ie->loop_hint = EVAS_IMAGE_ANIMATED_HINT_LOOP;
-        ie->frame_count = gif->ImageCount;
-        ie->frames = NULL;
+        ie->frame_count = MIN(gif->ImageCount, image_count);
      }
+   if (!full) ie->flags.alpha = 1;
+   ie->cur_frame = 1;
 
-   DGifCloseFile(gif);
    *error = EVAS_LOAD_ERROR_NONE;
-   return EINA_TRUE;
-}
-
-static Eina_Bool
-evas_image_load_specific_frame(Image_Entry *ie, const char *file, int frame_index, int *error)
-{
-   int                fd;
-   GifFileType       *gif;
-   Image_Entry_Frame *frame = NULL;
-   Gif_Frame         *gif_frame = NULL;
+   ret = EINA_TRUE;
 
-#ifndef __EMX__
-   fd = open(file, O_RDONLY);
-#else
-   fd = open(file, O_RDONLY | O_BINARY);
-#endif
-   if (fd < 0)
-     {
-        *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
-        return EINA_FALSE;
-     }
-
-   gif = DGifOpenFileHandle(fd);
-   if (!gif)
-     {
-        if (fd) close(fd);
-        *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
-        return EINA_FALSE;
-     }
-   if (!_evas_image_skip_frame(gif, frame_index-1))
-     {
-        if (fd) close(fd);
-        *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
-        return EINA_FALSE;
-     }
-
-   frame = malloc(sizeof (Image_Entry_Frame));
-   if (!frame)
-     {
-        if (fd) close(fd);
-        *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
-        return EINA_FALSE;
-     }
-
-   gif_frame = malloc(sizeof (Gif_Frame));
-   if (!gif_frame)
-     {
-        if (fd) close(fd);
-        *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
-        return EINA_FALSE;
-     }
-   frame->info = gif_frame;
-   frame->index = frame_index;
-   if (!_evas_image_load_frame(ie,gif, frame, LOAD_FRAME_DATA_INFO,error))
-     {
-        if (fd) close(fd);
-        *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
-        return EINA_FALSE;
-     }
-
-   ie->frames = eina_list_append(ie->frames, frame);
-   DGifCloseFile(gif);
-   return EINA_TRUE;
+on_error:
+   if (gif) DGifCloseFile(gif);
+   return ret;
 }
 
 static Eina_Bool
-evas_image_load_file_data_gif(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
+evas_image_load_file_data_gif(Image_Entry *ie,
+                              const char *file,
+                              const char *key __UNUSED__,
+                              int *error)
 {
-   int                cur_frame_index;
+   Eina_Bool ret = EINA_FALSE;
+   GifRecordType rec;
+   GifFileType *gif = NULL;
    Image_Entry_Frame *frame = NULL;
-   Eina_Bool          hit;
+   int index = 0, imgnum = 0;
+   Frame_Info *finfo;
 
-   if(!ie->flags.animated)
-     cur_frame_index = 1;
-   else
-     cur_frame_index = ie->cur_frame;
+   // 1. index set
+   index = ie->cur_frame;
 
    if ((ie->flags.animated) &&
-       ((cur_frame_index <0) || (cur_frame_index > FRAME_MAX) || (cur_frame_index > ie->frame_count)))
+       ((index <= 0) || (index > FRAME_MAX) || (index > ie->frame_count)))
+     LOADERR(EVAS_LOAD_ERROR_GENERIC);
+
+   frame = _find_frame(ie, index);
+   if (frame)
      {
-        *error = EVAS_LOAD_ERROR_GENERIC;
-        return EINA_FALSE;
+        if ((frame->loaded) && (frame->data))
+          // frame is already there and decoded - jump to end
+          goto on_ok;
      }
+   else
+     LOADERR(EVAS_LOAD_ERROR_CORRUPT_FILE);
 
-   /* first time frame is set to be 0. so default is 1 */
-   if (cur_frame_index == 0) cur_frame_index++;
-
-   /* Check current frame exists in hash table */
-   hit = _find_frame(ie, cur_frame_index, &frame);
+   // 2. ask libgif to open the file
+   int err = _gif_file_open(file, &gif);
+   if (err) LOADERR(err);
 
-   /* if current frame exist in has table, check load flag */
-   if (hit)
+   // always start from the first frame - don't know the previous frame
+   imgnum = 1;
+   do
      {
-        if (frame->loaded)
-          evas_image_load_file_data_gif_internal(ie,frame,error);
-        else
+        if (DGifGetRecordType(gif, &rec) == GIF_ERROR)
+          LOADERR(EVAS_LOAD_ERROR_UNKNOWN_FORMAT);
+        if (rec == EXTENSION_RECORD_TYPE)
           {
-             int           fd;
-             GifFileType  *gif;
+             int ext_code;
+             GifByteType *ext;
 
-#ifndef __EMX__
-             fd = open(file, O_RDONLY);
-#else
-             fd = open(file, O_RDONLY | O_BINARY);
-#endif
-             if (fd < 0)
+             ext = NULL;
+             DGifGetExtension(gif, &ext_code, &ext);
+             while (ext)
                {
-                  *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
-                  return EINA_FALSE;
+                  ext = NULL;
+                  DGifGetExtensionNext(gif, &ext);
                }
+          }
+        else if (rec == IMAGE_DESC_RECORD_TYPE)
+          {
+             int xin = 0, yin = 0, x = 0, y = 0, w = 0, h = 0;
+             int img_code;
+             GifByteType *img;
+             Image_Entry_Frame *prevframe = NULL;
+             Image_Entry_Frame *thisframe = NULL;
 
-             gif = DGifOpenFileHandle(fd);
-             if (!gif)
+             // get image desc
+             if (DGifGetImageDesc(gif) == GIF_ERROR)
+               LOADERR(EVAS_LOAD_ERROR_UNKNOWN_FORMAT);
+             // get the previous frame entry AND the current one to fill in
+             prevframe = _find_frame(ie, imgnum - 1);
+             thisframe = _find_frame(ie, imgnum);
+
+             // CASE 1: no data & animated
+             if ((thisframe) && (!thisframe->data) && (ie->flags.animated))
                {
-                  if (fd) close(fd);
-                  *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
-                  return EINA_FALSE;
+                  Eina_Bool first = EINA_FALSE;
+
+                  // allocate it
+                  thisframe->data =
+                    malloc(ie->w * ie->h * sizeof(DATA32));
+                  if (!thisframe->data)
+                    LOADERR(EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED);
+                  // if we have no prior frame OR prior frame data... empty
+                  if ((!prevframe) || (!prevframe->data))
+                    {
+                       first = EINA_TRUE;
+                       finfo = thisframe->info;
+                       memset(thisframe->data, 0,
+                              ie->w * ie->h * sizeof(DATA32));
+                    }
+                  // we have a prior frame to copy data from...
+                  else
+                    {
+                       finfo = prevframe->info;
+
+                       // fix coords of sub image in case it goes out...
+                       _clip_coords(ie->w, ie->h, &xin, &yin,
+                                    finfo->x, finfo->y, finfo->w, finfo->h,
+                                    &x, &y, &w, &h);
+                       // if dispose mode is not restore - then copy pre frame
+                       if (finfo->dispose != 3) // GIF_DISPOSE_RESTORE
+                         memcpy(thisframe->data, prevframe->data,
+                              ie->w * ie->h * sizeof(DATA32));
+                       // if dispose mode is "background" then fill with bg
+                       if (finfo->dispose == 2) // GIF_DISPOSE_BACKGND
+                         _fill_frame(thisframe->data, ie->w, gif,
+                                     finfo, x, y, w, h);
+                       else if (finfo->dispose == 3) // GIF_DISPOSE_RESTORE
+                         {
+                            Image_Entry_Frame *prevframe2;
+
+                            // we need to copy data from one frame back
+                            // from the prev frame into the current frame
+                            // (copy the whole image - at least the sample
+                            // GifWin.cpp from libgif indicates this is what
+                            // needs doing
+                            prevframe2 = _find_frame(ie, imgnum - 2);
+                            if (prevframe2)
+                              memcpy(thisframe->data, prevframe2->data,
+                                     ie->w * ie->h * sizeof(DATA32));
+                         }
+                    }
+                  // now draw this frame on top
+                  finfo = thisframe->info;
+                  _clip_coords(ie->w, ie->h, &xin, &yin,
+                               finfo->x, finfo->y, finfo->w, finfo->h,
+                               &x, &y, &w, &h);
+                  if (!_decode_image(gif, thisframe->data, ie->w,
+                                     xin, yin, finfo->transparent,
+                                     x, y, w, h, first))
+                    LOADERR(EVAS_LOAD_ERROR_CORRUPT_FILE);
+                  // mark as loaded and done
+                  thisframe->loaded = EINA_TRUE;
+                  // and flush old memory if needed (too much)
+                  _flush_older_frames(ie, ie->w, ie->h,
+                                      thisframe, prevframe);
                }
-             _evas_image_skip_frame(gif, cur_frame_index-1);
-             if (!_evas_image_load_frame(ie, gif, frame, LOAD_FRAME_DATA,error))
+             // CASE 2
+             else if ((thisframe) && (!thisframe->data) &&
+                      (!ie->flags.animated))
                {
-                  if (fd) close(fd);
-                  *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
-                  return EINA_FALSE;
+                  // if we don't have the data decoded yet - decode it
+                  if ((!thisframe->loaded) || (!thisframe->data))
+                    {
+                       DATA32 *pixels;
+                       if (!evas_cache_image_pixels(ie))
+                         evas_cache_image_surface_alloc(ie, ie->w, ie->h);
+                       pixels = evas_cache_image_pixels(ie);
+
+                       if (!pixels)
+                         LOADERR(EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED);
+
+                       // use frame info but we WONT allocate frame pixels
+                       finfo = thisframe->info;
+                       _clip_coords(ie->w, ie->h, &xin, &yin,
+                                    finfo->x, finfo->y, finfo->w, finfo->h,
+                                    &x, &y, &w, &h);
+                       // clear out all pixels
+                       _fill_frame(pixels, ie->w, gif,
+                                   finfo, 0, 0, ie->w, ie->h);
+                       // and decode the gif with overwriting
+                       if (!_decode_image(gif, pixels, ie->w,
+                                          xin, yin, finfo->transparent,
+                                          x, y, w, h, EINA_TRUE))
+                         LOADERR(EVAS_LOAD_ERROR_CORRUPT_FILE);
+                       // mark as loaded and done
+                       thisframe->loaded = EINA_TRUE;
+                    }
                }
-             if (!evas_image_load_file_data_gif_internal(ie, frame, error))
+             // CASE 3
+             else
                {
-                  if (fd) close(fd);
-                  *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
-                  return EINA_FALSE;
+                  // skip decoding and just walk image to next
+                  if (DGifGetCode(gif, &img_code, &img) == GIF_ERROR)
+                    LOADERR(EVAS_LOAD_ERROR_UNKNOWN_FORMAT);
+                  while (img)
+                    {
+                       img = NULL;
+                       DGifGetCodeNext(gif, &img);
+                    }
                }
-             DGifCloseFile(gif);
-             *error = EVAS_LOAD_ERROR_NONE;
-             return EINA_TRUE;
+             if (imgnum >= index) break;
+             imgnum++;
           }
      }
-   /* current frame does is not exist */
-   else
+   while (rec != TERMINATE_RECORD_TYPE);
+
+on_ok:
+   if ((ie->flags.animated) && (frame->data))
      {
-        if (!evas_image_load_specific_frame(ie, file, cur_frame_index, error))
-          {
-             return EINA_FALSE;
-          }
-        hit = EINA_FALSE;
-        frame = NULL;
-        hit = _find_frame(ie, cur_frame_index, &frame);
-        if (!hit) return EINA_FALSE;
-        if (!evas_image_load_file_data_gif_internal(ie, frame, error))
-          {
-             *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
-             return EINA_FALSE;
-          }
-        return EINA_TRUE;
+        DATA32 *pixels;
+        if (!evas_cache_image_pixels(ie))
+          evas_cache_image_surface_alloc(ie, ie->w, ie->h);
+        pixels = evas_cache_image_pixels(ie);
+
+        if (!pixels)
+          LOADERR(EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED);
+        memcpy(pixels, frame->data, ie->w * ie->h * sizeof(DATA32));
      }
-   return EINA_FALSE;
+
+   *error = EVAS_LOAD_ERROR_NONE;
+   ret = EINA_TRUE;
+
+on_error:
+   if (gif) DGifCloseFile(gif);
+   return ret;
 }
 
 static double
-evas_image_load_frame_duration_gif(Image_Entry *ie, const char *file, const int start_frame, const int frame_num)
+evas_image_load_frame_duration_gif(Image_Entry *ie,
+                                   const char *file,
+                                   const int start_frame,
+                                   const int frame_num)
 {
-   int                 fd;
    GifFileType        *gif;
    GifRecordType       rec;
-   int                 done;
    int                 current_frame = 1;
    int                 remain_frames = frame_num;
    double              duration = 0;
-   int                 frame_count = 0;
-
-   frame_count = ie->frame_count;
 
    if (!ie->flags.animated) return -1;
-   if ((start_frame + frame_num) > frame_count) return -1;
+   if ((start_frame + frame_num) > ie->frame_count) return -1;
    if (frame_num < 0) return -1;
 
-   done = 0;
-
-#ifndef __EMX__
-   fd = open(file, O_RDONLY);
-#else
-   fd = open(file, O_RDONLY | O_BINARY);
-#endif
-   if (fd < 0) return -1;
-
-   gif = DGifOpenFileHandle(fd);
-   if (!gif)
-     {
-        if (fd) close(fd);
-        return -1;
-     }
+   if (_gif_file_open(file, &gif)) return -1;
 
    do
      {
@@ -1046,7 +751,7 @@ evas_image_load_frame_duration_gif(Image_Entry *ie, const char *file, const int
                {
                   if (ext_code == 0xf9) /* Graphic Control Extension */
                     {
-                       if ((current_frame  >= start_frame) && (current_frame <= frame_count))
+                       if ((current_frame  >= start_frame) && (current_frame <= ie->frame_count))
                          {
                             int frame_duration = 0;
                             if (remain_frames < 0) break;
@@ -1068,6 +773,15 @@ evas_image_load_frame_duration_gif(Image_Entry *ie, const char *file, const int
    return duration;
 }
 
+static Evas_Image_Load_Func evas_image_load_gif_func =
+{
+  EINA_TRUE,
+  evas_image_load_file_head_gif,
+  evas_image_load_file_data_gif,
+  evas_image_load_frame_duration_gif,
+  EINA_FALSE
+};
+
 static int
 module_open(Evas_Module *em)
 {
index a2d722d..6598303 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @EVIL_CFLAGS@
 
 if BUILD_LOADER_ICO
@@ -19,7 +19,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_ico.c
 
-module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index a5eb2ae..03e831c 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_image_loader_jpeg_cflags@ \
 @EVIL_CFLAGS@
@@ -20,7 +20,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_jpeg.c
 
-module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ @evas_image_loader_jpeg_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@ @evas_image_loader_jpeg_libs@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index b7ed636..d4523e2 100644 (file)
@@ -25,10 +25,10 @@ struct _JPEG_error_mgr
 static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
 static void _JPEGErrorHandler(j_common_ptr cinfo);
 static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
-static int _get_orientation_app0(char *app0_head, size_t remain_length);
-static int _get_orientation_app1(char *app1_head, size_t remain_length);
-static int _get_orientation(void *map, size_t length);
-
+static Eina_Bool _get_next_app0(unsigned char *map, size_t fsize, size_t *position);
+static Eina_Bool _get_orientation_app1(unsigned char *map, size_t fsize, size_t *position,
+                                       int *orientation, Eina_Bool *flipped);
+static int _get_orientation(void *map, size_t length, Eina_Bool *flipped);
 static Eina_Bool evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
                                                          void *map,
                                                          size_t len,
@@ -175,19 +175,23 @@ typedef enum {
      EXIF_BYTE_ALIGN_MM
 } ExifByteAlign;
 
-static int
-_get_orientation_app0(char *app0_head, size_t remain_length)
+static Eina_Bool
+_get_next_app0(unsigned char *map, size_t fsize, size_t *position)
 {
-   unsigned int length = 0;
+   unsigned short length = 0;
    unsigned int w = 0, h = 0;
    unsigned int format = 0;
    unsigned int data_size = 0;
-   char *p;
+   unsigned char *app0_head, *p;
+
+
+   /* header_mark:2, length:2, identifier:5 version:2, unit:1, den=4 thum=2 */
+   if (*position + 16 >= fsize) return EINA_FALSE;
+   app0_head  = map + *position;
 
    /* p is appn's start pointer excluding app0 marker */
    p = app0_head + 2;
 
-
    length = ((*p << 8) + *(p + 1));
 
    /* JFIF segment format */
@@ -208,29 +212,47 @@ _get_orientation_app0(char *app0_head, size_t remain_length)
      }
 
      data_size = format * w * h;
-     p += length + data_size;
 
-     if (!memcmp(p, App1, sizeof (App1)))
-       return _get_orientation_app1(p, remain_length - (2 + length + data_size));
-     else
-       return 0;
+     if ((*position + 2+ length + data_size) > fsize)
+       return EINA_FALSE;
+
+     *position = *position + 2 + length + data_size;
+
+     return EINA_TRUE;
 }
 
-static int
-_get_orientation_app1(char *app1_head, size_t remain_length)
+/* If app1 data is abnormal, returns EINA_FALSE.
+   If app1 data is normal, returns EINA_TRUE.
+   If app1 data is normal but not orientation data, orientation value is -1.
+ */
+
+static Eina_Bool
+_get_orientation_app1(unsigned char *map, size_t fsize, size_t *position,
+                      int *orientation_res, Eina_Bool *flipped)
 {
-   char *buf;
-   char orientation[2];
+   unsigned char *app1_head, *buf;
+   unsigned char orientation[2];
    ExifByteAlign byte_align;
    unsigned int num_directory = 0;
    unsigned int i, j;
    int direction;
+   unsigned int data_size = 0;
 
-   /* start of app1 frame */
+   /* app1 mark:2, data_size:2, exif:6 tiff:8 */
+   if ((*position + 18) >= fsize) return EINA_FALSE;
+   app1_head  = map + *position;
    buf = app1_head;
 
-   /* 1. check 4~9bype with Exif Header (0x45786966 0000) */
-   if (memcmp(buf + 4, ExifHeader, sizeof (ExifHeader))) return 0;
+
+   data_size = ((*(buf + 2) << 8) + *(buf + 3));
+   if ((*position + 2 + data_size) > fsize) return EINA_FALSE;
+
+   if (memcmp(buf + 4, ExifHeader, sizeof (ExifHeader)))
+   {
+       *position = *position + 2 + data_size;
+       *orientation_res = -1;
+       return EINA_TRUE;
+   }
 
    /* 2. get 10&11 byte  get info of "II(0x4949)" or "MM(0x4d4d)" */
    /* 3. get [18]&[19] get directory entry # */
@@ -248,11 +270,12 @@ _get_orientation_app1(char *app1_head, size_t remain_length)
         orientation[0] = 0x12;
         orientation[1] = 0x01;
      }
-   else return 0;
+   else return EINA_FALSE;
 
-   buf = app1_head + 20;
+   /* check num_directory data */
+   if ((*position + (12 * num_directory + 20)) > fsize) return EINA_FALSE;
 
-   if (remain_length < (12 * num_directory + 20)) return 0;
+   buf = app1_head + 20;
 
    j = 0;
 
@@ -262,48 +285,144 @@ _get_orientation_app1(char *app1_head, size_t remain_length)
           {
              /*get orientation tag */
              if (byte_align == EXIF_BYTE_ALIGN_MM)
-              direction = *(buf+ j + 9);
+               direction = *(buf+ j + 9);
              else direction = *(buf+ j + 8);
              switch (direction)
                {
                 case 3:
+                  *orientation_res = 180;
+                  *flipped = EINA_FALSE;
+                  return EINA_TRUE;
                 case 4:
-                   return 180;
+                  *orientation_res = 180;
+                  *flipped = EINA_TRUE;
+                  return EINA_TRUE;
                 case 6:
+                  *orientation_res = 90;
+                  *flipped = EINA_FALSE;
+                  return EINA_TRUE;
                 case 7:
-                   return 90;
+                  *orientation_res = 90;
+                  *flipped = EINA_TRUE;
+                  return EINA_TRUE;
                 case 5:
+                  *orientation_res = 270;
+                  *flipped = EINA_TRUE;
+                  return EINA_TRUE;
                 case 8:
-                   return 270;
+                  *orientation_res = 270;
+                  *flipped = EINA_FALSE;
+                  return EINA_TRUE;
+                case 2:
+                  *orientation_res = 0;
+                  *flipped = EINA_TRUE;
+                  return EINA_TRUE;
                 default:
-                   return 0;
+                  *orientation_res = 0;
+                  *flipped = EINA_FALSE;
+                  return EINA_TRUE;
                }
           }
         else
           j = j + 12;
      }
-   return 0;
+   return EINA_FALSE;
 }
 
 static int
-_get_orientation(void *map, size_t length)
+_get_orientation(void *map, size_t length, Eina_Bool *flipped)
 {
-   char *buf;
+   unsigned char *buf;
+   size_t position = 0;
+   int orientation = -1;
+   Eina_Bool res = EINA_FALSE;
+   *flipped = EINA_FALSE;
 
    /* open file and get 22 byte frome file */
    if (!map) return 0;
    /* 1. read 22byte */
    if (length < 22) return 0;
-   buf = (char *)map;
+   buf = (unsigned char *)map;
 
+   position = 2;
    /* 2. check 2,3 bypte with APP0(0xFFE0) or APP1(0xFFE1) */
-   if (!memcmp(buf + 2, App0, sizeof (App0)))
-      return _get_orientation_app0(buf + 2, length - 2);
-   if (!memcmp(buf + 2, App1, sizeof (App1)))
-      return _get_orientation_app1(buf + 2, length - 2);
+   while((length - position) > 0)
+     {
+        if (!memcmp(buf + position, App0, sizeof (App0)))
+          {
+             res = _get_next_app0(map, length, &position);
+             if (!res) break;
+          }
+        else if (!memcmp(buf + position, App1, sizeof (App1)))
+          {
+             res = _get_orientation_app1(map, length, &position, &orientation, flipped);
+             if (!res) break;
+             if (orientation != -1) return orientation;
+          }
+        else break;
+     }
    return 0;
 }
 
+static void
+_rotate_region(unsigned int *r_x, unsigned int *r_y, unsigned int *r_w, unsigned int *r_h,
+               unsigned int x, unsigned int y, unsigned int w, unsigned int h,
+               unsigned int output_w, unsigned int output_h,
+               int degree, Eina_Bool flipped)
+{
+   switch (degree)
+     {
+      case 90:
+        if (flipped)
+          {
+             *r_x = output_w - (y + h);
+             *r_y = output_h - (x + w);
+             *r_w = h;
+             *r_h = w;
+          }
+        else
+          {
+             *r_x = y;
+             *r_y = output_h - (x + w);
+             *r_w = h;
+             *r_h = w;
+          }
+        break;
+      case 180:
+        if (flipped)
+          {
+             *r_y = output_h - (y + h);
+          }
+        else
+          {
+             *r_x = output_w - (x + w);
+             *r_y = output_h - (y + h);
+          }
+        break;
+      case 270:
+        if (flipped)
+          {
+             *r_x = y;
+             *r_y = x;
+             *r_w = h;
+             *r_h = w;
+          }
+        else
+          {
+             *r_x = output_w - (y + h);
+             *r_y = x;
+             *r_w = h;
+             *r_h = w;
+          }
+        break;
+      default:
+        if (flipped)
+           *r_x = output_w - (x + w);
+        break;
+     }
+}
+
+
 static Eina_Bool
 evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
                                         void *map, size_t length,
@@ -315,7 +434,7 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
 
    /* for rotation decoding */
    int degree = 0;
-   Eina_Bool change_wh = EINA_FALSE;
+   Eina_Bool change_wh = EINA_FALSE, flipped = EINA_FALSE;
    unsigned int load_opts_w = 0, load_opts_h = 0;
 
    memset(&cinfo, 0, sizeof(cinfo));
@@ -348,16 +467,17 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
    cinfo.do_block_smoothing = FALSE;
    cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
    cinfo.dither_mode = JDITHER_ORDERED;
+   cinfo.buffered_image = TRUE; // buffered mode in case jpg is progressive
    jpeg_start_decompress(&cinfo);
-
    /* rotation decoding */
    if (ie->load_opts.orientation)
      {
-        degree = _get_orientation(map, length);
-        if (degree != 0)
+        degree = _get_orientation(map, length, &flipped);
+        if (degree != 0 || flipped)
           {
              ie->load_opts.degree = degree;
              ie->flags.rotated = EINA_TRUE;
+             ie->flags.flipped = flipped;
 
              if (degree == 90 || degree == 270)
                change_wh = EINA_TRUE;
@@ -402,24 +522,29 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
              ie->load_opts.h = load_opts_w;
           }
 
-       if (ie->load_opts.w > 0)
-         {
-            w2 = ie->load_opts.w;
-            h2 = (ie->load_opts.w * h) / w;
-            if ((ie->load_opts.h > 0) && (h2 > ie->load_opts.h))
-              {
-                 unsigned int w3;
-                 h2 = ie->load_opts.h;
-                 w3 = (ie->load_opts.h * w) / h;
-                 if (w3 > w2)
-                   w2 = w3;
-              }
-         }
-       else if (ie->load_opts.h > 0)
-         {
-            h2 = ie->load_opts.h;
-            w2 = (ie->load_opts.h * w) / h;
-         }
+        // TIZEN ONLY
+        if (ie->load_opts.w < cinfo.output_width)
+          {
+             unsigned int ratio_scale;
+             for (ratio_scale = 1; ratio_scale < 4; ratio_scale++)
+               {
+                  scalew = cinfo.output_width >> ratio_scale;
+                  scaleh = scalew * h / w;
+                  if ((scalew <= ie->load_opts.w) && (scaleh <= ie->load_opts.h)) break;
+               }
+             ie->load_opts.w = scalew;
+             ie->load_opts.h = scaleh;
+          }
+        w2 = ie->load_opts.w;
+        h2 = (ie->load_opts.w * h) / w;
+        if (h2 > ie->load_opts.h)
+          {
+             unsigned int w3;
+             h2 = ie->load_opts.h;
+             w3 = (ie->load_opts.h * w) / h;
+             if (w3 > w2)
+             w2 = w3;
+          }
        w = w2;
        h = h2;
         if (change_wh)
@@ -467,6 +592,7 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
        cinfo.do_block_smoothing = FALSE;
        cinfo.scale_num = 1;
        cinfo.scale_denom = ie->scale;
+       cinfo.buffered_image = TRUE; // buffered mode in case jpg is progressive
        jpeg_calc_output_dimensions(&(cinfo));
        jpeg_start_decompress(&cinfo);
      }
@@ -485,30 +611,10 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
              load_region_y = ie->load_opts.region.y;
              load_region_w = ie->load_opts.region.w;
              load_region_h = ie->load_opts.region.h;
-
-             switch (degree)
-               {
-                case 90:
-                   ie->load_opts.region.x = load_region_y;
-                   ie->load_opts.region.y = h - (load_region_x + load_region_w);
-                   ie->load_opts.region.w = load_region_h;
-                   ie->load_opts.region.h = load_region_w;
-                   break;
-                case 180:
-                   ie->load_opts.region.x = w - (load_region_x+ load_region_w);
-                   ie->load_opts.region.y = h - (load_region_y + load_region_h);
-
-                   break;
-                case 270:
-                   ie->load_opts.region.x = w - (load_region_y + load_region_h);
-                   ie->load_opts.region.y = load_region_x;
-                   ie->load_opts.region.w = load_region_h;
-                   ie->load_opts.region.h = load_region_w;
-                   break;
-                default:
-                   break;
-               }
-
+             _rotate_region(&ie->load_opts.region.x, &ie->load_opts.region.y,
+                            &ie->load_opts.region.w, &ie->load_opts.region.h,
+                            load_region_x, load_region_y, load_region_w, load_region_h,
+                            w, h, degree, ie->flags.flipped);
           }
         RECTS_CLIP_TO_RECT(ie->load_opts.region.x, ie->load_opts.region.y,
                            ie->load_opts.region.w, ie->load_opts.region.h,
@@ -556,6 +662,88 @@ get_time(void)
 }
 */
 
+static void
+_rotate_180(DATA32 *data, int w, int h)
+{
+   DATA32 *p1, *p2;
+   DATA32 pt;
+   int x;
+
+   p1 = data;
+   p2 = data + (h * w) - 1;
+   for (x = (w * h) / 2; --x >= 0;)
+     {
+        pt = *p1;
+        *p1 = *p2;
+        *p2 = pt;
+        p1++;
+        p2--;
+     }
+}
+
+static void
+_flip_horizontal(DATA32 *data, int w, int h)
+{
+   DATA32 *p1, *p2;
+   DATA32 pt;
+   int x, y;
+
+   for (y = 0; y < h; y++)
+     {
+        p1 = data + (y * w);
+        p2 = data + ((y + 1) * w) - 1;
+        for (x = 0; x < (w >> 1); x++)
+          {
+             pt = *p1;
+             *p1 = *p2;
+             *p2 = pt;
+             p1++;
+             p2--;
+          }
+     }
+}
+
+static void
+_flip_vertical(DATA32 *data, int w, int h)
+{
+   DATA32 *p1, *p2;
+   DATA32 pt;
+   int x, y;
+
+   for (y = 0; y < (h >> 1); y++)
+     {
+        p1 = data + (y * w);
+        p2 = data + ((h - 1 - y) * w);
+        for (x = 0; x < w; x++)
+          {
+             pt = *p1;
+             *p1 = *p2;
+             *p2 = pt;
+             p1++;
+             p2++;
+          }
+     }
+}
+
+static void
+_rotate_change_wh(DATA32 *to, DATA32 *from,
+                  int w, int h,
+                  int dx, int dy)
+{
+   int x, y;
+
+   for (x = h; --x >= 0;)
+     {
+        for (y = w; --y >= 0;)
+          {
+             *to = *from;
+             from++;
+             to += dy;
+          }
+        to += dx;
+     }
+}
+
 static Eina_Bool
 evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
                                         void *map, size_t size,
@@ -1044,69 +1232,45 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
      }
    /* if rotation operation need, rotate it */
 done:
-
    if (ie->flags.rotated)
      {
-        DATA32             *data1, *data2,  *to, *from;
-        int                 lx, ly, lw, lh,  hw;
-
-        lw = ie->w;
-        lh = ie->h;
-        hw =lw * lh;
-
-        data1 = evas_cache_image_pixels(ie);
+        uint32_t *to;
+        int hw;
+        hw = ie_w * ie_h;
+        to = evas_cache_image_pixels(ie);
 
-        if (degree == 180)
+        switch (degree)
           {
-             DATA32 tmpd;
-
-             data2 = data1 + (lh * lw) -1;
-             for (lx = (lw * lh) / 2; --lx >= 0;)
-               {
-                  tmpd = *data1;
-                  *data1 = *data2;
-                  *data2 = tmpd;
-                  data1++;
-                  data2--;
-               }
+           case 90:
+              if (ie->flags.flipped)
+                _rotate_change_wh(to + hw - 1, ptr_rotate, ie_w, ie_h, hw - 1, -ie_h);
+              else
+                _rotate_change_wh(to + ie_h - 1, ptr_rotate, ie_w, ie_h, -hw - 1, ie_h);
+              break;
+
+           case 180:
+              if (ie->flags.flipped)
+                _flip_vertical(to, ie_w, ie_h);
+              else
+                _rotate_180(to, ie_w, ie_h);
+              break;
+
+           case 270:
+              if (ie->flags.flipped)
+                _rotate_change_wh(to, ptr_rotate, ie_w, ie_h, -hw + 1, ie_h);
+              else
+                _rotate_change_wh(to + hw - ie_h, ptr_rotate, ie_w, ie_h, hw + 1, -ie_h);
+              break;
+
+           default:
+              if (ie->flags.flipped)
+                _flip_horizontal(to, ie_w, ie_h);
+              break;
           }
-        else 
+        if (ptr_rotate)
           {
-             data2 = NULL;
-             to = NULL;
-             if (ptr_rotate) data2 = ptr_rotate;
-
-             if (degree == 90)
-               {
-                  to = data1 + lw - 1;
-                  hw = -hw - 1;
-               }
-             else if (degree == 270)
-               {
-                  to = data1 + hw - lw;
-                  lw = -lw;
-                  hw = hw + 1;
-               }
-
-             if (to)
-               {
-                  from = data2;
-                  for (lx = ie->w; --lx >= 0;)
-                    {
-                       for (ly =ie->h; --ly >= 0;)
-                         {
-                            *to = *from;
-                            from++;
-                            to += lw;
-                         }
-                       to += hw;
-                    }
-               }
-             if (ptr_rotate)
-               {
-                  free(ptr_rotate);
-                  ptr_rotate = NULL;
-               }
+             free(ptr_rotate);
+             ptr_rotate = NULL;
           }
         if (region)
           {
index ff7fdf8..366f890 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_image_loader_pmaps_cflags@ \
 @EVIL_CFLAGS@
@@ -20,7 +20,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_pmaps.c
 
-module_la_LIBADD = @evas_image_loader_pmaps_libs@ @EINA_LIBS@ @EVIL_LIBS@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @evas_image_loader_pmaps_libs@ @EVAS_GENERAL_LIBS@ @EVIL_LIBS@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 6958f02..08574ee 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_image_loader_png_cflags@ \
 @EVIL_CFLAGS@
@@ -20,7 +20,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_png.c
 
-module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_png_libs@ @EVIL_LIBS@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @evas_image_loader_png_libs@ @EVIL_LIBS@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 3007a57..35ff2ec 100644 (file)
@@ -39,6 +39,16 @@ static Evas_Image_Load_Func evas_image_load_png_func =
   EINA_FALSE
 };
 
+static const Evas_Colorspace cspace_grey[2] = {
+   EVAS_COLORSPACE_GRY8,
+   EVAS_COLORSPACE_ARGB8888
+};
+
+static const Evas_Colorspace cspace_grey_alpha[2] = {
+   EVAS_COLORSPACE_AGRY88,
+   EVAS_COLORSPACE_ARGB8888
+};
+
 static Eina_Bool
 evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
 {
@@ -124,8 +134,19 @@ evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key
         ie->h = (int) h32;
      }
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) hasa = 1;
-   if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) hasa = 1;
-   if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) hasa = 1;
+   switch (color_type)
+     {
+      case PNG_COLOR_TYPE_RGB_ALPHA:
+         hasa = 1;
+         break;
+      case PNG_COLOR_TYPE_GRAY_ALPHA:
+         hasa = 1;
+         ie->cspaces = cspace_grey_alpha;
+         break;
+      case PNG_COLOR_TYPE_GRAY:
+         if (!hasa) ie->cspaces = cspace_grey;
+         break;
+     }
    if (hasa) ie->flags.alpha = 1;
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    E_FCLOSE(f);
@@ -149,12 +170,11 @@ evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key
    png_infop info_ptr = NULL;
    int bit_depth, color_type, interlace_type;
    unsigned char buf[PNG_BYTES_TO_CHECK];
-   unsigned char **lines;
-   char hasa;
-   int i, j;
-   int scale_ratio = 1, image_w = 0;
+   char hasa, passes;
+   int i, j, p, k;
+   int scale_ratio = 1, image_w = 0, image_h = 0;
    unsigned char *tmp_line;
-   DATA32 *src_ptr, *dst_ptr;
+   unsigned int pack_offset;
 
    hasa = 0;
    f = E_FOPEN(file, "rb");
@@ -202,6 +222,7 @@ evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key
                (png_uint_32 *) (&h32), &bit_depth, &color_type,
                &interlace_type, NULL, NULL);
    image_w = w32;
+   image_h = h32;
    if (ie->load_opts.scale_down_by > 1)
      {
         scale_ratio = ie->load_opts.scale_down_by;
@@ -222,7 +243,12 @@ evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key
        *error = EVAS_LOAD_ERROR_GENERIC;
        goto close_file;
      }
-   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) hasa = 1;
+   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+     {
+        /* expand transparency entry -> alpha channel if present */
+        png_set_tRNS_to_alpha(png_ptr);
+        hasa = 1;
+     }
    if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) hasa = 1;
    if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) hasa = 1;
    if (hasa) ie->flags.alpha = 1;
@@ -234,54 +260,104 @@ evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key
    if ((color_type == PNG_COLOR_TYPE_GRAY) ||
        (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
      {
-       png_set_gray_to_rgb(png_ptr);
-       if (bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr);
+        if (ie->space == EVAS_COLORSPACE_ARGB8888)
+          png_set_gray_to_rgb(png_ptr);
+        if (bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr);
      }
-   /* expand transparency entry -> alpha channel if present */
-   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
-     png_set_tRNS_to_alpha(png_ptr);
    /* reduce 16bit color -> 8bit color if necessary */
    if (bit_depth > 8) png_set_strip_16(png_ptr);
    /* pack all pixels to byte boundaries */
    png_set_packing(png_ptr);
 
-   w = ie->w;
-   h = ie->h;
-   /* we want ARGB */
+   w = w32;
+   h = h32;
+
+   switch (ie->space)
+     {
+      case EVAS_COLORSPACE_ARGB8888:
+         /* we want ARGB */
+#ifdef WORDS_BIGENDIAN
+         png_set_swap_alpha(png_ptr);
+         if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
+#else
+         png_set_bgr(png_ptr);
+         if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
+#endif
+         pack_offset = sizeof(DATA32);
+         break;
+      case EVAS_COLORSPACE_AGRY88:
+         /* we want AGRY */
 #ifdef WORDS_BIGENDIAN
-   png_set_swap_alpha(png_ptr);
-   if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
+         png_set_swap_alpha(png_ptr);
+         if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
 #else
-   png_set_bgr(png_ptr);
-   if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
+         if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
 #endif
+         pack_offset = sizeof(DATA16);
+         break;
+      case EVAS_COLORSPACE_GRY8: pack_offset = sizeof(DATA8); break;
+      default: abort();
+     }
+
+   passes = png_set_interlace_handling(png_ptr);
 
    /* we read image line by line if scale down was set */
    if (scale_ratio == 1)
      {
-        lines = (unsigned char **) alloca(h * sizeof(unsigned char *));
-        for (i = 0; i < h; i++)
-          lines[i] = surface + (i * w * sizeof(DATA32));
-        png_read_image(png_ptr, lines);
+        for (p = 0; p < passes; p++)
+          {
+             for (i = 0; i < h; i++)
+               png_read_row(png_ptr, surface + (i * w * pack_offset), NULL);
+          }
         png_read_end(png_ptr, info_ptr);
      }
    else
      {
-        tmp_line = (unsigned char *) alloca(image_w * sizeof(DATA32));
-        dst_ptr = (DATA32 *)surface;
-        for (i = 0; i < h; i++)
+        unsigned char *src_ptr, *dst_ptr;
+
+        dst_ptr = surface;
+        if (passes == 1)
           {
-             png_read_row(png_ptr, tmp_line, NULL);
-             src_ptr = (DATA32 *)tmp_line;
-             for (j = 0; j < w; j++)
+             tmp_line = (unsigned char *) alloca(image_w * pack_offset);
+             for (i = 0; i < h; i++)
                {
-                  *dst_ptr = *src_ptr;
-                  dst_ptr++;
-                  src_ptr += scale_ratio;
+                  png_read_row(png_ptr, tmp_line, NULL);
+                  src_ptr = tmp_line;
+                  for (j = 0; j < w; j++)
+                    {
+                       for (k = 0; k < (int)pack_offset; k++)
+                         dst_ptr[k] = src_ptr[k];
+                       dst_ptr += pack_offset;
+                       src_ptr += scale_ratio * pack_offset;
+                    }
+                  for (j = 0; j < (scale_ratio - 1); j++)
+                    png_read_row(png_ptr, tmp_line, NULL);
                }
-             for (j = 0; j < (scale_ratio - 1); j++)
+          }
+        else
+          {
+             unsigned char *pixels2 = malloc(image_w * image_h * pack_offset);
+
+             if (pixels2)
                {
-                  png_read_row(png_ptr, tmp_line, NULL);
+                  for (p = 0; p < passes; p++)
+                    {
+                       for (i = 0; i < image_h; i++)
+                         png_read_row(png_ptr, pixels2 + (i * image_w * pack_offset), NULL);
+                    }
+
+                  for (i = 0; i < h; i++)
+                    {
+                       src_ptr = pixels2 + (i * scale_ratio * image_w * pack_offset);
+                       for (j = 0; j < w; j++)
+                         {
+                            for (k = 0; k < (int)pack_offset; k++)
+                              dst_ptr[k] = src_ptr[k];
+                            src_ptr += scale_ratio * pack_offset;
+                            dst_ptr += pack_offset;
+                         }
+                    }
+                  free(pixels2);
                }
           }
      }
index 7ce9f2c..5715ed1 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @EVIL_CFLAGS@
 
 if BUILD_LOADER_PSD
@@ -19,7 +19,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_psd.c
 
-module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index efb3e46..71fb8e6 100644 (file)
@@ -7,9 +7,10 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
-@evas_image_loader_svg_cflags@
+@evas_image_loader_svg_cflags@ \
+@EVIL_CFLAGS@
 
 if BUILD_LOADER_SVG
 if !EVAS_STATIC_BUILD_SVG
@@ -19,7 +20,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_esvg.c
 
-module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_svg_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @evas_image_loader_svg_libs@ @EVIL_LIBS@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 92100f6..c6c8455 100644 (file)
@@ -1,10 +1,18 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
 #include <math.h>
 
-#include "evas_common.h"
-#include "evas_private.h"
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
 
 #include <Esvg.h>
 
+#include "evas_common.h"
+#include "evas_private.h"
+
 static inline Eina_Bool evas_image_load_file_is_svg(const char *file) EINA_ARG_NONNULL(1) EINA_PURE;
 static Eina_Bool evas_image_load_file_head_svg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
 static Eina_Bool evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
@@ -72,24 +80,23 @@ evas_image_load_file_head_svg(Image_Entry *ie, const char *file, const char *key
         return EINA_FALSE;
      }
 
-   e = esvg_parser_load(file, NULL, NULL);
+   e = esvg_parser_load(file);
    if (!e)
      {
         *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
         return EINA_FALSE;
      }
 
-   esvg_renderable_x_dpi_set(e, 75.0);
-   esvg_renderable_y_dpi_set(e, 75.0);
+   esvg_svg_x_dpi_set(e, 92.0);
+   esvg_svg_y_dpi_set(e, 92.0);
    esvg_svg_actual_width_get(e, &sw);
    esvg_svg_actual_height_get(e, &sh);
-   esvg_element_setup(e, NULL);
    w = (int)ceil(sw);
    h = (int)ceil(sh);
    if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
        IMG_TOO_BIG(w, h))
      {
-        ender_element_delete(e);
+        ender_element_unref(e);
         if (IMG_TOO_BIG(w, h))
           *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
         else
@@ -127,7 +134,7 @@ evas_image_load_file_head_svg(Image_Entry *ie, const char *file, const char *key
    ie->h = h;
    ie->flags.alpha = 1;
 
-   ender_element_delete(e);
+   ender_element_unref(e);
 
    *error = EVAS_LOAD_ERROR_NONE;
    return EINA_TRUE;
@@ -152,22 +159,22 @@ evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key
         return EINA_FALSE;
      }
 
-   e = esvg_parser_load(file, NULL, NULL);
+   e = esvg_parser_load(file);
    if (!e)
      {
         *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
         return EINA_FALSE;
      }
 
-   esvg_renderable_x_dpi_set(e, 75.0);
-   esvg_renderable_y_dpi_set(e, 75.0);
+   esvg_svg_x_dpi_set(e, 92.0);
+   esvg_svg_y_dpi_set(e, 92.0);
    esvg_svg_actual_width_get(e, &sw);
    esvg_svg_actual_height_get(e, &sh);
    w = (int)ceil(sw);
    h = (int)ceil(sh);
    if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE))
      {
-        ender_element_delete(e);
+        ender_element_unref(e);
         if (IMG_TOO_BIG(w, h))
           *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
         else
@@ -224,9 +231,9 @@ evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key
         goto unref_renderer;
      }
 
-   esvg_element_setup(e, NULL);
+   esvg_svg_setup(e, NULL);
 
-   if (!esvg_renderable_draw(e, s, NULL, 0, 0, &err))
+   if (!esvg_svg_draw(e, s, NULL, 0, 0, &err))
      {
         *error = EVAS_LOAD_ERROR_GENERIC;
         enesim_error_dump(err);
@@ -251,7 +258,7 @@ evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key
    memcpy (pixels, data, h * stride);
 
    enesim_surface_unref(s);
-   ender_element_delete(e);
+   ender_element_unref(e);
 
    evas_common_image_set_alpha_sparse(ie);
 
@@ -260,7 +267,7 @@ evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key
  unref_surface:
    enesim_surface_unref(s);
  unref_renderer:
-   ender_element_delete(e);
+   ender_element_unref(e);
 
    return EINA_FALSE;
 }
index eeec57a..3d67668 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 @FREETYPE_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @EVIL_CFLAGS@
 
 if BUILD_LOADER_TGA
@@ -19,7 +19,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_tga.c
 
-module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
diff --git a/src/modules/loaders/tgv/Makefile.am b/src/modules/loaders/tgv/Makefile.am
new file mode 100644 (file)
index 0000000..13b2ffb
--- /dev/null
@@ -0,0 +1,40 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/static_deps/lz4 \
+-I$(top_srcdir)/src/static_deps/rg_etc \
+@FREETYPE_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
+@PIXMAN_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
+@EVIL_CFLAGS@
+
+if BUILD_LOADER_TGV
+if !EVAS_STATIC_BUILD_TGV
+
+pkgdir = $(libdir)/evas/modules/loaders/tgv/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_tgv.c \
+$(top_srcdir)/src/static_deps/lz4/lz4.c \
+$(top_srcdir)/src/static_deps/rg_etc/rg_etc1.c \
+$(top_srcdir)/src/static_deps/rg_etc/rg_etc2.c
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@ $(top_builddir)/src/lib/libevas.la
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+else
+
+noinst_LTLIBRARIES = libevas_loader_tgv.la
+libevas_loader_tgv_la_SOURCES = evas_image_load_tgv.c \
+$(top_srcdir)/src/static_deps/lz4/lz4.c \
+$(top_srcdir)/src/static_deps/rg_etc/rg_etc1.c \
+$(top_srcdir)/src/static_deps/rg_etc/rg_etc2.c
+libevas_loader_tgv_la_LIBADD =
+
+endif
+endif
diff --git a/src/modules/loaders/tgv/evas_image_load_tgv.c b/src/modules/loaders/tgv/evas_image_load_tgv.c
new file mode 100644 (file)
index 0000000..88ce53d
--- /dev/null
@@ -0,0 +1,525 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+
+#ifdef _WIN32
+# include <winsock2.h>
+#endif /* ifdef _WIN32 */
+
+#include "lz4.h"
+#include "rg_etc1.h"
+#include "evas_common.h"
+#include "evas_private.h"
+
+#ifdef BUILD_NEON
+#include <arm_neon.h>
+#endif
+
+/**************************************************************
+ * The TGV file format is oriented around compression mecanism
+ * that hardware are good at decompressing. We do still provide
+ * a fully software implementation in case your hardware doesn't
+ * handle it. As OpenGL is pretty bad at handling border of
+ * texture, we do duplicate the first pixels of every border.
+ *
+ * This file format is designed to compress/decompress things
+ * in block area. Giving opportunity to store really huge file
+ * and only decompress/compress them as we need. Note that region
+ * only work with software decompression as we don't have a sane
+ * way to duplicate border to avoid artifact when scaling texture.
+ *
+ * The file format is as follow :
+ * - char     magic[4]: "TGV1"
+ * - uint8_t  block_size (real block size = (4 << bits[0-3], 4 << bits[4-7])
+ * - uint8_t  algorithm (0 -> ETC1, 1 -> ETC2 RGB, 2 -> ETC2 RGBA, 3 -> ETC1+Alpha)
+ * - uint8_t  options[2] (bitmask: 1 -> lz4, 2 for block-less, 4 -> unpremultiplied)
+ * - uint32_t width
+ * - uint32_t height
+ * - blocks[]
+ *   - 0 length encoded compress size (if length == 64 * block_size => no compression)
+ *   - lzma encoded etc1 block
+ *
+ * If the format is ETC1+Alpha (algo = 3), then a second image is encoded
+ * in ETC1 right after the first one, and it contains grey-scale alpha
+ * values.
+ **************************************************************/
+
+// FIXME: wondering if we should support mipmap
+// TODO: support ETC1+ETC2 images (RGB only)
+
+static const Evas_Colorspace cspaces_etc1[2] = {
+  EVAS_COLORSPACE_ETC1,
+  EVAS_COLORSPACE_ARGB8888
+};
+
+static const Evas_Colorspace cspaces_rgb8_etc2[2] = {
+  EVAS_COLORSPACE_RGB8_ETC2,
+  EVAS_COLORSPACE_ARGB8888
+};
+
+static const Evas_Colorspace cspaces_rgba8_etc2_eac[2] = {
+  EVAS_COLORSPACE_RGBA8_ETC2_EAC,
+  EVAS_COLORSPACE_ARGB8888
+};
+
+static const Evas_Colorspace cspaces_etc1_alpha[2] = {
+  EVAS_COLORSPACE_ETC1_ALPHA,
+  EVAS_COLORSPACE_ARGB8888
+};
+
+static int
+roundup(int val, int rup)
+{
+   if (val >= 0 && rup > 0)
+     return (val + rup - 1) - ((val + rup - 1) % rup);
+   return 0;
+}
+
+#define OFFSET_BLOCK_SIZE 4
+#define OFFSET_ALGORITHM 5
+#define OFFSET_OPTIONS 6
+#define OFFSET_WIDTH 8
+#define OFFSET_HEIGHT 12
+#define OFFSET_BLOCKS 16
+
+static Eina_Bool
+evas_image_load_file_head_tgv(Image_Entry *ie, const char *file,
+                              const char *key __UNUSED__, int *error)
+{
+   Eina_File *f;
+   char *m = NULL;
+   unsigned int w, h;
+
+   f = eina_file_open(file, EINA_FALSE);
+   *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+   if (!f) return EINA_FALSE;
+
+   *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+   if (eina_file_size_get(f) <= OFFSET_BLOCKS)
+      goto close_file;
+
+   m = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
+   if (!m)
+     {
+        *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+        goto close_file;
+     }
+
+   if (strncmp(m, "TGV1", 4) != 0)
+     goto close_file;
+
+   switch (m[OFFSET_ALGORITHM] & 0xFF)
+     {
+      case 0:
+        ie->cspaces = cspaces_etc1;
+        ie->flags.alpha = EINA_FALSE;
+        break;
+      case 1:
+        ie->cspaces = cspaces_rgb8_etc2;
+        ie->flags.alpha = EINA_FALSE;
+        break;
+      case 2:
+        ie->cspaces = cspaces_rgba8_etc2_eac;
+        ie->flags.alpha = EINA_TRUE;
+        break;
+      case 3:
+        ie->cspaces = cspaces_etc1_alpha;
+        ie->flags.alpha = EINA_TRUE;
+        break;
+      default:
+        *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+        goto close_file;
+     }
+
+   w = ntohl(*((unsigned int*) &(m[OFFSET_WIDTH])));
+   h = ntohl(*((unsigned int*) &(m[OFFSET_HEIGHT])));
+
+   if (ie->load_opts.region.w == 0 && ie->load_opts.region.h == 0)
+     {
+        ie->w = w;
+        ie->h = h;
+     }
+   else
+     {
+        Eina_Rectangle r, lo_region;
+
+        // ETC1 colorspace doesn't work with region
+        ie->cspaces = NULL;
+
+        EINA_RECTANGLE_SET(&r, 0, 0, w, h);
+        EINA_RECTANGLE_SET(&lo_region,
+                           ie->load_opts.region.x, ie->load_opts.region.y,
+                           ie->load_opts.region.w, ie->load_opts.region.h);
+        if (!eina_rectangle_intersection(&r, &lo_region))
+          goto close_file;
+
+        ie->w = r.w;
+        ie->h = r.h;
+     }
+
+   eina_file_map_free(f, m);
+   eina_file_close(f);
+   *error = EVAS_LOAD_ERROR_NONE;
+   return EINA_TRUE;
+
+close_file:
+   if (m) eina_file_map_free(f, m);
+   eina_file_close(f);
+   return EINA_FALSE;
+}
+
+static inline unsigned int
+_tgv_length_get(const char *m, unsigned int length, unsigned int *offset)
+{
+   unsigned int r = 0;
+   unsigned int shift = 0;
+
+   while (*offset < length && ((*m) & 0x80))
+     {
+        r = r | (((*m) & 0x7F) << shift);
+        shift += 7;
+        m++;
+        (*offset)++;
+     }
+   if (*offset < length)
+     {
+        r = r | (((*m) & 0x7F) << shift);
+        (*offset)++;
+     }
+
+   return r;
+}
+
+Eina_Bool
+evas_image_load_file_data_tgv(Image_Entry *ie, const char *file,
+                               const char *key __UNUSED__, int *error)
+{
+   Eina_File *f;
+   char *m = NULL;
+   unsigned int bwidth, bheight;
+   unsigned int *p;
+   unsigned char *p_etc;
+   char *buffer = NULL;
+   Eina_Rectangle master;
+   unsigned int block_length;
+   unsigned int length, offset;
+   unsigned int x, y, w, h;
+   unsigned int block_count;
+   unsigned int etc_width = 0;
+   unsigned int etc_block_size;
+   unsigned int num_planes = 1, plane;
+   unsigned int alpha_offset = 0;
+   Evas_Colorspace cspace, file_cspace;
+   Eina_Bool compress, blockless, unpremul;
+   Eina_Bool r = EINA_FALSE;
+
+   f = eina_file_open(file, EINA_FALSE);
+   *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+   if (!f) return EINA_FALSE;
+
+   *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+   if (eina_file_size_get(f) <= OFFSET_BLOCKS)
+      goto close_file;
+
+   m = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
+   if (!m) goto close_file;
+
+   if (strncmp(m, "TGV1", 4) != 0)
+     goto close_file;
+
+   compress = m[OFFSET_OPTIONS] & 0x1;
+   blockless = (m[OFFSET_OPTIONS] & 0x2) != 0;
+   unpremul = (m[OFFSET_OPTIONS] & 0x4) != 0;
+   w = ntohl(*((unsigned int*) &(m[OFFSET_WIDTH])));
+   h = ntohl(*((unsigned int*) &(m[OFFSET_HEIGHT])));
+
+   switch (m[OFFSET_ALGORITHM] & 0xFF)
+     {
+      case 0:
+        file_cspace = EVAS_COLORSPACE_ETC1;
+        if (ie->flags.alpha != EINA_FALSE) goto close_file;
+        etc_block_size = 8;
+        etc_width = ((w + 2) / 4 + ((w + 2) % 4 ? 1 : 0)) * 8;
+        break;
+      case 1:
+        file_cspace = EVAS_COLORSPACE_RGB8_ETC2;
+        if (ie->flags.alpha != EINA_FALSE) goto close_file;
+        etc_block_size = 8;
+        etc_width = ((w + 2) / 4 + ((w + 2) % 4 ? 1 : 0)) * 8;
+        break;
+      case 2:
+        file_cspace = EVAS_COLORSPACE_RGBA8_ETC2_EAC;
+        if (ie->flags.alpha != EINA_TRUE) goto close_file;
+        etc_block_size = 16;
+        etc_width = ((w + 2) / 4 + ((w + 2) % 4 ? 1 : 0)) * 16;
+        break;
+      case 3:
+        file_cspace = EVAS_COLORSPACE_ETC1_ALPHA;
+        if (ie->flags.alpha != EINA_TRUE) goto close_file;
+        etc_block_size = 8;
+        etc_width = ((w + 2) / 4 + ((w + 2) % 4 ? 1 : 0)) * 8;
+        num_planes = 2;
+        alpha_offset = (((w + 2 + 3) / 4) * ((h + 2 + 3) / 4)) * 8 / sizeof(*p_etc);
+        break;
+      default:
+        *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+        goto close_file;
+     }
+
+   if (ie->space != EVAS_COLORSPACE_ARGB8888 && ie->space != file_cspace)
+     {
+        if (!((ie->space == EVAS_COLORSPACE_RGB8_ETC2) &&
+              (file_cspace == EVAS_COLORSPACE_ETC1)))
+          goto close_file;
+        // else: ETC2 is compatible with ETC1 and is preferred
+     }
+
+   // FIXME: I very much doubt that region load will work with this logic.
+   if (ie->w != w) goto close_file;
+   if (ie->h != h) goto close_file;
+
+   if (blockless)
+     {
+        bwidth = roundup(w + 2, 4);
+        bheight = roundup(h + 2, 4);
+     }
+   else
+     {
+        bwidth = 4 << (m[OFFSET_BLOCK_SIZE] & 0x0f);
+        bheight = 4 << ((m[OFFSET_BLOCK_SIZE] & 0xf0) >> 4);
+     }
+
+   EINA_RECTANGLE_SET(&master,
+                      ie->load_opts.region.x, ie->load_opts.region.y,
+                      ie->w, ie->h);
+
+   cspace = ie->space;
+   switch (cspace)
+     {
+      case EVAS_COLORSPACE_ETC1:
+      case EVAS_COLORSPACE_RGB8_ETC2:
+      case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+      case EVAS_COLORSPACE_ETC1_ALPHA:
+        if (master.x % 4 || master.y % 4)
+          abort();
+        break;
+      case EVAS_COLORSPACE_ARGB8888:
+        // Offset to take duplicated pixels into account
+        master.x += 1;
+        master.y += 1;
+        break;
+      default: abort();
+     }
+
+   evas_cache_image_surface_alloc(ie, w, h);
+   p = evas_cache_image_pixels(ie);
+   if (!p) goto close_file;
+   p_etc = (unsigned char*) p;
+
+   length = eina_file_size_get(f);
+   offset = OFFSET_BLOCKS;
+
+   // Allocate space for each ETC block (8 or 16 bytes per 4 * 4 pixels group)
+   block_count = bwidth * bheight / (4 * 4);
+   if (compress)
+     buffer = alloca(etc_block_size * block_count);
+
+   for (plane = 0; plane < num_planes; plane++)
+     for (y = 0; y < h + 2; y += bheight)
+       for (x = 0; x < w + 2; x += bwidth)
+         {
+            Eina_Rectangle current;
+            const char *data_start;
+            const char *it;
+            unsigned int expand_length;
+            unsigned int i, j;
+
+            block_length = _tgv_length_get(m + offset, length, &offset);
+
+            if (block_length == 0) goto close_file;
+
+            data_start = m + offset;
+            offset += block_length;
+
+            EINA_RECTANGLE_SET(&current, x, y,
+                               bwidth, bheight);
+
+            if (!eina_rectangle_intersection(&current, &master))
+              continue ;
+
+            if (compress)
+              {
+                 expand_length = LZ4_uncompress(data_start, buffer,
+                                                block_count * etc_block_size);
+                 // That's an overhead for now, need to be fixed
+                 if (expand_length != block_length)
+                   goto close_file;
+              }
+            else
+              {
+                 buffer = (void*) data_start;
+                 if (block_count * etc_block_size != block_length)
+                   goto close_file;
+              }
+            it = buffer;
+
+            for (i = 0; i < bheight; i += 4)
+              for (j = 0; j < bwidth; j += 4, it += etc_block_size)
+                {
+                   Eina_Rectangle current_etc;
+                   unsigned int temporary[4 * 4];
+                   unsigned int offset_x, offset_y;
+                   int k, l;
+
+                   EINA_RECTANGLE_SET(&current_etc, x + j, y + i, 4, 4);
+
+                   if (!eina_rectangle_intersection(&current_etc, &current))
+                     continue;
+
+                   switch (cspace)
+                     {
+                      case EVAS_COLORSPACE_ARGB8888:
+                        switch (file_cspace)
+                          {
+                           case EVAS_COLORSPACE_ETC1:
+                           case EVAS_COLORSPACE_ETC1_ALPHA:
+                             if (!rg_etc1_unpack_block(it, temporary, 0))
+                               {
+                                  // TODO: Should we decode as RGB8_ETC2?
+                                  fprintf(stderr, "ETC1: Block starting at {%i, %i} is corrupted!\n", x + j, y + i);
+                                  continue;
+                               }
+                             break;
+                           case EVAS_COLORSPACE_RGB8_ETC2:
+                             rg_etc2_rgb8_decode_block((uint8_t *) it, temporary);
+                             break;
+                           case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+                             rg_etc2_rgba8_decode_block((uint8_t *) it, temporary);
+                             break;
+                           default: abort();
+                          }
+
+                        offset_x = current_etc.x - x - j;
+                        offset_y = current_etc.y - y - i;
+
+                        if (!plane)
+                          {
+#ifdef BUILD_NEON
+                             // FIXME: This should not be using an evas func.
+                             if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
+                               {
+                                  uint32_t *dst = &p[current_etc.x - 1 + (current_etc.y - 1) * master.w];
+                                  uint32_t *src = &temporary[offset_x + offset_y * 4];
+                                  for (k = 0; k < current_etc.h; k++)
+                                    {
+                                       if (current_etc.w == 4)
+                                         vst1q_u32(dst, vld1q_u32(src));
+                                       else if (current_etc.w == 3)
+                                         {
+                                            vst1_u32(dst, vld1_u32(src));
+                                            *(dst + 2) = *(src + 2);
+                                         }
+                                       else if (current_etc.w == 2)
+                                         vst1_u32(dst, vld1_u32(src));
+                                       else
+                                          *dst = *src;
+                                       dst += master.w;
+                                       src += 4;
+                                    }
+                               }
+                             else
+#endif
+                                for (k = 0; k < current_etc.h; k++)
+                                  {
+                                     memcpy(&p[current_etc.x - 1 + (current_etc.y - 1 + k) * master.w],
+                                            &temporary[offset_x + (offset_y + k) * 4],
+                                            current_etc.w * sizeof (unsigned int));
+                                  }
+                          }
+                        else
+                          {
+                             for (k = 0; k < current_etc.h; k++)
+                               for (l = 0; l < current_etc.w; l++)
+                                 {
+                                    unsigned int *rgbdata =
+                                      &p[current_etc.x - 1 + (current_etc.y - 1 + k) * master.w + l];
+                                    unsigned int *adata =
+                                      &temporary[offset_x + (offset_y + k) * 4 + l];
+                                    A_VAL(rgbdata) = G_VAL(adata);
+                                 }
+                          }
+                        break;
+                      case EVAS_COLORSPACE_ETC1:
+                      case EVAS_COLORSPACE_RGB8_ETC2:
+                      case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+                        memcpy(&p_etc[(current_etc.x / 4) * etc_block_size +
+                              (current_etc.y / 4) * etc_width],
+                              it, etc_block_size);
+                        break;
+                      case EVAS_COLORSPACE_ETC1_ALPHA:
+                        memcpy(&p_etc[(current_etc.x / 4) * etc_block_size +
+                                      (current_etc.y / 4) * etc_width +
+                                      plane * alpha_offset],
+                               it, etc_block_size);
+                        break;
+                      default:
+                        abort();
+                     }
+                } // bx,by inside blocks
+         } // x,y macroblocks
+
+   // TODO: Add support for more unpremultiplied modes (ETC2)
+   if ((cspace == EVAS_COLORSPACE_ARGB8888) && unpremul)
+     evas_common_image_premul(ie);
+
+   *error = EVAS_LOAD_ERROR_NONE;
+   r = EINA_TRUE;
+
+close_file:
+   if (m) eina_file_map_free(f, m);
+   eina_file_close(f);
+   return r;
+}
+
+Evas_Image_Load_Func evas_image_load_tgv_func =
+{
+  EINA_TRUE, // Threadable
+  evas_image_load_file_head_tgv,
+  evas_image_load_file_data_tgv,
+  NULL, // Frame duration
+  EINA_FALSE // Region
+};
+
+static int
+module_open(Evas_Module *em)
+{
+   if (!em) return 0;
+   em->functions = (void *)(&evas_image_load_tgv_func);
+   return 1;
+}
+
+static void
+module_close(Evas_Module *em EINA_UNUSED)
+{
+}
+
+static Evas_Module_Api evas_modapi =
+{
+   EVAS_MODULE_API_VERSION,
+   "tgv",
+   "none",
+   {
+     module_open,
+     module_close
+   }
+};
+
+EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, tgv);
+
+#ifndef EVAS_STATIC_BUILD_TGV
+EVAS_EINA_MODULE_DEFINE(image_loader, tgv);
+#endif
index d44643c..9adb737 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_image_loader_tiff_cflags@ \
 @EVIL_CFLAGS@
@@ -20,7 +20,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_tiff.c
 
-module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ @evas_image_loader_tiff_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@ @evas_image_loader_tiff_libs@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index e5badaf..109a02b 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @EVIL_CFLAGS@
 
 if BUILD_LOADER_WBMP
@@ -19,7 +19,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_wbmp.c
 
-module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
diff --git a/src/modules/loaders/webp/Makefile.am b/src/modules/loaders/webp/Makefile.am
new file mode 100644 (file)
index 0000000..c10b5b9
--- /dev/null
@@ -0,0 +1,35 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+@FREETYPE_CFLAGS@ \
+@PIXMAN_CFLAGS@ \
+@EINA_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
+@evas_image_loader_webp_cflags@ \
+@EVIL_CFLAGS@
+
+if BUILD_LOADER_WEBP
+if !EVAS_STATIC_BUILD_WEBP
+
+pkgdir = $(libdir)/evas/modules/loaders/webp/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_load_webp.c
+
+module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ @evas_image_loader_webp_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+else
+
+noinst_LTLIBRARIES = libevas_loader_webp.la
+
+libevas_loader_webp_la_SOURCES = evas_image_load_webp.c
+libevas_loader_webp_la_LIBADD = @evas_image_loader_webp_libs@
+
+endif
+endif
diff --git a/src/modules/loaders/webp/evas_image_load_webp.c b/src/modules/loaders/webp/evas_image_load_webp.c
new file mode 100644 (file)
index 0000000..c1ee0ca
--- /dev/null
@@ -0,0 +1,171 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <webp/decode.h>
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "evas_common.h"
+#include "evas_private.h"
+
+static Eina_Bool evas_image_load_file_head_webp(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
+static Eina_Bool evas_image_load_file_data_webp(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
+
+static Evas_Image_Load_Func evas_image_load_webp_func =
+{
+  EINA_TRUE,
+  evas_image_load_file_head_webp,
+  evas_image_load_file_data_webp,
+  NULL,
+  EINA_FALSE
+};
+
+
+static Eina_Bool
+evas_image_load_file_head_webp(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
+{
+   WebPDecoderConfig config;
+   FILE *f;
+   size_t header_size = 30;
+   uint8_t header[30];
+
+   f = fopen(file, "rb");
+   if (!f)
+   {
+      *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+      return EINA_FALSE;
+   }
+   if (fread(header, header_size, 1, f) != 1)
+   {
+      fclose(f);
+      *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+      return EINA_FALSE;
+   }
+   fclose(f);
+
+   if (!WebPInitDecoderConfig(&config))
+   {
+      *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+      return EINA_FALSE;
+   }
+   if (WebPGetFeatures(header, header_size, &config.input) != VP8_STATUS_OK)
+   {
+      *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
+      return EINA_FALSE;
+   }
+
+   ie->w = config.input.width;
+   ie->h = config.input.height;
+   ie->flags.alpha = config.input.has_alpha;
+
+   *error = EVAS_LOAD_ERROR_NONE;
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+evas_image_load_file_data_webp(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
+{
+   FILE *f;
+   size_t file_size;
+   uint8_t *data, *decoded;
+   DATA32 *surface;
+   int width, height;
+
+   f = fopen(file, "rb");
+   if (!f)
+   {
+      *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+      return EINA_FALSE;
+   }
+
+   if (fseek(f, 0, SEEK_END) != 0)
+   {
+      *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+      goto close_file;
+   }
+   file_size = ftell(f);
+
+   if (fseek(f, 0, SEEK_SET) != 0)
+   {
+      *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+      goto close_file;
+   }
+
+   data = malloc(file_size);
+   if (!data)
+   {
+      *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+      goto close_file;
+   }
+   if (fread(data, file_size, 1, f) != 1)
+   {
+      *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+      goto free_data;
+   }
+
+   evas_cache_image_surface_alloc(ie, ie->w, ie->h);
+   surface = evas_cache_image_pixels(ie);
+   if (!surface)
+   {
+      *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+      goto free_data;
+   }
+
+   decoded = WebPDecodeBGRA(data, file_size, &width, &height);
+   if (!decoded)
+     {
+        *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+        goto free_data;
+     }
+   memcpy(surface, decoded, width * height * 4);
+   evas_common_image_premul(ie);  
+
+   free(decoded);
+   free(data);
+   fclose(f);
+
+   *error = EVAS_LOAD_ERROR_NONE;
+   return EINA_TRUE;
+
+free_data:
+   free(data);
+
+close_file:
+   fclose(f);
+   return EINA_FALSE;
+}
+
+static int
+module_open(Evas_Module *em)
+{
+   if (!em) return 0;
+   em->functions = (void *)(&evas_image_load_webp_func);
+   return 1;
+}
+
+static void
+module_close(Evas_Module *em __UNUSED__)
+{
+}
+
+static Evas_Module_Api evas_modapi =
+{
+   EVAS_MODULE_API_VERSION,
+   "webp",
+   "none",
+   {
+     module_open,
+     module_close
+   }
+};
+
+EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, webp);
+
+#ifndef EVAS_STATIC_BUILD_WEBP
+EVAS_EINA_MODULE_DEFINE(image_loader, webp);
+#endif
index 219803b..1213de5 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_image_loader_xpm_cflags@ \
 @EVIL_CFLAGS@
@@ -20,7 +20,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_load_xpm.c
 
-module_la_LIBADD = @EINA_LIBS@ @EVIL_LIBS@ @evas_image_loader_xpm_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @EVIL_LIBS@ @evas_image_loader_xpm_libs@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 24a5b06..09b1974 100644 (file)
@@ -31,6 +31,23 @@ static Evas_Image_Load_Func evas_image_load_xpm_func =
 static Eina_File *rgb_txt;
 static void *rgb_txt_map;
 
+static int
+_xpm_hexa_int(const char *s, int len)
+{
+   const char *hexa = "0123456789abcdef";
+   const char *lookup;
+   int i, c, r;
+
+   for (r = 0, i = 0; i < len; i++)
+     {
+        c = s[i];
+        lookup = strchr(hexa, tolower(c));
+        r = (r << 4) | (lookup ? lookup - hexa : 0);
+     }
+
+   return r;
+}
+
 static void
 xpm_parse_color(char *color, int *r, int *g, int *b)
 {
@@ -43,26 +60,15 @@ xpm_parse_color(char *color, int *r, int *g, int *b)
    if (color[0] == '#')
      {
         int                 len;
-        char                val[32];
 
         len = strlen(color) - 1;
         if (len < 96)
           {
-             int                 i;
 
              len /= 3;
-             for (i = 0; i < len; i++)
-                val[i] = color[1 + i + (0 * len)];
-             val[i] = 0;
-             sscanf(val, "%x", r);
-             for (i = 0; i < len; i++)
-                val[i] = color[1 + i + (1 * len)];
-             val[i] = 0;
-             sscanf(val, "%x", g);
-             for (i = 0; i < len; i++)
-                val[i] = color[1 + i + (2 * len)];
-             val[i] = 0;
-             sscanf(val, "%x", b);
+             *r = _xpm_hexa_int(&(color[1 + (0 * len)]), len);
+             *g = _xpm_hexa_int(&(color[1 + (1 * len)]), len);
+             *b = _xpm_hexa_int(&(color[1 + (2 * len)]), len);
              if (len == 1)
                {
                   *r = (*r << 4) | *r;
@@ -92,7 +98,7 @@ xpm_parse_color(char *color, int *r, int *g, int *b)
              int rr, gg, bb;
              char name[4096];
 
-             /* FIXME: not really efficient */
+             /* FIXME: not really efficient, should be loaded once in memory with a lookup table */
              memcpy(buf, tmp, endline - tmp);
              buf[endline - tmp + 1] = '\0';
 
@@ -111,29 +117,56 @@ xpm_parse_color(char *color, int *r, int *g, int *b)
      }
 }
 
+typedef struct _CMap CMap;
+struct _CMap {
+   EINA_RBTREE;
+   short         r, g, b;
+   char          str[6];
+   unsigned char transp;
+};
+
+Eina_Rbtree_Direction
+_cmap_cmp_node_cb(const Eina_Rbtree *left, const Eina_Rbtree *right, void *data __UNUSED__)
+{
+   CMap *lcm;
+   CMap *rcm;
+
+   lcm = EINA_RBTREE_CONTAINER_GET(left, CMap);
+   rcm = EINA_RBTREE_CONTAINER_GET(right, CMap);
+
+   if (strcmp(lcm->str, rcm->str) < 0)
+     return EINA_RBTREE_LEFT;
+   return EINA_RBTREE_RIGHT;
+}
+
+int
+_cmap_cmp_key_cb(const Eina_Rbtree *node, const void *key, int length __UNUSED__, void *data __UNUSED__)
+{
+   CMap *root = EINA_RBTREE_CONTAINER_GET(node, CMap);
+
+   return strcmp(root->str, key);
+}
+
 /** FIXME: clean this up and make more efficient  **/
 static Eina_Bool
 evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UNUSED__, int load_data, int *error)
 {
-   DATA32             *ptr, *end;
-   Eina_File          *f;
-   const char         *map;
-   size_t              length;
-   size_t              position;
-
-   int                 pc, c, i, j, k, w, h, ncolors, cpp, comment, transp,
-                       quote, context, len, done, r, g, b, backslash, lu1, lu2;
-   char               *line = NULL;
-   char                s[256], tok[128], col[256], *tl;
-   int                 lsz = 256;
-   struct _cmap {
-      char             str[6];
-      unsigned char    transp;
-      short            r, g, b;
-   }                  *cmap = NULL;
-
-   short               lookup[128 - 32][128 - 32];
-   int                 count, pixels;
+   DATA32      *ptr, *end, *head;
+   Eina_File   *f;
+   const char  *map;
+   size_t       length;
+   size_t       position;
+
+   int          pc, c, i, j, k, w, h, ncolors, cpp, comment, transp,
+                quote, context, len, done, r, g, b, backslash, lu1, lu2;
+   char        *line = NULL;
+   char         s[256], tok[128], col[256], *tl;
+   int          lsz = 256;
+   CMap        *cmap = NULL;
+   Eina_Rbtree *root = NULL;
+
+   short        lookup[128 - 32][128 - 32];
+   int          count, pixels;
 
    done = 0;
 //   transp = -1;
@@ -264,7 +297,7 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
 
                        if (!cmap)
                          {
-                            cmap = malloc(sizeof(struct _cmap) * ncolors);
+                            cmap = malloc(sizeof(CMap) * ncolors);
                             if (!cmap)
                               {
                                *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
@@ -293,6 +326,7 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
                             len = strlen(line);
                             strncpy(cmap[j].str, line, cpp);
                             cmap[j].str[cpp] = 0;
+                            if (load_data) root = eina_rbtree_inline_insert(root, EINA_RBTREE_GET(&cmap[j]), _cmap_cmp_node_cb, NULL);
                            for (slen = 0; slen < cpp; slen++)
                              {
                                 /* fix the ascii of the  color string - if its < 32 - just limit to 32 */
@@ -304,9 +338,11 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
                               {
                                  if (line[k] != ' ')
                                    {
-                                      s[0] = 0;
-                                      sscanf(&line[k], "%255s", s);
-                                      slen = strlen(s);
+                                      const char *tmp = strchr(&line[k], ' ');
+                                      slen = tmp ? tmp - &line[k]: 255;
+
+                                      strncpy(s, &line[k], slen);
+                                      s[slen] = 0;
                                       k += slen;
                                       if (!strcmp(s, "c")) iscolor = 1;
                                       if ((!strcmp(s, "m")) || (!strcmp(s, "s"))
@@ -367,7 +403,7 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
                               }
                          }
                        j++;
-                       if (j >= ncolors)
+                       if (load_data && j >= ncolors)
                          {
                             if (cpp == 1)
                              {
@@ -388,6 +424,7 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
                          {
                             evas_cache_image_surface_alloc(ie, w, h);
                             ptr = evas_cache_image_pixels(ie);
+                            head = ptr;
                             if (!ptr)
                               {
                                 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
@@ -520,6 +557,8 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
                                       ((i < 65536) && (ptr < end) && (line[i]));
                                       i++)
                                    {
+                                      Eina_Rbtree *l;
+
                                       for (j = 0; j < cpp; j++, i++)
                                        {
                                           col[j] = line[i];
@@ -527,30 +566,26 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
                                        }
                                       col[j] = 0;
                                       i--;
-                                      for (j = 0; j < ncolors; j++)
+
+                                      l = eina_rbtree_inline_lookup(root, col, j, _cmap_cmp_key_cb, NULL);
+                                      if (l)
                                         {
-                                           if (!strcmp(col, cmap[j].str))
+                                           CMap *cm = EINA_RBTREE_CONTAINER_GET(l, CMap);
+
+                                           r = (unsigned char)cm->r;
+                                           g = (unsigned char)cm->g;
+                                           b = (unsigned char)cm->b;
+                                           if (cm->transp)
                                              {
-                                                if (cmap[j].transp)
-                                                  {
-                                                     r = (unsigned char)cmap[j].r;
-                                                     g = (unsigned char)cmap[j].g;
-                                                     b = (unsigned char)cmap[j].b;
-                                                    *ptr = RGB_JOIN(r, g, b);
-                                                    ptr++;
-                                                     count++;
-                                                  }
-                                                else
-                                                  {
-                                                    r = (unsigned char)cmap[j].r;
-                                                     g = (unsigned char)cmap[j].g;
-                                                     b = (unsigned char)cmap[j].b;
-                                                    *ptr = ARGB_JOIN(0xff, r, g, b);
-                                                    ptr++;
-                                                     count++;
-                                                  }
-                                               break;
+                                                *ptr = RGB_JOIN(r, g, b);
                                              }
+                                           else
+                                             {
+                                                *ptr = ARGB_JOIN(0xff, r, g, b);
+                                             }
+
+                                           ptr++;
+                                           count++;
                                         }
                                    }
                               }
@@ -560,24 +595,26 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
                                       ((i < 65536) && (ptr < end) && (line[i]));
                                       i++)
                                    {
+                                      Eina_Rbtree *l;
+
                                       for (j = 0; j < cpp; j++, i++)
                                         {
                                            col[j] = line[i];
                                         }
                                       col[j] = 0;
                                       i--;
-                                      for (j = 0; j < ncolors; j++)
+
+                                      l = eina_rbtree_inline_lookup(root, col, 0, _cmap_cmp_key_cb, NULL);
+                                      if (l)
                                         {
-                                           if (!strcmp(col, cmap[j].str))
-                                             {
-                                                r = (unsigned char)cmap[j].r;
-                                                g = (unsigned char)cmap[j].g;
-                                                b = (unsigned char)cmap[j].b;
-                                               *ptr = ARGB_JOIN(0xff, r, g, b);
-                                               ptr++;
-                                               count++;
-                                                break;
-                                             }
+                                           CMap *cm = EINA_RBTREE_CONTAINER_GET(l, CMap);
+                                           
+                                           r = (unsigned char)cm->r;
+                                           g = (unsigned char)cm->g;
+                                           b = (unsigned char)cm->b;
+                                           *ptr = ARGB_JOIN(0xff, r, g, b);
+                                           ptr++;
+                                           count++;
                                         }
                                    }
                               }
@@ -610,7 +647,7 @@ evas_image_load_file_xpm(Image_Entry *ie, const char *file, const char *key __UN
              if (!tl) break;
             line = tl;
           }
-        if (((ptr) && ((ptr - evas_cache_image_pixels(ie)) >= (w * h * (int)sizeof(DATA32)))) ||
+        if (((ptr) && ((ptr - head) >= (w * h * (int)sizeof(DATA32)))) ||
             ((context > 1) && (count >= pixels)))
          break;
      }
index 0854052..aa4453f 100644 (file)
@@ -31,3 +31,10 @@ if !EVAS_STATIC_BUILD_TIFF
 SUBDIRS += tiff
 endif
 endif
+
+if BUILD_LOADER_TGV
+if !EVAS_STATIC_BUILD_TGV
+SUBDIRS += tgv
+endif
+endif
+
index b3cc95c..e5f7e3c 100644 (file)
@@ -6,7 +6,7 @@ AM_CPPFLAGS = -I. -I$(top_srcdir)/src/lib -I$(top_srcdir)/src/lib/include \
 @PIXMAN_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_image_loader_edb_cflags@ \
-@EINA_CFLAGS@
+@EVAS_GENERAL_CFLAGS@
 
 if BUILD_LOADER_EDB
 if !EVAS_STATIC_BUILD_EDB
@@ -16,7 +16,7 @@ pkg_LTLIBRARIES        = module.la
 
 module_la_SOURCES      = evas_image_save_edb.c
 
-module_la_LIBADD       = @EINA_LIBS@ @evas_image_loader_edb_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD       = @EVAS_GENERAL_LIBS@ @evas_image_loader_edb_libs@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS      = -no-undefined -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 679bad0..6d62167 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_image_loader_eet_cflags@
 
@@ -19,7 +19,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_save_eet.c
 
-module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_eet_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @evas_image_loader_eet_libs@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 4eb7176..c189a42 100644 (file)
@@ -7,7 +7,7 @@
 #include "evas_common.h"
 #include "evas_private.h"
 
-static int evas_image_save_file_eet(RGBA_Image *im, const char *file, const char *key, int quality, int compress);
+static int evas_image_save_file_eet(RGBA_Image *im, const char *file, const char *key, int quality, int compress, const char *encoding);
 
 static Evas_Image_Save_Func evas_image_save_eet_func =
 {
@@ -15,11 +15,12 @@ static Evas_Image_Save_Func evas_image_save_eet_func =
 };
 
 static int
-evas_image_save_file_eet(RGBA_Image *im, const char *file, const char *key, int quality, int compress)
+evas_image_save_file_eet(RGBA_Image *im, const char *file, const char *key, int quality, int compress, const char *encoding)
 {
    Eet_File            *ef;
    int alpha = 0, lossy = 0, ok = 0;
    DATA32   *data;
+   (void) encoding;
 
    if (!im || !im->image.data || !file)
       return 0;
index 90afcca..c1c7104 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS= \
 -I$(top_srcdir)/src/lib/include \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_image_loader_jpeg_cflags@
 
@@ -19,7 +19,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_save_jpeg.c
 
-module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_jpeg_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @evas_image_loader_jpeg_libs@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index c01dbdd..1160f24 100644 (file)
@@ -5,7 +5,7 @@
 #include <jpeglib.h>
 #include <setjmp.h>
 
-static int evas_image_save_file_jpeg(RGBA_Image *im, const char *file, const char *key, int quality, int compress);
+static int evas_image_save_file_jpeg(RGBA_Image *im, const char *file, const char *key, int quality, int compress, const char *encoding);
 
 static Evas_Image_Save_Func evas_image_save_jpeg_func =
 {
@@ -121,7 +121,7 @@ save_image_jpeg(RGBA_Image *im, const char *file, int quality)
    return 1;
 }
 
-static int evas_image_save_file_jpeg(RGBA_Image *im, const char *file, const char *key __UNUSED__, int quality, int compress __UNUSED__)
+static int evas_image_save_file_jpeg(RGBA_Image *im, const char *file, const char *key __UNUSED__, int quality, int compress __UNUSED__, const char *encoding __UNUSED__)
 {
    return save_image_jpeg(im, file, quality);
 }
index e25eeab..43eb5b2 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_image_loader_png_cflags@ \
 @EVIL_CFLAGS@
@@ -20,7 +20,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_save_png.c
 
-module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_png_libs@ @EVIL_LIBS@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @evas_image_loader_png_libs@ @EVIL_LIBS@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 734890c..792b04a 100644 (file)
@@ -21,7 +21,7 @@
 #include "evas_common.h"
 #include "evas_private.h"
 
-static int evas_image_save_file_png(RGBA_Image *im, const char *file, const char *key, int quality, int compress);
+static int evas_image_save_file_png(RGBA_Image *im, const char *file, const char *key, int quality, int compress, const char *encoding);
 
 static Evas_Image_Save_Func evas_image_save_png_func =
 {
@@ -156,7 +156,7 @@ save_image_png(RGBA_Image *im, const char *file, int do_compress, int interlace)
 }
 
 static int 
-evas_image_save_file_png(RGBA_Image *im, const char *file, const char *key __UNUSED__, int quality __UNUSED__, int do_compress)
+evas_image_save_file_png(RGBA_Image *im, const char *file, const char *key __UNUSED__, int quality __UNUSED__, int do_compress, const char *encoding __UNUSED__)
 {
    return save_image_png(im, file, do_compress, 0);
 }
diff --git a/src/modules/savers/tgv/Makefile.am b/src/modules/savers/tgv/Makefile.am
new file mode 100644 (file)
index 0000000..a764d6c
--- /dev/null
@@ -0,0 +1,41 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/static_deps/lz4 \
+-I$(top_srcdir)/src/static_deps/rg_etc \
+@FREETYPE_CFLAGS@ \
+@PIXMAN_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
+@evas_image_loader_tgv_cflags@
+
+if BUILD_LOADER_TGV
+if !EVAS_STATIC_BUILD_TGV
+
+pkgdir = $(libdir)/evas/modules/savers/tgv/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = evas_image_save_tgv.c \
+$(top_srcdir)/src/static_deps/lz4/lz4.c \
+$(top_srcdir)/src/static_deps/lz4/lz4hc.c \
+$(top_srcdir)/src/static_deps/rg_etc/rg_etc1.c \
+$(top_srcdir)/src/static_deps/rg_etc/etc2_encoder.c
+
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @evas_image_loader_tgv_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+else
+
+noinst_LTLIBRARIES = libevas_saver_tgv.la
+
+libevas_saver_tgv_la_SOURCES = evas_image_save_tgv.c \
+$(top_srcdir)/static_deps/rg_etc/rg_etc1.c
+libevas_saver_tgv_la_LIBADD = @evas_image_loader_tgv_libs@
+
+endif
+endif
diff --git a/src/modules/savers/tgv/evas_image_save_tgv.c b/src/modules/savers/tgv/evas_image_save_tgv.c
new file mode 100644 (file)
index 0000000..aa19d49
--- /dev/null
@@ -0,0 +1,571 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+
+#ifdef _WIN32
+# include <winsock2.h>
+#endif /* ifdef _WIN32 */
+
+#include "lz4.h"
+#include "lz4hc.h"
+#include "rg_etc1.h"
+#include "evas_common.h"
+#include "evas_private.h"
+
+// FIXME: Remove DEBUG
+#define DEBUG
+#if defined(DEBUG) && defined(HAVE_CLOCK_GETTIME) && defined(_POSIX_MONOTONIC_CLOCK)
+# include <time.h>
+# define DEBUG_STATS
+#endif
+
+static int
+_block_size_get(int size)
+{
+   static const int MAX_BLOCK = 6; // 256 pixels
+
+   int k = 0;
+   while ((4 << k) < size) k++;
+   k = MAX(0, k - 1);
+   if ((size * 3 / 2) >= (4 << k)) return MAX(0, MIN(k - 1, MAX_BLOCK));
+   return MIN(k, MAX_BLOCK);
+}
+
+static inline void
+_alpha_to_greyscale_convert(uint32_t *data, int len)
+{
+   for (int k = 0; k < len; k++)
+     {
+        int alpha = A_VAL(data);
+        *data++ = ARGB_JOIN(alpha, alpha, alpha, alpha);
+     }
+}
+
+static int
+_save_direct_tgv(RGBA_Image *im, const char *file, int compress)
+{
+   // FIXME: Now we have border information, this comment isn't valid anymore:
+
+   // In case we are directly copying ETC1/2 data, we can't properly
+   // duplicate the 1 pixel borders. So we just assume the image contains
+   // them already.
+
+   // TODO: Add block by block compression.
+
+   int image_width, image_height, planes = 1;
+   uint32_t width, height;
+   uint8_t header[8] = "TGV1";
+   int etc_block_size, etc_data_size, buffer_size, data_size, remain;
+   uint8_t *buffer = NULL;
+   uint8_t *data, *ptr;
+   FILE *f;
+
+   image_width = im->cache_entry.w;
+   image_height = im->cache_entry.h;
+   data = im->image.data8;
+   width = htonl(image_width);
+   height = htonl(image_height);
+   compress = !!compress;
+
+   if ((image_width & 0x3) || (image_height & 0x3))
+     return 0;
+
+   // header[4]: block size info, unused
+   header[4] = 0;
+
+   // header[5]: 0 for ETC1
+   switch (im->cache_entry.space)
+     {
+      case EVAS_COLORSPACE_ETC1:
+        etc_block_size = 8;
+        header[5] = 0;
+        break;
+      case EVAS_COLORSPACE_RGB8_ETC2:
+        etc_block_size = 8;
+        header[5] = 1;
+        break;
+      case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+        etc_block_size = 16;
+        header[5] = 2;
+        break;
+      case EVAS_COLORSPACE_ETC1_ALPHA:
+        // FIXME: Properly handle premul vs. unpremul data
+        etc_block_size = 8;
+        header[5] = 3;
+        planes = 2;
+        break;
+      default:
+        return 0;
+     }
+
+   // header[6]: 0 for raw, 1, for LZ4 compressed, 2 for block-less mode
+   header[6] = compress | 0x2;
+
+   // header[7]: options (unused)
+   header[7] = 0;
+
+   f = fopen(file, "w");
+   if (!f) return 0;
+
+   // Write header
+   if (fwrite(header, sizeof (uint8_t), 8, f) != 8) goto on_error;
+   if (fwrite(&width, sizeof (uint32_t), 1, f) != 1) goto on_error;
+   if (fwrite(&height, sizeof (uint32_t), 1, f) != 1) goto on_error;
+
+   etc_data_size = image_width * image_height * etc_block_size * planes / 16;
+   if (compress)
+     {
+        buffer_size = LZ4_compressBound(etc_data_size);
+        buffer = malloc(buffer_size);
+        if (!buffer) goto on_error;
+        data_size = LZ4_compressHC((char *) data, (char *) buffer, etc_data_size);
+     }
+   else
+     {
+        data_size = buffer_size = etc_data_size;
+        buffer = data;
+     }
+
+   // Write block length header -- We keep this even in block-less mode
+   if (data_size > 0)
+     {
+        unsigned int blen = data_size;
+
+        while (blen)
+          {
+             unsigned char plen;
+
+             plen = blen & 0x7F;
+             blen = blen >> 7;
+
+             if (blen) plen = 0x80 | plen;
+             if (fwrite(&plen, 1, 1, f) != 1) goto on_error;
+          }
+     }
+
+   // Write data
+   ptr = buffer;
+   remain = data_size;
+   while (remain > 0)
+     {
+        int written = fwrite(ptr, 1, remain, f);
+        if (written < 0) goto on_error;
+        remain -= written;
+        ptr += written;
+     }
+
+   if (compress) free(buffer);
+   fclose(f);
+   return 1;
+
+on_error:
+   if (compress) free(buffer);
+   fclose(f);
+   return 0;
+}
+
+static int
+evas_image_save_file_tgv(RGBA_Image *im,
+                         const char *file, const char *key EINA_UNUSED,
+                         int quality, int compress, const char *encoding)
+{
+   rg_etc1_pack_params param;
+   FILE *f;
+   uint8_t *comp = NULL;
+   uint8_t *buffer;
+   uint32_t *data = NULL;
+   uint32_t nl_width, nl_height;
+   uint8_t header[8] = "TGV1";
+   int block_width, block_height, macro_block_width, macro_block_height;
+   int block_count, image_stride, image_height, etc_block_size;
+   Evas_Colorspace cspace;
+   Eina_Bool alpha, alpha_texture = EINA_FALSE, unpremul = EINA_FALSE;
+   int num_planes = 1;
+
+#ifdef DEBUG_STATS
+   struct timespec ts1, ts2;
+   long long tsdiff, mse = 0, mse_div = 0, mse_alpha = 0;
+   clock_gettime(CLOCK_MONOTONIC, &ts1);
+#endif
+
+   if (!im || !im->image.data || !file)
+     return 0;
+
+   switch (im->cache_entry.space)
+     {
+      case EVAS_COLORSPACE_ARGB8888:
+        alpha = im->cache_entry.flags.alpha;
+        break;
+      case EVAS_COLORSPACE_ETC1:
+      case EVAS_COLORSPACE_RGB8_ETC2:
+      case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+      case EVAS_COLORSPACE_ETC1_ALPHA:
+        // Note: This case should probably never happen
+        if (encoding)
+          WRN("Ignoring 'encoding' argument the data is already ETC1/2");
+        return _save_direct_tgv(im, file, compress);
+      default:
+        return 0;
+     }
+
+   image_stride = im->cache_entry.w;
+   image_height = im->cache_entry.h;
+   nl_width = htonl(image_stride);
+   nl_height = htonl(image_height);
+   compress = !!compress;
+
+   // Disable dithering, as it will deteriorate the quality of flat surfaces
+   param.m_dithering = 0;
+
+   if (quality > 95)
+     param.m_quality = rg_etc1_high_quality;
+   else if (quality > 30)
+     param.m_quality = rg_etc1_medium_quality;
+   else
+     param.m_quality = rg_etc1_low_quality;
+
+   // header[4]: 4 bit block width, 4 bit block height
+   block_width = _block_size_get(image_stride + 2);
+   block_height = _block_size_get(image_height + 2);
+   header[4] = (block_height << 4) | block_width;
+
+   // header[5]: 0 for ETC1, 1 for RGB8_ETC2, 2 for RGBA8_ETC2_EAC, 3 for ETC1+Alpha
+   if (!encoding) encoding = "etc2";
+   if (!strcasecmp(encoding, "etc1"))
+     {
+        if (alpha)
+          {
+             ERR("ETC1 does not support alpha encoding. Abort. "
+                 "Please use 'encoding=etc1+alpha' for ETC1+Alpha encoding.");
+             return 0;
+          }
+        cspace = EVAS_COLORSPACE_ETC1;
+        etc_block_size = 8;
+        header[5] = 0;
+     }
+   else if (!strcasecmp(encoding, "etc2"))
+     {
+        if (!alpha)
+          {
+             cspace = EVAS_COLORSPACE_RGB8_ETC2;
+             etc_block_size = 8;
+             header[5] = 1;
+          }
+        else
+          {
+             cspace = EVAS_COLORSPACE_RGBA8_ETC2_EAC;
+             etc_block_size = 16;
+             header[5] = 2;
+          }
+     }
+   else if (!strcasecmp(encoding, "etc1+alpha"))
+     {
+        if (!alpha)
+          {
+             INF("Selected etc1+alpha but image has no alpha, reverting to etc1.");
+             cspace = EVAS_COLORSPACE_ETC1;
+             etc_block_size = 8;
+             header[5] = 0;
+          }
+        else
+          {
+             // Save as two textures, and unpremul the data
+             alpha_texture = EINA_TRUE;
+             unpremul = EINA_TRUE;
+             num_planes = 2; // RGB and Alpha
+             cspace = EVAS_COLORSPACE_ETC1_ALPHA;
+             etc_block_size = 8;
+             header[5] = 3;
+          }
+     }
+   else
+     {
+        ERR("Unknown encoding '%.8s' selected. Abort.", encoding);
+        return 0;
+     }
+
+   // header[6]: 0 for raw, 1, for LZ4 compressed, 4 for unpremultiplied RGBA
+   // blockless mode (0x2) is never used here
+   header[6] = (compress ? 0x1 : 0x0) | (unpremul ? 0x4 : 0x0);
+
+   // header[7]: unused options
+   // Note: consider extending the header instead of filling all the bits here
+   header[7] = 0;
+
+   f = fopen(file, "w");
+   if (!f) return 0;
+
+   // Write header
+   if (fwrite(header, sizeof (uint8_t), 8, f) != 8) goto on_error;
+   if (fwrite(&nl_width, sizeof (uint32_t), 1, f) != 1) goto on_error;
+   if (fwrite(&nl_height, sizeof (uint32_t), 1, f) != 1) goto on_error;
+
+   // Real block size in pixels, obviously a multiple of 4
+   macro_block_width = 4 << block_width;
+   macro_block_height = 4 << block_height;
+
+   // Number of ETC1 blocks in a compressed block
+   block_count = (macro_block_width * macro_block_height) / (4 * 4);
+   buffer = alloca(block_count * etc_block_size);
+
+   if (compress)
+     comp = alloca(LZ4_compressBound(block_count * etc_block_size));
+
+   // Write a whole plane (RGB or Alpha)
+   for (int plane = 0; plane < num_planes; plane++)
+     {
+        if (!alpha_texture)
+          {
+             // Normal mode
+             data = im->image.data;
+          }
+        else if (!plane)
+          {
+             int len = image_stride * image_height;
+             // RGB plane for ETC1+Alpha
+             data = malloc(len * 4);
+             if (!data) goto on_error;
+             memcpy(data, im->image.data, len * 4);
+             if (unpremul) evas_data_argb_unpremul(data, len);
+          }
+        else
+          {
+             // Alpha plane for ETC1+Alpha
+             _alpha_to_greyscale_convert(data, image_stride * image_height);
+          }
+
+        // Write macro block
+        for (int y = 0; y < image_height + 2; y += macro_block_height)
+          {
+             uint32_t *input, *last_col, *last_row, *last_pix;
+             int real_y;
+             int wlen;
+
+             if (y == 0) real_y = 0;
+             else if (y < image_height + 1) real_y = y - 1;
+             else real_y = image_height - 1;
+
+             for (int x = 0; x < image_stride + 2; x += macro_block_width)
+               {
+                  uint8_t *offset = buffer;
+                  int real_x = x;
+
+                  if (x == 0) real_x = 0;
+                  else if (x < image_stride + 1) real_x = x - 1;
+                  else real_x = image_stride - 1;
+
+                  input = data + real_y * image_stride + real_x;
+                  last_row = data + image_stride * (image_height - 1) + real_x;
+                  last_col = data + (real_y + 1) * image_stride - 1;
+                  last_pix = data + image_height * image_stride - 1;
+
+                  for (int by = 0; by < macro_block_height; by += 4)
+                    {
+                       int dup_top = ((y + by) == 0) ? 1 : 0;
+                       int max_row = MAX(0, MIN(4, image_height - real_y - by));
+                       int oy = (y == 0) ? 1 : 0;
+
+                       for (int bx = 0; bx < macro_block_width; bx += 4)
+                         {
+                            int dup_left = ((x + bx) == 0) ? 1 : 0;
+                            int max_col = MAX(0, MIN(4, image_stride - real_x - bx));
+                            uint32_t todo[16] = { 0 };
+                            int row, col;
+                            int ox = (x == 0) ? 1 : 0;
+
+                            if (dup_left)
+                              {
+                                 // Duplicate left column
+                                 for (row = 0; row < max_row; row++)
+                                   todo[row * 4] = input[row * image_stride];
+                                 for (row = max_row; row < 4; row++)
+                                   todo[row * 4] = last_row[0];
+                              }
+
+                            if (dup_top)
+                              {
+                                 // Duplicate top row
+                                 for (col = 0; col < max_col; col++)
+                                   todo[col] = input[MAX(col + bx - ox, 0)];
+                                 for (col = max_col; col < 4; col++)
+                                   todo[col] = last_col[0];
+                              }
+
+                            for (row = dup_top; row < 4; row++)
+                              {
+                                 for (col = dup_left; col < max_col; col++)
+                                   {
+                                      if (row < max_row)
+                                        {
+                                           // Normal copy
+                                           todo[row * 4 + col] = input[(row + by - oy) * image_stride + bx + col - ox];
+                                        }
+                                      else
+                                        {
+                                           // Copy last line
+                                           todo[row * 4 + col] = last_row[col + bx - ox];
+                                        }
+                                   }
+                                 for (col = max_col; col < 4; col++)
+                                   {
+                                      // Right edge
+                                      if (row < max_row)
+                                        {
+                                           // Duplicate last column
+                                           todo[row * 4 + col] = last_col[MAX(row + by - oy, 0) * image_stride];
+                                        }
+                                      else
+                                        {
+                                           // Duplicate very last pixel again and again
+                                           todo[row * 4 + col] = *last_pix;
+                                        }
+                                   }
+                              }
+
+                            switch (cspace)
+                              {
+                               case EVAS_COLORSPACE_ETC1:
+                               case EVAS_COLORSPACE_ETC1_ALPHA:
+                                 rg_etc1_pack_block(offset, (uint32_t *) todo, &param);
+                                 break;
+                               case EVAS_COLORSPACE_RGB8_ETC2:
+                                 etc2_rgb8_block_pack(offset, (uint32_t *) todo, &param);
+                                 break;
+                               case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+                                 etc2_rgba8_block_pack(offset, (uint32_t *) todo, &param);
+                                 break;
+                               default: return 0;
+                              }
+
+#ifdef DEBUG_STATS
+                            if (plane == 0)
+                              {
+                                 // Decode to compute PSNR, this is slow.
+                                 uint32_t done[16];
+
+                                 if (alpha)
+                                   rg_etc2_rgba8_decode_block(offset, done);
+                                 else
+                                    rg_etc2_rgb8_decode_block(offset, done);
+
+                                 for (int k = 0; k < 16; k++)
+                                   {
+                                      const int r = (R_VAL(&(todo[k])) - R_VAL(&(done[k])));
+                                      const int g = (G_VAL(&(todo[k])) - G_VAL(&(done[k])));
+                                      const int b = (B_VAL(&(todo[k])) - B_VAL(&(done[k])));
+                                      const int a = (A_VAL(&(todo[k])) - A_VAL(&(done[k])));
+                                      mse += r*r + g*g + b*b;
+                                      if (alpha) mse_alpha += a*a;
+                                      mse_div++;
+                                   }
+                              }
+#endif
+
+                            offset += etc_block_size;
+                         }
+                    }
+
+                  if (compress)
+                    {
+                       wlen = LZ4_compressHC((char *) buffer, (char *) comp,
+                                             block_count * etc_block_size);
+                    }
+                  else
+                    {
+                       comp = buffer;
+                       wlen = block_count * etc_block_size;
+                    }
+
+                  if (wlen > 0)
+                    {
+                       unsigned int blen = wlen;
+
+                       while (blen)
+                         {
+                            unsigned char plen;
+
+                            plen = blen & 0x7F;
+                            blen = blen >> 7;
+
+                            if (blen) plen = 0x80 | plen;
+                            if (fwrite(&plen, 1, 1, f) != 1) goto on_error;
+                         }
+                       if (fwrite(comp, wlen, 1, f) != 1) goto on_error;
+                    }
+               } // 4 rows
+          } // macroblocks
+     } // planes
+   fclose(f);
+
+#ifdef DEBUG_STATS
+   if (mse_div && mse)
+     {
+        // TODO: Add DSSIM too
+        double dmse = (double) mse / (double) (mse_div * 3.0);
+        double psnr = 20 * log10(255.0) - 10 * log10(dmse);
+        double dmse_alpha = (double) mse_alpha / (double) mse_div;
+        double psnr_alpha = (dmse_alpha > 0.0) ? (20 * log10(255.0) - 10 * log10(dmse_alpha)) : 0;
+        clock_gettime(CLOCK_MONOTONIC, &ts2);
+        tsdiff = ((ts2.tv_sec - ts1.tv_sec) * 1000LL) + ((ts2.tv_nsec - ts1.tv_nsec) / 1000000LL);
+        if (!alpha)
+          {
+             INF("ETC%d encoding stats: %dx%d, Time: %lldms, RGB PSNR: %.02fdB",
+                 alpha ? 2 : 1, image_stride, image_height, tsdiff, psnr);
+          }
+        else
+          {
+             INF("ETC%d encoding stats: %dx%d, Time: %lldms, RGB PSNR: %.02fdB, Alpha PSNR: %.02fdB",
+                 alpha ? 2 : 1, image_stride, image_height, tsdiff, psnr, psnr_alpha);
+          }
+     }
+#endif
+
+   if (alpha_texture) free(data);
+   return 1;
+
+on_error:
+   if (alpha_texture) free(data);
+   fclose(f);
+   return 0;
+}
+
+static Evas_Image_Save_Func evas_image_save_tgv_func =
+{
+   evas_image_save_file_tgv
+};
+
+static int
+module_open(Evas_Module *em)
+{
+   if (!em) return 0;
+   em->functions = (void *)(&evas_image_save_tgv_func);
+
+   rg_etc1_pack_block_init();
+   return 1;
+}
+
+static void
+module_close(Evas_Module *em EINA_UNUSED)
+{
+}
+
+static Evas_Module_Api evas_modapi =
+{
+   EVAS_MODULE_API_VERSION,
+   "tgv",
+   "none",
+   {
+     module_open,
+     module_close
+   }
+};
+
+EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_SAVER, image_saver, tgv);
+
+#ifndef EVAS_STATIC_BUILD_TGV
+EVAS_EINA_MODULE_DEFINE(image_saver, tgv);
+#endif
index 4730018..c0f8039 100644 (file)
@@ -7,7 +7,7 @@ AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/include \
 @FREETYPE_CFLAGS@ \
 @PIXMAN_CFLAGS@ \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @FRIBIDI_CFLAGS@ \
 @evas_image_loader_tiff_cflags@
 
@@ -19,7 +19,7 @@ pkg_LTLIBRARIES = module.la
 
 module_la_SOURCES = evas_image_save_tiff.c
 
-module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_tiff_libs@ $(top_builddir)/src/lib/libevas.la
+module_la_LIBADD = @EVAS_GENERAL_LIBS@ @evas_image_loader_tiff_libs@ $(top_builddir)/src/lib/libevas.la
 module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
 module_la_LIBTOOLFLAGS = --tag=disable-static
 
index 8148f51..033952f 100644 (file)
@@ -3,7 +3,7 @@
 
 #include <tiffio.h>
 
-static int evas_image_save_file_tiff(RGBA_Image *im, const char *file, const char *key, int quality, int compress);
+static int evas_image_save_file_tiff(RGBA_Image *im, const char *file, const char *key, int quality, int compress, const char *encoding);
 
 static Evas_Image_Save_Func evas_image_save_tiff_func =
 {
@@ -102,7 +102,7 @@ save_image_tiff(RGBA_Image *im, const char *file, int compress __UNUSED__, int i
    return 1;
 }
 
-static int evas_image_save_file_tiff(RGBA_Image *im, const char *file, const char *key __UNUSED__, int quality __UNUSED__, int compress)
+static int evas_image_save_file_tiff(RGBA_Image *im, const char *file, const char *key __UNUSED__, int quality __UNUSED__, int compress, const char *encoding __UNUSED__)
 {
    return save_image_tiff(im, file, compress, 0);
 }
index 08a0f5b..21e1701 100644 (file)
@@ -5,3 +5,8 @@ SUBDIRS =
 if EVAS_USE_LINEBREAK
 SUBDIRS += liblinebreak
 endif
+
+if BUILD_LOADER_TGV
+SUBDIRS += lz4 rg_etc
+endif
+
index f9ff9a1..4e13247 100644 (file)
@@ -536,6 +536,9 @@ void set_linebreaks(
        struct LineBreakProperties *lbpLang;
        size_t posCur = 0;
        size_t posLast = 0;
+       // TIZEN ONLY : (2013.08.19) for special processing at Zero-width space character
+       int zw_flag = 0;
+       //
 
        --posLast;      /* To be ++'d later */
        ch = get_next_char(s, len, &posCur);
@@ -584,6 +587,8 @@ nextline:
                        goto nextline;
                }
 
+               // TIZEN ONLY : (2013.08.19) for special processing at Zero-width space character
+               /*
                switch (lbcNew)
                {
                case LBP_SP:
@@ -638,6 +643,112 @@ nextline:
                }
 
                lbcCur = lbcNew;
+               */
+
+               // TIZEN ONLY - START
+               if (lbcCur == LBP_ZW && !zw_flag)
+               {
+                       zw_flag = 1;
+                       posLast = -1;
+                       posCur = 0;
+                       ch = get_next_char(s, len, &posCur);
+                       lbcCur = resolve_lb_class(get_char_lb_class_lang(ch, lbpLang), lang);
+                       lbcNew = LBP_Undefined;
+                       goto nextline;
+               }
+               else if (zw_flag)
+               {
+                       if (lbcCur == LBP_ZW)
+                               brks[posLast] = LINEBREAK_ALLOWBREAK;
+                       else
+                               brks[posLast] = LINEBREAK_NOBREAK;
+                       lbcCur = lbcNew;
+               }
+               else
+               {
+                       // TIZEN ONLY(20131106): For Hangul word wrap
+                       switch (lbcCur)
+                       {
+                               case LBP_H2:                    /**< Hangul LV */
+                               case LBP_H3:                    /**< Hangul LVT */
+                               case LBP_JL:                    /**< Hangul L Jamo */
+                               case LBP_JV:                    /**< Hangul V Jamo */
+                               case LBP_JT:                    /**< Hangul T Jamo */
+                                       lbcCur = LBP_AL;
+                                       break;
+                               default:
+                                       break;
+                       }
+
+                       switch (lbcNew)
+                       {
+                               case LBP_H2:                    /**< Hangul LV */
+                               case LBP_H3:                    /**< Hangul LVT */
+                               case LBP_JL:                    /**< Hangul L Jamo */
+                               case LBP_JV:                    /**< Hangul V Jamo */
+                               case LBP_JT:                    /**< Hangul T Jamo */
+                                       lbcNew = LBP_AL;
+                                       break;
+                               default:
+                                       break;
+                       }
+                       //
+
+                       switch (lbcNew)
+                       {
+                               case LBP_SP:
+                                       brks[posLast] = LINEBREAK_NOBREAK;
+                                       continue;
+                               case LBP_BK:
+                               case LBP_LF:
+                               case LBP_NL:
+                                       brks[posLast] = LINEBREAK_NOBREAK;
+                                       lbcCur = LBP_BK;
+                                       continue;
+                               case LBP_CR:
+                                       brks[posLast] = LINEBREAK_NOBREAK;
+                                       lbcCur = LBP_CR;
+                                       continue;
+                               case LBP_CB:
+                                       brks[posLast] = LINEBREAK_ALLOWBREAK;
+                                       lbcCur = LBP_BA;
+                                       continue;
+                               default:
+                                       break;
+                       }
+
+                       lbcNew = resolve_lb_class(lbcNew, lang);
+
+                       assert(lbcCur <= LBP_JT);
+                       assert(lbcNew <= LBP_JT);
+                       switch (baTable[lbcCur - 1][lbcNew - 1])
+                       {
+                               case DIR_BRK:
+                                       brks[posLast] = LINEBREAK_ALLOWBREAK;
+                                       break;
+                               case CMI_BRK:
+                               case IND_BRK:
+                                       if (lbcLast == LBP_SP)
+                                       {
+                                               brks[posLast] = LINEBREAK_ALLOWBREAK;
+                                       }
+                                       else
+                                       {
+                                               brks[posLast] = LINEBREAK_NOBREAK;
+                                       }
+                                       break;
+                               case CMP_BRK:
+                                       brks[posLast] = LINEBREAK_NOBREAK;
+                                       if (lbcLast != LBP_SP)
+                                               continue;
+                                       break;
+                               case PRH_BRK:
+                                       brks[posLast] = LINEBREAK_NOBREAK;
+                                       break;
+                       }
+                       lbcCur = lbcNew;
+               }
+               // TIZEN ONLY - END
        }
 
        assert(posLast == posCur - 1 && posCur <= len);
index 0021479..d4e5f0b 100644 (file)
@@ -6,6 +6,8 @@
 #include "linebreak.h"
 #include "linebreakdef.h"
 
+// 2014.09.18 Update Japanese char: LBP_NS(LBP_CJ in opensource) -> LBP_ID
+
 /** Default line breaking properties as from the Unicode Web site. */
 struct LineBreakProperties lb_prop_default[] = {
        { 0x0000, 0x0008, LBP_CM },
@@ -768,55 +770,58 @@ struct LineBreakProperties lb_prop_default[] = {
        { 0x3030, 0x303A, LBP_ID },
        { 0x303B, 0x303C, LBP_NS },
        { 0x303D, 0x303F, LBP_ID },
-       { 0x3041, 0x3041, LBP_NS },
+       { 0x3041, 0x3041, LBP_ID },
        { 0x3042, 0x3042, LBP_ID },
-       { 0x3043, 0x3043, LBP_NS },
+       { 0x3043, 0x3043, LBP_ID },
        { 0x3044, 0x3044, LBP_ID },
-       { 0x3045, 0x3045, LBP_NS },
+       { 0x3045, 0x3045, LBP_ID },
        { 0x3046, 0x3046, LBP_ID },
-       { 0x3047, 0x3047, LBP_NS },
+       { 0x3047, 0x3047, LBP_ID },
        { 0x3048, 0x3048, LBP_ID },
-       { 0x3049, 0x3049, LBP_NS },
+       { 0x3049, 0x3049, LBP_ID },
        { 0x304A, 0x3062, LBP_ID },
-       { 0x3063, 0x3063, LBP_NS },
+       { 0x3063, 0x3063, LBP_ID },
        { 0x3064, 0x3082, LBP_ID },
-       { 0x3083, 0x3083, LBP_NS },
+       { 0x3083, 0x3083, LBP_ID },
        { 0x3084, 0x3084, LBP_ID },
-       { 0x3085, 0x3085, LBP_NS },
+       { 0x3085, 0x3085, LBP_ID },
        { 0x3086, 0x3086, LBP_ID },
-       { 0x3087, 0x3087, LBP_NS },
+       { 0x3087, 0x3087, LBP_ID },
        { 0x3088, 0x308D, LBP_ID },
-       { 0x308E, 0x308E, LBP_NS },
+       { 0x308E, 0x308E, LBP_ID },
        { 0x308F, 0x3094, LBP_ID },
-       { 0x3095, 0x3096, LBP_NS },
+       { 0x3095, 0x3096, LBP_ID },
        { 0x3099, 0x309A, LBP_CM },
        { 0x309B, 0x309E, LBP_NS },
        { 0x309F, 0x309F, LBP_ID },
-       { 0x30A0, 0x30A1, LBP_NS },
+       { 0x30A0, 0x30A0, LBP_NS },
+       { 0x30A1, 0x30A1, LBP_ID },
        { 0x30A2, 0x30A2, LBP_ID },
-       { 0x30A3, 0x30A3, LBP_NS },
+       { 0x30A3, 0x30A3, LBP_ID },
        { 0x30A4, 0x30A4, LBP_ID },
-       { 0x30A5, 0x30A5, LBP_NS },
+       { 0x30A5, 0x30A5, LBP_ID },
        { 0x30A6, 0x30A6, LBP_ID },
-       { 0x30A7, 0x30A7, LBP_NS },
+       { 0x30A7, 0x30A7, LBP_ID },
        { 0x30A8, 0x30A8, LBP_ID },
-       { 0x30A9, 0x30A9, LBP_NS },
+       { 0x30A9, 0x30A9, LBP_ID },
        { 0x30AA, 0x30C2, LBP_ID },
-       { 0x30C3, 0x30C3, LBP_NS },
+       { 0x30C3, 0x30C3, LBP_ID },
        { 0x30C4, 0x30E2, LBP_ID },
-       { 0x30E3, 0x30E3, LBP_NS },
+       { 0x30E3, 0x30E3, LBP_ID },
        { 0x30E4, 0x30E4, LBP_ID },
-       { 0x30E5, 0x30E5, LBP_NS },
+       { 0x30E5, 0x30E5, LBP_ID },
        { 0x30E6, 0x30E6, LBP_ID },
-       { 0x30E7, 0x30E7, LBP_NS },
+       { 0x30E7, 0x30E7, LBP_ID },
        { 0x30E8, 0x30ED, LBP_ID },
-       { 0x30EE, 0x30EE, LBP_NS },
+       { 0x30EE, 0x30EE, LBP_ID },
        { 0x30EF, 0x30F4, LBP_ID },
-       { 0x30F5, 0x30F6, LBP_NS },
+       { 0x30F5, 0x30F6, LBP_ID },
        { 0x30F7, 0x30FA, LBP_ID },
-       { 0x30FB, 0x30FE, LBP_NS },
+       { 0x30FB, 0x30FB, LBP_NS },
+       { 0x30FC, 0x30FC, LBP_ID },
+       { 0x30FD, 0x30FE, LBP_NS },
        { 0x30FF, 0x31E3, LBP_ID },
-       { 0x31F0, 0x31FF, LBP_NS },
+       { 0x31F0, 0x31FF, LBP_ID },
        { 0x3200, 0x3247, LBP_ID },
        { 0x3248, 0x324F, LBP_AI },
        { 0x3250, 0x4DBF, LBP_ID },
@@ -1779,7 +1784,7 @@ struct LineBreakProperties lb_prop_default[] = {
        { 0xFF63, 0xFF64, LBP_CL },
        { 0xFF65, 0xFF65, LBP_NS },
        { 0xFF66, 0xFF66, LBP_AL },
-       { 0xFF67, 0xFF70, LBP_NS },
+       { 0xFF67, 0xFF70, LBP_ID },
        { 0xFF71, 0xFF9D, LBP_AL },
        { 0xFF9E, 0xFF9F, LBP_NS },
        { 0xFFA0, 0xFFDC, LBP_AL },
index 9ddb4d9..548d209 100644 (file)
@@ -107,7 +107,8 @@ static struct LineBreakProperties lb_prop_French[] = {
 static struct LineBreakProperties lb_prop_Russian[] = {
        { 0x00AB, 0x00AB, LBP_OP },     /* Left double angle quotation mark: opening */
        { 0x00BB, 0x00BB, LBP_CL },     /* Right double angle quotation mark: closing */
-       { 0x201C, 0x201C, LBP_CL },     /* Left double quotation mark: closing */
+       { 0x201C, 0x201C, LBP_OP },     /* Left double quotation mark: opening */
+       { 0x201D, 0x201D, LBP_CL },     /* Right double quotation mark: closing */
        { 0, 0, LBP_Undefined }
 };
 
diff --git a/src/static_deps/lz4/Makefile.am b/src/static_deps/lz4/Makefile.am
new file mode 100644 (file)
index 0000000..1180d81
--- /dev/null
@@ -0,0 +1,4 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+EXTRA_DIST = README lz4.c lz4.h lz4c.c lz4c.h
+
diff --git a/src/static_deps/lz4/README b/src/static_deps/lz4/README
new file mode 100644 (file)
index 0000000..718f773
--- /dev/null
@@ -0,0 +1,7 @@
+This iz the lz4 tree copied in:
+  http://lz4.googlecode.com/svn/trunk
+by:
+  yann.collet.73@gmail.com
+Copyright/licensing info in source files here.
+
+this was from revision 84.
diff --git a/src/static_deps/lz4/lz4.c b/src/static_deps/lz4/lz4.c
new file mode 100644 (file)
index 0000000..71ebf2e
--- /dev/null
@@ -0,0 +1,861 @@
+/*
+   LZ4 - Fast LZ compression algorithm
+   Copyright (C) 2011-2012, Yann Collet.
+   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+       * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+       * Redistributions in binary form must reproduce the above
+   copyright notice, this list of conditions and the following disclaimer
+   in the documentation and/or other materials provided with the
+   distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+   You can contact the author at :
+   - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
+   - LZ4 source repository : http://code.google.com/p/lz4/
+*/
+
+//**************************************
+// Tuning parameters
+//**************************************
+// MEMORY_USAGE :
+// Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
+// Increasing memory usage improves compression ratio
+// Reduced memory usage can improve speed, due to cache effect
+// Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
+#define MEMORY_USAGE 14
+
+// NOTCOMPRESSIBLE_DETECTIONLEVEL :
+// Decreasing this value will make the algorithm skip faster data segments considered "incompressible"
+// This may decrease compression ratio dramatically, but will be faster on incompressible data
+// Increasing this value will make the algorithm search more before declaring a segment "incompressible"
+// This could improve compression a bit, but will be slower on incompressible data
+// The default value (6) is recommended
+#define NOTCOMPRESSIBLE_DETECTIONLEVEL 6
+
+// BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE :
+// This will provide a small boost to performance for big endian cpu, but the resulting compressed stream will be incompatible with little-endian CPU.
+// You can set this option to 1 in situations where data will remain within closed environment
+// This option is useless on Little_Endian CPU (such as x86)
+//#define BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE 1
+
+
+
+//**************************************
+// CPU Feature Detection
+//**************************************
+// 32 or 64 bits ?
+#if (defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64) || defined(__ppc64__) || defined(_WIN64) || defined(__LP64__) || defined(_LP64) )   // Detects 64 bits mode
+#  define LZ4_ARCH64 1
+#else
+#  define LZ4_ARCH64 0
+#endif
+
+// Little Endian or Big Endian ?
+// Note : overwrite the below #define if you know your architecture endianess
+#if (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN) || defined(_ARCH_PPC) || defined(__PPC__) || defined(__PPC) || defined(PPC) || defined(__powerpc__) || defined(__powerpc) || defined(powerpc) || ((defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))) )
+#  define LZ4_BIG_ENDIAN 1
+#else
+// Little Endian assumed. PDP Endian and other very rare endian format are unsupported.
+#endif
+
+// Unaligned memory access is automatically enabled for "common" CPU, such as x86.
+// For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected
+// If you know your target CPU supports unaligned memory access, you may want to force this option manually to improve performance
+#if defined(__ARM_FEATURE_UNALIGNED)
+#  define LZ4_FORCE_UNALIGNED_ACCESS 1
+#endif
+
+// Define this parameter if your target system or compiler does not support hardware bit count
+#if defined(_MSC_VER) && defined(_WIN32_WCE)            // Visual Studio for Windows CE does not support Hardware bit count
+#  define LZ4_FORCE_SW_BITCOUNT
+#endif
+
+
+//**************************************
+// Compiler Options
+//**************************************
+#if __STDC_VERSION__ >= 199901L   // C99
+/* "restrict" is a known keyword */
+#else
+#  define restrict // Disable restrict
+#endif
+
+#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+
+#ifdef _MSC_VER  // Visual Studio
+#  include <intrin.h>   // For Visual 2005
+#  if LZ4_ARCH64       // 64-bit
+#    pragma intrinsic(_BitScanForward64) // For Visual 2005
+#    pragma intrinsic(_BitScanReverse64) // For Visual 2005
+#  else
+#    pragma intrinsic(_BitScanForward)   // For Visual 2005
+#    pragma intrinsic(_BitScanReverse)   // For Visual 2005
+#  endif
+#endif
+
+#ifdef _MSC_VER
+#  define lz4_bswap16(x) _byteswap_ushort(x)
+#else
+#  define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8)))
+#endif
+
+#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__)
+#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
+#else
+#  define expect(expr,value)    (expr)
+#endif
+
+#define likely(expr)     expect((expr) != 0, 1)
+#define unlikely(expr)   expect((expr) != 0, 0)
+
+
+//**************************************
+// Includes
+//**************************************
+#include <stdlib.h>   // for malloc
+#include <string.h>   // for memset
+#include "lz4.h"
+
+
+//**************************************
+// Basic Types
+//**************************************
+#if defined(_MSC_VER)    // Visual Studio does not support 'stdint' natively
+#  define BYTE unsigned __int8
+#  define U16          unsigned __int16
+#  define U32          unsigned __int32
+#  define S32          __int32
+#  define U64          unsigned __int64
+#else
+#  include <stdint.h>
+#  define BYTE uint8_t
+#  define U16          uint16_t
+#  define U32          uint32_t
+#  define S32          int32_t
+#  define U64          uint64_t
+#endif
+
+#ifndef LZ4_FORCE_UNALIGNED_ACCESS
+#  pragma pack(push, 1)
+#endif
+
+typedef struct _U16_S { U16 v; } U16_S;
+typedef struct _U32_S { U32 v; } U32_S;
+typedef struct _U64_S { U64 v; } U64_S;
+
+#ifndef LZ4_FORCE_UNALIGNED_ACCESS
+#  pragma pack(pop)
+#endif
+
+#define A64(x) (((U64_S *)(x))->v)
+#define A32(x) (((U32_S *)(x))->v)
+#define A16(x) (((U16_S *)(x))->v)
+
+
+//**************************************
+// Constants
+//**************************************
+#define MINMATCH 4
+
+#define HASH_LOG (MEMORY_USAGE-2)
+#define HASHTABLESIZE (1 << HASH_LOG)
+#define HASH_MASK (HASHTABLESIZE - 1)
+
+#define SKIPSTRENGTH (NOTCOMPRESSIBLE_DETECTIONLEVEL>2?NOTCOMPRESSIBLE_DETECTIONLEVEL:2)
+#define STACKLIMIT 13
+#define HEAPMODE (HASH_LOG>STACKLIMIT)  // Defines if memory is allocated into the stack (local variable), or into the heap (malloc()).
+#define COPYLENGTH 8
+#define LASTLITERALS 5
+#define MFLIMIT (COPYLENGTH+MINMATCH)
+#define MINLENGTH (MFLIMIT+1)
+
+#define MAXD_LOG 16
+#define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
+
+#define ML_BITS  4
+#define ML_MASK  ((1U<<ML_BITS)-1)
+#define RUN_BITS (8-ML_BITS)
+#define RUN_MASK ((1U<<RUN_BITS)-1)
+
+
+//**************************************
+// Architecture-specific macros
+//**************************************
+#if LZ4_ARCH64 // 64-bit
+#  define STEPSIZE 8
+#  define UARCH U64
+#  define AARCH A64
+#  define LZ4_COPYSTEP(s,d)       A64(d) = A64(s); d+=8; s+=8;
+#  define LZ4_COPYPACKET(s,d)     LZ4_COPYSTEP(s,d)
+#  define LZ4_SECURECOPY(s,d,e)   if (d<e) LZ4_WILDCOPY(s,d,e)
+#  define HTYPE                   U32
+#  define INITBASE(base)          const BYTE* const base = ip
+#else          // 32-bit
+#  define STEPSIZE 4
+#  define UARCH U32
+#  define AARCH A32
+#  define LZ4_COPYSTEP(s,d)       A32(d) = A32(s); d+=4; s+=4;
+#  define LZ4_COPYPACKET(s,d)     LZ4_COPYSTEP(s,d); LZ4_COPYSTEP(s,d);
+#  define LZ4_SECURECOPY          LZ4_WILDCOPY
+#  define HTYPE                   const BYTE*
+#  define INITBASE(base)          const int base = 0
+#endif
+
+#if (defined(LZ4_BIG_ENDIAN) && !defined(BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE))
+#  define LZ4_READ_LITTLEENDIAN_16(d,s,p) { U16 v = A16(p); v = lz4_bswap16(v); d = (s) - v; }
+#  define LZ4_WRITE_LITTLEENDIAN_16(p,i)  { U16 v = (U16)(i); v = lz4_bswap16(v); A16(p) = v; p+=2; }
+#else          // Little Endian
+#  define LZ4_READ_LITTLEENDIAN_16(d,s,p) { d = (s) - A16(p); }
+#  define LZ4_WRITE_LITTLEENDIAN_16(p,v)  { A16(p) = v; p+=2; }
+#endif
+
+
+//**************************************
+// Local structures
+//**************************************
+struct refTables
+{
+    HTYPE hashTable[HASHTABLESIZE];
+};
+
+
+//**************************************
+// Macros
+//**************************************
+#define LZ4_HASH_FUNCTION(i)   (((i) * 2654435761U) >> ((MINMATCH*8)-HASH_LOG))
+#define LZ4_HASH_VALUE(p)              LZ4_HASH_FUNCTION(A32(p))
+#define LZ4_WILDCOPY(s,d,e)            do { LZ4_COPYPACKET(s,d) } while (d<e);
+#define LZ4_BLINDCOPY(s,d,l)   { BYTE* e=(d)+l; LZ4_WILDCOPY(s,d,e); d=e; }
+
+
+//****************************
+// Private functions
+//****************************
+#if LZ4_ARCH64
+
+static inline int LZ4_NbCommonBytes (register U64 val)
+{
+#if defined(LZ4_BIG_ENDIAN)
+    #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    unsigned long r = 0;
+    _BitScanReverse64( &r, val );
+    return (int)(r>>3);
+    #elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    return (__builtin_clzll(val) >> 3);
+    #else
+    int r;
+    if (!(val>>32)) { r=4; } else { r=0; val>>=32; }
+    if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
+    r += (!val);
+    return r;
+    #endif
+#else
+    #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    unsigned long r = 0;
+    _BitScanForward64( &r, val );
+    return (int)(r>>3);
+    #elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    return (__builtin_ctzll(val) >> 3);
+    #else
+    static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
+    return DeBruijnBytePos[((U64)((val & -val) * 0x0218A392CDABBD3F)) >> 58];
+    #endif
+#endif
+}
+
+#else
+
+static inline int LZ4_NbCommonBytes (register U32 val)
+{
+#if defined(LZ4_BIG_ENDIAN)
+    #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    unsigned long r = 0;
+    _BitScanReverse( &r, val );
+    return (int)(r>>3);
+    #elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    return (__builtin_clz(val) >> 3);
+    #else
+    int r;
+    if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
+    r += (!val);
+    return r;
+    #endif
+#else
+    #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    unsigned long r = 0;
+    _BitScanForward( &r, val );
+    return (int)(r>>3);
+    #elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    return (__builtin_ctz(val) >> 3);
+    #else
+    static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
+    return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
+    #endif
+#endif
+}
+
+#endif
+
+
+
+//******************************
+// Compression functions
+//******************************
+
+// LZ4_compressCtx :
+// -----------------
+// Compress 'isize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'.
+// If it cannot achieve it, compression will stop, and result of the function will be zero.
+// return : the number of bytes written in buffer 'dest', or 0 if the compression fails
+
+static inline int LZ4_compressCtx(void** ctx,
+                 const char* source,
+                 char* dest,
+                 int isize,
+                 int maxOutputSize)
+{
+#if HEAPMODE
+    struct refTables *srt = (struct refTables *) (*ctx);
+    HTYPE* HashTable;
+#else
+    HTYPE HashTable[HASHTABLESIZE] = {0};
+#endif
+
+    const BYTE* ip = (BYTE*) source;
+    INITBASE(base);
+    const BYTE* anchor = ip;
+    const BYTE* const iend = ip + isize;
+    const BYTE* const mflimit = iend - MFLIMIT;
+#define matchlimit (iend - LASTLITERALS)
+
+    BYTE* op = (BYTE*) dest;
+    BYTE* const oend = op + maxOutputSize;
+
+    int len, length;
+    const int skipStrength = SKIPSTRENGTH;
+    U32 forwardH;
+
+
+    // Init
+    if (isize<MINLENGTH) goto _last_literals;
+#if HEAPMODE
+    if (*ctx == NULL)
+    {
+        srt = (struct refTables *) malloc ( sizeof(struct refTables) );
+        *ctx = (void*) srt;
+    }
+    HashTable = (HTYPE*)(srt->hashTable);
+    memset((void*)HashTable, 0, sizeof(srt->hashTable));
+#else
+    (void) ctx;
+#endif
+
+
+    // First Byte
+    HashTable[LZ4_HASH_VALUE(ip)] = ip - base;
+    ip++; forwardH = LZ4_HASH_VALUE(ip);
+
+    // Main Loop
+    for ( ; ; )
+    {
+        int findMatchAttempts = (1U << skipStrength) + 3;
+        const BYTE* forwardIp = ip;
+        const BYTE* ref;
+        BYTE* token;
+
+        // Find a match
+        do {
+            U32 h = forwardH;
+            int step = findMatchAttempts++ >> skipStrength;
+            ip = forwardIp;
+            forwardIp = ip + step;
+
+            if unlikely(forwardIp > mflimit) { goto _last_literals; }
+
+            forwardH = LZ4_HASH_VALUE(forwardIp);
+            ref = base + HashTable[h];
+            HashTable[h] = ip - base;
+
+        } while ((ref < ip - MAX_DISTANCE) || (A32(ref) != A32(ip)));
+
+        // Catch up
+        while ((ip>anchor) && (ref>(BYTE*)source) && unlikely(ip[-1]==ref[-1])) { ip--; ref--; }
+
+        // Encode Literal length
+        length = (int)(ip - anchor);
+        token = op++;
+        if unlikely(op + length + (2 + 1 + LASTLITERALS) + (length>>8) > oend) return 0;               // Check output limit
+#ifdef _MSC_VER
+        if (length>=(int)RUN_MASK) 
+        { 
+            int len = length-RUN_MASK; 
+            *token=(RUN_MASK<<ML_BITS); 
+            if (len>254)
+            {
+                do { *op++ = 255; len -= 255; } while (len>254);
+                *op++ = (BYTE)len; 
+                memcpy(op, anchor, length);
+                op += length;
+                goto _next_match;
+            }
+            else
+            *op++ = (BYTE)len; 
+        }
+        else *token = (length<<ML_BITS);
+#else
+        if (length>=(int)RUN_MASK) { *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *op++ = 255; *op++ = (BYTE)len; }
+        else *token = (length<<ML_BITS);
+#endif
+
+        // Copy Literals
+        LZ4_BLINDCOPY(anchor, op, length);
+
+_next_match:
+        // Encode Offset
+        LZ4_WRITE_LITTLEENDIAN_16(op,(U16)(ip-ref));
+
+        // Start Counting
+        ip+=MINMATCH; ref+=MINMATCH;   // MinMatch verified
+        anchor = ip;
+        while likely(ip<matchlimit-(STEPSIZE-1))
+        {
+            UARCH diff = AARCH(ref) ^ AARCH(ip);
+            if (!diff) { ip+=STEPSIZE; ref+=STEPSIZE; continue; }
+            ip += LZ4_NbCommonBytes(diff);
+            goto _endCount;
+        }
+        if (LZ4_ARCH64) if ((ip<(matchlimit-3)) && (A32(ref) == A32(ip))) { ip+=4; ref+=4; }
+        if ((ip<(matchlimit-1)) && (A16(ref) == A16(ip))) { ip+=2; ref+=2; }
+        if ((ip<matchlimit) && (*ref == *ip)) ip++;
+_endCount:
+
+        // Encode MatchLength
+        len = (int)(ip - anchor);
+        if unlikely(op + (1 + LASTLITERALS) + (len>>8) > oend) return 0;               // Check output limit
+        if (len>=(int)ML_MASK) { *token+=ML_MASK; len-=ML_MASK; for(; len > 509 ; len-=510) { *op++ = 255; *op++ = 255; } if (len > 254) { len-=255; *op++ = 255; } *op++ = (BYTE)len; }
+        else *token += len;
+
+        // Test end of chunk
+        if (ip > mflimit) { anchor = ip;  break; }
+
+        // Fill table
+        HashTable[LZ4_HASH_VALUE(ip-2)] = ip - 2 - base;
+
+        // Test next position
+        ref = base + HashTable[LZ4_HASH_VALUE(ip)];
+        HashTable[LZ4_HASH_VALUE(ip)] = ip - base;
+        if ((ref > ip - (MAX_DISTANCE + 1)) && (A32(ref) == A32(ip))) { token = op++; *token=0; goto _next_match; }
+
+        // Prepare next loop
+        anchor = ip++;
+        forwardH = LZ4_HASH_VALUE(ip);
+    }
+
+_last_literals:
+    // Encode Last Literals
+    {
+        int lastRun = (int)(iend - anchor);
+        if (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize) return 0;
+        if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
+        else *op++ = (lastRun<<ML_BITS);
+        memcpy(op, anchor, iend - anchor);
+        op += iend-anchor;
+    }
+
+    // End
+    return (int) (((char*)op)-dest);
+}
+
+
+
+// Note : this function is valid only if isize < LZ4_64KLIMIT
+#define LZ4_64KLIMIT ((1<<16) + (MFLIMIT-1))
+#define HASHLOG64K (HASH_LOG+1)
+#define HASH64KTABLESIZE (1U<<HASHLOG64K)
+#define LZ4_HASH64K_FUNCTION(i)        (((i) * 2654435761U) >> ((MINMATCH*8)-HASHLOG64K))
+#define LZ4_HASH64K_VALUE(p)   LZ4_HASH64K_FUNCTION(A32(p))
+static inline int LZ4_compress64kCtx(void** ctx,
+                 const char* source,
+                 char* dest,
+                 int isize,
+                 int maxOutputSize)
+{
+#if HEAPMODE
+    struct refTables *srt = (struct refTables *) (*ctx);
+    U16* HashTable;
+#else
+    U16 HashTable[HASH64KTABLESIZE] = {0};
+#endif
+
+    const BYTE* ip = (BYTE*) source;
+    const BYTE* anchor = ip;
+    const BYTE* const base = ip;
+    const BYTE* const iend = ip + isize;
+    const BYTE* const mflimit = iend - MFLIMIT;
+#define matchlimit (iend - LASTLITERALS)
+
+    BYTE* op = (BYTE*) dest;
+    BYTE* const oend = op + maxOutputSize;
+
+    int len, length;
+    const int skipStrength = SKIPSTRENGTH;
+    U32 forwardH;
+
+
+    // Init
+    if (isize<MINLENGTH) goto _last_literals;
+#if HEAPMODE
+    if (*ctx == NULL)
+    {
+        srt = (struct refTables *) malloc ( sizeof(struct refTables) );
+        *ctx = (void*) srt;
+    }
+    HashTable = (U16*)(srt->hashTable);
+    memset((void*)HashTable, 0, sizeof(srt->hashTable));
+#else
+    (void) ctx;
+#endif
+
+
+    // First Byte
+    ip++; forwardH = LZ4_HASH64K_VALUE(ip);
+
+    // Main Loop
+    for ( ; ; )
+    {
+        int findMatchAttempts = (1U << skipStrength) + 3;
+        const BYTE* forwardIp = ip;
+        const BYTE* ref;
+        BYTE* token;
+
+        // Find a match
+        do {
+            U32 h = forwardH;
+            int step = findMatchAttempts++ >> skipStrength;
+            ip = forwardIp;
+            forwardIp = ip + step;
+
+            if (forwardIp > mflimit) { goto _last_literals; }
+
+            forwardH = LZ4_HASH64K_VALUE(forwardIp);
+            ref = base + HashTable[h];
+            HashTable[h] = (U16)(ip - base);
+
+        } while (A32(ref) != A32(ip));
+
+        // Catch up
+        while ((ip>anchor) && (ref>(BYTE*)source) && (ip[-1]==ref[-1])) { ip--; ref--; }
+
+        // Encode Literal length
+        length = (int)(ip - anchor);
+        token = op++;
+        if unlikely(op + length + (2 + 1 + LASTLITERALS) + (length>>8) > oend) return 0;               // Check output limit
+#ifdef _MSC_VER
+        if (length>=(int)RUN_MASK) 
+        { 
+            int len = length-RUN_MASK; 
+            *token=(RUN_MASK<<ML_BITS); 
+            if (len>254)
+            {
+                do { *op++ = 255; len -= 255; } while (len>254);
+                *op++ = (BYTE)len; 
+                memcpy(op, anchor, length);
+                op += length;
+                goto _next_match;
+            }
+            else
+            *op++ = (BYTE)len; 
+        }
+        else *token = (length<<ML_BITS);
+#else
+        if (length>=(int)RUN_MASK) { *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *op++ = 255; *op++ = (BYTE)len; }
+        else *token = (length<<ML_BITS);
+#endif
+
+        // Copy Literals
+        LZ4_BLINDCOPY(anchor, op, length);
+
+_next_match:
+        // Encode Offset
+        LZ4_WRITE_LITTLEENDIAN_16(op,(U16)(ip-ref));
+
+        // Start Counting
+        ip+=MINMATCH; ref+=MINMATCH;   // MinMatch verified
+        anchor = ip;
+        while (ip<matchlimit-(STEPSIZE-1))
+        {
+            UARCH diff = AARCH(ref) ^ AARCH(ip);
+            if (!diff) { ip+=STEPSIZE; ref+=STEPSIZE; continue; }
+            ip += LZ4_NbCommonBytes(diff);
+            goto _endCount;
+        }
+        if (LZ4_ARCH64) if ((ip<(matchlimit-3)) && (A32(ref) == A32(ip))) { ip+=4; ref+=4; }
+        if ((ip<(matchlimit-1)) && (A16(ref) == A16(ip))) { ip+=2; ref+=2; }
+        if ((ip<matchlimit) && (*ref == *ip)) ip++;
+_endCount:
+
+        // Encode MatchLength
+        len = (int)(ip - anchor);
+        if unlikely(op + (1 + LASTLITERALS) + (len>>8) > oend) return 0;               // Check output limit
+        if (len>=(int)ML_MASK) { *token+=ML_MASK; len-=ML_MASK; for(; len > 509 ; len-=510) { *op++ = 255; *op++ = 255; } if (len > 254) { len-=255; *op++ = 255; } *op++ = (BYTE)len; }
+        else *token += len;
+
+        // Test end of chunk
+        if (ip > mflimit) { anchor = ip;  break; }
+
+        // Fill table
+        HashTable[LZ4_HASH64K_VALUE(ip-2)] = (U16)(ip - 2 - base);
+
+        // Test next position
+        ref = base + HashTable[LZ4_HASH64K_VALUE(ip)];
+        HashTable[LZ4_HASH64K_VALUE(ip)] = (U16)(ip - base);
+        if (A32(ref) == A32(ip)) { token = op++; *token=0; goto _next_match; }
+
+        // Prepare next loop
+        anchor = ip++;
+        forwardH = LZ4_HASH64K_VALUE(ip);
+    }
+
+_last_literals:
+    // Encode Last Literals
+    {
+        int lastRun = (int)(iend - anchor);
+        if (op + lastRun + 1 + (lastRun-RUN_MASK+255)/255 > oend) return 0;
+        if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
+        else *op++ = (lastRun<<ML_BITS);
+        memcpy(op, anchor, iend - anchor);
+        op += iend-anchor;
+    }
+
+    // End
+    return (int) (((char*)op)-dest);
+}
+
+
+int LZ4_compress_limitedOutput(const char* source, 
+                               char* dest, 
+                               int isize, 
+                               int maxOutputSize)
+{
+#if HEAPMODE
+    void* ctx = malloc(sizeof(struct refTables));
+    int result;
+    if (isize < LZ4_64KLIMIT)
+        result = LZ4_compress64kCtx(&ctx, source, dest, isize, maxOutputSize);
+    else result = LZ4_compressCtx(&ctx, source, dest, isize, maxOutputSize);
+    free(ctx);
+    return result;
+#else
+    if (isize < (int)LZ4_64KLIMIT) return LZ4_compress64kCtx(NULL, source, dest, isize, maxOutputSize);
+    return LZ4_compressCtx(NULL, source, dest, isize, maxOutputSize);
+#endif
+}
+
+
+int LZ4_compress(const char* source,
+                 char* dest,
+                 int isize)
+{
+    return LZ4_compress_limitedOutput(source, dest, isize, LZ4_compressBound(isize));
+}
+
+
+
+
+//****************************
+// Decompression functions
+//****************************
+
+// Note : The decoding functions LZ4_uncompress() and LZ4_uncompress_unknownOutputSize()
+//             are safe against "buffer overflow" attack type.
+//             They will never write nor read outside of the provided output buffers.
+//      LZ4_uncompress_unknownOutputSize() also insures that it will never read outside of the input buffer.
+//             A corrupted input will produce an error result, a negative int, indicating the position of the error within input stream.
+
+int LZ4_uncompress(const char* source,
+                 char* dest,
+                 int osize)
+{
+    // Local Variables
+    const BYTE* restrict ip = (const BYTE*) source;
+    const BYTE* ref;
+
+    BYTE* op = (BYTE*) dest;
+    BYTE* const oend = op + osize;
+    BYTE* cpy;
+
+    BYTE token;
+
+    int        len, length;
+    size_t dec[] ={0, 3, 2, 3, 0, 0, 0, 0};
+
+
+    // Main Loop
+    while (1)
+    {
+        // get runlength
+        token = *ip++;
+        if ((length=(token>>ML_BITS)) == RUN_MASK)  { for (;(len=*ip++)==255;length+=255){} length += len; }
+
+        // copy literals
+        cpy = op+length;
+        if unlikely(cpy>oend-COPYLENGTH)
+        {
+            if (cpy != oend) goto _output_error;         // Error : we must necessarily stand at EOF
+            memcpy(op, ip, length);
+            ip += length;
+            break;                                       // EOF
+        }
+        LZ4_WILDCOPY(ip, op, cpy); ip -= (op-cpy); op = cpy;
+
+        // get offset
+        LZ4_READ_LITTLEENDIAN_16(ref,cpy,ip); ip+=2;
+        if (ref < (BYTE* const)dest) goto _output_error;   // Error : offset create reference outside destination buffer
+
+        // get matchlength
+        if ((length=(token&ML_MASK)) == ML_MASK) { for (;*ip==255;length+=255) {ip++;} length += *ip++; }
+
+        // copy repeated sequence
+        if unlikely(op-ref<STEPSIZE)
+        {
+#if LZ4_ARCH64
+            size_t dec2table[]={0, 0, 0, -1, 0, 1, 2, 3};
+            size_t dec2 = dec2table[op-ref];
+#else
+            const int dec2 = 0;
+#endif
+            *op++ = *ref++;
+            *op++ = *ref++;
+            *op++ = *ref++;
+            *op++ = *ref++;
+            ref -= dec[op-ref];
+            A32(op)=A32(ref); op += STEPSIZE-4;
+            ref -= dec2;
+        } else { LZ4_COPYSTEP(ref,op); }
+        cpy = op + length - (STEPSIZE-4);
+        if (cpy>oend-COPYLENGTH)
+        {
+            if (cpy > oend) goto _output_error;             // Error : request to write beyond destination buffer
+            LZ4_SECURECOPY(ref, op, (oend-COPYLENGTH));
+            while(op<cpy) *op++=*ref++;
+            op=cpy;
+            if (op == oend) goto _output_error;    // Check EOF (should never happen, since last 5 bytes are supposed to be literals)
+            continue;
+        }
+        LZ4_SECURECOPY(ref, op, cpy);
+        op=cpy;                // correction
+    }
+
+    // end of decoding
+    return (int) (((char*)ip)-source);
+
+    // write overflow error detected
+_output_error:
+    return (int) (-(((char*)ip)-source));
+}
+
+
+int LZ4_uncompress_unknownOutputSize(
+                const char* source,
+                char* dest,
+                int isize,
+                int maxOutputSize)
+{
+    // Local Variables
+    const BYTE* restrict ip = (const BYTE*) source;
+    const BYTE* const iend = ip + isize;
+    const BYTE* ref;
+
+    BYTE* op = (BYTE*) dest;
+    BYTE* const oend = op + maxOutputSize;
+    BYTE* cpy;
+
+    size_t dec[] ={0, 3, 2, 3, 0, 0, 0, 0};
+
+
+    // Main Loop
+    while (ip<iend)
+    {
+        BYTE token;
+        int length;
+
+        // get runlength
+        token = *ip++;
+        if ((length=(token>>ML_BITS)) == RUN_MASK) { int s=255; while ((ip<iend) && (s==255)) { s=*ip++; length += s; } }
+
+        // copy literals
+        cpy = op+length;
+        if ((cpy>oend-COPYLENGTH) || (ip+length>iend-COPYLENGTH))
+        {
+            if (cpy > oend) goto _output_error;          // Error : writes beyond output buffer
+            if (ip+length != iend) goto _output_error;   // Error : LZ4 format requires to consume all input at this stage
+            memcpy(op, ip, length);
+            op += length;
+            ip = iend;
+            break;                                       // Necessarily EOF, due to parsing restrictions
+        }
+        LZ4_WILDCOPY(ip, op, cpy); ip -= (op-cpy); op = cpy;
+
+        // get offset
+        LZ4_READ_LITTLEENDIAN_16(ref,cpy,ip); ip+=2;
+        if (ref < (BYTE* const)dest) goto _output_error;   // Error : offset creates reference outside of destination buffer
+
+        // get matchlength
+        if ((length=(token&ML_MASK)) == ML_MASK) { while (ip<iend) { int s = *ip++; length +=s; if (s==255) continue; break; } }
+
+        // copy repeated sequence
+        if unlikely(op-ref<STEPSIZE)
+        {
+#if LZ4_ARCH64
+            size_t dec2table[]={0, 0, 0, -1, 0, 1, 2, 3};
+            size_t dec2 = dec2table[op-ref];
+#else
+            const int dec2 = 0;
+#endif
+            *op++ = *ref++;
+            *op++ = *ref++;
+            *op++ = *ref++;
+            *op++ = *ref++;
+            ref -= dec[op-ref];
+            A32(op)=A32(ref); op += STEPSIZE-4;
+            ref -= dec2;
+        } else { LZ4_COPYSTEP(ref,op); }
+        cpy = op + length - (STEPSIZE-4);
+        if (cpy>oend-COPYLENGTH)
+        {
+            if (cpy > oend) goto _output_error;    // Error : request to write outside of destination buffer
+            LZ4_SECURECOPY(ref, op, (oend-COPYLENGTH));
+            while(op<cpy) *op++=*ref++;
+            op=cpy;
+            if (op == oend) goto _output_error;    // Check EOF (should never happen, since last 5 bytes are supposed to be literals)
+            continue;
+        }
+        LZ4_SECURECOPY(ref, op, cpy);
+        op=cpy;                // correction
+    }
+
+    // end of decoding
+    return (int) (((char*)op)-dest);
+
+    // write overflow error detected
+_output_error:
+    return (int) (-(((char*)ip)-source));
+}
+
diff --git a/src/static_deps/lz4/lz4.h b/src/static_deps/lz4/lz4.h
new file mode 100644 (file)
index 0000000..a6cf625
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+   LZ4 - Fast LZ compression algorithm
+   Header File
+   Copyright (C) 2011-2012, Yann Collet.
+   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+       * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+       * Redistributions in binary form must reproduce the above
+   copyright notice, this list of conditions and the following disclaimer
+   in the documentation and/or other materials provided with the
+   distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+   You can contact the author at :
+   - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
+   - LZ4 source repository : http://code.google.com/p/lz4/
+*/
+#pragma once
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+//**************************************
+// Compiler Options
+//**************************************
+#ifdef _MSC_VER   // Visual Studio
+#  define inline __inline           // Visual is not C99, but supports some kind of inline
+#endif
+
+
+//****************************
+// Simple Functions
+//****************************
+
+int LZ4_compress   (const char* source, char* dest, int isize);
+int LZ4_uncompress (const char* source, char* dest, int osize);
+
+/*
+LZ4_compress() :
+    Compresses 'isize' bytes from 'source' into 'dest'.
+    Destination buffer must be already allocated,
+    and must be sized to handle worst cases situations (input data not compressible)
+    Worst case size evaluation is provided by function LZ4_compressBound()
+
+    isize  : is the input size. Max supported value is ~1.9GB
+    return : the number of bytes written in buffer dest
+
+
+LZ4_uncompress() :
+    osize  : is the output size, therefore the original size
+    return : the number of bytes read in the source buffer
+             If the source stream is malformed, the function will stop decoding and return a negative result, indicating the byte position of the faulty instruction
+             This function never writes outside of provided buffers, and never modifies input buffer.
+    note : destination buffer must be already allocated.
+           its size must be a minimum of 'osize' bytes.
+*/
+
+
+//****************************
+// Advanced Functions
+//****************************
+
+static inline int LZ4_compressBound(int isize)   { return ((isize) + ((isize)/255) + 16); }
+#define           LZ4_COMPRESSBOUND(    isize)            ((isize) + ((isize)/255) + 16)
+
+/*
+LZ4_compressBound() :
+    Provides the maximum size that LZ4 may output in a "worst case" scenario (input data not compressible)
+    primarily useful for memory allocation of output buffer.
+       inline function is recommended for the general case,
+       but macro is also provided when results need to be evaluated at compile time (such as table size allocation).
+
+    isize  : is the input size. Max supported value is ~1.9GB
+    return : maximum output size in a "worst case" scenario
+    note : this function is limited by "int" range (2^31-1)
+*/
+
+
+int LZ4_compress_limitedOutput   (const char* source, char* dest, int isize, int maxOutputSize);
+
+/*
+LZ4_compress_limitedOutput() :
+    Compress 'isize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'.
+    If it cannot achieve it, compression will stop, and result of the function will be zero.
+    This function never writes outside of provided output buffer.
+
+    isize  : is the input size. Max supported value is ~1.9GB
+    maxOutputSize : is the size of the destination buffer (which must be already allocated)
+    return : the number of bytes written in buffer 'dest'
+             or 0 if the compression fails
+*/
+
+
+int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize);
+
+/*
+LZ4_uncompress_unknownOutputSize() :
+    isize  : is the input size, therefore the compressed size
+    maxOutputSize : is the size of the destination buffer (which must be already allocated)
+    return : the number of bytes decoded in the destination buffer (necessarily <= maxOutputSize)
+             If the source stream is malformed, the function will stop decoding and return a negative result, indicating the byte position of the faulty instruction
+             This function never writes beyond dest + maxOutputSize, and is therefore protected against malicious data packets
+    note   : Destination buffer must be already allocated.
+             This version is slightly slower than LZ4_uncompress()
+*/
+
+
+#if defined (__cplusplus)
+}
+#endif
diff --git a/src/static_deps/lz4/lz4hc.c b/src/static_deps/lz4/lz4hc.c
new file mode 100644 (file)
index 0000000..042aa43
--- /dev/null
@@ -0,0 +1,671 @@
+/*
+   LZ4 HC - High Compression Mode of LZ4
+   Copyright (C) 2011-2012, Yann Collet.
+   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+       * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+       * Redistributions in binary form must reproduce the above
+   copyright notice, this list of conditions and the following disclaimer
+   in the documentation and/or other materials provided with the
+   distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+   You can contact the author at :
+   - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
+   - LZ4 source repository : http://code.google.com/p/lz4/
+*/
+
+
+//**************************************
+// CPU Feature Detection
+//**************************************
+// 32 or 64 bits ?
+#if (defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64) || defined(__ppc64__) || defined(_WIN64) || defined(__LP64__) || defined(_LP64) )   // Detects 64 bits mode
+#define LZ4_ARCH64 1
+#else
+#define LZ4_ARCH64 0
+#endif
+
+// Little Endian or Big Endian ? 
+#if (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN) || defined(_ARCH_PPC) || defined(__PPC__) || defined(__PPC) || defined(PPC) || defined(__powerpc__) || defined(__powerpc) || defined(powerpc) || ((defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))) )
+#define LZ4_BIG_ENDIAN 1
+#else
+// Little Endian assumed. PDP Endian and other very rare endian format are unsupported.
+#endif
+
+// Unaligned memory access is automatically enabled for "common" CPU, such as x86.
+// For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected
+// If you know your target CPU supports unaligned memory access, you may want to force this option manually to improve performance
+#if defined(__ARM_FEATURE_UNALIGNED)
+#define LZ4_FORCE_UNALIGNED_ACCESS 1
+#endif
+
+
+//**************************************
+// Compiler Options
+//**************************************
+#if __STDC_VERSION__ >= 199901L    // C99
+  /* "restrict" is a known keyword */
+#else
+#define restrict  // Disable restrict
+#endif
+
+#ifdef _MSC_VER
+#define inline __forceinline    // Visual is not C99, but supports some kind of inline
+#include <intrin.h>             // For Visual 2005
+#  if LZ4_ARCH64       // 64-bit
+#    pragma intrinsic(_BitScanForward64) // For Visual 2005
+#    pragma intrinsic(_BitScanReverse64) // For Visual 2005
+#  else
+#    pragma intrinsic(_BitScanForward)   // For Visual 2005
+#    pragma intrinsic(_BitScanReverse)   // For Visual 2005
+#  endif
+#endif
+
+#ifdef _MSC_VER  // Visual Studio
+#define lz4_bswap16(x) _byteswap_ushort(x)
+#else
+#define lz4_bswap16(x)  ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8)))
+#endif
+
+
+//**************************************
+// Includes
+//**************************************
+#include <stdlib.h>   // calloc, free
+#include <string.h>   // memset, memcpy
+#include "lz4hc.h"
+
+#define ALLOCATOR(s) calloc(1,s)
+#define FREEMEM free
+#define MEM_INIT memset
+
+
+//**************************************
+// Basic Types
+//**************************************
+#if defined(_MSC_VER)    // Visual Studio does not support 'stdint' natively
+#define BYTE   unsigned __int8
+#define U16            unsigned __int16
+#define U32            unsigned __int32
+#define S32            __int32
+#define U64            unsigned __int64
+#else
+#include <stdint.h>
+#define BYTE   uint8_t
+#define U16            uint16_t
+#define U32            uint32_t
+#define S32            int32_t
+#define U64            uint64_t
+#endif
+
+#ifndef LZ4_FORCE_UNALIGNED_ACCESS
+#pragma pack(push, 1) 
+#endif
+
+typedef struct _U16_S { U16 v; } U16_S;
+typedef struct _U32_S { U32 v; } U32_S;
+typedef struct _U64_S { U64 v; } U64_S;
+
+#ifndef LZ4_FORCE_UNALIGNED_ACCESS
+#pragma pack(pop) 
+#endif
+
+#define A64(x) (((U64_S *)(x))->v)
+#define A32(x) (((U32_S *)(x))->v)
+#define A16(x) (((U16_S *)(x))->v)
+
+
+//**************************************
+// Constants
+//**************************************
+#define MINMATCH 4
+
+#define DICTIONARY_LOGSIZE 16
+#define MAXD (1<<DICTIONARY_LOGSIZE)
+#define MAXD_MASK ((U32)(MAXD - 1))
+#define MAX_DISTANCE (MAXD - 1)
+
+#define HASH_LOG (DICTIONARY_LOGSIZE-1)
+#define HASHTABLESIZE (1 << HASH_LOG)
+#define HASH_MASK (HASHTABLESIZE - 1)
+
+#define MAX_NB_ATTEMPTS 256
+
+#define ML_BITS  4
+#define ML_MASK  (size_t)((1U<<ML_BITS)-1)
+#define RUN_BITS (8-ML_BITS)
+#define RUN_MASK ((1U<<RUN_BITS)-1)
+
+#define COPYLENGTH 8
+#define LASTLITERALS 5
+#define MFLIMIT (COPYLENGTH+MINMATCH)
+#define MINLENGTH (MFLIMIT+1)
+#define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH)
+
+
+//**************************************
+// Architecture-specific macros
+//**************************************
+#if LZ4_ARCH64 // 64-bit
+#define STEPSIZE 8
+#define LZ4_COPYSTEP(s,d)              A64(d) = A64(s); d+=8; s+=8;
+#define LZ4_COPYPACKET(s,d)            LZ4_COPYSTEP(s,d)
+#define UARCH U64
+#define AARCH A64
+#define HTYPE                                  U32
+#define INITBASE(b,s)                  const BYTE* const b = s
+#else          // 32-bit
+#define STEPSIZE 4
+#define LZ4_COPYSTEP(s,d)              A32(d) = A32(s); d+=4; s+=4;
+#define LZ4_COPYPACKET(s,d)            LZ4_COPYSTEP(s,d); LZ4_COPYSTEP(s,d);
+#define UARCH U32
+#define AARCH A32
+#define HTYPE                                  const BYTE*
+#define INITBASE(b,s)              const int b = 0
+#endif
+
+#if defined(LZ4_BIG_ENDIAN)
+#define LZ4_READ_LITTLEENDIAN_16(d,s,p) { U16 v = A16(p); v = lz4_bswap16(v); d = (s) - v; }
+#define LZ4_WRITE_LITTLEENDIAN_16(p,i)  { U16 v = (U16)(i); v = lz4_bswap16(v); A16(p) = v; p+=2; }
+#else          // Little Endian
+#define LZ4_READ_LITTLEENDIAN_16(d,s,p) { d = (s) - A16(p); }
+#define LZ4_WRITE_LITTLEENDIAN_16(p,v)  { A16(p) = v; p+=2; }
+#endif
+
+
+//************************************************************
+// Local Types
+//************************************************************
+typedef struct 
+{
+       const BYTE* base;
+       HTYPE hashTable[HASHTABLESIZE];
+       U16 chainTable[MAXD];
+       const BYTE* nextToUpdate;
+} LZ4HC_Data_Structure;
+
+
+//**************************************
+// Macros
+//**************************************
+#define LZ4_WILDCOPY(s,d,e)            do { LZ4_COPYPACKET(s,d) } while (d<e);
+#define LZ4_BLINDCOPY(s,d,l)   { BYTE* e=d+l; LZ4_WILDCOPY(s,d,e); d=e; }
+#define HASH_FUNCTION(i)       (((i) * 2654435761U) >> ((MINMATCH*8)-HASH_LOG))
+#define HASH_VALUE(p)          HASH_FUNCTION(*(U32*)(p))
+#define HASH_POINTER(p)                (HashTable[HASH_VALUE(p)] + base)
+#define DELTANEXT(p)           chainTable[(size_t)(p) & MAXD_MASK] 
+#define GETNEXT(p)                     ((p) - (size_t)DELTANEXT(p))
+#define ADD_HASH(p)                    { size_t delta = (p) - HASH_POINTER(p); if (delta>MAX_DISTANCE) delta = MAX_DISTANCE; DELTANEXT(p) = (U16)delta; HashTable[HASH_VALUE(p)] = (p) - base; }
+
+
+//**************************************
+// Private functions
+//**************************************
+#if LZ4_ARCH64
+
+inline static int LZ4_NbCommonBytes (register U64 val)
+{
+#if defined(LZ4_BIG_ENDIAN)
+    #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    unsigned long r = 0;
+    _BitScanReverse64( &r, val );
+    return (int)(r>>3);
+    #elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    return (__builtin_clzll(val) >> 3); 
+    #else
+       int r;
+       if (!(val>>32)) { r=4; } else { r=0; val>>=32; }
+       if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
+       r += (!val);
+       return r;
+    #endif
+#else
+    #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    unsigned long r = 0;
+    _BitScanForward64( &r, val );
+    return (int)(r>>3);
+    #elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    return (__builtin_ctzll(val) >> 3); 
+    #else
+       static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
+       return DeBruijnBytePos[((U64)((val & -val) * 0x0218A392CDABBD3F)) >> 58];
+    #endif
+#endif
+}
+
+#else
+
+inline static int LZ4_NbCommonBytes (register U32 val)
+{
+#if defined(LZ4_BIG_ENDIAN)
+    #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    unsigned long r = 0;
+    _BitScanReverse( &r, val );
+    return (int)(r>>3);
+    #elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    return (__builtin_clz(val) >> 3); 
+    #else
+       int r;
+       if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
+       r += (!val);
+       return r;
+    #endif
+#else
+    #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    unsigned long r = 0;
+    _BitScanForward( &r, val );
+    return (int)(r>>3);
+    #elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    return (__builtin_ctz(val) >> 3); 
+    #else
+       static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
+       return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
+    #endif
+#endif
+}
+
+#endif
+
+
+inline static int LZ4HC_Init (LZ4HC_Data_Structure* hc4, const BYTE* base)
+{
+       MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable));
+       MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable));
+       hc4->nextToUpdate = base + LZ4_ARCH64;
+       hc4->base = base;
+       return 1;
+}
+
+
+inline static void* LZ4HC_Create (const BYTE* base)
+{
+       void* hc4 = ALLOCATOR(sizeof(LZ4HC_Data_Structure));
+
+       LZ4HC_Init (hc4, base);
+       return hc4;
+}
+
+
+inline static int LZ4HC_Free (void** LZ4HC_Data)
+{
+       FREEMEM(*LZ4HC_Data);
+       *LZ4HC_Data = NULL;
+       return (1);
+}
+
+
+inline static void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip)
+{
+       U16*   chainTable = hc4->chainTable;
+       HTYPE* HashTable  = hc4->hashTable;
+       INITBASE(base,hc4->base);
+
+       while(hc4->nextToUpdate < ip)
+       {
+               ADD_HASH(hc4->nextToUpdate);
+               hc4->nextToUpdate++;
+       }
+}
+
+
+inline static int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4, const BYTE* ip, const BYTE* const matchlimit, const BYTE** matchpos)
+{
+       U16* const chainTable = hc4->chainTable;
+       HTYPE* const HashTable = hc4->hashTable;
+       const BYTE* ref;
+       INITBASE(base,hc4->base);
+       int nbAttempts=MAX_NB_ATTEMPTS;
+       int ml=0;
+
+       // HC4 match finder
+       LZ4HC_Insert(hc4, ip);
+       ref = HASH_POINTER(ip);
+       while ((ref >= (ip-MAX_DISTANCE)) && (nbAttempts))
+       {
+               nbAttempts--;
+               if (*(ref+ml) == *(ip+ml))
+               if (*(U32*)ref == *(U32*)ip)
+               {
+                       const BYTE* reft = ref+MINMATCH;
+                       const BYTE* ipt = ip+MINMATCH;
+
+                       while (ipt<matchlimit-(STEPSIZE-1))
+                       {
+                               UARCH diff = AARCH(reft) ^ AARCH(ipt);
+                               if (!diff) { ipt+=STEPSIZE; reft+=STEPSIZE; continue; }
+                               ipt += LZ4_NbCommonBytes(diff);
+                               goto _endCount;
+                       }
+                       if (LZ4_ARCH64) if ((ipt<(matchlimit-3)) && (A32(reft) == A32(ipt))) { ipt+=4; reft+=4; }
+                       if ((ipt<(matchlimit-1)) && (A16(reft) == A16(ipt))) { ipt+=2; reft+=2; }
+                       if ((ipt<matchlimit) && (*reft == *ipt)) ipt++;
+_endCount:
+
+                       if (ipt-ip > ml) { ml = (int)(ipt-ip); *matchpos = ref; }
+               }
+               ref = GETNEXT(ref);
+       }
+
+       return ml;
+}
+
+
+inline static int LZ4HC_InsertAndGetWiderMatch (LZ4HC_Data_Structure* hc4, const BYTE* ip, const BYTE* startLimit, const BYTE* matchlimit, int longest, const BYTE** matchpos, const BYTE** startpos)
+{
+       U16* const  chainTable = hc4->chainTable;
+       HTYPE* const HashTable = hc4->hashTable;
+       INITBASE(base,hc4->base);
+       const BYTE*  ref;
+       int nbAttempts = MAX_NB_ATTEMPTS;
+       int delta = (int)(ip-startLimit);
+
+       // First Match
+       LZ4HC_Insert(hc4, ip);
+       ref = HASH_POINTER(ip);
+
+       while ((ref >= ip-MAX_DISTANCE) && (ref >= hc4->base) && (nbAttempts))
+       {
+               nbAttempts--;
+               if (*(startLimit + longest) == *(ref - delta + longest))
+               if (*(U32*)ref == *(U32*)ip)
+               {
+                       const BYTE* reft = ref+MINMATCH;
+                       const BYTE* ipt = ip+MINMATCH;
+                       const BYTE* startt = ip;
+
+                       while (ipt<matchlimit-(STEPSIZE-1))
+                       {
+                               UARCH diff = AARCH(reft) ^ AARCH(ipt);
+                               if (!diff) { ipt+=STEPSIZE; reft+=STEPSIZE; continue; }
+                               ipt += LZ4_NbCommonBytes(diff);
+                               goto _endCount;
+                       }
+                       if (LZ4_ARCH64) if ((ipt<(matchlimit-3)) && (A32(reft) == A32(ipt))) { ipt+=4; reft+=4; }
+                       if ((ipt<(matchlimit-1)) && (A16(reft) == A16(ipt))) { ipt+=2; reft+=2; }
+                       if ((ipt<matchlimit) && (*reft == *ipt)) ipt++;
+_endCount:
+
+                       reft = ref;
+                       while ((startt>startLimit) && (reft > hc4->base) && (startt[-1] == reft[-1])) {startt--; reft--;}
+
+                       if ((ipt-startt) > longest)
+                       {
+                               longest = (int)(ipt-startt);
+                               *matchpos = reft;
+                               *startpos = startt;
+                       }
+               }
+               ref = GETNEXT(ref);
+       }
+
+       return longest;
+}
+
+
+inline static int LZ4_encodeSequence(const BYTE** ip, BYTE** op, const BYTE** anchor, int ml, const BYTE* ref)
+{
+       int length, len; 
+       BYTE* token;
+
+       // Encode Literal length
+       length = (int)(*ip - *anchor);
+       token = (*op)++;
+       if (length>=(int)RUN_MASK) { *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *(*op)++ = 255;  *(*op)++ = (BYTE)len; } 
+       else *token = (length<<ML_BITS);
+
+       // Copy Literals
+       LZ4_BLINDCOPY(*anchor, *op, length);
+
+       // Encode Offset
+       LZ4_WRITE_LITTLEENDIAN_16(*op,(U16)(*ip-ref));
+
+       // Encode MatchLength
+       len = (int)(ml-MINMATCH);
+       if (len>=(int)ML_MASK) { *token+=ML_MASK; len-=ML_MASK; for(; len > 509 ; len-=510) { *(*op)++ = 255; *(*op)++ = 255; } if (len > 254) { len-=255; *(*op)++ = 255; } *(*op)++ = (BYTE)len; } 
+       else *token += len;     
+
+       // Prepare next loop
+       *ip += ml;
+       *anchor = *ip; 
+
+       return 0;
+}
+
+
+//****************************
+// Compression CODE
+//****************************
+
+int LZ4_compressHCCtx(LZ4HC_Data_Structure* ctx,
+                                const char* source, 
+                                char* dest,
+                                int isize)
+{      
+       const BYTE* ip = (const BYTE*) source;
+       const BYTE* anchor = ip;
+       const BYTE* const iend = ip + isize;
+       const BYTE* const mflimit = iend - MFLIMIT;
+       const BYTE* const matchlimit = (iend - LASTLITERALS);
+
+       BYTE* op = (BYTE*) dest;
+
+       int     ml, ml2, ml3, ml0;
+       const BYTE* ref=NULL;
+       const BYTE* start2=NULL;
+       const BYTE* ref2=NULL;
+       const BYTE* start3=NULL;
+       const BYTE* ref3=NULL;
+       const BYTE* start0;
+       const BYTE* ref0;
+
+       ip++;
+
+       // Main Loop
+       while (ip < mflimit)
+       {
+               ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, (&ref));
+               if (!ml) { ip++; continue; }
+
+               // saved, in case we would skip too much
+               start0 = ip;
+               ref0 = ref;
+               ml0 = ml;
+
+_Search2:
+               if (ip+ml < mflimit)
+                       ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 1, matchlimit, ml, &ref2, &start2);
+               else ml2=ml;
+
+               if (ml2 == ml)  // No better match
+               {
+                       LZ4_encodeSequence(&ip, &op, &anchor, ml, ref);
+                       continue;
+               }
+
+               if (start0 < ip)
+               {
+                       if (start2 < ip + ml0)   // empirical
+                       {
+                               ip = start0;
+                               ref = ref0;
+                               ml = ml0;
+                       }
+               }
+
+               // Here, start0==ip
+               if ((start2 - ip) < 3)   // First Match too small : removed
+               {
+                       ml = ml2;
+                       ip = start2;
+                       ref =ref2;
+                       goto _Search2;
+               }
+
+_Search3:
+               // Currently we have :
+               // ml2 > ml1, and
+               // ip1+3 <= ip2 (usually < ip1+ml1)
+               if ((start2 - ip) < OPTIMAL_ML)
+               {
+                       int correction;
+                       int new_ml = ml;
+                       if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML;
+                       if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH;
+                       correction = new_ml - (int)(start2 - ip);
+                       if (correction > 0)
+                       {
+                               start2 += correction;
+                               ref2 += correction;
+                               ml2 -= correction;
+                       }
+               }
+               // Now, we have start2 = ip+new_ml, with new_ml=min(ml, OPTIMAL_ML=18)
+
+               if (start2 + ml2 < mflimit)
+                       ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3);
+               else ml3=ml2;
+
+               if (ml3 == ml2) // No better match : 2 sequences to encode
+               {
+                       // ip & ref are known; Now for ml
+                       if (start2 < ip+ml)
+                       {
+                               if ((start2 - ip) < OPTIMAL_ML)
+                               {
+                                       int correction;
+                                       if (ml > OPTIMAL_ML) ml = OPTIMAL_ML;
+                                       if (ip+ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH;
+                                       correction = ml - (int)(start2 - ip);
+                                       if (correction > 0)
+                                       {
+                                               start2 += correction;
+                                               ref2 += correction;
+                                               ml2 -= correction;
+                                       }
+                               }
+                               else
+                               {
+                                       ml = (int)(start2 - ip);
+                               }
+                       }
+                       // Now, encode 2 sequences
+                       LZ4_encodeSequence(&ip, &op, &anchor, ml, ref);
+                       ip = start2;
+                       LZ4_encodeSequence(&ip, &op, &anchor, ml2, ref2);
+                       continue;
+               }
+
+               if (start3 < ip+ml+3) // Not enough space for match 2 : remove it
+               {
+                       if (start3 >= (ip+ml)) // can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1
+                       {
+                               if (start2 < ip+ml)
+                               {
+                                       int correction = (int)(ip+ml - start2);
+                                       start2 += correction;
+                                       ref2 += correction;
+                                       ml2 -= correction;
+                                       if (ml2 < MINMATCH)
+                                       {
+                                               start2 = start3;
+                                               ref2 = ref3;
+                                               ml2 = ml3;
+                                       }
+                               }
+
+                               LZ4_encodeSequence(&ip, &op, &anchor, ml, ref);
+                               ip  = start3;
+                               ref = ref3;
+                               ml  = ml3;
+
+                               start0 = start2;
+                               ref0 = ref2;
+                               ml0 = ml2;
+                               goto _Search2;
+                       }
+
+                       start2 = start3;
+                       ref2 = ref3;
+                       ml2 = ml3;
+                       goto _Search3;
+               }
+
+               // OK, now we have 3 ascending matches; let's write at least the first one
+               // ip & ref are known; Now for ml
+               if (start2 < ip+ml)
+               {
+                       if ((start2 - ip) < (int)ML_MASK)
+                       {
+                               int correction;
+                               if (ml > OPTIMAL_ML) ml = OPTIMAL_ML;
+                               if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH;
+                               correction = ml - (int)(start2 - ip);
+                               if (correction > 0)
+                               {
+                                       start2 += correction;
+                                       ref2 += correction;
+                                       ml2 -= correction;
+                               }
+                       }
+                       else
+                       {
+                               ml = (int)(start2 - ip);
+                       }
+               }
+               LZ4_encodeSequence(&ip, &op, &anchor, ml, ref);
+
+               ip = start2;
+               ref = ref2;
+               ml = ml2;
+
+               start2 = start3;
+               ref2 = ref3;
+               ml2 = ml3;
+
+               goto _Search3;
+
+       }
+
+       // Encode Last Literals
+       {
+               int lastRun = (int)(iend - anchor);
+               if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } 
+               else *op++ = (lastRun<<ML_BITS);
+               memcpy(op, anchor, iend - anchor);
+               op += iend-anchor;
+       } 
+
+       // End
+       return (int) (((char*)op)-dest);
+}
+
+
+int LZ4_compressHC(const char* source, 
+                                char* dest,
+                                int isize)
+{
+       void* ctx = LZ4HC_Create((const BYTE*)source);
+       int result = LZ4_compressHCCtx(ctx, source, dest, isize);
+       LZ4HC_Free (&ctx);
+
+       return result;
+}
+
+
diff --git a/src/static_deps/lz4/lz4hc.h b/src/static_deps/lz4/lz4hc.h
new file mode 100644 (file)
index 0000000..18be104
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+   LZ4 HC - High Compression Mode of LZ4
+   Header File
+   Copyright (C) 2011-2012, Yann Collet.
+   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+       * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+       * Redistributions in binary form must reproduce the above
+   copyright notice, this list of conditions and the following disclaimer
+   in the documentation and/or other materials provided with the
+   distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+   You can contact the author at :
+   - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
+   - LZ4 source repository : http://code.google.com/p/lz4/
+*/
+#pragma once
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+int LZ4_compressHC (const char* source, char* dest, int isize);
+
+/*
+LZ4_compressHC :
+       return : the number of bytes in compressed buffer dest
+       note : destination buffer must be already allocated. 
+               To avoid any problem, size it to handle worst cases situations (input data not compressible)
+               Worst case size evaluation is provided by function LZ4_compressBound() (see "lz4.h")
+*/
+
+
+/* Note :
+Decompression functions are provided within regular LZ4 source code (see "lz4.h") (BSD license)
+*/
+
+
+#if defined (__cplusplus)
+}
+#endif
diff --git a/src/static_deps/rg_etc/Makefile.am b/src/static_deps/rg_etc/Makefile.am
new file mode 100644 (file)
index 0000000..c281172
--- /dev/null
@@ -0,0 +1,4 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+EXTRA_DIST = rg_etc1.c rg_etc2.c etc2_encoder.c rg_etc1.h
+
diff --git a/src/static_deps/rg_etc/README b/src/static_deps/rg_etc/README
new file mode 100644 (file)
index 0000000..04b9c2b
--- /dev/null
@@ -0,0 +1,31 @@
+Copyright notice for rg_etc1.
+
+rg-etc1 has been originally written by Rich Geldreich <richgel99@gmail.com>
+in C++ and then converted to plain C by the EFL team to fit the rest of
+the EFL.
+
+The original code comes from:
+https://code.google.com/p/rg-etc1/
+
+For the ZLIB license below, see http://opensource.org/licenses/Zlib
+
+Copyright (c) 2012 Rich Geldreich
+
+This software is provided 'as-is', without any express or implied
+warranty.  In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+claim that you wrote the original software. If you use this software
+in a product, an acknowledgment in the product documentation would be
+appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and must not be
+misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source distribution.
+
diff --git a/src/static_deps/rg_etc/etc2_encoder.c b/src/static_deps/rg_etc/etc2_encoder.c
new file mode 100644 (file)
index 0000000..60f167a
--- /dev/null
@@ -0,0 +1,1052 @@
+/*
+Copyright (C) 2014 Jean-Philippe ANDRE
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <Eina.h>
+#include "rg_etc1.h"
+
+// Enable this flag when working on (quality) optimizations
+//#define DEBUG
+
+#ifndef EINA_INLIST_FREE
+/**
+ * @def EINA_INLIST_FREE
+ * @param list The list to free.
+ * @param it The pointer to the list item, i.e. a pointer to each item
+ * that is part of the list.
+ *
+ * NOTE: it is the duty of the body loop to properly remove the item from the
+ * inlist and free it. This function will turn into a infinite loop if you
+ * don't remove all items from the list.
+ * @since 1.8
+ */
+#define EINA_INLIST_FREE(list, it)                              \
+  for (it = (__typeof__(it)) list; list; it = (__typeof__(it)) list)
+#endif
+
+// Weights for the distance (perceptual mode) - sum is ~1024
+static const int R_WEIGHT = 299 * 1024 / 1000;
+static const int G_WEIGHT = 587 * 1024 / 1000;
+static const int B_WEIGHT = 114 * 1024 / 1000;
+
+static const int kTargetError[3] = {
+   5*5*16, // 34 dB
+   2*2*16, // 42 dB
+   0 // infinite dB
+};
+
+// For T and H modes
+static const int kDistances[8] = {
+   3, 6, 11, 16, 23, 32, 41, 64
+};
+
+// For differential mode
+static const int kSigned3bit[8] = {
+   0, 1, 2, 3, -4, -3, -2, -1
+};
+
+// For alpha support
+static const int kAlphaModifiers[16][8] = {
+   {  -3,  -6,  -9,  -15,  2,  5,  8,  14},
+   {  -3,  -7, -10,  -13,  2,  6,  9,  12},
+   {  -2,  -5,  -8,  -13,  1,  4,  7,  12},
+   {  -2,  -4,  -6,  -13,  1,  3,  5,  12},
+   {  -3,  -6,  -8,  -12,  2,  5,  7,  11},
+   {  -3,  -7,  -9,  -11,  2,  6,  8,  10},
+   {  -4,  -7,  -8,  -11,  3,  6,  7,  10},
+   {  -3,  -5,  -8,  -11,  2,  4,  7,  10},
+   {  -2,  -6,  -8,  -10,  1,  5,  7,   9},
+   {  -2,  -5,  -8,  -10,  1,  4,  7,   9},
+   {  -2,  -4,  -8,  -10,  1,  3,  7,   9},
+   {  -2,  -5,  -7,  -10,  1,  4,  6,   9},
+   {  -3,  -4,  -7,  -10,  2,  3,  6,   9},
+   {  -1,  -2,  -3,  -10,  0,  1,  2,   9},
+   {  -4,  -6,  -8,   -9,  3,  5,  7,   8},
+   {  -3,  -5,  -7,   -9,  2,  4,  6,   8}
+};
+
+// Damn OpenGL people, why don't you just pack data as on a CPU???
+static const int kBlockWalk[16] = {
+   0, 4,  8, 12,
+   1, 5,  9, 13,
+   2, 6, 10, 14,
+   3, 7, 11, 15
+};
+
+// Use with static constants so the compiler can optimize everything
+#define BITS(byteval, lowbit, highbit) \
+   (((byteval) >> (lowbit)) & ((1 << ((highbit) - (lowbit) + 1)) - 1))
+
+#define BIT(byteval, bit) \
+   (((byteval) >> (bit)) & 0x1)
+
+// Real clamp
+#define CLAMP(a) ({ int _b = (a); (((_b) >= 0) ? (((_b) < 256) ? (_b) : 255) : 0); })
+
+// Simple min
+#define MIN(a,b) ({ int _z = (a), _y = (b); ((_z <= _y) ? _z : _y); })
+
+// Simple max
+#define MAX(a,b) ({ int __z = (a), __y = (b); ((__z > __y) ? __z : __y); })
+
+// Simple clamp between two values
+#define MINMAX(a,b,c) (MIN(c,MAX(a,b)))
+
+// Simple abs
+#define ABS(a) ({ int _a = (a); ((_a >= 0) ? _a : (-_a)); })
+
+// Write a BGRA value for output to Evas
+#define BGRA(r,g,b,a) ((a << 24) | (r << 16) | (g << 8) | b)
+
+#ifndef WORDS_BIGENDIAN
+/* x86 */
+#define A_VAL(p) (((uint8_t *)(p))[3])
+#define R_VAL(p) (((uint8_t *)(p))[2])
+#define G_VAL(p) (((uint8_t *)(p))[1])
+#define B_VAL(p) (((uint8_t *)(p))[0])
+#define R_IDX 2
+#define G_IDX 1
+#define B_IDX 0
+#else
+/* ppc */
+#define A_VAL(p) (((uint8_t *)(p))[0])
+#define R_VAL(p) (((uint8_t *)(p))[1])
+#define G_VAL(p) (((uint8_t *)(p))[2])
+#define B_VAL(p) (((uint8_t *)(p))[3])
+#define R_IDX 1
+#define G_IDX 2
+#define B_IDX 3
+#endif
+
+#ifndef DBG
+# ifdef DEBUG
+#  define DBG(fmt, ...) fprintf(stderr, "%s:%d: " fmt "\n", __FUNCTION__, __LINE__, ## __VA_ARGS__)
+# else
+#  define DBG(...)
+# endif
+#endif
+
+/** Pack alpha block given a modifier table and a multiplier
+ * @returns Squared error
+ */
+static int
+_etc2_alpha_block_pack(uint8_t *etc2_alpha,
+                       const int base_codeword,
+                       const int multiplier,
+                       const int modifierIdx,
+                       const uint32_t *bgra,
+                       const Eina_Bool write)
+{
+   const int *alphaModifiers = kAlphaModifiers[modifierIdx];
+   uint8_t alphaIndexes[16];
+   int errAcc2 = 0;
+
+   // Header
+   if (write)
+     {
+        etc2_alpha[0] = base_codeword & 0xFF;
+        etc2_alpha[1] = ((multiplier << 4) & 0xF0) | (modifierIdx & 0x0F);
+     }
+
+   // Compute alphas now
+   for (int i = 0; i < 16; i++)
+     {
+        const int realA = A_VAL(bgra + kBlockWalk[i]);
+        int minErr = INT_MAX, idx = 0;
+
+        // Brute force -- find modifier index
+        for (int k = 0; (k < 8) && minErr; k++)
+          {
+             int tryA = CLAMP(base_codeword + alphaModifiers[k] * multiplier);
+             int err = ABS(realA - tryA);
+             if (err < minErr)
+               {
+                  minErr = err;
+                  idx = k;
+                  if (!minErr) break;
+               }
+          }
+
+        alphaIndexes[i] = idx;
+
+        // Keep some stats
+        errAcc2 += minErr * minErr;
+     }
+
+   if (write)
+     for (int k = 0; k < 2; k++)
+       {
+          etc2_alpha[2 + 3 * k]  =  alphaIndexes[0 + 8 * k] << 5;        // A
+          etc2_alpha[2 + 3 * k] |=  alphaIndexes[1 + 8 * k] << 2;        // B
+          etc2_alpha[2 + 3 * k] |= (alphaIndexes[2 + 8 * k] >> 1) & 0x3; // C01
+          etc2_alpha[3 + 3 * k]  = (alphaIndexes[2 + 8 * k] & 0x1) << 7; // C2
+          etc2_alpha[3 + 3 * k] |=  alphaIndexes[3 + 8 * k] << 4;        // D
+          etc2_alpha[3 + 3 * k] |=  alphaIndexes[4 + 8 * k] << 1;        // E
+          etc2_alpha[3 + 3 * k] |= (alphaIndexes[5 + 8 * k] >> 2) & 0x1; // F0
+          etc2_alpha[4 + 3 * k]  = (alphaIndexes[5 + 8 * k] & 0x3) << 6; // F12
+          etc2_alpha[4 + 3 * k] |=  alphaIndexes[6 + 8 * k] << 3;        // G
+          etc2_alpha[4 + 3 * k] |=  alphaIndexes[7 + 8 * k];             // H
+       }
+
+   return errAcc2;
+}
+
+static int
+_etc2_alpha_encode(uint8_t *etc2_alpha, const uint32_t *bgra,
+                   const rg_etc1_pack_params *params)
+{
+   int alphas[16], avg = 0, diff = 0, maxDiff = 0, minErr = INT_MAX;
+   int base_codeword;
+   int multiplier, bestMult = 0;
+   int modifierIdx, bestIdx = 0, bestBase = 128;
+   int err, base_range, base_step = 1, max_error = 0;
+
+   // Try to select the best alpha value (avg)
+   for (int i = 0; i < 16; i++)
+     {
+        alphas[i] = A_VAL(bgra + kBlockWalk[i]);
+        avg += alphas[i];
+     }
+   avg /= 16;
+
+   for (int i = 0; i < 16; i++)
+     {
+        int thisDiff = ABS(alphas[i] - avg);
+        maxDiff = MAX(thisDiff, maxDiff);
+        diff += thisDiff;
+     }
+
+   base_codeword = alphas[0];
+   if (!diff)
+     {
+        // All same alphas
+        etc2_alpha[0] = base_codeword;
+        memset(etc2_alpha + 1, 0, 7);
+        return 0;
+     }
+
+   // Bruteforce -- try all tables and all multipliers, oh my god this will be slow.
+   max_error = kTargetError[params->m_quality];
+   switch (params->m_quality)
+     {
+      // The follow parameters are completely arbitrary.
+      // Need some real testing.
+      case rg_etc1_high_quality: // exhaustive search
+        base_range = 255;
+        base_step = 1;
+        break;
+      case rg_etc1_medium_quality: // tweaked for "decent" results
+        base_range = 40;
+        base_step = 4;
+        break;
+      case rg_etc1_low_quality: // fast (not even fastest)
+        base_range = 8;
+        base_step = 4;
+        break;
+     }
+
+   // for loop avg, avg-1, avg+1, avg-2, avg+2, ...
+   for (int step = 0; step < base_range; step += base_step)
+     for (base_codeword = CLAMP(avg - step);
+          base_codeword <= CLAMP(avg + step);)
+       {
+          for (modifierIdx = 0; modifierIdx < 16; modifierIdx++)
+            for (multiplier = 0; multiplier < 16; multiplier++)
+              {
+                 if ((ABS(multiplier * kAlphaModifiers[modifierIdx][3]) + ABS(base_codeword - avg)) < maxDiff)
+                   continue;
+
+                 err = _etc2_alpha_block_pack(etc2_alpha, base_codeword,
+                                              multiplier, modifierIdx, bgra, EINA_FALSE);
+                 if (err < minErr)
+                   {
+                      minErr = err;
+                      bestMult = multiplier;
+                      bestIdx = modifierIdx;
+                      bestBase = base_codeword;
+                      if (err <= max_error)
+                        goto pack_now;
+
+                   }
+              }
+          if (step <= 0) break;
+          if (base_codeword < 255)
+            base_codeword = CLAMP(base_codeword + 2 * step);
+          else
+            break;
+       }
+
+pack_now:
+   err = _etc2_alpha_block_pack(etc2_alpha, bestBase,
+                                bestMult, bestIdx, bgra, EINA_TRUE);
+   return err;
+}
+
+static Eina_Bool
+_etc2_t_mode_header_pack(uint8_t *etc2,
+                         uint32_t color1, uint32_t color2, int distance)
+{
+   // 4 bit colors
+   int r1_4 = R_VAL(&color1) >> 4;
+   int g1_4 = G_VAL(&color1) >> 4;
+   int b1_4 = B_VAL(&color1) >> 4;
+   int r2_4 = R_VAL(&color2) >> 4;
+   int g2_4 = G_VAL(&color2) >> 4;
+   int b2_4 = B_VAL(&color2) >> 4;
+   int distanceIdx, R, dR;
+
+   for (distanceIdx = 0; distanceIdx < 8; distanceIdx++)
+     if (kDistances[distanceIdx] == distance) break;
+
+   if (distanceIdx >= 8)
+     return EINA_FALSE;
+
+   // R1. R + [dR] must be outside [0..31]. Scanning all values. Not smart.
+   R  = r1_4 >> 2;
+   dR = r1_4 & 0x3;
+   for (int Rx = 0; Rx < 8; Rx++)
+     for (int dRx = 0; dRx < 2; dRx++)
+       {
+          int Rtry = R | (Rx << 2);
+          int dRtry = dR | (dRx << 2);
+          if ((Rtry + kSigned3bit[dRtry]) < 0 || (Rtry + kSigned3bit[dRtry] > 31))
+            {
+               R = Rtry;
+               dR = dRtry;
+               break;
+            }
+       }
+   if ((R + kSigned3bit[dR]) >= 0 && (R + kSigned3bit[dR] <= 31))
+     // this can't happen, should be an assert
+     return EINA_FALSE;
+
+   etc2[0] = ((R & 0x1F) << 3) | (dR & 0x7);
+
+   // G1, B1
+   etc2[1] = (g1_4 << 4) | b1_4;
+
+   // R2, G2
+   etc2[2] = (r2_4 << 4) | g2_4;
+
+   // B2, distance
+   etc2[3] = (b2_4 << 4) | ((distanceIdx >> 1) << 2) | (1 << 1) | (distanceIdx & 0x1);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_etc2_h_mode_header_pack(uint8_t *etc2, Eina_Bool *swap_colors,
+                         uint32_t color1, uint32_t color2, int distance)
+{
+   int distanceIdx, R, dR, G, dG, distanceSpecialBit, da, db;
+   int r1_4, g1_4, b1_4, r2_4, g2_4, b2_4;
+   uint32_t c1, c2;
+
+   for (distanceIdx = 0; distanceIdx < 8; distanceIdx++)
+     if (kDistances[distanceIdx] == distance) break;
+
+   if (distanceIdx >= 8)
+     return EINA_FALSE;
+
+   // The distance is coded in 3 bits. But in H mode, one bit is not coded
+   // in the header, as we use the comparison result between the two colors
+   // to select it.
+   distanceSpecialBit = BIT(distanceIdx, 0);
+   db = BIT(distanceIdx, 1);
+   da = BIT(distanceIdx, 2);
+
+   // Note: if c1 == c2, no big deal because H is not the best choice of mode
+   if (distanceSpecialBit)
+     {
+        c1 = MAX(color1, color2);
+        c2 = MIN(color1, color2);
+     }
+   else
+     {
+        c1 = MIN(color1, color2);
+        c2 = MAX(color1, color2);
+     }
+
+   // Return flag so we use the proper colors when packing the block
+   *swap_colors = (c1 != color1);
+
+   // 4 bit colors
+   r1_4 = R_VAL(&c1) >> 4;
+   g1_4 = G_VAL(&c1) >> 4;
+   b1_4 = B_VAL(&c1) >> 4;
+   r2_4 = R_VAL(&c2) >> 4;
+   g2_4 = G_VAL(&c2) >> 4;
+   b2_4 = B_VAL(&c2) >> 4;
+
+   // R1 + G1a. R + [dR] must be inside [0..31]. Scanning all values. Not smart.
+   R  = r1_4;
+   dR = g1_4 >> 1;
+   if ((R + kSigned3bit[dR]) < 0 || (R + kSigned3bit[dR] > 31))
+     R |= (1 << 4);
+
+   if ((R + kSigned3bit[dR]) < 0 || (R + kSigned3bit[dR] > 31))
+     return EINA_FALSE; // wtf?
+
+   etc2[0] = ((R & 0x1F) << 3) | (dR & 0x7);
+
+   // G1b + B1a + B1b[2 msb]. G + dG must be outside the range.
+   G  = (g1_4 & 0x1) << 1;
+   G |= BIT(b1_4, 3);
+   dG = BITS(b1_4, 1, 2);
+   for (int Gx = 0; Gx < 8; Gx++)
+     for (int dGx = 0; dGx < 2; dGx++)
+       {
+          int Gtry = G | (Gx << 2);
+          int dGtry = dG | (dGx << 2);
+          if ((Gtry + kSigned3bit[dGtry]) < 0 || (Gtry + kSigned3bit[dGtry] > 31))
+            {
+               G = Gtry;
+               dG = dGtry;
+               break;
+            }
+       }
+
+   if ((G + kSigned3bit[dG]) >= 0 && (G + kSigned3bit[dG] <= 31))
+     return EINA_FALSE; // wtf?
+
+   etc2[1] = ((G & 0x1F) << 3) | (dG & 0x7);
+
+   // B1[lsb] + R2 + G2 [3 msb]
+   etc2[2] = ((b1_4 & 0x1) << 7) | (r2_4 << 3) | (g2_4 >> 1);
+
+   // G2[lsb] + B2 + distance
+   etc2[3] = ((g2_4 & 0x1) << 7) | (b2_4 << 3)
+         | (da << 2) | 0x2 | db;
+
+   return EINA_TRUE;
+}
+
+static inline int
+_rgb_distance_percept(uint32_t color1, uint32_t color2)
+{
+   int R = R_VAL(&color1) - R_VAL(&color2);
+   int G = G_VAL(&color1) - G_VAL(&color2);
+   int B = B_VAL(&color1) - B_VAL(&color2);
+   return (R * R * R_WEIGHT) + (G * G * G_WEIGHT) + (B * B * B_WEIGHT);
+}
+
+static inline int
+_rgb_distance_euclid(uint32_t color1, uint32_t color2)
+{
+   int R = R_VAL(&color1) - R_VAL(&color2);
+   int G = G_VAL(&color1) - G_VAL(&color2);
+   int B = B_VAL(&color1) - B_VAL(&color2);
+   return (R * R) + (G * G) + (B * B);
+}
+
+static unsigned int
+_etc2_th_mode_block_pack(uint8_t *etc2, Eina_Bool h_mode,
+                         uint32_t color1, uint32_t color2, int distance,
+                         const uint32_t *bgra, Eina_Bool write,
+                         Eina_Bool *swap_colors)
+{
+   uint8_t paint_colors[4][4];
+   int errAcc = 0;
+
+   if (write)
+     {
+        memset(etc2 + 4, 0, 4);
+        if (!h_mode)
+          {
+             if (!_etc2_t_mode_header_pack(etc2, color1, color2, distance))
+               return INT_MAX; // assert
+          }
+        else
+          {
+             if (!_etc2_h_mode_header_pack(etc2, swap_colors,
+                                           color1, color2, distance))
+               return INT_MAX; // assert
+             if (*swap_colors)
+               {
+                  uint32_t tmp = color1;
+                  color1 = color2;
+                  color2 = tmp;
+               }
+          }
+     }
+
+   for (int k = 0; k < 4; k++)
+     {
+        if (!h_mode)
+          {
+             paint_colors[0][k] = ((uint8_t *) &color1)[k];
+             paint_colors[1][k] = CLAMP(((uint8_t *) &color2)[k] + distance);
+             paint_colors[2][k] = ((uint8_t *) &color2)[k];
+             paint_colors[3][k] = CLAMP(((uint8_t *) &color2)[k] - distance);
+          }
+        else
+          {
+             paint_colors[0][k] = CLAMP(((uint8_t *) &color1)[k] + distance);
+             paint_colors[1][k] = CLAMP(((uint8_t *) &color1)[k] - distance);
+             paint_colors[2][k] = CLAMP(((uint8_t *) &color2)[k] + distance);
+             paint_colors[3][k] = CLAMP(((uint8_t *) &color2)[k] - distance);
+          }
+     }
+
+   for (int k = 0; k < 16; k++)
+     {
+        uint32_t pixel = bgra[kBlockWalk[k]];
+        int bestDist = INT_MAX;
+        int bestIdx = 0;
+
+        for (int idx = 0; idx < 4; idx++)
+          {
+             int dist = _rgb_distance_euclid(pixel, *((uint32_t *) paint_colors[idx]));
+             if (dist < bestDist)
+               {
+                  bestDist = dist;
+                  bestIdx = idx;
+                  if (!dist) break;
+               }
+          }
+
+        errAcc += bestDist;
+
+        if (write)
+          {
+             etc2[5 - (k >> 3)] |= ((bestIdx & 0x2) ? 1 : 0) << (k & 0x7);
+             etc2[7 - (k >> 3)] |= (bestIdx & 0x1) << (k & 0x7);
+          }
+     }
+
+   return errAcc;
+}
+
+static uint32_t
+_color_reduce_444(uint32_t color)
+{
+   int R = R_VAL(&color);
+   int G = G_VAL(&color);
+   int B = B_VAL(&color);
+   int R1, R2, G1, G2, B1, B2;
+
+   R1 = (R & 0xF0) | (R >> 4);
+   R2 = ((R & 0xF0) + 0x10) | ((R >> 4) + 1);
+   G1 = (G & 0xF0) | (G >> 4);
+   G2 = ((G & 0xF0) + 0x10) | ((G >> 4) + 1);
+   B1 = (B & 0xF0) | (B >> 4);
+   B2 = ((B & 0xF0) + 0x10) | ((B >> 4) + 1);
+
+   R = (ABS(R - R1) <= ABS(R - R2)) ? R1 : R2;
+   G = (ABS(G - G1) <= ABS(G - G2)) ? G1 : G2;
+   B = (ABS(B - B1) <= ABS(B - B2)) ? B1 : B2;
+
+   return BGRA(R, G, B, 255);
+}
+
+static uint32_t
+_color_reduce_676(uint32_t color)
+{
+   int R = R_VAL(&color);
+   int G = G_VAL(&color);
+   int B = B_VAL(&color);
+   int R1, G1, B1;
+
+   // FIXME: Do we have better candidates to try?
+   R1 = (R & 0xFC) | (R >> 6);
+   G1 = (G & 0xFE) | (G >> 7);
+   B1 = (B & 0xFC) | (B >> 6);
+
+   return BGRA(R1, G1, B1, 255);
+}
+
+static int
+_block_main_colors_find(uint32_t *color1_out, uint32_t *color2_out,
+                        uint32_t color1, uint32_t color2, const uint32_t *bgra,
+                        const rg_etc1_pack_params *params EINA_UNUSED)
+{
+   static const int kMaxIterations = 20;
+
+   int errAcc;
+
+   /* k-means complexity is O(n^(d.k+1) log n)
+    * In this case, n = 16, k = 2, d = 3 so 20 loops
+    */
+
+   if (color1 == color2)
+     {
+        // We should select another mode (planar) to encode flat colors
+        // We could also dither with two approximated colors
+        *color1_out = *color2_out = color1;
+        goto found;
+     }
+
+   if (color1 == color2)
+     {
+        // We should dither...
+        *color1_out = *color2_out = color1;
+        goto found;
+     }
+
+   for (int iter = 0; iter < kMaxIterations; iter++)
+     {
+        int r1 = 0, r2 = 0, g1 = 0, g2 = 0, b1 = 0, b2 = 0;
+        int cluster1_cnt = 0, cluster2_cnt = 0;
+        int cluster1[16], cluster2[16];
+        int maxDist1 = 0, maxDist2 = 0;
+        uint32_t c1, c2;
+
+        errAcc = 0;
+        memset(cluster1, 0, sizeof(cluster1));
+        memset(cluster2, 0, sizeof(cluster2));
+
+        // k-means assignment step
+        for (int k = 0; k < 16; k++)
+          {
+             int dist1 = _rgb_distance_euclid(color1, bgra[k]);
+             int dist2 = _rgb_distance_euclid(color2, bgra[k]);
+             if (dist1 <= dist2)
+               {
+                  cluster1[cluster1_cnt++] = k;
+                  if (dist1 > maxDist1)
+                    maxDist1 = dist1;
+               }
+             else
+               {
+                  cluster2[cluster2_cnt++] = k;
+                  if (dist2 > maxDist2)
+                    maxDist2 = dist2;
+               }
+          }
+
+        // k-means failed
+        if (!cluster1_cnt || !cluster2_cnt)
+          return -1;
+
+        // k-means update step
+        for (int k = 0; k < cluster1_cnt; k++)
+          {
+             r1 += R_VAL(bgra + cluster1[k]);
+             g1 += G_VAL(bgra + cluster1[k]);
+             b1 += B_VAL(bgra + cluster1[k]);
+          }
+
+        for (int k = 0; k < cluster2_cnt; k++)
+          {
+             r2 += R_VAL(bgra + cluster2[k]);
+             g2 += G_VAL(bgra + cluster2[k]);
+             b2 += B_VAL(bgra + cluster2[k]);
+          }
+
+        r1 /= cluster1_cnt;
+        g1 /= cluster1_cnt;
+        b1 /= cluster1_cnt;
+        r2 /= cluster2_cnt;
+        g2 /= cluster2_cnt;
+        b2 /= cluster2_cnt;
+
+        c1 = _color_reduce_444(BGRA(r1, g1, b1, 255));
+        c2 = _color_reduce_444(BGRA(r2, g2, b2, 255));
+        if (c1 == color1 && c2 == color2)
+          break;
+
+        if (c1 != c2)
+          {
+             color1 = c1;
+             color2 = c2;
+          }
+        else if (_rgb_distance_euclid(c1, color1) > _rgb_distance_euclid(c2, color2))
+          {
+             color1 = c1;
+          }
+        else
+          {
+             color2 = c2;
+          }
+     }
+
+   *color1_out = color1;
+   *color2_out = color2;
+
+found:
+   errAcc = 0;
+   for (int k = 0; k < 16; k++)
+     errAcc += _rgb_distance_euclid(bgra[k], color2);
+   return errAcc;
+}
+
+static unsigned int
+_etc2_th_mode_block_encode(uint8_t *etc2, const uint32_t *bgra,
+                           const rg_etc1_pack_params *params)
+{
+   int err, bestDist = kDistances[0];
+   int minErr = INT_MAX, bestMode = 0;
+   uint32_t c1, c2, bestC1 = bgra[0], bestC2 = bgra[1];
+   Eina_Bool swap_colors = EINA_FALSE;
+
+   Eina_Inlist *tried_pairs = NULL;
+   struct ColorPair {
+      EINA_INLIST;
+      uint32_t low;
+      uint32_t high;
+   };
+   struct ColorPair *pair;
+
+   /* Bruteforce algo:
+    * Bootstrap k-means clustering with all possible pairs of colors
+    * from the 4x4 block.
+    * TODO: Don't retry the same rgb444 pairs again
+    */
+
+   for (int pix1 = 0; pix1 < 15; pix1++)
+     for (int pix2 = pix1 + 1; pix2 < 16; pix2++)
+       {
+          Eina_Bool already_tried = EINA_FALSE;
+
+          // Bootstrap k-means. Find new pair of colors.
+          c1 = _color_reduce_444(bgra[pix1]);
+          c2 = _color_reduce_444(bgra[pix2]);
+
+          if (c2 > c1)
+            {
+               uint32_t tmp = c2;
+               c2 = c1;
+               c1 = tmp;
+            }
+
+          EINA_INLIST_FOREACH(tried_pairs, pair)
+            if (c1 == pair->high && c2 == pair->low)
+              {
+                 already_tried = EINA_TRUE;
+                 break;
+              }
+
+          if (already_tried)
+            continue;
+
+          pair = calloc(1, sizeof(*pair));
+          if (pair)
+            {
+               pair->high = c1;
+               pair->low = c2;
+               tried_pairs = eina_inlist_append(tried_pairs, EINA_INLIST_GET(pair));
+            }
+
+          // Run k-means
+          err = _block_main_colors_find(&c1, &c2, c1, c2, bgra, params);
+          if (err < 0)
+            continue;
+
+          for (int distIdx = 0; distIdx < 8; distIdx++)
+            {
+               for (int mode = 0; mode < 2; mode++)
+                 {
+
+                    for (int swap = 0; swap < 2; swap++)
+                      {
+                         if (mode == 0 && swap)
+                           {
+                              uint32_t tmp = c2;
+                              c2 = c1;
+                              c1 = tmp;
+                           }
+                         err = _etc2_th_mode_block_pack(etc2, mode, c1, c2,
+                                                        kDistances[distIdx],
+                                                        bgra, EINA_FALSE,
+                                                        &swap_colors);
+                         if (err < minErr)
+                           {
+                              bestDist = kDistances[distIdx];
+                              minErr = err;
+                              bestC1 = (!swap_colors) ? c1 : c2;
+                              bestC2 = (!swap_colors) ? c2 : c1;
+                              bestMode = mode;
+                              if (err <= kTargetError[params->m_quality])
+                                goto found;
+                           }
+                      }
+                 }
+            }
+       }
+
+found:
+   EINA_INLIST_FREE(tried_pairs, pair)
+     {
+        tried_pairs = eina_inlist_remove(tried_pairs, EINA_INLIST_GET(pair));
+        free(pair);
+     }
+
+   err = _etc2_th_mode_block_pack(etc2, bestMode, bestC1, bestC2, bestDist,
+                                  bgra, EINA_TRUE, &swap_colors);
+
+   return err;
+}
+
+static inline Eina_Bool
+_etc2_planar_mode_header_pack(uint8_t *etc2,
+                              uint32_t RO, uint32_t RH, uint32_t RV,
+                              uint32_t GO, uint32_t GH, uint32_t GV,
+                              uint32_t BO, uint32_t BH, uint32_t BV)
+{
+   int R, dR;
+   int G, dG;
+   int B, dB;
+
+   // RO_6 [2..5]
+   R = BITS(RO >> 2, 2, 5);
+   // RO_6 [0..1] + GO_7[6]
+   dR = (BITS(RO >> 2, 0, 1) << 1) | BIT(GO >> 1, 6);
+
+   if (!((R + kSigned3bit[dR] >= 0) && (R + kSigned3bit[dR] <= 31)))
+     R |= 1 << 4;
+
+   // GO_7[2..5]
+   G = BITS(GO >> 1, 2, 5);
+   // GO_7[0..1] + BO_6[5]
+   dG = (BITS(GO >> 1, 0, 1) << 1) | BIT(BO >> 2, 5);
+
+   if (!((G + kSigned3bit[dG] >= 0) && (G + kSigned3bit[dG] <= 31)))
+     G |= 1 << 4;
+
+   // BO_6[3..4]
+   B = BITS(BO >> 2, 3, 4);
+   // BO_6[1..2]
+   dB = BITS(BO >> 2, 1, 2);
+
+   // B + dB must be outside the range.
+   for (int Bx = 0; Bx < 8; Bx++)
+     for (int dBx = 0; dBx < 2; dBx++)
+       {
+          int Btry = B | (Bx << 2);
+          int dBtry = dB | (dBx << 2);
+          if ((Btry + kSigned3bit[dBtry]) < 0 || (Btry + kSigned3bit[dBtry] > 31))
+            {
+               B = Btry;
+               dB = dBtry;
+               break;
+            }
+       }
+
+   if (!((R + kSigned3bit[dR] >= 0) && (R + kSigned3bit[dR] <= 31)))
+     return EINA_FALSE;
+
+   if (!((G + kSigned3bit[dG] >= 0) && (G + kSigned3bit[dG] <= 31)))
+     return EINA_FALSE;
+
+   if ((B + kSigned3bit[dB] >= 0) && (B + kSigned3bit[dB] <= 31))
+     return EINA_FALSE;
+
+   // Write everything
+   etc2[0] = (R << 3) | dR;
+   etc2[1] = (G << 3) | dG;
+   etc2[2] = (B << 3) | dB;
+   etc2[3] = (BIT(BO >> 2, 0) << 7) | (BITS(RH >> 2, 1, 5) << 2) | 0x2 | BIT(RH >> 2, 0);
+   etc2[4] = ((GH >> 1) << 1) | BIT(BH >> 2, 5);
+   etc2[5] = (BITS(BH >> 2, 0, 4) << 3) | BITS(RV >> 2, 3, 5);
+   etc2[6] = (BITS(RV >> 2, 0, 2) << 5) | BITS(GV >> 1, 2, 6);
+   etc2[7] = (BITS(GV >> 1, 0, 1) << 6) | (BV >> 2);
+
+   return EINA_TRUE;
+}
+
+static unsigned int
+_etc2_planar_mode_block_pack(uint8_t *etc2,
+                             uint32_t Ocol, uint32_t Hcol, uint32_t Vcol,
+                             const uint32_t *bgra, Eina_Bool write)
+{
+   unsigned int err = 0;
+   uint32_t RO, RH, RV, GO, GH, GV, BO, BH, BV;
+
+   RO = R_VAL(&Ocol);
+   RH = R_VAL(&Hcol);
+   RV = R_VAL(&Vcol);
+   GO = G_VAL(&Ocol);
+   GH = G_VAL(&Hcol);
+   GV = G_VAL(&Vcol);
+   BO = B_VAL(&Ocol);
+   BH = B_VAL(&Hcol);
+   BV = B_VAL(&Vcol);
+
+   if (write)
+     {
+        if (!_etc2_planar_mode_header_pack(etc2, RO, RH, RV, GO, GH, GV, BO, BH, BV))
+          return INT_MAX;
+     }
+
+   // Compute MSE, that's all we need to do
+
+   for (int y = 0; y < 4; y++)
+     for (int x = 0; x < 4; x++)
+       {
+          const int R = CLAMP(((x * (RH - RO)) + y * (RV - RO) + 4 * RO + 2) >> 2);
+          const int G = CLAMP(((x * (GH - GO)) + y * (GV - GO) + 4 * GO + 2) >> 2);
+          const int B = CLAMP(((x * (BH - BO)) + y * (BV - BO) + 4 * BO + 2) >> 2);
+          uint32_t color = BGRA(R, G, B, 255);
+
+          err += _rgb_distance_euclid(color, bgra[x + y * 4]);
+       }
+
+   return err;
+}
+
+static unsigned int
+_etc2_planar_mode_block_encode(uint8_t *etc2, const uint32_t *bgra,
+                               const rg_etc1_pack_params *params EINA_UNUSED)
+{
+   unsigned int err;
+   unsigned int Ocol, Hcol, Vcol, RO, GO, BO, Rx, Gx, Bx;
+
+   // TODO: Scan a broader range to avoid artifacts when the
+   // points O, H or V are exceptions
+
+   /* O is at (0,0)
+    * H is at (4,0)
+    * V is at (0,4)
+    * So, H and V are outside the block.
+    * We extrapolate the values from (0,3) and (3,0).
+    */
+
+   RO = R_VAL(&(bgra[0]));
+   GO = G_VAL(&(bgra[0]));
+   BO = B_VAL(&(bgra[0]));
+   Ocol = _color_reduce_676(bgra[0]);
+
+   Rx = CLAMP(RO + (4 * (R_VAL(&(bgra[3])) - RO)) / 3);
+   Gx = CLAMP(GO + (4 * (G_VAL(&(bgra[3])) - GO)) / 3);
+   Bx = CLAMP(BO + (4 * (B_VAL(&(bgra[3])) - BO)) / 3);
+   Hcol = _color_reduce_676(BGRA(Rx, Gx, Bx, 0xFF));
+
+   Rx = CLAMP(RO + (4 * (R_VAL(&(bgra[12])) - RO)) / 3);
+   Gx = CLAMP(GO + (4 * (G_VAL(&(bgra[12])) - GO)) / 3);
+   Bx = CLAMP(BO + (4 * (B_VAL(&(bgra[12])) - BO)) / 3);
+   Vcol = _color_reduce_676(BGRA(Rx, Gx, Bx, 0xFF));
+
+   err = _etc2_planar_mode_block_pack(etc2, Ocol, Hcol, Vcol, bgra, EINA_TRUE);
+
+   return err;
+}
+
+#ifdef DEBUG
+static unsigned int
+_block_error_calc(const uint32_t *enc, const uint32_t *orig, Eina_Bool perceptual)
+{
+   unsigned int errAcc = 0;
+
+   for (int k = 0; k < 16; k++)
+     {
+        if (perceptual)
+          errAcc += _rgb_distance_percept(enc[k], orig[k]);
+        else
+          errAcc += _rgb_distance_euclid(enc[k], orig[k]);
+     }
+
+   return errAcc;
+}
+#endif
+
+unsigned int
+etc2_rgba8_block_pack(unsigned char *etc2, const unsigned int *bgra,
+                      rg_etc1_pack_params *params)
+{
+   rg_etc1_pack_params safe_params;
+   unsigned int errors[3] = { INT_MAX, INT_MAX, INT_MAX };
+   unsigned int minErr = INT_MAX;
+   uint8_t etc2_try[3][8];
+   int bestSolution = 0;
+
+#ifdef DEBUG
+   static int cnt [3] = {0};
+#endif
+
+   safe_params.m_dithering = !!params->m_dithering;
+   safe_params.m_quality = MINMAX(params->m_quality, 0, 2);
+
+   errors[0] = rg_etc1_pack_block(etc2_try[0], bgra, &safe_params);
+   errors[1] = _etc2_th_mode_block_encode(etc2_try[1], bgra, &safe_params);
+   errors[2] = _etc2_planar_mode_block_encode(etc2_try[2], bgra, &safe_params);
+
+#ifdef DEBUG
+   for (int i = 1; i < 3; i++)
+     {
+        const char *mode = (i == 1) ? "T or H" : "Planar";
+        if (errors[i] < INT_MAX)
+          for (unsigned k = 0; k < sizeof(errors) / sizeof(*errors); k++)
+            {
+               uint32_t decoded[16];
+               unsigned int real_errors[2];
+               rg_etc2_rgb8_decode_block(etc2_try[i], decoded);
+               real_errors[0] = _block_error_calc(decoded, bgra, EINA_FALSE);
+               real_errors[1] = _block_error_calc(decoded, bgra, EINA_TRUE);
+
+               if (real_errors[0] != errors[i])
+                 DBG("Invalid error calc in %s mode", mode);
+            }
+     }
+#endif
+
+   for (unsigned k = 0; k < sizeof(errors) / sizeof(*errors); k++)
+     if (errors[k] < minErr)
+       {
+          minErr = errors[k];
+          bestSolution = k;
+       }
+
+   memcpy(etc2 + 8, etc2_try[bestSolution], 8);
+
+   minErr += _etc2_alpha_encode(etc2, bgra, &safe_params);
+
+#ifdef DEBUG
+   cnt[bestSolution]++;
+   DBG("Block count by mode: ETC1: %d T/H: %d Planar: %d. Err %d",
+       cnt[0], cnt[1], cnt[2], minErr);
+#endif
+
+   return minErr;
+}
+
+unsigned int
+etc2_rgb8_block_pack(unsigned char *etc2, const unsigned int *bgra,
+                     rg_etc1_pack_params *params)
+{
+  rg_etc1_pack_params safe_params;
+  unsigned int errors[3] = { INT_MAX, INT_MAX, INT_MAX };
+  unsigned int minErr = INT_MAX;
+  uint8_t etc2_try[3][8];
+  int bestSolution = 0;
+
+  safe_params.m_dithering = !!params->m_dithering;
+  safe_params.m_quality = MINMAX(params->m_quality, 0, 2);
+
+  errors[0] = rg_etc1_pack_block(etc2_try[0], bgra, &safe_params);
+  errors[1] = _etc2_th_mode_block_encode(etc2_try[1], bgra, &safe_params);
+  errors[2] = _etc2_planar_mode_block_encode(etc2_try[2], bgra, &safe_params);
+
+  for (unsigned k = 0; k < sizeof(errors) / sizeof(*errors); k++)
+    if (errors[k] < minErr)
+      {
+         minErr = errors[k];
+         bestSolution = k;
+      }
+
+  memcpy(etc2, etc2_try[bestSolution], 8);
+
+  return minErr;
+}
diff --git a/src/static_deps/rg_etc/rg_etc1.c b/src/static_deps/rg_etc/rg_etc1.c
new file mode 100644 (file)
index 0000000..59d79b4
--- /dev/null
@@ -0,0 +1,2833 @@
+// File: rg_etc1.cpp - Fast, high quality ETC1 block packer/unpacker - Rich Geldreich <richgel99@gmail.com>
+// Please see ZLIB license at the end of rg_etc1.h.
+//
+// For more information Ericsson Texture Compression (ETC/ETC1), see:
+// http://www.khronos.org/registry/gles/extensions/OES/OES_compressed_ETC1_RGB8_texture.txt
+//
+// v1.04 - 5/15/14 - Fix signed vs. unsigned subtraction problem (noticed when compiled with gcc) in pack_etc1_block_init().
+//         This issue would cause an assert when this func. was called in debug. (Note this module was developed/testing with MSVC,
+//         I still need to test it throughly when compiled with gcc.)
+//
+// v1.03 - 5/12/13 - Initial public release
+
+#include <stdlib.h>
+#include <memory.h>
+#include <math.h>
+
+#include "Eina.h"
+
+#include "rg_etc1.h"
+
+#if defined(_DEBUG) || defined(DEBUG)
+#define RG_ETC1_BUILD_DEBUG
+#endif
+
+typedef unsigned long long uint64;
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint;
+typedef unsigned int uint32;
+typedef unsigned char DATA8;
+
+#define MIN(A, B) ((A < B) ? A : B)
+#define MAX(A, B) ((A > B) ? A : B)
+#define CLAMP(Value, Low, High) ((Value < Low) ? Low : ((Value > High) ? High : Value))
+#define SQUARE(Value) (Value * Value)
+
+#ifndef UINT_MAX
+#define UINT_MAX  4294967295U
+#endif
+
+#ifndef ULLONG_MAX
+#define ULLONG_MAX 18446744073709551615ULL
+#endif
+
+#define cUINT32_MAX UINT_MAX
+#define cUINT64_MAX ULLONG_MAX
+#define RG_ETC1_ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0]))
+
+// Some configuration defines
+
+// Disable this constrained function, it produces artifacts (in black areas mostly)
+#define RG_ETC1_CONSTRAINED_SUBBLOCK 0
+// Disable dithering. It uses invalid RGBA order and isn't great visually
+// Dithering should happen AFTER the color selection, not before
+#define RG_ETC1_DITHERING 0
+
+enum RG_Etc_Constants
+  {
+    cETC1BytesPerBlock = 8U,
+
+    cETC1SelectorBits = 2U,
+    cETC1SelectorValues = 1U << cETC1SelectorBits,
+    cETC1SelectorMask = cETC1SelectorValues - 1U,
+
+    cETC1BlockShift = 2U,
+    cETC1BlockSize = 1U << cETC1BlockShift,
+
+    cETC1LSBSelectorIndicesBitOffset = 0,
+    cETC1MSBSelectorIndicesBitOffset = 16,
+
+    cETC1FlipBitOffset = 32,
+    cETC1DiffBitOffset = 33,
+
+    cETC1IntenModifierNumBits = 3,
+    cETC1IntenModifierValues = 1 << cETC1IntenModifierNumBits,
+    cETC1RightIntenModifierTableBitOffset = 34,
+    cETC1LeftIntenModifierTableBitOffset = 37,
+
+    // Base+Delta encoding (5 bit bases, 3 bit delta)
+    cETC1BaseColorCompNumBits = 5,
+    cETC1BaseColorCompMax = 1 << cETC1BaseColorCompNumBits,
+
+    cETC1DeltaColorCompNumBits = 3,
+    cETC1DeltaColorComp = 1 << cETC1DeltaColorCompNumBits,
+    cETC1DeltaColorCompMax = 1 << cETC1DeltaColorCompNumBits,
+
+    cETC1BaseColor5RBitOffset = 59,
+    cETC1BaseColor5GBitOffset = 51,
+    cETC1BaseColor5BBitOffset = 43,
+
+    cETC1DeltaColor3RBitOffset = 56,
+    cETC1DeltaColor3GBitOffset = 48,
+    cETC1DeltaColor3BBitOffset = 40,
+
+    // Absolute (non-delta) encoding (two 4-bit per component bases)
+    cETC1AbsColorCompNumBits = 4,
+    cETC1AbsColorCompMax = 1 << cETC1AbsColorCompNumBits,
+
+    cETC1AbsColor4R1BitOffset = 60,
+    cETC1AbsColor4G1BitOffset = 52,
+    cETC1AbsColor4B1BitOffset = 44,
+
+    cETC1AbsColor4R2BitOffset = 56,
+    cETC1AbsColor4G2BitOffset = 48,
+    cETC1AbsColor4B2BitOffset = 40,
+
+    cETC1ColorDeltaMin = -4,
+    cETC1ColorDeltaMax = 3,
+
+    // Delta3:
+    // 0   1   2   3   4   5   6   7
+    // 000 001 010 011 100 101 110 111
+    // 0   1   2   3   -4  -3  -2  -1
+  };
+
+/*
+ * IMPORTANT NOTE:
+ *
+ * rg_etc1 originally works only on R,G,B,A data
+ * evas works on B,G,R,A data
+ *
+ * ARGB_JOIN() is used for unpacking, so it will directly produce BGRA.
+ *
+ * Upon packing, we convert BGRA to RGBA so we can use the precomputed tables,
+ * so we must use the X_VAL_GET() macros.
+ * Upon unpacking, we directly output BGRA data using ARGB_JOIN() and X_VAL_SET()
+ *
+ * Yes, this is a mess. Maybe a clear BGRA API is needed
+ */
+
+#ifndef WORDS_BIGENDIAN
+// BGRA
+#define A_VAL_SET(p) (((DATA8 *)(p))[3])
+#define R_VAL_SET(p) (((DATA8 *)(p))[2])
+#define G_VAL_SET(p) (((DATA8 *)(p))[1])
+#define B_VAL_SET(p) (((DATA8 *)(p))[0])
+// RGBA
+#define A_VAL_GET(p) (((DATA8 *)(p))[3])
+#define R_VAL_GET(p) (((DATA8 *)(p))[0])
+#define G_VAL_GET(p) (((DATA8 *)(p))[1])
+#define B_VAL_GET(p) (((DATA8 *)(p))[2])
+#else
+// BIGENDIAN is untested
+#define A_VAL_SET(p) (((DATA8 *)(p))[0])
+#define R_VAL_SET(p) (((DATA8 *)(p))[1])
+#define G_VAL_SET(p) (((DATA8 *)(p))[2])
+#define B_VAL_SET(p) (((DATA8 *)(p))[3])
+#define A_VAL_GET(p) (((DATA8 *)(p))[0])
+#define R_VAL_GET(p) (((DATA8 *)(p))[3])
+#define G_VAL_GET(p) (((DATA8 *)(p))[2])
+#define B_VAL_GET(p) (((DATA8 *)(p))[1])
+#endif
+
+#define A_MASK (0xFFul << 24)
+
+// For unpacking and writing BGRA output data
+#define ARGB_JOIN(a,r,g,b) \
+        (((a) << 24) + ((r) << 16) + ((g) << 8) + (b))
+
+static unsigned char rg_etc_quant5_tab[256 + 16];
+
+static const int rg_etc1_inten_tables[cETC1IntenModifierValues][cETC1SelectorValues] = {
+  { -8,   -2,   2,   8 },
+  { -17,  -5,   5,  17 },
+  { -29,  -9,   9,  29 },
+  { -42,  -13, 13,  42 },
+  { -60,  -18, 18,  60 },
+  { -80,  -24, 24,  80 },
+  { -106, -33, 33, 106 },
+  { -183, -47, 47, 183 }
+};
+
+static const unsigned char rg_etc1_to_selector_index[cETC1SelectorValues] = { 2, 3, 1, 0 };
+static const unsigned char rg_etc_selector_index_to_etc1[cETC1SelectorValues] = { 3, 2, 0, 1 };
+
+// Given an ETC1 diff/inten_table/selector, and an 8-bit desired color, this table encodes the best packed_color in the low byte, and the abs error in the high byte.
+static unsigned short rg_etc1_inverse_lookup[2*8*4][256]; // [diff/inten_table/selector][desired_color]
+
+// rg_color8_to_etc_block_config[color][table_index] = Supplies for each 8-bit color value a list of packed ETC1 diff/intensity table/selectors/packed_colors that map to that color.
+// To pack: diff | (inten << 1) | (selector << 4) | (packed_c << 8)
+static const unsigned short rg_etc_color8_to_etc_block_config_0_255[2][33] = {
+  {
+    0x0000, 0x0010, 0x0002, 0x0012, 0x0004, 0x0014, 0x0006, 0x0016, 0x0008,
+    0x0018, 0x000A, 0x001A, 0x000C, 0x001C, 0x000E, 0x001E, 0x0001, 0x0011,
+    0x0003, 0x0013, 0x0005, 0x0015, 0x0007, 0x0017, 0x0009, 0x0019, 0x000B,
+    0x001B, 0x000D, 0x001D, 0x000F, 0x001F, 0xFFFF
+  },
+  {
+    0x0F20, 0x0F30, 0x0E32, 0x0F22, 0x0E34, 0x0F24, 0x0D36, 0x0F26, 0x0C38,
+    0x0E28, 0x0B3A, 0x0E2A, 0x093C, 0x0E2C, 0x053E, 0x0D2E, 0x1E31, 0x1F21,
+    0x1D33, 0x1F23, 0x1C35, 0x1E25, 0x1A37, 0x1E27, 0x1839, 0x1D29, 0x163B,
+    0x1C2B,  0x133D,  0x1B2D,  0x093F,  0x1A2F, 0xFFFF
+  },
+};
+
+// Really only [254][11].
+static const unsigned short rg_etc_color8_to_etc_block_config_1_to_254[254][12] = {
+  { 0x021C, 0x0D0D, 0xFFFF },
+  { 0x0020, 0x0021, 0x0A0B, 0x061F, 0xFFFF },
+  { 0x0113, 0x0217, 0xFFFF },
+  { 0x0116, 0x031E, 0x0B0E, 0x0405, 0xFFFF },
+  { 0x0022, 0x0204, 0x050A, 0x0023, 0xFFFF },
+  { 0x0111, 0x0319, 0x0809, 0x170F, 0xFFFF },
+  { 0x0303, 0x0215, 0x0607, 0xFFFF },
+  { 0x0030, 0x0114, 0x0408, 0x0031, 0x0201, 0x051D, 0xFFFF },
+  { 0x0100, 0x0024, 0x0306, 0x0025, 0x041B, 0x0E0D, 0xFFFF },
+  { 0x021A, 0x0121, 0x0B0B, 0x071F, 0xFFFF },
+  { 0x0213, 0x0317, 0xFFFF },
+  { 0x0112, 0x0505, 0xFFFF },
+  { 0x0026, 0x070C, 0x0123, 0x0027, 0xFFFF },
+  { 0x0211, 0x0909, 0xFFFF },
+  { 0x0110, 0x0315, 0x0707, 0x0419, 0x180F, 0xFFFF },
+  { 0x0218, 0x0131, 0x0301, 0x0403, 0x061D, 0xFFFF },
+  { 0x0032, 0x0202, 0x0033, 0x0125, 0x051B, 0x0F0D, 0xFFFF },
+  { 0x0028, 0x031C, 0x0221, 0x0029, 0xFFFF },
+  { 0x0120, 0x0313, 0x0C0B, 0x081F, 0xFFFF },
+  { 0x0605, 0x0417, 0xFFFF },
+  { 0x0216, 0x041E, 0x0C0E, 0x0223, 0x0127, 0xFFFF },
+  { 0x0122, 0x0304, 0x060A, 0x0311, 0x0A09, 0xFFFF },
+  { 0x0519, 0x190F, 0xFFFF },
+  { 0x002A, 0x0231, 0x0503, 0x0415, 0x0807, 0x002B, 0x071D, 0xFFFF },
+  { 0x0130, 0x0214, 0x0508, 0x0401, 0x0133, 0x0225, 0x061B, 0xFFFF },
+  { 0x0200, 0x0124, 0x0406, 0x0321, 0x0129, 0x100D, 0xFFFF },
+  { 0x031A, 0x0D0B, 0x091F, 0xFFFF },
+  { 0x0413, 0x0705, 0x0517, 0xFFFF },
+  { 0x0212, 0x0034, 0x0323, 0x0035, 0x0227, 0xFFFF },
+  { 0x0126, 0x080C, 0x0B09, 0xFFFF },
+  { 0x0411, 0x0619, 0x1A0F, 0xFFFF },
+  { 0x0210, 0x0331, 0x0603, 0x0515, 0x0907, 0x012B, 0xFFFF },
+  { 0x0318, 0x002C, 0x0501, 0x0233, 0x0325, 0x071B, 0x002D, 0x081D, 0xFFFF },
+  { 0x0132, 0x0302, 0x0229, 0x110D, 0xFFFF },
+  { 0x0128, 0x041C, 0x0421, 0x0E0B, 0x0A1F, 0xFFFF },
+  { 0x0220, 0x0513, 0x0617, 0xFFFF },
+  { 0x0135, 0x0805, 0x0327, 0xFFFF },
+  { 0x0316, 0x051E, 0x0D0E, 0x0423, 0xFFFF },
+  { 0x0222, 0x0404, 0x070A, 0x0511, 0x0719, 0x0C09, 0x1B0F, 0xFFFF },
+  { 0x0703, 0x0615, 0x0A07, 0x022B, 0xFFFF },
+  { 0x012A, 0x0431, 0x0601, 0x0333, 0x012D, 0x091D, 0xFFFF },
+  { 0x0230, 0x0314, 0x0036, 0x0608, 0x0425, 0x0037, 0x0329, 0x081B, 0x120D, 0xFFFF },
+  { 0x0300, 0x0224, 0x0506, 0x0521, 0x0F0B, 0x0B1F, 0xFFFF },
+  { 0x041A, 0x0613, 0x0717, 0xFFFF },
+  { 0x0235, 0x0905, 0xFFFF },
+  { 0x0312, 0x0134, 0x0523, 0x0427, 0xFFFF },
+  { 0x0226, 0x090C, 0x002E, 0x0611, 0x0D09, 0x002F, 0xFFFF },
+  { 0x0715, 0x0B07, 0x0819, 0x032B, 0x1C0F, 0xFFFF },
+  { 0x0310, 0x0531, 0x0701, 0x0803, 0x022D, 0x0A1D, 0xFFFF },
+  { 0x0418, 0x012C, 0x0433, 0x0525, 0x0137, 0x091B, 0x130D, 0xFFFF },
+  { 0x0232, 0x0402, 0x0621, 0x0429, 0xFFFF },
+  { 0x0228, 0x051C, 0x0713, 0x100B, 0x0C1F, 0xFFFF },
+  { 0x0320, 0x0335, 0x0A05, 0x0817, 0xFFFF },
+  { 0x0623, 0x0527, 0xFFFF },
+  { 0x0416, 0x061E, 0x0E0E, 0x0711, 0x0E09, 0x012F, 0xFFFF },
+  { 0x0322, 0x0504, 0x080A, 0x0919, 0x1D0F, 0xFFFF },
+  { 0x0631, 0x0903, 0x0815, 0x0C07, 0x042B, 0x032D, 0x0B1D, 0xFFFF },
+  { 0x022A, 0x0801, 0x0533, 0x0625, 0x0237, 0x0A1B, 0xFFFF },
+  { 0x0330, 0x0414, 0x0136, 0x0708, 0x0721, 0x0529, 0x140D, 0xFFFF },
+  { 0x0400, 0x0324, 0x0606, 0x0038, 0x0039, 0x110B, 0x0D1F, 0xFFFF },
+  { 0x051A, 0x0813, 0x0B05, 0x0917, 0xFFFF },
+  { 0x0723, 0x0435, 0x0627, 0xFFFF },
+  { 0x0412, 0x0234, 0x0F09, 0x022F, 0xFFFF },
+  { 0x0326, 0x0A0C, 0x012E, 0x0811, 0x0A19, 0x1E0F, 0xFFFF },
+  { 0x0731, 0x0A03, 0x0915, 0x0D07, 0x052B, 0xFFFF },
+  { 0x0410, 0x0901, 0x0633, 0x0725, 0x0337, 0x0B1B, 0x042D, 0x0C1D, 0xFFFF },
+  { 0x0518, 0x022C, 0x0629, 0x150D, 0xFFFF },
+  { 0x0332, 0x0502, 0x0821, 0x0139, 0x120B, 0x0E1F, 0xFFFF },
+  { 0x0328, 0x061C, 0x0913, 0x0A17, 0xFFFF },
+  { 0x0420, 0x0535, 0x0C05, 0x0727, 0xFFFF },
+  { 0x0823, 0x032F, 0xFFFF },
+  { 0x0516, 0x071E, 0x0F0E, 0x0911, 0x0B19, 0x1009, 0x1F0F, 0xFFFF },
+  { 0x0422, 0x0604, 0x090A, 0x0B03, 0x0A15, 0x0E07, 0x062B, 0xFFFF },
+  { 0x0831, 0x0A01, 0x0733, 0x052D, 0x0D1D, 0xFFFF },
+  { 0x032A, 0x0825, 0x0437, 0x0729, 0x0C1B, 0x160D, 0xFFFF },
+  { 0x0430, 0x0514, 0x0236, 0x0808, 0x0921, 0x0239, 0x130B, 0x0F1F, 0xFFFF },
+  { 0x0500, 0x0424, 0x0706, 0x0138, 0x0A13, 0x0B17, 0xFFFF },
+  { 0x061A, 0x0635, 0x0D05, 0xFFFF },
+  { 0x0923, 0x0827, 0xFFFF },
+  { 0x0512, 0x0334, 0x003A, 0x0A11, 0x1109, 0x003B, 0x042F, 0xFFFF },
+  { 0x0426, 0x0B0C, 0x022E, 0x0B15, 0x0F07, 0x0C19, 0x072B, 0xFFFF },
+  { 0x0931, 0x0B01, 0x0C03, 0x062D, 0x0E1D, 0xFFFF },
+  { 0x0510, 0x0833, 0x0925, 0x0537, 0x0D1B, 0x170D, 0xFFFF },
+  { 0x0618, 0x032C, 0x0A21, 0x0339, 0x0829, 0xFFFF },
+  { 0x0432, 0x0602, 0x0B13, 0x140B, 0x101F, 0xFFFF },
+  { 0x0428, 0x071C, 0x0735, 0x0E05, 0x0C17, 0xFFFF },
+  { 0x0520, 0x0A23, 0x0927, 0xFFFF },
+  { 0x0B11, 0x1209, 0x013B, 0x052F, 0xFFFF },
+  { 0x0616, 0x081E, 0x0D19, 0xFFFF },
+  { 0x0522, 0x0704, 0x0A0A, 0x0A31, 0x0D03, 0x0C15, 0x1007, 0x082B, 0x072D, 0x0F1D, 0xFFFF },
+  { 0x0C01, 0x0933, 0x0A25, 0x0637, 0x0E1B, 0xFFFF },
+  { 0x042A, 0x0B21, 0x0929, 0x180D, 0xFFFF },
+  { 0x0530, 0x0614, 0x0336, 0x0908, 0x0439, 0x150B, 0x111F, 0xFFFF },
+  { 0x0600, 0x0524, 0x0806, 0x0238, 0x0C13, 0x0F05, 0x0D17, 0xFFFF },
+  { 0x071A, 0x0B23, 0x0835, 0x0A27, 0xFFFF },
+  { 0x1309, 0x023B, 0x062F, 0xFFFF },
+  { 0x0612, 0x0434, 0x013A, 0x0C11, 0x0E19, 0xFFFF },
+  { 0x0526, 0x0C0C, 0x032E, 0x0B31, 0x0E03, 0x0D15, 0x1107, 0x092B, 0xFFFF },
+  { 0x0D01, 0x0A33, 0x0B25, 0x0737, 0x0F1B, 0x082D, 0x101D, 0xFFFF },
+  { 0x0610, 0x0A29, 0x190D, 0xFFFF },
+  { 0x0718, 0x042C, 0x0C21, 0x0539, 0x160B, 0x121F, 0xFFFF },
+  { 0x0532, 0x0702, 0x0D13, 0x0E17, 0xFFFF },
+  { 0x0528, 0x081C, 0x0935, 0x1005, 0x0B27, 0xFFFF },
+  { 0x0620, 0x0C23, 0x033B, 0x072F, 0xFFFF },
+  { 0x0D11, 0x0F19, 0x1409, 0xFFFF },
+  { 0x0716, 0x003C, 0x091E, 0x0F03, 0x0E15, 0x1207, 0x0A2B, 0x003D, 0xFFFF },
+  { 0x0622, 0x0804, 0x0B0A, 0x0C31, 0x0E01, 0x0B33, 0x092D, 0x111D, 0xFFFF },
+  { 0x0C25, 0x0837, 0x0B29, 0x101B, 0x1A0D, 0xFFFF },
+  { 0x052A, 0x0D21, 0x0639, 0x170B, 0x131F, 0xFFFF },
+  { 0x0630, 0x0714, 0x0436, 0x0A08, 0x0E13, 0x0F17, 0xFFFF },
+  { 0x0700, 0x0624, 0x0906, 0x0338, 0x0A35, 0x1105, 0xFFFF },
+  { 0x081A, 0x0D23, 0x0C27, 0xFFFF },
+  { 0x0E11, 0x1509, 0x043B, 0x082F, 0xFFFF },
+  { 0x0712, 0x0534, 0x023A, 0x0F15, 0x1307, 0x1019, 0x0B2B, 0x013D, 0xFFFF },
+  { 0x0626, 0x0D0C, 0x042E, 0x0D31, 0x0F01, 0x1003, 0x0A2D, 0x121D, 0xFFFF },
+  { 0x0C33, 0x0D25, 0x0937, 0x111B, 0x1B0D, 0xFFFF },
+  { 0x0710, 0x0E21, 0x0739, 0x0C29, 0xFFFF },
+  { 0x0818, 0x052C, 0x0F13, 0x180B, 0x141F, 0xFFFF },
+  { 0x0632, 0x0802, 0x0B35, 0x1205, 0x1017, 0xFFFF },
+  { 0x0628, 0x091C, 0x0E23, 0x0D27, 0xFFFF },
+  { 0x0720, 0x0F11, 0x1609, 0x053B, 0x092F, 0xFFFF },
+  { 0x1119, 0x023D, 0xFFFF },
+  { 0x0816, 0x013C, 0x0A1E, 0x0E31, 0x1103, 0x1015, 0x1407, 0x0C2B, 0x0B2D, 0x131D, 0xFFFF },
+  { 0x0722, 0x0904, 0x0C0A, 0x1001, 0x0D33, 0x0E25, 0x0A37, 0x121B, 0xFFFF },
+  { 0x0F21, 0x0D29, 0x1C0D, 0xFFFF },
+  { 0x062A, 0x0839, 0x190B, 0x151F, 0xFFFF },
+  { 0x0730, 0x0814, 0x0536, 0x0B08, 0x1013, 0x1305, 0x1117, 0xFFFF },
+  { 0x0800, 0x0724, 0x0A06, 0x0438, 0x0F23, 0x0C35, 0x0E27, 0xFFFF },
+  { 0x091A, 0x1709, 0x063B, 0x0A2F, 0xFFFF },
+  { 0x1011, 0x1219, 0x033D, 0xFFFF },
+  { 0x0812, 0x0634, 0x033A, 0x0F31, 0x1203, 0x1115, 0x1507, 0x0D2B, 0xFFFF },
+  { 0x0726, 0x0E0C, 0x052E, 0x1101, 0x0E33, 0x0F25, 0x0B37, 0x131B, 0x0C2D, 0x141D, 0xFFFF },
+  { 0x0E29, 0x1D0D, 0xFFFF },
+  { 0x0810, 0x1021, 0x0939, 0x1A0B, 0x161F, 0xFFFF },
+  { 0x0918, 0x062C, 0x1113, 0x1217, 0xFFFF },
+  { 0x0732, 0x0902, 0x0D35, 0x1405, 0x0F27, 0xFFFF },
+  { 0x0728, 0x0A1C, 0x1023, 0x073B, 0x0B2F, 0xFFFF },
+  { 0x0820, 0x1111, 0x1319, 0x1809, 0xFFFF },
+  { 0x1303, 0x1215, 0x1607, 0x0E2B, 0x043D, 0xFFFF },
+  { 0x0916, 0x023C, 0x0B1E, 0x1031, 0x1201, 0x0F33, 0x0D2D, 0x151D, 0xFFFF },
+  { 0x0822, 0x0A04, 0x0D0A, 0x1025, 0x0C37, 0x0F29, 0x141B, 0x1E0D, 0xFFFF },
+  { 0x1121, 0x0A39, 0x1B0B, 0x171F, 0xFFFF },
+  { 0x072A, 0x1213, 0x1317, 0xFFFF },
+  { 0x0830, 0x0914, 0x0636, 0x0C08, 0x0E35, 0x1505, 0xFFFF },
+  { 0x0900, 0x0824, 0x0B06, 0x0538, 0x1123, 0x1027, 0xFFFF },
+  { 0x0A1A, 0x1211, 0x1909, 0x083B, 0x0C2F, 0xFFFF },
+  { 0x1315, 0x1707, 0x1419, 0x0F2B, 0x053D, 0xFFFF },
+  { 0x0912, 0x0734, 0x043A, 0x1131, 0x1301, 0x1403, 0x0E2D, 0x161D, 0xFFFF },
+  { 0x0826, 0x0F0C, 0x062E, 0x1033, 0x1125, 0x0D37, 0x151B, 0x1F0D, 0xFFFF },
+  { 0x1221, 0x0B39, 0x1029, 0xFFFF },
+  { 0x0910, 0x1313, 0x1C0B, 0x181F, 0xFFFF },
+  { 0x0A18, 0x072C, 0x0F35, 0x1605, 0x1417, 0xFFFF },
+  { 0x0832, 0x0A02, 0x1223, 0x1127, 0xFFFF },
+  { 0x0828, 0x0B1C, 0x1311, 0x1A09, 0x093B, 0x0D2F, 0xFFFF },
+  { 0x0920, 0x1519, 0x063D, 0xFFFF },
+  { 0x1231, 0x1503, 0x1415, 0x1807, 0x102B, 0x0F2D, 0x171D, 0xFFFF },
+  { 0x0A16, 0x033C, 0x0C1E, 0x1401, 0x1133, 0x1225, 0x0E37, 0x161B, 0xFFFF },
+  { 0x0922, 0x0B04, 0x0E0A, 0x1321, 0x1129, 0xFFFF },
+  { 0x0C39, 0x1D0B, 0x191F, 0xFFFF },
+  { 0x082A, 0x1413, 0x1705, 0x1517, 0xFFFF },
+  { 0x0930, 0x0A14, 0x0736, 0x0D08, 0x1323, 0x1035, 0x1227, 0xFFFF },
+  { 0x0A00, 0x0924, 0x0C06, 0x0638, 0x1B09, 0x0A3B, 0x0E2F, 0xFFFF },
+  { 0x0B1A, 0x1411, 0x1619, 0x073D, 0xFFFF },
+  { 0x1331, 0x1603, 0x1515, 0x1907, 0x112B, 0xFFFF },
+  { 0x0A12, 0x0834, 0x053A, 0x1501, 0x1233, 0x1325, 0x0F37, 0x171B, 0x102D, 0x181D, 0xFFFF },
+  { 0x0926, 0x072E, 0x1229, 0xFFFF },
+  { 0x1421, 0x0D39, 0x1E0B, 0x1A1F, 0xFFFF },
+  { 0x0A10, 0x1513, 0x1617, 0xFFFF },
+  { 0x0B18, 0x082C, 0x1135, 0x1805, 0x1327, 0xFFFF },
+  { 0x0932, 0x0B02, 0x1423, 0x0B3B, 0x0F2F, 0xFFFF },
+  { 0x0928, 0x0C1C, 0x1511, 0x1719, 0x1C09, 0xFFFF },
+  { 0x0A20, 0x1703, 0x1615, 0x1A07, 0x122B, 0x083D, 0xFFFF },
+  { 0x1431, 0x1601, 0x1333, 0x112D, 0x191D, 0xFFFF },
+  { 0x0B16, 0x043C, 0x0D1E, 0x1425, 0x1037, 0x1329, 0x181B, 0xFFFF },
+  { 0x0A22, 0x0C04, 0x0F0A, 0x1521, 0x0E39, 0x1F0B, 0x1B1F, 0xFFFF },
+  { 0x1613, 0x1717, 0xFFFF },
+  { 0x092A, 0x1235, 0x1905, 0xFFFF },
+  { 0x0A30, 0x0B14, 0x0836, 0x0E08, 0x1523, 0x1427, 0xFFFF },
+  { 0x0B00, 0x0A24, 0x0D06, 0x0738, 0x1611, 0x1D09, 0x0C3B, 0x102F, 0xFFFF },
+  { 0x0C1A, 0x1715, 0x1B07, 0x1819, 0x132B, 0x093D, 0xFFFF },
+  { 0x1531, 0x1701, 0x1803, 0x122D, 0x1A1D, 0xFFFF },
+  { 0x0B12, 0x0934, 0x063A, 0x1433, 0x1525, 0x1137, 0x191B, 0xFFFF },
+  { 0x0A26, 0x003E, 0x082E, 0x1621, 0x0F39, 0x1429, 0x003F, 0xFFFF },
+  { 0x1713, 0x1C1F, 0xFFFF },
+  { 0x0B10, 0x1335, 0x1A05, 0x1817, 0xFFFF },
+  { 0x0C18, 0x092C, 0x1623, 0x1527, 0xFFFF },
+  { 0x0A32, 0x0C02, 0x1711, 0x1E09, 0x0D3B, 0x112F, 0xFFFF },
+  { 0x0A28, 0x0D1C, 0x1919, 0x0A3D, 0xFFFF },
+  { 0x0B20, 0x1631, 0x1903, 0x1815, 0x1C07, 0x142B, 0x132D, 0x1B1D, 0xFFFF },
+  { 0x1801, 0x1533, 0x1625, 0x1237, 0x1A1B, 0xFFFF },
+  { 0x0C16, 0x053C, 0x0E1E, 0x1721, 0x1529, 0x013F, 0xFFFF },
+  { 0x0B22, 0x0D04, 0x1039, 0x1D1F, 0xFFFF },
+  { 0x1813, 0x1B05, 0x1917, 0xFFFF },
+  { 0x0A2A, 0x1723, 0x1435, 0x1627, 0xFFFF },
+  { 0x0B30, 0x0C14, 0x0936, 0x0F08, 0x1F09, 0x0E3B, 0x122F, 0xFFFF },
+  { 0x0C00, 0x0B24, 0x0E06, 0x0838, 0x1811, 0x1A19, 0x0B3D, 0xFFFF },
+  { 0x0D1A, 0x1731, 0x1A03, 0x1915, 0x1D07, 0x152B, 0xFFFF },
+  { 0x1901, 0x1633, 0x1725, 0x1337, 0x1B1B, 0x142D, 0x1C1D, 0xFFFF },
+  { 0x0C12, 0x0A34, 0x073A, 0x1629, 0x023F, 0xFFFF },
+  { 0x0B26, 0x013E, 0x092E, 0x1821, 0x1139, 0x1E1F, 0xFFFF },
+  { 0x1913, 0x1A17, 0xFFFF },
+  { 0x0C10, 0x1535, 0x1C05, 0x1727, 0xFFFF },
+  { 0x0D18, 0x0A2C, 0x1823, 0x0F3B, 0x132F, 0xFFFF },
+  { 0x0B32, 0x0D02, 0x1911, 0x1B19, 0xFFFF },
+  { 0x0B28, 0x0E1C, 0x1B03, 0x1A15, 0x1E07, 0x162B, 0x0C3D, 0xFFFF },
+  { 0x0C20, 0x1831, 0x1A01, 0x1733, 0x152D, 0x1D1D, 0xFFFF },
+  { 0x1825, 0x1437, 0x1729, 0x1C1B, 0x033F, 0xFFFF },
+  { 0x0D16, 0x063C, 0x0F1E, 0x1921, 0x1239, 0x1F1F, 0xFFFF },
+  { 0x0C22, 0x0E04, 0x1A13, 0x1B17, 0xFFFF },
+  { 0x1635, 0x1D05, 0xFFFF },
+  { 0x0B2A, 0x1923, 0x1827, 0xFFFF },
+  { 0x0C30, 0x0D14, 0x0A36, 0x1A11, 0x103B, 0x142F, 0xFFFF },
+  { 0x0D00, 0x0C24, 0x0F06, 0x0938, 0x1B15, 0x1F07, 0x1C19, 0x172B, 0x0D3D, 0xFFFF },
+  { 0x0E1A, 0x1931, 0x1B01, 0x1C03, 0x162D, 0x1E1D, 0xFFFF },
+  { 0x1833, 0x1925, 0x1537, 0x1D1B, 0xFFFF },
+  { 0x0D12, 0x0B34, 0x083A, 0x1A21, 0x1339, 0x1829, 0x043F, 0xFFFF },
+  { 0x0C26, 0x023E, 0x0A2E, 0x1B13, 0xFFFF },
+  { 0x1735, 0x1E05, 0x1C17, 0xFFFF },
+  { 0x0D10, 0x1A23, 0x1927, 0xFFFF },
+  { 0x0E18, 0x0B2C, 0x1B11, 0x113B, 0x152F, 0xFFFF },
+  { 0x0C32, 0x0E02, 0x1D19, 0x0E3D, 0xFFFF },
+  { 0x0C28, 0x0F1C, 0x1A31, 0x1D03, 0x1C15, 0x182B, 0x172D, 0x1F1D, 0xFFFF },
+  { 0x0D20, 0x1C01, 0x1933, 0x1A25, 0x1637, 0x1E1B, 0xFFFF },
+  { 0x1B21, 0x1929, 0x053F, 0xFFFF },
+  { 0x0E16, 0x073C, 0x1439, 0xFFFF },
+  { 0x0D22, 0x0F04, 0x1C13, 0x1F05, 0x1D17, 0xFFFF },
+  { 0x1B23, 0x1835, 0x1A27, 0xFFFF },
+  { 0x0C2A, 0x123B, 0x162F, 0xFFFF },
+  { 0x0D30, 0x0E14, 0x0B36, 0x1C11, 0x1E19, 0x0F3D, 0xFFFF },
+  { 0x0E00, 0x0D24, 0x0A38, 0x1B31, 0x1E03, 0x1D15, 0x192B, 0xFFFF },
+  { 0x0F1A, 0x1D01, 0x1A33, 0x1B25, 0x1737, 0x1F1B, 0x182D, 0xFFFF },
+  { 0x1A29, 0x063F, 0xFFFF },
+  { 0x0E12, 0x0C34, 0x093A, 0x1C21, 0x1539, 0xFFFF },
+  { 0x0D26, 0x033E, 0x0B2E, 0x1D13, 0x1E17, 0xFFFF },
+  { 0x1935, 0x1B27, 0xFFFF },
+  { 0x0E10, 0x1C23, 0x133B, 0x172F, 0xFFFF },
+  { 0x0F18, 0x0C2C, 0x1D11, 0x1F19, 0xFFFF },
+  { 0x0D32, 0x0F02, 0x1F03, 0x1E15, 0x1A2B, 0x103D, 0xFFFF },
+  { 0x0D28, 0x1C31, 0x1E01, 0x1B33, 0x192D, 0xFFFF },
+  { 0x0E20, 0x1C25, 0x1837, 0x1B29, 0x073F, 0xFFFF },
+  { 0x1D21, 0x1639, 0xFFFF },
+  { 0x0F16, 0x083C, 0x1E13, 0x1F17, 0xFFFF },
+  { 0x0E22, 0x1A35, 0xFFFF },
+  { 0x1D23, 0x1C27, 0xFFFF },
+  { 0x0D2A, 0x1E11, 0x143B, 0x182F, 0xFFFF },
+  { 0x0E30, 0x0F14, 0x0C36, 0x1F15, 0x1B2B, 0x113D, 0xFFFF },
+  { 0x0F00, 0x0E24, 0x0B38, 0x1D31, 0x1F01, 0x1A2D, 0xFFFF },
+  { 0x1C33, 0x1D25, 0x1937, 0xFFFF },
+  { 0x1E21, 0x1739, 0x1C29, 0x083F, 0xFFFF },
+  { 0x0F12, 0x0D34, 0x0A3A, 0x1F13, 0xFFFF },
+  { 0x0E26, 0x043E, 0x0C2E, 0x1B35, 0xFFFF },
+  { 0x1E23, 0x1D27, 0xFFFF },
+  { 0x0F10, 0x1F11, 0x153B, 0x192F, 0xFFFF },
+  { 0x0D2C, 0x123D, 0xFFFF },
+};
+
+typedef union
+{
+   struct comp {
+      unsigned char r;
+      unsigned char g;
+      unsigned char b;
+      unsigned char a;
+   } comp;
+
+   unsigned int m_u32;
+} color_quad_u8;
+
+static inline int
+rg_etc1_color_quad_u8_clamp(int v)
+{
+   /* FIXME: (From Wikipedia)
+    * "In C, the result of right-shifting a negative value is implementation-defined"
+    * The following code assumes right-shift will duplicate the sign bit.
+    */
+   if (v & 0xFFFFFF00U)
+     v = ((~v) >> 31) & 0xFF;
+   return v;
+}
+
+static inline void
+rg_etc1_color_quad_u8_init(color_quad_u8 *color, int r, int g, int b, int alpha)
+{
+   color->comp.r = rg_etc1_color_quad_u8_clamp(r);
+   color->comp.g = rg_etc1_color_quad_u8_clamp(g);
+   color->comp.b = rg_etc1_color_quad_u8_clamp(b);
+   color->comp.a = rg_etc1_color_quad_u8_clamp(alpha);
+}
+static inline void
+rg_etc1_color_quad_u8_copy(color_quad_u8 *dst, const color_quad_u8 *src)
+{
+   dst->m_u32 = src->m_u32;
+}
+
+static inline void
+rg_etc1_color_quad_u8_clear(color_quad_u8 *color)
+{
+   color->m_u32 = 0;
+}
+
+static inline unsigned int
+rg_etc1_color_quad_u8_rgb_squared_distance(color_quad_u8 color1, color_quad_u8 color2)
+{
+   return SQUARE((color1.comp.r - color2.comp.r)) + SQUARE((color1.comp.g - color2.comp.g)) + SQUARE((color1.comp.b - color2.comp.b));
+}
+
+#if RG_ETC1_CONSTRAINED_SUBBLOCK
+static inline void
+rg_etc1_color_quad_u8_component_set(color_quad_u8 *color, unsigned char idx, unsigned char value)
+{
+   switch (idx)
+     {
+      case 0: color->comp.r = value; break;
+      case 1: color->comp.g = value; break;
+      case 2: color->comp.b = value; break;
+      case 3: color->comp.a = value; break;
+      default: abort();
+     }
+}
+#endif
+
+#if 0
+static inline unsigned int
+rg_etc1_color_quad_duplicate_init(unsigned char y, unsigned char alpha)
+{
+   return ARGB_JOIN(alpha, y, y, y);
+}
+#endif
+
+static inline unsigned int
+rg_etc1_color_quad_init(unsigned char r, unsigned char g, unsigned char b, unsigned char alpha)
+{
+   return ARGB_JOIN(alpha, r, g, b);
+}
+
+static inline unsigned int
+rg_etc1_color_quad_set(unsigned int old_color, unsigned int new_color)
+{
+   return (new_color & ~A_MASK) | (old_color & A_MASK);
+}
+
+static inline void
+rg_etc1_color_quad_get(unsigned int color, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *alpha)
+{
+   // Used for PACKING
+   if (r) *r = R_VAL_GET(&color);
+   if (g) *g = G_VAL_GET(&color);
+   if (b) *b = B_VAL_GET(&color);
+   if (alpha) *alpha = A_VAL_GET(&color);
+}
+
+#if RG_ETC1_CONSTRAINED_SUBBLOCK
+static inline unsigned char
+rg_etc1_color_quad_component_get(unsigned int color, unsigned char idx)
+{
+   switch (idx)
+     {
+      // FIXME: Untested code (RGBA vs BGRA)
+      case 0: return R_VAL_GET(&color);
+      case 1: return G_VAL_GET(&color);
+      case 2: return B_VAL_GET(&color);
+      case 3: return A_VAL_GET(&color);
+      default: abort();
+     }
+   return 0;
+}
+#endif
+
+#if 0
+static inline unsigned int
+rg_etc1_color_quad_component_set(unsigned int color, unsigned char idx, unsigned char value)
+{
+   unsigned char r, g, b, a;
+
+   rg_etc1_color_quad_get(color, &r, &g, &b, &a);
+
+   switch (idx)
+     {
+      case 0: r = value; break;
+      case 1: g = value; break;
+      case 2: b = value; break;
+      case 3: a = value; break;
+      default: abort();
+     }
+
+   return rg_etc1_color_quad_init(r, g, b, a);
+}
+
+static inline unsigned int
+rg_etc1_color_quad_grayscale_set(unsigned int color, unsigned char l)
+{
+   unsigned char a;
+
+   a = A_VAL_SET(&color);
+
+   return rg_etc1_color_quad_init(l, l, l, a);
+}
+
+static inline unsigned int
+rg_etc1_color_quad_clamp(unsigned int color, unsigned int low, unsigned high)
+{
+   unsigned char *c = (unsigned char *)&color;
+   unsigned char *l = (unsigned char *)&low;
+   unsigned char *h = (unsigned char *)&high;
+   unsigned int i;
+
+   for (i = 0; i < 4; i++)
+     c[i] = CLAMP(c[i], l[i], h[i]);
+
+   return color;
+}
+
+static inline unsigned int
+rg_etc1_color_quad_component_clamp(unsigned int color, unsigned int low, unsigned high)
+{
+   unsigned char *c = (unsigned char *)&color;
+   unsigned int i;
+
+   for (i = 0; i < 4; i++)
+     c[i] = CLAMP(c[i], low, high);
+
+   return color;
+}
+
+// Returns CCIR 601 luma (consistent with color_utils::RGB_To_Y).
+static inline unsigned char
+rg_etc1_color_quad_luma601_get(unsigned int color)
+{
+   unsigned char r, g, b;
+   rg_etc1_color_quad_get(color, &r, &g, &b, NULL);
+   return ((19595U * r + 38470U * g + 7471U * b + 32768U) >> 16U);
+}
+
+// Returns REC 709 luma.
+static inline unsigned char
+rg_etc1_color_quad_luma709_get(unsigned int color)
+{
+   unsigned char r, g, b;
+   rg_etc1_color_quad_get(color, &r, &g, &b, NULL);
+   return ((13938U * r + 46869U * g + 4729U * b + 32768U) >> 16U);
+}
+
+static inline unsigned int
+rg_etc1_color_quad_rgb_squared_distance(unsigned int color1, unsigned int color2)
+{
+   unsigned char r1, g1, b1;
+   unsigned char r2, g2, b2;
+
+   rg_etc1_color_quad_get(color1, &r1, &g1, &b1, NULL);
+   rg_etc1_color_quad_get(color2, &r2, &g2, &b2, NULL);
+
+   return SQUARE(r1 - r2) + SQUARE(g1 - g2) + SQUARE(b1 - b2);
+}
+
+static inline unsigned int
+rg_etc1_color_quad_argb_squared_distance(unsigned int color1, unsigned int color2)
+{
+   unsigned char r1, g1, b1, a1;
+   unsigned char r2, g2, b2, a2;
+
+   rg_etc1_color_quad_get(color1, &r1, &g1, &b1, &a1);
+   rg_etc1_color_quad_get(color2, &r2, &g2, &b2, &a2);
+
+   return SQUARE(r1 - r2) + SQUARE(g1 - g2) + SQUARE(b1 - b2) + SQUARE(a1 - a1);
+}
+
+static inline unsigned char
+rg_etc1_color_quad_rgb_equals(unsigned int color1, unsigned int color2)
+{
+   A_VAL_SET(&color1) = 0;
+   A_VAL_SET(&color2) = 0;
+
+   return color1 == color2;
+}
+
+static inline unsigned int
+rg_etc1_color_quad_add(unsigned int color1, unsigned int color2)
+{
+   unsigned char *c1 = (unsigned char *)&color1;
+   unsigned char *c2 = (unsigned char *)&color2;
+   unsigned int i;
+
+   for (i = 0; i < 4; i++)
+     {
+        unsigned short t;
+
+        t = c1[i] + c2[i];
+        c1[i] = (unsigned char) (MIN(t, 255));
+     }
+
+   return color1;
+}
+
+static inline unsigned int
+rg_etc1_color_quad_del(unsigned int color1, unsigned int color2)
+{
+   unsigned char *c1 = (unsigned char *)&color1;
+   unsigned char *c2 = (unsigned char *)&color2;
+   unsigned int i;
+
+   for (i = 0; i < 4; i++)
+     {
+        short t;
+
+        t = c1[i] - c2[i];
+        c1[i] = (unsigned char) (CLAMP(t, 0, 255));
+     }
+
+   return color1;
+}
+#endif
+
+static inline void
+rg_etc1_vec_init(float v[3], float s)
+{
+   v[0] = s; v[1] = s; v[2] = s;
+}
+
+static inline void
+rg_etc1_vec_set(float v[3], float x, float y, float z)
+{
+   v[0] = x; v[1] = y; v[2] = z;
+}
+
+static inline void
+rg_etc1_vec_copy(float dst[3], float src[3])
+{
+   dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2];
+}
+
+static inline void
+rg_etc1_vec_add(float r[3], float a[3])
+{
+   unsigned int i;
+
+   //for (i = 0; i < RG_ETC1_ARRAY_SIZE(r); i++)
+   for (i = 0; i < 3; i++)
+     r[i] += a[i];
+}
+
+static inline void
+rg_etc1_vec_scale(float r[3], float s)
+{
+   unsigned int i;
+
+   //for (i = 0; i < RG_ETC1_ARRAY_SIZE(r); i++)
+   for (i = 0; i < 3; i++)
+     r[i] *= s;
+}
+
+static inline unsigned char
+rg_etc1_block_byte_bits_get(const unsigned char bytes[8], unsigned char offset, unsigned char num)
+{
+   const unsigned char byte_offset = 7 - (offset >> 3);
+   const unsigned char byte_bit_offset = offset & 7;
+
+   return (bytes[byte_offset] >> byte_bit_offset) & ((1 << num) - 1);
+}
+
+static inline void
+rg_etc1_block_byte_bits_set(unsigned char bytes[8], unsigned char offset, unsigned char num, unsigned char bits)
+{
+   const unsigned char byte_offset = 7 - (offset >> 3);
+   const unsigned char byte_bit_offset = offset & 7;
+   const unsigned char mask = (1 << num) - 1;
+   bytes[byte_offset] &= ~(mask << byte_bit_offset);
+   bytes[byte_offset] |= (((!!bits) & 0x1) << byte_bit_offset);
+}
+
+static inline unsigned char
+rg_etc1_block_flip_bit_get(const unsigned char bytes[8])
+{
+   return (bytes[3] & 1) != 0;
+}
+
+static inline void
+rg_etc1_block_flip_bit_set(unsigned char bytes[8], unsigned char flip)
+{
+   bytes[3] &= ~1;
+   bytes[3] |= (!!flip) & 0x1;
+}
+
+static inline unsigned char
+rg_etc1_block_diff_bit_get(const unsigned char bytes[8])
+{
+   return (bytes[3] & 2) != 0;
+}
+
+static inline void
+rg_etc1_block_diff_bit_set(unsigned char bytes[8], unsigned char diff)
+{
+   bytes[3] &= ~2;
+   bytes[3] |= ((!!diff) & 0x1) << 1;
+}
+
+static inline void
+rg_etc1_block_clear(unsigned char bytes[8])
+{
+   memset(bytes, 0, sizeof (unsigned char) * 8);
+}
+
+// Returns intensity modifier table (0-7) used by subblock subblock_id.
+// subblock_id=0 left/top (CW 1), 1=right/bottom (CW 2)
+static inline unsigned char
+rg_etc1_block_inten_table_get(const unsigned char bytes[8], unsigned char subblock_id)
+{
+   const unsigned char offset = subblock_id ? 2 : 5;
+   if (!(subblock_id < 2)) return 0; // ERROR CASE NO ASSERT IN EVAS CODE
+   return (bytes[3] >> offset) & 7;
+}
+
+// Sets intensity modifier table (0-7) used by subblock subblock_id (0 or 1)
+static inline void
+rg_etc1_block_inten_table_set(unsigned char bytes[8], unsigned char subblock_id, unsigned char t)
+{
+   const unsigned char offset = subblock_id ? 2 : 5;
+   // ERROR CASE NO ASSERT IN EVAS CODE
+   if (!(subblock_id < 2) || !(t < 8)) return ;
+   bytes[3] &= ~(7 << offset);
+   bytes[3] |= (t << offset);
+}
+
+// Returned selector value ranges from 0-3 and is a direct index into g_etc1_inten_tables.
+static inline unsigned char
+rg_etc1_block_selector_get(const unsigned char bytes[8], unsigned char x, unsigned char y)
+{
+   // ERROR CASE NO ASSERT IN EVAS CODE
+   if (!((x | y) < 4)) return 0;
+
+   const unsigned char bit_index = x * 4 + y;
+   const unsigned char byte_bit_offset = bit_index & 7;
+   const unsigned char *p = &bytes[7 - (bit_index >> 3)];
+   const unsigned char lsb = (p[0] >> byte_bit_offset) & 1;
+   const unsigned char msb = (p[-2] >> byte_bit_offset) & 1;
+   const unsigned char val = lsb | (msb << 1);
+
+   return rg_etc1_to_selector_index[val];
+}
+
+// Selector "val" ranges from 0-3 and is a direct index into g_etc1_inten_tables.
+static inline void
+rg_etc1_block_selector_set(unsigned char bytes[8], unsigned char x, unsigned char y, unsigned char val)
+{
+   // ERROR CASE NO ASSERT IN EVAS CODE
+   if (!((x | y) < 4)) return ;
+
+   const unsigned char bit_index = x * 4 + y;
+
+   unsigned char *p = &bytes[7 - (bit_index >> 3)];
+
+   const unsigned char byte_bit_offsets = bit_index & 7;
+   const unsigned char mask = 1 << byte_bit_offsets;
+   const unsigned char etc1_val = rg_etc_selector_index_to_etc1[val];
+
+   const unsigned char lsb = etc1_val & 1;
+   const unsigned char msb = etc1_val >> 1;
+
+   p[0] &= ~mask;
+   p[0] |= (lsb << byte_bit_offsets);
+
+   p[-2] &= ~mask;
+   p[-2] |= (msb << byte_bit_offsets);
+}
+
+static inline unsigned short
+rg_etc_block_base4_color_get(const unsigned char bytes[8], unsigned char idx)
+{
+   unsigned short r, g, b;
+
+   if (idx)
+     {
+        r = (bytes[0]) & ((1 << 4) - 1);
+        g = (bytes[1]) & ((1 << 4) - 1);
+        b = (bytes[2]) & ((1 << 4) - 1);
+     }
+   else
+     {
+        r = (bytes[0] >> 4) & ((1 << 4) - 1);
+        g = (bytes[1] >> 4) & ((1 << 4) - 1);
+        b = (bytes[2] >> 4) & ((1 << 4) - 1);
+     }
+
+   return b | (g << 4) | (r << 8);
+}
+
+static inline void
+rg_etc1_block_base4_color_set(unsigned char bytes[8], unsigned char idx, unsigned short c)
+{
+   if (idx)
+     {
+        rg_etc1_block_byte_bits_set(bytes, cETC1AbsColor4R2BitOffset, 4, (c >> 8) & 15);
+        rg_etc1_block_byte_bits_set(bytes, cETC1AbsColor4G2BitOffset, 4, (c >> 4) & 15);
+        rg_etc1_block_byte_bits_set(bytes, cETC1AbsColor4B2BitOffset, 4, c & 15);
+     }
+   else
+     {
+        rg_etc1_block_byte_bits_set(bytes, cETC1AbsColor4R1BitOffset, 4, (c >> 8) & 15);
+        rg_etc1_block_byte_bits_set(bytes, cETC1AbsColor4G1BitOffset, 4, (c >> 4) & 15);
+        rg_etc1_block_byte_bits_set(bytes, cETC1AbsColor4B1BitOffset, 4, c & 15);
+     }
+}
+
+static inline unsigned short
+rg_etc1_block_base5_color_get(const unsigned char bytes[8])
+{
+   unsigned short r, g, b;
+
+   r = (bytes[0] >> 3) & ((1 << 5) - 1);
+   g = (bytes[1] >> 3) & ((1 << 5) - 1);
+   b = (bytes[2] >> 3) & ((1 << 5) - 1);
+
+   return b | (g << 5) | (r << 10);
+}
+
+static inline void
+rg_etc1_block_base5_color_set(unsigned char bytes[8], unsigned short c)
+{
+   rg_etc1_block_byte_bits_set(bytes, cETC1BaseColor5RBitOffset, 5, (c >> 10) & 31);
+   rg_etc1_block_byte_bits_set(bytes, cETC1BaseColor5GBitOffset, 5, (c >> 5) & 31);
+   rg_etc1_block_byte_bits_set(bytes, cETC1BaseColor5BBitOffset, 5, c & 31);
+}
+
+static inline unsigned short
+rg_etc1_block_delta3_color_get(const unsigned char bytes[8])
+{
+   unsigned short r, g, b;
+
+   r = (bytes[0]) & ((1 << 3) - 1);
+   g = (bytes[1]) & ((1 << 3) - 1);
+   b = (bytes[2]) & ((1 << 3) - 1);
+
+   return b | (g << 3) | (r << 6);
+}
+
+static inline void
+rg_etc1_block_delta3_color_set(unsigned char bytes[8], unsigned short c)
+{
+   rg_etc1_block_byte_bits_set(bytes, cETC1DeltaColor3RBitOffset, 3, (c >> 6) & 7);
+   rg_etc1_block_byte_bits_set(bytes, cETC1DeltaColor3GBitOffset, 3, (c >> 3) & 7);
+   rg_etc1_block_byte_bits_set(bytes, cETC1DeltaColor3BBitOffset, 3, c & 7);
+}
+
+static inline unsigned short
+rg_etc1_block_color5_component_pack(unsigned char r, unsigned char g, unsigned char b,
+                                    unsigned char scaled, unsigned char bias)
+{
+   if (scaled)
+     {
+        r = (r * 31 + bias) / 255U;
+        g = (g * 31 + bias) / 255U;
+        b = (b * 31 + bias) / 255U;
+     }
+
+   r = MIN(r, 31);
+   g = MIN(g, 31);
+   b = MIN(b, 31);
+
+   return b | (g << 5) | (r << 10);
+}
+
+static inline unsigned short
+rg_etc1_block_color5_pack(unsigned int c, unsigned char scaled, unsigned char bias)
+{
+   unsigned char r, g, b;
+
+   rg_etc1_color_quad_get(c, &r, &g, &b, NULL);
+   return rg_etc1_block_color5_component_pack(r, g, b, scaled, bias);
+}
+
+static inline void
+rg_etc1_block_color5_component_unpack(unsigned char *r, unsigned char *g, unsigned char *b,
+                                      unsigned short packed_color5, unsigned scaled)
+{
+   *r = (packed_color5 >> 10) & 31;
+   *g = (packed_color5 >> 5) & 31;
+   *b = packed_color5 & 31;
+
+   if (scaled)
+     {
+        *b = (*b << 3) | (*b >> 2);
+        *g = (*g << 3) | (*g >> 2);
+        *r = (*r << 3) | (*r >> 2);
+     }
+}
+
+static inline unsigned int
+rg_etc1_block_color5_unpack(unsigned short packed_color5, unsigned char scaled, unsigned char alpha)
+{
+   unsigned char r, g, b;
+
+   rg_etc1_block_color5_component_unpack(&r, &g, &b, packed_color5, scaled);
+
+   return rg_etc1_color_quad_init(r, g, b, MIN(alpha, 255));
+}
+
+// Inputs range from -4 to 3 (cETC1ColorDeltaMin to cETC1ColorDeltaMax)
+static inline unsigned int
+rg_etc1_block_delta3_pack(char r, char g, char b)
+{
+   // ERROR CASE NO ASSERT IN EVAS CODE
+   if (!((r >= cETC1ColorDeltaMin) && (r <= cETC1ColorDeltaMax))) return 0;
+   if (!((g >= cETC1ColorDeltaMin) && (g <= cETC1ColorDeltaMax))) return 0;
+   if (!((b >= cETC1ColorDeltaMin) && (b <= cETC1ColorDeltaMax))) return 0;
+
+   if (r < 0) r += 8;
+   if (g < 0) g += 8;
+   if (b < 0) b += 8;
+
+   return b | (g << 3) | (r << 6);
+}
+
+// Results range from -4 to 3 (cETC1ColorDeltaMin to cETC1ColorDeltaMax)
+static inline void
+rg_etc1_block_delta3_unpack(char *r, char *g, char *b, unsigned short packed_delta3)
+{
+   *r = (packed_delta3 >> 6) & 7;
+   *g = (packed_delta3 >> 3) & 7;
+   *b = packed_delta3 & 7;
+
+   if (*r >= 4) *r -= 8;
+   if (*g >= 4) *g -= 8;
+   if (*b >= 4) *b -= 8;
+}
+
+static inline unsigned short
+rg_etc1_block_color4_component_pack(unsigned char r, unsigned char g, unsigned char b,
+                                    unsigned char scaled, unsigned char bias)
+{
+   if (scaled)
+     {
+        r = (r * 15 + bias) / 255;
+        g = (g * 15 + bias) / 255;
+        b = (b * 15 + bias) / 255;
+     }
+
+   r = MIN(r, 15);
+   g = MIN(g, 15);
+   b = MIN(b, 15);
+
+   return b | (g << 4) | (r << 8);
+}
+
+static inline unsigned short
+rg_etc1_block_color4_pack(unsigned int color, unsigned char scaled, unsigned char bias)
+{
+   unsigned char r, g, b;
+
+   rg_etc1_color_quad_get(color, &r, &g, &b, NULL);
+   return rg_etc1_block_color4_component_pack(r, g, b, scaled, bias);
+}
+
+static inline void
+rg_etc1_block_color4_component_unpack(unsigned char *r, unsigned char *g, unsigned char *b,
+                                      unsigned short packed_color4, bool scaled)
+{
+   *r = (packed_color4 >> 8) & 15;
+   *g = (packed_color4 >> 4) & 15;
+   *b = packed_color4 & 15;
+
+   if (scaled)
+     {
+        *b = (*b << 4) | *b;
+        *g = (*g << 4) | *g;
+        *r = (*r << 4) | *r;
+     }
+}
+
+static inline unsigned int
+rg_etc1_block_color4_unpack(unsigned short packed_color4, unsigned char scaled, unsigned char alpha)
+{
+   unsigned char r, g, b;
+
+   rg_etc1_block_color4_component_unpack(&r, &g, &b, packed_color4, scaled);
+
+   return rg_etc1_color_quad_init(r, g, b, alpha);
+}
+
+
+static inline unsigned char
+rg_etc1_block_color5_delta3_component_unpack(unsigned char *r, unsigned char *g, unsigned char *b,
+                                             unsigned short packed_color5, unsigned short packed_delta3, bool scaled)
+{
+   unsigned char success = 1;
+   char dc_r, dc_g, dc_b;
+
+   rg_etc1_block_delta3_unpack(&dc_r, &dc_g, &dc_b, packed_delta3);
+
+   *r = ((packed_color5 >> 10) & 31) + dc_r;
+   *g = ((packed_color5 >> 5) & 31) + dc_g;
+   *b = (packed_color5 & 31) + dc_b;
+
+   if ((*r | *g | *b) > 31)
+     {
+        success = 0;
+        *r = MIN(*r, 31);
+        *g = MIN(*g, 31);
+        *b = MIN(*b, 31);
+     }
+
+   if (scaled)
+     {
+        *r = (*r << 3) | (*r >> 2);
+        *g = (*g << 3) | (*g >> 2);
+        *b = (*b << 3) | (*b >> 2);
+     }
+
+   return success;
+}
+
+
+static inline unsigned char
+rg_etc1_block_color5_delta3_unpack(unsigned int *result,
+                                   unsigned short packed_color5, unsigned short packed_delta3,
+                                   bool scaled, unsigned char alpha)
+{
+   unsigned char success;
+   unsigned char r, g, b;
+
+   success = rg_etc1_block_color5_delta3_component_unpack(&r, &g, &b, packed_color5, packed_delta3, scaled);
+
+   *result = rg_etc1_color_quad_init(r, g, b, alpha);
+   return success;
+}
+
+static inline void
+rg_etc1_block_sublock_diff(unsigned int dst[4], const int *pInten_modifer_table,
+                           unsigned char r, unsigned char g, unsigned char b)
+{
+   int i;
+
+   for (i = 0; i < 4; i++)
+     {
+        int y = pInten_modifer_table[i];
+
+        dst[i] = rg_etc1_color_quad_init(CLAMP((int)r + y, 0, 255),
+                                         CLAMP((int) g + y,0, 255),
+                                         CLAMP((int) b + y,0, 255),
+                                         255);
+     }
+}
+
+static inline void
+rg_etc1_block_subblock_color5_diff_get(unsigned int dst[4], unsigned short packed_color5, unsigned char table_idx)
+{
+   const int *pInten_modifer_table;
+   unsigned char r, g, b;
+
+   // ERROR CASE NO ASSERT IN EVAS CODE
+   if (!(table_idx < cETC1IntenModifierValues)) return ;
+
+   rg_etc1_block_color5_component_unpack(&r, &g, &b, packed_color5, 1);
+
+   pInten_modifer_table = &rg_etc1_inten_tables[table_idx][0];
+   rg_etc1_block_sublock_diff(dst, pInten_modifer_table, r, g, b);
+}
+
+static inline unsigned char
+rg_etc1_block_subblock_color5_delta3_diff_get(unsigned int dst[4],
+                                              unsigned short packed_color5, unsigned short packed_delta3,
+                                              unsigned char table_idx)
+{
+   const int *pInten_modifer_table;
+   unsigned char r, g, b;
+   unsigned char success;
+
+   // ERROR CASE NO ASSERT IN EVAS CODE
+   if (!(table_idx < cETC1IntenModifierValues))
+     {
+        fprintf(stderr, "table_idx %i < %i\n", table_idx, cETC1IntenModifierValues);
+        return 0;
+     }
+
+   success = rg_etc1_block_color5_delta3_component_unpack(&r, &g, &b, packed_color5, packed_delta3, 1);
+
+   pInten_modifer_table = &rg_etc1_inten_tables[table_idx][0];
+   rg_etc1_block_sublock_diff(dst, pInten_modifer_table, r, g, b);
+
+   return success;
+}
+
+static inline void
+rg_etc1_block_subblock_color4_abs_get(unsigned int dst[4], unsigned short packed_color4, unsigned char table_idx)
+{
+   const int *pInten_modifer_table;
+   unsigned char r, g, b;
+
+   // ERROR CASE NO ASSERT IN EVAS CODE
+   if (!(table_idx < cETC1IntenModifierValues)) return ;
+
+   rg_etc1_block_color4_component_unpack(&r, &g, &b, packed_color4, 1);
+
+   pInten_modifer_table = &rg_etc1_inten_tables[table_idx][0];
+   rg_etc1_block_sublock_diff(dst, pInten_modifer_table, r, g, b);
+}
+
+// This is the exported function to unpack a block
+bool
+rg_etc1_unpack_block(const void *ETC1_block, unsigned int *pDst_pixels_BGRA, bool preserve_alpha)
+{
+   unsigned char diff_flag, flip_flag, table_index0, table_index1;
+   unsigned int subblock_colors0[4] = { 0 };
+   unsigned int subblock_colors1[4] = { 0 };
+   unsigned char success = 1;
+   const unsigned char *bytes;
+   bytes = (unsigned char *)ETC1_block;
+
+   diff_flag = rg_etc1_block_diff_bit_get(ETC1_block);
+   flip_flag = rg_etc1_block_flip_bit_get(ETC1_block);
+   table_index0 = (bytes[3] >> 5) & 7;
+   table_index1 = (bytes[3] >> 2) & 7;
+
+   if (diff_flag)
+     {
+        unsigned short base_color5, delta_color3;
+
+        base_color5 = rg_etc1_block_base5_color_get(ETC1_block);
+        delta_color3 = rg_etc1_block_delta3_color_get(ETC1_block);
+
+        rg_etc1_block_subblock_color5_diff_get(subblock_colors0, base_color5, table_index0);
+        success = rg_etc1_block_subblock_color5_delta3_diff_get(subblock_colors1,
+                                                                base_color5, delta_color3,
+                                                                table_index1);
+     }
+   else
+     {
+        unsigned short base_color4_0, base_color4_1;
+
+        base_color4_0 = rg_etc_block_base4_color_get(ETC1_block, 0);
+        base_color4_1 = rg_etc_block_base4_color_get(ETC1_block, 1);
+
+        rg_etc1_block_subblock_color4_abs_get(subblock_colors0, base_color4_0, table_index0);
+        rg_etc1_block_subblock_color4_abs_get(subblock_colors1, base_color4_1, table_index1);
+     }
+
+   // FIXME: preserve_alpha and continue
+   // Block is either :
+   //  0000
+   //  0000
+   //  1111
+   //  1111
+   // or :
+   //  0011
+   //  0011
+   //  0011
+   //  0011
+   unsigned char val0 = (bytes[7] & 1) | ((bytes[5] & 1) << 1);
+   unsigned char val1 = ((bytes[7] >> 4) & 1) | (((bytes[5] >> 4) & 1) << 1);
+   unsigned char val2 = (bytes[6] & 1) | ((bytes[4] & 1) << 1);
+   unsigned char val3 = ((bytes[6] >> 4) & 1) | (((bytes[4] >> 4) & 1) << 1);
+   unsigned char val4 = ((bytes[7] >> 1) & 1) | (((bytes[5] >> 1) & 1) << 1);
+   unsigned char val5 = ((bytes[7] >> 5) & 1) | (((bytes[5] >> 5) & 1) << 1);
+   unsigned char val6 = ((bytes[6] >> 1) & 1) | (((bytes[4] >> 1) & 1) << 1);
+   unsigned char val7 = ((bytes[6] >> 5) & 1) | (((bytes[4] >> 5) & 1) << 1);
+   unsigned char val8 = ((bytes[7] >> 2) & 1) | (((bytes[5] >> 2) & 1) << 1);
+   unsigned char val9 = ((bytes[7] >> 6) & 1) | (((bytes[5] >> 6) & 1) << 1);
+   unsigned char val10 = ((bytes[6] >> 2) & 1) | (((bytes[4] >> 2) & 1) << 1);
+   unsigned char val11 = ((bytes[6] >> 6) & 1) | (((bytes[4] >> 6) & 1) << 1);
+   unsigned char val12 = ((bytes[7] >> 3) & 1) | (((bytes[5] >> 3) & 1) << 1);
+   unsigned char val13 = ((bytes[7] >> 7) & 1) | (((bytes[5] >> 7) & 1) << 1);
+   unsigned char val14 = ((bytes[6] >> 3) & 1) | (((bytes[4] >> 3) & 1) << 1);
+   unsigned char val15 = ((bytes[6] >> 7) & 1) | (((bytes[4] >> 7) & 1) << 1);
+
+   if (preserve_alpha)   // Depending on flip_flag.
+      {
+       if (flip_flag)
+         {
+            pDst_pixels_BGRA[0] = rg_etc1_color_quad_set(pDst_pixels_BGRA[0],
+                                               subblock_colors0[rg_etc1_to_selector_index[val0]]);
+            pDst_pixels_BGRA[1] = rg_etc1_color_quad_set(pDst_pixels_BGRA[1],
+                                               subblock_colors0[rg_etc1_to_selector_index[val1]]);
+            pDst_pixels_BGRA[2] = rg_etc1_color_quad_set(pDst_pixels_BGRA[2],
+                                               subblock_colors0[rg_etc1_to_selector_index[val2]]);
+            pDst_pixels_BGRA[3] = rg_etc1_color_quad_set(pDst_pixels_BGRA[3],
+                                               subblock_colors0[rg_etc1_to_selector_index[val3]]);
+            pDst_pixels_BGRA[4] = rg_etc1_color_quad_set(pDst_pixels_BGRA[4],
+                                               subblock_colors0[rg_etc1_to_selector_index[val4]]);
+            pDst_pixels_BGRA[5] = rg_etc1_color_quad_set(pDst_pixels_BGRA[5],
+                                               subblock_colors0[rg_etc1_to_selector_index[val5]]);
+            pDst_pixels_BGRA[6] = rg_etc1_color_quad_set(pDst_pixels_BGRA[6],
+                                               subblock_colors0[rg_etc1_to_selector_index[val6]]);
+            pDst_pixels_BGRA[7] = rg_etc1_color_quad_set(pDst_pixels_BGRA[7],
+                                               subblock_colors0[rg_etc1_to_selector_index[val7]]);
+            pDst_pixels_BGRA[8] = rg_etc1_color_quad_set(pDst_pixels_BGRA[8],
+                                               subblock_colors1[rg_etc1_to_selector_index[val8]]);
+            pDst_pixels_BGRA[9] = rg_etc1_color_quad_set(pDst_pixels_BGRA[9],
+                                               subblock_colors1[rg_etc1_to_selector_index[val9]]);
+            pDst_pixels_BGRA[10] = rg_etc1_color_quad_set(pDst_pixels_BGRA[10],
+                                               subblock_colors1[rg_etc1_to_selector_index[val10]]);
+            pDst_pixels_BGRA[11] = rg_etc1_color_quad_set(pDst_pixels_BGRA[11],
+                                               subblock_colors1[rg_etc1_to_selector_index[val11]]);
+            pDst_pixels_BGRA[12] = rg_etc1_color_quad_set(pDst_pixels_BGRA[12],
+                                               subblock_colors1[rg_etc1_to_selector_index[val12]]);
+            pDst_pixels_BGRA[13] = rg_etc1_color_quad_set(pDst_pixels_BGRA[13],
+                                               subblock_colors1[rg_etc1_to_selector_index[val13]]);
+            pDst_pixels_BGRA[14] = rg_etc1_color_quad_set(pDst_pixels_BGRA[14],
+                                               subblock_colors1[rg_etc1_to_selector_index[val14]]);
+            pDst_pixels_BGRA[15] = rg_etc1_color_quad_set(pDst_pixels_BGRA[15],
+                                               subblock_colors1[rg_etc1_to_selector_index[val15]]);
+         }
+       else
+         {
+            pDst_pixels_BGRA[0] = rg_etc1_color_quad_set(pDst_pixels_BGRA[0],
+                                               subblock_colors0[rg_etc1_to_selector_index[val0]]);
+            pDst_pixels_BGRA[1] = rg_etc1_color_quad_set(pDst_pixels_BGRA[1],
+                                               subblock_colors0[rg_etc1_to_selector_index[val1]]);
+            pDst_pixels_BGRA[2] = rg_etc1_color_quad_set(pDst_pixels_BGRA[2],
+                                               subblock_colors1[rg_etc1_to_selector_index[val2]]);
+            pDst_pixels_BGRA[3] = rg_etc1_color_quad_set(pDst_pixels_BGRA[3],
+                                               subblock_colors1[rg_etc1_to_selector_index[val3]]);
+            pDst_pixels_BGRA[4] = rg_etc1_color_quad_set(pDst_pixels_BGRA[4],
+                                               subblock_colors0[rg_etc1_to_selector_index[val4]]);
+            pDst_pixels_BGRA[5] = rg_etc1_color_quad_set(pDst_pixels_BGRA[5],
+                                               subblock_colors0[rg_etc1_to_selector_index[val5]]);
+            pDst_pixels_BGRA[6] = rg_etc1_color_quad_set(pDst_pixels_BGRA[6],
+                                               subblock_colors1[rg_etc1_to_selector_index[val6]]);
+            pDst_pixels_BGRA[7] = rg_etc1_color_quad_set(pDst_pixels_BGRA[7],
+                                               subblock_colors1[rg_etc1_to_selector_index[val7]]);
+            pDst_pixels_BGRA[8] = rg_etc1_color_quad_set(pDst_pixels_BGRA[8],
+                                               subblock_colors0[rg_etc1_to_selector_index[val8]]);
+            pDst_pixels_BGRA[9] = rg_etc1_color_quad_set(pDst_pixels_BGRA[9],
+                                               subblock_colors0[rg_etc1_to_selector_index[val9]]);
+            pDst_pixels_BGRA[10] = rg_etc1_color_quad_set(pDst_pixels_BGRA[10],
+                                               subblock_colors1[rg_etc1_to_selector_index[val10]]);
+            pDst_pixels_BGRA[11] = rg_etc1_color_quad_set(pDst_pixels_BGRA[11],
+                                               subblock_colors1[rg_etc1_to_selector_index[val11]]);
+            pDst_pixels_BGRA[12] = rg_etc1_color_quad_set(pDst_pixels_BGRA[12],
+                                               subblock_colors0[rg_etc1_to_selector_index[val12]]);
+            pDst_pixels_BGRA[13] = rg_etc1_color_quad_set(pDst_pixels_BGRA[13],
+                                               subblock_colors0[rg_etc1_to_selector_index[val13]]);
+            pDst_pixels_BGRA[14] = rg_etc1_color_quad_set(pDst_pixels_BGRA[14],
+                                               subblock_colors1[rg_etc1_to_selector_index[val14]]);
+            pDst_pixels_BGRA[15] = rg_etc1_color_quad_set(pDst_pixels_BGRA[15],
+                                               subblock_colors1[rg_etc1_to_selector_index[val15]]);
+         }
+      }
+      else
+      {
+       if (flip_flag)
+         {
+            pDst_pixels_BGRA[0] = subblock_colors0[rg_etc1_to_selector_index[val0]];
+            pDst_pixels_BGRA[1] = subblock_colors0[rg_etc1_to_selector_index[val1]];
+            pDst_pixels_BGRA[2] = subblock_colors0[rg_etc1_to_selector_index[val2]];
+            pDst_pixels_BGRA[3] = subblock_colors0[rg_etc1_to_selector_index[val3]];
+            pDst_pixels_BGRA[4] = subblock_colors0[rg_etc1_to_selector_index[val4]];
+            pDst_pixels_BGRA[5] = subblock_colors0[rg_etc1_to_selector_index[val5]];
+            pDst_pixels_BGRA[6] = subblock_colors0[rg_etc1_to_selector_index[val6]];
+            pDst_pixels_BGRA[7] = subblock_colors0[rg_etc1_to_selector_index[val7]];
+            pDst_pixels_BGRA[8] = subblock_colors1[rg_etc1_to_selector_index[val8]];
+            pDst_pixels_BGRA[9] = subblock_colors1[rg_etc1_to_selector_index[val9]];
+            pDst_pixels_BGRA[10] = subblock_colors1[rg_etc1_to_selector_index[val10]];
+            pDst_pixels_BGRA[11] = subblock_colors1[rg_etc1_to_selector_index[val11]];
+            pDst_pixels_BGRA[12] = subblock_colors1[rg_etc1_to_selector_index[val12]];
+            pDst_pixels_BGRA[13] = subblock_colors1[rg_etc1_to_selector_index[val13]];
+            pDst_pixels_BGRA[14] = subblock_colors1[rg_etc1_to_selector_index[val14]];
+            pDst_pixels_BGRA[15] = subblock_colors1[rg_etc1_to_selector_index[val15]];
+         }
+       else
+         {
+            pDst_pixels_BGRA[0] = subblock_colors0[rg_etc1_to_selector_index[val0]];
+            pDst_pixels_BGRA[1] = subblock_colors0[rg_etc1_to_selector_index[val1]];
+            pDst_pixels_BGRA[2] = subblock_colors1[rg_etc1_to_selector_index[val2]];
+            pDst_pixels_BGRA[3] = subblock_colors1[rg_etc1_to_selector_index[val3]];
+            pDst_pixels_BGRA[4] = subblock_colors0[rg_etc1_to_selector_index[val4]];
+            pDst_pixels_BGRA[5] = subblock_colors0[rg_etc1_to_selector_index[val5]];
+            pDst_pixels_BGRA[6] = subblock_colors1[rg_etc1_to_selector_index[val6]];
+            pDst_pixels_BGRA[7] = subblock_colors1[rg_etc1_to_selector_index[val7]];
+            pDst_pixels_BGRA[8] = subblock_colors0[rg_etc1_to_selector_index[val8]];
+            pDst_pixels_BGRA[9] = subblock_colors0[rg_etc1_to_selector_index[val9]];
+            pDst_pixels_BGRA[10] = subblock_colors1[rg_etc1_to_selector_index[val10]];
+            pDst_pixels_BGRA[11] = subblock_colors1[rg_etc1_to_selector_index[val11]];
+            pDst_pixels_BGRA[12] = subblock_colors0[rg_etc1_to_selector_index[val12]];
+            pDst_pixels_BGRA[13] = subblock_colors0[rg_etc1_to_selector_index[val13]];
+            pDst_pixels_BGRA[14] = subblock_colors1[rg_etc1_to_selector_index[val14]];
+            pDst_pixels_BGRA[15] = subblock_colors1[rg_etc1_to_selector_index[val15]];
+         }
+      }
+
+   return success;
+}
+
+// NOTE: Most of the following loop could be unrolled, but for sanity and readability, I did
+// prefer to stick to simpler solution.
+static inline unsigned int *
+rg_etc1_indirect_radix_sort(unsigned int num_indices, unsigned int pIndices0[8], unsigned int pIndices1[8],
+                            const unsigned short pKeys[8], unsigned int key_ofs, unsigned char key_size,
+                            unsigned char init_indices)
+{
+   unsigned int hist[256 * 4];
+   unsigned int *p;
+   unsigned int *q;
+   unsigned int *pCur;
+   unsigned int *pNew;
+   unsigned int key;
+   unsigned int pass;
+
+   // ERROR CASE NO ASSERT IN EVAS CODE
+   if (!(key_ofs < sizeof(unsigned int) * 8)) return NULL;
+   if (!((key_size >= 1) && (key_size <= 4))) return NULL;
+
+   if (init_indices)
+     {
+        unsigned int i;
+
+        p = pIndices0;
+        for (i = 0; i < num_indices; p++, i++)
+          *p = i;
+     }
+
+   memset(hist, 0, sizeof (hist));
+
+#define RG_ETC1_GET_KEY(p) (*(const unsigned int*)((const unsigned char*)(pKeys + *(p)) + key_ofs))
+#define RG_ETC1_GET_KEY_FROM_INDEX(i) (*(const unsigned int*)((const unsigned char*)(pKeys + (i)) + key_ofs))
+
+   switch (key_size)
+     {
+      case 4:
+         p = pIndices0;
+         q = pIndices0 + num_indices;
+
+         for (; p != q; p++)
+           {
+              key = RG_ETC1_GET_KEY(p);
+
+              hist[        key        & 0xFF]++;
+              hist[256 + ((key >>  8) & 0xFF)]++;
+              hist[512 + ((key >> 16) & 0xFF)]++;
+              hist[768 + ((key >> 24) & 0xFF)]++;
+           }
+         break;
+      case 3:
+         p = pIndices0;
+         q = pIndices0 + num_indices;
+
+         for ( ; p != q; p++)
+           {
+              key = RG_ETC1_GET_KEY(p);
+
+              hist[        key        & 0xFF]++;
+              hist[256 + ((key >>  8) & 0xFF)]++;
+              hist[512 + ((key >> 16) & 0xFF)]++;
+           }
+         break;
+      case 2:
+         p = pIndices0;
+         q = pIndices0 + num_indices;
+
+         for ( ; p != q; p++)
+           {
+              key = RG_ETC1_GET_KEY(p);
+
+              hist[        key        & 0xFF]++;
+              hist[256 + ((key >>  8) & 0xFF)]++;
+           }
+         break;
+      case 1:
+         p = pIndices0;
+         q = pIndices0 + num_indices;
+
+         for ( ; p != q; p++)
+           {
+              key = RG_ETC1_GET_KEY(p);
+
+              hist[key & 0xFF]++;
+           }
+         break;
+      default:
+         abort();
+     }
+
+   pCur = pIndices0;
+   pNew = pIndices1;
+
+   for (pass = 0; pass < key_size; pass++)
+     {
+        unsigned int offsets[256];
+        const unsigned int *pHist = &hist[pass << 8];
+        unsigned int *t;
+        unsigned int cur_ofs = 0;
+        unsigned int i;
+        unsigned int pass_shift = pass << 3;
+
+        for (i = 0; i < 256; i++)
+          {
+             offsets[i] = cur_ofs;
+             cur_ofs += pHist[i];
+          }
+
+        q = pCur + num_indices;
+        for (p = pCur; p != q; p++)
+          {
+             unsigned int dst_offset;
+             unsigned int idx = p[0];
+             unsigned int c = (RG_ETC1_GET_KEY_FROM_INDEX(idx) >> pass_shift) & 0xFF;
+
+             dst_offset = offsets[c]++;
+             pNew[dst_offset] = idx;
+          }
+
+        t = pCur;
+        pCur = pNew;
+        pNew = t;
+     }
+
+   return pCur;
+}
+
+typedef struct _Etc1_Solution_Coordinates Etc1_Solution_Coordinates;
+struct _Etc1_Solution_Coordinates
+{
+   color_quad_u8 m_unscaled_color;
+   unsigned int m_inten_table;
+   unsigned char m_color4;
+};
+
+static inline void
+rg_etc1_solution_coordinates_component_set(Etc1_Solution_Coordinates *solution,
+                                           int r, int g, int b,
+                                           unsigned int inten_table, unsigned char color4)
+{
+   rg_etc1_color_quad_u8_init(&solution->m_unscaled_color, r, g, b, 255);
+   solution->m_inten_table = inten_table;
+   solution->m_color4 = color4;
+}
+
+static inline void
+rg_etc1_solution_coordinates_set(Etc1_Solution_Coordinates *solution,
+                                 color_quad_u8 unscaled_color, unsigned int inten_table, unsigned char color4)
+{
+   rg_etc1_color_quad_u8_copy(&solution->m_unscaled_color, &unscaled_color);
+   solution->m_inten_table = inten_table;
+   solution->m_color4 = color4;
+}
+
+static inline void
+rg_etc1_solution_coordinates_clear(Etc1_Solution_Coordinates *solution)
+{
+   memset(solution, 0, sizeof (Etc1_Solution_Coordinates));
+}
+
+static inline void
+rg_etc1_solution_coordinates_component_get(const Etc1_Solution_Coordinates *solution,
+                                           unsigned char *r, unsigned char *g, unsigned char *b)
+{
+   *r = solution->m_unscaled_color.comp.r;
+   *g = solution->m_unscaled_color.comp.g;
+   *b = solution->m_unscaled_color.comp.b;
+
+   if (solution->m_color4)
+     {
+        *r = *r | (*r << 4);
+        *g = *g | (*g << 4);
+        *b = *b | (*b << 4);
+     }
+   else
+     {
+        *r = (*r >> 2) | (*r << 3);
+        *g = (*g >> 2) | (*g << 3);
+        *b = (*b >> 2) | (*b << 3);
+     }
+}
+
+static inline void
+rg_etc1_solution_coordinates_get_scaled_color(color_quad_u8 *color, const Etc1_Solution_Coordinates *coords)
+{
+   unsigned char br, bg, bb;
+
+   rg_etc1_solution_coordinates_component_get(coords, &br, &bg, &bb);
+   rg_etc1_color_quad_u8_init(color, br, bg, bb, 255);
+}
+
+static inline void
+rg_etc1_solution_coordinates_block_colors_get(const Etc1_Solution_Coordinates *coords, color_quad_u8 colors[4])
+{
+   const int* pInten_table = rg_etc1_inten_tables[coords->m_inten_table];
+   unsigned char i;
+   unsigned char br, bg, bb;
+
+   rg_etc1_solution_coordinates_component_get(coords, &br, &bg, &bb);
+
+   for (i = 0; i < 4; i++)
+     rg_etc1_color_quad_u8_init(&colors[i], br + pInten_table[i], bg + pInten_table[i], bb + pInten_table[i], 255);
+}
+
+static inline void
+rg_etc1_pack_params_clear(rg_etc1_pack_params *params)
+{
+   params->m_quality = rg_etc1_high_quality;
+   params->m_dithering = EINA_FALSE;
+}
+
+static const int rg_etc1_default_scan_delta[] = { 0 };
+
+typedef struct _rg_etc1_optimizer_params rg_etc1_optimizer_params;
+struct _rg_etc1_optimizer_params
+{
+   rg_etc1_pack_params *base_params;
+   uint m_num_src_pixels;
+   const color_quad_u8* m_pSrc_pixels;
+
+   bool m_use_color4;
+   const int* m_pScan_deltas;
+   uint m_scan_delta_size;
+
+   color_quad_u8 m_base_color5;
+   bool m_constrain_against_base_color5;
+};
+
+static inline void
+rg_etc1_optimizer_params_clean(rg_etc1_optimizer_params *params)
+{
+   params->m_num_src_pixels = 0;
+   params->m_pSrc_pixels = 0;
+
+   params->m_use_color4 = EINA_FALSE;
+   params->m_pScan_deltas = rg_etc1_default_scan_delta;
+   params->m_scan_delta_size = 1;
+
+   rg_etc1_color_quad_u8_clear(&params->m_base_color5);
+   params->m_constrain_against_base_color5 = EINA_FALSE;
+}
+
+static inline void
+rg_etc1_optimizer_params_base_clear(rg_etc1_optimizer_params *params)
+{
+   rg_etc1_pack_params_clear(params->base_params);
+   rg_etc1_optimizer_params_clean(params);
+}
+
+typedef struct
+{
+   uint64 m_error;
+   color_quad_u8 m_block_color_unscaled;
+   uint m_block_inten_table;
+   uint m_n;
+   uint8* m_pSelectors;
+   bool m_block_color4;
+} rg_etc1_optimizer_results;
+
+static inline void
+rg_etc1_optimizer_results_duplicate(rg_etc1_optimizer_results *dst, const rg_etc1_optimizer_results *src)
+{
+   rg_etc1_color_quad_u8_copy(&dst->m_block_color_unscaled,&src->m_block_color_unscaled);
+   dst->m_block_color4 = src->m_block_color4;
+   dst->m_block_inten_table = src->m_block_inten_table;
+   dst->m_error = src->m_error;
+   // ERROR CASE NO ASSERT IN EVAS CODE
+   if (!(dst->m_n == src->m_n)) return ;
+   memcpy(dst->m_pSelectors, src->m_pSelectors, src->m_n);
+}
+
+typedef struct
+{
+   Etc1_Solution_Coordinates m_coords;
+   uint8                      m_selectors[8];
+   uint64                     m_error;
+   bool                       m_valid;
+} rg_etc1_potential_solution;
+
+static inline void
+rg_etc1_potential_solution_clear(rg_etc1_potential_solution *solution)
+{
+   rg_etc1_solution_coordinates_clear(&solution->m_coords);
+   solution->m_error = cUINT64_MAX;
+   solution->m_valid = EINA_FALSE;
+}
+
+typedef struct
+{
+   const rg_etc1_optimizer_params* m_pParams;
+   rg_etc1_optimizer_results* m_pResult;
+
+   int m_limit;
+
+   float m_avg_color[3];
+   int m_br, m_bg, m_bb;
+   uint16 m_luma[8];
+   uint32 m_sorted_luma[2][8];
+   const uint32* m_pSorted_luma_indices;
+   uint32* m_pSorted_luma;
+
+   uint8 m_selectors[8];
+   uint8 m_best_selectors[8];
+
+   rg_etc1_potential_solution m_best_solution;
+   rg_etc1_potential_solution m_trial_solution;
+   uint8 m_temp_selectors[8];
+}rg_etc1_optimizer;
+
+static inline void
+rg_etc1_optimizer_clear(rg_etc1_optimizer *optimizer)
+{
+   optimizer->m_pParams = NULL;
+   optimizer->m_pResult = NULL;
+   optimizer->m_pSorted_luma = NULL;
+   optimizer->m_pSorted_luma_indices = NULL;
+   optimizer->m_br = optimizer->m_bg = optimizer->m_bb = 0;
+   rg_etc1_potential_solution_clear(&optimizer->m_best_solution);
+   rg_etc1_potential_solution_clear(&optimizer->m_trial_solution);
+}
+
+static bool rg_etc1_optimizer_evaluate_solution(rg_etc1_optimizer *optimizer, const Etc1_Solution_Coordinates* coords,
+                                                rg_etc1_potential_solution* trial_solution,
+                                                rg_etc1_potential_solution* pBest_solution);
+static bool rg_etc1_optimizer_evaluate_solution_fast(rg_etc1_optimizer *optimizer,const Etc1_Solution_Coordinates *coords,
+                                                     rg_etc1_potential_solution *trial_solution,
+                                                     rg_etc1_potential_solution *pBest_solution);
+
+static bool
+rg_etc1_optimizer_compute(rg_etc1_optimizer *optimizer)
+{
+   const uint n = optimizer->m_pParams->m_num_src_pixels;
+   const int scan_delta_size = optimizer->m_pParams->m_scan_delta_size;
+   int zdi;
+
+   // Scan through a subset of the 3D lattice centered around the avg block color trying each 3D (555 or 444) lattice point as a potential block color.
+   // Each time a better solution is found try to refine the current solution's block color based of the current selectors and intensity table index.
+   for (zdi = 0; zdi < scan_delta_size; zdi++)
+     {
+        const int zd = optimizer->m_pParams->m_pScan_deltas[zdi];
+        const int mbb = optimizer->m_bb + zd;
+        int ydi;
+        if (mbb < 0) continue; else if (mbb > optimizer->m_limit) break;
+
+        for (ydi = 0; ydi < scan_delta_size; ydi++)
+          {
+             const int yd = optimizer->m_pParams->m_pScan_deltas[ydi];
+             const int mbg = optimizer->m_bg + yd;
+             int xdi;
+
+             if (mbg < 0) continue; else if (mbg > optimizer->m_limit) break;
+
+             for (xdi = 0; xdi < scan_delta_size; xdi++)
+               {
+                  const int xd = optimizer->m_pParams->m_pScan_deltas[xdi];
+                  const int mbr = optimizer->m_br + xd;
+                  Etc1_Solution_Coordinates coords;
+                  uint max_refinement_trials;
+                  uint refinement_trial;
+
+                  rg_etc1_solution_coordinates_component_set(&coords, mbr, mbg, mbb, 0, optimizer->m_pParams->m_use_color4);
+                  if (mbr < 0) continue; else if (mbr > optimizer->m_limit) break;
+
+                  if (optimizer->m_pParams->base_params->m_quality == rg_etc1_high_quality)
+                    {
+                       if (!rg_etc1_optimizer_evaluate_solution(optimizer, &coords, &optimizer->m_trial_solution, &optimizer->m_best_solution))
+                         continue;
+                    }
+                  else
+                    {
+                       if (!rg_etc1_optimizer_evaluate_solution_fast(optimizer, &coords, &optimizer->m_trial_solution, &optimizer->m_best_solution))
+                         continue;
+                    }
+
+                  // Now we have the input block, the avg. color of the input pixels, a set of trial selector indices, and the block color+intensity index.
+                  // Now, for each component, attempt to refine the current solution by solving a simple linear equation. For example, for 4 colors:
+                  // The goal is:
+                  // pixel0 - (block_color+inten_table[selector0]) + pixel1 - (block_color+inten_table[selector1]) + pixel2 - (block_color+inten_table[selector2]) + pixel3 - (block_color+inten_table[selector3]) = 0
+                  // Rearranging this:
+                  // (pixel0 + pixel1 + pixel2 + pixel3) - (block_color+inten_table[selector0]) - (block_color+inten_table[selector1]) - (block_color+inten_table[selector2]) - (block_color+inten_table[selector3]) = 0
+                  // (pixel0 + pixel1 + pixel2 + pixel3) - block_color - inten_table[selector0] - block_color-inten_table[selector1] - block_color-inten_table[selector2] - block_color-inten_table[selector3] = 0
+                  // (pixel0 + pixel1 + pixel2 + pixel3) - 4*block_color - inten_table[selector0] - inten_table[selector1] - inten_table[selector2] - inten_table[selector3] = 0
+                  // (pixel0 + pixel1 + pixel2 + pixel3) - 4*block_color - (inten_table[selector0] + inten_table[selector1] + inten_table[selector2] + inten_table[selector3]) = 0
+                  // (pixel0 + pixel1 + pixel2 + pixel3)/4 - block_color - (inten_table[selector0] + inten_table[selector1] + inten_table[selector2] + inten_table[selector3])/4 = 0
+                  // block_color = (pixel0 + pixel1 + pixel2 + pixel3)/4 - (inten_table[selector0] + inten_table[selector1] + inten_table[selector2] + inten_table[selector3])/4
+                  // So what this means:
+                  // optimal_block_color = avg_input - avg_inten_delta
+                  // So the optimal block color can be computed by taking the average block color and subtracting the current average of the intensity delta.
+                  // Unfortunately, optimal_block_color must then be quantized to 555 or 444 so it's not always possible to improve matters using this formula.
+                  // Also, the above formula is for unclamped intensity deltas. The actual implementation takes into account clamping.
+
+                  max_refinement_trials = (optimizer->m_pParams->base_params->m_quality == rg_etc1_low_quality) ? 2 : (((xd | yd | zd) == 0) ? 4 : 2);
+                  for (refinement_trial = 0; refinement_trial < max_refinement_trials; refinement_trial++)
+                    {
+                       const uint8* pSelectors = optimizer->m_best_solution.m_selectors;
+                       const int* pInten_table = rg_etc1_inten_tables[optimizer->m_best_solution.m_coords.m_inten_table];
+
+                       int delta_sum_r = 0, delta_sum_g = 0, delta_sum_b = 0;
+                       uint index;
+                       color_quad_u8 base_color;
+                       float avg_delta_r_f, avg_delta_g_f, avg_delta_b_f;
+                       int br1, bg1, bb1;
+                       bool skip;
+                       Etc1_Solution_Coordinates coords1;
+                       rg_etc1_solution_coordinates_get_scaled_color(&base_color, &optimizer->m_best_solution.m_coords);
+
+                       for (index = 0; index < n; index++)
+                         {
+                            const uint s = *pSelectors++;
+                            const int yyd = pInten_table[s];
+                            // Compute actual delta being applied to each pixel, taking into account clamping.
+                            delta_sum_r += CLAMP(base_color.comp.r + yyd, 0, 255) - base_color.comp.r;
+                            delta_sum_g += CLAMP(base_color.comp.g + yyd, 0, 255) - base_color.comp.g;
+                            delta_sum_b += CLAMP(base_color.comp.b + yyd, 0, 255) - base_color.comp.b;
+                         }
+                       if ((!delta_sum_r) && (!delta_sum_g) && (!delta_sum_b))
+                         break;
+                       avg_delta_r_f = (float)(delta_sum_r) / n;
+                       avg_delta_g_f = (float)(delta_sum_g) / n;
+                       avg_delta_b_f = (float)(delta_sum_b) / n;
+                       br1 = (uint)CLAMP(((optimizer->m_avg_color[0] - avg_delta_r_f) * optimizer->m_limit / 255.0f + .5f),
+                                         0, optimizer->m_limit);
+                       bg1 = (uint)CLAMP(((optimizer->m_avg_color[1] - avg_delta_g_f) * optimizer->m_limit / 255.0f + .5f),
+                                         0, optimizer->m_limit);
+                       bb1 = (uint)CLAMP(((optimizer->m_avg_color[2] - avg_delta_b_f) * optimizer->m_limit / 255.0f + .5f),
+                                         0, optimizer->m_limit);
+                       skip = EINA_FALSE;
+
+                       if ((mbr == br1) && (mbg == bg1) && (mbb == bb1)) {
+                          skip = EINA_TRUE;
+                       } else if ((br1 == optimizer->m_best_solution.m_coords.m_unscaled_color.comp.r) &&
+                                  (bg1 == optimizer->m_best_solution.m_coords.m_unscaled_color.comp.g) &&
+                                  (bb1 == optimizer->m_best_solution.m_coords.m_unscaled_color.comp.b)) {
+                          skip = EINA_TRUE;
+                       } else if ((optimizer->m_br == br1) && (optimizer->m_bg == bg1) && (optimizer->m_bb == bb1)) {
+                          skip = EINA_TRUE;
+                       }
+
+                       if (skip)
+                         break;
+
+                       rg_etc1_solution_coordinates_component_set(&coords1, br1, bg1, bb1, 0, optimizer->m_pParams->m_use_color4);
+                       if (optimizer->m_pParams->base_params->m_quality == rg_etc1_high_quality)
+                         {
+                            if (!rg_etc1_optimizer_evaluate_solution(optimizer, &coords1, &optimizer->m_trial_solution, &optimizer->m_best_solution))
+                              break;
+                         }
+                       else
+                         {
+                            if (!rg_etc1_optimizer_evaluate_solution_fast(optimizer, &coords1, &optimizer->m_trial_solution, &optimizer->m_best_solution))
+                              break;
+                         }
+
+                    }  // refinement_trial
+
+               } // xdi
+          } // ydi
+     } // zdi
+
+   if (!optimizer->m_best_solution.m_valid)
+     {
+        optimizer->m_pResult->m_error = cUINT32_MAX;
+        return EINA_FALSE;
+     }
+
+#ifdef RG_ETC1_BUILD_DEBUG
+   {
+      color_quad_u8 block_colors[4];
+      const color_quad_u8* pSrc_pixels;
+      uint64 actual_error=0;
+      uint i;
+      const uint8* pSelectors = optimizer->m_best_solution.m_selectors;
+
+      rg_etc1_solution_coordinates_block_colors_get(&optimizer->m_best_solution.m_coords, block_colors);
+      pSrc_pixels = optimizer->m_pParams->m_pSrc_pixels;
+      for (i = 0; i < n; i++)
+        actual_error += rg_etc1_color_quad_u8_rgb_squared_distance(pSrc_pixels[i], block_colors[pSelectors[i]]);
+
+      // ERROR CASE NO ASSERT IN EVAS CODE
+      if (actual_error != optimizer->m_best_solution.m_error)
+        return EINA_FALSE;
+   }
+#endif
+
+   optimizer->m_pResult->m_error = optimizer->m_best_solution.m_error;
+   rg_etc1_color_quad_u8_copy(&optimizer->m_pResult->m_block_color_unscaled,&optimizer->m_best_solution.m_coords.m_unscaled_color);
+   optimizer->m_pResult->m_block_color4 = optimizer->m_best_solution.m_coords.m_color4;
+   optimizer->m_pResult->m_block_inten_table = optimizer->m_best_solution.m_coords.m_inten_table;
+   memcpy(optimizer->m_pResult->m_pSelectors, optimizer->m_best_solution.m_selectors, n);
+   optimizer->m_pResult->m_n = n;
+
+   return EINA_TRUE;
+}
+
+void
+rg_etc1_optimizer_init(rg_etc1_optimizer *optimizer, const rg_etc1_optimizer_params *params,
+                       rg_etc1_optimizer_results *result)
+{
+   // This version is hardcoded for 8 pixel subblocks.
+   // ERROR CASE NO ASSERT IN EVAS CODE
+   if (params->m_num_src_pixels != 8) return ;
+
+   const uint n = 8;
+   uint i;
+   float avg_color[3];
+   float fc[3];
+
+   optimizer->m_pParams = params;
+   optimizer->m_pResult = result;
+
+   rg_etc1_vec_init(avg_color, 0.0f);
+   optimizer->m_limit = optimizer->m_pParams->m_use_color4 ? 15 : 31;
+
+   for ( i = 0; i < n; i++)
+     {
+        const color_quad_u8 *c = &optimizer->m_pParams->m_pSrc_pixels[i];
+        rg_etc1_vec_set(fc, c->comp.r, c->comp.g, c->comp.b);
+
+        rg_etc1_vec_add(avg_color,fc);
+
+        optimizer->m_luma[i] = (uint16)(c->comp.r + c->comp.g + c->comp.b);
+        optimizer->m_sorted_luma[0][i] = i;
+     }
+   rg_etc1_vec_scale(avg_color, (1.0f/(float)(n)));
+   rg_etc1_vec_copy(optimizer->m_avg_color,avg_color);
+
+   optimizer->m_br = MIN((int)(optimizer->m_avg_color[0] * optimizer->m_limit / 255.0f + .5f), optimizer->m_limit);
+   optimizer->m_bg = MIN((int)(optimizer->m_avg_color[1] * optimizer->m_limit / 255.0f + .5f), optimizer->m_limit);
+   optimizer->m_bb = MIN((int)(optimizer->m_avg_color[2] * optimizer->m_limit / 255.0f + .5f), optimizer->m_limit);
+
+   if (optimizer->m_pParams->base_params->m_quality <= rg_etc1_medium_quality)
+     {
+        optimizer->m_pSorted_luma_indices = rg_etc1_indirect_radix_sort(n, optimizer->m_sorted_luma[0],
+                                                                        optimizer->m_sorted_luma[1], optimizer->m_luma,
+                                                                        0, sizeof(optimizer->m_luma[0]), EINA_FALSE);
+        optimizer->m_pSorted_luma = optimizer->m_sorted_luma[0];
+
+        if (optimizer->m_pSorted_luma_indices == optimizer->m_sorted_luma[0])
+          optimizer->m_pSorted_luma = optimizer->m_sorted_luma[1];
+
+        for (i = 0; i < n; i++)
+          optimizer->m_pSorted_luma[i] = optimizer->m_luma[optimizer->m_pSorted_luma_indices[i]];
+     }
+
+   rg_etc1_solution_coordinates_clear(&optimizer->m_best_solution.m_coords);
+   optimizer->m_best_solution.m_valid = EINA_FALSE;
+   optimizer->m_best_solution.m_error = cUINT64_MAX;
+}
+
+static bool
+rg_etc1_optimizer_evaluate_solution(rg_etc1_optimizer *optimizer, const Etc1_Solution_Coordinates* coords,
+                                    rg_etc1_potential_solution* trial_solution, rg_etc1_potential_solution* pBest_solution)
+{
+   color_quad_u8 base_color;
+   const uint n = 8;
+   uint inten_table;
+   bool success = EINA_FALSE;
+
+   trial_solution->m_valid = EINA_FALSE;
+
+   if (optimizer->m_pParams->m_constrain_against_base_color5)
+     {
+        int dr, dg, db;
+        dr = coords->m_unscaled_color.comp.r - optimizer->m_pParams->m_base_color5.comp.r;
+        dg = coords->m_unscaled_color.comp.g - optimizer->m_pParams->m_base_color5.comp.g;
+        db = coords->m_unscaled_color.comp.b - optimizer->m_pParams->m_base_color5.comp.b;
+
+        if ((MIN(MIN(dr,dg),db) < cETC1ColorDeltaMin) || (MAX(MAX(dr,dg),db) > cETC1ColorDeltaMax))
+          return EINA_FALSE;
+     }
+
+   rg_etc1_solution_coordinates_get_scaled_color(&base_color, coords);
+   trial_solution->m_error = cUINT64_MAX;
+
+   for (inten_table = 0; inten_table < cETC1IntenModifierValues; inten_table++)
+     {
+        const int* pInten_table = rg_etc1_inten_tables[inten_table];
+        uint64 total_error = 0;
+        color_quad_u8 block_colors[4];
+        const color_quad_u8* pSrc_pixels = optimizer->m_pParams->m_pSrc_pixels;
+
+        uint c;
+        for (c = 0; c < 4; c++)
+          {
+             const int yd = pInten_table[c];
+             rg_etc1_color_quad_u8_init(&block_colors[c], base_color.comp.r+yd, base_color.comp.g+yd, base_color.comp.b+yd, 0);
+          }
+
+        for (c = 0; c < n; c++)
+          {
+             uint best_selector_index = 0, best_error, trial_error;
+             const color_quad_u8* src_pixel = pSrc_pixels++;
+
+             best_error = SQUARE((src_pixel->comp.r - block_colors[0].comp.r)) +
+               SQUARE((src_pixel->comp.g - block_colors[0].comp.g)) +
+               SQUARE((src_pixel->comp.b - block_colors[0].comp.b));
+             trial_error = SQUARE((src_pixel->comp.r - block_colors[1].comp.r)) +
+               SQUARE((src_pixel->comp.g - block_colors[1].comp.g)) +
+               SQUARE((src_pixel->comp.b - block_colors[1].comp.b));
+             if (trial_error < best_error)
+               {
+                  best_error = trial_error;
+                  best_selector_index = 1;
+               }
+
+             trial_error = SQUARE((src_pixel->comp.r - block_colors[2].comp.r)) +
+               SQUARE((src_pixel->comp.g - block_colors[2].comp.g)) +
+               SQUARE((src_pixel->comp.b - block_colors[2].comp.b));
+             if (trial_error < best_error)
+               {
+                  best_error = trial_error;
+                  best_selector_index = 2;
+               }
+
+             trial_error = SQUARE((src_pixel->comp.r - block_colors[3].comp.r)) +
+               SQUARE((src_pixel->comp.g - block_colors[3].comp.g)) +
+               SQUARE((src_pixel->comp.b - block_colors[3].comp.b));
+             if (trial_error < best_error)
+               {
+                  best_error = trial_error;
+                  best_selector_index = 3;
+               }
+
+             optimizer->m_temp_selectors[c] = (uint8)(best_selector_index);
+
+             total_error += best_error;
+             if (total_error >= trial_solution->m_error)
+               break;
+          }
+
+        if (total_error < trial_solution->m_error)
+          {
+             trial_solution->m_error = total_error;
+             trial_solution->m_coords.m_inten_table = inten_table;
+             memcpy(trial_solution->m_selectors, optimizer->m_temp_selectors, 8);
+             trial_solution->m_valid = EINA_TRUE;
+          }
+     }
+   rg_etc1_color_quad_u8_copy(&trial_solution->m_coords.m_unscaled_color,&coords->m_unscaled_color);
+   trial_solution->m_coords.m_color4 = optimizer->m_pParams->m_use_color4;
+
+   if (pBest_solution)
+     {
+        if (trial_solution->m_error < pBest_solution->m_error)
+          {
+             memcpy(pBest_solution,trial_solution,sizeof(rg_etc1_potential_solution));
+             success = EINA_TRUE;
+          }
+     }
+
+   return success;
+}
+
+static bool
+rg_etc1_optimizer_evaluate_solution_fast(rg_etc1_optimizer *optimizer, const Etc1_Solution_Coordinates *coords,
+                                         rg_etc1_potential_solution *trial_solution, rg_etc1_potential_solution *pBest_solution)
+{
+   color_quad_u8 base_color;
+   const uint n = 8;
+   int inten_table;
+   bool success = EINA_FALSE;
+
+   if (optimizer->m_pParams->m_constrain_against_base_color5)
+     {
+        int dr, dg, db;
+        dr = coords->m_unscaled_color.comp.r - optimizer->m_pParams->m_base_color5.comp.r;
+        dg = coords->m_unscaled_color.comp.g - optimizer->m_pParams->m_base_color5.comp.g;
+        db = coords->m_unscaled_color.comp.b - optimizer->m_pParams->m_base_color5.comp.b;
+
+
+        if ((MIN(MIN(dr,dg),db) < cETC1ColorDeltaMin) || (MAX(MAX(dr,dg),db) > cETC1ColorDeltaMax))
+          {
+             trial_solution->m_valid = EINA_FALSE;
+             return EINA_FALSE;
+          }
+     }
+
+   rg_etc1_solution_coordinates_get_scaled_color(&base_color,coords);
+
+   trial_solution->m_error = cUINT64_MAX;
+
+   for (inten_table = cETC1IntenModifierValues - 1; inten_table >= 0; --inten_table)
+     {
+        const int* pInten_table = rg_etc1_inten_tables[inten_table];
+        uint block_inten[4];
+        color_quad_u8 block_colors[4];
+        uint block_inten_midpoints[3];
+        uint64 total_error = 0;
+        const color_quad_u8* pSrc_pixels = optimizer->m_pParams->m_pSrc_pixels;
+        uint s, c;
+
+        for (s = 0; s < 4; s++)
+          {
+             const int yd = pInten_table[s];
+             rg_etc1_color_quad_u8_init(&block_colors[s], base_color.comp.r+yd, base_color.comp.g+yd, base_color.comp.b+yd, 0);
+             block_inten[s] = block_colors[s].comp.r + block_colors[s].comp.g + block_colors[s].comp.b;
+          }
+
+        // evaluate_solution_fast() enforces/assumesd a total ordering of the input colors along the intensity (1,1,1) axis to more quickly classify the inputs to selectors.
+        // The inputs colors have been presorted along the projection onto this axis, and ETC1 block colors are always ordered along the intensity axis, so this classification is fast.
+        // 0   1   2   3
+        //   01  12  23
+        block_inten_midpoints[0] = block_inten[0] + block_inten[1];
+        block_inten_midpoints[1] = block_inten[1] + block_inten[2];
+        block_inten_midpoints[2] = block_inten[2] + block_inten[3];
+
+        if ((optimizer->m_pSorted_luma[n - 1] * 2) < block_inten_midpoints[0])
+          {
+             if (block_inten[0] > optimizer->m_pSorted_luma[n - 1])
+               {
+                  const uint min_error = labs(block_inten[0] - optimizer->m_pSorted_luma[n - 1]);
+                  if (min_error >= trial_solution->m_error)
+                    continue;
+               }
+
+             memset(&optimizer->m_temp_selectors[0], 0, n);
+
+             for (c = 0; c < n; c++) {
+                total_error += rg_etc1_color_quad_u8_rgb_squared_distance(block_colors[0], pSrc_pixels[c]);
+             }
+          }
+        else if ((optimizer->m_pSorted_luma[0] * 2) >= block_inten_midpoints[2])
+          {
+             if (optimizer->m_pSorted_luma[0] > block_inten[3])
+               {
+                  const uint min_error = labs(optimizer->m_pSorted_luma[0] - block_inten[3]);
+                  if (min_error >= trial_solution->m_error)
+                    continue;
+               }
+
+             memset(&optimizer->m_temp_selectors[0], 3, n);
+
+             for (c = 0; c < n; c++)
+               total_error += rg_etc1_color_quad_u8_rgb_squared_distance(block_colors[3], pSrc_pixels[c]);
+          }
+        else
+          {
+             uint cur_selector = 0;
+             for (c = 0; c < n; c++)
+               {
+                  const uint y = optimizer->m_pSorted_luma[c];
+                  while ((y * 2) >= block_inten_midpoints[cur_selector])
+                    if (++cur_selector > 2)
+                      goto done;
+                  const uint sorted_pixel_index = optimizer->m_pSorted_luma_indices[c];
+                  optimizer->m_temp_selectors[sorted_pixel_index] = (uint8)(cur_selector);
+                  total_error += rg_etc1_color_quad_u8_rgb_squared_distance(block_colors[cur_selector],
+                                                                            pSrc_pixels[sorted_pixel_index]);
+               }
+          done:
+             while (c < n)
+               {
+                  const uint sorted_pixel_index = optimizer->m_pSorted_luma_indices[c];
+                  optimizer->m_temp_selectors[sorted_pixel_index] = 3;
+                  total_error += rg_etc1_color_quad_u8_rgb_squared_distance(block_colors[3], pSrc_pixels[sorted_pixel_index]);
+                  ++c;
+               }
+          }
+
+        if (total_error < trial_solution->m_error)
+          {
+             trial_solution->m_error = total_error;
+             trial_solution->m_coords.m_inten_table = inten_table;
+             memcpy(trial_solution->m_selectors, optimizer->m_temp_selectors, n);
+             trial_solution->m_valid = EINA_TRUE;
+             if (!total_error)
+               break;
+          }
+     }
+   rg_etc1_color_quad_u8_copy(&trial_solution->m_coords.m_unscaled_color,&coords->m_unscaled_color);
+   trial_solution->m_coords.m_color4 = optimizer->m_pParams->m_use_color4;
+
+   if (pBest_solution)
+     {
+        if (trial_solution->m_error < pBest_solution->m_error)
+          {
+             memcpy(pBest_solution,trial_solution,sizeof(rg_etc1_potential_solution));
+             success = EINA_TRUE;
+          }
+     }
+
+   return success;
+}
+
+static uint
+etc1_decode_value(uint diff, uint inten, uint selector, uint packed_c)
+{
+   const uint limit = diff ? 32 : 16;
+   // ERROR CASE NO ASSERT IN EVAS CODE
+   if (!((diff < 2) && (inten < 8) && (selector < 4) && (packed_c < limit)))
+     return 0;
+   int c;
+   if (diff)
+     c = (packed_c >> 2) | (packed_c << 3);
+   else
+     c = packed_c | (packed_c << 4);
+   c += rg_etc1_inten_tables[inten][selector];
+   c = CLAMP(c, 0, 255);
+   return c;
+}
+
+static inline int mul_8bit(int a, int b) { int t = a*b + 128; return (t + (t >> 8)) >> 8; }
+
+void rg_etc1_pack_block_init()
+{
+   uint diff;
+   uint expand5[32];
+   int i;
+   for (diff = 0; diff < 2; diff++)
+     {
+        const uint limit = diff ? 32 : 16;
+        uint inten;
+
+        for (inten = 0; inten < 8; inten++)
+          {
+             uint selector;
+             for (selector = 0; selector < 4; selector++)
+               {
+                  const uint inverse_table_index = diff + (inten << 1) + (selector << 4);
+                  uint color;
+                  for (color = 0; color < 256; color++)
+                    {
+                       uint best_error = cUINT32_MAX, best_packed_c = 0;
+                       uint packed_c;
+                       for (packed_c = 0; packed_c < limit; packed_c++)
+                         {
+                            int v = etc1_decode_value(diff, inten, selector, packed_c);
+                            uint err = labs(v - (int)color);
+                            if (err < best_error)
+                              {
+                                 best_error = err;
+                                 best_packed_c = packed_c;
+                                 if (!best_error)
+                                   break;
+                              }
+                         }
+                       if (!(best_error <= 255))
+                         {
+                            fprintf(stderr, "ETC1: Failed to write the inverse lookup table!\n");
+                            return;
+                         }
+                       rg_etc1_inverse_lookup[inverse_table_index][color] = (uint16)(best_packed_c | (best_error << 8));
+                    }
+               }
+          }
+     }
+
+   for(i = 0; i < 32; i++)
+     expand5[i] = (i << 3) | (i >> 2);
+
+   for(i = 0; i < 256 + 16; i++)
+     {
+        int v = (int)CLAMP(i - 8, 0, 255);
+        rg_etc_quant5_tab[i] = (uint8)(expand5[mul_8bit(v,31)]);
+     }
+}
+
+// Packs solid color blocks efficiently using a set of small precomputed tables.
+// For random 888 inputs, MSE results are better than Erricson's ETC1 packer in "slow" mode ~9.5% of the time, is slightly worse only ~.01% of the time, and is equal the rest of the time.
+static uint64
+rg_etc1_pack_block_solid_color(unsigned char *block, const color_quad_u8 *color, rg_etc1_pack_params *pack_params EINA_UNUSED)
+{
+   const uint8 *pColor = (uint8 *) &color->m_u32;
+
+   if (!rg_etc1_inverse_lookup[0][255])
+     rg_etc1_pack_block_init();
+
+   if (!rg_etc1_inverse_lookup[0][255])
+     {
+        fprintf(stderr, "ETC1: Inverse lookup table not set (in %s)!\n", __FUNCTION__);
+        return 0;
+     }
+
+   const uint s_next_comp[4] = { 1, 2, 0, 1 };
+   uint best_error = cUINT32_MAX, best_i = 0;
+   int best_x = 0, best_packed_c1 = 0, best_packed_c2 = 0;
+   uint i;
+
+   // For each possible 8-bit value, there is a precomputed list of diff/inten/selector configurations
+   // that allow that 8-bit value to be encoded with no error.
+   for (i = 0; i < 3; i++)
+     {
+        const int c0 = pColor[i];
+        const int c1 = pColor[s_next_comp[i]];
+        const int c2 = pColor[s_next_comp[i + 1]];
+
+        const int delta_range = 1;
+        int delta;
+        for (delta = -delta_range; delta <= delta_range; delta++)
+          {
+             const int c_plus_delta = CLAMP(c0 + delta, 0, 255);
+
+             uint16* pTable;
+             if (!c_plus_delta)
+               pTable = (uint16 *)rg_etc_color8_to_etc_block_config_0_255[0];
+             else if (c_plus_delta == 255)
+               pTable = (uint16 *)rg_etc_color8_to_etc_block_config_0_255[1];
+             else
+               pTable = (uint16 *)rg_etc_color8_to_etc_block_config_1_to_254[c_plus_delta - 1];
+
+             do
+               {
+                  const uint x = *pTable++;
+                  uint16* pInverse_table;
+                  uint16 p1, p2;
+                  uint trial_error;
+
+#ifdef RG_ETC1_BUILD_DEBUG
+                  const uint diff = x & 1;
+                  const uint inten = (x >> 1) & 7;
+                  const uint selector = (x >> 4) & 3;
+                  const uint p0 = (x >> 8) & 255;
+                  // ERROR CASE NO ASSERT IN EVAS CODE
+                  if (etc1_decode_value(diff, inten, selector, p0) != (uint)c_plus_delta) return 0;
+#endif
+
+                  pInverse_table = rg_etc1_inverse_lookup[x & 0xFF];
+                  p1 = pInverse_table[c1];
+                  p2 = pInverse_table[c2];
+                  trial_error = SQUARE((c_plus_delta - c0)) + SQUARE((p1 >> 8)) + SQUARE((p2 >> 8));
+                  if (trial_error < best_error)
+                    {
+                       best_error = trial_error;
+                       best_x = x;
+                       best_packed_c1 = p1 & 0xFF;
+                       best_packed_c2 = p2 & 0xFF;
+                       best_i = i;
+                       if (!best_error)
+                         goto found_perfect_match;
+                    }
+               } while (*pTable != 0xFFFF);
+          }
+     }
+ found_perfect_match:
+   {
+      const uint diff = best_x & 1;
+      const uint inten = (best_x >> 1) & 7;
+      uint etc1_selector;
+      uint best_packed_c0;
+      uint selector_val;
+
+      block[0] = block[1] = block[2] = 0;
+      block[3] = (uint8)(((inten | (inten << 3)) << 2) | (diff << 1));
+
+      etc1_selector = rg_etc_selector_index_to_etc1[(best_x >> 4) & 3];
+      selector_val = (etc1_selector & 2) ? 0xFFFF : 0;
+      memcpy(&block[4], &selector_val, 2);
+      selector_val = (etc1_selector & 1) ? 0xFFFF : 0;
+      memcpy(&block[6], &selector_val, 2);
+
+      best_packed_c0 = (best_x >> 8) & 255;
+      if (diff)
+        {
+           block[best_i] = (uint8)(best_packed_c0 << 3);
+           block[s_next_comp[best_i]] = (uint8)(best_packed_c1 << 3);
+           block[s_next_comp[best_i+1]] = (uint8)(best_packed_c2 << 3);
+        }
+      else
+        {
+           block[best_i] = (uint8)(best_packed_c0 | (best_packed_c0 << 4));
+           block[s_next_comp[best_i]] = (uint8)(best_packed_c1 | (best_packed_c1 << 4));
+           block[s_next_comp[best_i+1]] = (uint8)(best_packed_c2 | (best_packed_c2 << 4));
+        }
+   }
+   return best_error;
+}
+
+#if RG_ETC1_CONSTRAINED_SUBBLOCK
+static uint
+rg_etc1_pack_block_solid_color_constrained(rg_etc1_optimizer_results *results,uint num_colors,
+                                           const uint8* pColor, rg_etc1_pack_params *pack_params EINA_UNUSED,
+                                           bool use_diff, const color_quad_u8* pBase_color5_unscaled)
+{
+   static uint s_next_comp[4] = { 1, 2, 0, 1 };
+   uint best_error = cUINT32_MAX, best_i = 0;
+   int best_x = 0, best_packed_c1 = 0, best_packed_c2 = 0;
+   uint i;
+
+   if (!rg_etc1_inverse_lookup[0][255])
+     rg_etc1_pack_block_init();
+
+   if (!rg_etc1_inverse_lookup[0][255])
+     {
+        fprintf(stderr, "ETC1: Inverse lookup table not set (in %s)!\n", __FUNCTION__);
+        return 0;
+     }
+
+   // For each possible 8-bit value, there is a precomputed list of diff/inten/selector configurations
+   // that allow that 8-bit value to be encoded with no error.
+   for (i = 0; i < 3; i++)
+     {
+        const uint c1 = pColor[s_next_comp[i]], c2 = pColor[s_next_comp[i + 1]];
+        const int delta_range = 1;
+        int delta;
+        for (delta = -delta_range; delta <= delta_range; delta++)
+          {
+             const int c_plus_delta = CLAMP(pColor[i] + delta, 0, 255);
+             const uint16* pTable;
+             if (!c_plus_delta)
+               pTable = rg_etc_color8_to_etc_block_config_0_255[0];
+             else if (c_plus_delta == 255)
+               pTable = rg_etc_color8_to_etc_block_config_0_255[1];
+             else
+               pTable = rg_etc_color8_to_etc_block_config_1_to_254[c_plus_delta - 1];
+
+             do
+               {
+                  const uint x = *pTable++;
+                  const uint diff = x & 1;
+                  if (((uint)use_diff) != diff)
+                    {
+                       if (*pTable == 0xFFFF)
+                         break;
+                       continue;
+                    }
+
+                  if ((diff) && (pBase_color5_unscaled))
+                    {
+                       const int p0 = (x >> 8) & 255;
+                       unsigned char cc1 = rg_etc1_color_quad_component_get(pBase_color5_unscaled->m_u32,
+                                                                           i);
+                       int delta1 = p0 - (int)(cc1);
+                       if ((delta1 < cETC1ColorDeltaMin) || (delta1 > cETC1ColorDeltaMax))
+                         {
+                            if (*pTable == 0xFFFF)
+                              break;
+                            continue;
+                         }
+                    }
+
+#ifdef RG_ETC1_BUILD_DEBUG
+                  {
+                     const uint inten = (x >> 1) & 7;
+                     const uint selector = (x >> 4) & 3;
+                     const uint p0 = (x >> 8) & 255;
+                     // ERROR CASE NO ASSERT IN EVAS CODE
+                     if (etc1_decode_value(diff, inten, selector, p0) != (uint)c_plus_delta) return 0;
+                  }
+#endif
+
+                  const uint16* pInverse_table = rg_etc1_inverse_lookup[x & 0xFF];
+                  uint16 p1 = pInverse_table[c1];
+                  uint16 p2 = pInverse_table[c2];
+                  uint trial_error;
+
+                  if ((diff) && (pBase_color5_unscaled))
+                    {
+                       unsigned char cc1 = rg_etc1_color_quad_component_get(pBase_color5_unscaled->m_u32,
+                                                                           s_next_comp[i]);
+                       int delta1 = (p1 & 0xFF) - (int)(cc1);
+                       unsigned char cc2 = rg_etc1_color_quad_component_get(pBase_color5_unscaled->m_u32,
+                                                                           s_next_comp[i + 1]);
+                       int delta2 = (p2 & 0xFF) - (int)(cc2);
+                       if ((delta1 < cETC1ColorDeltaMin) || (delta1 > cETC1ColorDeltaMax) 
+                           || (delta2 < cETC1ColorDeltaMin) || (delta2 > cETC1ColorDeltaMax))
+                         {
+                            if (*pTable == 0xFFFF)
+                              break;
+                            continue;
+                         }
+                    }
+
+                  trial_error = SQUARE((c_plus_delta - pColor[i])) + SQUARE((p1 >> 8)) + SQUARE((p2 >> 8));
+                  if (trial_error < best_error)
+                    {
+                       best_error = trial_error;
+                       best_x = x;
+                       best_packed_c1 = p1 & 0xFF;
+                       best_packed_c2 = p2 & 0xFF;
+                       best_i = i;
+                       if (!best_error)
+                         goto found_perfect_match;
+                    }
+               } while (*pTable != 0xFFFF);
+          }
+     }
+ found_perfect_match:
+
+   if (best_error == cUINT32_MAX)
+     return best_error;
+
+   best_error *= num_colors;
+
+   results->m_n = num_colors;
+   results->m_block_color4 = !(best_x & 1);
+   results->m_block_inten_table = (best_x >> 1) & 7;
+   memset(results->m_pSelectors, (best_x >> 4) & 3, num_colors);
+   {
+      const uint best_packed_c0 = (best_x >> 8) & 255;
+      rg_etc1_color_quad_u8_component_set(&results->m_block_color_unscaled, best_i, (uint8)best_packed_c0);
+      rg_etc1_color_quad_u8_component_set(&results->m_block_color_unscaled, s_next_comp[best_i], (uint8)best_packed_c1);
+      rg_etc1_color_quad_u8_component_set(&results->m_block_color_unscaled, s_next_comp[best_i+1], (uint8)best_packed_c2);
+      results->m_error = best_error;
+   }
+   return best_error;
+}
+#endif
+
+#if RG_ETC1_DITHERING
+// Function originally from RYG's public domain real-time DXT1 compressor, modified for 555.
+static void
+rg_etc1_dither_block_555(color_quad_u8* dest, color_quad_u8* block)
+{
+   int err[8],*ep1 = err,*ep2 = err+4;
+   uint8 *quant = rg_etc_quant5_tab+8;
+   int ch;
+
+   memset(dest, 0xFF, sizeof(color_quad_u8)*16);
+
+   // process channels seperately
+   for(ch=0;ch<3;ch++)
+     {
+        uint8* bp = (uint8*)block;
+        uint8* dp = (uint8*)dest;
+        int y;
+
+        bp += ch; dp += ch;
+
+        memset(err,0, sizeof(err));
+        for(y = 0; y < 4; y++)
+          {
+             int *tmp;
+             // pixel 0
+             dp[ 0] = quant[bp[ 0] + ((3*ep2[1] + 5*ep2[0]) >> 4)];
+             ep1[0] = bp[ 0] - dp[ 0];
+
+             // pixel 1
+             dp[ 4] = quant[bp[ 4] + ((7*ep1[0] + 3*ep2[2] + 5*ep2[1] + ep2[0]) >> 4)];
+             ep1[1] = bp[ 4] - dp[ 4];
+
+             // pixel 2
+             dp[ 8] = quant[bp[ 8] + ((7*ep1[1] + 3*ep2[3] + 5*ep2[2] + ep2[1]) >> 4)];
+             ep1[2] = bp[ 8] - dp[ 8];
+
+             // pixel 3
+             dp[12] = quant[bp[12] + ((7*ep1[2] + 5*ep2[3] + ep2[2]) >> 4)];
+             ep1[3] = bp[12] - dp[12];
+
+             // advance to next line
+             tmp = ep1; ep1 = ep2; ep2 = tmp;
+             bp += 16;
+             dp += 16;
+          }
+     }
+}
+#endif
+
+static inline unsigned int
+_bgra_to_rgba(unsigned int val)
+{
+   //(((a) << 24) + ((r) << 16) + ((g) << 8) + (b))
+   return ARGB_JOIN(A_VAL_GET(&val), R_VAL_GET(&val), G_VAL_GET(&val), B_VAL_GET(&val));
+}
+
+static void
+_bgra_to_rgba_block(color_quad_u8 *output, const unsigned int *input, int len)
+{
+   for (int k = len; k; --k)
+     {
+        output->m_u32 = _bgra_to_rgba(*input++);
+        output++;
+     }
+}
+
+unsigned int
+rg_etc1_pack_block(void* pETC1_block, const unsigned int* pSrc_pixels_BGRA, rg_etc1_pack_params *pack_params)
+{
+   color_quad_u8 pSrc_pixels[16];
+   unsigned char *dst_block = (unsigned char *)pETC1_block;
+   unsigned int first_pixel_u32;
+   int r;
+   color_quad_u8 subblock_pixels[8];
+   uint64 best_error = cUINT64_MAX;
+   uint best_use_color4=EINA_FALSE;
+   uint best_flip=EINA_FALSE;
+   uint8 best_selectors[2][8];
+   rg_etc1_optimizer optimizer = { 0 };
+   rg_etc1_optimizer_results best_results[2] = { { 0 } };
+   rg_etc1_optimizer_results results[3] = { { 0 } };
+   rg_etc1_optimizer_params params;
+   uint i, flip;
+   uint8 selectors[3][8];
+   int dr, dg, db;
+   uint selector0 = 0, selector1 = 0;
+   static const int s_scan_delta_0_to_4[] = { -4, -3, -2, -1, 0, 1, 2, 3, 4 };
+   static const int s_scan_delta_0_to_1[] = { -1, 0, 1 };
+   static const int s_scan_delta_0[] = { 0 };
+
+#ifdef RG_ETC1_BUILD_DEBUG
+   // Ensure all alpha values are 0xFF.
+   for (i = 0; i < 16; i++)
+     {
+        // ERROR CASE NO ASSERT IN EVAS CODE
+        if (pSrc_pixels[i].comp.a != 255) return 0;
+     }
+#endif
+   rg_etc1_optimizer_clear(&optimizer);
+
+   // Convert evas BGRA to rg_etc1 RGBA
+   _bgra_to_rgba_block(pSrc_pixels, pSrc_pixels_BGRA, 16);
+   first_pixel_u32 = pSrc_pixels[0].m_u32;
+
+   // Check for solid block.
+   for (r = 15; r >= 1; --r)
+     if (pSrc_pixels[r].m_u32 != first_pixel_u32)
+       break;
+   if (!r)
+     return (unsigned int)(16 * rg_etc1_pack_block_solid_color(dst_block, &pSrc_pixels[0], pack_params));
+
+#if RG_ETC1_DITHERING
+   // Dithering gives mitigated results... It would be nice to know when to use it.
+   color_quad_u8 dithered_pixels[16];
+   if (pack_params->m_dithering)
+     {
+        rg_etc1_dither_block_555(dithered_pixels, pSrc_pixels);
+        pSrc_pixels = dithered_pixels;
+     }
+#endif
+
+   for (i = 0; i < 2; i++)
+     {
+        best_results[i].m_n = 8;
+        best_results[i].m_pSelectors = best_selectors[i];
+     }
+
+   for (i = 0; i < 3; i++)
+     {
+        results[i].m_n = 8;
+        results[i].m_pSelectors = selectors[i];
+     }
+
+   rg_etc1_optimizer_params_clean(&params);
+   params.base_params = pack_params;
+   params.m_num_src_pixels = 8;
+   params.m_pSrc_pixels = subblock_pixels;
+
+   // try horizontal VS. vertical split
+   for (flip = 0; flip < 2; flip++)
+     {
+        // try two color types: RGB555 + diff333 or RGB444 & RGB444
+        uint use_color4;
+        for (use_color4 = 0; use_color4 < 2; use_color4++)
+          {
+             uint64 trial_error = 0;
+
+             // subblock is either top/bottom or left/right
+             uint subblock;
+             for (subblock = 0; subblock < 2; subblock++)
+               {
+                  results[2].m_error = cUINT64_MAX;
+
+                  if (flip)
+                    // subblock is top or bottom, copy source
+                    memcpy(subblock_pixels, pSrc_pixels + subblock * 8, sizeof(color_quad_u8) * 8);
+                  else
+                    {
+                       // subblock = 1 : left, subblock = 2 : right, copy source
+                       const color_quad_u8* pSrc_col = pSrc_pixels + subblock * 2;
+                       rg_etc1_color_quad_u8_copy(&subblock_pixels[0], &pSrc_col[0]);
+                       rg_etc1_color_quad_u8_copy(&subblock_pixels[1], &pSrc_col[4]);
+                       rg_etc1_color_quad_u8_copy(&subblock_pixels[2], &pSrc_col[8]);
+                       rg_etc1_color_quad_u8_copy(&subblock_pixels[3], &pSrc_col[12]);
+                       rg_etc1_color_quad_u8_copy(&subblock_pixels[4], &pSrc_col[1]);
+                       rg_etc1_color_quad_u8_copy(&subblock_pixels[5], &pSrc_col[5]);
+                       rg_etc1_color_quad_u8_copy(&subblock_pixels[6], &pSrc_col[9]);
+                       rg_etc1_color_quad_u8_copy(&subblock_pixels[7], &pSrc_col[13]);
+                    }
+
+#if RG_ETC1_CONSTRAINED_SUBBLOCK
+                  if ((params.base_params->m_quality >= rg_etc1_medium_quality) && ((subblock) || (use_color4)))
+                    {
+                       const uint32 subblock_pixel0_u32 = subblock_pixels[0].m_u32;
+                       for (r = 7; r >= 1; --r)
+                         if (subblock_pixels[r].m_u32 != subblock_pixel0_u32)
+                           break;
+                       if (!r)
+                         {
+                            // all pixels in subblock have the same color
+                            rg_etc1_pack_block_solid_color_constrained(&results[2], 8, &subblock_pixels[0].comp.r,
+                                                                       pack_params, !use_color4,
+                                                                       (subblock && !use_color4) ? &results[0].m_block_color_unscaled : NULL);
+                         }
+                    }
+#endif
+
+                  params.m_use_color4 = (use_color4 != 0);
+                  params.m_constrain_against_base_color5 = EINA_FALSE;
+
+                  if ((!use_color4) && (subblock))
+                    {
+                       params.m_constrain_against_base_color5 = EINA_TRUE;
+                       rg_etc1_color_quad_u8_copy(&params.m_base_color5,&results[0].m_block_color_unscaled);
+                    }
+
+                  if (params.base_params->m_quality == rg_etc1_high_quality)
+                    {
+                       params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_0_to_4);
+                       params.m_pScan_deltas = s_scan_delta_0_to_4;
+                    }
+                  else if (params.base_params->m_quality == rg_etc1_medium_quality)
+                    {
+                       params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_0_to_1);
+                       params.m_pScan_deltas = s_scan_delta_0_to_1;
+                    }
+                  else
+                    {
+                       params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_0);
+                       params.m_pScan_deltas = s_scan_delta_0;
+                    }
+
+                  rg_etc1_optimizer_init(&optimizer, &params, &results[subblock]);
+                  if (!rg_etc1_optimizer_compute(&optimizer))
+                    break;
+
+                  if (params.base_params->m_quality >= rg_etc1_medium_quality)
+                    {
+                       // TODO: Fix fairly arbitrary/unrefined thresholds that control how far away to scan for potentially better solutions.
+                       const uint refinement_error_thresh0 = 3000;
+                       const uint refinement_error_thresh1 = 6000;
+                       if (results[subblock].m_error > refinement_error_thresh0)
+                         {
+                            if (params.base_params->m_quality == rg_etc1_medium_quality)
+                              {
+                                 static const int s_scan_delta_2_to_3[] = { -3, -2, 2, 3 };
+                                 params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_2_to_3);
+                                 params.m_pScan_deltas = s_scan_delta_2_to_3;
+                              }
+                            else
+                              {
+                                 static const int s_scan_delta_5_to_5[] = { -5, 5 };
+                                 static const int s_scan_delta_5_to_8[] = { -8, -7, -6, -5, 5, 6, 7, 8 };
+                                 if (results[subblock].m_error > refinement_error_thresh1)
+                                   {
+                                      params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_5_to_8);
+                                      params.m_pScan_deltas = s_scan_delta_5_to_8;
+                                   }
+                                 else
+                                   {
+                                      params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_5_to_5);
+                                      params.m_pScan_deltas = s_scan_delta_5_to_5;
+                                   }
+                              }
+
+                            if (!rg_etc1_optimizer_compute(&optimizer))
+                              break;
+                         }
+
+                       if (results[2].m_error < results[subblock].m_error)
+                         results[subblock] = results[2];
+                    }
+
+                  trial_error += results[subblock].m_error;
+                  if (trial_error >= best_error)
+                    break;
+               }
+
+             if (subblock < 2)
+               continue;
+
+             best_error = trial_error;
+             rg_etc1_optimizer_results_duplicate(&best_results[0], &results[0]);
+             rg_etc1_optimizer_results_duplicate(&best_results[1], &results[1]);
+             best_flip = flip;
+             best_use_color4 = use_color4;
+          } // use_color4
+     } // flip
+
+   dr = best_results[1].m_block_color_unscaled.comp.r - best_results[0].m_block_color_unscaled.comp.r;
+   dg = best_results[1].m_block_color_unscaled.comp.g - best_results[0].m_block_color_unscaled.comp.g;
+   db = best_results[1].m_block_color_unscaled.comp.b - best_results[0].m_block_color_unscaled.comp.b;
+   // ERROR CASE NO ASSERT IN EVAS CODE
+   if (!(best_use_color4 || ((MIN(MIN(dr, dg), db) >= cETC1ColorDeltaMin) && (MAX(MAX(dr, dg), db) <= cETC1ColorDeltaMax)))) return 0;
+
+   if (best_use_color4)
+     {
+        dst_block[0] = (uint8)(best_results[1].m_block_color_unscaled.comp.r |
+                               (best_results[0].m_block_color_unscaled.comp.r << 4));
+        dst_block[1] = (uint8)(best_results[1].m_block_color_unscaled.comp.g |
+                               (best_results[0].m_block_color_unscaled.comp.g << 4));
+        dst_block[2] = (uint8)(best_results[1].m_block_color_unscaled.comp.b |
+                               (best_results[0].m_block_color_unscaled.comp.b << 4));
+     }
+   else
+     {
+        if (dr < 0) dr += 8; dst_block[0] = (uint8)((best_results[0].m_block_color_unscaled.comp.r << 3) | dr);
+        if (dg < 0) dg += 8; dst_block[1] = (uint8)((best_results[0].m_block_color_unscaled.comp.g << 3) | dg);
+        if (db < 0) db += 8; dst_block[2] = (uint8)((best_results[0].m_block_color_unscaled.comp.b << 3) | db);
+     }
+
+   dst_block[3] = (uint8)((best_results[1].m_block_inten_table << 2) |
+                          (best_results[0].m_block_inten_table << 5) |
+                          ((~best_use_color4 & 1) << 1) | best_flip );
+
+   if (best_flip)
+     {
+        // flipped:
+        // { 0, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 },
+        // { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 }
+        //
+        // { 0, 2 }, { 1, 2 }, { 2, 2 }, { 3, 2 },
+        // { 0, 3 }, { 1, 3 }, { 2, 3 }, { 3, 3 }
+        const uint8* pSelectors0 = best_results[0].m_pSelectors;
+        const uint8* pSelectors1 = best_results[1].m_pSelectors;
+        int x;
+        for (x = 3; x >= 0; --x)
+          {
+             uint b;
+             b = rg_etc_selector_index_to_etc1[pSelectors1[4 + x]];
+             selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1);
+
+             b = rg_etc_selector_index_to_etc1[pSelectors1[x]];
+             selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1);
+
+             b = rg_etc_selector_index_to_etc1[pSelectors0[4 + x]];
+             selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1);
+
+             b = rg_etc_selector_index_to_etc1[pSelectors0[x]];
+             selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1);
+          }
+     }
+   else
+     {
+        // non-flipped:
+        // { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 },
+        // { 1, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 }
+        //
+        // { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 },
+        // { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 }
+        int subblock;
+        for (subblock = 1; subblock >= 0; --subblock)
+          {
+             const uint8* pSelectors = best_results[subblock].m_pSelectors + 4;
+             uint j;
+             for (j = 0; j < 2; j++)
+               {
+                  uint b;
+                  b = rg_etc_selector_index_to_etc1[pSelectors[3]];
+                  selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1);
+
+                  b = rg_etc_selector_index_to_etc1[pSelectors[2]];
+                  selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1);
+
+                  b = rg_etc_selector_index_to_etc1[pSelectors[1]];
+                  selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1);
+
+                  b = rg_etc_selector_index_to_etc1[pSelectors[0]];
+                  selector0 = (selector0 << 1) | (b & 1);selector1 = (selector1 << 1) | (b >> 1);
+
+                  pSelectors -= 4;
+               }
+          }
+     }
+
+   dst_block[4] = (uint8)(selector1 >> 8); dst_block[5] = (uint8)(selector1 & 0xFF);
+   dst_block[6] = (uint8)(selector0 >> 8); dst_block[7] = (uint8)(selector0 & 0xFF);
+   return (unsigned int)(best_error);
+}
diff --git a/src/static_deps/rg_etc/rg_etc1.h b/src/static_deps/rg_etc/rg_etc1.h
new file mode 100644 (file)
index 0000000..6f4b944
--- /dev/null
@@ -0,0 +1,78 @@
+// File: rg_etc1.h - Fast, high quality ETC1 block packer/unpacker - Rich Geldreich <richgel99@gmail.com>
+// Please see ZLIB license at the end of this file.
+#ifndef __RG_ETC1_H__
+#define __RG_ETC1_H__
+
+typedef unsigned char bool;
+
+// Unpacks an 8-byte ETC1 compressed block to a block of 4x4 32bpp RGBA pixels.
+// Returns false if the block is invalid. Invalid blocks will still be unpacked with clamping.
+// This function is thread safe, and does not dynamically allocate any memory.
+// If preserve_alpha is true, the alpha channel of the destination pixels will not be overwritten. Otherwise, alpha will be set to 255.
+bool rg_etc1_unpack_block(const void *pETC1_block, unsigned int* pDst_pixels_rgba, bool preserve_alpha);
+
+// Quality setting = the higher the quality, the slower.
+// To pack large textures, it is highly recommended to call pack_etc1_block() in parallel, on different blocks, from multiple threads (particularly when using cHighQuality).
+typedef enum {
+  rg_etc1_low_quality,
+  rg_etc1_medium_quality,
+  rg_etc1_high_quality
+} rg_etc1_quality;
+
+
+typedef struct
+{
+   rg_etc1_quality m_quality;
+   bool m_dithering;
+} rg_etc1_pack_params;
+
+// pack_etc1_block_init() should be called before calling pack_etc1_block(),
+// Otherwise rg_etc1_pack_block() will call rg_etc1_pack_block_init() for you.
+void rg_etc1_pack_block_init();
+
+// Packs a 4x4 block of 32bpp BGRA pixels to an 8-byte ETC1 block.
+// 32-bit BGRA pixels must always be arranged as (B,G,R,A) (B first, A last) in memory, independent of platform endianness. A should always be 255.
+// Returns squared error of result.
+// This function is thread safe, and does not dynamically allocate any memory.
+// pack_etc1_block() does not currently support "perceptual" colorspace metrics - it primarily optimizes for RGB RMSE.
+unsigned int rg_etc1_pack_block(void* pETC1_block, const unsigned int* pSrc_pixels_BGRA, rg_etc1_pack_params *pack_params);
+
+// Pack a 4x4 block of 32bpp BGRA pixels to a 16-byte RGBA8_ETC2_EAC block (supports alpha).
+unsigned int etc2_rgba8_block_pack(unsigned char *etc2, const unsigned int *bgra, rg_etc1_pack_params *params);
+
+// Pack a 4x4 block of 32bpp BGRA pixels to a 8-byte RGB8_ETC2 block (opaque).
+unsigned int etc2_rgb8_block_pack(unsigned char *etc2, const unsigned int *bgra, rg_etc1_pack_params *params);
+
+// ETC2 support: RGB8_ETC2
+void rg_etc2_rgb8_decode_block(const unsigned char *etc_block, unsigned int *bgra);
+
+// ETC2 support: RGBA8_ETC2_EAC
+void rg_etc2_rgba8_decode_block(const unsigned char *etc_block, unsigned int *bgra);
+
+//------------------------------------------------------------------------------
+//
+// rg_etc1 uses the ZLIB license:
+// http://opensource.org/licenses/Zlib
+//
+// Copyright (c) 2012 Rich Geldreich
+//
+// This software is provided 'as-is', without any express or implied
+// warranty.  In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+//------------------------------------------------------------------------------
+#endif // __RG_ETC1_H__
diff --git a/src/static_deps/rg_etc/rg_etc2.c b/src/static_deps/rg_etc/rg_etc2.c
new file mode 100644 (file)
index 0000000..18b3f4f
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+Copyright (C) 2014 Jean-Philippe ANDRE
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ * ETC2 decoding functions, reimplemented from scratch based on the
+ * OpenGL ES 3.0 spec (annex C.1).
+ *
+ * @author Jean-Philippe ANDRE
+ * @license BSD-2 with advertisement clause
+ */
+
+#include <Eina.h>
+#include "rg_etc1.h"
+
+void rg_etc2_rgb8_decode_block(const unsigned char *etc_block, unsigned int *bgra);
+void rg_etc2_rgba8_decode_block(const unsigned char *etc_block, unsigned int *bgra);
+
+typedef const uint8_t etc_block;
+
+// For T and H modes
+static const int kDistances[8] = {
+   3, 6, 11, 16, 23, 32, 41, 64
+};
+
+// For differential mode
+static const int kSigned3bit[8] = {
+   0, 1, 2, 3, -4, -3, -2, -1
+};
+
+// For alpha support
+static const int kAlphaModifiers[16][8] = {
+   {  -3,  -6,  -9,  -15,  2,  5,  8,  14},
+   {  -3,  -7, -10,  -13,  2,  6,  9,  12},
+   {  -2,  -5,  -8,  -13,  1,  4,  7,  12},
+   {  -2,  -4,  -6,  -13,  1,  3,  5,  12},
+   {  -3,  -6,  -8,  -12,  2,  5,  7,  11},
+   {  -3,  -7,  -9,  -11,  2,  6,  8,  10},
+   {  -4,  -7,  -8,  -11,  3,  6,  7,  10},
+   {  -3,  -5,  -8,  -11,  2,  4,  7,  10},
+   {  -2,  -6,  -8,  -10,  1,  5,  7,   9},
+   {  -2,  -5,  -8,  -10,  1,  4,  7,   9},
+   {  -2,  -4,  -8,  -10,  1,  3,  7,   9},
+   {  -2,  -5,  -7,  -10,  1,  4,  6,   9},
+   {  -3,  -4,  -7,  -10,  2,  3,  6,   9},
+   {  -1,  -2,  -3,  -10,  0,  1,  2,   9},
+   {  -4,  -6,  -8,   -9,  3,  5,  7,   8},
+   {  -3,  -5,  -7,   -9,  2,  4,  6,   8}
+};
+
+// Use with static constants so the compiler can optimize everything
+#define BITS(byteval, lowbit, highbit) \
+   (((byteval) >> (lowbit)) & ((1 << ((highbit) - (lowbit) + 1)) - 1))
+
+#define BIT(byteval, bit) \
+   (((byteval) >> (bit)) & 0x1)
+
+// Clamps only if value is > 255
+#define CLAMPDOWN(a) ({ int _z = (a); ((_z <= 255) ? _z : 255); })
+
+// Clamps only if value is < 0
+#define CLAMPUP(a) ({ int _z = (a); ((_z >= 0) ? _z : 0); })
+
+// Real clamp
+#define CLAMP(a) ({ int _b = (a); (((_b) >= 0) ? (((_b) < 256) ? (_b) : 255) : 0); })
+
+// Simple min
+#define MIN(a,b) ({ int _z = (a), _y = (b); ((_z <= _y) ? _z : _y); })
+
+// Write a BGRA value for output to Evas
+#define BGRA(r,g,b,a) ((a << 24) | (r << 16) | (g << 8) | b)
+
+#define _4to8(a) ({ int _a = (a) & ((1 << 4) - 1); ((_a << 4) | (_a & 0xf)); })
+#define _5to8(a) ({ int _a = (a) & ((1 << 5) - 1); ((_a << 3) | ((_a >> 2) & 0x7)); })
+#define _6to8(a) ({ int _a = (a) & ((1 << 6) - 1); ((_a << 2) | ((_a >> 4) & 0x3)); })
+#define _7to8(a) ({ int _a = (a) & ((1 << 7) - 1); ((_a << 1) | ((_a >> 6) & 0x1)); })
+
+#ifndef WORDS_BIGENDIAN
+/* x86 */
+#define A_VAL(p) (((uint8_t *)(p))[3])
+#define R_VAL(p) (((uint8_t *)(p))[2])
+#define G_VAL(p) (((uint8_t *)(p))[1])
+#define B_VAL(p) (((uint8_t *)(p))[0])
+#else
+/* ppc */
+#define A_VAL(p) (((uint8_t *)(p))[0])
+#define R_VAL(p) (((uint8_t *)(p))[1])
+#define G_VAL(p) (((uint8_t *)(p))[2])
+#define B_VAL(p) (((uint8_t *)(p))[3])
+#endif
+
+
+static inline void
+_T_mode_color_read(const uint8_t *etc, uint32_t *paint_colors)
+{
+   // 4 bit colors
+   const int r1_4 = (BITS(etc[0], 3, 4) << 2) | BITS(etc[0], 0, 1);
+   const int g1_4 = BITS(etc[1], 4, 7);
+   const int b1_4 = BITS(etc[1], 0, 3);
+   const int r2_4 = BITS(etc[2], 4, 7);
+   const int g2_4 = BITS(etc[2], 0, 3);
+   const int b2_4 = BITS(etc[3], 4, 7);
+
+   // Distance index
+   const int didx = (BITS(etc[3], 2, 3) << 1) | BIT(etc[3], 0);
+   const int d = kDistances[didx];
+
+   // Write out paint colors for T mode
+   paint_colors[0] = BGRA(_4to8(r1_4), _4to8(g1_4), _4to8(b1_4), 255);
+   paint_colors[1] = BGRA(CLAMPDOWN(_4to8(r2_4) + d),
+                          CLAMPDOWN(_4to8(g2_4) + d),
+                          CLAMPDOWN(_4to8(b2_4) + d),
+                          255);
+   paint_colors[2] = BGRA(_4to8(r2_4), _4to8(g2_4), _4to8(b2_4), 255);
+   paint_colors[3] = BGRA(CLAMPUP(_4to8(r2_4) - d),
+                          CLAMPUP(_4to8(g2_4) - d),
+                          CLAMPUP(_4to8(b2_4) - d),
+                          255);
+}
+
+static inline void
+_H_mode_color_read(const uint8_t *etc, uint32_t *paint_colors)
+{
+   // 4 bit colors
+   const int r1_4 = BITS(etc[0], 3, 6);
+   const int g1_4 = (BITS(etc[0], 0, 2) << 1) | (BIT(etc[1], 4));
+   const int b1_4 = (BIT(etc[1], 3) << 3) | (BITS(etc[1], 0, 1) << 1) | (BIT(etc[2], 7));
+   const int r2_4 = BITS(etc[2], 3, 6);
+   const int g2_4 = (BITS(etc[2], 0, 2) << 1) | (BIT(etc[3], 7));
+   const int b2_4 = BITS(etc[3], 3, 6);
+
+   // Distance index
+   const int basecol1 = (_4to8(r1_4) << 16) | (_4to8(g1_4) << 8) | _4to8(b1_4);
+   const int basecol2 = (_4to8(r2_4) << 16) | (_4to8(g2_4) << 8) | _4to8(b2_4);
+   const int didx =
+         (BIT(etc[3], 2) << 2) |
+         (BIT(etc[3], 0) << 1) |
+         ((basecol1 >= basecol2) ? 1 : 0);
+   const int d = kDistances[didx];
+
+   // Write out paint colors for H mode
+   paint_colors[0] = BGRA(CLAMPDOWN(_4to8(r1_4) + d),
+                          CLAMPDOWN(_4to8(g1_4) + d),
+                          CLAMPDOWN(_4to8(b1_4) + d),
+                          255);
+   paint_colors[1] = BGRA(CLAMPUP(_4to8(r1_4) - d),
+                          CLAMPUP(_4to8(g1_4) - d),
+                          CLAMPUP(_4to8(b1_4) - d),
+                          255);
+   paint_colors[2] = BGRA(CLAMPDOWN(_4to8(r2_4) + d),
+                          CLAMPDOWN(_4to8(g2_4) + d),
+                          CLAMPDOWN(_4to8(b2_4) + d),
+                          255);
+   paint_colors[3] = BGRA(CLAMPUP(_4to8(r2_4) - d),
+                          CLAMPUP(_4to8(g2_4) - d),
+                          CLAMPUP(_4to8(b2_4) - d),
+                          255);
+}
+
+static inline void
+_planar_mode_color_read(const uint8_t *etc, uint32_t *bgra)
+{
+   // RO: Bits 57-62
+   const int RO = _6to8(BITS(etc[0], 1, 6));
+   // GO: Bits 49-54,56
+   const int GO = _7to8((BIT(etc[0], 0) << 6) | (BITS(etc[1], 1, 6)));
+   // BO: Bits 39,40-41,43-44,48
+   const int BO = _6to8((BIT(etc[1], 0) << 5) | (BITS(etc[2], 3, 4) << 3) | (BITS(etc[2], 0, 1) << 1) | BIT(etc[3], 7));
+   // RH: Bits 32,34-38
+   const int RH = _6to8((BITS(etc[3], 2, 6) << 1) | BIT(etc[3], 0));
+   // GH: Bits 25-31
+   const int GH = _7to8(BITS(etc[4], 1, 7));
+   // BH: Bits 19-23,24
+   const int BH = _6to8((BIT(etc[4], 0) << 5) | (BITS(etc[5], 3, 7)));
+   // RV: Bits 13-15,16-18
+   const int RV = _6to8((BITS(etc[5], 0, 2) << 3) | (BITS(etc[6], 5, 7)));
+   // GV: Bits 6-7,8-12
+   const int GV = _7to8((BITS(etc[6], 0, 4) << 2) | (BITS(etc[7], 6, 7)));
+   // BV: Bits 0-5
+   const int BV = _6to8(BITS(etc[7], 0, 5));
+
+   for (int y = 0; y < 4; y++)
+     for (int x = 0; x < 4; x++)
+       {
+          // Formulas straight from the spec
+          const int R = CLAMP(((x * (RH - RO)) + y * (RV - RO) + 4 * RO + 2) >> 2);
+          const int G = CLAMP(((x * (GH - GO)) + y * (GV - GO) + 4 * GO + 2) >> 2);
+          const int B = CLAMP(((x * (BH - BO)) + y * (BV - BO) + 4 * BO + 2) >> 2);
+          *bgra++ = BGRA(R, G, B, 255);
+       }
+}
+
+static inline void
+_TH_paint(const uint8_t *etc, uint32_t paint_colors[4], uint32_t *bgra)
+{
+   // Common code for modes T and H.
+
+   // a,b,c,d
+   bgra[ 0] = paint_colors[(BIT(etc[5], 0) << 1) | (BIT(etc[7], 0))];
+   bgra[ 4] = paint_colors[(BIT(etc[5], 1) << 1) | (BIT(etc[7], 1))];
+   bgra[ 8] = paint_colors[(BIT(etc[5], 2) << 1) | (BIT(etc[7], 2))];
+   bgra[12] = paint_colors[(BIT(etc[5], 3) << 1) | (BIT(etc[7], 3))];
+
+   // e,f,g,h
+   bgra[ 1] = paint_colors[(BIT(etc[5], 4) << 1) | (BIT(etc[7], 4))];
+   bgra[ 5] = paint_colors[(BIT(etc[5], 5) << 1) | (BIT(etc[7], 5))];
+   bgra[ 9] = paint_colors[(BIT(etc[5], 6) << 1) | (BIT(etc[7], 6))];
+   bgra[13] = paint_colors[(BIT(etc[5], 7) << 1) | (BIT(etc[7], 7))];
+
+   // i,j,k,l
+   bgra[ 2] = paint_colors[(BIT(etc[4], 0) << 1) | (BIT(etc[6], 0))];
+   bgra[ 6] = paint_colors[(BIT(etc[4], 1) << 1) | (BIT(etc[6], 1))];
+   bgra[10] = paint_colors[(BIT(etc[4], 2) << 1) | (BIT(etc[6], 2))];
+   bgra[14] = paint_colors[(BIT(etc[4], 3) << 1) | (BIT(etc[6], 3))];
+
+   // m,n,o,p
+   bgra[ 3] = paint_colors[(BIT(etc[4], 4) << 1) | (BIT(etc[6], 4))];
+   bgra[ 7] = paint_colors[(BIT(etc[4], 5) << 1) | (BIT(etc[6], 5))];
+   bgra[11] = paint_colors[(BIT(etc[4], 6) << 1) | (BIT(etc[6], 6))];
+   bgra[15] = paint_colors[(BIT(etc[4], 7) << 1) | (BIT(etc[6], 7))];
+}
+
+void
+rg_etc2_rgb8_decode_block(const unsigned char *etc, unsigned int *bgra)
+{
+   // Check differential mode bit
+   if ((etc[3] & 0x2) == 0)
+     goto etc1;
+
+   // Read R,G,B
+   const int R  = BITS(etc[0], 3, 7);
+   const int dR = kSigned3bit[BITS(etc[0], 0, 2)];
+   const int G  = BITS(etc[1], 3, 7);
+   const int dG = kSigned3bit[BITS(etc[1], 0, 2)];
+   const int B  = BITS(etc[2], 3, 7);
+   const int dB = kSigned3bit[BITS(etc[2], 0, 2)];
+   uint32_t paint_colors[4];
+
+   if ((R + dR) < 0 || (R + dR) >= 32)
+     {
+        // T mode
+        _T_mode_color_read(etc, paint_colors);
+        _TH_paint(etc, paint_colors, bgra);
+        return;
+     }
+   if ((G + dG) < 0 || (G + dG) >= 32)
+     {
+        // H mode
+        _H_mode_color_read(etc, paint_colors);
+        _TH_paint(etc, paint_colors, bgra);
+        return;
+     }
+   if ((B + dB) < 0 || (B + dB) >= 32)
+     {
+        // Planar mode
+        _planar_mode_color_read(etc, bgra);
+        return;
+     }
+
+etc1:
+   // Valid differential mode or individual mode: ETC1
+   if (!rg_etc1_unpack_block(etc, bgra, 0))
+     fprintf(stderr, "ETC2: Something very strange is happening here!\n");
+}
+
+void
+rg_etc2_rgba8_decode_block(const unsigned char *etc, unsigned int *bgra)
+{
+   const uint8_t zeros[7] = {0};
+   uint32_t table_index;
+   int base_codeword;
+   int multiplier;
+
+   base_codeword = etc[0];
+
+   // Fast path if alpha is the same for all pixels
+   if (!memcmp(etc + 1, zeros, 7))
+     {
+        if (!base_codeword)
+          memset(bgra, 0, 64);
+        else
+          {
+             rg_etc2_rgb8_decode_block(etc + 8, bgra);
+             if (base_codeword != 255)
+               for (int k = 0; k < 16; k++)
+                 {
+                    const uint32_t rgb = *bgra;
+                    const int R = MIN(R_VAL(&rgb), base_codeword);
+                    const int G = MIN(G_VAL(&rgb), base_codeword);
+                    const int B = MIN(B_VAL(&rgb), base_codeword);
+                    *bgra++ = BGRA(R, G, B, base_codeword);
+                 }
+          }
+        return;
+     }
+
+   rg_etc2_rgb8_decode_block(etc + 8, bgra);
+
+   multiplier = BITS(etc[1], 4, 7);
+   table_index = BITS(etc[1], 0, 3);
+
+   for (int x = 0, k = 0; x < 4; x++)
+     for (int y = 0; y < 4; y++, k += 3)
+       {
+          const uint32_t byte = (k >> 3); // = [k/8]
+          const uint32_t bit = k - (byte << 3); // = k%8
+          const uint32_t rgb = bgra[(y << 2) + x];
+          uint32_t index, alpha, R, G, B;
+
+          if (bit < 6)
+            index = BITS(etc[byte + 2], 5 - bit, 7 - bit);
+          else if (bit == 6)
+            index = (BITS(etc[byte + 2], 0, 1) << 1) | BIT(etc[byte + 3], 7);
+          else // bit == 7
+            index = (BIT(etc[byte + 2], 0) << 2) | BITS(etc[byte + 3], 6, 7);
+          alpha = CLAMP(base_codeword + kAlphaModifiers[table_index][index] * multiplier);
+          R = MIN(R_VAL(&rgb), alpha);
+          G = MIN(G_VAL(&rgb), alpha);
+          B = MIN(B_VAL(&rgb), alpha);
+          bgra[(y << 2) + x] = BGRA(R, G, B, alpha);
+       }
+}
index c659106..d1790d4 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS = \
 -DPACKAGE_BIN_DIR=\"$(bindir)\" \
 -DPACKAGE_LIB_DIR=\"$(libdir)\" \
 -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
-@EINA_CFLAGS@ \
+@EVAS_GENERAL_CFLAGS@ \
 @CHECK_CFLAGS@
 
 if EFL_ENABLE_TESTS
@@ -24,6 +24,6 @@ evas_test_callbacks.c \
 evas_tests_helpers.h \
 evas_suite.h
 
-evas_suite_LDADD = @CHECK_LIBS@ $(top_builddir)/src/lib/libevas.la @EINA_LIBS@
+evas_suite_LDADD = @CHECK_LIBS@ $(top_builddir)/src/lib/libevas.la @EVAS_GENERAL_LIBS@
 
 endif
index 99ab405..edf1bbe 100644 (file)
@@ -113,7 +113,10 @@ START_TEST(evas_text_geometries)
         fail_if(x <= px);
         px = x;
         /* Get back the coords */
-        fail_if(i != evas_object_text_char_coords_get(to, x + (w / 2),
+        fail_if(i != evas_object_text_char_coords_get(to, x + (w / 4),
+                 y + (h / 2), NULL, NULL, NULL, NULL));
+        /* Get back cursor position, if click on right half of char. */
+        fail_if((i + 1) != evas_object_text_char_coords_get(to, x + ((3 * w) / 4),
                  y + (h / 2), &x, &y, &w, &h));
      }
 
@@ -362,7 +365,20 @@ START_TEST(evas_text_bidi)
         fail_if(x >= px);
         px = x;
         /* Get back the coords */
-        fail_if(i != evas_object_text_char_coords_get(to, x + (w / 2),
+        fail_if(i != evas_object_text_char_coords_get(to, x + ((3 * w) / 4),
+                 y + (h / 2), &x, &y, &w, &h));
+     }
+
+   /* Get back cursor position, if click on left half of char.  */
+   evas_object_text_text_set(to, "שלום...");
+   x = 0;
+   px = 200;
+   for (i = 0 ; i < eina_unicode_utf8_get_len("שלום...") ; i++)
+     {
+        fail_if(!evas_object_text_char_pos_get(to, i, &x, &y, &w, &h));
+        fail_if(x >= px);
+        px = x;
+        fail_if((i + 1) != evas_object_text_char_coords_get(to, x + (w / 4),
                  y + (h / 2), &x, &y, &w, &h));
      }
 
@@ -376,7 +392,7 @@ START_TEST(evas_text_bidi)
         fail_if(x <= px);
         px = x;
         /* Get back the coords */
-        fail_if(i != evas_object_text_char_coords_get(to, x + (w / 2),
+        fail_if(i != evas_object_text_char_coords_get(to, x + (w / 4),
                  y + (h / 2), &x, &y, &w, &h));
      }
 
@@ -384,7 +400,7 @@ START_TEST(evas_text_bidi)
    fail_if(!evas_object_text_char_pos_get(to, i, &x, &y, &w, &h));
    fail_if(x <= px);
    px = x;
-   fail_if(i != evas_object_text_char_coords_get(to, x + (w / 2),
+   fail_if(i != evas_object_text_char_coords_get(to, x + ((3 * w) / 4),
             y + (h / 2), &x, &y, &w, &h));
    i++;
    for ( ; i < eina_unicode_utf8_get_len("Test - נסיון") ; i++)
@@ -421,7 +437,13 @@ START_TEST(evas_text_bidi)
         fail_if(x >= px);
         px = x;
         /* Get back the coords */
-        fail_if(i != evas_object_text_char_coords_get(to, x + (w / 2),
+        if (w == 0)
+          {
+             int cx;
+             fail_if(!evas_object_text_char_pos_get(to, i - 1, &cx, NULL, NULL, NULL));
+             w = cx - x;
+          }
+        fail_if(i != evas_object_text_char_coords_get(to, x + ((3 * w) / 4),
                  y + (h / 2), &x, &y, &w, &h));
      }
 
index aa1e3d0..9f2b43a 100644 (file)
@@ -590,9 +590,341 @@ START_TEST(evas_textblock_cursor)
         fail_if(18 != evas_textblock_cursor_pos_get(cur));
         evas_textblock_cursor_word_end(cur);
         fail_if(18 != evas_textblock_cursor_pos_get(cur));
+
+        /* Bug with 1 char word separators at paragraph start. */
+        evas_object_textblock_text_markup_set(tb, "=test");
+        evas_textblock_cursor_pos_set(cur, 4);
+        evas_textblock_cursor_word_start(cur);
+        fail_if(1 != evas_textblock_cursor_pos_get(cur));
+     }
+
+   END_TB_TEST();
+}
+END_TEST
+
+START_TEST(evas_textblock_split_cursor)
+{
+#ifdef HAVE_FRIBIDI
+   START_TB_TEST();
+   Evas_Coord x, w, x2, w2;
+   Evas_Coord nw, nh;
+   Evas_Coord cx, cy, cx2, cy2;
+
+   /* Split cursor in LTR paragraph. */
+   /*0123456789  10  123  14  5678901234 */
+   evas_object_textblock_text_markup_set(tb, "test נסיון\u202babc\u202cנסיון bang");
+   evas_object_textblock_size_native_get(tb, &nw, &nh);
+   evas_object_resize(tb, nw, nh);
+
+   /* Logical cursor after "test " */
+   evas_textblock_cursor_pos_set(cur, 5);
+   fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                    NULL, &cx2, NULL, NULL, NULL,
+                                                    EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pos_set(cur, 4);
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
+   evas_textblock_cursor_pos_set(cur, 5);
+   evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
+   fail_if(cx != (x + w));
+   fail_if(cx2 != (x2 + w2));
+
+   /* Logical cursor before " bang" */
+   evas_textblock_cursor_pos_set(cur, 20);
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
+   fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                    NULL, &cx2, NULL, NULL, NULL,
+                                                    EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pos_set(cur, 19);
+   evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
+   fail_if(cx != x);
+   fail_if(cx2 != x2);
+
+   /* Logical cursor before "a" */
+   evas_textblock_cursor_pos_set(cur, 11);
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
+   fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                    NULL, &cx2, NULL, NULL, NULL,
+                                                    EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pos_set(cur, 9);
+   evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
+   fail_if(cx != x);
+   fail_if(cx2 != x2);
+
+   /* Logical cursor after "c" */
+   evas_textblock_cursor_pos_set(cur, 15);
+   evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
+   fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                    NULL, &cx2, NULL, NULL, NULL,
+                                                    EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pos_set(cur, 13);
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
+   fail_if(cx != (x + w));
+   fail_if(cx2 != (x2 + w2));
+
+   /* Logical cursor in the beginning */
+   evas_textblock_cursor_line_char_first(cur);
+   fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                   NULL, NULL, NULL, NULL, NULL,
+                                                   EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
+   fail_if(cx != x);
+
+   /* Logical cursor in the end */
+   evas_textblock_cursor_line_char_last(cur);
+   fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                   NULL, NULL, NULL, NULL, NULL,
+                                                   EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pos_set(cur, 24);
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
+   fail_if(cx != (x + w));
+
+   /* Logical cursor on the first pos */
+   evas_textblock_cursor_pos_set(cur, 1);
+   fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                   NULL, NULL, NULL, NULL, NULL,
+                                                   EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
+   fail_if(cx != x);
+
+   /* Split cursor in RTL paragraph. */
+   /*              1                2
+    *                                                            0123456789   0  12345  6   7890123456 */
+   evas_object_textblock_text_markup_set(tb, "שלום test \u202aעברית\u202c efl נסיון");
+   evas_object_textblock_size_native_get(tb, &nw, &nh);
+   evas_object_resize(tb, nw, nh);
+
+   /* Logical cursor before "test" */
+   evas_textblock_cursor_pos_set(cur, 4);
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
+   evas_textblock_cursor_pos_set(cur, 5);
+
+   fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                    NULL, &cx2, NULL, NULL, NULL,
+                                                    EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pos_set(cur, 5);
+   evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
+   fail_if(cx != x);
+   fail_if(cx2 != x2);
+
+   /* Logical cursor after " efl" */
+   evas_textblock_cursor_pos_set(cur, 21);
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
+
+   fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                    NULL, &cx2, NULL, NULL, NULL,
+                                                    EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pos_set(cur, 20);
+   evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
+   fail_if(cx != (x + w));
+   fail_if(cx2 != (x2 + w2));
+
+   /* Logical cursor before " efl" */
+   evas_textblock_cursor_pos_set(cur, 17);
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
+
+   fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                    NULL, &cx2, NULL, NULL, NULL,
+                                                    EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pos_set(cur, 15);
+   evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
+   fail_if(cx != x2);
+   fail_if(cx2 != x);
+
+   /* Logical cursor after "test " */
+   evas_textblock_cursor_pos_set(cur, 11);
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
+
+   fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                    NULL, &cx2, NULL, NULL, NULL,
+                                                    EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pos_set(cur, 9);
+   evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
+   fail_if(cx != (x + w));
+   fail_if(cx2 != (x2 + w2));
+
+   /* Logical cursor in the beginning */
+   evas_textblock_cursor_line_char_first(cur);
+   fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                   NULL, NULL, NULL, NULL, NULL,
+                                                   EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
+   fail_if(cx != (x + w));
+
+   /* Logical cursor in the end */
+   evas_textblock_cursor_line_char_last(cur);
+   fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                   NULL, NULL, NULL, NULL, NULL,
+                                                   EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pos_set(cur, 26);
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
+   fail_if(cx != x);
+
+   /* Corner cases for split cursor. */
+
+   /* End of line in LTR paragraph */
+   /*         1
+    *                                                       01234567890123  4   567   */
+   evas_object_textblock_text_markup_set(tb, "test נסיוןشسيب\u202babc");
+   evas_textblock_cursor_line_char_last(cur);
+   evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
+   evas_object_textblock_size_native_get(tb, &nw, &nh);
+   evas_object_resize(tb, nw, nh);
+
+   evas_textblock_cursor_line_char_last(cur);
+   fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                    NULL, &cx2, NULL, NULL, NULL,
+                                                    EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pos_set(cur, 4);
+   evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
+   evas_textblock_cursor_pos_set(cur, 5);
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
+   fail_if(cx != (x + w));
+   fail_if(cx2 != (x2 + w2));
+
+   /* End of line in RTL paragraph */
+   /*            1              2
+    *                                                          0123456789012345678   9  0123 */
+   evas_object_textblock_text_markup_set(tb, "נסיוןشسي testпривет\u202aשלום");
+   evas_object_textblock_size_native_get(tb, &nw, &nh);
+   evas_object_resize(tb, nw, nh);
+
+   evas_textblock_cursor_line_char_last(cur);
+   fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                    NULL, &cx2, NULL, NULL, NULL,
+                                                    EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pos_set(cur, 8);
+   evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
+   evas_textblock_cursor_pos_set(cur, 9);
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
+   fail_if(cx != x);
+   fail_if(cx2 != x2);
+
+   /* Cursor is between items of the same direction */
+   evas_textblock_cursor_pos_set(cur, 13);
+   fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                   NULL, NULL, NULL, NULL, NULL,
+                                                   EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
+   fail_if(cx != x);
+
+   /* Cursor type is UNDER */
+   evas_textblock_cursor_pos_set(cur, 0);
+   fail_if(evas_textblock_cursor_geometry_bidi_get(cur, &cx, NULL, NULL,
+                                                   NULL, NULL, NULL, NULL, NULL,
+                                                   EVAS_TEXTBLOCK_CURSOR_UNDER));
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
+   fail_if(cx != x);
+
+   /* Multiline */
+   Evas_Coord ly;
+   int i;
+   /* 012345678901234 */
+   evas_object_textblock_text_markup_set(tb, "<wrap=char>testשלוםشسيبefl");
+   evas_object_textblock_size_native_get(tb, &nw, &nh);
+   nh = nh * 15;
+   evas_object_resize(tb, nw, nh);
+
+   for (i = 0; i < nw; i++)
+     {
+        evas_object_resize(tb, i, nh);
+
+        evas_textblock_cursor_pos_set(cur, 12);
+        fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, &cy, NULL,
+                                                         NULL, &cx2, &cy2, NULL, NULL,
+                                                         EVAS_TEXTBLOCK_CURSOR_BEFORE));
+        evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
+        fail_if(cy != ly);
+        evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
+        fail_if(cx != x);
+        evas_textblock_cursor_pos_set(cur, 11);
+        evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
+        fail_if(cy2 != ly);
+        evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
+        fail_if(cx2 != x2);
+     }
+   /* 01234567890123456789 */
+   evas_object_textblock_text_markup_set(tb, "<wrap=char>נסיוןhelloприветשלום");
+   evas_object_textblock_size_native_get(tb, &nw, &nh);
+   nh = nh * 20;
+   evas_object_resize(tb, nw, nh);
+
+   for (i = 0; i < nw; i++)
+     {
+        evas_object_resize(tb, i, nh);
+
+        evas_textblock_cursor_pos_set(cur, 16);
+        fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, &cy, NULL,
+                                                         NULL, &cx2, &cy2, NULL, NULL,
+                                                         EVAS_TEXTBLOCK_CURSOR_BEFORE));
+        evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
+        fail_if(cy != ly);
+        evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
+        fail_if(cx != (x + w));
+        evas_textblock_cursor_pos_set(cur, 15);
+        evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
+        fail_if(cy2 != ly);
+        evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
+        fail_if(cx2 != (x2 + w2));
      }
 
+   /* Testing multiline, when only RTL item is in the line. */
+   /* 012345678901234567890123 */
+   evas_object_textblock_text_markup_set(tb, "<wrap=char>testtesttestтестשלוםشسيب");
+   evas_object_textblock_size_native_get(tb, &nw, &nh);
+   nh = nh * 23;
+   evas_object_resize(tb, nw, nh);
+
+   evas_textblock_cursor_pos_set(cur, 15);
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
+   /* Resizing textblock, so RTL item will be on the next line.*/
+   evas_object_resize(tb, x + w, nh);
+
+   evas_textblock_cursor_pos_set(cur, 24);
+   fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, &cy, NULL,
+                                                    NULL, &cx2, &cy2, NULL, NULL,
+                                                    EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pos_set(cur, 16);
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
+   fail_if(cx != (x + w));
+   evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
+   fail_if(cy != ly);
+
+   evas_textblock_cursor_pos_set(cur, 23);
+   evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, NULL, NULL);
+   fail_if(cx2 != x2);
+   evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
+   fail_if(cy2 != ly);
+
+   /* Testing multiline, when only LTR item is in the line. */
+   /* 012345678901234567890123 */
+   evas_object_textblock_text_markup_set(tb, "<wrap=char>שלוםשלוםשלוםشسيبtestтест");
+   evas_object_textblock_size_native_get(tb, &nw, &nh);
+   nh = nh * 23;
+   evas_object_resize(tb, nw, nh);
+
+   evas_textblock_cursor_pos_set(cur, 15);
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, &w, NULL);
+   /* Resizing textblock, so LTR item will be on the next line.*/
+   evas_object_resize(tb, nw - x, nh);
+
+   evas_textblock_cursor_pos_set(cur, 24);
+   fail_if(!evas_textblock_cursor_geometry_bidi_get(cur, &cx, &cy, NULL,
+                                                    NULL, &cx2, &cy2, NULL, NULL,
+                                                    EVAS_TEXTBLOCK_CURSOR_BEFORE));
+   evas_textblock_cursor_pos_set(cur, 16);
+   evas_textblock_cursor_pen_geometry_get(cur, &x, NULL, NULL, NULL);
+   fail_if(cx != x);
+   evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
+   fail_if(cy != ly);
+
+   evas_textblock_cursor_pos_set(cur, 23);
+   evas_textblock_cursor_pen_geometry_get(cur, &x2, NULL, &w2, NULL);
+   fail_if(cx2 != (x2 + w2));
+   evas_textblock_cursor_line_geometry_get(cur, NULL, &ly, NULL, NULL);
+   fail_if(cy2 != ly);
+
    END_TB_TEST();
+#endif
 }
 END_TEST
 
@@ -801,6 +1133,17 @@ START_TEST(evas_textblock_format_removal)
    fnode = evas_textblock_node_format_first_get(tb);
    fail_if(fnode);
 
+
+   /* Deleting a range with just one char and surrounded by formats, that
+    * deletes a paragraph. */
+   evas_object_textblock_text_markup_set(tb, "A<ps/><b>B</b>");
+   evas_textblock_cursor_pos_set(cur, 2);
+   evas_textblock_cursor_pos_set(main_cur, 3);
+   evas_textblock_cursor_range_delete(cur, main_cur);
+   fnode = evas_textblock_node_format_first_get(tb);
+   fnode = evas_textblock_node_format_next_get(fnode);
+   fail_if (fnode);
+
    /* Two formats in the same place. */
    evas_object_textblock_text_markup_set(tb, "a<b><a>b</a></b>b");
    evas_textblock_cursor_pos_set(cur, 1);
@@ -823,6 +1166,20 @@ START_TEST(evas_textblock_format_removal)
    fnode = evas_textblock_node_format_first_get(tb);
    fail_if (fnode);
 
+   /* Range delete with item formats, TEST_CASE#1 */
+   evas_object_textblock_text_markup_set(tb, "The <b>Multiline</b><item size=50x50 href=abc></item> text!");
+   evas_textblock_cursor_pos_set(cur, 4);
+   evas_textblock_cursor_pos_set(main_cur, 14);
+   evas_textblock_cursor_range_delete(cur, main_cur);
+   ck_assert_str_eq(evas_object_textblock_text_markup_get(tb), "The  text!");
+
+   /* Range delete with item formats, TEST_CASE#2 */
+   evas_object_textblock_text_markup_set(tb, "The <b>Multiline</b><item size=50x50 href=abc></item> text! it is lon<item size=40x40 href=move></item>g text for test.");
+   evas_textblock_cursor_pos_set(cur, 14);
+   evas_textblock_cursor_pos_set(main_cur, 15);
+   evas_textblock_cursor_range_delete(cur, main_cur);
+   ck_assert_str_eq(evas_object_textblock_text_markup_get(tb), "The <b>Multiline</b><item size=50x50 href=abc></item>text! it is lon<item size=40x40 href=move></item>g text for test.");
+
    /* Verify fmt position and REP_CHAR positions are the same */
    evas_object_textblock_text_markup_set(tb,
          "This is<ps/>an <item absize=93x152 vsize=ascent></>a.");
@@ -989,7 +1346,7 @@ START_TEST(evas_textblock_items)
    buf = "This is an <item absize=93x152 vsize=full></>.";
    evas_object_textblock_text_markup_set(tb, buf);
    evas_object_textblock_size_formatted_get(tb, &w, &h);
-   fail_if((w < 93) || (h != 152));
+   fail_if((w < 93) || (h < 153));
    evas_textblock_cursor_pos_set(cur, 11);
    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &h);
    fail_if((w != 93) || (h != 152));
@@ -997,7 +1354,7 @@ START_TEST(evas_textblock_items)
    buf = "This is an <item absize=93x152 vsize=ascent></>.";
    evas_object_textblock_text_markup_set(tb, buf);
    evas_object_textblock_size_formatted_get(tb, &w, &h);
-   fail_if((w < 93) || (h <= 152));
+   fail_if((w < 93) || (h <= 153));
    evas_textblock_cursor_pos_set(cur, 11);
    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &h);
    fail_if((w != 93) || (h != 152));
@@ -1006,7 +1363,7 @@ START_TEST(evas_textblock_items)
    buf = "This is an <item size=93x152 vsize=full></>.";
    evas_object_textblock_text_markup_set(tb, buf);
    evas_object_textblock_size_formatted_get(tb, &w, &h);
-   fail_if((w < 93) || (h != 152));
+   fail_if((w < 93) || (h < 153));
    evas_textblock_cursor_pos_set(cur, 11);
    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &h);
    fail_if((w != 93) || (h != 152));
@@ -1014,7 +1371,7 @@ START_TEST(evas_textblock_items)
    buf = "This is an <item size=93x152 vsize=ascent></>.";
    evas_object_textblock_text_markup_set(tb, buf);
    evas_object_textblock_size_formatted_get(tb, &w, &h);
-   fail_if((w < 93) || (h <= 152));
+   fail_if((w < 93) || (h <= 153));
    evas_textblock_cursor_pos_set(cur, 11);
    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &h);
    fail_if((w != 93) || (h != 152));
@@ -1023,7 +1380,7 @@ START_TEST(evas_textblock_items)
    buf = "This is an <item size=93x152 vsize=full></>.";
    evas_object_textblock_text_markup_set(tb, buf);
    evas_object_textblock_size_formatted_get(tb, &w, &h);
-   fail_if((w < (2 * 93)) || (h != (2 * 152)));
+   fail_if((w < (2 * 93)) || (h < (2 * 154)));
    evas_textblock_cursor_pos_set(cur, 11);
    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &h);
    fail_if((w != (2 * 93)) || (h != (2 * 152)));
@@ -1034,7 +1391,7 @@ START_TEST(evas_textblock_items)
    buf = "This is an <item size=93x152 vsize=ascent></>.";
    evas_object_textblock_text_markup_set(tb, buf);
    evas_object_textblock_size_formatted_get(tb, &w, &h);
-   fail_if((w < (2 * 93)) || (h <= (2 * 152)));
+   fail_if((w < (2 * 93)) || (h <= (2 * 154)));
    evas_textblock_cursor_pos_set(cur, 11);
    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &h);
    fail_if((w != (2 * 93)) || (h != (2 * 152)));
@@ -1046,10 +1403,10 @@ START_TEST(evas_textblock_items)
    buf = "This is an <item relsize=93x152 vsize=full></>.";
    evas_object_textblock_text_markup_set(tb, buf);
    evas_object_textblock_size_formatted_get(tb, &w, &h);
-   fail_if((w >= 93) || (h >= 152));
+   fail_if((w >= 93) || (h >= 153));
    evas_textblock_cursor_pos_set(cur, 11);
    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &ih);
-   fail_if((w > 90) || (h != ih));
+   fail_if((w > 90) || (h <= ih));
 
    buf = "This is an <item relize=93x152 vsize=ascent></>.";
    evas_object_textblock_text_markup_set(tb, buf);
@@ -1169,6 +1526,19 @@ START_TEST(evas_textblock_wrapping)
      }
    fail_if(w != bw);
 
+   /* Verify that no empty line is added */
+   evas_object_textblock_text_markup_set(tb, "<wrap=word>Hello</wrap>");
+   evas_object_textblock_size_native_get(tb, NULL, &nh);
+   evas_object_resize(tb, 0, 1000);
+   evas_object_textblock_size_formatted_get(tb, NULL, &h);
+   ck_assert_int_eq(nh, h);
+
+   evas_object_textblock_text_markup_set(tb, "<wrap=char>a</wrap>");
+   evas_object_textblock_size_native_get(tb, NULL, &nh);
+   evas_object_resize(tb, 0, 1000);
+   evas_object_textblock_size_formatted_get(tb, NULL, &h);
+   ck_assert_int_eq(nh, h);
+
    /* Word wrap */
    evas_object_textblock_text_markup_set(tb, "aaaaaa");
    evas_object_textblock_size_formatted_get(tb, &bw, &bh);
@@ -1267,19 +1637,54 @@ START_TEST(evas_textblock_wrapping)
 
 
    /* Ellipsis */
-   evas_object_textblock_text_markup_set(tb, "aaaaaaaaaa");
-   evas_textblock_cursor_format_prepend(cur, "+ ellipsis=1.0");
-   evas_object_textblock_size_native_get(tb, &nw, &nh);
-   evas_object_resize(tb, nw / 2, nh);
-   evas_object_textblock_size_formatted_get(tb, &w, &h);
-   fail_if((w > (nw / 2)) || (h != nh));
-
    evas_object_textblock_text_markup_set(tb, "aaaaaaaaaaaaaaaaaa<br/>b");
    evas_textblock_cursor_format_prepend(cur, "+ ellipsis=1.0 wrap=word");
    evas_object_textblock_size_native_get(tb, &nw, &nh);
    evas_object_resize(tb, nw / 2, nh * 2);
    evas_object_textblock_size_formatted_get(tb, &w, &h);
-   fail_if(w > (nw / 2));
+   ck_assert_int_le(w, (nw / 2));
+
+   {
+      double ellip;
+      for(ellip = 0.0; ellip <= 1.0; ellip = ellip + 0.1)
+        {
+           char buf[128];
+           Evas_Coord w1, h1, w2, h2;
+
+           sprintf(buf, "+ ellipsis=%f", ellip);
+           evas_object_textblock_text_markup_set(tb, "aaaaaaaaaa");
+           evas_textblock_cursor_format_prepend(cur, buf);
+           evas_object_textblock_size_native_get(tb, &nw, &nh);
+           evas_object_resize(tb, nw / 2, nh);
+           evas_object_textblock_size_formatted_get(tb, &w, &h);
+           ck_assert_int_le(w, (nw / 2));
+           ck_assert_int_eq(h, nh);
+
+           evas_object_textblock_text_markup_set(tb, "aaaaaaaaaa");
+           evas_textblock_cursor_format_prepend(cur, buf);
+           evas_object_textblock_size_native_get(tb, &nw, &nh);
+           evas_object_resize(tb, nw, nh);
+           evas_object_textblock_size_formatted_get(tb, &w, &h);
+           evas_object_resize(tb, nw / 2, nh);
+           evas_object_textblock_size_formatted_get(tb, &w1, &h1);
+           evas_object_resize(tb, nw, nh);
+           evas_object_textblock_size_formatted_get(tb, &w2, &h2);
+           ck_assert_int_eq(w, w2);
+           ck_assert_int_eq(h, h2);
+
+           sprintf(buf, "+ ellipsis=%f", ellip);
+           evas_object_textblock_text_markup_set(tb,
+                 "the<tab>quick brown fox"
+                 "jumps<tab> over the<tab> lazy dog"
+                 );
+           evas_textblock_cursor_format_prepend(cur, buf);
+           evas_object_textblock_size_native_get(tb, &nw, &nh);
+           evas_object_resize(tb, nw / 2, nh);
+           evas_object_textblock_size_formatted_get(tb, &w, &h);
+           ck_assert_int_le(w, (nw / 2));
+           ck_assert_int_eq(h, nh);
+        }
+   }
 
    END_TB_TEST();
 }
@@ -1698,6 +2103,41 @@ START_TEST(evas_textblock_text_getters)
         free(tmp);
      }
 
+   /* complex markup set/get */
+     {
+        const char *text =
+           "This is an entry widget in this window that<ps/>"
+           "uses markup <b>like this</> for styling and<ps/>"
+           "formatting <em>like this</>, as well as<ps/>"
+           "<a href=X><link>links in the text</></a>, so enter text<ps/>"
+           "in here to edit it. By the way, links are<ps/>"
+           "called <a href=anc-02>Anchors</a> so you will need<ps/>"
+           "to refer to them this way.<ps/>"
+           "<ps/>"
+
+           "Also you can stick in items with (relsize + ascent): "
+           "<item relsize=16x16 vsize=ascent href=emoticon/evil-laugh></item>"
+           " (full) "
+           "<item relsize=16x16 vsize=full href=emoticon/guilty-smile></item>"
+           " (to the left)<ps/>"
+
+           "Also (size + ascent): "
+           "<item size=16x16 vsize=ascent href=emoticon/haha></item>"
+           " (full) "
+           "<item size=16x16 vsize=full href=emoticon/happy-panting></item>"
+           " (before this)<ps/>"
+
+           "And as well (absize + ascent): "
+           "<item absize=64x64 vsize=ascent href=emoticon/knowing-grin></item>"
+           " (full) "
+           "<item absize=64x64 vsize=full href=emoticon/not-impressed></item>"
+           " or even paths to image files on disk too like: "
+           "<item absize=96x128 vsize=full href=file://bla/images/sky_01.jpg></item>"
+           " ... end.";
+        evas_object_textblock_text_markup_set(tb, text);
+        ck_assert_str_eq(text, evas_object_textblock_text_markup_get(tb));
+     }
+
    END_TB_TEST();
 }
 END_TEST
@@ -1944,6 +2384,16 @@ START_TEST(evas_textblock_formats)
    fail_if(strcmp(evas_textblock_cursor_content_get(cur), "<item>"));
    fail_if(!evas_textblock_cursor_format_is_visible_get(cur));
 
+   evas_object_textblock_text_markup_set(tb, "abc<br/>def");
+   evas_textblock_cursor_pos_set(cur, 3);
+   evas_object_textblock_text_markup_prepend(cur, "<b></b>");
+   ck_assert_str_eq(evas_object_textblock_text_markup_get(tb), "abc<b></b><br/>def");
+   evas_object_textblock_text_markup_set(tb, "abc<br/>def");
+   evas_textblock_cursor_pos_set(cur, 2);
+   evas_object_textblock_text_markup_prepend(cur, "<b></b>");
+   ck_assert_str_eq(evas_object_textblock_text_markup_get(tb), "ab<b></b>c<br/>def");
+
+
    END_TB_TEST();
 }
 END_TEST
@@ -2115,11 +2565,11 @@ START_TEST(evas_textblock_escaping)
 
    const char *buf = "This &middot; is";
    evas_object_textblock_text_markup_set(tb, buf);
-   fail_if(strcmp(evas_object_textblock_text_markup_get(tb), buf));
+   fail_if(strcmp(evas_object_textblock_text_markup_get(tb), "This \xc2\xb7 is"));
 
    buf = "This &nbsp; is";
    evas_object_textblock_text_markup_set(tb, buf);
-   fail_if(strcmp(evas_object_textblock_text_markup_get(tb), buf));
+   fail_if(strcmp(evas_object_textblock_text_markup_get(tb), "This \xc2\xa0 is"));
 
    END_TB_TEST();
 }
@@ -2130,21 +2580,38 @@ START_TEST(evas_textblock_size)
    START_TB_TEST();
    Evas_Coord w, h, h2, nw, nh;
    const char *buf = "This is a <br/> test.<br/>גם בעברית";
+
+   /* Empty textblock */
+   evas_object_textblock_size_formatted_get(tb, &w, &h);
+   evas_object_textblock_size_native_get(tb, &nw, &nh);
+   ck_assert_int_eq(w, nw);
+   ck_assert_int_eq(h, nh);
+   fail_if(w != 0);
+
+
    /* When wrapping is off, native size should be the same as formatted
     * size */
 
+   evas_object_textblock_text_markup_set(tb, buf);
    evas_object_textblock_size_formatted_get(tb, &w, &h);
    evas_object_textblock_size_native_get(tb, &nw, &nh);
    fail_if((w != nw) || (h != nh));
-   fail_if(w != 0);
 
    evas_object_textblock_text_markup_set(tb, "a<br/>a");
    evas_object_textblock_size_formatted_get(tb, &w, &h2);
    evas_object_textblock_size_native_get(tb, &nw, &nh);
    fail_if((w != nw) || (h2 != nh));
 
-   /* Two lines == double the height */
-   fail_if(h * 2 != h2);
+   evas_object_textblock_text_markup_set(tb, "/u200eאאא AAA");
+   evas_object_resize(tb, 1, 1); //force wrapping
+   evas_object_textblock_size_native_get(tb, &nw, &nh);
+   evas_object_resize(tb, nw, nh);
+   evas_object_textblock_size_formatted_get(tb, &w, &h);
+   ck_assert_int_eq(w, nw);
+   ck_assert_int_eq(h, nh);
+
+   /* Two lines != double the height */
+   fail_if(h * 2 == h2);
 
    evas_object_textblock_text_markup_set(tb, buf);
 
@@ -2153,6 +2620,18 @@ START_TEST(evas_textblock_size)
    fail_if((w != nw) || (h != nh));
    fail_if(w <= 0);
 
+   evas_object_textblock_text_markup_set(tb, "i<b>。</b>");
+   evas_object_textblock_size_formatted_get(tb, &w, &h);
+   evas_object_textblock_size_native_get(tb, &nw, &nh);
+   ck_assert_int_eq(w, nw);
+   ck_assert_int_eq(h, nh);
+
+   evas_object_textblock_text_markup_set(tb, "。<b>i</b>");
+   evas_object_textblock_size_formatted_get(tb, &w, &h);
+   evas_object_textblock_size_native_get(tb, &nw, &nh);
+   ck_assert_int_eq(w, nw);
+   ck_assert_int_eq(h, nh);
+
    /* This time with margins. */
      {
         Evas_Textblock_Style *newst;
@@ -2176,6 +2655,12 @@ START_TEST(evas_textblock_size)
               (nw != oldnw + 8) || (nh != oldnh));
      }
 
+   evas_object_resize(tb, 1000, 1000);
+   evas_object_textblock_text_markup_set(tb, "\u200fHello שלום");
+   evas_object_textblock_size_formatted_get(tb, &w, NULL);
+   evas_object_textblock_size_native_get(tb, &nw, NULL);
+   ck_assert_int_eq(nw, w);
+
    /* FIXME: There is a lot more to be done. */
    END_TB_TEST();
 }
@@ -2185,6 +2670,7 @@ void evas_test_textblock(TCase *tc)
 {
    tcase_add_test(tc, evas_textblock_simple);
    tcase_add_test(tc, evas_textblock_cursor);
+   tcase_add_test(tc, evas_textblock_split_cursor);
    tcase_add_test(tc, evas_textblock_size);
    tcase_add_test(tc, evas_textblock_editing);
    tcase_add_test(tc, evas_textblock_style);