Evas GL: implement GLES2/GLES3 wrapper functions

Summary:
I found some bugs in EvasGL with OpenGL ES conformance test.

6 wrapper functions are added for GLES2,
(glDeleteFramebuffers, glFramebufferRenderbuffer
glFramebufferTexture2D, glGetError
glGetFloatv, glGetFramebufferAttachmentParameteriv)

3 wrapper fucntions are added for GLES3.
(glDrawbuffers, glGetStringi, glReadBuffer)

Test Plan:
GLES3 sample app,
EvasGL(OpenGL ES CTS) for 2.0 is passed.
For 3.0, 10 TCs are failed (Total : 2994TCs).

Reviewers: wonsik, spacegrapher, jpeg

Subscribers: cedric, JoogabYun, scholb.kim

Maniphest Tasks: T2621

Differential Revision: https://phab.enlightenment.org/D3301
This commit is contained in:
DaeKwang Ryu 2015-11-11 11:36:42 +09:00 committed by Jean-Philippe Andre
parent 25bcf4c64f
commit 5ccd783069
8 changed files with 1044 additions and 156 deletions

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,12 @@ _EVASGL_FUNCTION_PRIVATE_BEGIN(const GLubyte *, glGetString, (GLenum name), (nam
_EVASGL_FUNCTION_PRIVATE_BEGIN_VOID( glReadPixels, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels), (x, y, width, height, format, type, pixels))
_EVASGL_FUNCTION_PRIVATE_BEGIN_VOID( glScissor, (GLint x, GLint y, GLsizei width, GLsizei height), (x, y, width, height))
_EVASGL_FUNCTION_PRIVATE_BEGIN_VOID( glViewport, (GLint x, GLint y, GLsizei width, GLsizei height), (x, y, width, height))
_EVASGL_FUNCTION_PRIVATE_BEGIN_VOID( glDeleteFramebuffers, (GLsizei n, const GLuint* framebuffers), (n, framebuffers))
_EVASGL_FUNCTION_PRIVATE_BEGIN_VOID( glFramebufferRenderbuffer, (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer), (target, attachment, renderbuffertarget, renderbuffer))
_EVASGL_FUNCTION_PRIVATE_BEGIN_VOID( glFramebufferTexture2D, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level), (target, attachment, textarget, texture, level))
_EVASGL_FUNCTION_PRIVATE_BEGIN(GLenum, glGetError, (void), ())
_EVASGL_FUNCTION_PRIVATE_BEGIN_VOID( glGetFloatv, (GLenum pname, GLfloat* params), (pname, params))
_EVASGL_FUNCTION_PRIVATE_BEGIN_VOID( glGetFramebufferAttachmentParameteriv, (GLenum target, GLenum attachment, GLenum pname, GLint* params), (target, attachment, pname, params))
_EVASGL_FUNCTION_BEGIN_VOID( glActiveTexture, (GLenum texture), (texture))
_EVASGL_FUNCTION_BEGIN_VOID( glAttachShader, (GLuint program, GLuint shader), (program, shader))
@ -39,7 +45,6 @@ _EVASGL_FUNCTION_BEGIN(GLuint, glCreateProgram, (void), ())
_EVASGL_FUNCTION_BEGIN(GLuint, glCreateShader, (GLenum type), (type))
_EVASGL_FUNCTION_BEGIN_VOID( glCullFace, (GLenum mode), (mode))
_EVASGL_FUNCTION_BEGIN_VOID( glDeleteBuffers, (GLsizei n, const GLuint* buffers), (n, buffers))
_EVASGL_FUNCTION_BEGIN_VOID( glDeleteFramebuffers, (GLsizei n, const GLuint* framebuffers), (n, framebuffers))
_EVASGL_FUNCTION_BEGIN_VOID( glDeleteProgram, (GLuint program), (program))
_EVASGL_FUNCTION_BEGIN_VOID( glDeleteRenderbuffers, (GLsizei n, const GLuint* renderbuffers), (n, renderbuffers))
_EVASGL_FUNCTION_BEGIN_VOID( glDeleteShader, (GLuint shader), (shader))
@ -53,8 +58,6 @@ _EVASGL_FUNCTION_BEGIN_VOID( glDrawElements, (GLenum mode, GLsizei count, GLenum
_EVASGL_FUNCTION_BEGIN_VOID( glEnableVertexAttribArray, (GLuint index), (index))
_EVASGL_FUNCTION_BEGIN_VOID( glFinish, (void), ())
_EVASGL_FUNCTION_BEGIN_VOID( glFlush, (void), ())
_EVASGL_FUNCTION_BEGIN_VOID( glFramebufferRenderbuffer, (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer), (target, attachment, renderbuffertarget, renderbuffer))
_EVASGL_FUNCTION_BEGIN_VOID( glFramebufferTexture2D, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level), (target, attachment, textarget, texture, level))
_EVASGL_FUNCTION_BEGIN_VOID( glFrontFace, (GLenum mode), (mode))
_EVASGL_FUNCTION_BEGIN_VOID( glGenBuffers, (GLsizei n, GLuint* buffers), (n, buffers))
_EVASGL_FUNCTION_BEGIN_VOID( glGenerateMipmap, (GLenum target), (target))
@ -67,9 +70,6 @@ _EVASGL_FUNCTION_BEGIN_VOID( glGetAttachedShaders, (GLuint program, GLsizei maxc
_EVASGL_FUNCTION_BEGIN(int, glGetAttribLocation, (GLuint program, const char* name), (program, name))
_EVASGL_FUNCTION_BEGIN_VOID( glGetBooleanv, (GLenum pname, GLboolean* params), (pname, params))
_EVASGL_FUNCTION_BEGIN_VOID( glGetBufferParameteriv, (GLenum target, GLenum pname, GLint* params), (target, pname, params))
_EVASGL_FUNCTION_BEGIN(GLenum, glGetError, (void), ())
_EVASGL_FUNCTION_BEGIN_VOID( glGetFloatv, (GLenum pname, GLfloat* params), (pname, params))
_EVASGL_FUNCTION_BEGIN_VOID( glGetFramebufferAttachmentParameteriv, (GLenum target, GLenum attachment, GLenum pname, GLint* params), (target, attachment, pname, params))
_EVASGL_FUNCTION_BEGIN_VOID( glGetProgramiv, (GLuint program, GLenum pname, GLint* params), (program, pname, params))
_EVASGL_FUNCTION_BEGIN_VOID( glGetProgramInfoLog, (GLuint program, GLsizei bufsize, GLsizei* length, char* infolog), (program, bufsize, length, infolog))
_EVASGL_FUNCTION_BEGIN_VOID( glGetRenderbufferParameteriv, (GLenum target, GLenum pname, GLint* params), (target, pname, params))

View File

@ -19,6 +19,8 @@ static char *_gles1_ext_string_official = NULL;
// list of gles 3.1 exts by official name
static char *_gles3_ext_string = NULL;
static char *_gles3_ext_string_official = NULL;
// indexed pointer list of each extension of gles 3
Eina_Array *_gles3_ext_plist = NULL;
typedef void (*_getproc_fn) (void);
typedef _getproc_fn (*fp_getproc)(const char *);
@ -1236,6 +1238,7 @@ _evgl_api_gles3_ext_init(void *getproc, const char *glueexts)
}
#endif
_gles3_ext_plist = eina_array_new(1);
gles3_funcs = _evgl_api_gles3_internal_get();
if (!gles3_funcs || !gles3_funcs->glGetString)
{
@ -1352,7 +1355,10 @@ _evgl_api_gles3_ext_init(void *getproc, const char *glueexts)
{ \
eina_strbuf_append(sb, name" "); \
if ((strncmp(name, "GL_", 3) == 0) && (strstr(eina_strbuf_string_get(sboff), name) == NULL)) \
eina_strbuf_append(sboff, name" "); \
{ \
eina_strbuf_append(sboff, name" "); \
eina_array_push(_gles3_ext_plist, name); \
} \
}
#define _EVASGL_EXT_DRVNAME(name) \
if (_curext_supported) \
@ -1506,3 +1512,32 @@ evgl_api_ext_string_get(Eina_Bool official, int version)
return (official?_gl_ext_string_official:_gl_ext_string);
}
const char *
evgl_api_ext_stringi_get(GLuint index, int version)
{
if (_evgl_api_ext_status < 1)
{
ERR("EVGL extension is not yet initialized.");
return NULL;
}
if (version == EVAS_GL_GLES_3_X)
{
if (index < evgl_api_ext_num_extensions_get(version))
{
return eina_array_data_get(_gles3_ext_plist, index);
}
}
return NULL;
}
GLuint
evgl_api_ext_num_extensions_get(int version)
{
if (version == EVAS_GL_GLES_3_X)
return eina_array_count_get(_gles3_ext_plist);
return 0;
}

View File

@ -108,6 +108,8 @@ extern void evgl_api_gles1_ext_get(Evas_GL_API *gl_funcs, void *getproc, const c
extern void evgl_api_gles3_ext_get(Evas_GL_API *gl_funcs, void *getproc, const char *glueexts);
extern const char *evgl_api_ext_egl_string_get(void);
extern const char *evgl_api_ext_string_get(Eina_Bool official, int version);
extern const char *evgl_api_ext_stringi_get(GLuint index, int version);
extern GLuint evgl_api_ext_num_extensions_get(int version);
#endif //_EVAS_GL_API_EXT_H

View File

@ -1,3 +1,7 @@
_EVASGL_FUNCTION_PRIVATE_BEGIN_VOID( glDrawBuffers, (GLsizei n, const GLenum *bufs), (n, bufs))
_EVASGL_FUNCTION_PRIVATE_BEGIN(const GLubyte *, glGetStringi, (GLenum name, GLuint index), (name, index))
_EVASGL_FUNCTION_PRIVATE_BEGIN_VOID( glReadBuffer, (GLenum src), (src))
_EVASGL_FUNCTION_BEGIN_VOID( glBeginQuery, (GLenum target, GLuint id), (target, id))
_EVASGL_FUNCTION_BEGIN_VOID( glBeginTransformFeedback, (GLenum primitiveMode), (primitiveMode))
_EVASGL_FUNCTION_BEGIN_VOID( glBindBufferBase, (GLenum target, GLuint index, GLuint buffer), (target, index, buffer))
@ -21,7 +25,6 @@ _EVASGL_FUNCTION_BEGIN_VOID( glDeleteSync, (GLsync sync), (sync))
_EVASGL_FUNCTION_BEGIN_VOID( glDeleteTransformFeedbacks, (GLsizei n, const GLuint *ids), (n, ids))
_EVASGL_FUNCTION_BEGIN_VOID( glDeleteVertexArrays, (GLsizei n, const GLuint *arrays), (n, arrays))
_EVASGL_FUNCTION_BEGIN_VOID( glDrawArraysInstanced, (GLenum mode, GLint first, GLsizei count, GLsizei primcount), (mode, first, count, primcount))
_EVASGL_FUNCTION_BEGIN_VOID( glDrawBuffers, (GLsizei n, const GLenum *bufs), (n, bufs))
_EVASGL_FUNCTION_BEGIN_VOID( glDrawElementsInstanced, (GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei primcount), (mode, count, type, indices, primcount))
_EVASGL_FUNCTION_BEGIN_VOID( glDrawRangeElements, (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices), (mode, start, end, count, type, indices))
_EVASGL_FUNCTION_BEGIN_VOID( glEndQuery, (GLenum target), (target))
@ -48,7 +51,6 @@ _EVASGL_FUNCTION_BEGIN_VOID( glGetQueryiv, (GLenum target, GLenum pname, GLint *
_EVASGL_FUNCTION_BEGIN_VOID( glGetQueryObjectuiv, (GLuint id, GLenum pname, GLuint * params), (id, pname, params))
_EVASGL_FUNCTION_BEGIN_VOID( glGetSamplerParameterfv, (GLuint sampler, GLenum pname, GLfloat * params), (sampler, pname, params))
_EVASGL_FUNCTION_BEGIN_VOID( glGetSamplerParameteriv, (GLuint sampler, GLenum pname, GLint * params), (sampler, pname, params))
_EVASGL_FUNCTION_BEGIN(const GLubyte *, glGetStringi, (GLenum name, GLuint index), (name, index))
_EVASGL_FUNCTION_BEGIN_VOID( glGetSynciv, (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values), (sync, pname, bufSize, length, values))
_EVASGL_FUNCTION_BEGIN_VOID( glGetTransformFeedbackVarying, (GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, char * name), (program, index, bufSize, length, size, type, name))
_EVASGL_FUNCTION_BEGIN(GLuint, glGetUniformBlockIndex, (GLuint program, const GLchar *uniformBlockName), (program, uniformBlockName))
@ -67,7 +69,6 @@ _EVASGL_FUNCTION_BEGIN(void *, glMapBufferRange, (GLenum target, GLintptr offset
_EVASGL_FUNCTION_BEGIN_VOID( glPauseTransformFeedback, (void), ())
_EVASGL_FUNCTION_BEGIN_VOID( glProgramBinary, (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length), (program, binaryFormat, binary, length))
_EVASGL_FUNCTION_BEGIN_VOID( glProgramParameteri, (GLuint program, GLenum pname, GLint value), (program, pname, value))
_EVASGL_FUNCTION_BEGIN_VOID( glReadBuffer, (GLenum src), (src))
_EVASGL_FUNCTION_BEGIN_VOID( glRenderbufferStorageMultisample, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height), (target, samples, internalformat, width, height))
_EVASGL_FUNCTION_BEGIN_VOID( glResumeTransformFeedback, (void), ())
_EVASGL_FUNCTION_BEGIN_VOID( glSamplerParameterf, (GLuint sampler, GLenum pname, GLfloat param), (sampler, pname, param))

View File

@ -32,6 +32,8 @@
# ifdef GL_GLES
# include <GLES2/gl2.h>
# include <GLES2/gl2ext.h>
# include <GLES3/gl3.h>
# include <GLES3/gl3ext.h>
# else
# include <GL/gl.h>
# include <GL/glext.h>

View File

@ -204,7 +204,7 @@ _texture_destroy(GLuint *tex)
// Attach 2D texture with the given format to already bound FBO
// *NOTE: attach2 here is used for depth_stencil attachment in GLES env.
static void
_texture_attach_2d(GLuint tex, GLenum attach, GLenum attach2, int samples, Eina_Bool use_extension)
_texture_attach_2d(GLuint tex, GLenum attach, GLenum attach2, int samples, Evas_GL_Context_Version version)
{
if (samples)
{
@ -224,7 +224,7 @@ _texture_attach_2d(GLuint tex, GLenum attach, GLenum attach2, int samples, Eina_
ERR("MSAA not supported. Should not have come in here...!");
#endif
}
else if (use_extension)
else if (version == EVAS_GL_GLES_1_X)
{
if (EXT_FUNC_GLES1(glFramebufferTexture2DOES))
EXT_FUNC_GLES1(glFramebufferTexture2DOES)(GL_FRAMEBUFFER, attach, GL_TEXTURE_2D, tex, 0);
@ -302,9 +302,9 @@ _egl_image_destroy(void *image)
}
static void
_framebuffer_create(GLuint *buf, Eina_Bool use_extension)
_framebuffer_create(GLuint *buf, Evas_GL_Context_Version version)
{
if (use_extension)
if (version == EVAS_GL_GLES_1_X)
{
if (EXT_FUNC_GLES1(glGenFramebuffersOES))
EXT_FUNC_GLES1(glGenFramebuffersOES)(1, buf);
@ -316,9 +316,9 @@ _framebuffer_create(GLuint *buf, Eina_Bool use_extension)
}
static void
_framebuffer_bind(GLuint buf, Eina_Bool use_extension)
_framebuffer_bind(GLuint buf, Evas_GL_Context_Version version)
{
if (use_extension)
if (version == EVAS_GL_GLES_1_X)
{
if (EXT_FUNC_GLES1(glBindFramebufferOES))
EXT_FUNC_GLES1(glBindFramebufferOES)(GL_FRAMEBUFFER, buf);
@ -329,11 +329,27 @@ _framebuffer_bind(GLuint buf, Eina_Bool use_extension)
}
}
static void
_framebuffer_draw_bind(GLuint buf, Evas_GL_Context_Version version)
{
if (version == EVAS_GL_GLES_3_X)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buf);
}
//This function is not needed in EvasGL backend engine with GLES 2.0.
//But It is useful when EvasGL backend works with GLES 3.X and use read buffers.
static void
_framebuffer_read_bind(GLuint buf, Evas_GL_Context_Version version)
{
if (version == EVAS_GL_GLES_3_X)
glBindFramebuffer(GL_READ_FRAMEBUFFER, buf);
}
static GLenum
_framebuffer_check(Eina_Bool use_extension)
_framebuffer_check(Evas_GL_Context_Version version)
{
GLenum ret = 0;
if (use_extension)
if (version == EVAS_GL_GLES_1_X)
{
if (EXT_FUNC_GLES1(glCheckFramebufferStatusOES))
ret = EXT_FUNC_GLES1(glCheckFramebufferStatusOES)(GL_FRAMEBUFFER);
@ -384,9 +400,9 @@ _renderbuffer_destroy(GLuint *buf)
// Attach a renderbuffer with the given format to already bound FBO
static void
_renderbuffer_attach(GLuint buf, GLenum attach, Eina_Bool use_extension)
_renderbuffer_attach(GLuint buf, GLenum attach, Evas_GL_Context_Version version)
{
if (use_extension)
if (version == EVAS_GL_GLES_1_X)
{
if (EXT_FUNC_GLES1(glFramebufferRenderbufferOES))
EXT_FUNC_GLES1(glFramebufferRenderbufferOES)(GL_FRAMEBUFFER, attach, GL_RENDERBUFFER, buf);
@ -398,6 +414,7 @@ _renderbuffer_attach(GLuint buf, GLenum attach, Eina_Bool use_extension)
}
// Check whether the given FBO surface config is supported by the driver
// TODO - we also should test with GLES3's formats.
static int
_fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
GLenum depth_fmt, GLenum stencil_fmt, int mult_samples)
@ -420,7 +437,7 @@ _fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
{
_texture_create(&color_buf);
_texture_allocate_2d(color_buf, color_ifmt, color_fmt, GL_UNSIGNED_BYTE, w, h);
_texture_attach_2d(color_buf, GL_COLOR_ATTACHMENT0, 0, mult_samples, EINA_FALSE);
_texture_attach_2d(color_buf, GL_COLOR_ATTACHMENT0, 0, mult_samples, EVAS_GL_GLES_2_X);
}
// Check Depth_Stencil Format First
@ -431,7 +448,7 @@ _fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
_texture_allocate_2d(depth_stencil_buf, depth_fmt,
depth_fmt, GL_UNSIGNED_INT_24_8_OES, w, h);
_texture_attach_2d(depth_stencil_buf, GL_DEPTH_ATTACHMENT,
GL_STENCIL_ATTACHMENT, mult_samples, EINA_FALSE);
GL_STENCIL_ATTACHMENT, mult_samples, EVAS_GL_GLES_2_X);
depth_stencil = 1;
}
#else
@ -449,7 +466,7 @@ _fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
{
_renderbuffer_create(&depth_buf);
_renderbuffer_allocate(depth_buf, depth_fmt, w, h, mult_samples);
_renderbuffer_attach(depth_buf, GL_DEPTH_ATTACHMENT, EINA_FALSE);
_renderbuffer_attach(depth_buf, GL_DEPTH_ATTACHMENT, EVAS_GL_GLES_2_X);
}
// Stencil Attachment
@ -457,7 +474,7 @@ _fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
{
_renderbuffer_create(&stencil_buf);
_renderbuffer_allocate(stencil_buf, stencil_fmt, w, h, mult_samples);
_renderbuffer_attach(stencil_buf, GL_STENCIL_ATTACHMENT, EINA_FALSE);
_renderbuffer_attach(stencil_buf, GL_STENCIL_ATTACHMENT, EVAS_GL_GLES_2_X);
}
// Check FBO for completeness
@ -1087,47 +1104,47 @@ _surface_context_list_print()
// Start from here.....
//--------------------------------------------------------//
static int
_surface_buffers_fbo_set(EVGL_Surface *sfc, GLuint fbo, Eina_Bool use_extension)
_surface_buffers_fbo_set(EVGL_Surface *sfc, GLuint fbo, Evas_GL_Context_Version version)
{
int status;
_framebuffer_bind(fbo, use_extension);
_framebuffer_bind(fbo, version);
// Detach any previously attached buffers
_texture_attach_2d(0, GL_COLOR_ATTACHMENT0, 0, 0, use_extension);
_renderbuffer_attach(0, GL_DEPTH_ATTACHMENT, use_extension);
_renderbuffer_attach(0, GL_STENCIL_ATTACHMENT, use_extension);
_texture_attach_2d(0, GL_COLOR_ATTACHMENT0, 0, 0, version);
_renderbuffer_attach(0, GL_DEPTH_ATTACHMENT, version);
_renderbuffer_attach(0, GL_STENCIL_ATTACHMENT, version);
#ifdef GL_GLES
_texture_attach_2d(0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT, 0, use_extension);
_texture_attach_2d(0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT, 0, version);
#else
_renderbuffer_attach(0, GL_DEPTH_STENCIL_ATTACHMENT, use_extension);
_renderbuffer_attach(0, GL_DEPTH_STENCIL_ATTACHMENT, version);
#endif
// Render Target Texture
if (sfc->color_buf)
_texture_attach_2d(sfc->color_buf, GL_COLOR_ATTACHMENT0, 0, sfc->msaa_samples, use_extension);
_texture_attach_2d(sfc->color_buf, GL_COLOR_ATTACHMENT0, 0, sfc->msaa_samples, version);
// Depth Stencil RenderBuffer - Attach it to FBO
if (sfc->depth_stencil_buf)
{
#ifdef GL_GLES
_texture_attach_2d(sfc->depth_stencil_buf, GL_DEPTH_ATTACHMENT,
GL_STENCIL_ATTACHMENT, sfc->msaa_samples, use_extension);
GL_STENCIL_ATTACHMENT, sfc->msaa_samples, version);
#else
_renderbuffer_attach(sfc->depth_stencil_buf, GL_DEPTH_STENCIL_ATTACHMENT, use_extension);
_renderbuffer_attach(sfc->depth_stencil_buf, GL_DEPTH_STENCIL_ATTACHMENT, version);
#endif
}
// Depth RenderBuffer - Attach it to FBO
if (sfc->depth_buf)
_renderbuffer_attach(sfc->depth_buf, GL_DEPTH_ATTACHMENT, use_extension);
_renderbuffer_attach(sfc->depth_buf, GL_DEPTH_ATTACHMENT, version);
// Stencil RenderBuffer - Attach it to FBO
if (sfc->stencil_buf)
_renderbuffer_attach(sfc->stencil_buf, GL_STENCIL_ATTACHMENT, use_extension);
_renderbuffer_attach(sfc->stencil_buf, GL_STENCIL_ATTACHMENT, version);
// Check FBO for completeness
status = _framebuffer_check(use_extension);
status = _framebuffer_check(version);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
ERR("FBO not complete. Error Code: %x!", status);
@ -1173,7 +1190,7 @@ _surface_buffers_create(EVGL_Surface *sfc)
static int
_surface_buffers_allocate(void *eng_data, EVGL_Surface *sfc, int w, int h, int mc)
_surface_buffers_allocate(void *eng_data, EVGL_Surface *sfc, int w, int h, int mc, Evas_GL_Context_Version version)
{
// Set the context current with resource context/surface
if (mc)
@ -1203,9 +1220,18 @@ _surface_buffers_allocate(void *eng_data, EVGL_Surface *sfc, int w, int h, int m
if (sfc->depth_stencil_fmt)
{
#ifdef GL_GLES
_texture_allocate_2d(sfc->depth_stencil_buf, sfc->depth_stencil_fmt,
sfc->depth_stencil_fmt, GL_UNSIGNED_INT_24_8_OES,
w, h);
if (version == EVAS_GL_GLES_3_X)
{
_texture_allocate_2d(sfc->depth_stencil_buf, GL_DEPTH24_STENCIL8_OES,
sfc->depth_stencil_fmt, GL_UNSIGNED_INT_24_8_OES,
w, h);
}
else
{
_texture_allocate_2d(sfc->depth_stencil_buf, sfc->depth_stencil_fmt,
sfc->depth_stencil_fmt, GL_UNSIGNED_INT_24_8_OES,
w, h);
}
#else
_renderbuffer_allocate(sfc->depth_stencil_buf, sfc->depth_stencil_fmt,
w, h, sfc->msaa_samples);
@ -2133,6 +2159,7 @@ evgl_context_create(void *eng_data, EVGL_Context *share_ctx,
ctx->scissor_coord[1] = 0;
ctx->scissor_coord[2] = evgl_engine->caps.max_w;
ctx->scissor_coord[3] = evgl_engine->caps.max_h;
ctx->gl_error = GL_NO_ERROR;
// Call engine create context
if (share_ctx)
@ -2242,7 +2269,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
{
Eina_Bool dbg = EINA_FALSE;
EVGL_Resource *rsc;
int curr_fbo = 0;
int curr_fbo = 0, curr_draw_fbo = 0, curr_read_fbo = 0;
// Check the input validity. If either sfc or ctx is NULL, it's also error.
if ( (!evgl_engine) ||
@ -2276,14 +2303,30 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
if (rsc->direct.partial.enabled)
evgl_direct_partial_render_end();
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo);
if ((rsc->current_ctx->surface_fbo == (GLuint) curr_fbo) ||
(rsc->current_ctx->current_sfc &&
rsc->current_ctx->current_sfc->color_buf == (GLuint) curr_fbo))
if (rsc->current_ctx->version == EVAS_GL_GLES_3_X)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
rsc->current_ctx->current_fbo = 0;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &curr_draw_fbo);
if ((rsc->current_ctx->surface_fbo == (GLuint) curr_draw_fbo) ||
(rsc->current_ctx->current_sfc &&
rsc->current_ctx->current_sfc->color_buf == (GLuint) curr_draw_fbo))
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
rsc->current_ctx->current_draw_fbo = 0;
rsc->current_ctx->current_read_fbo = 0;
}
}
else
{
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo);
if ((rsc->current_ctx->surface_fbo == (GLuint) curr_fbo) ||
(rsc->current_ctx->current_sfc &&
rsc->current_ctx->current_sfc->color_buf == (GLuint) curr_fbo))
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
rsc->current_ctx->current_fbo = 0;
}
}
}
if (dbg) DBG("Calling make_current(NULL, NULL)");
@ -2370,7 +2413,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
// Destroy created resources
if (sfc->buffers_allocated)
{
if (!_surface_buffers_allocate(eng_data, sfc, 0, 0, 0))
if (!_surface_buffers_allocate(eng_data, sfc, 0, 0, 0, ctx->version))
{
ERR("Unable to destroy surface buffers!");
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
@ -2391,7 +2434,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
if (!sfc->buffers_allocated)
{
if (dbg) DBG("Allocating buffers for sfc %p", sfc);
if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, 0))
if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, 1, ctx->version))
{
ERR("Unable Create Specificed Surfaces. Unsupported format!");
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
@ -2406,7 +2449,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
{
if (!sfc->buffers_allocated)
{
if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, 0))
if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, 0, ctx->version))
{
ERR("Unable Create Allocate Memory for Surface.");
evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
@ -2459,53 +2502,100 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
glViewport(ctx->viewport_coord[0], ctx->viewport_coord[1], ctx->viewport_coord[2], ctx->viewport_coord[3]);
if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
glDisable(GL_SCISSOR_TEST);
}
if (ctx->version == EVAS_GL_GLES_3_X)
{
ctx->current_draw_fbo = 0;
ctx->current_read_fbo = 0;
}
else
{
ctx->current_fbo = 0;
}
ctx->current_fbo = 0;
rsc->direct.rendered = 0;
}
}
else
{
Eina_Bool use_extension = EINA_FALSE;
#ifdef GL_GLES
if ((ctx->version == EVAS_GL_GLES_1_X) && (gles1_funcs))
use_extension = EINA_TRUE;
#endif
// Normal FBO Rendering
// Create FBO if it hasn't been created
if (!ctx->surface_fbo)
_framebuffer_create(&ctx->surface_fbo, use_extension);
_framebuffer_create(&ctx->surface_fbo, ctx->version);
// Direct Rendering
if (_evgl_direct_renderable(rsc, sfc))
{
if (dbg) DBG("sfc %p is direct renderable.", sfc);
// This is to transition from FBO rendering to direct rendering
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo);
if (ctx->surface_fbo == (GLuint)curr_fbo)
if (ctx->version == EVAS_GL_GLES_3_X)
{
_framebuffer_bind(0, use_extension);
ctx->current_fbo = 0;
}
else if (ctx->current_sfc && (ctx->current_sfc->pbuffer.is_pbuffer))
{
// Using the same context, we were rendering on a pbuffer
_framebuffer_bind(0, use_extension);
ctx->current_fbo = 0;
}
if (ctx->current_fbo == 0)
{
// If master clip is set and clip is greater than 0, do partial render
if (rsc->direct.partial.enabled)
// This is to transition from FBO rendering to direct rendering
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &curr_draw_fbo);
if (ctx->surface_fbo == (GLuint)curr_draw_fbo)
{
if (!ctx->partial_render)
_framebuffer_draw_bind(0, ctx->version);
ctx->current_draw_fbo = 0;
}
else if (ctx->current_sfc && (ctx->current_sfc->pbuffer.is_pbuffer))
{
// Using the same context, we were rendering on a pbuffer
_framebuffer_draw_bind(0, ctx->version);
ctx->current_draw_fbo = 0;
}
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &curr_read_fbo);
if (ctx->surface_fbo == (GLuint)curr_read_fbo)
{
_framebuffer_read_bind(0, ctx->version);
ctx->current_read_fbo = 0;
}
else if (ctx->current_sfc && (ctx->current_sfc->pbuffer.is_pbuffer))
{
_framebuffer_read_bind(0, ctx->version);
ctx->current_read_fbo = 0;
}
if (ctx->current_read_fbo == 0)
{
// If master clip is set and clip is greater than 0, do partial render
if (rsc->direct.partial.enabled)
{
evgl_direct_partial_render_start();
ctx->partial_render = 1;
if (!ctx->partial_render)
{
evgl_direct_partial_render_start();
ctx->partial_render = 1;
}
}
}
}
else
{
// This is to transition from FBO rendering to direct rendering
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo);
if (ctx->surface_fbo == (GLuint)curr_fbo)
{
_framebuffer_bind(0, ctx->version);
ctx->current_fbo = 0;
}
else if (ctx->current_sfc && (ctx->current_sfc->pbuffer.is_pbuffer))
{
// Using the same context, we were rendering on a pbuffer
_framebuffer_bind(0, ctx->version);
ctx->current_fbo = 0;
}
if (ctx->current_fbo == 0)
{
// If master clip is set and clip is greater than 0, do partial render
if (rsc->direct.partial.enabled)
{
if (!ctx->partial_render)
{
evgl_direct_partial_render_start();
ctx->partial_render = 1;
}
}
}
}
@ -2522,7 +2612,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
if (sfc->color_buf)
{
if (!_surface_buffers_fbo_set(sfc, sfc->color_buf, use_extension))
if (!_surface_buffers_fbo_set(sfc, sfc->color_buf, ctx->version))
ERR("Could not detach current FBO");
}
@ -2531,8 +2621,20 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
ctx->context, EINA_TRUE);
// Bind to the previously bound buffer (may be 0)
if (ctx->current_fbo)
_framebuffer_bind(ctx->current_fbo, use_extension);
if (ctx->version == EVAS_GL_GLES_3_X)
{
if (ctx->current_draw_fbo)
{
_framebuffer_draw_bind(ctx->current_draw_fbo, ctx->version);
}
}
else
{
if (ctx->current_fbo)
{
_framebuffer_bind(ctx->current_fbo, ctx->version);
}
}
rsc->direct.rendered = 0;
}
@ -2555,7 +2657,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
if (rsc->direct.partial.enabled)
evgl_direct_partial_render_end();
if (!_surface_buffers_fbo_set(sfc, ctx->surface_fbo, use_extension))
if (!_surface_buffers_fbo_set(sfc, ctx->surface_fbo, ctx->version))
{
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);
@ -2564,8 +2666,20 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
}
// Bind to the previously bound buffer
if (ctx->current_fbo)
_framebuffer_bind(ctx->current_fbo, use_extension);
if (ctx->version == EVAS_GL_GLES_3_X)
{
if (ctx->current_draw_fbo)
_framebuffer_draw_bind(ctx->current_draw_fbo, ctx->version);
if (ctx->current_read_fbo)
_framebuffer_read_bind(ctx->current_read_fbo, ctx->version);
}
else
{
if (ctx->current_fbo)
_framebuffer_bind(ctx->current_fbo, ctx->version);
}
}
rsc->direct.rendered = 0;
}

View File

@ -169,6 +169,8 @@ struct _EVGL_Context
// Current FBO
GLuint current_fbo;
GLuint current_draw_fbo; //for GLES3
GLuint current_read_fbo; //for GLES3
// Direct Rendering Related
unsigned scissor_enabled : 1;
@ -190,6 +192,9 @@ struct _EVGL_Context
int partial_render;
EVGL_Surface *current_sfc;
//glGetError
GLenum gl_error;
};
typedef enum _EVGL_Color_Bit