static CoglBool _cogl_texture_2d_is_foreign (CoglTexture *tex) { return COGL_TEXTURE_2D (tex)->is_foreign; }
static CoglPixelFormat _cogl_texture_2d_get_format (CoglTexture *tex) { return COGL_TEXTURE_2D (tex)->internal_format; }
static GLenum _cogl_texture_2d_get_gl_format (CoglTexture *tex) { return COGL_TEXTURE_2D (tex)->gl_internal_format; }
static int _cogl_texture_2d_get_height (CoglTexture *tex) { return COGL_TEXTURE_2D (tex)->height; }
static int _cogl_texture_2d_get_width (CoglTexture *tex) { return COGL_TEXTURE_2D (tex)->width; }
static int _cogl_texture_2d_get_data (CoglTexture *tex, CoglPixelFormat format, unsigned int rowstride, guint8 *data) { CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); int bpp; int byte_size; CoglPixelFormat closest_format; int closest_bpp; GLenum closest_gl_format; GLenum closest_gl_type; CoglBitmap target_bmp; CoglBitmap new_bmp; gboolean success; guint8 *src; guint8 *dst; int y; /* Default to internal format if none specified */ if (format == COGL_PIXEL_FORMAT_ANY) format = tex_2d->format; /* Rowstride from texture width if none specified */ bpp = _cogl_get_format_bpp (format); if (rowstride == 0) rowstride = tex_2d->width * bpp; /* Return byte size if only that requested */ byte_size = tex_2d->height * rowstride; if (data == NULL) return byte_size; closest_format = _cogl_texture_driver_find_best_gl_get_data_format (format, &closest_gl_format, &closest_gl_type); closest_bpp = _cogl_get_format_bpp (closest_format); target_bmp.width = tex_2d->width; target_bmp.height = tex_2d->height; /* Is the requested format supported? */ if (closest_format == format) { /* Target user data directly */ target_bmp.format = format; target_bmp.rowstride = rowstride; target_bmp.data = data; } else { /* Target intermediate buffer */ target_bmp.format = closest_format; target_bmp.rowstride = target_bmp.width * closest_bpp; target_bmp.data = g_malloc (target_bmp.height * target_bmp.rowstride); } _cogl_texture_driver_prep_gl_for_pixels_download (target_bmp.rowstride, closest_bpp); GE( glBindTexture (GL_TEXTURE_2D, tex_2d->gl_texture) ); if (!_cogl_texture_driver_gl_get_tex_image (GL_TEXTURE_2D, closest_gl_format, closest_gl_type, target_bmp.data)) { /* XXX: In some cases _cogl_texture_2d_download_from_gl may * fail to read back the texture data; such as for GLES which doesn't * support glGetTexImage, so here we fallback to drawing the texture * and reading the pixels from the framebuffer. */ _cogl_texture_draw_and_read (tex, &target_bmp, closest_gl_format, closest_gl_type); } /* Was intermediate used? */ if (closest_format != format) { /* Convert to requested format */ success = _cogl_bitmap_convert_format_and_premult (&target_bmp, &new_bmp, format); /* Free intermediate data and return if failed */ g_free (target_bmp.data); if (!success) return 0; /* Copy to user buffer */ for (y = 0; y < new_bmp.height; ++y) { src = new_bmp.data + y * new_bmp.rowstride; dst = data + y * rowstride; memcpy (dst, src, new_bmp.width); } /* Free converted data */ g_free (new_bmp.data); } return byte_size; }
static gboolean _cogl_texture_2d_set_region (CoglTexture *tex, int src_x, int src_y, int dst_x, int dst_y, unsigned int dst_width, unsigned int dst_height, int width, int height, CoglPixelFormat format, unsigned int rowstride, const guint8 *data) { CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); int bpp; CoglBitmap source_bmp; CoglBitmap tmp_bmp; gboolean tmp_bmp_owner = FALSE; GLenum closest_gl_format; GLenum closest_gl_type; /* Check for valid format */ if (format == COGL_PIXEL_FORMAT_ANY) return FALSE; /* Shortcut out early if the image is empty */ if (width == 0 || height == 0) return TRUE; /* Init source bitmap */ source_bmp.width = width; source_bmp.height = height; source_bmp.format = format; source_bmp.data = (guint8 *)data; /* Rowstride from width if none specified */ bpp = _cogl_get_format_bpp (format); source_bmp.rowstride = (rowstride == 0) ? width * bpp : rowstride; /* Prepare the bitmap so that it will do the premultiplication conversion */ _cogl_texture_prepare_for_upload (&source_bmp, tex_2d->format, NULL, &tmp_bmp, &tmp_bmp_owner, NULL, &closest_gl_format, &closest_gl_type); /* Send data to GL */ _cogl_texture_driver_upload_subregion_to_gl (GL_TEXTURE_2D, tex_2d->gl_texture, src_x, src_y, dst_x, dst_y, dst_width, dst_height, &tmp_bmp, closest_gl_format, closest_gl_type); /* Free data if owner */ if (tmp_bmp_owner) g_free (tmp_bmp.data); tex_2d->mipmaps_dirty = TRUE; return TRUE; }