Hi all,

In my earlier post, I've discussed about the issues with getting the

      evas_object_image_native_surface_set(..., Evas_Native_Surface *surf);

function for setting OpenGL output texture.   There was also a disucssion
about how Evas should provide a GL glue layer.  We've discussed two
proposals.
After some discussion, I went ahead with the preferred way and have
implemented the APIs.

The APIs go something like... (in Evas_GL.h)

   EAPI Evas_GL                 *evas_gl_new                      (Evas *e);
   EAPI Evas_GL_Surface    *evas_gl_surface_create      (Evas_GL *evas_gl,
Evas_GL_Config *cfg, int w, int h);
   EAPI Evas_GL_Context    *evas_gl_context_create      (Evas_GL *evas_gl,
Evas_GL_Context *share_ctx);
   EAPI Eina_Bool                 evas_gl_make_current        (Evas_GL
*evas_gl, Evas_GL_Surface *surf, Evas_GL_Context *ctx);
   EAPI Evas_GL_Func         evas_gl_proc_address_get   (Evas_GL *evas_gl,
const char *name);

   EAPI Eina_Bool                 evas_gl_native_surface_get (Evas_GL
*evas_gl, Evas_GL_Surface *surf, Evas_Native_Surface *ns);

I actually have the above APIs running on my machine but
instead of dumping the entire thing, I wanted to get incremental comments
for review.

I'm now attaching Evas_GL.h and evas_gl.c and a Sample program that uses the
APIs.

Your comments would be very much appreciated.  After the initial review,
I'll submit
a RFC for the engine part of the code that I wrote for gl_x11 module.

One issue that I ran into with the above APIs is that Evas_GL_Context is
already used
by the gl_common part of the code in the engine module.  Upon discussing it
with Raster,
the consensus was that it was better to change the internal code since it's
not exposed.
So, in my implementation, I've changed the internal part to
Evas_Engine_GL_Context.
I just wanted to mention that here for now even though it won't show in the
files that i'm
attaching.

thanks!
Sung
#ifndef _EVAS_GL_H
#define _EVAS_GL_H

#include <Evas.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct _Evas_GL               Evas_GL;
typedef struct _Evas_GL_Surface       Evas_GL_Surface;
typedef struct _Evas_GL_Context       Evas_GL_Context;
typedef struct _Evas_GL_Config        Evas_GL_Config;
typedef void*                         Evas_GL_Func;

typedef enum _Evas_GL_Color_Format
{
    EVAS_GL_RGB_8,      // 8 bits per channel
    EVAS_GL_RGBA_8,
    EVAS_GL_RGB_32,     // 32-bits per channel
    EVAS_GL_RGBA_32,
} Evas_GL_Color_Format;

typedef enum _Evas_GL_Depth_Bits
{
    EVAS_GL_DEPTH_BIT_8,
    EVAS_GL_DEPTH_BIT_16,
    EVAS_GL_DEPTH_BIT_24,
    EVAS_GL_DEPTH_BIT_32,
    EVAS_GL_DEPTH_NONE
} Evas_GL_Depth_Bits;

typedef enum _Evas_GL_Stencil_Bits
{
    EVAS_GL_STENCIL_BIT_1,
    EVAS_GL_STENCIL_BIT_2,
    EVAS_GL_STENCIL_BIT_4,
    EVAS_GL_STENCIL_BIT_8,
    EVAS_GL_STENCIL_BIT_16,
    EVAS_GL_STENCIL_NONE
} Evas_GL_Stencil_Bits;

struct _Evas_GL_Config
{
    Evas_GL_Color_Format     color_format;
    Evas_GL_Depth_Bits       depth_bits;
    Evas_GL_Stencil_Bits     stencil_bits;
};

/**
 * @defgroup Evas_GL group for rendering GL on Evas
 *
 * Functions that are used to do GL rendering on Evas.
 *
 * @ingroup Evas_Canvas
 */

   EAPI Evas_GL                 *evas_gl_new                (Evas *e);
   EAPI void                     evas_gl_free               (Evas_GL *evas_gl);
   EAPI Evas_GL_Surface         *evas_gl_surface_create     (Evas_GL *evas_gl, Evas_GL_Config *cfg, int w, int h);
   EAPI void                     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); 
   EAPI void                     evas_gl_context_destroy    (Evas_GL *evas_gl, Evas_GL_Context *ctx); 
   EAPI Eina_Bool                evas_gl_make_current       (Evas_GL *evas_gl, Evas_GL_Surface *surf, Evas_GL_Context *ctx);
   EAPI Evas_GL_Func             evas_gl_proc_address_get   (Evas_GL *evas_gl, const char *name);

   EAPI Eina_Bool                evas_gl_native_surface_get (Evas_GL *evas_gl, Evas_GL_Surface *surf, Evas_Native_Surface *ns);
 
//   EAPI Evas_GL                 *evas_gl_api_get            (Evas *e, Evas_GL_API *glapi) EINA_ARG_NONNULL(1, 2);

#ifdef __cplusplus
}
#endif

