evas: add YUV double buffering for OpenGL backend.
SVN revision: 63225
This commit is contained in:
parent
9c08e73d48
commit
120306f05f
|
@ -362,11 +362,17 @@ struct _Evas_GL_Texture
|
||||||
{
|
{
|
||||||
Evas_Engine_GL_Context *gc;
|
Evas_Engine_GL_Context *gc;
|
||||||
Evas_GL_Image *im;
|
Evas_GL_Image *im;
|
||||||
Evas_GL_Texture_Pool *pt, *ptu, *ptv, *ptuv;
|
Evas_GL_Texture_Pool *pt, *ptu, *ptv, *ptuv;
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
double sx1, sy1, sx2, sy2;
|
double sx1, sy1, sx2, sy2;
|
||||||
int references;
|
int references;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
Evas_GL_Texture_Pool *pt[2], *ptuv[2];
|
||||||
|
int source;
|
||||||
|
} double_buffer;
|
||||||
|
|
||||||
Eina_Bool alpha : 1;
|
Eina_Bool alpha : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -649,6 +649,7 @@ evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt)
|
||||||
static void
|
static void
|
||||||
pt_unref(Evas_GL_Texture_Pool *pt)
|
pt_unref(Evas_GL_Texture_Pool *pt)
|
||||||
{
|
{
|
||||||
|
if (!pt) return;
|
||||||
if (!pt->gc) return;
|
if (!pt->gc) return;
|
||||||
pt->references--;
|
pt->references--;
|
||||||
if (pt->references != 0) return;
|
if (pt->references != 0) return;
|
||||||
|
@ -666,6 +667,17 @@ pt_unref(Evas_GL_Texture_Pool *pt)
|
||||||
free(pt);
|
free(pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pt_link(Evas_Engine_GL_Context *gc, Evas_GL_Texture *tex, Evas_GL_Texture_Pool *pt)
|
||||||
|
{
|
||||||
|
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, pt);
|
||||||
|
pt->slot = -1;
|
||||||
|
pt->fslot = -1;
|
||||||
|
pt->whole = 1;
|
||||||
|
pt->allocations = eina_list_prepend(pt->allocations, tex);
|
||||||
|
pt->references++;
|
||||||
|
}
|
||||||
|
|
||||||
Evas_GL_Texture *
|
Evas_GL_Texture *
|
||||||
evas_gl_common_texture_native_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, Evas_GL_Image *im)
|
evas_gl_common_texture_native_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, Evas_GL_Image *im)
|
||||||
{
|
{
|
||||||
|
@ -874,15 +886,36 @@ evas_gl_common_texture_free(Evas_GL_Texture *tex)
|
||||||
if (!tex) return;
|
if (!tex) return;
|
||||||
tex->references--;
|
tex->references--;
|
||||||
if (tex->references != 0) return;
|
if (tex->references != 0) return;
|
||||||
if (tex->pt)
|
if (tex->double_buffer.pt[0])
|
||||||
{
|
{
|
||||||
// printf("tex->pt = %p\n", tex->pt);
|
tex->double_buffer.pt[0]->allocations = eina_list_remove(tex->double_buffer.pt[0]->allocations, tex);
|
||||||
// printf("tex->pt->references = %i\n", tex->pt->references);
|
tex->double_buffer.pt[1]->allocations = eina_list_remove(tex->double_buffer.pt[1]->allocations, tex);
|
||||||
tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex);
|
tex->double_buffer.ptuv[0]->allocations = eina_list_remove(tex->double_buffer.ptuv[0]->allocations, tex);
|
||||||
pt_unref(tex->pt);
|
tex->double_buffer.ptuv[1]->allocations = eina_list_remove(tex->double_buffer.ptuv[1]->allocations, tex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (tex->pt)
|
||||||
|
{
|
||||||
|
tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex);
|
||||||
|
pt_unref(tex->pt);
|
||||||
|
}
|
||||||
|
if (tex->ptu)
|
||||||
|
{
|
||||||
|
tex->ptu->allocations = eina_list_remove(tex->ptu->allocations, tex);
|
||||||
|
pt_unref(tex->ptu);
|
||||||
|
}
|
||||||
|
if (tex->ptv)
|
||||||
|
{
|
||||||
|
tex->ptv->allocations = eina_list_remove(tex->ptv->allocations, tex);
|
||||||
|
pt_unref(tex->ptv);
|
||||||
|
}
|
||||||
|
if (tex->ptuv)
|
||||||
|
{
|
||||||
|
tex->ptuv->allocations = eina_list_remove(tex->ptuv->allocations, tex);
|
||||||
|
pt_unref(tex->ptuv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (tex->ptu) pt_unref(tex->ptu);
|
|
||||||
if (tex->ptv) pt_unref(tex->ptv);
|
|
||||||
free(tex);
|
free(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,43 +1110,49 @@ _evas_gl_common_texture_y2uv_new(Evas_Engine_GL_Context *gc,
|
||||||
GLenum y_ifmt, GLenum y_fmt,
|
GLenum y_ifmt, GLenum y_fmt,
|
||||||
GLenum uv_ifmt, GLenum uv_fmt)
|
GLenum uv_ifmt, GLenum uv_fmt)
|
||||||
{
|
{
|
||||||
|
Evas_GL_Texture_Pool *pt[2] = { NULL, NULL };
|
||||||
|
Evas_GL_Texture_Pool *ptuv[2] = { NULL, NULL };
|
||||||
Evas_GL_Texture *tex;
|
Evas_GL_Texture *tex;
|
||||||
|
|
||||||
|
pt[0] = _pool_tex_new(gc, yw + 1, yh + 1, y_ifmt, y_fmt);
|
||||||
|
pt[1] = _pool_tex_new(gc, yw + 1, yh + 1, y_ifmt, y_fmt);
|
||||||
|
|
||||||
|
ptuv[0] = _pool_tex_new(gc, uvw + 1, uvh + 1, uv_ifmt, uv_fmt);
|
||||||
|
ptuv[1] = _pool_tex_new(gc, uvw + 1, uvh + 1, uv_ifmt, uv_fmt);
|
||||||
|
|
||||||
|
if (!pt[0] || !pt[1] || !ptuv[0] || !ptuv[1])
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
tex = calloc(1, sizeof(Evas_GL_Texture));
|
tex = calloc(1, sizeof(Evas_GL_Texture));
|
||||||
if (!tex) return NULL;
|
if (!tex)
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
tex->gc = gc;
|
tex->gc = gc;
|
||||||
tex->references = 1;
|
tex->references = 1;
|
||||||
tex->pt = _pool_tex_new(gc, yw + 1, yh + 1, y_ifmt, y_fmt);
|
tex->pt = pt[0];
|
||||||
if (!tex->pt)
|
tex->ptuv = ptuv[0];
|
||||||
{
|
|
||||||
free(tex);
|
pt_link(gc, tex, pt[0]);
|
||||||
return NULL;
|
pt_link(gc, tex, pt[1]);
|
||||||
}
|
pt_link(gc, tex, ptuv[0]);
|
||||||
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, tex->pt);
|
pt_link(gc, tex, ptuv[1]);
|
||||||
tex->pt->slot = -1;
|
|
||||||
tex->pt->fslot = -1;
|
|
||||||
tex->pt->whole = 1;
|
|
||||||
tex->ptuv = _pool_tex_new(gc, uvw + 1, uvh + 1, uv_ifmt, uv_fmt);
|
|
||||||
if (!tex->ptuv)
|
|
||||||
{
|
|
||||||
pt_unref(tex->pt);
|
|
||||||
free(tex);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, tex->ptuv);
|
|
||||||
tex->ptuv->slot = -1;
|
|
||||||
tex->ptuv->fslot = -1;
|
|
||||||
tex->ptuv->whole = 1;
|
|
||||||
tex->x = 0;
|
tex->x = 0;
|
||||||
tex->y = 0;
|
tex->y = 0;
|
||||||
tex->w = yw;
|
tex->w = yw;
|
||||||
tex->h = yh;
|
tex->h = yh;
|
||||||
tex->pt->allocations = eina_list_prepend(tex->pt->allocations, tex);
|
tex->double_buffer.source = 0;
|
||||||
tex->ptuv->allocations = eina_list_prepend(tex->ptuv->allocations, tex);
|
memcpy(tex->double_buffer.pt, pt, sizeof (Evas_GL_Texture_Pool *) * 2);
|
||||||
tex->pt->references++;
|
memcpy(tex->double_buffer.ptuv, ptuv, sizeof (Evas_GL_Texture_Pool *) * 2);
|
||||||
tex->ptuv->references++;
|
|
||||||
return tex;
|
return tex;
|
||||||
|
|
||||||
|
on_error:
|
||||||
|
pt_unref(pt[0]);
|
||||||
|
pt_unref(pt[1]);
|
||||||
|
pt_unref(ptuv[0]);
|
||||||
|
pt_unref(ptuv[1]);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Evas_GL_Texture *
|
Evas_GL_Texture *
|
||||||
|
@ -1131,7 +1170,7 @@ evas_gl_common_texture_nv12_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsign
|
||||||
{
|
{
|
||||||
Evas_GL_Texture *tex;
|
Evas_GL_Texture *tex;
|
||||||
|
|
||||||
tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h / 2, alpha_ifmt, alpha_fmt, lum_alpha_ifmt, lum_alpha_fmt);
|
tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h / 2, lum_ifmt, lum_fmt, lum_alpha_ifmt, lum_alpha_fmt);
|
||||||
evas_gl_common_texture_nv12_update(tex, rows, w, h);
|
evas_gl_common_texture_nv12_update(tex, rows, w, h);
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
@ -1153,6 +1192,10 @@ evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned
|
||||||
// FIXME: works on lowest size 4 pixel high buffers. must also be multiple of 2
|
// FIXME: works on lowest size 4 pixel high buffers. must also be multiple of 2
|
||||||
unsigned int y;
|
unsigned int y;
|
||||||
|
|
||||||
|
tex->double_buffer.source = 1 - tex->double_buffer.source;
|
||||||
|
tex->pt = tex->double_buffer.pt[tex->double_buffer.source];
|
||||||
|
tex->ptuv = tex->double_buffer.ptuv[tex->double_buffer.source];
|
||||||
|
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
||||||
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
||||||
|
@ -1188,6 +1231,11 @@ void
|
||||||
evas_gl_common_texture_nv12_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
|
evas_gl_common_texture_nv12_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
|
||||||
{
|
{
|
||||||
if (!tex->pt) return;
|
if (!tex->pt) return;
|
||||||
|
|
||||||
|
tex->double_buffer.source = 1 - tex->double_buffer.source;
|
||||||
|
tex->pt = tex->double_buffer.pt[tex->double_buffer.source];
|
||||||
|
tex->ptuv = tex->double_buffer.ptuv[tex->double_buffer.source];
|
||||||
|
|
||||||
// FIXME: works on lowest size 4 pixel high buffers. must also be multiple of 2
|
// FIXME: works on lowest size 4 pixel high buffers. must also be multiple of 2
|
||||||
#ifdef GL_UNPACK_ROW_LENGTH
|
#ifdef GL_UNPACK_ROW_LENGTH
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]);
|
||||||
|
@ -1246,14 +1294,19 @@ evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsi
|
||||||
|
|
||||||
if (!tex->pt) return;
|
if (!tex->pt) return;
|
||||||
|
|
||||||
|
tex->double_buffer.source = 1 - tex->double_buffer.source;
|
||||||
|
tex->pt = tex->double_buffer.pt[tex->double_buffer.source];
|
||||||
|
tex->ptuv = tex->double_buffer.ptuv[tex->double_buffer.source];
|
||||||
|
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
||||||
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
|
||||||
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
|
||||||
|
|
||||||
mb_w = w / 64;
|
mb_w = w / 64;
|
||||||
mb_h = h / 32;
|
mb_h = h / 32;
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
|
||||||
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
||||||
|
|
||||||
// We are telling the driver to not swizzle back the buffer as we are going to replace all pixel
|
// We are telling the driver to not swizzle back the buffer as we are going to replace all pixel
|
||||||
_tex_2d(tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat);
|
_tex_2d(tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat);
|
||||||
|
|
||||||
|
@ -1321,7 +1374,6 @@ evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsi
|
||||||
_tex_sub_2d(x, ry[offset], 32, 32,
|
_tex_sub_2d(x, ry[offset], 32, 32,
|
||||||
tex->ptuv->format, tex->ptuv->dataformat,
|
tex->ptuv->format, tex->ptuv->dataformat,
|
||||||
rows[mb_y + base_h] + rmb_x);
|
rows[mb_y + base_h] + rmb_x);
|
||||||
|
|
||||||
step++;
|
step++;
|
||||||
if ((step & 0x3) == 0)
|
if ((step & 0x3) == 0)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue