Esempio n. 1
0
static void
st_icon_paint (ClutterActor *actor)
{
  StIconPrivate *priv = ST_ICON (actor)->priv;

  /* Chain up to paint background */
  CLUTTER_ACTOR_CLASS (st_icon_parent_class)->paint (actor);

  if (priv->icon_texture)
    {
      if (priv->shadow_material)
        {
          ClutterActorBox allocation;
          float width, height;

          clutter_actor_get_allocation_box (priv->icon_texture, &allocation);
          clutter_actor_box_get_size (&allocation, &width, &height);

          allocation.x1 = (width - priv->shadow_width) / 2;
          allocation.y1 = (height - priv->shadow_height) / 2;
          allocation.x2 = allocation.x1 + priv->shadow_width;
          allocation.y2 = allocation.y1 + priv->shadow_height;

          _st_paint_shadow_with_opacity (priv->shadow_spec,
                                         priv->shadow_material,
                                         &allocation,
                                         clutter_actor_get_paint_opacity (priv->icon_texture));
        }

      clutter_actor_paint (priv->icon_texture);
    }
}
Esempio n. 2
0
static void
st_icon_paint (ClutterActor *actor)
{
  StIconPrivate *priv = ST_ICON (actor)->priv;

  st_widget_paint_background (ST_WIDGET (actor));

  if (priv->icon_texture)
    {
      if (priv->shadow_material)
        {
          ClutterActorBox allocation;
          float width, height;

          clutter_actor_get_allocation_box (priv->icon_texture, &allocation);
          clutter_actor_box_get_size (&allocation, &width, &height);

          _st_paint_shadow_with_opacity (priv->shadow_spec,
                                         priv->shadow_material,
                                         &allocation,
                                         clutter_actor_get_paint_opacity (priv->icon_texture));
        }

      clutter_actor_paint (priv->icon_texture);
    }
}
Esempio n. 3
0
static void
clutter_box_real_paint (ClutterActor *actor)
{
  ClutterBoxPrivate *priv = CLUTTER_BOX (actor)->priv;

  if (priv->color_set)
    {
      ClutterActorBox box = { 0, };
      gfloat width, height;
      guint8 tmp_alpha;

      clutter_actor_get_allocation_box (actor, &box);
      clutter_actor_box_get_size (&box, &width, &height);

      tmp_alpha = clutter_actor_get_paint_opacity (actor)
                * priv->color.alpha
                / 255;

      cogl_set_source_color4ub (priv->color.red,
                                priv->color.green,
                                priv->color.blue,
                                tmp_alpha);

      cogl_rectangle (0, 0, width, height);
    }

  g_list_foreach (priv->children, (GFunc) clutter_actor_paint, NULL);
}
Esempio n. 4
0
static void
glide_image_paint (ClutterActor *self)
{
  GlideImage *image = GLIDE_IMAGE (self);
  GlideImagePrivate *priv = image->priv;
  ClutterActorBox box = {0, };
  gfloat t_w, t_h;
  guint8 paint_opacity = clutter_actor_get_paint_opacity (self);

  if (paint_opacity == 0)
    {
      return;
    }
  
  GLIDE_NOTE (PAINT,
	      "painting image '%s'",
	      GLIDE_ACTOR_DISPLAY_NAME (self));
  
  cogl_material_set_color4ub (priv->material, paint_opacity, paint_opacity, paint_opacity, paint_opacity);
  clutter_actor_get_allocation_box (self, &box);
  
  GLIDE_NOTE (PAINT, "paint to x1: %f, y1: %f x2: %f, y2: %f "
	      "opacity: %i",
	      box.x1, box.y1, box.x2, box.y2,
	      clutter_actor_get_opacity (self));
  
  t_w = 1.0;
  t_h = 1.0;
  
  cogl_set_source (priv->material);
  cogl_rectangle_with_texture_coords (0, 0,
				      box.x2 - box.x1, box.y2 - box.y1,
				      0, 0, t_w, t_h);
}
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 ();
}
Esempio n. 6
0
static void
mex_tile_paint (ClutterActor *actor)
{
  MexTilePrivate *priv = MEX_TILE (actor)->priv;
  MxPadding padding;
  ClutterActorBox box;

  CLUTTER_ACTOR_CLASS (mex_tile_parent_class)->paint (actor);

  clutter_actor_paint (priv->child);

  mx_widget_get_padding (MX_WIDGET (actor), &padding);

  if (priv->header_visible)
    {
      clutter_actor_get_allocation_box (actor, &box);


      if (priv->header_background_color)
        {
          cogl_set_source_color4ub (priv->header_background_color->red,
                                    priv->header_background_color->green,
                                    priv->header_background_color->blue,
                                    priv->header_background_color->alpha);

          cogl_rectangle (padding.left, padding.top,
                          box.x2 - box.x1 - padding.right,
                          priv->header_height);
        }


      if (cogl_material_get_n_layers (priv->material) > 0)
        {
          guint8 opacity;

          opacity = clutter_actor_get_paint_opacity (actor);

          cogl_material_set_color4ub (priv->material, opacity, opacity, opacity,
                                      opacity);
          cogl_set_source (priv->material);

          cogl_rectangle (padding.left, padding.top,
                          box.x2 - box.x1 - padding.right,
                          priv->header_height);
        }

      clutter_actor_paint (priv->box_layout);

      if (priv->icon1)
        clutter_actor_paint (priv->icon1);

      if (priv->icon2)
        clutter_actor_paint (priv->icon2);
    }
}
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);
}
Esempio n. 8
0
static void
mx_fade_effect_paint_target (ClutterOffscreenEffect *effect)
{
  guint8 opacity;
  CoglColor color;
  ClutterActor *actor;

  CoglMaterial *material = clutter_offscreen_effect_get_target (effect);
  MxFadeEffect *self = MX_FADE_EFFECT (effect);
  MxFadeEffectPrivate *priv = self->priv;

  if (priv->update_vbo)
    mx_fade_effect_update_vbo (self);

  if (!priv->vbo || !priv->indices || !material)
    return;

  /* Set the blend string if the material has changed so we can blend with
   * the paint opacity.
   */
  if (material != priv->old_material)
    {
      GError *error = NULL;
      priv->old_material = material;

      if (!cogl_material_set_layer_combine (material, 1,
                                            "RGBA = MODULATE(PREVIOUS,CONSTANT)", &error))
        {
          g_warning (G_STRLOC ": Error setting layer combine blend string: %s",
                     error->message);
          g_error_free (error);
        }
    }

  /* Set the layer-combine constant so the texture is blended with the paint
   * opacity when painted.
   */
  actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
  opacity = clutter_actor_get_paint_opacity (actor);
  cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
  cogl_material_set_layer_combine_constant (material, 1, &color);

  /* Draw the texture */
  cogl_set_source (material);
  cogl_vertex_buffer_draw_elements (priv->vbo,
                                    COGL_VERTICES_MODE_TRIANGLES,
                                    priv->indices,
                                    0,
                                    (priv->n_quads * 4) - 1,
                                    0,
                                    priv->n_quads * 6);
}
Esempio n. 9
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);
}
Esempio n. 10
0
static void
st_widget_paint (ClutterActor *actor)
{
  StWidget *self = ST_WIDGET (actor);
  StThemeNode *theme_node;
  ClutterActorBox allocation;

  theme_node = st_widget_get_theme_node (self);

  clutter_actor_get_allocation_box (actor, &allocation);

  st_theme_node_paint (theme_node, &allocation, clutter_actor_get_paint_opacity (actor));
}
Esempio n. 11
0
static gboolean
draw_cb (ClutterCairoTexture *canvas,
         cairo_t *cr)
{
    EmpathyRoundedRectangle *self = EMPATHY_ROUNDED_RECTANGLE (canvas);
    guint width, height;
    guint border_width;
    gdouble tmp_alpha;
    gdouble radius;

    width = self->priv->width;
    height = self->priv->height;
    radius = self->priv->height / self->priv->round_factor;
    border_width = self->priv->border_width;

    /* compute the composited opacity of the actor taking into
     * account the opacity of the color set by the user */
    tmp_alpha = (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self))
                 * self->priv->border_color.alpha) / 255.;

    cairo_set_source_rgba (cr,
                           self->priv->border_color.red / 255.,
                           self->priv->border_color.green / 255.,
                           self->priv->border_color.blue / 255.,
                           tmp_alpha);

    cairo_set_line_width (cr, border_width);

    cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
    cairo_paint (cr);
    cairo_set_operator (cr, CAIRO_OPERATOR_OVER);

    /* make room for the portion of the border drawn on the outside */
    cairo_translate (cr, border_width/2.0, border_width/2.0);

    cairo_new_sub_path (cr);
    cairo_arc (cr, width - radius, radius, radius,
               -M_PI/2.0, 0);
    cairo_arc (cr, width - radius, height - radius, radius,
               0, M_PI/2.0);
    cairo_arc (cr, radius, height - radius, radius,
               M_PI/2.0, M_PI);
    cairo_arc (cr, radius, radius, radius,
               M_PI, -M_PI/2.0);
    cairo_close_path (cr);

    cairo_stroke (cr);

    return TRUE;
}
Esempio n. 12
0
static void
mnb_spinner_paint (ClutterActor *self)
{
  MnbSpinnerPrivate *priv   = MNB_SPINNER (self)->priv;
  MxWidget          *widget = MX_WIDGET (self);
  ClutterTexture    *background;

  /*
   * This paints border-image.
   */
  CLUTTER_ACTOR_CLASS (mnb_spinner_parent_class)->paint (self);

  if ((background = (ClutterTexture *) mx_widget_get_background_image (widget)))
    {
      gint            tx_w, tx_h;
      gfloat          tf_x, tf_y, tf_w, tf_h;
      guint8          opacity;
      ClutterActorBox box = { 0, };
      CoglHandle      material;

      if (!CLUTTER_IS_TEXTURE (background))
        return;

      opacity = clutter_actor_get_paint_opacity (self);

      if (opacity == 0)
        return;

      clutter_texture_get_base_size (background, &tx_w, &tx_h);

      material = clutter_texture_get_cogl_material (background);

      cogl_material_set_color4ub (material, opacity, opacity, opacity, opacity);

      clutter_actor_get_allocation_box (self, &box);

      tf_x = (gfloat)priv->frame / (gfloat) priv->n_frames;
      tf_y = 0.0;
      tf_w = tf_x + 1.0 / priv->n_frames;
      tf_h = 1.0;

      /* Paint will have translated us */
      cogl_set_source (material);
      cogl_rectangle_with_texture_coords (0.0, 0.0,
                                          box.x2 - box.x1,
                                          box.y2 - box.y1,
                                          tf_x, tf_y, tf_w, tf_h);
    }
}
Esempio n. 13
0
static void
meta_background_actor_paint (ClutterActor *actor)
{
  MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor);
  MetaBackgroundActorPrivate *priv = self->priv;
  guint8 opacity = clutter_actor_get_paint_opacity (actor);
  guint8 color_component;
  int width, height;

  meta_screen_get_size (priv->background->screen, &width, &height);

  color_component = (int)(0.5 + opacity * priv->dim_factor);

  cogl_material_set_color4ub (priv->material,
                              color_component,
                              color_component,
                              color_component,
                              opacity);

  cogl_set_source (priv->material);

  if (priv->visible_region)
    {
      int n_rectangles = cairo_region_num_rectangles (priv->visible_region);
      int i;

      for (i = 0; i < n_rectangles; i++)
        {
          cairo_rectangle_int_t rect;
          cairo_region_get_rectangle (priv->visible_region, i, &rect);

          cogl_rectangle_with_texture_coords (rect.x, rect.y,
                                              rect.x + rect.width, rect.y + rect.height,
                                              rect.x / priv->background->texture_width,
                                              rect.y / priv->background->texture_height,
                                              (rect.x + rect.width) / priv->background->texture_width,
                                              (rect.y + rect.height) / priv->background->texture_height);
        }
    }
  else
    {
      cogl_rectangle_with_texture_coords (0.0f, 0.0f,
                                          width, height,
                                          0.0f, 0.0f,
                                          width / priv->background->texture_width,
                                          height / priv->background->texture_height);
    }
}
static void
empathy_rounded_rectangle_paint (EmpathyRoundedRectangle *self)
{
  guint width, height;
  guint tmp_alpha;
  cairo_t *cr;

#define RADIUS (height / 8.)

  clutter_cairo_texture_get_surface_size (CLUTTER_CAIRO_TEXTURE (self),
      &width, &height);

  /* compute the composited opacity of the actor taking into
   * account the opacity of the color set by the user */
  tmp_alpha = clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self))
            * self->priv->border_color.alpha
            / 255;

  cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (self));

  cairo_set_source_rgba (cr,
      self->priv->border_color.red,
      self->priv->border_color.green,
      self->priv->border_color.blue,
      tmp_alpha);

  cairo_set_line_width (cr, self->priv->border_width);

  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
  cairo_paint (cr);
  cairo_set_operator (cr, CAIRO_OPERATOR_OVER);

  cairo_new_sub_path (cr);
  cairo_arc (cr, width - RADIUS, RADIUS, RADIUS,
      -M_PI/2.0, 0);
  cairo_arc (cr, width - RADIUS, height - RADIUS, RADIUS,
      0, M_PI/2.0);
  cairo_arc (cr, RADIUS, height - RADIUS, RADIUS,
      M_PI/2.0, M_PI);
  cairo_arc (cr, RADIUS, RADIUS, RADIUS,
      M_PI, -M_PI/2.0);
  cairo_close_path (cr);

  cairo_stroke (cr);
  cairo_destroy (cr);

