Use FBOs and use cogl_read_pixels() to efficiently read partial textures
* cogl_texture_get_data() is converted to use _cogl_texture_foreach_sub_texture_in_region() to iterate through the underlying textures. * When we need to read only a portion of the underlying texture, we set up a FBO and use _cogl_read_pixels() to read the portion we need. This is enormously more efficient for reading a small portion of a large atlas texture. * The CoglAtlasTexture, CoglSubTexture, and CoglTexture2dSliced implementation of get_texture() are removed. http://bugzilla.clutter-project.org/show_bug.cgi?id=2414
This commit is contained in:

committed by
Neil Roberts

parent
47ccbf472e
commit
cda29a8011
@ -1335,153 +1335,6 @@ _cogl_texture_2d_sliced_set_region (CoglTexture *tex,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_cogl_texture_2d_sliced_download_from_gl (
|
||||
CoglTexture2DSliced *tex_2ds,
|
||||
CoglBitmap *target_bmp,
|
||||
GLuint target_gl_format,
|
||||
GLuint target_gl_type)
|
||||
{
|
||||
CoglSpan *x_span;
|
||||
CoglSpan *y_span;
|
||||
CoglHandle slice_tex;
|
||||
int bpp;
|
||||
int x, y;
|
||||
CoglBitmap *slice_bmp;
|
||||
CoglPixelFormat target_format = _cogl_bitmap_get_format (target_bmp);
|
||||
|
||||
bpp = _cogl_get_format_bpp (target_format);
|
||||
|
||||
/* Iterate vertical slices */
|
||||
for (y = 0; y < tex_2ds->slice_y_spans->len; ++y)
|
||||
{
|
||||
y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, y);
|
||||
|
||||
/* Iterate horizontal slices */
|
||||
for (x = 0; x < tex_2ds->slice_x_spans->len; ++x)
|
||||
{
|
||||
/*if (x != 0 || y != 1) continue;*/
|
||||
x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, x);
|
||||
|
||||
/* Pick the sliced texture */
|
||||
slice_tex = g_array_index (tex_2ds->slice_textures, CoglHandle,
|
||||
y * tex_2ds->slice_x_spans->len + x);
|
||||
|
||||
/* If there's any waste we need to copy manually
|
||||
(no glGetTexSubImage) */
|
||||
|
||||
if (y_span->waste != 0 || x_span->waste != 0)
|
||||
{
|
||||
int rowstride = x_span->size * bpp;
|
||||
guint8 *data = g_malloc (rowstride * y_span->size);
|
||||
|
||||
/* Setup temp bitmap for slice subregion */
|
||||
slice_bmp = _cogl_bitmap_new_from_data (data,
|
||||
target_format,
|
||||
x_span->size,
|
||||
y_span->size,
|
||||
rowstride,
|
||||
(CoglBitmapDestroyNotify)
|
||||
g_free,
|
||||
NULL);
|
||||
|
||||
/* Setup gl alignment to 0,0 top-left corner */
|
||||
_cogl_texture_driver_prep_gl_for_pixels_download (rowstride, bpp);
|
||||
|
||||
if (!cogl_texture_get_data (slice_tex,
|
||||
target_format,
|
||||
rowstride,
|
||||
data))
|
||||
{
|
||||
/* Free temp bitmap */
|
||||
cogl_object_unref (slice_bmp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Copy portion of slice from temp to target bmp */
|
||||
_cogl_bitmap_copy_subregion (slice_bmp,
|
||||
target_bmp,
|
||||
0, 0,
|
||||
x_span->start,
|
||||
y_span->start,
|
||||
x_span->size - x_span->waste,
|
||||
y_span->size - y_span->waste);
|
||||
/* Free temp bitmap */
|
||||
cogl_object_unref (slice_bmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
guint8 *data;
|
||||
GLvoid *dst;
|
||||
gboolean ret;
|
||||
int rowstride = _cogl_bitmap_get_rowstride (target_bmp);
|
||||
|
||||
data = _cogl_bitmap_map (target_bmp,
|
||||
COGL_BUFFER_ACCESS_WRITE,
|
||||
0);
|
||||
if (data == NULL)
|
||||
return FALSE;
|
||||
|
||||
dst = data + x_span->start * bpp + y_span->start * rowstride;
|
||||
|
||||
_cogl_texture_driver_prep_gl_for_pixels_download (rowstride, bpp);
|
||||
|
||||
/* Download slice image data */
|
||||
ret = cogl_texture_get_data (slice_tex,
|
||||
target_format,
|
||||
rowstride,
|
||||
dst);
|
||||
|
||||
_cogl_bitmap_unmap (target_bmp);
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_cogl_texture_2d_sliced_get_data (CoglTexture *tex,
|
||||
CoglPixelFormat format,
|
||||
unsigned int rowstride,
|
||||
guint8 *data)
|
||||
{
|
||||
CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex);
|
||||
int bpp;
|
||||
GLenum gl_format;
|
||||
GLenum gl_type;
|
||||
CoglBitmap *target_bmp;
|
||||
gboolean ret;
|
||||
|
||||
bpp = _cogl_get_format_bpp (format);
|
||||
|
||||
_cogl_pixel_format_to_gl (format,
|
||||
NULL, /* internal format */
|
||||
&gl_format,
|
||||
&gl_type);
|
||||
|
||||
target_bmp = _cogl_bitmap_new_from_data (data,
|
||||
format,
|
||||
tex_2ds->width,
|
||||
tex_2ds->height,
|
||||
rowstride,
|
||||
NULL, /* destroy_fn */
|
||||
NULL /* destroy_fn_data */);
|
||||
|
||||
/* Retrieve data from slices */
|
||||
ret = _cogl_texture_2d_sliced_download_from_gl (tex_2ds,
|
||||
target_bmp,
|
||||
gl_format,
|
||||
gl_type);
|
||||
|
||||
cogl_object_unref (target_bmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static CoglPixelFormat
|
||||
_cogl_texture_2d_sliced_get_format (CoglTexture *tex)
|
||||
{
|
||||
@ -1528,7 +1381,7 @@ static const CoglTextureVtable
|
||||
cogl_texture_2d_sliced_vtable =
|
||||
{
|
||||
_cogl_texture_2d_sliced_set_region,
|
||||
_cogl_texture_2d_sliced_get_data,
|
||||
NULL, /* get_data */
|
||||
_cogl_texture_2d_sliced_foreach_sub_texture_in_region,
|
||||
_cogl_texture_2d_sliced_get_max_waste,
|
||||
_cogl_texture_2d_sliced_is_sliced,
|
||||
|
Reference in New Issue
Block a user