Beispiel #1
0
static void
texture_tower_revalidate_fbo (MetaTextureTower *tower,
                              int               level)
{
  CoglTexture *source_texture = tower->textures[level - 1];
  int source_texture_width = cogl_texture_get_width (source_texture);
  int source_texture_height = cogl_texture_get_height (source_texture);
  CoglTexture *dest_texture = tower->textures[level];
  int dest_texture_width = cogl_texture_get_width (dest_texture);
  int dest_texture_height = cogl_texture_get_height (dest_texture);
  Box *invalid = &tower->invalid[level];
  CoglFramebuffer *fb;
  CoglError *catch_error = NULL;
  CoglPipeline *pipeline;

  if (tower->fbos[level] == NULL)
    tower->fbos[level] = cogl_offscreen_new_with_texture (dest_texture);

  fb = COGL_FRAMEBUFFER (tower->fbos[level]);

  if (!cogl_framebuffer_allocate (fb, &catch_error))
    {
      cogl_error_free (catch_error);
      return;
    }

  cogl_framebuffer_orthographic (fb, 0, 0, dest_texture_width, dest_texture_height, -1., 1.);

  if (!tower->pipeline_template)
    {
      CoglContext *ctx =
        clutter_backend_get_cogl_context (clutter_get_default_backend ());
      tower->pipeline_template = cogl_pipeline_new (ctx);
      cogl_pipeline_set_blend (tower->pipeline_template, "RGBA = ADD (SRC_COLOR, 0)", NULL);
    }

  pipeline = cogl_pipeline_copy (tower->pipeline_template);
  cogl_pipeline_set_layer_texture (pipeline, 0, tower->textures[level - 1]);

  cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
                                            invalid->x1, invalid->y1,
                                            invalid->x2, invalid->y2,
                                            (2. * invalid->x1) / source_texture_width,
                                            (2. * invalid->y1) / source_texture_height,
                                            (2. * invalid->x2) / source_texture_width,
                                            (2. * invalid->y2) / source_texture_height);

  cogl_object_unref (pipeline);
}
Beispiel #2
0
static VALUE
rb_cogl_texture_get_width (VALUE self)
{
  CoglHandle tex = rb_cogl_texture_get_handle (self);

  return UINT2NUM (cogl_texture_get_width (tex));
}
Beispiel #3
0
static void
pp_super_aa_paint (ClutterActor *actor)
{
  CoglHandle texture;
  gfloat width, height;

  PPSuperAAPrivate *priv = PP_SUPER_AA (actor)->priv;

  clutter_actor_get_size (actor, &width, &height);
  texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (actor));

  if (!texture ||
      (cogl_texture_get_width (texture) != (guint)(width * priv->x_res)) ||
      (cogl_texture_get_height (texture) != (guint)(height * priv->y_res)))
    {
      texture = cogl_texture_new_with_size ((guint)(width * priv->x_res),
                                            (guint)(height * priv->y_res),
                                            COGL_TEXTURE_NO_SLICING,
                                            COGL_PIXEL_FORMAT_RGBA_8888_PRE);
      clutter_texture_set_cogl_texture (CLUTTER_TEXTURE (actor), texture);
      cogl_handle_unref (texture);
    }

  CLUTTER_ACTOR_CLASS (pp_super_aa_parent_class)->paint (actor);
}
Beispiel #4
0
static void
_cogl_sub_texture_map_quad (CoglSubTexture *sub_tex,
                            float *coords)
{
  CoglTexture *tex = COGL_TEXTURE (sub_tex);

  /* NB: coords[] always come in as normalized coordinates but may go
   * out as non-normalized if sub_tex->full_texture is a
   * CoglTextureRectangle.
   *
   * NB: sub_tex->sub_x/y/width/height are in non-normalized
   * coordinates.
   */

  if (cogl_is_texture_rectangle (sub_tex->full_texture))
    {
      coords[0] = coords[0] * tex->width + sub_tex->sub_x;
      coords[1] = coords[1] * tex->height + sub_tex->sub_y;
      coords[2] = coords[2] * tex->width + sub_tex->sub_x;
      coords[3] = coords[3] * tex->height + sub_tex->sub_y;
    }
  else
    {
      float width = cogl_texture_get_width (sub_tex->full_texture);
      float height = cogl_texture_get_height (sub_tex->full_texture);
      coords[0] = (coords[0] * tex->width + sub_tex->sub_x) / width;
      coords[1] = (coords[1] * tex->height + sub_tex->sub_y) / height;
      coords[2] = (coords[2] * tex->width + sub_tex->sub_x) / width;
      coords[3] = (coords[3] * tex->height + sub_tex->sub_y) / height;
    }
}
CoglHandle
_st_create_shadow_material (StShadow   *shadow_spec,
                            CoglHandle  src_texture)
{
  static CoglHandle shadow_material_template = COGL_INVALID_HANDLE;

  CoglHandle  material;
  CoglHandle  texture;
  guchar     *pixels_in, *pixels_out;
  gint        width_in, height_in, rowstride_in;
  gint        width_out, height_out, rowstride_out;

  g_return_val_if_fail (shadow_spec != NULL, COGL_INVALID_HANDLE);
  g_return_val_if_fail (src_texture != COGL_INVALID_HANDLE,
                        COGL_INVALID_HANDLE);

  width_in  = cogl_texture_get_width  (src_texture);
  height_in = cogl_texture_get_height (src_texture);
  rowstride_in = (width_in + 3) & ~3;

  pixels_in  = g_malloc0 (rowstride_in * height_in);

  cogl_texture_get_data (src_texture, COGL_PIXEL_FORMAT_A_8,
                         rowstride_in, pixels_in);

  pixels_out = blur_pixels (pixels_in, width_in, height_in, rowstride_in,
                            shadow_spec->blur,
                            &width_out, &height_out, &rowstride_out);
  g_free (pixels_in);

  texture = cogl_texture_new_from_data (width_out,
                                        height_out,
                                        COGL_TEXTURE_NONE,
                                        COGL_PIXEL_FORMAT_A_8,
                                        COGL_PIXEL_FORMAT_A_8,
                                        rowstride_out,
                                        pixels_out);

  g_free (pixels_out);

  if (G_UNLIKELY (shadow_material_template == COGL_INVALID_HANDLE))
    {
      shadow_material_template = cogl_material_new ();

      /* We set up the material to blend the shadow texture with the combine
       * constant, but defer setting the latter until painting, so that we can
       * take the actor's overall opacity into account. */
      cogl_material_set_layer_combine (shadow_material_template, 0,
                                       "RGBA = MODULATE (CONSTANT, TEXTURE[A])",
                                       NULL);
    }

  material = cogl_material_copy (shadow_material_template);

  cogl_material_set_layer (material, 0, texture);

  cogl_handle_unref (texture);

  return material;
}
static void
cogl_pango_glyph_cache_update_position_cb (void *user_data,
                                           CoglTexture *new_texture,
                                           const CoglRectangleMapEntry *rect)
{
  CoglPangoGlyphCacheValue *value = user_data;
  float tex_width, tex_height;

  if (value->texture)
    cogl_object_unref (value->texture);
  value->texture = cogl_object_ref (new_texture);

  tex_width = cogl_texture_get_width (new_texture);
  tex_height = cogl_texture_get_height (new_texture);

  value->tx1 = rect->x / tex_width;
  value->ty1 = rect->y / tex_height;
  value->tx2 = (rect->x + value->draw_width) / tex_width;
  value->ty2 = (rect->y + value->draw_height) / tex_height;

  value->tx_pixel = rect->x;
  value->ty_pixel = rect->y;

  /* The glyph has changed position so it will need to be redrawn */
  value->dirty = TRUE;
}
Beispiel #7
0
static void
_cogl_sub_texture_unmap_quad (CoglSubTexture *sub_tex,
                              float *coords)
{
  CoglTexture *tex = COGL_TEXTURE (sub_tex);

  /* NB: coords[] come in as non-normalized if sub_tex->full_texture
   * is a CoglTextureRectangle otherwhise they are normalized. The
   * coordinates we write out though must always be normalized.
   *
   * NB: sub_tex->sub_x/y/width/height are in non-normalized
   * coordinates.
   */
  if (cogl_is_texture_rectangle (sub_tex->full_texture))
    {
      coords[0] = (coords[0] - sub_tex->sub_x) / tex->width;
      coords[1] = (coords[1] - sub_tex->sub_y) / tex->height;
      coords[2] = (coords[2] - sub_tex->sub_x) / tex->width;
      coords[3] = (coords[3] - sub_tex->sub_y) / tex->height;
    }
  else
    {
      float width = cogl_texture_get_width (sub_tex->full_texture);
      float height = cogl_texture_get_height (sub_tex->full_texture);
      coords[0] = (coords[0] * width - sub_tex->sub_x) / tex->width;
      coords[1] = (coords[1] * height - sub_tex->sub_y) / tex->height;
      coords[2] = (coords[2] * width - sub_tex->sub_x) / tex->width;
      coords[3] = (coords[3] * height - sub_tex->sub_y) / tex->height;
    }
}
static void
shell_grid_desaturate_effect_paint_target (ClutterOffscreenEffect *effect)
{
  ShellGridDesaturateEffect *self = SHELL_GRID_DESATURATE_EFFECT (effect);
  ClutterActor *actor;
  CoglHandle texture;
  guint8 paint_opacity;

  texture = clutter_offscreen_effect_get_texture (effect);
  cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);

  actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
  paint_opacity = clutter_actor_get_paint_opacity (actor);

  cogl_pipeline_set_color4ub (self->pipeline,
                              paint_opacity,
                              paint_opacity,
                              paint_opacity,
                              paint_opacity);
  cogl_push_source (self->pipeline);

  cogl_rectangle (0, 0,
                  cogl_texture_get_width (texture),
                  cogl_texture_get_height (texture));

  cogl_pop_source ();
}
Beispiel #9
0
static void
mx_toggle_get_preferred_width (ClutterActor *actor,
                               gfloat        for_height,
                               gfloat       *min_width_p,
                               gfloat       *pref_width_p)
{
  CoglHandle background;
  gfloat pref_w;

  background = mx_widget_get_background_texture (MX_WIDGET (actor));

  if (!background)
    {
      if (min_width_p)
        *min_width_p = 0;
      if (pref_width_p)
        *pref_width_p = 0;

      return;
    }

  pref_w = cogl_texture_get_width (background);

  if (min_width_p)
    *min_width_p = pref_w;

  if (pref_width_p)
    *pref_width_p = pref_w;
}
static void
update_unshaded_uniform (ShellGridDesaturateEffect *self)
{
  float values[4] = { 0., 0., 0., 0.};
  ClutterOffscreenEffect *offscreen_effect = CLUTTER_OFFSCREEN_EFFECT (self);
  CoglHandle texture;
  float width, height;

  if (self->unshaded_uniform == -1)
    return;

  texture = clutter_offscreen_effect_get_texture (offscreen_effect);
  if (texture == COGL_INVALID_HANDLE)
    goto out;

  width = cogl_texture_get_width (texture);
  height = cogl_texture_get_height (texture);

  values[0] = MIN (1.0, self->unshaded_rect->origin.x / width);
  values[1] = MIN (1.0, self->unshaded_rect->origin.y / height);
  values[2] = MIN (1.0, (self->unshaded_rect->origin.x + self->unshaded_rect->size.width) / width);
  values[3] = MIN (1.0, (self->unshaded_rect->origin.y + self->unshaded_rect->size.height) / height);

  self->unshaded_uniform_dirty = FALSE;

 out:
  cogl_pipeline_set_uniform_float (self->pipeline,
                                   self->unshaded_uniform,
                                   4, 1,
                                   values);
}
Beispiel #11
0
static void
set_texture (MetaScreenBackground *background,
             CoglHandle            texture)
{
  MetaDisplay *display = meta_screen_get_display (background->screen);
  GSList *l;

  /* This may trigger destruction of an old texture pixmap, which, if
   * the underlying X pixmap is already gone has the tendency to trigger
   * X errors inside DRI. For safety, trap errors */
  meta_error_trap_push (display);
  if (background->texture != COGL_INVALID_HANDLE)
    {
      cogl_handle_unref (background->texture);
      background->texture = COGL_INVALID_HANDLE;
    }
  meta_error_trap_pop (display);

  if (texture != COGL_INVALID_HANDLE)
    background->texture = cogl_handle_ref (texture);

  background->texture_width = cogl_texture_get_width (background->texture);
  background->texture_height = cogl_texture_get_height (background->texture);

  for (l = background->actors; l; l = l->next)
    set_texture_on_actor (l->data);

  update_wrap_mode (background);
}
Beispiel #12
0
static void
aisleriot_card_get_preferred_width (ClutterActor *self,
                                    ClutterUnit   for_height,
                                    ClutterUnit  *min_width_p,
                                    ClutterUnit  *natural_width_p)
{
  AisleriotCard *card = AISLERIOT_CARD (self);
  AisleriotCardPrivate *priv = card->priv;
  CoglHandle tex;
  guint width;

  tex = games_card_textures_cache_get_card_texture (priv->cache,
                                                    priv->top_card);

  if (G_UNLIKELY (tex == COGL_INVALID_HANDLE))
    width = 0;
  else
    width = cogl_texture_get_width (tex);

  if (min_width_p)
    *min_width_p = 0;

  if (natural_width_p)
    *natural_width_p = CLUTTER_UNITS_FROM_DEVICE (width);
}
Beispiel #13
0
static void
recorder_fetch_cursor_image (ShellRecorder *recorder)
{
  CoglTexture *texture;
  int width, height;
  int stride;
  guint8 *data;

  texture = meta_cursor_tracker_get_sprite (recorder->cursor_tracker);
  if (!texture)
    return;

  width = cogl_texture_get_width (texture);
  height = cogl_texture_get_height (texture);
  stride = 4 * width;
  data = g_new (guint8, stride * height);
  cogl_texture_get_data (texture, CLUTTER_CAIRO_FORMAT_ARGB32, stride, data);

  /* FIXME: cairo-gl? */
  recorder->cursor_image = cairo_image_surface_create_for_data (data,
                                                                CAIRO_FORMAT_ARGB32,
                                                                width, height,
                                                                stride);
  recorder->cursor_memory = data;
}
Beispiel #14
0
CoglPipeline *
_st_create_shadow_pipeline (StShadow    *shadow_spec,
                            CoglTexture *src_texture)
{
    ClutterBackend *backend = clutter_get_default_backend ();
    CoglContext *ctx = clutter_backend_get_cogl_context (backend);

    static CoglPipeline *shadow_pipeline_template = NULL;

    CoglPipeline *pipeline;
    CoglTexture *texture;
    guchar *pixels_in, *pixels_out;
    gint width_in, height_in, rowstride_in;
    gint width_out, height_out, rowstride_out;

    g_return_val_if_fail (shadow_spec != NULL, NULL);
    g_return_val_if_fail (src_texture != NULL, NULL);

    width_in  = cogl_texture_get_width  (src_texture);
    height_in = cogl_texture_get_height (src_texture);
    rowstride_in = (width_in + 3) & ~3;

    pixels_in  = g_malloc0 (rowstride_in * height_in);

    cogl_texture_get_data (src_texture, COGL_PIXEL_FORMAT_A_8,
                           rowstride_in, pixels_in);

    pixels_out = blur_pixels (pixels_in, width_in, height_in, rowstride_in,
                              shadow_spec->blur,
                              &width_out, &height_out, &rowstride_out);
    g_free (pixels_in);

    texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, width_out, height_out,
                            COGL_PIXEL_FORMAT_A_8,
                            rowstride_out,
                            pixels_out,
                            NULL));

    g_free (pixels_out);

    if (G_UNLIKELY (shadow_pipeline_template == NULL))
    {
        CoglContext *ctx =
            clutter_backend_get_cogl_context (clutter_get_default_backend ());

        shadow_pipeline_template = cogl_pipeline_new (ctx);

        /* We set up the pipeline to blend the shadow texture with the combine
         * constant, but defer setting the latter until painting, so that we can
         * take the actor's overall opacity into account. */
        cogl_pipeline_set_layer_combine (shadow_pipeline_template, 0,
                                         "RGBA = MODULATE (CONSTANT, TEXTURE[A])",
                                         NULL);
    }

    pipeline = cogl_pipeline_copy (shadow_pipeline_template);
    cogl_pipeline_set_layer_texture (pipeline, 0, texture);
    cogl_object_unref (texture);
    return pipeline;
}
Beispiel #15
0
static void
aisleriot_slot_renderer_paint_card (AisleriotSlotRenderer *srend,
                                    guint card_num)
{
  AisleriotSlotRendererPrivate *priv = srend->priv;
  Card card = CARD (priv->slot->cards->data[card_num]);
  CoglHandle cogl_tex;
  guint tex_width, tex_height;
  int cardx, cardy;

  cogl_tex = ar_card_textures_cache_get_card_texture (priv->cache, card);
  if (G_UNLIKELY (cogl_tex == COGL_INVALID_HANDLE))
    return;

  tex_width = cogl_texture_get_width (cogl_tex);
  tex_height = cogl_texture_get_height (cogl_tex);

  aisleriot_game_get_card_offset (priv->slot, card_num,
                                  FALSE,
                                  &cardx, &cardy);

  aisleriot_slot_renderer_set_material_for_card
    (srend, cogl_tex,
     priv->show_highlight && card_num >= priv->highlight_start);

  cogl_rectangle (cardx, cardy, cardx + tex_width, cardy + tex_height);
}
Beispiel #16
0
static void
st_background_effect_set_property (GObject      *gobject,
                                   guint         prop_id,
                                   const GValue *value,
                                   GParamSpec   *pspec)
{
  StBackgroundEffect *self = ST_BACKGROUND_EFFECT (gobject);

  switch (prop_id)
    {
    case PROP_BUMPMAP:

      self->bumpmap_location = g_value_dup_string (value);

      if (self->bg_bumpmap != NULL)
        {
          cogl_handle_unref (self->bg_bumpmap);
          self->bg_bumpmap = NULL;
        }

      if (self->bumpmap_location == NULL)
        {
          break;
        }

      GFile *file = g_file_new_for_path (g_strdup (self->bumpmap_location));
      if (g_file_query_exists (file, NULL))
        {
          self->bg_bumpmap = cogl_texture_new_from_file (self->bumpmap_location,
                                                         COGL_TEXTURE_NO_SLICING,
                                                         COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                                                         NULL);
        }

      g_object_unref (file);

      if (self->bg_bumpmap != NULL)
        {
          self->bumptex_width_i = cogl_texture_get_width (self->bg_bumpmap);
          self->bumptex_height_i = cogl_texture_get_height (self->bg_bumpmap);

          cogl_pipeline_set_layer_texture (self->pipeline0, 1, self->bg_bumpmap);
        }
      else
        {
          cogl_pipeline_set_layer_null_texture (self->pipeline0,
                                                1,
                                                COGL_TEXTURE_TYPE_2D);
        }

      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
      break;
    }
}
Beispiel #17
0
static void
mx_tooltip_allocate (ClutterActor          *self,
                     const ClutterActorBox *box,
                     ClutterAllocationFlags flags)
{
  MxTooltipPrivate *priv = MX_TOOLTIP (self)->priv;
  ClutterActorBox child_box;
  gfloat arrow_height, arrow_width;
  CoglHandle arrow_image;
  MxPadding padding;

  CLUTTER_ACTOR_CLASS (mx_tooltip_parent_class)->allocate (self,
                                                           box,
                                                           flags);

  mx_widget_get_padding (MX_WIDGET (self), &padding);

  arrow_image = mx_widget_get_background_texture (MX_WIDGET (self));

  if (arrow_image && !priv->actor_below)
    {
      arrow_height = cogl_texture_get_height (arrow_image);
      arrow_width = cogl_texture_get_width (arrow_image);

      priv->arrow_box.x1 = (float)(priv->arrow_offset) - (int)(arrow_width / 2);
      priv->arrow_box.y1 = 0;
      priv->arrow_box.x2 = priv->arrow_box.x1 + arrow_width;
      priv->arrow_box.y2 = arrow_height;
    }
  else
    {
      arrow_height = 0;
      arrow_width = 0;
    }

  child_box.x1 = child_box.y1 = 0;
  child_box.x2 = (box->x2 - box->x1);
  child_box.y2 = (box->y2 - box->y1);

  /* remove the space that is used by the arrow */
  child_box.y1 += arrow_height;

  priv->text_allocation = child_box;

  if (priv->label)
    {
      /* now remove the padding */
      child_box.y1 += padding.top;
      child_box.x1 += padding.left;
      child_box.x2 -= padding.right;
      child_box.y2 -= padding.bottom;

      clutter_actor_allocate (priv->label, &child_box, flags);
    }
}
static void
penge_magic_texture_paint (ClutterActor *actor)
{
  ClutterActorBox box;
  CoglHandle *material, *tex;
  float bw, bh;
  float aw, ah;
  float v;
  float tx1, tx2, ty1, ty2;
  guint8 alpha;

  clutter_actor_get_allocation_box (actor, &box);
  material = clutter_texture_get_cogl_material (CLUTTER_TEXTURE (actor));
  tex = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (actor));

  bw = (float) cogl_texture_get_width (tex); /* base texture width */
  bh = (float) cogl_texture_get_height (tex); /* base texture height */

  aw = (float) (box.x2 - box.x1); /* allocation width */
  ah = (float) (box.y2 - box.y1); /* allocation height */

  /* no comment */
  if ((float)bw/bh < (float)aw/ah)
  {
    /* fit width */
    v = (((float)ah * bw) / ((float)aw * bh)) / 2;
    tx1 = 0;
    tx2 = 1;
    ty1 = (0.5 - v);
    ty2 = (0.5 + v);
  } else {
    /* fit height */
    v = (((float)aw * bh) / ((float)ah * bw)) / 2;
    tx1 = (0.5 - v);
    tx2 = (0.5 + v);
    ty1 = 0;
    ty2 = 1;
  }

  alpha = clutter_actor_get_paint_opacity (actor);

  cogl_material_set_color4ub (material,
                              alpha,
                              alpha,
                              alpha,
                              alpha);

  cogl_set_source (material);
  cogl_rectangle_with_texture_coords (0, 0,
                                      aw, ah,
                                      tx1, ty1,
                                      tx2, ty2);
}
Beispiel #19
0
static void
clutter_image_paint_content (ClutterContent   *content,
                             ClutterActor     *actor,
                             ClutterPaintNode *root)
{
  ClutterImagePrivate *priv = CLUTTER_IMAGE (content)->priv;
  ClutterScalingFilter min_f, mag_f;
  ClutterContentRepeat repeat;
  ClutterPaintNode *node;
  ClutterActorBox box;
  ClutterColor color;
  guint8 paint_opacity;

  if (priv->texture == NULL)
    return;

  clutter_actor_get_content_box (actor, &box);
  paint_opacity = clutter_actor_get_paint_opacity (actor);
  clutter_actor_get_content_scaling_filters (actor, &min_f, &mag_f);
  repeat = clutter_actor_get_content_repeat (actor);

  /* ClutterTextureNode will premultiply the blend color, so we
   * want it to be white with the paint opacity
   */
  color.red = 255;
  color.green = 255;
  color.blue = 255;
  color.alpha = paint_opacity;

  node = clutter_texture_node_new (priv->texture, &color, min_f, mag_f);
  clutter_paint_node_set_name (node, "Image");

  if (repeat == CLUTTER_REPEAT_NONE)
    clutter_paint_node_add_rectangle (node, &box);
  else
    {
      float t_w = 1.f, t_h = 1.f;

      if ((repeat & CLUTTER_REPEAT_X_AXIS) != FALSE)
        t_w = (box.x2 - box.x1) / cogl_texture_get_width (priv->texture);

      if ((repeat & CLUTTER_REPEAT_Y_AXIS) != FALSE)
        t_h = (box.y2 - box.y1) / cogl_texture_get_height (priv->texture);

      clutter_paint_node_add_texture_rectangle (node, &box,
                                                0.f, 0.f,
                                                t_w, t_h);
    }

  clutter_paint_node_add_child (root, node);
  clutter_paint_node_unref (node);
}
Beispiel #20
0
/**
 * meta_texture_tower_set_base_texture:
 * @tower: a #MetaTextureTower
 * @texture: the new texture used as a base for scaled down versions
 *
 * Sets the base texture that is the scaled texture that the
 * scaled textures of the tower are derived from. The texture itself
 * will be used as level 0 of the tower and will be referenced until
 * unset or until the tower is freed.
 */