#undef RADIUS
}
/*
 * MxWidget::paint_background vfunction implementation.
 */
static void
mpl_panel_background_paint_background (MxWidget           *self,
                                       ClutterActor       *background,
                                       const ClutterColor *color)
{
  MxPadding padding = { 0, };

  mx_widget_get_padding (self, &padding);

  /*
   * Paint any solid background colour that is not completely transparent.
   */
  if (color && color->alpha != 0)
    {
      ClutterActor *actor = CLUTTER_ACTOR (self);
      ClutterActorBox allocation = { 0, };
      ClutterColor bg_color = *color;
      gfloat w, h;

      bg_color.alpha = clutter_actor_get_paint_opacity (actor)
                       * bg_color.alpha
                       / 255;

      clutter_actor_get_allocation_box (actor, &allocation);

      w = allocation.x2 - allocation.x1;
      h = allocation.y2 - allocation.y1;

      cogl_set_source_color4ub (bg_color.red,
                                bg_color.green,
                                bg_color.blue,
                                bg_color.alpha);
      cogl_rectangle (padding.left, padding.top,
                      w - padding.left - padding.right,
                      h - padding.top - padding.bottom);
    }

  /*
   * Now paint the asset.
   */
  if (background)
    mpl_panel_background_paint_border_image (MX_TEXTURE_FRAME (background),
                                             &padding);
}
Esempio n. 16
0
static void
clutter_clone_paint (ClutterActor *actor)
{
  ClutterClone *self = CLUTTER_CLONE (actor);
  ClutterClonePrivate *priv = self->priv;
  gboolean was_unmapped = FALSE;

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

  CLUTTER_NOTE (PAINT, "painting clone actor '%s'",
                _clutter_actor_get_debug_name (actor));

  /* The final bits of magic:
   * - We need to override the paint opacity of the actor with our own
   *   opacity.
   * - We need to inform the actor that it's in a clone paint (for the function
   *   clutter_actor_is_in_clone_paint())
   * - We need to stop clutter_actor_paint applying the model view matrix of
   *   the clone source actor.
   */
  _clutter_actor_set_in_clone_paint (priv->clone_source, TRUE);
  _clutter_actor_set_opacity_override (priv->clone_source,
                                       clutter_actor_get_paint_opacity (actor));
  _clutter_actor_set_enable_model_view_transform (priv->clone_source, FALSE);

  if (!CLUTTER_ACTOR_IS_MAPPED (priv->clone_source))
    {
      _clutter_actor_set_enable_paint_unmapped (priv->clone_source, TRUE);
      was_unmapped = TRUE;
    }

  _clutter_actor_push_clone_paint ();
  clutter_actor_paint (priv->clone_source);
  _clutter_actor_pop_clone_paint ();

  if (was_unmapped)
    _clutter_actor_set_enable_paint_unmapped (priv->clone_source, FALSE);

  _clutter_actor_set_enable_model_view_transform (priv->clone_source, TRUE);
  _clutter_actor_set_opacity_override (priv->clone_source, -1);
  _clutter_actor_set_in_clone_paint (priv->clone_source, FALSE);
}
Esempio n. 17
0
static void
aisleriot_slot_renderer_set_material_for_card (AisleriotSlotRenderer *srend,
                                               CoglHandle tex,
                                               gboolean show_highlight)
{
  AisleriotSlotRendererPrivate *priv = srend->priv;
  guint8 opacity = clutter_actor_get_paint_opacity (CLUTTER_ACTOR (srend));

  if (priv->material == COGL_INVALID_HANDLE)
    priv->material = cogl_material_new ();

  if (show_highlight)
    {
      CoglColor color;

      /* The previous code for drawing the highlight rendered the
         normal card texture and then rendered the card again
         multiplied by the highlight color but with 50%
         transparency. The blend function is alpha*src+(1-alpha*dst)
         where src is effectively the tex times the highlight color
         and the dst is the original tex. Therefore the final color is
         0.5*tex+0.5*tex*highlight which is the same as
         (0.5+highlight/2)*tex. We can precompute that value to avoid
         having to draw the card twice */
      cogl_color_set_from_4ub (&color,
                               MIN (priv->highlight_color.red
                                    / 2 + 128, 0xff),
                               MIN (priv->highlight_color.green
                                    / 2 + 128, 0xff),
                               MIN (priv->highlight_color.blue
                                    / 2 + 128, 0xff),
                               opacity);
      cogl_color_premultiply (&color);
      cogl_material_set_color (priv->material, &color);
    }
  else
    cogl_material_set_color4ub (priv->material,
                                opacity, opacity, opacity, opacity);

  cogl_material_set_layer (priv->material, 0, tex);
  cogl_set_source (priv->material);
}
Esempio n. 18
0
static void
mx_tooltip_paint (ClutterActor *self)
{
  MxTooltipPrivate *priv = MX_TOOLTIP (self)->priv;
  gfloat width, height;
  CoglHandle arrow_image;
  guint alpha;

  clutter_actor_get_size (self, &width, &height);
  width = (gint)(width / 2.f);
  height = (gint)(height / 2.f);

  alpha = clutter_actor_get_paint_opacity (self);

  cogl_push_matrix ();
  cogl_translate (priv->text_allocation.x1,
                  priv->text_allocation.y1,
                  0);

  if (priv->border_image_texture)
    mx_texture_frame_paint_texture (priv->border_image_texture,
                                    alpha,
                                    priv->border_image->top,
                                    priv->border_image->right,
                                    priv->border_image->bottom,
                                    priv->border_image->left,
                                    priv->text_allocation.x2 - priv->text_allocation.x1,
                                    priv->text_allocation.y2 - priv->text_allocation.y1);
  cogl_pop_matrix ();

  arrow_image = mx_widget_get_background_texture (MX_WIDGET (self));
  if (arrow_image && !priv->actor_below)
    {
      _mx_paint_texture_with_opacity (arrow_image, alpha,
                                      priv->arrow_box.x1, priv->arrow_box.y1,
                                      priv->arrow_box.x2 - priv->arrow_box.x1,
                                      priv->arrow_box.y2 - priv->arrow_box.y1);
    }

  clutter_actor_paint (priv->label);
}
static void
shell_anamorphosis_effect_paint_target (ClutterOffscreenEffect *effect)
{
  ShellAnamorphosisEffect *self = SHELL_ANAMORPHOSIS_EFFECT (effect);
  ShellAnamorphosisEffectPrivate *priv = shell_anamorphosis_effect_get_instance_private (self);
  CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
  ClutterActor *actor;
  guint8 paint_opacity;

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


  cogl_pipeline_set_color4ub (priv->pipeline,
                              paint_opacity,
                              paint_opacity,
                              paint_opacity,
                              paint_opacity);

  cogl_framebuffer_draw_rectangle (fb, priv->pipeline,
                                   0, 0, priv->tex_width, priv->tex_height);
}
Esempio n. 20
0
static void trickplay_webgl_canvas_paint (ClutterActor *self)
{
  ClutterTexture *texture = CLUTTER_TEXTURE (self);
  guint8 paint_opacity = clutter_actor_get_paint_opacity (self);

  CoglMaterial * material = ( CoglMaterial * ) clutter_texture_get_cogl_material( texture );

  cogl_material_set_color4ub (material,
			      paint_opacity,
                              paint_opacity,
                              paint_opacity,
                              paint_opacity);

  cogl_set_source (material);

  ClutterActorBox box;

  clutter_actor_get_allocation_box (self, &box);

  cogl_rectangle_with_texture_coords ( 0 , 0 , box.x2 - box.x1 , box.y2 - box.y1 ,
			              0, 1, 1, 0);
}
Esempio n. 21
0
static void
clutter_colorize_effect_paint_target (ClutterOffscreenEffect *effect)
{
  ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect);
  CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
  ClutterActor *actor;
  guint8 paint_opacity;

  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_framebuffer_draw_rectangle (framebuffer,
                                   self->pipeline,
                                   0, 0,
                                   self->tex_width, self->tex_height);
}
Esempio n. 22
0
static void
shell_glsl_quad_paint (ClutterActor *actor)
{
  ShellGLSLQuad *self = SHELL_GLSL_QUAD (actor);
  ShellGLSLQuadPrivate *priv;
  guint8 paint_opacity;
  ClutterActorBox box;

  priv = shell_glsl_quad_get_instance_private (self);

  paint_opacity = clutter_actor_get_paint_opacity (actor);
  clutter_actor_get_allocation_box (actor, &box);

  cogl_pipeline_set_color4ub (priv->pipeline,
                              paint_opacity,
                              paint_opacity,
                              paint_opacity,
                              paint_opacity);
  cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
                                   priv->pipeline,
                                   box.x1, box.y1,
                                   box.x2, box.y2);
}
Esempio n. 23
0
static gboolean
st_background_effect_pre_paint (ClutterEffect *effect)
{
  StBackgroundEffect *self = ST_BACKGROUND_EFFECT (effect);
  ClutterEffectClass *parent_class;
  gfloat width;
  gfloat height;
  gfloat posx;
  gfloat posy;
  guchar *data;
  guint size;
  guint rowstride;
  glong new_time;
  gdouble time_used;
  ClutterActor *stage;
  gfloat stage_width;
  gfloat stage_height;

  if (self->bg_bumpmap == NULL)
    return FALSE;

  if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
    return FALSE;

  self->actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
  if (self->actor == NULL)
    return FALSE;

  if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
  {
    /* if we don't have support for GLSL shaders then we
     * forcibly disable the ActorMeta
     */
    g_warning ("Unable to use the ShaderEffect: the graphics hardware "
           "or the current GL driver does not implement support "
           "for the GLSL shading language.");
    clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
    return FALSE;
  }

  new_time = clock();
  time_used = ((double) (new_time - self->old_time)*100) / (double) CLOCKS_PER_SEC;
  self->old_time = new_time;

  posx = 0.0f;
  posy = 0.0f;

  width = 0.0f;
  height = 0.0f;

  stage_width = 0.0f;
  stage_height = 0.0f;

  clutter_actor_get_transformed_position (self->actor, &posx, &posy);
  clutter_actor_get_transformed_size (self->actor, &width, &height);
  self->opacity = clutter_actor_get_paint_opacity (self->actor);
  stage = clutter_actor_get_stage (self->actor);
  clutter_actor_get_size (stage, &stage_width, &stage_height);

  if ((posx < 0) || (posy < 0) || ((posx + width) > stage_width) || ((posy + height) > stage_height))
    return FALSE;

  if  (( posx != self->posx_old)
       || ( posy != self->posy_old)
       || ( width != self->width_old)
       || ( height != self->height_old)
       || (time_used > 50.0))

  {
    self->posx_old = posx;
    self->posy_old = posy;
    self->width_old = width;
    self->height_old = height;

    self->bg_posx_i = round(posx)+2;
    self->bg_posy_i = round(posy)+2;
    self->bg_width_i = round(width)-4;
    self->bg_height_i = round(height)-4;

    size = (self->bg_width_i) * (self->bg_height_i) * 4;

    if (((self->opacity == 0xff) || (self->bg_texture == NULL)) && (size > 400))
      {
        rowstride = (self->bg_width_i) * 4;


        data = g_malloc (size);

        cogl_read_pixels (self->bg_posx_i,
                          self->bg_posy_i,
                          self->bg_width_i,
                          self->bg_height_i,
                          COGL_READ_PIXELS_COLOR_BUFFER,
                          COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                          data);

        if (data != NULL)
          {

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

            self->bg_texture = st_cogl_texture_new_from_data_wrapper  (self->bg_width_i,
                                                                       self->bg_height_i,
                                                                       COGL_TEXTURE_NO_SLICING,
                                                                       COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                                                                       COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                                                                       rowstride,
                                                                       data);

            g_free (data);

          }
      }
  }

  parent_class = CLUTTER_EFFECT_CLASS (st_background_effect_parent_class);

  if (parent_class->pre_paint (effect))
    {
      ClutterOffscreenEffect *offscreen_effect =  CLUTTER_OFFSCREEN_EFFECT (effect);
      CoglHandle fg_texture;

      fg_texture = clutter_offscreen_effect_get_texture (offscreen_effect);

      if (fg_texture != COGL_INVALID_HANDLE)
        {
          self->fg_width_i = cogl_texture_get_width (fg_texture);
          self->fg_height_i = cogl_texture_get_height (fg_texture);

          if ((self->bg_texture != NULL) && (self->opacity == 0xff))
            {


              if (self->pixel_step_uniform0 > -1)
                {
                  gfloat pixel_step[3];

                  pixel_step[0] = 1.0f / (self->bg_width_i);
                  pixel_step[1] = 1.0f / (self->bg_height_i);
                  pixel_step[2] = 0.0f;

                  cogl_pipeline_set_uniform_float (self->pipeline0,
                                                   self->pixel_step_uniform0,
                                                   3,
                                                   1,
                                                   pixel_step);
                }

              if (self->BumpTex_uniform > -1)
                {

                  cogl_pipeline_set_uniform_1i (self->pipeline0,
                                                self->BumpTex_uniform,
                                                1);
                }

              if (self->bump_step_uniform > -1)
                {
                  gfloat bump_step[2];

                  bump_step[0] = 1.0f / (self->bumptex_width_i);
                  bump_step[1] = 1.0f / (self->bumptex_height_i);

                  cogl_pipeline_set_uniform_float (self->pipeline0,
                                                   self->bump_step_uniform,
                                                   2,
                                                   1,
                                                   bump_step);
                }

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

              self->bg_sub_texture = st_cogl_texture_new_with_size_wrapper (self->bg_width_i, self->bg_height_i,
                                                                            COGL_TEXTURE_NO_SLICING,
                                                                            COGL_PIXEL_FORMAT_RGBA_8888_PRE);

              cogl_pipeline_set_layer_texture (self->pipeline0, 0, self->bg_texture);

              if (self->pixel_step_uniform1 > -1)
                {
                  gfloat pixel_step[3];

                  pixel_step[0] = 1.0f / (self->bg_width_i);
                  pixel_step[1] = 1.0f / (self->bg_height_i);
                  pixel_step[2] = 1.0f;

                  cogl_pipeline_set_uniform_float (self->pipeline1,
                                                   self->pixel_step_uniform1,
                                                   3,
                                                   1,
                                                   pixel_step);
                }

              if (self->pixel_step_uniform2 > -1)
                {
                  gfloat pixel_step[3];

                  pixel_step[0] = 1.0f / (self->fg_width_i);
                  pixel_step[1] = 1.0f / (self->fg_height_i);
                  pixel_step[2] = 2.0f;

                  cogl_pipeline_set_uniform_float (self->pipeline3,
                                                   self->pixel_step_uniform2,
                                                   3,
                                                   1,
                                                   pixel_step);
                }

            }

          cogl_pipeline_set_layer_texture (self->pipeline2, 0, fg_texture);
          cogl_pipeline_set_layer_texture (self->pipeline3, 0, fg_texture);
          cogl_pipeline_set_layer_texture (self->pipeline4, 0, fg_texture);

        }
      return TRUE;
    }
  else
    {
      return FALSE;
    }
}
Esempio n. 24
0
static void
meta_window_group_paint (ClutterActor *actor)
{
  cairo_region_t *visible_region;
  ClutterActor *stage;
  cairo_rectangle_int_t visible_rect;
  GList *children, *l;
  int paint_x_origin, paint_y_origin;
  int actor_x_origin, actor_y_origin;
  int paint_x_offset, paint_y_offset;

  MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
  MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen);

  /* Normally we expect an actor to be drawn at it's position on the screen.
   * However, if we're inside the paint of a ClutterClone, that won't be the
   * case and we need to compensate. We look at the position of the window
   * group under the current model-view matrix and the position of the actor.
   * If they are both simply integer translations, then we can compensate
   * easily, otherwise we give up.
   *
   * Possible cleanup: work entirely in paint space - we can compute the
   * combination of the model-view matrix with the local matrix for each child
   * actor and get a total transformation for that actor for how we are
   * painting currently, and never worry about how actors are positioned
   * on the stage.
   */
  if (!painting_untransformed (window_group, &paint_x_origin, &paint_y_origin) ||
      !meta_actor_is_untransformed (actor, &actor_x_origin, &actor_y_origin))
    {
      CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);
      return;
    }

  paint_x_offset = paint_x_origin - actor_x_origin;
  paint_y_offset = paint_y_origin - actor_y_origin;

  /* We walk the list from top to bottom (opposite of painting order),
   * and subtract the opaque area of each window out of the visible
   * region that we pass to the windows below.
   */
  children = clutter_actor_get_children (actor);
  children = g_list_reverse (children);

  /* Get the clipped redraw bounds from Clutter so that we can avoid
   * painting shadows on windows that don't need to be painted in this
   * frame. In the case of a multihead setup with mismatched monitor
   * sizes, we could intersect this with an accurate union of the
   * monitors to avoid painting shadows that are visible only in the
   * holes. */
  stage = clutter_actor_get_stage (actor);
  clutter_stage_get_redraw_clip_bounds (CLUTTER_STAGE (stage),
                                        &visible_rect);

  visible_region = cairo_region_create_rectangle (&visible_rect);

  if (info->unredirected_window != NULL)
    {
      cairo_rectangle_int_t unredirected_rect;
      MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window);

      meta_window_get_outer_rect (window, (MetaRectangle *)&unredirected_rect);
      cairo_region_subtract_rectangle (visible_region, &unredirected_rect);
    }

  for (l = children; l; l = l->next)
    {
      if (!CLUTTER_ACTOR_IS_VISIBLE (l->data))
        continue;

      if (l->data == info->unredirected_window)
        continue;

      /* If an actor has effects applied, then that can change the area
       * it paints and the opacity, so we no longer can figure out what
       * portion of the actor is obscured and what portion of the screen
       * it obscures, so we skip the actor.
       *
       * This has a secondary beneficial effect: if a ClutterOffscreenEffect
       * is applied to an actor, then our clipped redraws interfere with the
       * caching of the FBO - even if we only need to draw a small portion
       * of the window right now, ClutterOffscreenEffect may use other portions
       * of the FBO later. So, skipping actors with effects applied also
       * prevents these bugs.
       *
       * Theoretically, we should check clutter_actor_get_offscreen_redirect()
       * as well for the same reason, but omitted for simplicity in the
       * hopes that no-one will do that.
       */
      if (clutter_actor_has_effects (l->data))
        continue;

      if (META_IS_WINDOW_ACTOR (l->data))
        {
          MetaWindowActor *window_actor = l->data;
          int x, y;

          if (!meta_actor_is_untransformed (CLUTTER_ACTOR (window_actor), &x, &y))
            continue;

          x += paint_x_offset;
          y += paint_y_offset;

          /* Temporarily move to the coordinate system of the actor */
          cairo_region_translate (visible_region, - x, - y);

          meta_window_actor_set_visible_region (window_actor, visible_region);

          if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff)
            {
              cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (window_actor);
              if (obscured_region)
                cairo_region_subtract (visible_region, obscured_region);
            }

          meta_window_actor_set_visible_region_beneath (window_actor, visible_region);
          cairo_region_translate (visible_region, x, y);
        }
      else if (META_IS_BACKGROUND_ACTOR (l->data) ||
               META_IS_BACKGROUND_GROUP (l->data))
        {
          ClutterActor *background_actor = l->data;
          int x, y;

          if (!meta_actor_is_untransformed (CLUTTER_ACTOR (background_actor), &x, &y))
            continue;

          x += paint_x_offset;
          y += paint_y_offset;

          cairo_region_translate (visible_region, - x, - y);

          if (META_IS_BACKGROUND_GROUP (background_actor))
            meta_background_group_set_visible_region (META_BACKGROUND_GROUP (background_actor), visible_region);
          else
            meta_background_actor_set_visible_region (META_BACKGROUND_ACTOR (background_actor), visible_region);
          cairo_region_translate (visible_region, x, y);
        }
    }

  cairo_region_destroy (visible_region);

  CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);

  /* Now that we are done painting, unset the visible regions (they will
   * mess up painting clones of our actors)
   */
  for (l = children; l; l = l->next)
    {
      if (META_IS_WINDOW_ACTOR (l->data))
        {
          MetaWindowActor *window_actor = l->data;
          meta_window_actor_reset_visible_regions (window_actor);
        }
      else if (META_IS_BACKGROUND_ACTOR (l->data))
        {
          MetaBackgroundActor *background_actor = l->data;
          meta_background_actor_set_visible_region (background_actor, NULL);
        }
    }

  g_list_free (children);
}
Esempio n. 25
0
static void
mnb_toolbar_background_paint_background (MxWidget           *self,
                                         ClutterActor       *background,
                                         const ClutterColor *color)
{
  MnbToolbarBackgroundPrivate *priv = TOOLBAR_BACKGROUND_PRIVATE (self);
  ClutterActor *actor = (ClutterActor *) self;
  CoglHandle cogl_texture, cogl_material;
  ClutterActorBox box = { 0, };
  gfloat width, height;
  gfloat tex_width, tex_height;
  gfloat ex, ey;
  gfloat tx1, ty1, tx2, ty2;
  guint8 opacity;

  /* Copied from MxWidget:
   *
   * Default implementation just draws the background
   * colour and the image on top
   */
  if (color && color->alpha != 0)
    {
      ClutterColor bg_color = *color;

      bg_color.alpha = clutter_actor_get_paint_opacity (actor)
                       * bg_color.alpha
                       / 255;

      clutter_actor_get_allocation_box (actor, &box);

      width = box.x2 - box.x1;
      height = box.y2 - box.y1;

      cogl_set_source_color4ub (bg_color.red,
                                bg_color.green,
                                bg_color.blue,
                                bg_color.alpha);
      cogl_rectangle (0, 0, width, height);
    }

  /*
   * Copied from MxTextureFrame
   */

  /* no need to paint stuff if we don't have a texture */
  if (G_UNLIKELY (priv->parent_texture == NULL))
    return;

  cogl_texture = clutter_texture_get_cogl_texture (priv->parent_texture);
  if (cogl_texture == COGL_INVALID_HANDLE)
    return;
  cogl_material = clutter_texture_get_cogl_material (priv->parent_texture);
  if (cogl_material == COGL_INVALID_HANDLE)
    return;

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

  clutter_actor_get_allocation_box (actor, &box);
  width = box.x2 - box.x1;
  height = box.y2 - box.y1;

  opacity = clutter_actor_get_paint_opacity (actor);

  /* Paint using the parent texture's material. It should already have
     the cogl texture set as the first layer */
  /* NB: for correct blending we need set a preumultiplied color here: */
  cogl_material_set_color4ub (cogl_material,
                              opacity, opacity, opacity, opacity);

  selector_texture = mnb_toolbar_get_selector_texture (priv->toolbar);

  cogl_material_set_layer (cogl_material, 1, selector_texture);
  cogl_material_set_layer_wrap_mode (cogl_material, 1,
                                     COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE);

  if (!cogl_material_set_layer_combine (cogl_material, 1,
                                        "RGBA = MODULATE(PREVIOUS,TEXTURE)",
                                        &error))
    {
      g_warning (G_STRLOC ": Error setting layer combine blend string: %s",
                 error->message);
      g_error_free (error);
    }

  cogl_set_source (cogl_material);

  /* simple stretch */
  if (priv->left == 0 && priv->right == 0 && priv->top == 0
      && priv->bottom == 0)
    {
      float spot_width, spot_height;
      float coords[8] = {
        0, 0, 1, 1,
        0, 0, 0, 0
      };

      mnb_toolbar_get_selector_allocation_box (priv->toolbar, &box);
      spot_width = box.x2 - box.x1;
      spot_height = box.y2 - box.y1;
      coords[4] = -(box.x1 / width) * (width / spot_width);
      coords[5] = -(box.y1 / height) * (height / spot_height);
      coords[6] = width / spot_width - (box.x1 / width) * (width / spot_width);
      coords[7] = height / spot_height - (box.y1 / height) * (height / spot_height);
      cogl_rectangle_with_multitexture_coords (0, 0, width, height, coords, 8);
      return;
    }

  tx1 = priv->left / tex_width;
  tx2 = (tex_width - priv->right) / tex_width;
  ty1 = priv->top / tex_height;
  ty2 = (tex_height - priv->bottom) / tex_height;

  ex = width - priv->right;
  if (ex < priv->left)
    ex = priv->left;

  ey = height - priv->bottom;
  if (ey < priv->top)
    ey = priv->top;

  {
    GLfloat rectangles[] =
    {
      /* top left corner */
      0, 0,
      priv->left, priv->top,
      0.0, 0.0,
      tx1, ty1,

      /* top middle */
      priv->left, 0,
      MAX (priv->left, ex), priv->top,
      tx1, 0.0,
      tx2, ty1,

      /* top right */
      ex, 0,
      MAX (ex + priv->right, width), priv->top,
      tx2, 0.0,
      1.0, ty1,

      /* mid left */
      0, priv->top,
      priv->left,  ey,
      0.0, ty1,
      tx1, ty2,

      /* center */
      priv->left, priv->top,
      ex, ey,
      tx1, ty1,
      tx2, ty2,

      /* mid right */
      ex, priv->top,
      MAX (ex + priv->right, width), ey,
      tx2, ty1,
      1.0, ty2,

      /* bottom left */
      0, ey,
      priv->left, MAX (ey + priv->bottom, height),
      0.0, ty2,
      tx1, 1.0,

      /* bottom center */
      priv->left, ey,
      ex, MAX (ey + priv->bottom, height),
      tx1, ty2,
      tx2, 1.0,

      /* bottom right */
      ex, ey,
      MAX (ex + priv->right, width), MAX (ey + priv->bottom, height),
      tx2, ty2,
      1.0, 1.0
    };

    cogl_rectangles_with_texture_coords (rectangles, 9);
  }
}
Esempio n. 26
0
static void
clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect)
{
  ClutterDeformEffect *self= CLUTTER_DEFORM_EFFECT (effect);
  ClutterDeformEffectPrivate *priv = self->priv;
  CoglHandle material;
  CoglPipeline *pipeline;
  CoglDepthState depth_state;
  CoglFramebuffer *fb = cogl_get_draw_framebuffer ();

  if (priv->is_dirty)
    {
      ClutterRect rect;
      gboolean mapped_buffer;
      CoglVertexP3T2C4 *verts;
      ClutterActor *actor;
      gfloat width, height;
      guint opacity;
      gint i, j;

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

      /* if we don't have a target size, fall back to the actor's
       * allocation, though wrong it might be
       */
      if (clutter_offscreen_effect_get_target_rect (effect, &rect))
        {
          width = clutter_rect_get_width (&rect);
          height = clutter_rect_get_height (&rect);
        }
      else
        clutter_actor_get_size (actor, &width, &height);

      /* XXX ideally, the sub-classes should tell us what they
       * changed in the texture vertices; we then would be able to
       * avoid resubmitting the same data, if it did not change. for
       * the time being, we resubmit everything
       */
      verts = cogl_buffer_map (COGL_BUFFER (priv->buffer),
                               COGL_BUFFER_ACCESS_WRITE,
                               COGL_BUFFER_MAP_HINT_DISCARD);

      /* If the map failed then we'll resort to allocating a temporary
         buffer */
      if (verts == NULL)
        {
          mapped_buffer = FALSE;
          verts = g_malloc (sizeof (*verts) * priv->n_vertices);
        }
      else
        mapped_buffer = TRUE;

      for (i = 0; i < priv->y_tiles + 1; i++)
        {
          for (j = 0; j < priv->x_tiles + 1; j++)
            {
              CoglVertexP3T2C4 *vertex_out;
              CoglTextureVertex vertex;

              /* CoglTextureVertex isn't an ideal structure to use for
                 this because it contains a CoglColor. The internal
                 layout of CoglColor is mean to be private so Clutter
                 can not pass a pointer to it as a vertex
                 attribute. Also it contains padding so we end up
                 storing more data in the vertex buffer than we need
                 to. Instead we let the application modify a dummy
                 vertex and then copy the details back out to a more
                 well-defined struct */

              vertex.tx = (float) j / priv->x_tiles;
              vertex.ty = (float) i / priv->y_tiles;

              vertex.x = width * vertex.tx;
              vertex.y = height * vertex.ty;
              vertex.z = 0.0f;

              cogl_color_init_from_4ub (&vertex.color, 255, 255, 255, opacity);

              clutter_deform_effect_deform_vertex (self,
                                                   width, height,
                                                   &vertex);

              vertex_out = verts + i * (priv->x_tiles + 1) + j;

              vertex_out->x = vertex.x;
              vertex_out->y = vertex.y;
              vertex_out->z = vertex.z;
              vertex_out->s = vertex.tx;
              vertex_out->t = vertex.ty;
              vertex_out->r = cogl_color_get_red_byte (&vertex.color);
              vertex_out->g = cogl_color_get_green_byte (&vertex.color);
              vertex_out->b = cogl_color_get_blue_byte (&vertex.color);
              vertex_out->a = cogl_color_get_alpha_byte (&vertex.color);
            }
        }

      if (mapped_buffer)
        cogl_buffer_unmap (COGL_BUFFER (priv->buffer));
      else
        {
          cogl_buffer_set_data (COGL_BUFFER (priv->buffer),
                                0, /* offset */
                                verts,
                                sizeof (*verts) * priv->n_vertices);
          g_free (verts);
        }

      priv->is_dirty = FALSE;
    }

  material = clutter_offscreen_effect_get_target (effect);
  pipeline = COGL_PIPELINE (material);

  /* enable depth testing */
  cogl_depth_state_init (&depth_state);
  cogl_depth_state_set_test_enabled (&depth_state, TRUE);
  cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL);

  /* enable backface culling if we have a back material */
  if (priv->back_pipeline != NULL)
    cogl_pipeline_set_cull_face_mode (pipeline,
                                      COGL_PIPELINE_CULL_FACE_MODE_BACK);

  /* draw the front */
  if (material != NULL)
    cogl_framebuffer_draw_primitive (fb, pipeline, priv->primitive);

  /* draw the back */
  if (priv->back_pipeline != NULL)
    {
      CoglPipeline *back_pipeline;

      /* We probably shouldn't be modifying the user's material so
         instead we make a temporary copy */
      back_pipeline = cogl_pipeline_copy (priv->back_pipeline);
      cogl_pipeline_set_depth_state (back_pipeline, &depth_state, NULL);
      cogl_pipeline_set_cull_face_mode (back_pipeline,
                                        COGL_PIPELINE_CULL_FACE_MODE_FRONT);

      cogl_framebuffer_draw_primitive (fb, back_pipeline, priv->primitive);

      cogl_object_unref (back_pipeline);
    }

  if (G_UNLIKELY (priv->lines_primitive != NULL))
    {
      CoglContext *ctx =
        clutter_backend_get_cogl_context (clutter_get_default_backend ());
      CoglPipeline *lines_pipeline = cogl_pipeline_new (ctx);
      cogl_pipeline_set_color4f (lines_pipeline, 1.0, 0, 0, 1.0);
      cogl_framebuffer_draw_primitive (fb, lines_pipeline,
                                       priv->lines_primitive);
      cogl_object_unref (lines_pipeline);
    }
}
Esempio n. 27
0
static void
clutter_rectangle_paint (ClutterActor *self)
{
  ClutterRectanglePrivate *priv = CLUTTER_RECTANGLE (self)->priv;
  ClutterGeometry geom;
  guint8 tmp_alpha;

  CLUTTER_NOTE (PAINT,
                "painting rect '%s'",
		clutter_actor_get_name (self) ? clutter_actor_get_name (self)
                                              : "unknown");
  clutter_actor_get_allocation_geometry (self, &geom);

  if (priv->has_border)
    {
      /* We paint the border and the content only if the rectangle
       * is big enough to show them
       */
      if ((priv->border_width * 2) < geom.width &&
          (priv->border_width * 2) < geom.height)
        {
          /* compute the composited opacity of the actor taking into
           * account the opacity of the color set by the user
           */
          tmp_alpha = clutter_actor_get_paint_opacity (self)
                    * priv->border_color.alpha
                    / 255;

          /* paint the border */
          cogl_set_source_color4ub (priv->border_color.red,
                                    priv->border_color.green,
                                    priv->border_color.blue,
                                    tmp_alpha);

          /* this sucks, but it's the only way to make a border */
          cogl_rectangle (priv->border_width, 0,
                          geom.width,
                          priv->border_width);

          cogl_rectangle (geom.width - priv->border_width,
                          priv->border_width,
                          geom.width,
                          geom.height);

          cogl_rectangle (0, geom.height - priv->border_width,
                          geom.width - priv->border_width,
                          geom.height);

          cogl_rectangle (0, 0,
                          priv->border_width,
                          geom.height - priv->border_width);

          tmp_alpha = clutter_actor_get_paint_opacity (self)
                    * priv->color.alpha
                    / 255;

          /* now paint the rectangle */
          cogl_set_source_color4ub (priv->color.red,
                                    priv->color.green,
                                    priv->color.blue,
                                    tmp_alpha);

          cogl_rectangle (priv->border_width, priv->border_width,
                          geom.width - priv->border_width,
                          geom.height - priv->border_width);
        }
      else
        {
          /* Otherwise, we draw a rectangle with the same color
           * as the border, since we can only fit that into the
           * allocation.
           */
          tmp_alpha = clutter_actor_get_paint_opacity (self)
                    * priv->border_color.alpha
                    / 255;

          cogl_set_source_color4ub (priv->border_color.red,
                                    priv->border_color.green,
                                    priv->border_color.blue,
                                    tmp_alpha);

          cogl_rectangle (0, 0, geom.width, geom.height);
        }
    }
  else
    {
      /* compute the composited opacity of the actor taking into
       * account the opacity of the color set by the user
       */
      tmp_alpha = clutter_actor_get_paint_opacity (self)
                * priv->color.alpha
                / 255;

      cogl_set_source_color4ub (priv->color.red,
                                priv->color.green,
                                priv->color.blue,
                                tmp_alpha);

      cogl_rectangle (0, 0, geom.width, geom.height);
    }
}
Esempio n. 28
0
static void
meta_window_group_cull_out (MetaWindowGroup *group,
                            ClutterActor    *unredirected_window,
                            gboolean         has_unredirected_window,
                            cairo_region_t  *unobscured_region,
                            cairo_region_t  *clip_region)
{
  ClutterActor *actor = CLUTTER_ACTOR (group);
  ClutterActor *child;
  ClutterActorIter iter;

  /* We walk the list from top to bottom (opposite of painting order),
   * and subtract the opaque area of each window out of the visible
   * region that we pass to the windows below.
   */
  clutter_actor_iter_init (&iter, actor);
  while (clutter_actor_iter_prev (&iter, &child))
    {
      if (!CLUTTER_ACTOR_IS_VISIBLE (child))
        continue;

      if (has_unredirected_window && child == unredirected_window)
        continue;

      /* If an actor has effects applied, then that can change the area
       * it paints and the opacity, so we no longer can figure out what
       * portion of the actor is obscured and what portion of the screen
       * it obscures, so we skip the actor.
       *
       * This has a secondary beneficial effect: if a ClutterOffscreenEffect
       * is applied to an actor, then our clipped redraws interfere with the
       * caching of the FBO - even if we only need to draw a small portion
       * of the window right now, ClutterOffscreenEffect may use other portions
       * of the FBO later. So, skipping actors with effects applied also
       * prevents these bugs.
       *
       * Theoretically, we should check clutter_actor_get_offscreen_redirect()
       * as well for the same reason, but omitted for simplicity in the
       * hopes that no-one will do that.
       */
      if (clutter_actor_has_effects (child))
        continue;

      if (META_IS_WINDOW_ACTOR (child))
        {
          MetaWindowActor *window_actor = META_WINDOW_ACTOR (child);
          int x, y;

          if (!meta_actor_is_untransformed (CLUTTER_ACTOR (window_actor), &x, &y))
            continue;

          /* Temporarily move to the coordinate system of the actor */
          cairo_region_translate (unobscured_region, - x, - y);
          cairo_region_translate (clip_region, - x, - y);

          meta_window_actor_set_unobscured_region (window_actor, unobscured_region);
          meta_window_actor_set_visible_region (window_actor, clip_region);

          if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff)
            {
              cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (window_actor);
              if (obscured_region)
                {
                  cairo_region_subtract (unobscured_region, obscured_region);
                  cairo_region_subtract (clip_region, obscured_region);
                }
            }

          meta_window_actor_set_visible_region_beneath (window_actor, clip_region);

          cairo_region_translate (unobscured_region, x, y);
          cairo_region_translate (clip_region, x, y);
        }
      else if (META_IS_BACKGROUND_ACTOR (child))
        {
          int x, y;

          if (!meta_actor_is_untransformed (child, &x, &y))
            continue;

          cairo_region_translate (clip_region, - x, - y);

          meta_background_actor_set_visible_region (META_BACKGROUND_ACTOR (child), clip_region);

          cairo_region_translate (clip_region, x, y);
        }
    }
}
static void
clutter_rectangle_paint (ClutterActor *self)
{
  ClutterRectangle        *rectangle = CLUTTER_RECTANGLE(self);
  ClutterRectanglePrivate *priv;
  ClutterGeometry          geom;
  ClutterColor             tmp_col;

  rectangle = CLUTTER_RECTANGLE(self);
  priv = rectangle->priv;

  CLUTTER_NOTE (PAINT,
                "painting rect '%s'",
		clutter_actor_get_name (self) ? clutter_actor_get_name (self)
                                              : "unknown");
  clutter_actor_get_allocation_geometry (self, &geom);

  CLUTTER_NOTE (PAINT, "paint to x1: %i, y1: %i x2: %i, y2: %i "
                       "opacity: %i",
                geom.x, geom.y, geom.x+geom.width, geom.y+geom.height,
                clutter_actor_get_opacity (self));

  /* parent paint call will have translated us into position so
   * paint from 0, 0
   */
  if (priv->has_border)
    {
      tmp_col.red   = priv->border_color.red;
      tmp_col.green = priv->border_color.green;
      tmp_col.blue  = priv->border_color.blue;
      tmp_col.alpha = clutter_actor_get_paint_opacity (self)
                      * priv->border_color.alpha
                      / 255;

      cogl_color (&tmp_col);

      /* this sucks, but it's the only way to make a border */
      cogl_rectangle (priv->border_width, 0,
                      geom.width - priv->border_width,
                      priv->border_width);

      cogl_rectangle (geom.width - priv->border_width,
                      priv->border_width,
                      priv->border_width,
                      geom.height - priv->border_width);

      cogl_rectangle (0, geom.height - priv->border_width,
                      geom.width - priv->border_width,
                      priv->border_width);

      cogl_rectangle (0, 0,
                      priv->border_width,
                      geom.height - priv->border_width);

      tmp_col.red   = priv->color.red;
      tmp_col.green = priv->color.green;
      tmp_col.blue  = priv->color.blue;
      tmp_col.alpha = clutter_actor_get_paint_opacity (self)
                      * priv->color.alpha
                      / 255;

      cogl_color (&tmp_col);

      cogl_rectangle (priv->border_width, priv->border_width,
                      geom.width - priv->border_width * 2,
                      geom.height - priv->border_width * 2);
    }
  else
    {
      tmp_col.red   = priv->color.red;
      tmp_col.green = priv->color.green;
      tmp_col.blue  = priv->color.blue;
      tmp_col.alpha = clutter_actor_get_paint_opacity (self)
                      * priv->color.alpha
                      / 255;

      cogl_color (&tmp_col);

      cogl_rectangle (0, 0, geom.width, geom.height);
    }
}
static void
st_drawing_area_paint (ClutterActor *self)
{
  StDrawingArea *area = ST_DRAWING_AREA (self);
  StDrawingAreaPrivate *priv = area->priv;
  StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (self));
  ClutterActorBox allocation_box;
  ClutterActorBox content_box;
  int width, height;
  CoglColor color;
  guint8 paint_opacity;

  (CLUTTER_ACTOR_CLASS (st_drawing_area_parent_class))->paint (self);

  clutter_actor_get_allocation_box (self, &allocation_box);
  st_theme_node_get_content_box (theme_node, &allocation_box, &content_box);

  width = (int)(0.5 + content_box.x2 - content_box.x1);
  height = (int)(0.5 + content_box.y2 - content_box.y1);

  if (priv->material == COGL_INVALID_HANDLE)
    priv->material = cogl_material_new ();

  if (priv->texture != COGL_INVALID_HANDLE &&
      (width != cogl_texture_get_width (priv->texture) ||
       height != cogl_texture_get_height (priv->texture)))
    {
      cogl_handle_unref (priv->texture);
      priv->texture = COGL_INVALID_HANDLE;
    }

  if (width > 0 && height > 0)
    {
      if (priv->texture == COGL_INVALID_HANDLE)
        {
          priv->texture = cogl_texture_new_with_size (width, height,
                                                      COGL_TEXTURE_NONE,
                                                      CLUTTER_CAIRO_FORMAT_ARGB32);
          priv->needs_repaint = TRUE;
        }

      if (priv->needs_repaint)
        {
          cairo_surface_t *surface;

          surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
          priv->context = cairo_create (surface);
          priv->in_repaint = TRUE;
          priv->needs_repaint = FALSE;

          g_signal_emit ((GObject*)area, st_drawing_area_signals[REPAINT], 0);

          priv->in_repaint = FALSE;
          cairo_destroy (priv->context);
          priv->context = NULL;

          cogl_texture_set_region (priv->texture, 0, 0, 0, 0, width, height, width, height,
                                   CLUTTER_CAIRO_FORMAT_ARGB32,
                                   cairo_image_surface_get_stride (surface),
                                   cairo_image_surface_get_data (surface));

          cairo_surface_destroy (surface);
        }
    }

  cogl_material_set_layer (priv->material, 0, priv->texture);

  if (priv->texture)
    {
      paint_opacity = clutter_actor_get_paint_opacity (self);
      cogl_color_set_from_4ub (&color,
                               paint_opacity, paint_opacity, paint_opacity, paint_opacity);
      cogl_material_set_color (priv->material, &color);

      cogl_set_source (priv->material);
      cogl_rectangle_with_texture_coords (content_box.x1, content_box.y1,
                                          width, height,
                                          0.0f, 0.0f, 1.0f, 1.0f);
    }
}