GLView: Add new APIs to match Evas GL

This adds the following new features, based on Evas GL:
- rotation_get
- evas_gl_get
- client-side rotation
- precise stencil and depth buffer selection

The changes follow recent changes in EFL.

Merge branch 'devs/jpeg/evasgl'
This commit is contained in:
Jean-Philippe Andre 2014-10-20 13:37:28 +09:00
commit 01a1d3c0a4
5 changed files with 208 additions and 34 deletions

View File

@ -47,31 +47,23 @@ _elm_glview_elm_widget_on_focus(Eo *obj, Elm_Glview_Data *_pd EINA_UNUSED)
static void
_glview_update_surface(Evas_Object *obj)
{
Evas_Native_Surface ns = { 0 };
ELM_GLVIEW_DATA_GET(obj, sd);
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
if (!sd) return;
if (sd->surface)
{
evas_object_image_native_surface_set
(wd->resize_obj, NULL);
evas_object_image_native_surface_set(wd->resize_obj, NULL);
evas_gl_surface_destroy(sd->evasgl, sd->surface);
sd->surface = NULL;
}
evas_object_image_size_set(wd->resize_obj, sd->w, sd->h);
if (!sd->surface)
{
Evas_Native_Surface ns;
sd->surface = evas_gl_surface_create
(sd->evasgl, sd->config, sd->w, sd->h);
evas_gl_native_surface_get(sd->evasgl, sd->surface, &ns);
evas_object_image_native_surface_set
(wd->resize_obj, &ns);
elm_glview_changed_set(obj);
}
sd->surface = evas_gl_surface_create(sd->evasgl, sd->config, sd->w, sd->h);
evas_gl_native_surface_get(sd->evasgl, sd->surface, &ns);
evas_object_image_native_surface_set(wd->resize_obj, &ns);
elm_glview_changed_set(obj);
}
EOLIAN static void
@ -181,7 +173,7 @@ _set_render_policy_callback(Evas_Object *obj)
}
EOLIAN static void
_elm_glview_evas_object_smart_add(Eo *obj, Elm_Glview_Data *priv)
_elm_glview_evas_object_smart_add(Eo *obj, Elm_Glview_Data *priv EINA_UNUSED)
{
Evas_Object *img;
@ -193,7 +185,11 @@ _elm_glview_evas_object_smart_add(Eo *obj, Elm_Glview_Data *priv)
evas_object_image_size_set(img, 1, 1);
eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
}
static void
_elm_glview_constructor(Eo *obj, Elm_Glview_Data *priv)
{
// Evas_GL
priv->evasgl = evas_gl_new(evas_object_evas_get(obj));
if (!priv->evasgl)
@ -223,15 +219,22 @@ _elm_glview_evas_object_smart_add(Eo *obj, Elm_Glview_Data *priv)
priv->w = 64;
priv->h = 64;
// Set context version
if (!priv->gles_version)
priv->gles_version = EVAS_GL_GLES_2_X;
priv->config->gles_version = priv->gles_version;
// Create Context
priv->context = evas_gl_context_create(priv->evasgl, NULL);
if (priv->gles_version == EVAS_GL_GLES_2_X)
priv->context = evas_gl_context_create(priv->evasgl, NULL);
else
priv->context = evas_gl_context_version_create(priv->evasgl, NULL, priv->gles_version);
if (!priv->context)
{
ERR("Error Creating an Evas_GL Context.\n");
evas_gl_config_free(priv->config);
evas_gl_free(priv->evasgl);
priv->evasgl = NULL;
ELM_SAFE_FREE(priv->config, evas_gl_config_free);
ELM_SAFE_FREE(priv->evasgl, evas_gl_free);
return;
}
}
@ -239,6 +242,8 @@ _elm_glview_evas_object_smart_add(Eo *obj, Elm_Glview_Data *priv)
EOLIAN static void
_elm_glview_evas_object_smart_del(Eo *obj, Elm_Glview_Data *sd)
{
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
// Call delete func if it's registered
if (sd->del_func)
{
@ -248,7 +253,11 @@ _elm_glview_evas_object_smart_del(Eo *obj, Elm_Glview_Data *sd)
ecore_idle_enterer_del(sd->render_idle_enterer);
if (sd->surface) evas_gl_surface_destroy(sd->evasgl, sd->surface);
if (sd->surface)
{
evas_object_image_native_surface_set(wd->resize_obj, NULL);
evas_gl_surface_destroy(sd->evasgl, sd->surface);
}
if (sd->context) evas_gl_context_destroy(sd->evasgl, sd->context);
if (sd->config) evas_gl_config_free(sd->config);
if (sd->evasgl) evas_gl_free(sd->evasgl);
@ -260,14 +269,34 @@ EAPI Evas_Object *
elm_glview_add(Evas_Object *parent)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
Evas_Object *obj = eo_add(MY_CLASS, parent);
Evas_Object *obj = eo_add(MY_CLASS, parent,
elm_obj_glview_version_constructor(EVAS_GL_GLES_2_X));
return obj;
}
EAPI Evas_Object *
elm_glview_version_add(Evas_Object *parent, Evas_GL_Context_Version version)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
Evas_Object *obj = eo_add(MY_CLASS, parent,
elm_obj_glview_version_constructor(version));
return obj;
}
EOLIAN static void
_elm_glview_eo_base_constructor(Eo *obj, Elm_Glview_Data *sd)
_elm_glview_eo_base_constructor(Eo *obj, Elm_Glview_Data *sd EINA_UNUSED)
{
eo_do_super(obj, MY_CLASS, eo_constructor());
}
EOLIAN static void
_elm_glview_version_constructor(Eo *obj, Elm_Glview_Data *sd,
Evas_GL_Context_Version version)
{
sd->gles_version =
((version > 0) && (version <= 3)) ? version : EVAS_GL_GLES_2_X;
_elm_glview_constructor(obj, sd);
eo_do(obj,
evas_obj_type_set(MY_CLASS_NAME_LEGACY),
evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
@ -283,7 +312,7 @@ _elm_glview_eo_base_constructor(Eo *obj, Elm_Glview_Data *sd)
EOLIAN static Evas_GL_API*
_elm_glview_gl_api_get(Eo *obj EINA_UNUSED, Elm_Glview_Data *sd)
{
return evas_gl_api_get(sd->evasgl);
return evas_gl_context_api_get(sd->evasgl, sd->context);
}
EOLIAN static Eina_Bool
@ -295,16 +324,59 @@ _elm_glview_mode_set(Eo *obj, Elm_Glview_Data *sd, Elm_GLView_Mode mode)
if (mode & ELM_GLVIEW_ALPHA) sd->config->color_format = EVAS_GL_RGBA_8888;
else sd->config->color_format = EVAS_GL_RGB_888;
if (mode & ELM_GLVIEW_DEPTH) sd->config->depth_bits = EVAS_GL_DEPTH_BIT_24;
else sd->config->depth_bits = EVAS_GL_DEPTH_NONE;
if (mode & ELM_GLVIEW_DEPTH)
{
const int mask = 7 << 6;
if ((mode & mask) == (ELM_GLVIEW_DEPTH_8 & mask))
sd->config->depth_bits = EVAS_GL_DEPTH_BIT_8;
else if ((mode & mask) == (ELM_GLVIEW_DEPTH_16 & mask))
sd->config->depth_bits = EVAS_GL_DEPTH_BIT_16;
else if ((mode & mask) == (ELM_GLVIEW_DEPTH_24 & mask))
sd->config->depth_bits = EVAS_GL_DEPTH_BIT_24;
else if ((mode & mask) == (ELM_GLVIEW_DEPTH_32 & mask))
sd->config->depth_bits = EVAS_GL_DEPTH_BIT_32;
else
sd->config->depth_bits = EVAS_GL_DEPTH_BIT_24;
}
else
sd->config->depth_bits = EVAS_GL_DEPTH_NONE;
if (mode & ELM_GLVIEW_STENCIL)
sd->config->stencil_bits = EVAS_GL_STENCIL_BIT_8;
else sd->config->stencil_bits = EVAS_GL_STENCIL_NONE;
{
const int mask = 7 << 9;
if ((mode & mask) == (ELM_GLVIEW_STENCIL_1 & mask))
sd->config->stencil_bits = EVAS_GL_STENCIL_BIT_1;
else if ((mode & mask) == (ELM_GLVIEW_STENCIL_1 & mask))
sd->config->stencil_bits = EVAS_GL_STENCIL_BIT_2;
else if ((mode & mask) == (ELM_GLVIEW_STENCIL_4 & mask))
sd->config->stencil_bits = EVAS_GL_STENCIL_BIT_4;
else if ((mode & mask) == (ELM_GLVIEW_STENCIL_8 & mask))
sd->config->stencil_bits = EVAS_GL_STENCIL_BIT_8;
else if ((mode & mask) == (ELM_GLVIEW_STENCIL_16 & mask))
sd->config->stencil_bits = EVAS_GL_STENCIL_BIT_16;
else
sd->config->stencil_bits = EVAS_GL_STENCIL_BIT_8;
}
else
sd->config->stencil_bits = EVAS_GL_STENCIL_NONE;
if (mode & ELM_GLVIEW_MULTISAMPLE_HIGH)
{
if ((mode & ELM_GLVIEW_MULTISAMPLE_HIGH) == ELM_GLVIEW_MULTISAMPLE_LOW)
sd->config->multisample_bits = EVAS_GL_MULTISAMPLE_LOW;
else if ((mode & ELM_GLVIEW_MULTISAMPLE_HIGH) == ELM_GLVIEW_MULTISAMPLE_MED)
sd->config->multisample_bits = EVAS_GL_MULTISAMPLE_MED;
else
sd->config->multisample_bits = EVAS_GL_MULTISAMPLE_HIGH;
}
else
sd->config->multisample_bits = EVAS_GL_MULTISAMPLE_NONE;
sd->config->options_bits = EVAS_GL_OPTIONS_NONE;
if (mode & ELM_GLVIEW_DIRECT)
sd->config->options_bits = EVAS_GL_OPTIONS_DIRECT;
else sd->config->options_bits = EVAS_GL_OPTIONS_NONE;
if (mode & ELM_GLVIEW_CLIENT_SIDE_ROTATION)
sd->config->options_bits |= EVAS_GL_OPTIONS_CLIENT_SIDE_ROTATION;
// Check for Alpha Channel and enable it
if (mode & ELM_GLVIEW_ALPHA)
@ -417,6 +489,18 @@ _elm_glview_changed_set(Eo *obj, Elm_Glview_Data *sd)
ecore_idle_enterer_before_add((Ecore_Task_Cb)_render_cb, obj);
}
EOLIAN static Evas_GL *
_elm_glview_evas_gl_get(Eo *obj EINA_UNUSED, Elm_Glview_Data *sd)
{
return sd->evasgl;
}
EOLIAN static int
_elm_glview_rotation_get(Eo *obj EINA_UNUSED, Elm_Glview_Data *sd)
{
return evas_gl_rotation_get(sd->evasgl);
}
static void
_elm_glview_class_constructor(Eo_Class *klass)
{

View File

@ -1,6 +1,15 @@
class Elm_Glview (Elm_Widget)
{
eo_prefix: elm_obj_glview;
methods {
version_constructor {
/*@ Constructor with context version number. */
legacy: null;
params {
@in Evas_GL_Context_Version version;
}
}
}
properties {
size {
set {
@ -162,6 +171,43 @@ class Elm_Glview (Elm_Widget)
return: Evas_GL_API *;
}
}
evas_gl {
get {
/*@
Get the internal Evas GL attached to this view.
@note The returned Evas_GL must not be destroyed as it is still owned
by the view. But this pointer can be used then to call all the evas_gl_
functions.
@since 1.12
@return The Evas_GL used by this GLView.
@ingroup GLView */
return: Evas_GL *;
}
}
rotation {
get {
/*@
Get the current GL view's rotation when using direct rendering
@return A window rotation in degrees (0, 90, 180 or 270)
@note This rotation can be different from the device orientation. This
rotation value must be used in case of direct rendering and should be
taken into account by the application when setting the internal rotation
matrix for the view.
@see ELM_GLVIEW_CLIENT_SIDE_ROTATION
@since 1.12
@ingroup GLView */
return: int;
}
}
}
implements {
class.constructor;
@ -177,5 +223,7 @@ class Elm_Glview (Elm_Widget)
language,changed;
access,changed;
}
constructors {
.version_constructor;
}
}

View File

@ -1,17 +1,47 @@
typedef void (*Elm_GLView_Func_Cb)(Evas_Object *obj);
/**
* Defines mode of GLView
* @brief Selects the target surface properties
*
* An OR combination of @c Elm_GLView_Mode values should be passed to
* @ref elm_glview_mode_set when setting up a GL widget. These flags will
* specify the properties of the rendering target surface; in particular,
* the mode can request the surface to support alpha, depth and stencil buffers.
*
* @note @c ELM_GLVIEW_CLIENT_SIDE_ROTATION is a special value that indicates
* to EFL that the application will handle the view rotation when the
* device is rotated. This is needed only when the application requests
* direct rendering. Please refer to @ref Evas_GL
* for more information about direct rendering.
*
* @see elm_glview_mode_set
* @see @ref elm_opengl_page
* @ingroup GLView
*/
typedef enum _Elm_GLView_Mode
{
ELM_GLVIEW_NONE = 0,
// 0x1 is reserved for future use
ELM_GLVIEW_ALPHA = (1<<1), /**< Alpha channel enabled rendering mode */
ELM_GLVIEW_DEPTH = (1<<2), /**< Depth buffer enabled rendering mode */
ELM_GLVIEW_STENCIL = (1<<3), /**< Stencil buffer enabled rendering mode */
ELM_GLVIEW_DIRECT = (1<<4) /**< Direct rendering optimization hint */
ELM_GLVIEW_DEPTH = (1<<2), /**< Depth buffer enabled rendering mode (24 bits by default) */
ELM_GLVIEW_STENCIL = (1<<3), /**< Stencil buffer enabled rendering mode (8 bits by default) */
ELM_GLVIEW_DIRECT = (1<<4), /**< Request direct rendering, unless there must be a fallback */
ELM_GLVIEW_CLIENT_SIDE_ROTATION = (1<<5), /**< Client will handle GL view rotation if direct rendering is enabled */
// Depth buffer sizes (3 bits)
ELM_GLVIEW_DEPTH_8 = ELM_GLVIEW_DEPTH | (1 << 6), /**< Request min. 8 bits for the depth buffer */
ELM_GLVIEW_DEPTH_16 = ELM_GLVIEW_DEPTH | (2 << 6), /**< Request min. 16 bits for the depth buffer */
ELM_GLVIEW_DEPTH_24 = ELM_GLVIEW_DEPTH | (3 << 6), /**< Request min. 24 bits for the depth buffer (default) */
ELM_GLVIEW_DEPTH_32 = ELM_GLVIEW_DEPTH | (4 << 6), /**< Request min. 32 bits for the depth buffer */
// Stencil buffer sizes (3 bits)
ELM_GLVIEW_STENCIL_1 = ELM_GLVIEW_STENCIL | (1 << 9), /**< Request min. 1 bits for the stencil buffer */
ELM_GLVIEW_STENCIL_2 = ELM_GLVIEW_STENCIL | (2 << 9), /**< Request min. 2 bits for the stencil buffer */
ELM_GLVIEW_STENCIL_4 = ELM_GLVIEW_STENCIL | (3 << 9), /**< Request min. 4 bits for the stencil buffer */
ELM_GLVIEW_STENCIL_8 = ELM_GLVIEW_STENCIL | (4 << 9), /**< Request min. 8 bits for the stencil buffer (default) */
ELM_GLVIEW_STENCIL_16 = ELM_GLVIEW_STENCIL | (5 << 9), /**< Request min. 16 bits for the stencil buffer */
// MSAA params (2 bits)
ELM_GLVIEW_MULTISAMPLE_LOW = (1 << 12), /**< MSAA with minimum number of samples */
ELM_GLVIEW_MULTISAMPLE_MED = (2 << 12), /**< MSAA with half the number of maximum samples */
ELM_GLVIEW_MULTISAMPLE_HIGH = (3 << 12) /**< MSAA with maximum number of samples */
} Elm_GLView_Mode;
/**

View File

@ -8,4 +8,15 @@
*/
EAPI Evas_Object *elm_glview_add(Evas_Object *parent);
#include "elm_glview.eo.legacy.h"
/**
* Adds a new GLView to the parent, given an OpenGL-ES context version number.
*
* @param[in] parent The parent object
* @param[in] version Requested GL ES version number (default is 2.x, 1.x may also be supported)
* @return The new object or @c NULL if it cannot be created
*
* @since 1.12
*/
EAPI Evas_Object *elm_glview_version_add(Evas_Object *parent, Evas_GL_Context_Version version);
#include "elm_glview.eo.legacy.h"

View File

@ -29,6 +29,7 @@ struct _Elm_Glview_Data
Elm_GLView_Mode mode;
Elm_GLView_Resize_Policy scale_policy;
Elm_GLView_Render_Policy render_policy;
Evas_GL_Context_Version gles_version;
Evas_GL *evasgl;
Evas_GL_Config *config;