void
meta_texture_tower_set_base_texture (MetaTextureTower *tower,
                                     CoglTexture      *texture)
{
  int i;

  g_return_if_fail (tower != NULL);

  if (texture == tower->textures[0])
    return;

  if (tower->textures[0] != NULL)
    {
      for (i = 1; i < tower->n_levels; i++)
        {
          if (tower->textures[i] != NULL)
            {
              cogl_object_unref (tower->textures[i]);
              tower->textures[i] = NULL;
            }

          if (tower->fbos[i] != NULL)
            {
              cogl_object_unref (tower->fbos[i]);
              tower->fbos[i] = NULL;
            }
        }

      cogl_object_unref (tower->textures[0]);
    }

  tower->textures[0] = texture;

  if (tower->textures[0] != NULL)
    {
      int width, height;

      cogl_object_ref (tower->textures[0]);

      width = cogl_texture_get_width (tower->textures[0]);
      height = cogl_texture_get_height (tower->textures[0]);

      tower->n_levels = 1 + MAX ((int)(M_LOG2E * log (width)), (int)(M_LOG2E * log (height)));
      tower->n_levels = MIN(tower->n_levels, MAX_TEXTURE_LEVELS);

      meta_texture_tower_update_area (tower, 0, 0, width, height);
    }
  else
    {
      tower->n_levels = 0;
    }
}
Beispiel #21
0
static CoglBool
_cogl_sub_texture_can_hardware_repeat (CoglTexture *tex)
{
  CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex);

  /* We can hardware repeat if the subtexture actually represents all of the
     of the full texture */
  return (tex->width ==
          cogl_texture_get_width (sub_tex->full_texture) &&
          tex->height ==
          cogl_texture_get_height (sub_tex->full_texture) &&
          _cogl_texture_can_hardware_repeat (sub_tex->full_texture));
}
Beispiel #22
0
static void
aisleriot_slot_renderer_paint (ClutterActor *actor)
{
  AisleriotSlotRenderer *srend = (AisleriotSlotRenderer *) actor;
  AisleriotSlotRendererPrivate *priv = srend->priv;
  guint n_cards, n_animated_cards;
  guint i;

  g_return_if_fail (priv->cache != NULL);
  g_return_if_fail (priv->slot != NULL);

  n_cards = priv->slot->cards->len;
  n_animated_cards = priv->animations->len + priv->n_unexposed_animated_cards;

  g_assert (n_cards >= priv->slot->exposed);
  g_assert (priv->n_unexposed_animated_cards == 0 || priv->animations->len > 0);
  g_assert (n_cards >= n_animated_cards);

  if (n_cards <= n_animated_cards) {
    CoglHandle cogl_tex;
    guint tex_width, tex_height;

    cogl_tex = ar_card_textures_cache_get_slot_texture (priv->cache);
    if (G_UNLIKELY (cogl_tex == COGL_INVALID_HANDLE))
      return;

    tex_width = cogl_texture_get_width (cogl_tex);
    tex_height = cogl_texture_get_height (cogl_tex);

    aisleriot_slot_renderer_set_material_for_card (srend, cogl_tex,
                                                   priv->show_highlight);
    cogl_rectangle (0, 0, tex_width, tex_height);
  } else {
    guint first_card, last_card;

    first_card = MIN (n_cards - n_animated_cards - 1,
                      n_cards - priv->slot->exposed);
    last_card = n_cards - n_animated_cards;

    for (i = first_card; i < last_card; i++)
      if (i != priv->revealed_card)
        aisleriot_slot_renderer_paint_card (srend, i);

    /* Paint the revealed card after all of the other cards so that it
     * will appeear on top.
     */
    if (priv->revealed_card >= first_card && priv->revealed_card < last_card)
      aisleriot_slot_renderer_paint_card (srend, priv->revealed_card);
  }
}
static void
paint_cb (ClutterActor *actor)
{
  int stage_width = clutter_actor_get_width (actor);
  int stage_height = clutter_actor_get_height (actor);
  int image_width = cogl_texture_get_width (redhand);
  int image_height = cogl_texture_get_height (redhand);

  cogl_set_source (material);
  cogl_rectangle (stage_width/2.0f - image_width/2.0f,
                  stage_height/2.0f - image_height/2.0f,
                  stage_width/2.0f + image_width/2.0f,
                  stage_height/2.0f + image_height/2.0f);
}
Beispiel #24
0
static void
_draw_cursor_image (MetaCursorTracker     *tracker,
                    cairo_surface_t       *surface,
                    cairo_rectangle_int_t  area)
{
  CoglTexture *texture;
  int width, height;
  int stride;
  guint8 *data;
  cairo_surface_t *cursor_surface;
  cairo_region_t *screenshot_region;
  cairo_t *cr;
  int x, y;
  int xhot, yhot;

  screenshot_region = cairo_region_create_rectangle (&area);
  get_pointer_coords (&x, &y);

  if (!cairo_region_contains_point (screenshot_region, x, y))
    {
      cairo_region_destroy (screenshot_region);
      return;
    }

  texture = meta_cursor_tracker_get_sprite (tracker);
  meta_cursor_tracker_get_hot (tracker, &xhot, &yhot);
  width = cogl_texture_get_width (texture);
  height = cogl_texture_get_height (texture);
  stride = 4 * width;
  data = g_new (guint8, stride * height);
  cogl_texture_get_data (texture, CLUTTER_CAIRO_FORMAT_ARGB32, stride, data);

  /* FIXME: cairo-gl? */
  cursor_surface = cairo_image_surface_create_for_data (data,
                                                        CAIRO_FORMAT_ARGB32,
                                                        width, height,
                                                        stride);

  cr = cairo_create (surface);
  cairo_set_source_surface (cr,
                            cursor_surface,
                            x - xhot - area.x,
                            y - yhot - area.y);
  cairo_paint (cr);

  cairo_destroy (cr);
  cairo_surface_destroy (cursor_surface);
  cairo_region_destroy (screenshot_region);
  g_free (data);
}
Beispiel #25
0
CoglSubTexture *
cogl_sub_texture_new (CoglContext *ctx,
                      CoglTexture *next_texture,
                      int sub_x, int sub_y,
                      int sub_width, int sub_height)
{
  CoglTexture    *full_texture;
  CoglSubTexture *sub_tex;
  CoglTexture    *tex;
  unsigned int    next_width, next_height;

  next_width = cogl_texture_get_width (next_texture);
  next_height = cogl_texture_get_height (next_texture);

  /* The region must specify a non-zero subset of the full texture */
  _COGL_RETURN_VAL_IF_FAIL (sub_x >= 0 && sub_y >= 0, NULL);
  _COGL_RETURN_VAL_IF_FAIL (sub_width > 0 && sub_height > 0, NULL);
  _COGL_RETURN_VAL_IF_FAIL (sub_x + sub_width <= next_width, NULL);
  _COGL_RETURN_VAL_IF_FAIL (sub_y + sub_height <= next_height, NULL);

  sub_tex = g_new (CoglSubTexture, 1);

  tex = COGL_TEXTURE (sub_tex);

  _cogl_texture_init (tex, ctx, sub_width, sub_height,
                      _cogl_texture_get_format (next_texture),
                      NULL, /* no loader */
                      &cogl_sub_texture_vtable);

  /* If the next texture is also a sub texture we can avoid one level
     of indirection by referencing the full texture of that texture
     instead. */
  if (cogl_is_sub_texture (next_texture))
    {
      CoglSubTexture *other_sub_tex = COGL_SUB_TEXTURE (next_texture);
      full_texture = other_sub_tex->full_texture;
      sub_x += other_sub_tex->sub_x;
      sub_y += other_sub_tex->sub_y;
    }
  else
    full_texture = next_texture;

  sub_tex->next_texture = cogl_object_ref (next_texture);
  sub_tex->full_texture = cogl_object_ref (full_texture);

  sub_tex->sub_x = sub_x;
  sub_tex->sub_y = sub_y;

  return _cogl_sub_texture_object_new (sub_tex);
}
Beispiel #26
0
static CoglBool
_cogl_sub_texture_set_region (CoglTexture *tex,
                              int src_x,
                              int src_y,
                              int dst_x,
                              int dst_y,
                              int dst_width,
                              int dst_height,
                              int level,
                              CoglBitmap *bmp,
                              CoglError **error)
{
  CoglSubTexture  *sub_tex = COGL_SUB_TEXTURE (tex);

  if (level != 0)
    {
      int full_width = cogl_texture_get_width (sub_tex->full_texture);
      int full_height = cogl_texture_get_width (sub_tex->full_texture);

      _COGL_RETURN_VAL_IF_FAIL (sub_tex->sub_x == 0 &&
                                cogl_texture_get_width (tex) == full_width,
                                FALSE);
      _COGL_RETURN_VAL_IF_FAIL (sub_tex->sub_y == 0 &&
                                cogl_texture_get_height (tex) == full_height,
                                FALSE);
    }

  return cogl_texture_set_region_from_bitmap (sub_tex->full_texture,
                                              src_x, src_y,
                                              dst_width, dst_height,
                                              bmp,
                                              dst_x + sub_tex->sub_x,
                                              dst_y + sub_tex->sub_y,
                                              level,
                                              error);
}
Beispiel #27
0
static gboolean
get_texture_bits_via_copy (CoglHandle      texture_handle,
                           int             x,
                           int             y,
                           int             width,
                           int             height,
                           guint8         *dst_bits,
                           unsigned int    dst_rowstride,
                           CoglPixelFormat dst_format)
{
  CoglTexture *tex = COGL_TEXTURE (texture_handle);
  unsigned int full_rowstride;
  guint8 *full_bits;
  gboolean ret = TRUE;
  int bpp;
  int full_tex_width, full_tex_height;

  full_tex_width = cogl_texture_get_width (texture_handle);
  full_tex_height = cogl_texture_get_height (texture_handle);

  bpp = _cogl_get_format_bpp (dst_format);

  full_rowstride = bpp * full_tex_width;
  full_bits = g_malloc (full_rowstride * full_tex_height);

  if (tex->vtable->get_data (tex,
                             dst_format,
                             full_rowstride,
                             full_bits))
    {
      guint8 *dst = dst_bits;
      guint8 *src = full_bits + x * bpp + y * full_rowstride;
      int i;

      for (i = 0; i < height; i++)
        {
          memcpy (dst, src, bpp * width);
          dst += dst_rowstride;
          src += full_rowstride;
        }
    }
  else
    ret = FALSE;

  g_free (full_bits);

  return ret;
}
Beispiel #28
0
/**
 * meta_texture_tower_update_area:
 * @tower: a #MetaTextureTower
 * @x: X coordinate of upper left of rectangle that changed
 * @y: Y coordinate of upper left of rectangle that changed
 * @width: width of rectangle that changed
 * @height: height rectangle that changed
 *
 * Mark a region of the base texture as having changed; the next
 * time a scaled down version of the base texture is retrieved,
 * the appropriate area of the scaled down texture will be updated.
 */