#endif
#include "evas_common.h"
#include "evas_private.h"
#include "Evas_GL.h"

struct _Evas_GL
{
   int      magic;
   Evas    *evas;
};

struct _Evas_GL_Context
{
   void    *data;
};

struct _Evas_GL_Surface
{
   void    *data;
};


/**
 * @addtogroup Evas_GL
 * @{
 */

/**
 * Creates a new Evas_GL object and returns a handle for gl rendering on efl.
 *
 * @param e The given evas.
 * @return The created evas_gl object.
 */
EAPI Evas_GL *
evas_gl_new(Evas *e)
{
   Evas_GL *evas_gl;

   evas_gl = calloc(1, sizeof(Evas_GL));
   if (!evas_gl) return NULL;

   evas_gl->magic = MAGIC_EVAS_GL;
   evas_gl->evas = e;

   return evas_gl;
}

/**
 * Frees the created Evas_GL object.
 *
 * @param evas_gl The given Evas_GL object.
 */
EAPI void
evas_gl_free(Evas_GL *evas_gl)
{
   // Magic
   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
   return;
   MAGIC_CHECK_END();

   free(evas_gl);
   evas_gl = NULL;
}

/**
 * Creates and returns new Evas_GL_Surface object for GL Rendering.
 *
 * @param evas_gl The given Evas_GL object.
 * @param config The pixel format and configuration of the rendering surface.
 * @param width The width of the surface.
 * @param height The height of the surface.
 * @return The created GL surface object.
 */
EAPI Evas_GL_Surface *
evas_gl_surface_create(Evas_GL *evas_gl, Evas_GL_Config *config, int width, int height)
{
   Evas_GL_Surface *surf;

   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
   return NULL;
   MAGIC_CHECK_END();

   surf = calloc(1, sizeof(Evas_GL_Surface));

   surf->data = evas_gl->evas->engine.func->gl_surface_create(evas_gl->evas->engine.data.output, config, width, height); 

   if (!surf->data) 
     {
        printf("Error: Failed creating a surface from the engine\n");
        free(surf);
        return NULL;
     }

   return surf;
}

/**
 * Destroys the created Evas GL Surface.
 *
 * @param evas_gl The given Evas_GL object.
 * @param surf The given GL surface object.
 */
EAPI void 
evas_gl_surface_destroy(Evas_GL *evas_gl, Evas_GL_Surface *surf)
{
   // Magic
   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
   return;
   MAGIC_CHECK_END();

   if (!surf)
     {
	ERR("Trying to destroy a NULL surface pointer!\n");
        return;
     }

   // Call Engine's Surface Destroy
   evas_gl->evas->engine.func->gl_surface_destroy(evas_gl->evas->engine.data.output, surf->data);

   free(surf);
   surf = NULL;
}

/**
 * Creates and returns a new Evas GL context object
 *
 * @param evas_gl The given Evas_GL object.
 */
EAPI Evas_GL_Context *
evas_gl_context_create(Evas_GL *evas_gl, Evas_GL_Context *share_ctx)
{
   Evas_GL_Context *ctx;

   // Magic
   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
   return NULL;
   MAGIC_CHECK_END();

   // Allocate a context object
   ctx = calloc(1, sizeof(Evas_GL_Context));
   if (!ctx) 
     {
        printf("Error: Unable to create a Evas_GL_Context object\n");
        return NULL;
     }

   // Call engine->gl_create_context
   if (share_ctx)
     {
        ctx->data = evas_gl->evas->engine.func->gl_context_create(evas_gl->evas->engine.data.output, share_ctx->data); 
     }
   else 
     {
        ctx->data = evas_gl->evas->engine.func->gl_context_create(evas_gl->evas->engine.data.output, NULL); 
     }

   // Set a few variables
   if (!ctx->data) 
     {
        printf("Error: Failed creating a context from the engine\n");
        free(ctx);
        return NULL;
     }

   return ctx;

}

/**
 * Destroys the given Evas GL context object
 *
 * @param evas_gl The given Evas_GL object.
 * @param ctx The given Evas GL context.
 */
EAPI void
evas_gl_context_destroy(Evas_GL *evas_gl, Evas_GL_Context *ctx)
{

   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
   return;
   MAGIC_CHECK_END();

   if (!ctx)
     {
	ERR("Trying to destroy a NULL context pointer!\n");
        return;
     }

   evas_gl->evas->engine.func->gl_context_destroy(evas_gl->evas->engine.data.output, ctx->data); 

   free(ctx);
   ctx = NULL;
}

/**
 * Sets the given context as a current context for the given surface
 *
 * @param evas_gl The given Evas_GL object.
 * @param surf The given Evas GL surface.
 * @param ctx The given Evas GL context.
 */
EAPI Eina_Bool
evas_gl_make_current(Evas_GL *evas_gl, Evas_GL_Surface *surf, Evas_GL_Context *ctx)
{
   Eina_Bool ret;

   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, NULL, NULL); 
   else 
      ret = (Eina_Bool)evas_gl->evas->engine.func->gl_make_current(evas_gl->evas->engine.data.output, surf->data, ctx->data); 
   
   return ret;
}

