Exemplo n.º 1
0
CoglBitmap *
_cogl_bitmap_from_file (const char  *filename,
			GError     **error)
{
  static CoglUserDataKey bitmap_data_key;
  CoglBitmap *bmp;
  int      stb_pixel_format;
  int      width;
  int      height;
  uint8_t  *pixels;

  _COGL_GET_CONTEXT (ctx, NULL);

  _COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, FALSE);

  /* Load from file using stb */
  pixels = stbi_load (filename,
                      &width, &height, &stb_pixel_format,
                      STBI_rgb_alpha);
  if (pixels == NULL)
    return FALSE;

  /* Store bitmap info */
  bmp = cogl_bitmap_new_for_data (ctx,
                                  width, height,
                                  COGL_PIXEL_FORMAT_RGBA_8888,
                                  width * 4, /* rowstride */
                                  pixels);
  /* Register a destroy function so the pixel data will be freed
     automatically when the bitmap object is destroyed */
  cogl_object_set_user_data (COGL_OBJECT (bmp), &bitmap_data_key, pixels, free);

  return bmp;
}
Exemplo n.º 2
0
CoglBitmap *
_cogl_bitmap_new_with_malloc_buffer (CoglContext *context,
                                     unsigned int width,
                                     unsigned int height,
                                     CoglPixelFormat format,
                                     CoglError **error)
{
  static CoglUserDataKey bitmap_free_key;
  int bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
  int rowstride = ((width * bpp) + 3) & ~3;
  uint8_t *data = g_try_malloc (rowstride * height);
  CoglBitmap *bitmap;

  if (!data)
    {
      _cogl_set_error (error,
                       COGL_SYSTEM_ERROR,
                       COGL_SYSTEM_ERROR_NO_MEMORY,
                       "Failed to allocate memory for bitmap");
      return NULL;
    }

  bitmap = cogl_bitmap_new_for_data (context,
                                     width, height,
                                     format,
                                     rowstride,
                                     data);
  cogl_object_set_user_data (COGL_OBJECT (bitmap),
                             &bitmap_free_key,
                             data,
                             g_free);

  return bitmap;
}
Exemplo n.º 3
0
CoglXlibRenderer *
_cogl_xlib_renderer_get_data (CoglRenderer *renderer)
{
  static CoglUserDataKey key;
  CoglXlibRenderer *data;

  /* Constructs a CoglXlibRenderer struct on demand and attaches it to
     the object using user data. It's done this way instead of using a
     subclassing hierarchy in the winsys data because all EGL winsys's
     need the EGL winsys data but only one of them wants the Xlib
     data. */

  data = cogl_object_get_user_data (COGL_OBJECT (renderer), &key);

  if (data == NULL)
    {
      data = g_slice_new0 (CoglXlibRenderer);

      cogl_object_set_user_data (COGL_OBJECT (renderer),
                                 &key,
                                 data,
                                 destroy_xlib_renderer_data);
    }

  return data;
}
static void
dirty_shader_state (CoglPipeline *pipeline)
{
  cogl_object_set_user_data (COGL_OBJECT (pipeline),
                             &shader_state_key,
                             NULL,
                             NULL);
}
Exemplo n.º 5
0
static void
set_glsl_priv (CoglPipeline *pipeline, CoglPipelineVertendPrivate *priv)
{
  cogl_object_set_user_data (COGL_OBJECT (pipeline),
                             &glsl_priv_key,
                             priv,
                             destroy_glsl_priv);
}
Exemplo n.º 6
0
static void
dirty_glsl_shader_state (CoglPipeline *pipeline)
{
  cogl_object_set_user_data (COGL_OBJECT (pipeline),
                             &glsl_priv_key,
                             NULL,
                             destroy_glsl_priv);
}
static void
set_shader_state (CoglPipeline *pipeline,
                  CoglPipelineShaderState *shader_state)
{
  cogl_object_set_user_data (COGL_OBJECT (pipeline),
                             &shader_state_key,
                             shader_state,
                             destroy_shader_state);
}
Exemplo n.º 8
0
CoglPipeline *
_cogl_pango_pipeline_cache_get (CoglPangoPipelineCache *cache,
                                CoglHandle texture)
{
  CoglPangoPipelineCacheEntry *entry;
  PipelineDestroyNotifyData *destroy_data;
  static CoglUserDataKey pipeline_destroy_notify_key;

  /* Look for an existing entry */
  entry = g_hash_table_lookup (cache->hash_table, texture);

  if (entry)
    return cogl_object_ref (entry->pipeline);

  /* No existing pipeline was found so let's create another */
  entry = g_slice_new (CoglPangoPipelineCacheEntry);

  if (texture)
    {
      CoglPipeline *base;

      entry->texture = cogl_object_ref (texture);

      if (cogl_texture_get_format (entry->texture) == COGL_PIXEL_FORMAT_A_8)
        base = get_base_texture_alpha_pipeline (cache);
      else
        base = get_base_texture_rgba_pipeline (cache);

      entry->pipeline = cogl_pipeline_copy (base);

      cogl_pipeline_set_layer_texture (entry->pipeline, 0 /* layer */, texture);
    }
  else
    {
      entry->texture = NULL;
      entry->pipeline = cogl_pipeline_new ();
    }

  /* Add a weak reference to the pipeline so we can remove it from the
     hash table when it is destroyed */
  destroy_data = g_slice_new (PipelineDestroyNotifyData);
  destroy_data->cache = cache;
  destroy_data->texture = texture;
  cogl_object_set_user_data (entry->pipeline,
                             &pipeline_destroy_notify_key,
                             destroy_data,
                             pipeline_destroy_notify_cb);

  g_hash_table_insert (cache->hash_table,
                       texture ? cogl_object_ref (texture) : NULL,
                       entry);

  /* This doesn't take a reference on the pipeline so that it will use
     the newly created reference */
  return entry->pipeline;
}
Exemplo n.º 9
0
static void
_rut_camera_flush_transforms (RutCamera *camera)
{
  const CoglMatrix *projection;
  CoglFramebuffer *fb = camera->fb;
  CameraFlushState *state;

  /* While a camera is in a suspended state then we don't expect to
   * _flush() and use that camera before it is restored. */
  g_return_if_fail (camera->suspended == FALSE);

  state = cogl_object_get_user_data (COGL_OBJECT (fb), &fb_camera_key);
  if (!state)
    {
      state = g_slice_new (CameraFlushState);
      cogl_object_set_user_data (COGL_OBJECT (fb),
                                 &fb_camera_key,
                                 state,
                                 free_camera_flush_state);
    }
  else if (state->current_camera == camera &&
           camera->transform_age == state->transform_age)
    goto done;

  if (camera->in_frame)
    {
      g_warning ("Un-balanced rut_camera_flush/_end calls: "
                 "repeat _flush() calls before _end()");
    }

  cogl_framebuffer_set_viewport (fb,
                                 camera->viewport[0],
                                 camera->viewport[1],
                                 camera->viewport[2],
                                 camera->viewport[3]);

  projection = rut_camera_get_projection (camera);
  cogl_framebuffer_set_projection_matrix (fb, projection);

  cogl_framebuffer_set_modelview_matrix (fb, &camera->view);

  state->current_camera = camera;
  state->transform_age = camera->transform_age;

done:
  camera->in_frame = TRUE;
}
Exemplo n.º 10
0
CoglBitmap *
_cogl_bitmap_from_file (const char   *filename,
			GError      **error)
{
  static CoglUserDataKey pixbuf_key;
  GdkPixbuf        *pixbuf;
  CoglBool          has_alpha;
  GdkColorspace     color_space;
  CoglPixelFormat   pixel_format;
  int               width;
  int               height;
  int               rowstride;
  int               bits_per_sample;
  int               n_channels;
  CoglBitmap       *bmp;

  _COGL_GET_CONTEXT (ctx, NULL);

  _COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, FALSE);

  /* Load from file using GdkPixbuf */
  pixbuf = gdk_pixbuf_new_from_file (filename, error);
  if (pixbuf == NULL)
    return FALSE;

  /* Get pixbuf properties */
  has_alpha       = gdk_pixbuf_get_has_alpha (pixbuf);
  color_space     = gdk_pixbuf_get_colorspace (pixbuf);
  width           = gdk_pixbuf_get_width (pixbuf);
  height          = gdk_pixbuf_get_height (pixbuf);
  rowstride       = gdk_pixbuf_get_rowstride (pixbuf);
  bits_per_sample = gdk_pixbuf_get_bits_per_sample (pixbuf);
  n_channels      = gdk_pixbuf_get_n_channels (pixbuf);

  /* According to current docs this should be true and so
   * the translation to cogl pixel format below valid */
  g_assert (bits_per_sample == 8);

  if (has_alpha)
    g_assert (n_channels == 4);
  else
    g_assert (n_channels == 3);

  /* Translate to cogl pixel format */
  switch (color_space)
    {
    case GDK_COLORSPACE_RGB:
      /* The only format supported by GdkPixbuf so far */
      pixel_format = has_alpha ?
	COGL_PIXEL_FORMAT_RGBA_8888 :
	COGL_PIXEL_FORMAT_RGB_888;
      break;

    default:
      /* Ouch, spec changed! */
      g_object_unref (pixbuf);
      return FALSE;
    }

  /* We just use the data directly from the pixbuf so that we don't
     have to copy to a seperate buffer. Note that Cogl is expected not
     to read past the end of bpp*width on the last row even if the
     rowstride is much larger so we don't need to worry about
     GdkPixbuf's semantics that it may under-allocate the buffer. */
  bmp = cogl_bitmap_new_for_data (ctx,
                                  width,
                                  height,
                                  pixel_format,
                                  rowstride,
                                  gdk_pixbuf_get_pixels (pixbuf));

  cogl_object_set_user_data (COGL_OBJECT (bmp),
                             &pixbuf_key,
                             pixbuf,
                             g_object_unref);

  return bmp;
}
Exemplo n.º 11
0
CoglHandle
meta_texture_rectangle_new (unsigned int width,
                            unsigned int height,
                            CoglTextureFlags flags,
                            CoglPixelFormat format,
                            GLenum internal_gl_format,
                            GLenum internal_format,
                            unsigned int rowstride,
                            const guint8 *data)
{
  CoglHandle cogl_tex = COGL_INVALID_HANDLE;

#ifdef GL_TEXTURE_RECTANGLE_ARB

  static CoglUserDataKey user_data_key;
  GLint old_binding;
  GLuint tex;

  if (pf_glGenTextures == NULL)
    {
      pf_glGetIntegerv = (void *) cogl_get_proc_address ("glGetIntegerv");
      pf_glTexImage2D = (void *) cogl_get_proc_address ("glTexImage2D");
      pf_glGenTextures = (void *) cogl_get_proc_address ("glGenTextures");
      pf_glDeleteTextures = (void *) cogl_get_proc_address ("glDeleteTextures");
      pf_glBindTexture = (void *) cogl_get_proc_address ("glBindTexture");
    }

  pf_glGenTextures (1, &tex);
  pf_glGetIntegerv (GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
  pf_glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex);
  pf_glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0,
                   internal_gl_format, width, height,
                   0, internal_gl_format,
                   GL_UNSIGNED_BYTE, NULL);
  pf_glBindTexture (GL_TEXTURE_RECTANGLE_ARB, old_binding);

  cogl_tex = cogl_texture_new_from_foreign (tex,
                                            GL_TEXTURE_RECTANGLE_ARB,
                                            width, height,
                                            0, 0, /* no waste */
                                            internal_format);

  /* Cogl won't destroy the GL texture when a foreign texture is used
     so we need to destroy it manually. We can set a destroy
     notification callback to do this transparently */
  cogl_object_set_user_data (cogl_tex,
                             &user_data_key,
                             GUINT_TO_POINTER (tex),
                             rectangle_texture_destroy_cb);

  /* Use cogl_texture_set_region instead of uploading the data
     directly with GL calls so that we can let Cogl deal with setting
     the pixel store parameters and handling format conversion */
  if (data)
    cogl_texture_set_region (cogl_tex,
                             0, 0, /* src x/y */
                             0, 0, /* dst x/y */
                             width, height, /* dst width/height */
                             width, height, /* src width/height */
                             format,
                             rowstride,
                             data);

#endif /* GL_TEXTURE_RECTANGLE_ARB */

  return cogl_tex;
}