void
meta_texture_tower_update_area (MetaTextureTower *tower,
                                int               x,
                                int               y,
                                int               width,
                                int               height)
{
  int texture_width, texture_height;
  Box invalid;
  int i;

  g_return_if_fail (tower != NULL);

  if (tower->textures[0] == NULL)
    return;

  texture_width = cogl_texture_get_width (tower->textures[0]);
  texture_height = cogl_texture_get_height (tower->textures[0]);

  invalid.x1 = x;
  invalid.y1 = y;
  invalid.x2 = x + width;
  invalid.y2 = y + height;

  for (i = 1; i < tower->n_levels; i++)
    {
      texture_width = MAX (1, texture_width / 2);
      texture_height = MAX (1, texture_height / 2);

      invalid.x1 = invalid.x1 / 2;
      invalid.y1 = invalid.y1 / 2;
      invalid.x2 = MIN (texture_width, (invalid.x2 + 1) / 2);
      invalid.y2 = MIN (texture_height, (invalid.y2 + 1) / 2);

      if (tower->invalid[i].x1 == tower->invalid[i].x2 ||
          tower->invalid[i].y1 == tower->invalid[i].y2)
        {
          tower->invalid[i] = invalid;
        }
      else
        {
          tower->invalid[i].x1 = MIN (tower->invalid[i].x1, invalid.x1);
          tower->invalid[i].y1 = MIN (tower->invalid[i].y1, invalid.y1);
          tower->invalid[i].x2 = MAX (tower->invalid[i].x2, invalid.x2);
          tower->invalid[i].y2 = MAX (tower->invalid[i].y2, invalid.y2);
        }
    }
}
Beispiel #29
0
static void
_cogl_sub_texture_transform_coords_to_gl (CoglTexture *tex,
                                          float *s,
                                          float *t)
{
  CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex);

  /* This won't work if the sub texture is not the size of the full
     texture and the coordinates are outside the range [0,1] */
  *s = ((*s * tex->width + sub_tex->sub_x) /
        cogl_texture_get_width (sub_tex->full_texture));
  *t = ((*t * tex->height + sub_tex->sub_y) /
        cogl_texture_get_height (sub_tex->full_texture));

  _cogl_texture_transform_coords_to_gl (sub_tex->full_texture, s, t);
}
/**
 * st_drawing_area_get_surface_size:
 * @area: the #StDrawingArea
 * @width: (out): location to store the width of the painted area
 * @height: (out): location to store the height of the painted area
 *
 * Gets the size of the cairo surface being painted to, which is equal
 * to the size of the content area of the widget. This function must
 * only be called from a signal hander for the ::repaint signal.
 */
void
st_drawing_area_get_surface_size (StDrawingArea *area,
                                  guint         *width,
                                  guint         *height)
{
  StDrawingAreaPrivate *priv;

  g_return_if_fail (ST_IS_DRAWING_AREA (area));
  g_return_if_fail (area->priv->in_repaint);

  priv = area->priv;

  if (width)
    *width = cogl_texture_get_width (priv->texture);
  if (height)
    *height = cogl_texture_get_height (priv->texture);
}