Revert the wobbly window code in wayland_egl engine - fun is over guys

So ok. haha. Amusing. But this is inappropriate.

1. It's not an INTENDED effect in theme so unless the theme ius doing
it - it shouldn't happen.
2. There are places to do this and it's NOT inside an engine. There
are high level filter and other mechanisms.
3. Actually this shouldn't be even done client-side. It should be done
compositor-side when moving a window around. Knowing velocity vector
etc. is useful to a client so the protocol can stay but doing the
animation client-side is "wrong". Some windows wobble and others do
not based on toolkit? really? sure we have to live with the CSD
difference but this? The compositor can do this JUYST fine. leave it
to compositor... OR do this properly with filters client-side. e.g. a
2d displacement map with evas filters would do the job as long as it
interpolates. If you want a way of forcing ALL objects in the canvas
to redirect to an intermediate buffer then do it up there at the
canvas level. It then works in GL and software, as opposed to only GL.

Also.... this is now causing issues for users:

<memeka> hi, from
https://git.enlightenment.org/core/efl.git/commit/?id=fb76fe55a52ac212b6870f1d74470a79ea5c5246
i run EFL_WAYLAND_DISABLE_WWW=1 terminology -> but it crashes in
wayland_egl/www.c in the setup_shaders function .... HELP?

so the fun was fune until we do a release (now) and until this causes
problems for users. Back to tried and tested code.

If you want to do this... do it right at the portable layers above.

...

Revert "wayland-egl: Fix use after free"
Revert "wayland_egl: Fix redirect to texture"
Revert "evas-wayland-egl: Add www protocol handling to wayland-egl engine"
Revert "gl_common: Add API for redirecting render to texture"

This reverts commit 2760afbb0e.
This reverts commit c937248eac.
This reverts commit c67f50b40a.
This reverts commit 0f7f4b6de0.
This commit is contained in:
Carsten Haitzler 2016-07-11 14:53:36 +09:00
parent e03d4142ef
commit 72438ab2a1
8 changed files with 4 additions and 1172 deletions

View File

@ -1215,9 +1215,7 @@ dist_installed_evasmainheaders_DATA += modules/evas/engines/wayland_egl/Evas_Eng
WAYLAND_EGL_SOURCES = \
modules/evas/engines/wayland_egl/evas_engine.c \
modules/evas/engines/wayland_egl/evas_wl_main.c \
modules/evas/engines/wayland_egl/evas_engine.h \
modules/evas/engines/wayland_egl/www.c \
modules/evas/engines/wayland_egl/www.h
modules/evas/engines/wayland_egl/evas_engine.h
if EVAS_STATIC_BUILD_WAYLAND_EGL
lib_evas_libevas_la_SOURCES += $(WAYLAND_EGL_SOURCES)
lib_evas_libevas_la_CPPFLAGS += @evas_engine_wayland_egl_cflags@

View File

@ -60,7 +60,6 @@
typedef struct _Evas_GL_Program Evas_GL_Program;
typedef struct _Evas_GL_Shared Evas_GL_Shared;
typedef struct _Evas_Engine_GL_Context Evas_Engine_GL_Context;
typedef struct _Evas_GL_Redirect Evas_GL_Redirect;
typedef struct _Evas_GL_Texture_Pool Evas_GL_Texture_Pool;
typedef struct _Evas_GL_Texture_Alloca Evas_GL_Texture_Alloca;
typedef struct _Evas_GL_Texture Evas_GL_Texture;
@ -343,17 +342,6 @@ struct _Evas_Engine_GL_Context
int gles_version;
RGBA_Image *font_surface;
GLuint current_fb;
};
struct _Evas_GL_Redirect
{
Evas_Engine_GL_Context *gc;
GLuint fb;
GLuint texture;
GLuint depth_buffer;
Eina_Bool active : 1;
};
struct _Evas_GL_Texture_Pool
@ -540,13 +528,6 @@ typedef void (*Evas_Gl_Symbols)(void *(*GetProcAddress)(const char *sym));
EAPI void __evas_gl_err(int err, const char *file, const char *func, int line, const char *op);
EAPI Evas_GL_Redirect *evas_gl_common_context_redirect(Evas_Engine_GL_Context *gc);
EAPI void evas_gl_common_context_unredirect(Evas_GL_Redirect *re);
EAPI GLuint evas_gl_common_context_redirect_texture_get(Evas_GL_Redirect *re);
EAPI void evas_gl_common_context_redirect_bind(Evas_GL_Redirect *re);
EAPI void evas_gl_common_context_redirect_unbind(Evas_GL_Redirect *re);
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,

View File