/**
 * Returns a GL or the Glue Layer's extension function.
 *
 * @param evas_gl The given Evas_GL object.
 * @param name The name of the function to return.
 */
EAPI Evas_GL_Func
evas_gl_proc_address_get(Evas_GL *evas_gl, const char *name)
{
   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
   return EINA_FALSE;
   MAGIC_CHECK_END();

   return (Evas_GL_Func)evas_gl->evas->engine.func->gl_proc_address_get(evas_gl->evas->engine.data.output, name); 
}

/**
 * Fills in the Native Surface information from the given Evas GL surface.
 *
 * @param evas_gl The given Evas_GL object.
 * @param surf The given Evas GL surface to retrieve the Native Surface info from.
 * @param ns The native surface structure that the function fills in.
 */
EAPI Eina_Bool
evas_gl_native_surface_get (Evas_GL *evas_gl, Evas_GL_Surface *surf, Evas_Native_Surface *ns)
{

   MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL);
   return EINA_FALSE;
   MAGIC_CHECK_END();

   return (Eina_Bool)evas_gl->evas->engine.func->gl_native_surface_get(evas_gl->evas->engine.data.output, surf->data, ns); 
}

/**
 * @}
 */


/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
/**
 * Simple Evas_GL example
 *
 */
#include <Ecore_Evas.h>
#include <Ecore.h>
#include <Evas_GL.h>
#include <stdio.h>
#include <GL/gl.h>

#define WIDTH  (512)
#define HEIGHT (512)

static void init_gl(Evas *evas);
static void draw_gl();
static void free_gl();

static Ecore_Evas       *ee;
static Evas_GL          *evasgl;
static Evas_GL_Surface  *sfc;
static Evas_GL_Context  *ctx;

void key_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
    Evas_Event_Key_Down *ev;
    ev = (Evas_Event_Key_Down *)event_info;
    printf("You hit key: %s\n", ev->keyname);

    ecore_main_loop_quit();
}

int main(void)
{
    Evas *canvas;
    Evas_Object *r1;
    Evas_Native_Surface ns;

    ecore_init();
    ecore_evas_init();

    ee = ecore_evas_gl_x11_new(NULL, 0, 0, 0, WIDTH, HEIGHT);
    ecore_evas_title_set(ee, "Evas_GL Sample Program");
    ecore_evas_borderless_set(ee, 0);
    ecore_evas_show(ee);

    canvas = ecore_evas_get(ee);

    // Draw GL
    init_gl(canvas);
    draw_gl();

    // Get the Native_Surface from EvasGL
    evas_gl_native_surface_get(evasgl, sfc, &ns);		

    // EvasImage Object
    r1 = evas_object_image_add(canvas);
    evas_object_image_fill_set(r1, 0, 0, 256, 256);
    evas_object_move(r1, 128, 128);
    evas_object_image_load_size_set(r1, 256, 256);
    evas_object_resize(r1, 256, 256);
    evas_object_image_size_set(r1, 256, 256);
    //evas_object_image_data_set(r1, (void*)data);
    evas_object_image_native_surface_set(r1, &ns);
    evas_object_show(r1);

    evas_object_focus_set(r1, 1);
    evas_object_event_callback_add(r1, EVAS_CALLBACK_KEY_DOWN, key_down, NULL);

    ecore_main_loop_begin();

    free_gl();
    ecore_evas_shutdown();
    ecore_shutdown();

    return 0;
}

static void init_gl(Evas *evas)
{
    Evas_GL_Config config = {EVAS_GL_RGBA_8, 
                             EVAS_GL_DEPTH_NONE, 
                             EVAS_GL_STENCIL_NONE };
    int w, h;

    w = 256; 
    h = 256;

    // Evas GL code...
    evasgl  = evas_gl_new(evas);
    sfc     = evas_gl_surface_create(evasgl, &config, w, h);
    ctx     = evas_gl_context_create(evasgl, NULL);

    evas_gl_make_current(evasgl, sfc, ctx);

    // GL Init Stuff
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, w, 0, h, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glClearColor(0.3,0.3,0.3,1);
    glClear(GL_COLOR_BUFFER_BIT);

}

static void draw_gl()
{
    // Draw a Triangle
    glEnable(GL_BLEND);
    glBegin(GL_TRIANGLES);
    glColor3f(1, 0, 0);
    glVertex3f(20, 20, 0);
    glColor3f(0, 1, 0);
    glVertex3f(236, 20, 0);
    glColor3f(0, 0, 1);
    glVertex3f(128, 236, 0);
    glEnd();

}

static void free_gl()
{
    evas_gl_surface_destroy(evasgl, sfc);
    evas_gl_context_destroy(evasgl, ctx);
    evas_gl_free(evasgl);
}

/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
------------------------------------------------------------------------------
What You Don't Know About Data Connectivity CAN Hurt You
This paper provides an overview of data connectivity, details
its effect on application quality, and explores various alternative
solutions. http://p.sf.net/sfu/progress-d2d
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to