forked from enlightenment/efl
Evas GL: Add support for OpenGL-ES 1.1 and some new APIs
This adds support for the following features: - OpenGL-ES 1.1 (works only with EGL right now), - PBuffer (basic support), - Multithreading safety in gl_x11, - EGL fence_sync extension, - Improve direct rendering, - And a few other evas_gl_ APIs. Merge branch 'devs/jpeg/evasgl'
This commit is contained in:
commit
fb3564304e
|
@ -575,6 +575,7 @@ modules/evas/engines/gl_common/evas_gl_api_ext_def.h \
|
|||
modules/evas/engines/gl_common/evas_gl_core.h \
|
||||
modules/evas/engines/gl_common/evas_gl_core_private.h \
|
||||
modules/evas/engines/gl_common/evas_gl_api.c \
|
||||
modules/evas/engines/gl_common/evas_gl_api_gles1.c \
|
||||
modules/evas/engines/gl_common/evas_gl_api_ext.c \
|
||||
modules/evas/engines/gl_common/shader/font_frag.h \
|
||||
modules/evas/engines/gl_common/shader/font_vert.h \
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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,95 @@ struct _Evas_GL_Surface
|
|||
void *data;
|
||||
};
|
||||
|
||||
struct _Evas_GL_TLS_data
|
||||
{
|
||||
int error_state;
|
||||
};
|
||||
|
||||
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,6 +131,7 @@ evas_gl_new(Evas *e)
|
|||
|
||||
evas_gl->magic = MAGIC_EVAS_GL;
|
||||
evas_gl->evas = eo_data_ref(e, EVAS_CANVAS_CLASS);
|
||||
LKI(evas_gl->lck);
|
||||
|
||||
if (!evas_gl->evas->engine.func->gl_context_create)
|
||||
{
|
||||
|
@ -44,6 +140,15 @@ evas_gl_new(Evas *e)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// 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 +159,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,8 +167,12 @@ 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);
|
||||
|
||||
eo_data_unref(evas_gl->evas->evas, evas_gl->evas);
|
||||
evas_gl->magic = 0;
|
||||
LKD(evas_gl->lck);
|
||||
free(evas_gl);
|
||||
}
|
||||
|
||||
|
@ -98,18 +206,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);
|
||||
|
||||
|
@ -121,7 +235,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;
|
||||
}
|
||||
|
@ -137,6 +309,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;
|
||||
}
|
||||
|
||||
|
@ -144,7 +317,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);
|
||||
|
@ -152,7 +327,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;
|
||||
|
||||
|
@ -161,23 +337,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)
|
||||
|
@ -188,10 +370,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
|
||||
|
@ -205,6 +394,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;
|
||||
}
|
||||
|
||||
|
@ -212,7 +402,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);
|
||||
|
@ -227,7 +419,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))
|
||||
|
@ -235,17 +427,94 @@ 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();
|
||||
|
||||
if (!evas_gl->evas->engine.func->gl_current_context_get)
|
||||
{
|
||||
CRI("Can not get current context with this engine: %s",
|
||||
evas_gl->evas->engine.module->definition->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if (!evas_gl->evas->engine.func->gl_current_surface_get)
|
||||
{
|
||||
CRI("Can not get current surface with this engine: %s",
|
||||
evas_gl->evas->engine.module->definition->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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 NULL;
|
||||
return "";
|
||||
MAGIC_CHECK_END();
|
||||
|
||||
return (const char *)evas_gl->evas->engine.func->gl_string_query(evas_gl->evas->engine.data.output, name);
|
||||
|
@ -268,9 +537,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;
|
||||
}
|
||||
|
||||
|
@ -285,6 +562,91 @@ 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 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);
|
||||
}
|
||||
|
||||
// Internal function - called from evas_gl_core.c
|
||||
EAPI void *
|
||||
_evas_gl_native_context_get(Evas_GL_Context *ctx)
|
||||
{
|
||||
if (!ctx) return NULL;
|
||||
return ctx->data;
|
||||
}
|
||||
|
|
|
@ -2948,8 +2948,7 @@ evas_process_dirty_pixels(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
|
|||
(obj->cur->color.g == 255) &&
|
||||
(obj->cur->color.b == 255) &&
|
||||
(obj->cur->color.a == 255) &&
|
||||
(!obj->map->cur.map) &&
|
||||
(!o->cur->has_alpha)) ||
|
||||
(!obj->map->cur.map)) ||
|
||||
(direct_override)) &&
|
||||
(!direct_force_off) )
|
||||
{
|
||||
|
|
|
@ -157,6 +157,7 @@ struct _Evas_3D_File_Eet
|
|||
|
||||
typedef Eina_Bool (*Evas_3D_Node_Func)(Evas_3D_Node *, void *data);
|
||||
|
||||
|
||||
typedef enum _Evas_3D_Node_Traverse_Type
|
||||
{
|
||||
EVAS_3D_NODE_TRAVERSE_DOWNWARD,
|
||||
|
@ -1231,19 +1232,25 @@ 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);
|
||||
int (*gl_native_surface_get) (void *data, void *surface, void *native_surface);
|
||||
void *(*gl_api_get) (void *data);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
|
|
@ -1160,7 +1160,7 @@ evgl_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const
|
|||
#endif
|
||||
|
||||
static void *
|
||||
eng_gl_api_get(void *data)
|
||||
eng_gl_api_get(void *data, int version EINA_UNUSED)
|
||||
{
|
||||
Render_Engine *re;
|
||||
|
||||
|
|
|
@ -16,12 +16,12 @@ void _make_current_check(const char* api)
|
|||
{
|
||||
EVGL_Context *ctx = NULL;
|
||||
|
||||
ctx = _evgl_current_context_get();
|
||||
ctx = evas_gl_common_current_context_get();
|
||||
|
||||
if (!ctx)
|
||||
{
|
||||
CRI("\e[1;33m%s\e[m: Current Context NOT SET: GL Call Should NOT Be Called without MakeCurrent!!!", api);
|
||||
}
|
||||
CRI("\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_2_X)
|
||||
CRI("\e[1;33m%s\e[m: This API is being called with the wrong context (invalid version).", api);
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -29,7 +29,7 @@ void _direct_rendering_check(const char *api)
|
|||
{
|
||||
EVGL_Context *ctx = NULL;
|
||||
|
||||
ctx = _evgl_current_context_get();
|
||||
ctx = evas_gl_common_current_context_get();
|
||||
if (!ctx)
|
||||
{
|
||||
ERR("Current Context Not Set");
|
||||
|
@ -59,7 +59,7 @@ _evgl_glBindFramebuffer(GLenum target, GLuint framebuffer)
|
|||
EVGL_Resource *rsc;
|
||||
|
||||
rsc = _evgl_tls_resource_get();
|
||||
ctx = _evgl_current_context_get();
|
||||
ctx = evas_gl_common_current_context_get();
|
||||
|
||||
if (!ctx)
|
||||
{
|
||||
|
@ -185,7 +185,7 @@ _evgl_glReleaseShaderCompiler(void)
|
|||
// 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
|
||||
static void
|
||||
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,
|
||||
|
@ -307,6 +307,27 @@ compute_gl_coordinates(int win_w, int win_h, int rot, int clip_image,
|
|||
//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)
|
||||
{
|
||||
|
@ -338,6 +359,29 @@ _evgl_glClear(GLbitfield mask)
|
|||
{
|
||||
if (!(rsc->current_ctx->current_fbo))
|
||||
{
|
||||
/* 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);
|
||||
|
@ -374,6 +418,8 @@ _evgl_glClear(GLbitfield mask)
|
|||
}
|
||||
|
||||
glClear(mask);
|
||||
|
||||
// TODO/FIXME: Restore previous client-side scissors.
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -403,7 +449,7 @@ _evgl_glEnable(GLenum cap)
|
|||
{
|
||||
EVGL_Context *ctx;
|
||||
|
||||
ctx = _evgl_current_context_get();
|
||||
ctx = evas_gl_common_current_context_get();
|
||||
|
||||
if (cap == GL_SCISSOR_TEST)
|
||||
if (ctx) ctx->scissor_enabled = 1;
|
||||
|
@ -415,7 +461,7 @@ _evgl_glDisable(GLenum cap)
|
|||
{
|
||||
EVGL_Context *ctx;
|
||||
|
||||
ctx = _evgl_current_context_get();
|
||||
ctx = evas_gl_common_current_context_get();
|
||||
|
||||
if (cap == GL_SCISSOR_TEST)
|
||||
if (ctx) ctx->scissor_enabled = 0;
|
||||
|
@ -887,7 +933,7 @@ void
|
|||
_evgld_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
|
||||
{
|
||||
EVGL_FUNC_BEGIN();
|
||||
glClearColor(red, green, blue, alpha);
|
||||
_evgl_glClearColor(red, green, blue, alpha);
|
||||
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
||||
EVGL_FUNC_END();
|
||||
}
|
||||
|
@ -2386,7 +2432,7 @@ _normal_gl_api_get(Evas_GL_API *funcs)
|
|||
ORD(glBufferSubData);
|
||||
ORD(glCheckFramebufferStatus);
|
||||
// ORD(glClear);
|
||||
ORD(glClearColor);
|
||||
// ORD(glClearColor);
|
||||
// ORD(glClearDepthf);
|
||||
ORD(glClearStencil);
|
||||
ORD(glColorMask);
|
||||
|
@ -2525,6 +2571,7 @@ _normal_gl_api_get(Evas_GL_API *funcs)
|
|||
|
||||
// For Direct Rendering
|
||||
ORD(glClear);
|
||||
ORD(glClearColor);
|
||||
ORD(glDisable);
|
||||
ORD(glEnable);
|
||||
ORD(glGetIntegerv);
|
||||
|
@ -2551,6 +2598,7 @@ _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);
|
||||
|
@ -2719,6 +2767,8 @@ _debug_gl_api_get(Evas_GL_API *funcs)
|
|||
void
|
||||
_evgl_api_get(Evas_GL_API *funcs, int debug)
|
||||
{
|
||||
memset(funcs, 0, sizeof(Evas_GL_API));
|
||||
|
||||
if (debug)
|
||||
_debug_gl_api_get(funcs);
|
||||
else
|
||||
|
|
|
@ -63,61 +63,108 @@ char _gl_ext_string[10240] = { 0 };
|
|||
|
||||
// Evas extensions from EGL extensions
|
||||
#ifdef GL_GLES
|
||||
static void *
|
||||
evgl_evasglCreateImage(int target, void* buffer, int *attrib_list)
|
||||
#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("Unable to execute GL command. Error retrieving tls");
|
||||
return NULL;
|
||||
ERR("%s: Unable to execute GL command. Error retrieving tls", function);
|
||||
evas_gl_common_error_set(NULL, EVAS_GL_NOT_INITIALIZED);
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
if (!rsc->current_eng)
|
||||
{
|
||||
ERR("Unable to retrive Current Engine");
|
||||
return NULL;
|
||||
ERR("%s: Unable to retrive Current Engine", function);
|
||||
evas_gl_common_error_set(NULL, 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 EXT_FUNC(eglCreateImage)(dpy, EGL_NO_CONTEXT, target, buffer, attrib_list);
|
||||
return dpy;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Invalid Engine... (Can't acccess EGL Display)\n");
|
||||
return NULL;
|
||||
ERR("%s: Invalid Engine... (Can't acccess EGL Display)\n", function);
|
||||
evas_gl_common_error_set(NULL, 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_native_context_get(evasctx);
|
||||
return _evgl_eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
|
||||
}
|
||||
|
||||
static void
|
||||
evgl_evasglDestroyImage(EvasGLImage image)
|
||||
{
|
||||
EGLDisplay dpy = EGL_NO_DISPLAY;
|
||||
EVGL_Resource *rsc;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if ((evgl_engine) && (evgl_engine->funcs->display_get))
|
||||
{
|
||||
dpy = (EGLDisplay)evgl_engine->funcs->display_get(rsc->current_eng);
|
||||
EXT_FUNC(eglDestroyImage)(dpy, image);
|
||||
}
|
||||
else
|
||||
ERR("Invalid Engine... (Can't acccess EGL Display)\n");
|
||||
EGLDisplay dpy = EGLDISPLAY_GET();
|
||||
if (!dpy) return;
|
||||
EXT_FUNC(eglDestroyImage)(dpy, image);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -129,9 +176,63 @@ evgl_glEvasGLImageTargetTexture2D(GLenum target, EvasGLImage image)
|
|||
static void
|
||||
evgl_glEvasGLImageTargetRenderbufferStorage(GLenum target, EvasGLImage image)
|
||||
{
|
||||
EXT_FUNC(glEGLImageTargetTexture2DOES)(target, 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
|
||||
|
||||
|
|
|
@ -446,12 +446,15 @@ _EVASGL_EXT_BEGIN(EGL_KHR_image_base)
|
|||
_EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("eglDestroyImageKHR"))
|
||||
_EVASGL_EXT_FUNCTION_PRIVATE_END()
|
||||
|
||||
_EVASGL_EXT_FUNCTION_BEGIN(EvasGLImage, evasglCreateImage, (int target, void* buffer, int *attrib_list))
|
||||
_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
|
||||
{
|
||||
|
@ -562,6 +565,67 @@ _EVASGL_EXT_BEGIN(EGL_KHR_gl_renderbuffer_image)
|
|||
#endif
|
||||
_EVASGL_EXT_END()
|
||||
|
||||
_EVASGL_EXT_BEGIN(EGL_KHR_fence_sync)
|
||||
|
||||
_EVASGL_EXT_DRVNAME(EGL_KHR_fence_sync)
|
||||
|
||||
_EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(void *, eglCreateSyncKHR, (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list))
|
||||
_EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("eglCreateSyncKHR"))
|
||||
_EVASGL_EXT_FUNCTION_PRIVATE_END()
|
||||
_EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(EGLBoolean, eglDestroySyncKHR, (EGLDisplay dpy, EGLSyncKHR sync))
|
||||
_EVASGL_EXT_FUNCTION_DRVFUNC(GETPROCADDR("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(GETPROCADDR("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(GETPROCADDR("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(GETPROCADDR("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(GETPROCADDR("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)
|
||||
|
@ -575,6 +639,7 @@ _EVASGL_EXT_BEGIN(EGL_SEC_map_image)
|
|||
_EVASGL_EXT_END()
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -754,6 +754,10 @@ EAPI void evas_gl_preload_render_unlock(evas_gl_make_current_cb make_cur
|
|||
EAPI void evas_gl_preload_render_relax(evas_gl_make_current_cb make_current, void *engine_data);
|
||||
EAPI void evas_gl_symbols(void *(*GetProcAddress)(const char *name));
|
||||
|
||||
EAPI void evas_gl_common_error_set(void *data, int error_enum);
|
||||
EAPI int evas_gl_common_error_get(void *data);
|
||||
EAPI void *evas_gl_common_current_context_get(void);
|
||||
|
||||
typedef int (*Evas_GL_Preload)(void);
|
||||
typedef void (*Evas_GL_Common_Image_Call)(Evas_GL_Image *im);
|
||||
typedef void (*Evas_GL_Common_Context_Call)(Evas_Engine_GL_Context *gc);
|
||||
|
|
|
@ -10,10 +10,14 @@ typedef struct _GL_Format
|
|||
|
||||
// Globals
|
||||
static Evas_GL_API gl_funcs;
|
||||
static Evas_GL_API gles1_funcs;
|
||||
EVGL_Engine *evgl_engine = NULL;
|
||||
int _evas_gl_log_dom = -1;
|
||||
int _evas_gl_log_level = -1;
|
||||
|
||||
typedef void *(*glsym_func_void_ptr) ();
|
||||
glsym_func_void_ptr glsym_evas_gl_native_context_get = NULL;
|
||||
|
||||
static void _surface_cap_print(int error);
|
||||
static void _surface_context_list_print();
|
||||
static void _internal_resources_destroy(void *eng_data, EVGL_Resource *rsc);
|
||||
|
@ -59,13 +63,15 @@ _internal_resources_create(void *eng_data)
|
|||
}
|
||||
|
||||
// Create a resource context
|
||||
rsc->context = evgl_engine->funcs->context_create(eng_data, NULL);
|
||||
rsc->context = evgl_engine->funcs->context_create(eng_data, NULL, EVAS_GL_GLES_2_X);
|
||||
if (!rsc->context)
|
||||
{
|
||||
ERR("Internal resource context creations failed.");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rsc->error_state = EVAS_GL_SUCCESS;
|
||||
|
||||
return rsc;
|
||||
|
||||
error:
|
||||
|
@ -817,6 +823,8 @@ _surface_context_list_print()
|
|||
#define YELLOW "\e[1;33m"
|
||||
#define RED "\e[1;31m"
|
||||
|
||||
LKL(evgl_engine->resource_lock);
|
||||
|
||||
DBG( YELLOW "-----------------------------------------------" RESET);
|
||||
DBG("Total Number of active Evas GL Surfaces: %d", eina_list_count(evgl_engine->surfaces));
|
||||
|
||||
|
@ -864,6 +872,8 @@ _surface_context_list_print()
|
|||
}
|
||||
DBG( YELLOW "-----------------------------------------------" RESET);
|
||||
|
||||
LKU(evgl_engine->resource_lock);
|
||||
|
||||
#undef RESET
|
||||
#undef GREEN
|
||||
#undef YELLOW
|
||||
|
@ -891,11 +901,9 @@ _surface_buffers_fbo_set(EVGL_Surface *sfc, GLuint fbo)
|
|||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
#endif
|
||||
|
||||
|
||||
// Render Target Texture
|
||||
if (sfc->color_buf)
|
||||
_texture_attach_2d(sfc->color_buf, GL_COLOR_ATTACHMENT0, 0, sfc->msaa_samples);
|
||||
|
||||
_texture_attach_2d(sfc->color_buf, GL_COLOR_ATTACHMENT0, 0, sfc->msaa_samples);
|
||||
|
||||
// Depth Stencil RenderBuffer - Attach it to FBO
|
||||
if (sfc->depth_stencil_buf)
|
||||
|
@ -910,11 +918,11 @@ _surface_buffers_fbo_set(EVGL_Surface *sfc, GLuint fbo)
|
|||
|
||||
// Depth RenderBuffer - Attach it to FBO
|
||||
if (sfc->depth_buf)
|
||||
_renderbuffer_attach(sfc->depth_buf, GL_DEPTH_ATTACHMENT);
|
||||
_renderbuffer_attach(sfc->depth_buf, GL_DEPTH_ATTACHMENT);
|
||||
|
||||
// Stencil RenderBuffer - Attach it to FBO
|
||||
if (sfc->stencil_buf)
|
||||
_renderbuffer_attach(sfc->stencil_buf, GL_STENCIL_ATTACHMENT);
|
||||
_renderbuffer_attach(sfc->stencil_buf, GL_STENCIL_ATTACHMENT);
|
||||
|
||||
// Check FBO for completeness
|
||||
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
@ -1086,9 +1094,15 @@ _internal_config_set(EVGL_Surface *sfc, Evas_GL_Config *cfg)
|
|||
sfc->depth_stencil_fmt = evgl_engine->caps.fbo_fmts[i].depth_stencil_fmt;
|
||||
sfc->msaa_samples = evgl_engine->caps.fbo_fmts[i].samples;
|
||||
|
||||
// TODO: Implement surface reconfigure and add depth+stencil support
|
||||
|
||||
// Direct Rendering Option
|
||||
if ( (!stencil_bit) || (evgl_engine->direct_override) )
|
||||
sfc->direct_fb_opt = cfg->options_bits & EVAS_GL_OPTIONS_DIRECT;
|
||||
if ((!depth_bit && !stencil_bit) || evgl_engine->direct_override)
|
||||
sfc->direct_fb_opt = cfg->options_bits & EVAS_GL_OPTIONS_DIRECT;
|
||||
|
||||
// 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);
|
||||
|
||||
cfg_index = i;
|
||||
break;
|
||||
|
@ -1110,6 +1124,7 @@ _internal_config_set(EVGL_Surface *sfc, Evas_GL_Config *cfg)
|
|||
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(" Client-side Rot. : %d", sfc->client_side_rotation);
|
||||
sfc->cfg_index = cfg_index;
|
||||
return 1;
|
||||
}
|
||||
|
@ -1130,7 +1145,7 @@ _evgl_direct_renderable(EVGL_Resource *rsc, EVGL_Surface *sfc)
|
|||
// Functions used by Evas GL module
|
||||
//---------------------------------------------------------------//
|
||||
EVGL_Resource *
|
||||
_evgl_tls_resource_get()
|
||||
_evgl_tls_resource_get(void)
|
||||
{
|
||||
EVGL_Resource *rsc = NULL;
|
||||
|
||||
|
@ -1219,8 +1234,8 @@ _evgl_tls_resource_destroy(void *eng_data)
|
|||
evgl_engine->resource_key = 0;
|
||||
}
|
||||
|
||||
EVGL_Context *
|
||||
_evgl_current_context_get()
|
||||
EAPI void * /* EVGL_Context */
|
||||
evas_gl_common_current_context_get(void)
|
||||
{
|
||||
EVGL_Resource *rsc;
|
||||
|
||||
|
@ -1230,11 +1245,11 @@ _evgl_current_context_get()
|
|||
return NULL;
|
||||
}
|
||||
else
|
||||
return rsc->current_ctx;
|
||||
return rsc->current_ctx;
|
||||
}
|
||||
|
||||
int
|
||||
_evgl_not_in_pixel_get()
|
||||
_evgl_not_in_pixel_get(void)
|
||||
{
|
||||
EVGL_Resource *rsc;
|
||||
|
||||
|
@ -1254,7 +1269,7 @@ _evgl_not_in_pixel_get()
|
|||
}
|
||||
|
||||
int
|
||||
_evgl_direct_enabled()
|
||||
_evgl_direct_enabled(void)
|
||||
{
|
||||
EVGL_Resource *rsc;
|
||||
EVGL_Surface *sfc;
|
||||
|
@ -1266,6 +1281,50 @@ _evgl_direct_enabled()
|
|||
return _evgl_direct_renderable(rsc, sfc);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_gl_common_error_set(void *data EINA_UNUSED, int error_enum)
|
||||
{
|
||||
EVGL_Resource *rsc;
|
||||
|
||||
if (!(rsc=_evgl_tls_resource_get()))
|
||||
{
|
||||
WRN("evgl: Unable to set error!");
|
||||
return;
|
||||
}
|
||||
|
||||
rsc->error_state = error_enum;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
evas_gl_common_error_get(void *data EINA_UNUSED)
|
||||
{
|
||||
EVGL_Resource *rsc;
|
||||
|
||||
if (!(rsc=_evgl_tls_resource_get()))
|
||||
{
|
||||
WRN("evgl: Unable to get error!");
|
||||
return EVAS_GL_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return rsc->error_state;
|
||||
}
|
||||
|
||||
EVGLNative_Context
|
||||
_evgl_native_context_get(Evas_GL_Context *ctx)
|
||||
{
|
||||
EVGL_Context *evglctx;
|
||||
|
||||
if (!glsym_evas_gl_native_context_get)
|
||||
{
|
||||
ERR("Engine can't get a pointer to the native context");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
evglctx = glsym_evas_gl_native_context_get(ctx);
|
||||
if (!evglctx) return NULL;
|
||||
return evglctx->context;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------//
|
||||
// Exported functions for evas_engine to use
|
||||
|
||||
|
@ -1315,6 +1374,8 @@ evgl_engine_init(void *eng_data, const EVGL_Interface *efunc)
|
|||
goto error;
|
||||
}
|
||||
|
||||
LKI(evgl_engine->resource_lock);
|
||||
|
||||
// Assign functions
|
||||
evgl_engine->funcs = efunc;
|
||||
|
||||
|
@ -1326,6 +1387,9 @@ evgl_engine_init(void *eng_data, const EVGL_Interface *efunc)
|
|||
}
|
||||
DBG("TLS KEY created: %d", evgl_engine->resource_key);
|
||||
|
||||
// Link to evas_gl.c (this doesn't look great)
|
||||
glsym_evas_gl_native_context_get = dlsym(RTLD_DEFAULT, "_evas_gl_native_context_get");
|
||||
|
||||
// Initialize Extensions
|
||||
if (efunc->proc_address_get && efunc->ext_string_get)
|
||||
evgl_api_ext_init(efunc->proc_address_get, efunc->ext_string_get(eng_data));
|
||||
|
@ -1381,6 +1445,7 @@ error:
|
|||
{
|
||||
if (evgl_engine->resource_key)
|
||||
eina_tls_free(evgl_engine->resource_key);
|
||||
LKD(evgl_engine->resource_lock);
|
||||
free(evgl_engine);
|
||||
}
|
||||
evgl_engine = NULL;
|
||||
|
@ -1394,7 +1459,11 @@ void
|
|||
evgl_engine_shutdown(void *eng_data)
|
||||
{
|
||||
// Check if engine is valid
|
||||
if (!evgl_engine) return;
|
||||
if (!evgl_engine)
|
||||
{
|
||||
ERR("EVGL Engine not valid!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Log
|
||||
eina_log_domain_unregister(_evas_gl_log_dom);
|
||||
|
@ -1403,6 +1472,8 @@ evgl_engine_shutdown(void *eng_data)
|
|||
// Destroy internal resources
|
||||
_evgl_tls_resource_destroy(eng_data);
|
||||
|
||||
LKD(evgl_engine->resource_lock);
|
||||
|
||||
// Free engine
|
||||
free(evgl_engine);
|
||||
evgl_engine = NULL;
|
||||
|
@ -1414,17 +1485,20 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, 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;
|
||||
|
||||
// Check if engine is valid
|
||||
if (!evgl_engine)
|
||||
{
|
||||
ERR("Invalid EVGL Engine!");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ACCESS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!cfg)
|
||||
{
|
||||
ERR("Invalid Config!");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONFIG);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1433,6 +1507,7 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int 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);
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1460,6 +1535,7 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h)
|
|||
if (!sfc)
|
||||
{
|
||||
ERR("Surface allocation failed.");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -1471,6 +1547,7 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h)
|
|||
if (!_internal_config_set(sfc, cfg))
|
||||
{
|
||||
ERR("Unsupported Format!");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONFIG);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -1478,13 +1555,28 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h)
|
|||
if (!_internal_resource_make_current(eng_data, NULL))
|
||||
{
|
||||
ERR("Error doing an internal resource make current");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT);
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Allocate a special surface for 1.1
|
||||
if (cfg->gles_version == EVAS_GL_GLES_1_X)
|
||||
{
|
||||
if (!evgl_engine->funcs->gles1_surface_create)
|
||||
{
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_NOT_INITIALIZED);
|
||||
goto error;
|
||||
}
|
||||
|
||||
INF("Creating special surface for GLES 1.x rendering");
|
||||
evgl_engine->funcs->gles1_surface_create(eng_data, sfc, cfg, w, h);
|
||||
}
|
||||
|
||||
// Create internal buffers
|
||||
if (!_surface_buffers_create(sfc))
|
||||
{
|
||||
ERR("Unable Create Specificed Surfaces.");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
|
||||
goto error;
|
||||
};
|
||||
|
||||
|
@ -1494,6 +1586,7 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h)
|
|||
if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, 0))
|
||||
{
|
||||
ERR("Unable Create Allocate Memory for Surface.");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
@ -1501,11 +1594,28 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h)
|
|||
if (!evgl_engine->funcs->make_current(eng_data, NULL, NULL, 0))
|
||||
{
|
||||
ERR("Error doing make_current(NULL, NULL).");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT);
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Keep track of all the created surfaces
|
||||
LKL(evgl_engine->resource_lock);
|
||||
evgl_engine->surfaces = eina_list_prepend(evgl_engine->surfaces, sfc);
|
||||
LKU(evgl_engine->resource_lock);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (need_reconfigure)
|
||||
{
|
||||
// See FIXME notice above in _internal_config_set
|
||||
ERR("Surface reconfigure is not implemented yet");
|
||||
}
|
||||
|
||||
return sfc;
|
||||
|
||||
|
@ -1514,11 +1624,123 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// Check if engine is valid
|
||||
if (!evgl_engine)
|
||||
{
|
||||
ERR("Invalid EVGL Engine!");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ACCESS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!cfg)
|
||||
{
|
||||
ERR("Invalid Config!");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONFIG);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!evgl_engine->funcs->pbuffer_surface_create)
|
||||
{
|
||||
ERR("Engine can not create PBuffers");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_NOT_INITIALIZED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Allocate surface structure
|
||||
sfc = calloc(1, sizeof(EVGL_Surface));
|
||||
if (!sfc)
|
||||
{
|
||||
ERR("Surface allocation failed.");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
|
||||
goto error;
|
||||
}
|
||||
|
||||
sfc->w = w;
|
||||
sfc->h = h;
|
||||
sfc->pbuffer.color_fmt = cfg->color_format;
|
||||
sfc->pbuffer.is_pbuffer = EINA_TRUE;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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(sfc, cfg))
|
||||
{
|
||||
ERR("Unsupported Format!");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONFIG);
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Create internal buffers
|
||||
if (!_surface_buffers_create(sfc))
|
||||
{
|
||||
ERR("Unable Create Specificed Surfaces.");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
|
||||
goto error;
|
||||
};
|
||||
|
||||
// Allocate resources for fallback unless the flag is on
|
||||
if (!evgl_engine->direct_mem_opt)
|
||||
{
|
||||
if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, 0))
|
||||
{
|
||||
ERR("Unable Create Allocate Memory for Surface.");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not calling make_current
|
||||
|
||||
pbuffer = evgl_engine->funcs->pbuffer_surface_create
|
||||
(eng_data, sfc, attrib_list);
|
||||
|
||||
if (!pbuffer)
|
||||
{
|
||||
ERR("Engine failed to create a PBuffer");
|
||||
goto error;
|
||||
}
|
||||
|
||||
sfc->pbuffer.native_surface = pbuffer;
|
||||
|
||||
if (!evgl_engine->funcs->make_current(eng_data, NULL, NULL, 0))
|
||||
{
|
||||
ERR("Error doing make_current(NULL, NULL).");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Keep track of all the created surfaces
|
||||
LKL(evgl_engine->resource_lock);
|
||||
evgl_engine->surfaces = eina_list_prepend(evgl_engine->surfaces, sfc);
|
||||
LKU(evgl_engine->resource_lock);
|
||||
|
||||
return sfc;
|
||||
|
||||
error:
|
||||
free(sfc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc)
|
||||
{
|
||||
EVGL_Resource *rsc;
|
||||
Eina_Bool need_reconfigure = EINA_FALSE;
|
||||
|
||||
// Check input parameter
|
||||
if ((!evgl_engine) || (!sfc))
|
||||
|
@ -1549,13 +1771,35 @@ evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc)
|
|||
evgl_make_current(eng_data, NULL, NULL);
|
||||
}
|
||||
|
||||
// Set the context current with resource context/surface
|
||||
if (!_internal_resource_make_current(eng_data, NULL))
|
||||
if (!sfc->pbuffer.native_surface)
|
||||
{
|
||||
ERR("Error doing an internal resource make current");
|
||||
return 0;
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
INF("Destroying special surface used for GLES 1.x rendering");
|
||||
ret = evgl_engine->funcs->gles1_surface_destroy(eng_data, sfc);
|
||||
|
||||
if (!ret) ERR("Engine failed to destroy a GLES1.x Surface.");
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Destroy created buffers
|
||||
if (!_surface_buffers_destroy(sfc))
|
||||
{
|
||||
|
@ -1563,6 +1807,24 @@ evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Destroy PBuffer surfaces
|
||||
if (sfc->pbuffer.native_surface)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sfc->pbuffer.fbo)
|
||||
glDeleteFramebuffers(1, &sfc->pbuffer.fbo);
|
||||
|
||||
ret = evgl_engine->funcs->pbuffer_surface_destroy(eng_data, sfc->pbuffer.native_surface);
|
||||
LKL(evgl_engine->resource_lock);
|
||||
evgl_engine->surfaces = eina_list_remove(evgl_engine->surfaces, sfc);
|
||||
LKU(evgl_engine->resource_lock);
|
||||
free(sfc);
|
||||
|
||||
if (!ret) ERR("Engine failed to destroy a PBuffer.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!evgl_engine->funcs->make_current(eng_data, NULL, NULL, 0))
|
||||
{
|
||||
ERR("Error doing make_current(NULL, NULL).");
|
||||
|
@ -1570,7 +1832,25 @@ evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc)
|
|||
}
|
||||
|
||||
// Remove it from the list
|
||||
LKL(evgl_engine->resource_lock);
|
||||
evgl_engine->surfaces = eina_list_remove(evgl_engine->surfaces, sfc);
|
||||
LKU(evgl_engine->resource_lock);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (need_reconfigure)
|
||||
{
|
||||
// See FIXME notice above in _internal_config_set
|
||||
WRN("Surface reconfigure is not implemented yet");
|
||||
}
|
||||
|
||||
free(sfc);
|
||||
sfc = NULL;
|
||||
|
@ -1580,7 +1860,8 @@ evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc)
|
|||
}
|
||||
|
||||
void *
|
||||
evgl_context_create(void *eng_data, EVGL_Context *share_ctx)
|
||||
evgl_context_create(void *eng_data, EVGL_Context *share_ctx,
|
||||
Evas_GL_Context_Version version)
|
||||
{
|
||||
EVGL_Context *ctx = NULL;
|
||||
|
||||
|
@ -1588,6 +1869,14 @@ evgl_context_create(void *eng_data, EVGL_Context *share_ctx)
|
|||
if (!evgl_engine)
|
||||
{
|
||||
ERR("Invalid EVGL Engine!");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ACCESS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((version < EVAS_GL_GLES_1_X) || (version > EVAS_GL_GLES_3_X))
|
||||
{
|
||||
ERR("Invalid context version number %d", version);
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1596,13 +1885,17 @@ evgl_context_create(void *eng_data, EVGL_Context *share_ctx)
|
|||
if (!ctx)
|
||||
{
|
||||
ERR("Error allocating context object.");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->version = version;
|
||||
|
||||
// Call engine create context
|
||||
if (share_ctx)
|
||||
ctx->context = evgl_engine->funcs->context_create(eng_data, share_ctx->context);
|
||||
ctx->context = evgl_engine->funcs->context_create(eng_data, share_ctx->context, version);
|
||||
else
|
||||
ctx->context = evgl_engine->funcs->context_create(eng_data, NULL);
|
||||
ctx->context = evgl_engine->funcs->context_create(eng_data, NULL, version);
|
||||
|
||||
// Call engine create context
|
||||
if (!ctx->context)
|
||||
|
@ -1613,7 +1906,9 @@ evgl_context_create(void *eng_data, EVGL_Context *share_ctx)
|
|||
}
|
||||
|
||||
// Keep track of all the created context
|
||||
LKL(evgl_engine->resource_lock);
|
||||
evgl_engine->contexts = eina_list_prepend(evgl_engine->contexts, ctx);
|
||||
LKU(evgl_engine->resource_lock);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
@ -1655,7 +1950,9 @@ evgl_context_destroy(void *eng_data, EVGL_Context *ctx)
|
|||
}
|
||||
|
||||
// Remove it from the list
|
||||
LKL(evgl_engine->resource_lock);
|
||||
evgl_engine->contexts = eina_list_remove(evgl_engine->contexts, ctx);
|
||||
LKU(evgl_engine->resource_lock);
|
||||
|
||||
// Free context
|
||||
free(ctx);
|
||||
|
@ -1677,6 +1974,8 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
(sfc && (!ctx)) )
|
||||
{
|
||||
ERR("Invalid Inputs. Engine: %p Surface: %p Context: %p!", evgl_engine, sfc, ctx);
|
||||
if(!sfc) evas_gl_common_error_set(eng_data, EVAS_GL_BAD_SURFACE);
|
||||
if(!ctx) evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1726,6 +2025,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
if (!_surface_buffers_allocate(eng_data, sfc, 0, 0, 1))
|
||||
{
|
||||
ERR("Unable to destroy surface buffers!");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
|
||||
return 0;
|
||||
}
|
||||
sfc->buffers_allocated = 0;
|
||||
|
@ -1745,6 +2045,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, 1))
|
||||
{
|
||||
ERR("Unable Create Specificed Surfaces. Unsupported format!");
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
|
||||
return 0;
|
||||
};
|
||||
sfc->buffers_allocated = 1;
|
||||
|
@ -1757,9 +2058,28 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
if (!_internal_resource_make_current(eng_data, ctx))
|
||||
{
|
||||
ERR("Error doing a make current with internal surface. Context: %p", ctx);
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->version == EVAS_GL_GLES_1_X)
|
||||
{
|
||||
if (_evgl_direct_renderable(rsc, sfc))
|
||||
{
|
||||
rsc->direct.rendered = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
evgl_engine->funcs->make_current(eng_data, sfc->gles1_sfc,
|
||||
ctx->context, EINA_TRUE);
|
||||
}
|
||||
|
||||
ctx->current_sfc = sfc;
|
||||
rsc->current_ctx = ctx;
|
||||
rsc->current_eng = eng_data;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Normal FBO Rendering
|
||||
// Create FBO if it hasn't been created
|
||||
if (!ctx->surface_fbo)
|
||||
|
@ -1775,6 +2095,12 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
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
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
ctx->current_fbo = 0;
|
||||
}
|
||||
|
||||
if (ctx->current_fbo == 0)
|
||||
{
|
||||
|
@ -1791,6 +2117,35 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
|
||||
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)
|
||||
{
|
||||
glGenFramebuffers(1, &sfc->pbuffer.fbo);
|
||||
GLERRLOG();
|
||||
}
|
||||
if (!_surface_buffers_fbo_set(sfc, sfc->pbuffer.fbo))
|
||||
ERR("Could not detach current FBO");
|
||||
}
|
||||
|
||||
evgl_engine->funcs->make_current(eng_data, sfc->pbuffer.native_surface,
|
||||
ctx->context, EINA_TRUE);
|
||||
|
||||
// Bind to the previously bound buffer (may be 0)
|
||||
if (ctx->current_fbo)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
|
||||
GLERRLOG();
|
||||
}
|
||||
|
||||
rsc->direct.rendered = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Attach fbo and the buffers
|
||||
|
@ -1811,6 +2166,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
|
|||
if (!_surface_buffers_fbo_set(sfc, ctx->surface_fbo))
|
||||
{
|
||||
ERR("Attaching buffers to context fbo failed. Engine: %p Surface: %p Context FBO: %u", evgl_engine, sfc, ctx->surface_fbo);
|
||||
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1837,7 +2193,7 @@ evgl_string_query(int name)
|
|||
switch(name)
|
||||
{
|
||||
case EVAS_GL_EXTENSIONS:
|
||||
return (void*)evgl_api_ext_string_get();
|
||||
return evgl_api_ext_string_get();
|
||||
default:
|
||||
return "";
|
||||
};
|
||||
|
@ -1885,35 +2241,38 @@ evgl_direct_rendered()
|
|||
return rsc->direct.rendered;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
evgl_direct_info_set(int win_w, int win_h, int rot, int img_x, int img_y, int img_w, int img_h, int clip_x, int clip_y, int clip_w, int clip_h)
|
||||
evgl_direct_info_set(int win_w, int win_h, int rot,
|
||||
int img_x, int img_y, int img_w, int img_h,
|
||||
int clip_x, int clip_y, int clip_w, int clip_h)
|
||||
{
|
||||
EVGL_Resource *rsc;
|
||||
|
||||
if (!(rsc=_evgl_tls_resource_get())) return;
|
||||
|
||||
// Normally direct rendering isn't allowed if alpha is on and
|
||||
// rotation is not 0. BUT, if override is on, allow it.
|
||||
if ( (rot==0) ||
|
||||
((rot!=0) && (evgl_engine->direct_override)) )
|
||||
/* Normally direct rendering isn't allowed if rotation is not 0.
|
||||
* BUT, if client_side_rotation or override is on, allow it.
|
||||
*/
|
||||
if ((rot == 0) || evgl_engine->direct_override ||
|
||||
(rsc->current_ctx &&
|
||||
rsc->current_ctx->current_sfc &&
|
||||
rsc->current_ctx->current_sfc->client_side_rotation))
|
||||
{
|
||||
rsc->direct.enabled = EINA_TRUE;
|
||||
|
||||
rsc->direct.win_w = win_w;
|
||||
rsc->direct.win_h = win_h;
|
||||
rsc->direct.rot = rot;
|
||||
rsc->direct.win_w = win_w;
|
||||
rsc->direct.win_h = win_h;
|
||||
rsc->direct.rot = rot;
|
||||
|
||||
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.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;
|
||||
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
|
||||
{
|
||||
|
@ -1932,11 +2291,19 @@ evgl_direct_info_clear()
|
|||
}
|
||||
|
||||
Evas_GL_API *
|
||||
evgl_api_get()
|
||||
evgl_api_get(Evas_GL_Context_Version version)
|
||||
{
|
||||
_evgl_api_get(&gl_funcs, evgl_engine->api_debug_mode);
|
||||
|
||||
return &gl_funcs;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1993,7 +2360,7 @@ void
|
|||
evgl_direct_partial_render_end()
|
||||
{
|
||||
EVGL_Context *ctx;
|
||||
ctx = _evgl_current_context_get();
|
||||
ctx = evas_gl_common_current_context_get();
|
||||
|
||||
if (!ctx) return;
|
||||
|
||||
|
|
|
@ -24,15 +24,16 @@ typedef void (*EVGL_Engine_Call)(void *eng_data);
|
|||
EVGL_Engine *evgl_engine_init(void *eng_data, const EVGL_Interface *efunc);
|
||||
|
||||
void *evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, 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);
|
||||
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);
|
||||
void *evgl_proc_address_get(const char *name);
|
||||
int evgl_native_surface_get(EVGL_Surface *sfc, Evas_Native_Surface *ns);
|
||||
Evas_GL_API *evgl_api_get();
|
||||
Evas_GL_API *evgl_api_get(Evas_GL_Context_Version version);
|
||||
|
||||
int evgl_direct_rendered();
|
||||
void evgl_direct_override_get(int *override, int *force_off);
|
||||
|
|
|
@ -50,7 +50,7 @@ struct _EVGL_Interface
|
|||
int (*surface_destroy)(void *data, void *surface);
|
||||
|
||||
// Creates/Destroys the native surface from evas engine.
|
||||
void *(*context_create)(void *data, void *share_ctx);
|
||||
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.
|
||||
|
@ -64,6 +64,16 @@ struct _EVGL_Interface
|
|||
|
||||
// Returns the current rotation angle of evas
|
||||
int (*rotation_angle_get)(void *data);
|
||||
|
||||
// Create a pbuffer surface
|
||||
void *(*pbuffer_surface_create)(void *data, EVGL_Surface *evgl_sfc, const int *attrib_list);
|
||||
int (*pbuffer_surface_destroy)(void *data, void *surface);
|
||||
|
||||
// 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);
|
||||
};
|
||||
|
||||
struct _EVGL_Surface
|
||||
|
@ -93,8 +103,14 @@ struct _EVGL_Surface
|
|||
GLuint depth_stencil_buf;
|
||||
GLenum depth_stencil_fmt;
|
||||
|
||||
// Direct Rendering Option
|
||||
int direct_fb_opt;
|
||||
// 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 xpixmap : 1;
|
||||
|
||||
int cfg_index;
|
||||
|
||||
|
@ -108,6 +124,22 @@ struct _EVGL_Surface
|
|||
// 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;
|
||||
|
||||
//-------------------------//
|
||||
// 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;
|
||||
|
@ -119,6 +151,8 @@ struct _EVGL_Context
|
|||
{
|
||||
EVGLNative_Context context;
|
||||
|
||||
Evas_GL_Context_Version version;
|
||||
|
||||
// Context FBO
|
||||
GLuint surface_fbo;
|
||||
|
||||
|
@ -212,6 +246,8 @@ struct _EVGL_Resource
|
|||
EVGL_Context *current_ctx;
|
||||
void *current_eng;
|
||||
|
||||
int error_state;
|
||||
|
||||
struct {
|
||||
EVGLNative_Surface surface;
|
||||
int rendered;
|
||||
|
@ -235,6 +271,9 @@ struct _EVGL_Resource
|
|||
|
||||
Eina_Bool enabled : 1;
|
||||
} direct;
|
||||
struct {
|
||||
GLclampf r, g, b, a;
|
||||
} clear_color;
|
||||
|
||||
};
|
||||
|
||||
|
@ -269,6 +308,7 @@ struct _EVGL_Engine
|
|||
// Keep track of all the current surfaces/contexts
|
||||
Eina_List *surfaces;
|
||||
Eina_List *contexts;
|
||||
Eina_List *direct_depth_stencil_surfaces;
|
||||
|
||||
//void *engine_data;
|
||||
|
||||
|
@ -280,11 +320,13 @@ extern EVGL_Engine *evgl_engine;
|
|||
|
||||
// Internally used functions
|
||||
extern void _evgl_api_get(Evas_GL_API *api, int debug);
|
||||
extern EVGL_Resource *_evgl_tls_resource_get();
|
||||
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();
|
||||
extern int _evgl_not_in_pixel_get();
|
||||
extern int _evgl_direct_enabled();
|
||||
extern EVGL_Context *_evgl_current_context_get(void);
|
||||
extern int _evgl_not_in_pixel_get(void);
|
||||
extern int _evgl_direct_enabled(void);
|
||||
extern EVGLNative_Context _evgl_native_context_get(Evas_GL_Context *ctx);
|
||||
|
||||
#endif //_EVAS_GL_CORE_PRIVATE_H
|
||||
|
|
|
@ -84,7 +84,7 @@ static void *evgl_eng_native_window_create(void *data);
|
|||
static int evgl_eng_native_window_destroy(void *data, void *native_window);
|
||||
static void *evgl_eng_window_surface_create(void *data, void *native_window);
|
||||
static int evgl_eng_window_surface_destroy(void *data, void *surface);
|
||||
static void *evgl_eng_context_create(void *data, void *share_ctx);
|
||||
static void *evgl_eng_context_create(void *data, void *share_ctx, int version);
|
||||
static int evgl_eng_context_destroy(void *data, void *context);
|
||||
static const char *evgl_eng_string_get(void *data);
|
||||
static void *evgl_eng_proc_address_get(const char *name);
|
||||
|
@ -118,7 +118,11 @@ static const EVGL_Interface evgl_funcs =
|
|||
evgl_eng_make_current,
|
||||
evgl_eng_proc_address_get,
|
||||
evgl_eng_string_get,
|
||||
evgl_eng_rotation_angle_get
|
||||
evgl_eng_rotation_angle_get,
|
||||
NULL, // PBuffer
|
||||
NULL, // PBuffer
|
||||
NULL, // OpenGL-ES 1
|
||||
NULL, // OpenGL-ES 1
|
||||
};
|
||||
|
||||
/* local functions */
|
||||
|
@ -405,7 +409,7 @@ evgl_eng_window_surface_destroy(void *data, void *surface)
|
|||
}
|
||||
|
||||
static void *
|
||||
evgl_eng_context_create(void *data, void *share_ctx)
|
||||
evgl_eng_context_create(void *data, void *share_ctx, int version)
|
||||
{
|
||||
Render_Engine *re = (Render_Engine *)data;
|
||||
EGLContext context = EGL_NO_CONTEXT;
|
||||
|
@ -417,6 +421,12 @@ evgl_eng_context_create(void *data, void *share_ctx)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (version != EVAS_GL_GLES_2_X)
|
||||
{
|
||||
ERR("This engine only supports OpenGL-ES 2.0 contexts for now!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
|
||||
context_attrs[1] = 2;
|
||||
context_attrs[2] = EGL_NONE;
|
||||
|
|
|
@ -1113,6 +1113,15 @@ eng_gl_surface_create(void *data, void *config, int w, int h)
|
|||
return evgl_surface_create(data, cfg, w, h);
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_gl_pbuffer_surface_create(void *data, void *config, int w, int h, const int *attrib_list)
|
||||
{
|
||||
Evas_GL_Config *cfg = (Evas_GL_Config *)config;
|
||||
|
||||
EVGLINIT(data, NULL);
|
||||
return evgl_pbuffer_surface_create(data, cfg, w, h, attrib_list);
|
||||
}
|
||||
|
||||
static int
|
||||
eng_gl_surface_destroy(void *data, void *surface)
|
||||
{
|
||||
|
@ -1123,12 +1132,12 @@ eng_gl_surface_destroy(void *data, void *surface)
|
|||
}
|
||||
|
||||
static void *
|
||||
eng_gl_context_create(void *data, void *share_context)
|
||||
eng_gl_context_create(void *data, void *share_context, int version)
|
||||
{
|
||||
EVGL_Context *sctx = (EVGL_Context *)share_context;
|
||||
|
||||
EVGLINIT(data, NULL);
|
||||
return evgl_context_create(data, sctx);
|
||||
return evgl_context_create(data, sctx, version);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1147,6 +1156,8 @@ eng_gl_make_current(void *data, void *surface, void *context)
|
|||
EVGL_Surface *sfc = (EVGL_Surface *)surface;
|
||||
EVGL_Context *ctx = (EVGL_Context *)context;
|
||||
|
||||
// TODO: Add check for main thread before flush
|
||||
|
||||
EVGLINIT(data, 0);
|
||||
if ((sfc) && (ctx))
|
||||
{
|
||||
|
@ -1166,6 +1177,28 @@ eng_gl_make_current(void *data, void *surface, void *context)
|
|||
return evgl_make_current(data, sfc, ctx);
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_gl_current_surface_get(void *data EINA_UNUSED)
|
||||
{
|
||||
EVGL_Context *ctx;
|
||||
|
||||
ctx = evas_gl_common_current_context_get();
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
// Note: We could verify with a call to eglGetCurrentSurface
|
||||
|
||||
return ctx->current_sfc;
|
||||
}
|
||||
|
||||
static int
|
||||
eng_gl_rotation_angle_get(void *data)
|
||||
{
|
||||
if (!evgl_engine->funcs->rotation_angle_get) return 0;
|
||||
if (!_evgl_direct_enabled()) return 0;
|
||||
return evgl_engine->funcs->rotation_angle_get(data);
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_gl_string_query(void *data, int name)
|
||||
{
|
||||
|
@ -1190,10 +1223,10 @@ eng_gl_native_surface_get(void *data EINA_UNUSED, void *surface, void *native_su
|
|||
}
|
||||
|
||||
static void *
|
||||
eng_gl_api_get(void *data)
|
||||
eng_gl_api_get(void *data, int version)
|
||||
{
|
||||
EVGLINIT(data, NULL);
|
||||
return evgl_api_get();
|
||||
return evgl_api_get(version);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1303,6 +1336,112 @@ eng_gl_surface_read_pixels(void *data, void *surface,
|
|||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
eng_gl_surface_query(void *data, void *surface, int attr, void *value)
|
||||
{
|
||||
Render_Engine_GL_Generic *re = data;
|
||||
EVGL_Surface *sfc = surface;
|
||||
|
||||
#ifdef GL_GLES
|
||||
if (sfc->pbuffer.is_pbuffer)
|
||||
{
|
||||
// This is a real EGL surface, let's just call EGL directly
|
||||
int val;
|
||||
Eina_Bool ok;
|
||||
void *disp;
|
||||
|
||||
disp = re->window_egl_display_get(re->software.ob);
|
||||
ok = eglQuerySurface(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
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
evas_gl_common_error_set(data, EVAS_GL_BAD_ATTRIBUTE);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
#else
|
||||
(void) re; (void) sfc; (void) attr; (void) value;
|
||||
ERR("GLX support for surface_query is not implemented!");
|
||||
return EINA_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------//
|
||||
|
||||
static int
|
||||
|
@ -1769,6 +1908,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);
|
||||
|
@ -1782,6 +1922,11 @@ module_open(Evas_Module *em)
|
|||
ORD(gl_surface_lock);
|
||||
ORD(gl_surface_read_pixels);
|
||||
ORD(gl_surface_unlock);
|
||||
//ORD(gl_error_get);
|
||||
ORD(gl_surface_query);
|
||||
// gl_current_context_get is in engine
|
||||
ORD(gl_current_surface_get);
|
||||
ORD(gl_rotation_angle_get);
|
||||
|
||||
ORD(image_load_error_get);
|
||||
|
||||
|
|
|
@ -198,10 +198,16 @@ evgl_eng_window_surface_destroy(void *data EINA_UNUSED,
|
|||
}
|
||||
|
||||
static void *
|
||||
evgl_eng_context_create(void *data, void *share_ctx EINA_UNUSED)
|
||||
evgl_eng_context_create(void *data, void *share_ctx EINA_UNUSED, int version)
|
||||
{
|
||||
Render_Engine *re = data;
|
||||
|
||||
if (version != EVAS_GL_GLES_2_X)
|
||||
{
|
||||
ERR("This engine only supports OpenGL-ES 2.0 contexts for now!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
|
||||
return SDL_GL_CreateContext(re->generic.software.ob->window);
|
||||
}
|
||||
|
@ -248,7 +254,11 @@ static const EVGL_Interface evgl_funcs =
|
|||
evgl_eng_make_current,
|
||||
evgl_eng_proc_address_get,
|
||||
evgl_eng_string_get,
|
||||
evgl_eng_rotation_angle_get
|
||||
evgl_eng_rotation_angle_get,
|
||||
NULL, // PBuffer
|
||||
NULL, // PBuffer
|
||||
NULL, // OpenGL-ES 1
|
||||
NULL, // OpenGL-ES 1
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -22,8 +22,6 @@
|
|||
|
||||
#define EVAS_GL_UPDATE_TILE_SIZE 16
|
||||
|
||||
static int safe_native = -1;
|
||||
|
||||
typedef struct _Render_Engine Render_Engine;
|
||||
|
||||
struct _Render_Engine
|
||||
|
@ -75,6 +73,10 @@ 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;
|
||||
|
||||
glsym_func_void glsym_evas_gl_common_error_set = NULL;
|
||||
glsym_func_int glsym_evas_gl_common_error_get = NULL;
|
||||
glsym_func_void_ptr glsym_evas_gl_common_current_context_get = NULL;
|
||||
|
||||
#ifdef GL_GLES
|
||||
|
||||
#ifndef EGL_NATIVE_PIXMAP_KHR
|
||||
|
@ -217,6 +219,7 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush)
|
|||
if (!re)
|
||||
{
|
||||
ERR("Invalid Render Engine Data!");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -231,12 +234,15 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush)
|
|||
ret = eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
if (!ret)
|
||||
{
|
||||
ERR("eglMakeCurrent() failed! Error Code=%#x", eglGetError());
|
||||
int err = eglGetError();
|
||||
glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
|
||||
ERR("eglMakeCurrent() failed! Error Code=%#x", err);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// FIXME: Check (eglGetCurrentDisplay() != dpy) ?
|
||||
if ((eglGetCurrentContext() != ctx) ||
|
||||
(eglGetCurrentSurface(EGL_READ) != sfc) ||
|
||||
(eglGetCurrentSurface(EGL_DRAW) != sfc) )
|
||||
|
@ -251,7 +257,9 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush)
|
|||
|
||||
if (!ret)
|
||||
{
|
||||
ERR("eglMakeCurrent() failed! Error Code=%#x", eglGetError());
|
||||
int err = eglGetError();
|
||||
glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
|
||||
ERR("eglMakeCurrent() failed! Error Code=%#x", err);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -267,6 +275,7 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush)
|
|||
if (!ret)
|
||||
{
|
||||
ERR("glXMakeCurrent() failed!");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_DISPLAY);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
@ -285,6 +294,7 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush)
|
|||
if (!ret)
|
||||
{
|
||||
ERR("glXMakeCurrent() failed. Ret: %d! Context: %p Surface: %p", ret, (void*)ctx, (void*)sfc);
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_DISPLAY);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -303,6 +313,7 @@ evgl_eng_native_window_create(void *data)
|
|||
if (!re)
|
||||
{
|
||||
ERR("Invalid Render Engine Data!");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -331,6 +342,7 @@ evgl_eng_native_window_create(void *data)
|
|||
if (!win)
|
||||
{
|
||||
ERR("Creating native X window failed.");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_DISPLAY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -346,12 +358,14 @@ evgl_eng_native_window_destroy(void *data, void *native_window)
|
|||
if (!re)
|
||||
{
|
||||
ERR("Invalid Render Engine Data!");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!native_window)
|
||||
{
|
||||
ERR("Inavlid native surface.");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_NATIVE_WINDOW);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -374,6 +388,7 @@ evgl_eng_window_surface_create(void *data, void *native_window EINA_UNUSED)
|
|||
if (!re)
|
||||
{
|
||||
ERR("Invalid Render Engine Data!");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -414,6 +429,7 @@ evgl_eng_window_surface_destroy(void *data, void *surface)
|
|||
if (!re)
|
||||
{
|
||||
ERR("Invalid Render Engine Data!");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -421,6 +437,7 @@ evgl_eng_window_surface_destroy(void *data, void *surface)
|
|||
if (!surface)
|
||||
{
|
||||
ERR("Invalid surface.");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_SURFACE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -432,7 +449,7 @@ evgl_eng_window_surface_destroy(void *data, void *surface)
|
|||
}
|
||||
|
||||
static void *
|
||||
evgl_eng_context_create(void *data, void *share_ctx)
|
||||
evgl_eng_context_create(void *data, void *share_ctx, Evas_GL_Context_Version version)
|
||||
{
|
||||
Render_Engine *re = (Render_Engine *)data;
|
||||
|
||||
|
@ -440,6 +457,14 @@ evgl_eng_context_create(void *data, void *share_ctx)
|
|||
if (!re)
|
||||
{
|
||||
ERR("Invalid Render Engine Data!");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((version < EVAS_GL_GLES_1_X) || (version > EVAS_GL_GLES_3_X))
|
||||
{
|
||||
ERR("Invalid context version number %d", version);
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -448,7 +473,7 @@ evgl_eng_context_create(void *data, void *share_ctx)
|
|||
int context_attrs[3];
|
||||
|
||||
context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
|
||||
context_attrs[1] = 2;
|
||||
context_attrs[1] = version;
|
||||
context_attrs[2] = EGL_NONE;
|
||||
|
||||
// Share context already assumes that it's sharing with evas' context
|
||||
|
@ -459,6 +484,13 @@ evgl_eng_context_create(void *data, void *share_ctx)
|
|||
(EGLContext)share_ctx,
|
||||
context_attrs);
|
||||
}
|
||||
else if (version == EVAS_GL_GLES_1_X)
|
||||
{
|
||||
context = eglCreateContext(eng_get_ob(re)->egl_disp,
|
||||
eng_get_ob(re)->egl_config,
|
||||
NULL,
|
||||
context_attrs);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = eglCreateContext(eng_get_ob(re)->egl_disp,
|
||||
|
@ -469,7 +501,9 @@ evgl_eng_context_create(void *data, void *share_ctx)
|
|||
|
||||
if (!context)
|
||||
{
|
||||
ERR("Engine Context Creations Failed. Error: %#x.", eglGetError());
|
||||
int err = eglGetError();
|
||||
ERR("Engine Context Creations Failed. Error: %#x.", err);
|
||||
glsym_evas_gl_common_error_set(data, err - EGL_SUCCESS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -485,6 +519,15 @@ evgl_eng_context_create(void *data, void *share_ctx)
|
|||
(GLXContext)share_ctx,
|
||||
1);
|
||||
}
|
||||
/* TODO: Check this case.
|
||||
else if (version == EVAS_GL_GLES_1_X)
|
||||
{
|
||||
context = glXCreateContext(eng_get_ob(re)->info->info.display,
|
||||
eng_get_ob(re)->visualinfo,
|
||||
NULL,
|
||||
1);
|
||||
}
|
||||
*/
|
||||
else
|
||||
{
|
||||
context = glXCreateContext(eng_get_ob(re)->info->info.display,
|
||||
|
@ -496,6 +539,8 @@ evgl_eng_context_create(void *data, void *share_ctx)
|
|||
if (!context)
|
||||
{
|
||||
ERR("Internal Resource Context Creations Failed.");
|
||||
if(!(eng_get_ob(re)->info->info.display)) glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_DISPLAY);
|
||||
if(!(eng_get_ob(re)->win)) glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_NATIVE_WINDOW);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -513,6 +558,8 @@ evgl_eng_context_destroy(void *data, void *context)
|
|||
if ((!re) || (!context))
|
||||
{
|
||||
ERR("Invalid Render Input Data. Engine: %p, Context: %p", data, context);
|
||||
if (!re) glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
||||
if (!context) glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_CONTEXT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -534,6 +581,7 @@ evgl_eng_string_get(void *data)
|
|||
if (!re)
|
||||
{
|
||||
ERR("Invalid Render Engine Data!");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -566,18 +614,346 @@ evgl_eng_rotation_angle_get(void *data)
|
|||
if (!re)
|
||||
{
|
||||
ERR("Invalid Render Engine Data!");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((eng_get_ob(re)) && (eng_get_ob(re)->gl_context))
|
||||
return eng_get_ob(re)->gl_context->rot;
|
||||
return eng_get_ob(re)->gl_context->rot;
|
||||
else
|
||||
{
|
||||
ERR("Unable to retrieve rotation angle.");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_CONTEXT);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
evgl_eng_pbuffer_surface_create(void *data, EVGL_Surface *sfc,
|
||||
const int *attrib_list)
|
||||
{
|
||||
Render_Engine_GL_Generic *re = data;
|
||||
|
||||
// TODO: Add support for surfaceless pbuffers (EGL_NO_TEXTURE)
|
||||
// TODO: Add support for EGL_MIPMAP_TEXTURE??? (GLX doesn't support them)
|
||||
|
||||
if (attrib_list)
|
||||
WRN("This PBuffer implementation does not support extra attributes yet");
|
||||
|
||||
#ifdef GL_GLES
|
||||
int config_attrs[20];
|
||||
int surface_attrs[20];
|
||||
EGLSurface egl_sfc;
|
||||
EGLConfig egl_cfg;
|
||||
int num_config, i = 0;
|
||||
EGLDisplay disp;
|
||||
EGLContext ctx;
|
||||
|
||||
disp = re->window_egl_display_get(re->software.ob);
|
||||
ctx = re->window_gl_context_get(re->software.ob);
|
||||
|
||||
#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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (sfc->depth_fmt || sfc->depth_stencil_fmt)
|
||||
{
|
||||
config_attrs[i++] = EGL_DEPTH_SIZE;
|
||||
config_attrs[i++] = 1;
|
||||
}
|
||||
|
||||
if (sfc->stencil_fmt || sfc->depth_stencil_fmt)
|
||||
{
|
||||
config_attrs[i++] = EGL_STENCIL_SIZE;
|
||||
config_attrs[i++] = 1;
|
||||
}
|
||||
|
||||
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(disp, ctx, EGL_CONFIG_ID, &config_attrs[1]);
|
||||
#endif
|
||||
|
||||
if (!eglChooseConfig(disp, config_attrs, &egl_cfg, 1, &num_config)
|
||||
|| (num_config < 1))
|
||||
{
|
||||
int err = eglGetError();
|
||||
glsym_evas_gl_common_error_set(data, err - EGL_SUCCESS);
|
||||
ERR("eglChooseConfig failed with error %x", err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 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(disp, egl_cfg, surface_attrs);
|
||||
if (!egl_sfc)
|
||||
{
|
||||
int err = eglGetError();
|
||||
glsym_evas_gl_common_error_set(data, err - EGL_SUCCESS);
|
||||
ERR("eglCreatePbufferSurface failed with error %x", err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return egl_sfc;
|
||||
#else
|
||||
GLXPbuffer pbuf;
|
||||
GLXFBConfig *cfgs;
|
||||
int config_attrs[20];
|
||||
int surface_attrs[20];
|
||||
int ncfg = 0, i;
|
||||
|
||||
// TODO: Check all required config attributes
|
||||
|
||||
#ifndef GLX_VISUAL_ID
|
||||
# define GLX_VISUAL_ID 0x800b
|
||||
#endif
|
||||
|
||||
i = 0;
|
||||
if (sfc->pbuffer.color_fmt != EVAS_GL_NO_FBO)
|
||||
{
|
||||
config_attrs[i++] = GLX_BUFFER_SIZE;
|
||||
if (sfc->pbuffer.color_fmt == EVAS_GL_RGBA_8888)
|
||||
{
|
||||
config_attrs[i++] = 32;
|
||||
//config_attrs[i++] = GLX_BIND_TO_TEXTURE_RGBA_EXT;
|
||||
//config_attrs[i++] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
config_attrs[i++] = 24;
|
||||
//config_attrs[i++] = GLX_BIND_TO_TEXTURE_RGB_EXT;
|
||||
//config_attrs[i++] = 1;
|
||||
}
|
||||
}
|
||||
if (sfc->depth_fmt)
|
||||
{
|
||||
config_attrs[i++] = GLX_DEPTH_SIZE;
|
||||
config_attrs[i++] = 24; // FIXME: This should depend on the requested bits
|
||||
}
|
||||
if (sfc->stencil_fmt)
|
||||
{
|
||||
config_attrs[i++] = GLX_STENCIL_SIZE;
|
||||
config_attrs[i++] = 8; // FIXME: This should depend on the requested bits
|
||||
}
|
||||
//config_attrs[i++] = GLX_VISUAL_ID;
|
||||
//config_attrs[i++] = XVisualIDFromVisual(vis);
|
||||
config_attrs[i++] = 0;
|
||||
|
||||
cfgs = glXChooseFBConfig(re->software.ob->disp, re->software.ob->screen,
|
||||
config_attrs, &ncfg);
|
||||
if (!cfgs || !ncfg)
|
||||
{
|
||||
ERR("GLX failed to find a valid config for the pbuffer");
|
||||
if (cfgs) XFree(cfgs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
surface_attrs[i++] = GLX_LARGEST_PBUFFER;
|
||||
surface_attrs[i++] = 0;
|
||||
surface_attrs[i++] = GLX_PBUFFER_WIDTH;
|
||||
surface_attrs[i++] = sfc->w;
|
||||
surface_attrs[i++] = GLX_PBUFFER_HEIGHT;
|
||||
surface_attrs[i++] = sfc->h;
|
||||
surface_attrs[i++] = 0;
|
||||
pbuf = glXCreatePbuffer(re->software.ob->disp, cfgs[0], surface_attrs);
|
||||
if (cfgs) XFree(cfgs);
|
||||
|
||||
if (!pbuf)
|
||||
{
|
||||
ERR("GLX failed to create a pbuffer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (void*)(intptr_t)pbuf;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
evgl_eng_pbuffer_surface_destroy(void *data, void *surface)
|
||||
{
|
||||
/* EVGLINIT(re, 0); */
|
||||
if (!data)
|
||||
{
|
||||
ERR("Invalid Render Engine Data!");
|
||||
glsym_evas_gl_common_error_set(NULL, EVAS_GL_NOT_INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!surface)
|
||||
{
|
||||
ERR("Invalid surface.");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_SURFACE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef GL_GLES
|
||||
Render_Engine *re = data;
|
||||
|
||||
eglDestroySurface(eng_get_ob(re)->egl_disp, (EGLSurface)surface);
|
||||
#else
|
||||
Render_Engine_GL_Generic *re = data;
|
||||
GLXPbuffer pbuf = (GLXPbuffer)(intptr_t) surface;
|
||||
|
||||
glXDestroyPbuffer(re->software.ob->disp, pbuf);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 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 *)data;
|
||||
Pixmap px;
|
||||
|
||||
if (!re || !evgl_sfc || !cfg)
|
||||
{
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cfg->gles_version != EVAS_GL_GLES_1_X)
|
||||
{
|
||||
ERR("Inconsistent parameters, not creating any surface!");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FIXME: Check the depth of the buffer!
|
||||
px = XCreatePixmap(eng_get_ob(re)->disp, eng_get_ob(re)->win, w, h,
|
||||
XDefaultDepth(eng_get_ob(re)->disp, eng_get_ob(re)->screen));
|
||||
if (!px)
|
||||
{
|
||||
ERR("Failed to create XPixmap!");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_ALLOC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef GL_GLES
|
||||
EGLSurface egl_sfc;
|
||||
|
||||
egl_sfc = eglCreatePixmapSurface(eng_get_ob(re)->egl_disp, eng_get_ob(re)->egl_config, px, NULL);
|
||||
if (!egl_sfc)
|
||||
{
|
||||
int err = eglGetError();
|
||||
ERR("eglCreatePixmapSurface failed with error: %x", err);
|
||||
glsym_evas_gl_common_error_set(data, err - EGL_SUCCESS);
|
||||
XFreePixmap(eng_get_ob(re)->disp, px);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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 = eng_get_ob(re)->info->info.visual; // FIXME: Check this!
|
||||
return evgl_sfc;
|
||||
|
||||
#else
|
||||
evgl_sfc->gles1_indirect = EINA_TRUE;
|
||||
evgl_sfc->xpixmap = EINA_TRUE;
|
||||
evgl_sfc->gles1_sfc_native = (void *)(intptr_t) px;
|
||||
evgl_sfc->gles1_sfc = (void *)(intptr_t) px;
|
||||
evgl_sfc->gles1_sfc_visual = eng_get_ob(re)->info->info.visual; // FIXME: Check this!
|
||||
return evgl_sfc;
|
||||
#endif
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
Render_Engine *re = (Render_Engine *)data;
|
||||
|
||||
if (!re)
|
||||
{
|
||||
ERR("Invalid Render Engine Data!");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_NOT_INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef GL_GLES
|
||||
if ((!evgl_sfc) || (!evgl_sfc->gles1_sfc))
|
||||
{
|
||||
ERR("Invalid surface.");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_SURFACE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
eglDestroySurface(eng_get_ob(re)->egl_disp, (EGLSurface)evgl_sfc->gles1_sfc);
|
||||
#endif
|
||||
|
||||
if (!evgl_sfc->gles1_sfc_native)
|
||||
{
|
||||
ERR("Inconsistent parameters, not freeing XPixmap for gles1 surface!");
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_BAD_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
XFreePixmap(eng_get_ob(re)->disp, (Pixmap)evgl_sfc->gles1_sfc_native);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const EVGL_Interface evgl_funcs =
|
||||
{
|
||||
evgl_eng_display_get,
|
||||
|
@ -591,7 +967,11 @@ static const EVGL_Interface evgl_funcs =
|
|||
evgl_eng_make_current,
|
||||
evgl_eng_proc_address_get,
|
||||
evgl_eng_string_get,
|
||||
evgl_eng_rotation_angle_get
|
||||
evgl_eng_rotation_angle_get,
|
||||
evgl_eng_pbuffer_surface_create,
|
||||
evgl_eng_pbuffer_surface_destroy,
|
||||
evgl_eng_gles1_surface_create,
|
||||
evgl_eng_gles1_surface_destroy,
|
||||
};
|
||||
|
||||
//----------------------------------------------------------//
|
||||
|
@ -630,6 +1010,9 @@ gl_symbols(void)
|
|||
LINK2GENERIC(evas_gl_preload_shutdown);
|
||||
LINK2GENERIC(evgl_engine_shutdown);
|
||||
LINK2GENERIC(evas_gl_symbols);
|
||||
LINK2GENERIC(evas_gl_common_error_get);
|
||||
LINK2GENERIC(evas_gl_common_error_set);
|
||||
LINK2GENERIC(evas_gl_common_current_context_get);
|
||||
|
||||
#ifdef GL_GLES
|
||||
#define FINDSYM(dst, sym, typ) \
|
||||
|
@ -916,23 +1299,6 @@ eng_setup(Evas *eo_e, void *in)
|
|||
}
|
||||
}
|
||||
|
||||
if (safe_native == -1)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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"))
|
||||
|
@ -1240,6 +1606,52 @@ eng_output_dump(void *data)
|
|||
_re_winfree(re);
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_gl_current_context_get(void *data EINA_UNUSED)
|
||||
{
|
||||
EVGL_Context *ctx;
|
||||
|
||||
ctx = glsym_evas_gl_common_current_context_get();
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
#ifdef GL_GLES
|
||||
if (eglGetCurrentContext() == (ctx->context))
|
||||
return ctx;
|
||||
else
|
||||
return NULL;
|
||||
#else
|
||||
if (glXGetCurrentContext() == (ctx->context))
|
||||
return ctx;
|
||||
else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
eng_gl_error_get(void *data)
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((err = glsym_evas_gl_common_error_get(data)) != EVAS_GL_SUCCESS)
|
||||
goto end;
|
||||
|
||||
#ifdef GL_GLES
|
||||
err = eglGetError() - EGL_SUCCESS;
|
||||
#else
|
||||
Render_Engine *re = data;
|
||||
|
||||
if (!eng_get_ob(re)->win)
|
||||
err = EVAS_GL_BAD_DISPLAY;
|
||||
else if (!eng_get_ob(re)->info)
|
||||
err = EVAS_GL_BAD_SURFACE;
|
||||
#endif
|
||||
|
||||
end:
|
||||
glsym_evas_gl_common_error_set(data, EVAS_GL_SUCCESS);
|
||||
return err;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
@ -1357,15 +1769,19 @@ _native_free_cb(void *data, void *image)
|
|||
#ifdef GL_GLES
|
||||
if (n->egl_surface)
|
||||
{
|
||||
if (glsym_eglDestroyImage)
|
||||
{
|
||||
glsym_eglDestroyImage(eng_get_ob(re)->egl_disp,
|
||||
n->egl_surface);
|
||||
if (eglGetError() != EGL_SUCCESS)
|
||||
ERR("eglDestroyImage() failed.");
|
||||
}
|
||||
else
|
||||
ERR("Try eglDestroyImage on EGL with no support");
|
||||
int err;
|
||||
if (glsym_eglDestroyImage)
|
||||
{
|
||||
glsym_eglDestroyImage(eng_get_ob(re)->egl_disp,
|
||||
n->egl_surface);
|
||||
if ((err = eglGetError()) != EGL_SUCCESS)
|
||||
{
|
||||
ERR("eglDestroyImage() failed.");
|
||||
glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
|
||||
}
|
||||
}
|
||||
else
|
||||
ERR("Try eglDestroyImage on EGL with no support");
|
||||
}
|
||||
#else
|
||||
# ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
|
||||
|
@ -1549,7 +1965,12 @@ eng_image_native_set(void *data, void *image, void *native)
|
|||
|
||||
if (!eglChooseConfig(eng_get_ob(re)->egl_disp, config_attrs,
|
||||
&egl_config, 1, &num_config))
|
||||
ERR("eglChooseConfig() failed for pixmap 0x%x, num_config = %i", (unsigned int)pm, num_config);
|
||||
{
|
||||
int err = eglGetError();
|
||||
ERR("eglChooseConfig() failed for pixmap 0x%x, num_config = %i with error %d",
|
||||
(unsigned int)pm, num_config, err);
|
||||
glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
int val;
|
||||
|
@ -1875,6 +2296,10 @@ module_open(Evas_Module *em)
|
|||
|
||||
ORD(image_native_set);
|
||||
|
||||
ORD(gl_error_get);
|
||||
// gl_current_surface_get is in gl generic
|
||||
ORD(gl_current_context_get);
|
||||
|
||||
gl_symbols();
|
||||
|
||||
/* now advertise out own api */
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
#include "evas_engine.h"
|
||||
|
||||
static Outbuf *_evas_gl_x11_window = NULL;
|
||||
static Eina_TLS _outbuf_key = 0;
|
||||
static Eina_TLS _context_key = 0;
|
||||
|
||||
#ifdef GL_GLES
|
||||
static EGLContext context = EGL_NO_CONTEXT;
|
||||
typedef EGLContext GLContext;
|
||||
#else
|
||||
// FIXME: this will only work for 1 display connection (glx land can have > 1)
|
||||
static GLXContext context = 0;
|
||||
static GLXContext rgba_context = 0;
|
||||
typedef GLXContext GLContext;
|
||||
static Eina_TLS _rgba_context_key = 0;
|
||||
static GLXFBConfig fbconf = 0;
|
||||
static GLXFBConfig rgba_fbconf = 0;
|
||||
#endif
|
||||
|
@ -21,6 +22,80 @@ static Colormap _evas_gl_x11_cmap = 0;
|
|||
static Colormap _evas_gl_x11_rgba_cmap = 0;
|
||||
|
||||
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(&_outbuf_key))
|
||||
goto error;
|
||||
if (!eina_tls_new(&_context_key))
|
||||
goto error;
|
||||
|
||||
eina_tls_set(_outbuf_key, NULL);
|
||||
eina_tls_set(_context_key, NULL);
|
||||
|
||||
#ifndef GL_GLES
|
||||
if (!eina_tls_new(&_rgba_context_key))
|
||||
goto error;
|
||||
eina_tls_set(_rgba_context_key, NULL);
|
||||
#endif
|
||||
|
||||
initted = EINA_TRUE;
|
||||
return EINA_TRUE;
|
||||
|
||||
error:
|
||||
ERR("Could not create TLS key!");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static inline Outbuf *
|
||||
_tls_outbuf_get(void)
|
||||
{
|
||||
if (!initted) eng_init();
|
||||
return eina_tls_get(_outbuf_key);
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
_tls_outbuf_set(Outbuf *xwin)
|
||||
{
|
||||
if (!initted) eng_init();
|
||||
return eina_tls_set(_outbuf_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);
|
||||
}
|
||||
|
||||
#ifndef GL_GLES
|
||||
static inline GLXContext
|
||||
_tls_rgba_context_get(void)
|
||||
{
|
||||
if (!initted) eng_init();
|
||||
return eina_tls_get(_rgba_context_key);
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
_tls_rgba_context_set(GLXContext ctx)
|
||||
{
|
||||
if (!initted) eng_init();
|
||||
return eina_tls_set(_rgba_context_key, ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
Outbuf *
|
||||
eng_window_new(Evas_Engine_Info_GL_X11 *info,
|
||||
|
@ -38,11 +113,16 @@ eng_window_new(Evas_Engine_Info_GL_X11 *info,
|
|||
Render_Engine_Swap_Mode swap_mode)
|
||||
{
|
||||
Outbuf *gw;
|
||||
GLContext context;
|
||||
#ifdef GL_GLES
|
||||
int context_attrs[3];
|
||||
int config_attrs[40];
|
||||
int major_version, minor_version;
|
||||
int num_config, n = 0;
|
||||
#else
|
||||
# ifdef NEWGL
|
||||
GLXContext rgbactx;
|
||||
# endif
|
||||
#endif
|
||||
const GLubyte *vendor, *renderer, *version;
|
||||
int blacklist = 0;
|
||||
|
@ -140,6 +220,7 @@ eng_window_new(Evas_Engine_Info_GL_X11 *info,
|
|||
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)
|
||||
|
@ -148,7 +229,8 @@ eng_window_new(Evas_Engine_Info_GL_X11 *info,
|
|||
eng_window_free(gw);
|
||||
return NULL;
|
||||
}
|
||||
if (context == EGL_NO_CONTEXT) context = gw->egl_context[0];
|
||||
if (context == EGL_NO_CONTEXT)
|
||||
_tls_context_set(gw->egl_context[0]);
|
||||
|
||||
if (eglMakeCurrent(gw->egl_disp,
|
||||
gw->egl_surface[0],
|
||||
|
@ -193,6 +275,7 @@ eng_window_new(Evas_Engine_Info_GL_X11 *info,
|
|||
}
|
||||
// GLX
|
||||
#else
|
||||
context = _tls_context_get();
|
||||
if (!context)
|
||||
{
|
||||
#ifdef NEWGL
|
||||
|
@ -210,18 +293,21 @@ eng_window_new(Evas_Engine_Info_GL_X11 *info,
|
|||
else
|
||||
context = glXCreateContext(gw->disp, gw->visualinfo, NULL, GL_TRUE);
|
||||
#endif
|
||||
_tls_context_set(context);
|
||||
}
|
||||
#ifdef NEWGL
|
||||
if ((gw->alpha) && (!rgba_context))
|
||||
rgbactx = _tls_rgba_context_get();
|
||||
if ((gw->alpha) && (!rgbactx))
|
||||
{
|
||||
if (indirect)
|
||||
rgba_context = glXCreateNewContext(gw->disp, rgba_fbconf,
|
||||
GLX_RGBA_TYPE, context,
|
||||
GL_FALSE);
|
||||
rgbactx = glXCreateNewContext(gw->disp, rgba_fbconf,
|
||||
GLX_RGBA_TYPE, context,
|
||||
GL_FALSE);
|
||||
else
|
||||
rgba_context = glXCreateNewContext(gw->disp, rgba_fbconf,
|
||||
GLX_RGBA_TYPE, context,
|
||||
GL_TRUE);
|
||||
rgbactx = glXCreateNewContext(gw->disp, rgba_fbconf,
|
||||
GLX_RGBA_TYPE, context,
|
||||
GL_TRUE);
|
||||
_tls_rgba_context_set(rgbactx);
|
||||
}
|
||||
if (gw->alpha)
|
||||
gw->glxwin = glXCreateWindow(gw->disp, rgba_fbconf, gw->win, NULL);
|
||||
|
@ -234,7 +320,7 @@ eng_window_new(Evas_Engine_Info_GL_X11 *info,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (gw->alpha) gw->context = rgba_context;
|
||||
if (gw->alpha) gw->context = rgbactx;
|
||||
else gw->context = context;
|
||||
#else
|
||||
gw->context = context;
|
||||
|
@ -404,10 +490,16 @@ eng_window_new(Evas_Engine_Info_GL_X11 *info,
|
|||
void
|
||||
eng_window_free(Outbuf *gw)
|
||||
{
|
||||
Outbuf *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_outbuf_get();
|
||||
|
||||
if (gw == xwin) _tls_outbuf_set(NULL);
|
||||
if (gw->gl_context)
|
||||
{
|
||||
ref = gw->gl_context->references - 1;
|
||||
|
@ -417,6 +509,8 @@ eng_window_free(Outbuf *gw)
|
|||
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]);
|
||||
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)
|
||||
|
@ -424,7 +518,7 @@ eng_window_free(Outbuf *gw)
|
|||
if (context) eglDestroyContext(gw->egl_disp, context);
|
||||
eglTerminate(gw->egl_disp);
|
||||
eglReleaseThread();
|
||||
context = EGL_NO_CONTEXT;
|
||||
_tls_context_set(EGL_NO_CONTEXT);
|
||||
}
|
||||
#else
|
||||
if (gw->glxwin)
|
||||
|
@ -434,15 +528,16 @@ eng_window_free(Outbuf *gw)
|
|||
}
|
||||
if (ref == 0)
|
||||
{
|
||||
GLXContext rgbactx = _tls_rgba_context_get();
|
||||
if (!gw->glxwin)
|
||||
{
|
||||
if (glXGetCurrentContext() == gw->context)
|
||||
glXMakeCurrent(gw->disp, 0, NULL);
|
||||
}
|
||||
if (context) glXDestroyContext(gw->disp, context);
|
||||
if (rgba_context) glXDestroyContext(gw->disp, rgba_context);
|
||||
context = 0;
|
||||
rgba_context = 0;
|
||||
if (rgbactx) glXDestroyContext(gw->disp, rgbactx);
|
||||
_tls_context_set(0);
|
||||
_tls_rgba_context_set(0);
|
||||
fbconf = 0;
|
||||
rgba_fbconf = 0;
|
||||
}
|
||||
|
@ -504,29 +599,43 @@ void
|
|||
eng_window_use(Outbuf *gw)
|
||||
{
|
||||
Eina_Bool force_use = EINA_FALSE;
|
||||
Outbuf *xwin;
|
||||
|
||||
xwin = _tls_outbuf_get();
|
||||
|
||||
glsym_evas_gl_preload_render_lock(eng_window_make_current, gw);
|
||||
#ifdef GL_GLES
|
||||
if (_evas_gl_x11_window)
|
||||
if (xwin)
|
||||
{
|
||||
if (eglGetCurrentContext() != _evas_gl_x11_window->egl_context[0])
|
||||
force_use = EINA_TRUE;
|
||||
if ((eglGetCurrentDisplay() !=
|
||||
xwin->egl_disp) ||
|
||||
(eglGetCurrentContext() !=
|
||||
xwin->egl_context[0])
|
||||
#if 0
|
||||
// FIXME: Figure out what that offscreen thing was about...
|
||||
|| (eglGetCurrentSurface(EGL_READ) !=
|
||||
xwin->egl_surface[xwin->offscreen])
|
||||
|| (eglGetCurrentSurface(EGL_DRAW) !=
|
||||
xwin->egl_surface[xwin->offscreen])
|
||||
#endif
|
||||
)
|
||||
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)
|
||||
{
|
||||
glsym_evas_gl_common_context_use(_evas_gl_x11_window->gl_context);
|
||||
glsym_evas_gl_common_context_flush(_evas_gl_x11_window->gl_context);
|
||||
glsym_evas_gl_common_context_use(xwin->gl_context);
|
||||
glsym_evas_gl_common_context_flush(xwin->gl_context);
|
||||
}
|
||||
_evas_gl_x11_window = gw;
|
||||
_tls_outbuf_set(gw);
|
||||
if (gw)
|
||||
{
|
||||
// EGL / GLES
|
||||
|
@ -571,16 +680,23 @@ eng_window_unsurf(Outbuf *gw)
|
|||
if (!getenv("EVAS_GL_WIN_RESURF")) return;
|
||||
if (getenv("EVAS_GL_INFO"))
|
||||
printf("unsurf %p\n", gw);
|
||||
|
||||
#ifdef GL_GLES
|
||||
if (_evas_gl_x11_window)
|
||||
glsym_evas_gl_common_context_flush(_evas_gl_x11_window->gl_context);
|
||||
if (_evas_gl_x11_window == gw)
|
||||
Outbuf *xwin;
|
||||
|
||||
xwin = _tls_outbuf_get();
|
||||
if (xwin)
|
||||
glsym_evas_gl_common_context_flush(xwin->gl_context);
|
||||
if (xwin == gw)
|
||||
{
|
||||
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_outbuf_set(NULL);
|
||||
}
|
||||
#else
|
||||
if (gw->glxwin)
|
||||
|
@ -1059,19 +1175,6 @@ eng_outbuf_push_updated_region(Outbuf *ob, RGBA_Image *update EINA_UNUSED,
|
|||
if (!_re_wincheck(ob)) return;
|
||||
ob->draw.drew = 1;
|
||||
glsym_evas_gl_common_context_flush(ob->gl_context);
|
||||
#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
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -116,6 +116,10 @@ static void *gl_lib_handle;
|
|||
static int gl_lib_is_gles = 0;
|
||||
static Evas_GL_API gl_funcs;
|
||||
|
||||
static Eina_Bool _tls_init = EINA_FALSE;
|
||||
static Eina_TLS gl_current_ctx_key = 0;
|
||||
static Eina_TLS gl_current_sfc_key = 0;
|
||||
|
||||
//------------------------------------------------------//
|
||||
// OSMesa APIS...
|
||||
static OSMesaContext (*_sym_OSMesaCreateContextExt) (GLenum format, GLint depthBits, GLint stencilBits, GLint accumBits, OSMesaContext sharelist) = NULL;
|
||||
|
@ -2263,7 +2267,25 @@ eng_image_load_error_get(void *data EINA_UNUSED, void *image)
|
|||
return im->cache_entry.load_error;
|
||||
}
|
||||
|
||||
|
||||
//------------ Evas GL engine code ---------------//
|
||||
#ifdef EVAS_GL
|
||||
static inline int
|
||||
_tls_check(void)
|
||||
{
|
||||
// note: this is not thread safe...
|
||||
if (!_tls_init)
|
||||
{
|
||||
if (!eina_tls_new(&gl_current_ctx_key)) return 0;
|
||||
if (!eina_tls_new(&gl_current_sfc_key)) return 0;
|
||||
eina_tls_set(gl_current_ctx_key, NULL);
|
||||
eina_tls_set(gl_current_sfc_key, NULL);
|
||||
}
|
||||
_tls_init = EINA_TRUE;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *
|
||||
eng_gl_surface_create(void *data EINA_UNUSED, void *config, int w, int h)
|
||||
{
|
||||
|
@ -2370,6 +2392,10 @@ eng_gl_surface_destroy(void *data EINA_UNUSED, void *surface)
|
|||
|
||||
if (!sfc) return 0;
|
||||
|
||||
_tls_check();
|
||||
if (sfc == eina_tls_get(gl_current_sfc_key))
|
||||
eina_tls_set(gl_current_sfc_key, NULL);
|
||||
|
||||
if (sfc->buffer) free(sfc->buffer);
|
||||
|
||||
free(sfc);
|
||||
|
@ -2384,12 +2410,19 @@ eng_gl_surface_destroy(void *data EINA_UNUSED, void *surface)
|
|||
}
|
||||
|
||||
static void *
|
||||
eng_gl_context_create(void *data EINA_UNUSED, void *share_context)
|
||||
eng_gl_context_create(void *data EINA_UNUSED, void *share_context,
|
||||
int version)
|
||||
{
|
||||
#ifdef EVAS_GL
|
||||
Render_Engine_GL_Context *ctx;
|
||||
Render_Engine_GL_Context *share_ctx;
|
||||
|
||||
if (version != EVAS_GL_GLES_2_X)
|
||||
{
|
||||
ERR("This engine only supports OpenGL-ES 2.0 contexts for now!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx = calloc(1, sizeof(Render_Engine_GL_Context));
|
||||
|
||||
if (!ctx) return NULL;
|
||||
|
@ -2432,6 +2465,10 @@ eng_gl_context_destroy(void *data EINA_UNUSED, void *context)
|
|||
|
||||
if (!ctx) return 0;
|
||||
|
||||
_tls_check();
|
||||
if (ctx == eina_tls_get(gl_current_ctx_key))
|
||||
eina_tls_set(gl_current_ctx_key, NULL);
|
||||
|
||||
_sym_OSMesaDestroyContext(ctx->context);
|
||||
|
||||
free(ctx);
|
||||
|
@ -2456,11 +2493,15 @@ eng_gl_make_current(void *data EINA_UNUSED, void *surface, void *context)
|
|||
sfc = (Render_Engine_GL_Surface*)surface;
|
||||
ctx = (Render_Engine_GL_Context*)context;
|
||||
|
||||
_tls_check();
|
||||
|
||||
// Unset surface/context
|
||||
if ((!sfc) || (!ctx))
|
||||
{
|
||||
if (ctx) ctx->current_sfc = NULL;
|
||||
if (sfc) sfc->current_ctx = NULL;
|
||||
eina_tls_set(gl_current_ctx_key, NULL);
|
||||
eina_tls_set(gl_current_sfc_key, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2480,6 +2521,8 @@ eng_gl_make_current(void *data EINA_UNUSED, void *surface, void *context)
|
|||
if (!ctx->context)
|
||||
{
|
||||
ERR("Error initializing context.");
|
||||
eina_tls_set(gl_current_ctx_key, NULL);
|
||||
eina_tls_set(gl_current_sfc_key, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2494,6 +2537,8 @@ eng_gl_make_current(void *data EINA_UNUSED, void *surface, void *context)
|
|||
if (ret == GL_FALSE)
|
||||
{
|
||||
ERR("Error doing MakeCurrent.");
|
||||
eina_tls_set(gl_current_ctx_key, NULL);
|
||||
eina_tls_set(gl_current_sfc_key, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2502,6 +2547,8 @@ eng_gl_make_current(void *data EINA_UNUSED, void *surface, void *context)
|
|||
// Set the current surface/context
|
||||
ctx->current_sfc = sfc;
|
||||
sfc->current_ctx = ctx;
|
||||
eina_tls_set(gl_current_ctx_key, ctx);
|
||||
eina_tls_set(gl_current_sfc_key, sfc);
|
||||
|
||||
return 1;
|
||||
#else
|
||||
|
@ -2556,8 +2603,11 @@ eng_gl_native_surface_get(void *data EINA_UNUSED, void *surface, void *native_su
|
|||
|
||||
|
||||
static void *
|
||||
eng_gl_api_get(void *data EINA_UNUSED)
|
||||
eng_gl_api_get(void *data EINA_UNUSED, int version)
|
||||
{
|
||||
if (version != EVAS_GL_GLES_2_X)
|
||||
return NULL;
|
||||
|
||||
#ifdef EVAS_GL
|
||||
return &gl_funcs;
|
||||
#else
|
||||
|
@ -2565,6 +2615,39 @@ eng_gl_api_get(void *data EINA_UNUSED)
|
|||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
eng_gl_error_get(void *data)
|
||||
{
|
||||
Render_Engine_Software_Generic *re = data;
|
||||
|
||||
// TODO: Track EGL-like errors in the software engines
|
||||
|
||||
if (!re->ob)
|
||||
return EVAS_GL_BAD_DISPLAY;
|
||||
|
||||
return EVAS_GL_SUCCESS;
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_gl_current_context_get(void *data EINA_UNUSED)
|
||||
{
|
||||
_tls_check();
|
||||
return eina_tls_get(gl_current_ctx_key);
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_gl_current_surface_get(void *data EINA_UNUSED)
|
||||
{
|
||||
_tls_check();
|
||||
return eina_tls_get(gl_current_sfc_key);
|
||||
}
|
||||
|
||||
static int
|
||||
eng_gl_rotation_angle_get(void *data EINA_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------//
|
||||
|
||||
/* The following function require that any engine
|
||||
|
@ -2989,6 +3072,7 @@ static Evas_Func func =
|
|||
eng_font_text_props_info_create,
|
||||
eng_font_right_inset_get,
|
||||
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
|
||||
|
@ -3002,6 +3086,11 @@ static Evas_Func func =
|
|||
NULL, // need software mesa for gl rendering <- gl_surface_lock
|
||||
NULL, // need software mesa for gl rendering <- gl_surface_read_pixels
|
||||
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
|
||||
eng_image_load_error_get,
|
||||
eng_font_run_font_end_get,
|
||||
eng_image_animated_get,
|
||||
|
@ -3971,6 +4060,9 @@ static int
|
|||
gl_lib_init(void)
|
||||
{
|
||||
#ifdef EVAS_GL
|
||||
// Current ctx & sfc stuff
|
||||
if (!_tls_check()) return 0;
|
||||
|
||||
// dlopen OSMesa
|
||||
gl_lib_handle = dlopen("libOSMesa.so.9", RTLD_NOW);
|
||||
if (!gl_lib_handle) gl_lib_handle = dlopen("libOSMesa.so.8", RTLD_NOW);
|
||||
|
@ -4020,6 +4112,10 @@ init_gl(void)
|
|||
ORD(gl_proc_address_get); // FIXME: Need to implement
|
||||
ORD(gl_native_surface_get);
|
||||
ORD(gl_api_get);
|
||||
ORD(gl_error_get);
|
||||
ORD(gl_current_context_get);
|
||||
ORD(gl_current_surface_get);
|
||||
ORD(gl_rotation_angle_get);
|
||||
#undef ORD
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,6 @@ void (*glsym_glEGLImageTargetTexture2DOES) (int a, void *b) = NULL;
|
|||
unsigned int (*glsym_eglSwapBuffersWithDamage) (EGLDisplay a, void *b, const EGLint *d, EGLint c) = NULL;
|
||||
|
||||
/* local variables */
|
||||
static int safe_native = -1;
|
||||
static Eina_Bool initted = EINA_FALSE;
|
||||
static int gl_wins = 0;
|
||||
static Evas_Func func, pfunc;
|
||||
|
@ -324,7 +323,7 @@ evgl_eng_window_surface_destroy(void *data, void *surface)
|
|||
}
|
||||
|
||||
static void *
|
||||
evgl_eng_context_create(void *data, void *ctxt)
|
||||
evgl_eng_context_create(void *data, void *ctxt, int version)
|
||||
{
|
||||
Render_Engine *re;
|
||||
Outbuf *ob;
|
||||
|
@ -334,6 +333,12 @@ evgl_eng_context_create(void *data, void *ctxt)
|
|||
if (!(re = (Render_Engine *)data)) return NULL;
|
||||
if (!(ob = eng_get_ob(re))) return NULL;
|
||||
|
||||
if (version != EVAS_GL_GLES_2_X)
|
||||
{
|
||||
ERR("This engine only supports OpenGL-ES 2.0 contexts for now!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
|
||||
attrs[1] = 2;
|
||||
attrs[2] = EGL_NONE;
|
||||
|
@ -466,7 +471,11 @@ static const EVGL_Interface evgl_funcs =
|
|||
evgl_eng_make_current,
|
||||
evgl_eng_proc_address_get,
|
||||
evgl_eng_string_get,
|
||||
evgl_eng_rotation_angle_get
|
||||
evgl_eng_rotation_angle_get,
|
||||
NULL, // PBuffer
|
||||
NULL, // PBuffer
|
||||
NULL, // OpenGL-ES 1
|
||||
NULL, // OpenGL-ES 1
|
||||
};
|
||||
|
||||
/* engine functions */
|
||||
|
@ -565,23 +574,6 @@ eng_setup(Evas *evas, void *info)
|
|||
}
|
||||
}
|
||||
|
||||
if (safe_native == -1)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(re = epd->engine.data.output))
|
||||
{
|
||||
Render_Engine_Merge_Mode merge = MERGE_BOUNDING;
|
||||
|
|
Loading…
Reference in New Issue