@ -1168,81 +1168,6 @@ evas_gl_common_context_resize(Evas_Engine_GL_Context *gc, int w, int h, int rot)
if (_evas_gl_common_context == gc) _evas_gl_common_viewport_set(gc);
}
EAPI void
evas_gl_common_context_unredirect(Evas_GL_Redirect *re)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteTextures(1, &re->texture);
glDeleteRenderbuffers(1, &re->depth_buffer);
glDeleteFramebuffers(1, &re->fb);
re->gc->current_fb = 0;
re->active = EINA_FALSE;
free(re);
}
EAPI Evas_GL_Redirect *
evas_gl_common_context_redirect(Evas_Engine_GL_Context *gc)
{
Evas_GL_Redirect *out;
out = calloc(1, sizeof(Evas_GL_Redirect));
/* Create a framebuffer object for RTT */
glGenTextures(1, &out->texture);
glBindTexture(GL_TEXTURE_2D, out->texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, gc->w, gc->h,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glGenFramebuffers(1, &out->fb);
glBindFramebuffer(GL_FRAMEBUFFER, out->fb);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, out->texture, 0);
glGenRenderbuffers(1, &out->depth_buffer);
glBindRenderbuffer(GL_RENDERBUFFER, out->depth_buffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, gc->w, gc->h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, out->depth_buffer);
glBindFramebuffer(GL_FRAMEBUFFER, out->fb);
out->gc = gc;
gc->current_fb = out->fb;
out->active = EINA_TRUE;
return out;
}
EAPI GLuint
evas_gl_common_context_redirect_texture_get(Evas_GL_Redirect *re)
{
return re->texture;
}
EAPI void
evas_gl_common_context_redirect_bind(Evas_GL_Redirect *re)
{
if (re->active) return;
glBindFramebuffer(GL_FRAMEBUFFER, re->fb);
re->gc->current_fb = re->fb;
re->active = EINA_TRUE;
}
EAPI void
evas_gl_common_context_redirect_unbind(Evas_GL_Redirect *re EINA_UNUSED)
{
if (!re->active) return;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
re->active = EINA_FALSE;
re->gc->current_fb = 0;
}
void
evas_gl_common_tiling_start(Evas_Engine_GL_Context *gc EINA_UNUSED,
int rot, int gw, int gh,
@ -1333,7 +1258,7 @@ evas_gl_common_context_target_surface_set(Evas_Engine_GL_Context *gc,
# endif
#endif
if (gc->pipe[0].shader.surface == gc->def_surface)
glsym_glBindFramebuffer(GL_FRAMEBUFFER, gc->current_fb);
glsym_glBindFramebuffer(GL_FRAMEBUFFER, 0);
else
glsym_glBindFramebuffer(GL_FRAMEBUFFER, surface->tex->pt->fb);
_evas_gl_common_viewport_set(gc);

View File

@ -62,11 +62,6 @@ Evas_GL_Common_Context_Call glsym_evas_gl_common_context_newframe = NULL;
Evas_GL_Common_Context_Call glsym_evas_gl_common_context_done = NULL;
Evas_GL_Common_Context_Resize_Call glsym_evas_gl_common_context_resize = NULL;
Evas_GL_Common_Buffer_Dump_Call glsym_evas_gl_common_buffer_dump = NULL;
Evas_GL_Redirect *(*glsym_evas_gl_common_context_redirect) (Evas_Engine_GL_Context *gc) = NULL;
void (*glsym_evas_gl_common_context_unredirect) (Evas_GL_Redirect *re) = NULL;
GLuint (*glsym_evas_gl_common_context_redirect_texture_get) (Evas_GL_Redirect *re) = NULL;
void (*glsym_evas_gl_common_context_redirect_bind) (Evas_GL_Redirect *re) = NULL;
void (*glsym_evas_gl_common_context_redirect_unbind) (Evas_GL_Redirect *re) = NULL;
Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock = NULL;
Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock = NULL;
Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_relax = NULL;
@ -78,17 +73,6 @@ void (*glsym_glEGLImageTargetTexture2DOES) (int a, void *b) = NULL;
unsigned int (*glsym_eglSwapBuffersWithDamage) (EGLDisplay a, void *b, const EGLint *d, EGLint c) = NULL;
unsigned int (*glsym_eglSetDamageRegionKHR) (EGLDisplay a, EGLSurface b, EGLint *c, EGLint d) = NULL;
unsigned int (*glsym_eglQueryWaylandBufferWL)(EGLDisplay a, struct wl_resource *b, EGLint c, EGLint *d) = NULL;
GLuint (*glsym_glCreateShader) (GLenum a) = NULL;
void (*glsym_glShaderSource) (GLuint a, GLsizei b, const GLchar **c, const GLint *d) = NULL;
void (*glsym_glCompileShader) (GLuint a) = NULL;
void (*glsym_glGetShaderiv) (GLuint a, GLenum b, GLint *c) = NULL;
void (*glsym_glGetShaderInfoLog) (GLuint a, GLsizei b, GLsizei *c, GLchar *d) = NULL;
GLuint (*glsym_glCreateProgram) (void) = NULL;
void (*glsym_glAttachShader) (GLuint a, GLuint b) = NULL;
void (*glsym_glBindAttribLocation) (GLuint a, GLuint b, const GLchar *c) = NULL;
void (*glsym_glLinkProgram) (GLuint a) = NULL;
void (*glsym_glGetProgramiv) (GLuint a, GLenum b, GLint *c) = NULL;
void (*glsym_glGetProgramInfoLog) (GLuint a, GLsizei b, GLsizei *c, GLchar *d) = NULL;
/* local variables */
static Eina_Bool initted = EINA_FALSE;
@ -140,11 +124,6 @@ gl_symbols(void)
LINK2GENERIC(evas_gl_common_context_newframe);
LINK2GENERIC(evas_gl_common_context_done);
LINK2GENERIC(evas_gl_common_context_resize);
LINK2GENERIC(evas_gl_common_context_unredirect);
LINK2GENERIC(evas_gl_common_context_redirect);
LINK2GENERIC(evas_gl_common_context_redirect_bind);
LINK2GENERIC(evas_gl_common_context_redirect_unbind);
LINK2GENERIC(evas_gl_common_context_redirect_texture_get);
LINK2GENERIC(evas_gl_common_buffer_dump);
LINK2GENERIC(evas_gl_preload_render_lock);
LINK2GENERIC(evas_gl_preload_render_unlock);
@ -195,28 +174,6 @@ gl_symbols(void)
FINDSYM(glsym_eglQueryWaylandBufferWL, "eglQueryWaylandBufferWL",
glsym_func_uint);
FINDSYM(glsym_glCreateShader, "glCreateShader", glsym_func_uint);
FINDSYM(glsym_glShaderSource, "glShaderSource", glsym_func_void);
FINDSYM(glsym_glCompileShader, "glCompileShader", glsym_func_void);
FINDSYM(glsym_glGetShaderiv, "glGetShaderiv", glsym_func_void);
FINDSYM(glsym_glGetShaderInfoLog, "glGetShaderInfoLog", glsym_func_void);
FINDSYM(glsym_glCreateProgram, "glCreateProgram", glsym_func_uint);
FINDSYM(glsym_glAttachShader, "glAttachShader", glsym_func_void);
FINDSYM(glsym_glBindAttribLocation, "glBindAttribLocation", glsym_func_void);
FINDSYM(glsym_glLinkProgram, "glLinkProgram", glsym_func_void);
FINDSYM(glsym_glGetProgramiv, "glGetProgramiv", glsym_func_void);
FINDSYM(glsym_glGetProgramInfoLog, "glGetProgramInfoLog", glsym_func_void);
done = EINA_TRUE;
}

View File

@ -7,8 +7,6 @@
# include "Evas.h"
# include "Evas_Engine_Wayland_Egl.h"
# include "www.h"
/* NB: This already includes wayland-client.h */
# include <wayland-egl.h>
@ -83,12 +81,6 @@ struct _Outbuf
Eina_Bool lost_back : 1;
Eina_Bool surf : 1;
Model *model;
float offset_x, offset_y;
Evas_GL_Redirect *redirect;
};
struct _Context_3D
@ -112,28 +104,9 @@ extern Evas_GL_Common_Buffer_Dump_Call glsym_evas_gl_common_buffer_dump;
extern Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock;
extern Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock;
extern Evas_GL_Redirect *(*glsym_evas_gl_common_context_redirect) (Evas_Engine_GL_Context *gc);
extern void (*glsym_evas_gl_common_context_unredirect) (Evas_GL_Redirect *re);
extern GLuint (*glsym_evas_gl_common_context_redirect_texture_get) (Evas_GL_Redirect *re);
extern void (*glsym_evas_gl_common_context_redirect_bind) (Evas_GL_Redirect *re);
extern void (*glsym_evas_gl_common_context_redirect_unbind) (Evas_GL_Redirect *re);
extern unsigned int (*glsym_eglSwapBuffersWithDamage) (EGLDisplay a, void *b, const EGLint *d, EGLint c);
extern unsigned int (*glsym_eglSetDamageRegionKHR) (EGLDisplay a, EGLSurface b, EGLint *c, EGLint d);
extern GLuint (*glsym_glCreateShader) (GLenum a);
extern void (*glsym_glShaderSource) (GLuint a, GLsizei b, const GLchar **c, const GLint *d);
extern void (*glsym_glCompileShader) (GLuint a);
extern void (*glsym_glGetShaderiv) (GLuint a, GLenum b, GLint *c);
extern void (*glsym_glGetShaderInfoLog) (GLuint a, GLsizei b, GLsizei *c, GLchar *d);
extern GLuint (*glsym_glCreateProgram) (void);
extern void (*glsym_glAttachShader) (GLuint a, GLuint b);
extern void (*glsym_glBindAttribLocation) (GLuint a, GLuint b, const GLchar *c);
extern void (*glsym_glLinkProgram) (GLuint a);
extern void (*glsym_glGetProgramiv) (GLuint a, GLenum b, GLint *c);
extern void (*glsym_glGetProgramInfoLog) (GLuint a, GLsizei b, GLsizei *c, GLchar *d);
Outbuf *eng_window_new(Evas *evas, Evas_Engine_Info_Wayland_Egl *einfo, int w, int h, Render_Engine_Swap_Mode swap_mode);
void eng_window_free(Outbuf *gw);
void eng_window_use(Outbuf *gw);

