Esempio n. 1
0
static void
_cogl_texture_driver_upload_to_gl (CoglContext *ctx,
                                   GLenum       gl_target,
                                   GLuint       gl_handle,
                                   CoglBool     is_foreign,
                                   CoglBitmap  *source_bmp,
                                   GLint        internal_gl_format,
                                   GLuint       source_gl_format,
                                   GLuint       source_gl_type)
{
  uint8_t *data;
  CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp);
  int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format);

  data = _cogl_bitmap_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0);

  /* Setup gl alignment to match rowstride and top-left corner */
  prep_gl_for_pixels_upload_full (ctx,
                                  cogl_bitmap_get_rowstride (source_bmp),
                                  0, 0, 0, bpp);

  _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign);

  GE( ctx, glTexImage2D (gl_target, 0,
                         internal_gl_format,
                         cogl_bitmap_get_width (source_bmp),
                         cogl_bitmap_get_height (source_bmp),
                         0,
                         source_gl_format,
                         source_gl_type,
                         data) );

  _cogl_bitmap_unbind (source_bmp);
}
Esempio n. 2
0
static void
_cogl_texture_driver_prep_gl_for_pixels_upload (CoglContext *ctx,
                                                int pixels_rowstride,
                                                int pixels_bpp)
{
  prep_gl_for_pixels_upload_full (ctx, pixels_rowstride, 0, 0, 0, pixels_bpp);
}
Esempio n. 3
0
static void
_cg_texture_driver_prep_gl_for_pixels_upload(cg_device_t *dev,
                                             int pixels_rowstride,
                                             int pixels_bpp)
{
    prep_gl_for_pixels_upload_full(dev, pixels_rowstride, 0, 0, 0,
                                   pixels_bpp);
}
Esempio n. 4
0
static bool
_cg_texture_driver_upload_to_gl(cg_device_t *dev,
                                GLenum gl_target,
                                GLuint gl_handle,
                                bool is_foreign,
                                cg_bitmap_t *source_bmp,
                                GLint internal_gl_format,
                                GLuint source_gl_format,
                                GLuint source_gl_type,
                                cg_error_t **error)
{
    uint8_t *data;
    cg_pixel_format_t source_format = cg_bitmap_get_format(source_bmp);
    int bpp = _cg_pixel_format_get_bytes_per_pixel(source_format);
    GLenum gl_error;
    bool status = true;
    cg_error_t *internal_error = NULL;

    data = _cg_bitmap_gl_bind(source_bmp,
                              CG_BUFFER_ACCESS_READ,
                              0, /* hints */
                              &internal_error);

    /* NB: _cg_bitmap_gl_bind() may return NULL when successful so we
     * have to explicitly check the cg error pointer to catch
     * problems... */
    if (internal_error) {
        _cg_propagate_error(error, internal_error);
        return false;
    }

    /* Setup gl alignment to match rowstride and top-left corner */
    prep_gl_for_pixels_upload_full(dev, cg_bitmap_get_rowstride(source_bmp),
                                   0, 0, 0, bpp);

    _cg_bind_gl_texture_transient(gl_target, gl_handle, is_foreign);

    /* Clear any GL errors */
    while ((gl_error = dev->glGetError()) != GL_NO_ERROR)
        ;

    dev->glTexImage2D(gl_target,
                      0,
                      internal_gl_format,
                      cg_bitmap_get_width(source_bmp),
                      cg_bitmap_get_height(source_bmp),
                      0,
                      source_gl_format,
                      source_gl_type,
                      data);

    if (_cg_gl_util_catch_out_of_memory(dev, error))
        status = false;

    _cg_bitmap_gl_unbind(source_bmp);

    return status;
}
Esempio n. 5
0
static bool
_cg_texture_driver_upload_to_gl_3d(cg_device_t *dev,
                                   GLenum gl_target,
                                   GLuint gl_handle,
                                   bool is_foreign,
                                   GLint height,
                                   GLint depth,
                                   cg_bitmap_t *source_bmp,
                                   GLint internal_gl_format,
                                   GLuint source_gl_format,
                                   GLuint source_gl_type,
                                   cg_error_t **error)
{
    uint8_t *data;
    cg_pixel_format_t source_format = cg_bitmap_get_format(source_bmp);
    int bpp = _cg_pixel_format_get_bytes_per_pixel(source_format);
    GLenum gl_error;
    bool status = true;

    data = _cg_bitmap_gl_bind(source_bmp, CG_BUFFER_ACCESS_READ, 0, error);
    if (!data)
        return false;

    /* Setup gl alignment to match rowstride and top-left corner */
    prep_gl_for_pixels_upload_full(dev,
                                   cg_bitmap_get_rowstride(source_bmp),
                                   (cg_bitmap_get_height(source_bmp) / depth),
                                   0,
                                   0,
                                   bpp);

    _cg_bind_gl_texture_transient(gl_target, gl_handle, is_foreign);

    /* Clear any GL errors */
    while ((gl_error = dev->glGetError()) != GL_NO_ERROR)
        ;

    dev->glTexImage3D(gl_target,
                      0, /* level */
                      internal_gl_format,
                      cg_bitmap_get_width(source_bmp),
                      height,
                      depth,
                      0,
                      source_gl_format,
                      source_gl_type,
                      data);

    if (_cg_gl_util_catch_out_of_memory(dev, error))
        status = false;

    _cg_bitmap_gl_unbind(source_bmp);

    return status;
}
static CoglBool
_cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx,
                                             CoglTexture *texture,
                                             CoglBool is_foreign,
                                             int src_x,
                                             int src_y,
                                             int dst_x,
                                             int dst_y,
                                             int width,
                                             int height,
                                             int level,
                                             CoglBitmap *source_bmp,
				             GLuint source_gl_format,
				             GLuint source_gl_type,
                                             CoglError **error)
{
  GLenum gl_target;
  GLuint gl_handle;
  uint8_t *data;
  CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp);
  int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format);
  CoglBitmap *slice_bmp;
  int rowstride;
  GLenum gl_error;
  CoglBool status = TRUE;
  CoglError *internal_error = NULL;
  int level_width;
  int level_height;

  cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target);

  /* If we have the GL_EXT_unpack_subimage extension then we can
     upload from subregions directly. Otherwise we may need to copy
     the bitmap */
  if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE) &&
      (src_x != 0 || src_y != 0 ||
       width != cogl_bitmap_get_width (source_bmp) ||
       height != cogl_bitmap_get_height (source_bmp)))
    {
      slice_bmp =
        _cogl_bitmap_new_with_malloc_buffer (ctx,
                                             width, height,
                                             source_format,
                                             error);
      if (!slice_bmp)
        return FALSE;

      if (!_cogl_bitmap_copy_subregion (source_bmp,
                                        slice_bmp,
                                        src_x, src_y,
                                        0, 0, /* dst_x/y */
                                        width, height,
                                        error))
        {
          cogl_object_unref (slice_bmp);
          return FALSE;
        }

      src_x = src_y = 0;
    }
  else
    {
      slice_bmp = prepare_bitmap_alignment_for_upload (ctx, source_bmp, error);
      if (!slice_bmp)
        return FALSE;
    }

  rowstride = cogl_bitmap_get_rowstride (slice_bmp);

  /* Setup gl alignment to match rowstride and top-left corner */
  prep_gl_for_pixels_upload_full (ctx, rowstride, src_x, src_y, bpp);

  data = _cogl_bitmap_gl_bind (slice_bmp, COGL_BUFFER_ACCESS_READ, 0, &internal_error);

  /* NB: _cogl_bitmap_gl_bind() may return NULL when successfull so we
   * have to explicitly check the cogl error pointer to catch
   * problems... */
  if (internal_error)
    {
      _cogl_propagate_error (error, internal_error);
      cogl_object_unref (slice_bmp);
      return FALSE;
    }

  _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign);

  /* Clear any GL errors */
  while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
    ;

  _cogl_texture_get_level_size (texture,
                                level,
                                &level_width,
                                &level_height,
                                NULL);

  if (level_width == width && level_height == height)
    {
      /* GL gets upset if you use glTexSubImage2D to define the
       * contents of a mipmap level so we make sure to use
       * glTexImage2D if we are uploading a full mipmap level.
       */
      ctx->glTexImage2D (gl_target,
                         level,
                         _cogl_texture_gl_get_format (texture),
                         width,
                         height,
                         0,
                         source_gl_format,
                         source_gl_type,
                         data);
    }
  else
    {
      /* GL gets upset if you use glTexSubImage2D to initialize the
       * contents of a mipmap level so if this is the first time
       * we've seen a request to upload to this level we call
       * glTexImage2D first to assert that the storage for this
       * level exists.
       */
      if (texture->max_level < level)
        {
          ctx->glTexImage2D (gl_target,
                             level,
                             _cogl_texture_gl_get_format (texture),
                             level_width,
                             level_height,
                             0,
                             source_gl_format,
                             source_gl_type,
                             NULL);
        }

      ctx->glTexSubImage2D (gl_target,
                            level,
                            dst_x, dst_y,
                            width, height,
                            source_gl_format,
                            source_gl_type,
                            data);
    }

  if (_cogl_gl_util_catch_out_of_memory (ctx, error))
    status = FALSE;

  _cogl_bitmap_gl_unbind (slice_bmp);

  cogl_object_unref (slice_bmp);

  return status;
}
Esempio n. 7
0
static bool
_cg_texture_driver_upload_subregion_to_gl(cg_device_t *dev,
                                          cg_texture_t *texture,
                                          bool is_foreign,
                                          int src_x,
                                          int src_y,
                                          int dst_x,
                                          int dst_y,
                                          int width,
                                          int height,
                                          int level,
                                          cg_bitmap_t *source_bmp,
                                          GLuint source_gl_format,
                                          GLuint source_gl_type,
                                          cg_error_t **error)
{
    GLenum gl_target;
    GLuint gl_handle;
    uint8_t *data;
    cg_pixel_format_t source_format = cg_bitmap_get_format(source_bmp);
    int bpp = _cg_pixel_format_get_bytes_per_pixel(source_format);
    GLenum gl_error;
    bool status = true;
    cg_error_t *internal_error = NULL;
    int level_width;
    int level_height;

    cg_texture_get_gl_texture(texture, &gl_handle, &gl_target);

    data = _cg_bitmap_gl_bind(
        source_bmp, CG_BUFFER_ACCESS_READ, 0, &internal_error);

    /* NB: _cg_bitmap_gl_bind() may return NULL when successfull so we
     * have to explicitly check the cg error pointer to catch
     * problems... */
    if (internal_error) {
        _cg_propagate_error(error, internal_error);
        return false;
    }

    /* Setup gl alignment to match rowstride and top-left corner */
    prep_gl_for_pixels_upload_full(dev, cg_bitmap_get_rowstride(source_bmp),
                                   0, src_x, src_y, bpp);

    _cg_bind_gl_texture_transient(gl_target, gl_handle, is_foreign);

    /* Clear any GL errors */
    while ((gl_error = dev->glGetError()) != GL_NO_ERROR)
        ;

    _cg_texture_get_level_size(
        texture, level, &level_width, &level_height, NULL);

    if (level_width == width && level_height == height) {
        /* GL gets upset if you use glTexSubImage2D to initialize the
         * contents of a mipmap level so we make sure to use
         * glTexImage2D if we are uploading a full mipmap level.
         */
        dev->glTexImage2D(gl_target,
                          level,
                          _cg_texture_gl_get_format(texture),
                          width,
                          height,
                          0,
                          source_gl_format,
                          source_gl_type,
                          data);

    } else {
        /* GL gets upset if you use glTexSubImage2D to initialize the
         * contents of a mipmap level so if this is the first time
         * we've seen a request to upload to this level we call
         * glTexImage2D first to assert that the storage for this
         * level exists.
         */
        if (texture->max_level < level) {
            dev->glTexImage2D(gl_target,
                              level,
                              _cg_texture_gl_get_format(texture),
                              level_width,
                              level_height,
                              0,
                              source_gl_format,
                              source_gl_type,
                              NULL);
        }

        dev->glTexSubImage2D(gl_target,
                             level,
                             dst_x,
                             dst_y,
                             width,
                             height,
                             source_gl_format,
                             source_gl_type,
                             data);
    }

    if (_cg_gl_util_catch_out_of_memory(dev, error))
        status = false;

    _cg_bitmap_gl_unbind(source_bmp);

    return status;
}