示例#1
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;
}
示例#2
0
文件: rut-camera.c 项目: cee1/rig
void
rut_camera_suspend (RutCamera *camera)
{
  CameraFlushState *state;

  /* There's not point suspending a frame that hasn't been flushed */
  g_return_if_fail (camera->in_frame == TRUE);

  g_return_if_fail (camera->suspended == FALSE);

  state = cogl_object_get_user_data (COGL_OBJECT (camera->fb), &fb_camera_key);

  /* We only expect to be saving a camera that has been flushed */
  g_return_if_fail (state != NULL);

  /* While the camera is in a suspended state we aren't expecting the
   * camera to be touched but we want to double check that at least
   * the transform hasn't been touched when we come to resume the
   * camera... */
  camera->at_suspend_transform_age = camera->transform_age;

  /* When we resume the camer we'll need to restore the modelview,
   * projection and viewport transforms. The easiest way for us to
   * handle restoring the modelview is to use the framebuffer's
   * matrix stack... */
  cogl_framebuffer_push_matrix (camera->fb);

  camera->suspended = TRUE;
  camera->in_frame = FALSE;
}
示例#3
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;
}
示例#4
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;
}
示例#5
0
文件: rut-camera.c 项目: cee1/rig
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;
}
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
dirty_shader_state (CoglPipeline *pipeline)
{
  cogl_object_set_user_data (COGL_OBJECT (pipeline),
                             &shader_state_key,
                             NULL,
                             NULL);
}
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);
}
static void
set_glsl_priv (CoglPipeline *pipeline, CoglPipelineVertendPrivate *priv)
{
  cogl_object_set_user_data (COGL_OBJECT (pipeline),
                             &glsl_priv_key,
                             priv,
                             destroy_glsl_priv);
}
示例#10
0
void
_cogl_texture_associate_framebuffer (CoglHandle handle,
                                     CoglFramebuffer *framebuffer)
{
  CoglTexture *tex = COGL_TEXTURE (handle);
  static CoglUserDataKey framebuffer_destroy_notify_key;

  /* Note: we don't take a reference on the framebuffer here because
   * that would introduce a circular reference. */
  tex->framebuffers = g_list_prepend (tex->framebuffers, framebuffer);

  /* Since we haven't taken a reference on the framebuffer we setup
   * some private data so we will be notified if it is destroyed... */
  _cogl_object_set_user_data (COGL_OBJECT (framebuffer),
                              &framebuffer_destroy_notify_key,
                              tex,
                              _cogl_texture_framebuffer_destroy_cb);
}
static void
set_shader_state (CoglPipeline *pipeline, CoglPipelineShaderState *shader_state)
{
  if (shader_state)
    {
      shader_state->ref_count++;

      /* If we're not setting the state on the template pipeline then
       * mark it as a usage of the pipeline cache entry */
      if (shader_state->cache_entry &&
          shader_state->cache_entry->pipeline != pipeline)
        shader_state->cache_entry->usage_count++;
    }

  _cogl_object_set_user_data (COGL_OBJECT (pipeline),
                              &shader_state_key,
                              shader_state,
                              destroy_shader_state);
}
示例#12
0
文件: rut-camera.c 项目: cee1/rig
void
rut_camera_resume (RutCamera *camera)
{
  CameraFlushState *state;
  CoglFramebuffer *fb = camera->fb;

  g_return_if_fail (camera->in_frame == FALSE);
  g_return_if_fail (camera->suspended == TRUE);

  /* While a camera is in a suspended state we don't expect the camera
   * to be touched so its transforms shouldn't have changed... */
  g_return_if_fail (camera->at_suspend_transform_age == camera->transform_age);

  state = cogl_object_get_user_data (COGL_OBJECT (fb), &fb_camera_key);

  /* We only expect to be restoring a camera that has been flushed
   * before */
  g_return_if_fail (state != NULL);

  cogl_framebuffer_pop_matrix (fb);

  /* If the save turned out to be redundant then we have nothing
   * else to restore... */
  if (state->current_camera == camera)
    goto done;

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

  cogl_framebuffer_set_projection_matrix (fb, &camera->projection);

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

done:
  camera->in_frame = TRUE;
  camera->suspended = FALSE;
}
示例#13
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;
}
static CoglPipelineShaderState *
get_shader_state (CoglPipeline *pipeline)
{
  return cogl_object_get_user_data (COGL_OBJECT (pipeline), &shader_state_key);
}
示例#15
0
static CoglPipelineVertendPrivate *
get_glsl_priv (CoglPipeline *pipeline)
{
  return cogl_object_get_user_data (COGL_OBJECT (pipeline), &glsl_priv_key);
}
示例#16
0
static CoglBool
dump_layer_cb (CoglNode *node, void *user_data)
{
  CoglPipelineLayer *layer = COGL_PIPELINE_LAYER (node);
  PrintDebugState *state = user_data;
  int layer_id = *state->node_id_ptr;
  PrintDebugState state_out;
  GString *changes_label;
  CoglBool changes = FALSE;

  if (state->parent_id >= 0)
    g_string_append_printf (state->graph, "%*slayer%p -> layer%p;\n",
                            state->indent, "",
                            layer->_parent.parent,
                            layer);

  g_string_append_printf (state->graph,
                          "%*slayer%p [label=\"layer=0x%p\\n"
                          "ref count=%d\" "
                          "color=\"blue\"];\n",
                          state->indent, "",
                          layer,
                          layer,
                          COGL_OBJECT (layer)->ref_count);

  changes_label = g_string_new ("");
  g_string_append_printf (changes_label,
                          "%*slayer%p -> layer_state%d [weight=100];\n"
                          "%*slayer_state%d [shape=box label=\"",
                          state->indent, "",
                          layer,
                          layer_id,
                          state->indent, "",
                          layer_id);

  if (layer->differences & COGL_PIPELINE_LAYER_STATE_UNIT)
    {
      changes = TRUE;
      g_string_append_printf (changes_label,
                              "\\lunit=%u\\n",
                              layer->unit_index);
    }

  if (layer->differences & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA)
    {
      changes = TRUE;
      g_string_append_printf (changes_label,
                              "\\ltexture=%p\\n",
                              layer->texture);
    }

  if (changes)
    {
      g_string_append_printf (changes_label, "\"];\n");
      g_string_append (state->graph, changes_label->str);
      g_string_free (changes_label, TRUE);
    }

  state_out.parent_id = layer_id;

  state_out.node_id_ptr = state->node_id_ptr;
  (*state_out.node_id_ptr)++;

  state_out.graph = state->graph;
  state_out.indent = state->indent + 2;

  _cogl_pipeline_node_foreach_child (COGL_NODE (layer),
                                     dump_layer_cb,
                                     &state_out);

  return TRUE;
}
示例#17
0
static CoglBool
dump_pipeline_cb (CoglNode *node, void *user_data)
{
  CoglPipeline *pipeline = COGL_PIPELINE (node);
  PrintDebugState *state = user_data;
  int pipeline_id = *state->node_id_ptr;
  PrintDebugState state_out;
  GString *changes_label;
  CoglBool changes = FALSE;
  CoglBool layers = FALSE;

  if (state->parent_id >= 0)
    g_string_append_printf (state->graph, "%*spipeline%d -> pipeline%d;\n",
                            state->indent, "",
                            state->parent_id,
                            pipeline_id);

  g_string_append_printf (state->graph,
                          "%*spipeline%d [label=\"pipeline=0x%p\\n"
                          "ref count=%d\\n"
                          "breadcrumb=\\\"%s\\\"\" color=\"red\"];\n",
                          state->indent, "",
                          pipeline_id,
                          pipeline,
                          COGL_OBJECT (pipeline)->ref_count,
                          pipeline->has_static_breadcrumb ?
#ifdef COGL_DEBUG_ENABLED
                          pipeline->static_breadcrumb : "NULL"
#else
                          "NULL"
#endif
                          );

  changes_label = g_string_new ("");
  g_string_append_printf (changes_label,
                          "%*spipeline%d -> pipeline_state%d [weight=100];\n"
                          "%*spipeline_state%d [shape=box label=\"",
                          state->indent, "",
                          pipeline_id,
                          pipeline_id,
                          state->indent, "",
                          pipeline_id);


  if (pipeline->differences & COGL_PIPELINE_STATE_COLOR)
    {
      changes = TRUE;
      g_string_append_printf (changes_label,
                              "\\lcolor=0x%02X%02X%02X%02X\\n",
                              cogl_color_get_red_byte (&pipeline->color),
                              cogl_color_get_green_byte (&pipeline->color),
                              cogl_color_get_blue_byte (&pipeline->color),
                              cogl_color_get_alpha_byte (&pipeline->color));
    }

  if (pipeline->differences & COGL_PIPELINE_STATE_BLEND)
    {
      const char *blend_enable_name;

      changes = TRUE;

      switch (pipeline->blend_enable)
        {
        case COGL_PIPELINE_BLEND_ENABLE_AUTOMATIC:
          blend_enable_name = "AUTO";
          break;
        case COGL_PIPELINE_BLEND_ENABLE_ENABLED:
          blend_enable_name = "ENABLED";
          break;
        case COGL_PIPELINE_BLEND_ENABLE_DISABLED:
          blend_enable_name = "DISABLED";
          break;
        default:
          blend_enable_name = "UNKNOWN";
        }
      g_string_append_printf (changes_label,
                              "\\lblend=%s\\n",
                              blend_enable_name);
    }

  if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS)
    {
      changes = TRUE;
      layers = TRUE;
      g_string_append_printf (changes_label, "\\ln_layers=%d\\n",
                              pipeline->n_layers);
    }

  if (changes)
    {
      g_string_append_printf (changes_label, "\"];\n");
      g_string_append (state->graph, changes_label->str);
      g_string_free (changes_label, TRUE);
    }

  if (layers)
    {
      g_list_foreach (pipeline->layer_differences,
                      (GFunc)dump_layer_ref_cb,
                      state);
    }

  state_out.parent_id = pipeline_id;

  state_out.node_id_ptr = state->node_id_ptr;
  (*state_out.node_id_ptr)++;

  state_out.graph = state->graph;
  state_out.indent = state->indent + 2;

  _cogl_pipeline_node_foreach_child (COGL_NODE (pipeline),
                                     dump_pipeline_cb,
                                     &state_out);

  return TRUE;
}