View File

@ -222,8 +222,7 @@ eng_window_free(Outbuf *gw)
eglReleaseThread();
context = EGL_NO_CONTEXT;
}
free(gw->model);
gw->model = NULL;
free(gw);
}
@ -247,7 +246,6 @@ eng_window_use(Outbuf *gw)
{
glsym_evas_gl_common_context_use(_evas_gl_wl_window->gl_context);
glsym_evas_gl_common_context_flush(_evas_gl_wl_window->gl_context);
if (_evas_gl_wl_window->redirect) glsym_evas_gl_common_context_redirect_unbind(_evas_gl_wl_window->redirect);
}
_evas_gl_wl_window = gw;
@ -268,7 +266,6 @@ eng_window_use(Outbuf *gw)
{
glsym_evas_gl_common_context_use(gw->gl_context);
glsym_evas_gl_common_context_resize(gw->gl_context, gw->w, gw->h, gw->rot);
if (gw->redirect) glsym_evas_gl_common_context_redirect_bind(gw->redirect);
}
}
@ -323,23 +320,11 @@ eng_window_resurf(Outbuf *gw)
void
eng_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth EINA_UNUSED)
{
Eina_Bool redirected;
if (!ob->model) ob->model = wobbly_create(0, 0, w, h);
wobbly_resize(ob->model, w, h);
redirected = !!ob->redirect;
if (ob->redirect)
glsym_evas_gl_common_context_unredirect(ob->redirect);
ob->redirect = NULL;
ob->w = w;
ob->h = h;
ob->rot = rot;
eng_window_use(ob);
glsym_evas_gl_common_context_resize(ob->gl_context, w, h, rot);
if (redirected)
ob->redirect = glsym_evas_gl_common_context_redirect(ob->gl_context);
if (ob->win)
{
@ -382,11 +367,6 @@ eng_outbuf_rotation_get(Outbuf *ob)
Render_Engine_Swap_Mode
eng_outbuf_swap_mode_get(Outbuf *ob)
{
if (ob->redirect)
{
ob->prev_age = 0;
return MODE_FULL;
}
if ((ob->swap_mode == MODE_AUTO) && (extn_have_buffer_age))
{
Render_Engine_Swap_Mode swap_mode;
@ -514,8 +494,6 @@ eng_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update EINA_UNUSED, int x
void
eng_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode)
{
Eina_Bool effect_continues = EINA_FALSE;
if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) goto end;
if (!_re_wincheck(ob)) goto end;
@ -535,33 +513,7 @@ eng_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode)
if (ob->info->callback.pre_swap)
ob->info->callback.pre_swap(ob->info->callback.data, ob->evas);
if (ob->model) effect_continues = wobbly_process(ob->model, ob->info,
ob->w, ob->h,
!!ob->redirect);
if (ob->redirect)
{
float tlx, tly, brx, bry;
int w, h;
wobbly_bounds(ob->model, &tlx, &tly, &brx, &bry);
w = brx - tlx;
h = bry - tly;
wl_egl_window_resize(ob->win, w, h,
tlx - ob->offset_x,
tly - ob->offset_y);
ob->offset_x = tlx;
ob->offset_y = tly;
glsym_evas_gl_common_context_redirect_unbind(ob->redirect);
glViewport(0, 0, w, h);
wobbly_draw(ob->redirect, ob->model);
wl_surface_set_opaque_region(ob->info->info.surface, NULL);
eglSwapBuffers(ob->egl_disp, ob->egl_surface[0]);
glsym_evas_gl_common_context_redirect_bind(ob->redirect);
glViewport(0, 0, ob->w, ob->h);
}
else if ((glsym_eglSwapBuffersWithDamage) && (rects) &&
if ((glsym_eglSwapBuffersWithDamage) && (rects) &&
(ob->swap_mode != MODE_FULL))
{
EGLint num = 0, *result = NULL, i = 0;
@ -584,23 +536,6 @@ eng_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode)
else
eglSwapBuffers(ob->egl_disp, ob->egl_surface[0]);
if (ob->redirect && !effect_continues) ob->info->wobbling = EINA_TRUE;
else ob->info->wobbling = effect_continues;
if (effect_continues)
{
if (ob->redirect)
glsym_evas_gl_common_context_unredirect(ob->redirect);
ob->redirect = glsym_evas_gl_common_context_redirect(ob->gl_context);
}
else
{
ob->offset_x = 0;
ob->offset_y = 0;
if (ob->redirect)
glsym_evas_gl_common_context_unredirect(ob->redirect);
ob->redirect = NULL;
}
if (ob->info->callback.post_swap)
ob->info->callback.post_swap(ob->info->callback.data, ob->evas);

View File

@ -1,885 +0,0 @@
/*
* Copyright © 2005 Novell, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of
* Novell, Inc. not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* Novell, Inc. makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@novell.com>
*/
/*
* Spring model implemented by Kristian Hogsberg.
*/
#include "evas_engine.h"
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <Eina.h>
#include <Evas.h>
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include "www.h"
# define GRID_WIDTH 4
# define GRID_HEIGHT 4
# define MODEL_MAX_SPRINGS (GRID_WIDTH * GRID_HEIGHT * 2)
# define MASS 15.0f
# define MAXSHORT 32767
# define MINSHORT -MAXSHORT
# define WOBBLY_GRID_RESOLUTION 32
# define WOBBLY_MIN_GRID_SIZE 64
typedef struct _xy_pair
{
float x, y;
} Point, Vector;
typedef struct _Object
{
Vector force;
Point position;
Vector velocity;
float theta;
Eina_Bool immobile;
} Object;
typedef struct _Spring
{
Object *a;
Object *b;
Vector offset;
} Spring;
typedef struct _Model
{
Object *objects;
int numObjects;
Spring springs[MODEL_MAX_SPRINGS];
int numSprings;
Object *anchorObject;
float steps;
Point topLeft;
Point bottomRight;
int indexSize;
GLushort *indices;
int vertexStride;
GLfloat *vertices;
int vertexSize;
int texCoordSize;
int wobbleGrace;
int vCount;
int indexCount;
struct timeval tv;
GLuint fs;
GLuint vs;
GLuint prog;
} Model;
static const GLchar *prog_vs =
"attribute vec3 pos;\n"
"attribute vec2 tc;\n"
"varying vec2 f_tc;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(pos, 1.0);\n"
" f_tc = tc;\n"
"}\n";
static const GLchar *prog_fs =
"precision mediump float;\n"
"varying vec2 f_tc;\n"
"uniform sampler2D ts;\n"
"void main()\n"
"{\n"
" gl_FragColor = texture2D(ts, f_tc);\n"
"}\n";
static Eina_Bool
setup_shaders(Model *m)
{
GLint err;
char errbuf[2048];
m->vs = glsym_glCreateShader(GL_VERTEX_SHADER);
glsym_glShaderSource(m->vs, 1, &prog_vs, NULL);
glsym_glCompileShader(m->vs);
glsym_glGetShaderiv(m->vs, GL_COMPILE_STATUS, &err);
if (!err)
{
glsym_glGetShaderInfoLog(m->vs, sizeof errbuf, NULL, errbuf);
fprintf(stderr, "vs sigh: %s\n", errbuf);
return EINA_FALSE;
}
m->fs = glsym_glCreateShader(GL_FRAGMENT_SHADER);
glsym_glShaderSource(m->fs, 1, &prog_fs, NULL);
glsym_glCompileShader(m->fs);
glsym_glGetShaderiv(m->fs, GL_COMPILE_STATUS, &err);
if (!err)
{
glsym_glGetShaderInfoLog(m->fs, sizeof errbuf, NULL, errbuf);
fprintf(stderr, "fs sigh: %s\n", errbuf);
return EINA_FALSE;
}
m->prog = glsym_glCreateProgram();
glsym_glAttachShader(m->prog, m->vs);
glsym_glAttachShader(m->prog, m->fs);
glsym_glBindAttribLocation(m->prog, 0, "tc");
glsym_glBindAttribLocation(m->prog, 1, "pos");
glsym_glLinkProgram(m->prog);
glsym_glGetProgramiv(m->prog, GL_LINK_STATUS, &err);
if (!err)
{
glsym_glGetProgramInfoLog(m->prog, sizeof errbuf, NULL, errbuf);
fprintf(stderr, "link : %s\n", errbuf);
return EINA_FALSE;
}
return EINA_TRUE;
}
static void
objectInit(Object *object,
float positionX,
float positionY,
float velocityX,
float velocityY)
{
object->force.x = 0;
object->force.y = 0;
object->position.x = positionX;
object->position.y = positionY;
object->velocity.x = velocityX;
object->velocity.y = velocityY;
object->theta = 0;
object->immobile = EINA_FALSE;
}
static void
springInit(Spring *spring,
Object *a,
Object *b,
float offsetX,
float offsetY)
{
spring->a = a;
spring->b = b;
spring->offset.x = offsetX;
spring->offset.y = offsetY;
}
static void
modelCalcBounds(Model *model)
{
int i;
model->topLeft.x = MAXSHORT;
model->topLeft.y = MAXSHORT;
model->bottomRight.x = MINSHORT;
model->bottomRight.y = MINSHORT;
for (i = 0; i < model->numObjects; i++)
{
if (model->objects[i].position.x < model->topLeft.x)
model->topLeft.x = model->objects[i].position.x;
else if (model->objects[i].position.x > model->bottomRight.x)
model->bottomRight.x = model->objects[i].position.x;
if (model->objects[i].position.y < model->topLeft.y)
model->topLeft.y = model->objects[i].position.y;
else if (model->objects[i].position.y > model->bottomRight.y)
model->bottomRight.y = model->objects[i].position.y;
}
}
static void
modelAddSpring(Model *model,
Object *a,
Object *b,
float offsetX,
float offsetY)
{
Spring *spring;
spring = &model->springs[model->numSprings];
model->numSprings++;
springInit(spring, a, b, offsetX, offsetY);
}
static void
modelSetMiddleAnchor(Model *model,
int x,
int y,
int width,
int height)
{
float gx, gy;
gx = ((GRID_WIDTH - 1) / 2 * width) / (float)(GRID_WIDTH - 1);
gy = ((GRID_HEIGHT - 1) / 2 * height) / (float)(GRID_HEIGHT - 1);
if (model->anchorObject)
model->anchorObject->immobile = EINA_FALSE;
model->anchorObject = &model->objects[GRID_WIDTH *
((GRID_HEIGHT - 1) / 2) +
(GRID_WIDTH - 1) / 2];
model->anchorObject->position.x = x + gx;
model->anchorObject->position.y = y + gy;
model->anchorObject->immobile = EINA_TRUE;
}
static void
modelAdjustObjectPosition(Model *model,
Object *object,
int x,
int y,
int width,
int height)
{
Object *o;
int gridX, gridY, i = 0;
for (gridY = 0; gridY < GRID_HEIGHT; gridY++)
{
for (gridX = 0; gridX < GRID_WIDTH; gridX++)
{
o = &model->objects[i];
if (o == object)
{
o->position.x = x + (gridX * width) / (GRID_WIDTH - 1);
o->position.y = y + (gridY * height) / (GRID_HEIGHT - 1);
return;
}
i++;
}
}
}
static void
modelInitObjects(Model *model,
int x,
int y,
int width,
int height)
{
int gridX, gridY, i = 0;
float gw, gh;
gw = GRID_WIDTH - 1;
gh = GRID_HEIGHT - 1;
for (gridY = 0; gridY < GRID_HEIGHT; gridY++)
{
for (gridX = 0; gridX < GRID_WIDTH; gridX++)
{
objectInit(&model->objects[i],
x + (gridX * width) / gw,
y + (gridY * height) / gh,
0, 0);
i++;
}
}
modelSetMiddleAnchor(model, x, y, width, height);
}
static void
modelAdjustObjectsForShiver(Model *model,
int x,
int y,
int width,
int height)
{
int gridX, gridY, i = 0;
float vX, vY;
float w, h;
float scale;
w = width;
h = height;
for (gridY = 0; gridY < GRID_HEIGHT; gridY++)
{
for (gridX = 0; gridX < GRID_WIDTH; gridX++)
{
if (!model->objects[i].immobile)
{
vX = model->objects[i].position.x - (x + w / 2);
vY = model->objects[i].position.y - (y + h / 2);
vX /= w;
vY /= h;
scale = ((float)rand() * 7.5f) / RAND_MAX;
model->objects[i].velocity.x += vX * scale;
model->objects[i].velocity.y += vY * scale;
}
i++;
}
}
}
static void
modelInitSprings(Model *model,
int x EINA_UNUSED,
int y EINA_UNUSED,
int width,
int height)
{
int gridX, gridY, i = 0;
float hpad, vpad;
model->numSprings = 0;
hpad = ((float)width) / (GRID_WIDTH - 1);
vpad = ((float)height) / (GRID_HEIGHT - 1);
for (gridY = 0; gridY < GRID_HEIGHT; gridY++)
{
for (gridX = 0; gridX < GRID_WIDTH; gridX++)
{
if (gridX > 0)
modelAddSpring(model,
&model->objects[i - 1],
&model->objects[i],
hpad, 0);
if (gridY > 0)
modelAddSpring(model,
&model->objects[i - GRID_WIDTH],
&model->objects[i],
0, vpad);
i++;
}
}
}
Model *
wobbly_create(int x,
int y,
int width,
int height)
{
Model *model;
model = calloc(sizeof (Model), 1);
if (!model)
return 0;
model->numObjects = GRID_WIDTH * GRID_HEIGHT;
model->objects = malloc(sizeof (Object) * model->numObjects);
if (!model->objects)
{
free(model);
return 0;
}
model->anchorObject = 0;
model->numSprings = 0;
model->steps = 0;
modelInitObjects(model, x, y, width, height);
modelInitSprings(model, x, y, width, height);
modelCalcBounds(model);
setup_shaders(model);
return model;
}
static void
objectApplyForce(Object *object,
float fx,
float fy)
{
object->force.x += fx;
object->force.y += fy;
}
static void
springExertForces(Spring *spring,
float k)
{
Vector da, db;
Vector a, b;
a = spring->a->position;
b = spring->b->position;
da.x = 0.5f * (b.x - a.x - spring->offset.x);
da.y = 0.5f * (b.y - a.y - spring->offset.y);
db.x = 0.5f * (a.x - b.x + spring->offset.x);
db.y = 0.5f * (a.y - b.y + spring->offset.y);
objectApplyForce(spring->a, k * da.x, k * da.y);
objectApplyForce(spring->b, k * db.x, k * db.y);
}
static float
modelStepObject(Object *object, float *force)
{
float friction = 0.8f;
object->theta += 0.05f;
if (object->immobile)
{
object->velocity.x = 0.0f;
object->velocity.y = 0.0f;
object->force.x = 0.0f;
object->force.y = 0.0f;
*force = 0.0f;
return 0.0f;
}
else
{
object->force.x -= friction * object->velocity.x;
object->force.y -= friction * object->velocity.y;
object->velocity.x += object->force.x / MASS;
object->velocity.y += object->force.y / MASS;
object->position.x += object->velocity.x;
object->position.y += object->velocity.y;
*force = fabs(object->force.x) + fabs(object->force.y);
object->force.x = 0.0f;
object->force.y = 0.0f;
return fabs(object->velocity.x) + fabs(object->velocity.y);
}
}
int
modelStep(Model *model, float time)
{
float k = 0.9;
int i, j, steps;
float velocitySum = 0.0f;
float force, forceSum = 0.0f;
int wobbly = 0;
if (model->wobbleGrace)
{
model->wobbleGrace--;
wobbly |= 4;
}
model->steps += time / 15.0f;
steps = floor(model->steps);
model->steps -= steps;
if (!steps)
return 1;
for (j = 0; j < steps; j++)
{
for (i = 0; i < model->numSprings; i++)
springExertForces(&model->springs[i], k);
for (i = 0; i < model->numObjects; i++)
{
velocitySum += modelStepObject(&model->objects[i], &force);
forceSum += force;
}
}
modelCalcBounds(model);
if (velocitySum > 0.5f)
wobbly |= 1; //WobblyVelocity;
if (forceSum > 20.0f)
wobbly |= 2; //WobblyForce;
return wobbly;
}
static void
bezierPatchEvaluate(Model *model,
float u,
float v,
float *patchX,
float *patchY)
{
float coeffsU[4], coeffsV[4];
float x, y;
int i, j;
coeffsU[0] = (1 - u) * (1 - u) * (1 - u);
coeffsU[1] = 3 * u * (1 - u) * (1 - u);
coeffsU[2] = 3 * u * u * (1 - u);
coeffsU[3] = u * u * u;
coeffsV[0] = (1 - v) * (1 - v) * (1 - v);
coeffsV[1] = 3 * v * (1 - v) * (1 - v);
coeffsV[2] = 3 * v * v * (1 - v);
coeffsV[3] = v * v * v;
x = y = 0.0f;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
x += coeffsU[i] * coeffsV[j] *
model->objects[j * GRID_WIDTH + i].position.x;
y += coeffsU[i] * coeffsV[j] *
model->objects[j * GRID_WIDTH + i].position.y;
}
}
*patchX = x;
*patchY = y;
}
static float
objectDistance(Object *object,
float x,
float y)
{
float dx, dy;
dx = object->position.x - x;
dy = object->position.y - y;
return sqrt(dx * dx + dy * dy);
}
static Object *
modelFindNearestObject(Model *model,
float x,
float y)
{
Object *object = &model->objects[0];
float distance, minDistance = 0.0;
int i;
for (i = 0; i < model->numObjects; i++)
{
distance = objectDistance(&model->objects[i], x, y);
if (i == 0 || distance < minDistance)
{
minDistance = distance;
object = &model->objects[i];
}
}
return object;
}
static Eina_Bool
moreWindowVertices(Model *m, int newSize)
{
if (newSize > m->vertexSize)
{
GLfloat *vertices;
vertices = realloc(m->vertices, sizeof(GLfloat) * newSize);
if (!vertices) return EINA_FALSE;
m->vertices = vertices;
m->vertexSize = newSize;
}
return EINA_TRUE;
}
static Eina_Bool
moreWindowIndices(Model *m, int newSize)
{
if (newSize > m->indexSize)
{
GLushort *indices;
indices = realloc(m->indices, sizeof(GLushort) * newSize);
if (!indices) return EINA_FALSE;
m->indices = indices;
m->indexSize = newSize;
}
return EINA_TRUE;
}
void
wobblyGeometryDo(Model *m, int in_w, int in_h)
{
int nVertices, nIndices;
GLushort *i;
GLfloat *v;
int x1, y1, x2, y2;
float width, height;
float deformedX, deformedY;
int x, y, iw, ih, wx, wy;
int vSize;
int gridW, gridH;
int bound_w = m->bottomRight.x - m->topLeft.x;
int bound_h = m->bottomRight.y - m->topLeft.y;
wx = 0;
wy = 0;
width = in_w;
height = in_h;
gridW = width / WOBBLY_GRID_RESOLUTION;
if (gridW < WOBBLY_MIN_GRID_SIZE)
gridW = WOBBLY_MIN_GRID_SIZE;
gridH = height / WOBBLY_GRID_RESOLUTION;
if (gridH < WOBBLY_MIN_GRID_SIZE)
gridH = WOBBLY_MIN_GRID_SIZE;
vSize = 3 + 2; /* 3 vert, 2 texcoord */
nVertices = m->vCount = 0;
nIndices = m->indexCount = 0;
v = m->vertices + (nVertices * vSize);
i = m->indices + nIndices;
x1 = 0;
y1 = 0;
x2 = width;
y2 = height;
iw = ((x2 - x1 - 1) / gridW) + 1;
ih = ((y2 - y1 - 1) / gridH) + 1;
if (nIndices + (iw * ih * 6) > m->indexSize)
{
if (!moreWindowIndices(m, nIndices + (iw * ih * 6)))
return;
i = m->indices + nIndices;
}
iw++;
ih++;
for (y = 0; y < ih - 1; y++)
{
for (x = 0; x < iw - 1; x++)
{
*i++ = nVertices + iw * (y + 1) + x;
*i++ = nVertices + iw * (y + 1) + x + 1;
*i++ = nVertices + iw * y + x + 1;
*i++ = nVertices + iw * y + x + 1;
*i++ = nVertices + iw * y + x;
*i++ = nVertices + iw * (y + 1) + x;
nIndices += 6;
}
}
if (((nVertices + iw * ih) * vSize) > m->vertexSize)
{
if (!moreWindowVertices(m, (nVertices + iw * ih) * vSize))
return;
v = m->vertices + (nVertices * vSize);
}
for (y = y1;; y += gridH)
{
if (y > y2)
y = y2;
for (x = x1;; x += gridW)
{
if (x > x2)
x = x2;
bezierPatchEvaluate(m,
(x - wx) / width,
(y - wy) / height,
&deformedX,
&deformedY);
//Tex co-ord
*v++ = x / width;
*v++ = y / height;
// vertex
*v++ = -1 + ((deformedX - m->topLeft.x) / (bound_w / 2.0));
*v++ = -1 + ((deformedY - m->topLeft.y) / (bound_h / 2.0));
*v++ = 0.0;
nVertices++;
if (x == x2)
break;
}
if (y == y2)
break;
}
m->vCount = nVertices;
m->vertexStride = vSize;
m->texCoordSize = 2;
m->indexCount = nIndices;
}
void
wobblyMap(Model *m, int w, int h)
{
modelInitObjects(m, 0, 0, w, h);
modelInitSprings(m, 0, 0, w, h);
modelSetMiddleAnchor(m, 0, 0, w, h);
modelAdjustObjectsForShiver(m, 0, 0, w, h);
m->wobbleGrace = 10;
}
void
wobblyMove(Model *m, int dx, int dy, int w, int h)
{
m->wobbleGrace = 10;
modelAdjustObjectPosition(m, m->anchorObject, 0, 0, w, h);
m->anchorObject->position.x += dx;
m->anchorObject->position.y += dy;
}
void
wobblyAnchorRelease(Model *m)
{
if (m->anchorObject)
m->anchorObject->immobile = EINA_FALSE;
}
void
wobblyAnchor(Model *m, int cx, int cy, int w, int h)
{
wobblyAnchorRelease(m);
m->anchorObject = modelFindNearestObject(m, cx, h - cy);
m->anchorObject->immobile = EINA_TRUE;
modelAdjustObjectPosition(m, m->anchorObject, 0, 0, w, h);
m->wobbleGrace = 10;
}
void
wobbly_resize(Model *m, int dwidth, int dheight)
{
m->wobbleGrace = 10;
modelInitObjects(m, 0, 0, dwidth, dheight);
modelInitSprings(m, 0, 0, dwidth, dheight);
modelCalcBounds(m);
}
void
wobbly_draw(Evas_GL_Redirect *re, Model *m)
{
GLuint tex;
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(m->prog);
tex = glsym_evas_gl_common_context_redirect_texture_get(re);
glBindTexture(GL_TEXTURE_2D, tex);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), m->vertices);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), m->vertices + 2);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glDrawElements(GL_TRIANGLES, m->indexCount, GL_UNSIGNED_SHORT, m->indices);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
}
Eina_Bool
wobbly_process(Model *m, Evas_Engine_Info_Wayland_Egl *info, int w, int h, Eina_Bool redirected)
{
int ret = EINA_FALSE;
if (info->just_mapped)
{
info->just_mapped = EINA_FALSE;
wobblyMap(m, w, h);
return EINA_TRUE;
}
if (info->drag_start)
{
wobblyAnchor(m, info->x_cursor, info->y_cursor, w, h);
ret = EINA_TRUE;
}
if (!info->resizing && (info->x_rel || info->y_rel))
{
wobblyMove(m, info->x_rel, -info->y_rel, w, h);
ret = EINA_TRUE;
}
if (info->drag_stop)
{
wobblyAnchorRelease(m);
ret = EINA_TRUE;
}
if (redirected)
{
double oldms, ms;
oldms = m->tv.tv_usec / 1000 + m->tv.tv_sec * 1000;
gettimeofday(&m->tv, NULL);
ms = m->tv.tv_usec / 1000 + m->tv.tv_sec * 1000 - oldms;
if (ms > 100) ms = 0;
if (modelStep(m, ms)) ret = EINA_TRUE;
wobblyGeometryDo(m, w, h);
}
return ret;
}
void
wobbly_bounds(Model *m, float *tlx, float *tly, float *brx, float *bry)
{
*tlx = m->topLeft.x;
*tly = m->topLeft.y;
*brx = m->bottomRight.x;
*bry = m->bottomRight.y;
}

View File

@ -1,52 +0,0 @@
/*
* Copyright C 2005 Novell, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of
* Novell, Inc. not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* Novell, Inc. makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@novell.com>
*/
/*
* Spring model implemented by Kristian Hogsberg.
*/
#ifndef EVAS_WWW_H
# define EVAS_WWW_H
# include "../gl_generic/Evas_Engine_GL_Generic.h"
typedef struct _Model Model;
Model *
wobbly_create(int x, int y, int width, int height);
void
wobbly_resize(Model *m, int dw, int dh);
void
wobbly_draw(Evas_GL_Redirect *re, Model *m);
Eina_Bool
wobbly_process(Model *m, Evas_Engine_Info_Wayland_Egl *info, int w, int h, Eina_Bool redirected);
void
wobbly_bounds(Model *m, float *tlx, float *tly, float *brx, float *bry);
#endif