예제 #1
0
EAPI int
evas_common_tilebuf_add_redraw(Tilebuf *tb, int x, int y, int w, int h)
{
#ifdef RECTUPDATE
   int i;

   if ((w <= 0) || (h <= 0)) return 0;
   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
   if ((w <= 0) || (h <= 0)) return 0;
   for (i = 0; i < h; i++)
     evas_common_regionbuf_span_add(tb->rb, x, x + w - 1, y + i);
   return 1;
#elif defined(EVAS_RECT_SPLIT)
   return _add_redraw(&tb->rects, tb->outbuf_w, tb->outbuf_h, x, y, w, h);
#else
   int tx1, tx2, ty1, ty2, tfx1, tfx2, tfy1, tfy2, xx, yy;
   int num;

   if ((w <= 0) || (h <= 0)) return 0;
   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
   if ((w <= 0) || (h <= 0)) return 0;
   num = 0;
   /* wipes out any motion vectors in tiles it touches into redraws */
   if (tilebuf_x_intersect(tb, x, w, &tx1, &tx2, &tfx1, &tfx2) &&
       tilebuf_y_intersect(tb, y, h, &ty1, &ty2, &tfy1, &tfy2))
     {
        Tilebuf_Tile    *tbt;
        int             delta_x;
        int             delta_y;

        tbt = &(TILE(tb, tx1, ty1));
        delta_x = tx2 - tx1 + 1;
        delta_y = ty2 - ty1 + 1;
	for (yy = delta_y; yy > 0; yy--)
	  {
	     Tilebuf_Tile *tbti;

	     tbti = tbt;
	     for (xx = delta_x; xx > 0; xx--)
	       {
		  tbti->redraw = 1;
		  tbti++;
	       }
             tbt += tb->tiles.w;
	  }
	num = (tx2 - tx1 + 1) * (ty2 - ty1 + 1);
     }
   return num;
#endif
}
예제 #2
0
static inline int
_add_redraw(list_t *rects, int max_w, int max_h, int x, int y, int w, int h)
{
   rect_node_t *rn;

   if ((w <= 0) || (h <= 0)) return 0;
   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, max_w, max_h);
   if ((w <= 0) || (h <= 0)) return 0;

   x >>= 1;
   y >>= 1;
   w += 2;
   w >>= 1;
   h += 2;
   h >>= 1;

   rn = (rect_node_t *)rect_list_node_pool_get();
   rn->_lst = list_node_zeroed;
   rect_init(&rn->rect, x, y, w, h);
   //INF("ACCOUNTING: add_redraw: %4d,%4d %3dx%3d", x, y, w, h);
   //testing on my core2 duo desktop - fuzz of 32 or 48 is best.
#define FUZZ 32
   rect_list_add_split_fuzzy_and_merge(rects, (list_node_t *)rn,
                                       FUZZ * FUZZ, FUZZ * FUZZ);
   return 1;
}
예제 #3
0
EAPI void
evas_common_draw_context_clip_clip(RGBA_Draw_Context *dc, int x, int y, int w, int h)
{
   if (dc->clip.use)
     {
	RECTS_CLIP_TO_RECT(dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h,
			   x, y, w, h);
     }
   else
     evas_common_draw_context_set_clip(dc, x, y, w, h);
}
예제 #4
0
파일: evas_outbuf.c 프로젝트: jgfenix/efl
RGBA_Image *
evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch)
{
   RGBA_Image *img = NULL;

   if ((w <= 0) || (h <= 0)) return NULL;

   /* DBG("Outbuf Region New: %d %d %d %d", x, y, w, h); */

   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, ob->w, ob->h);

   if ((ob->rotation == 0) && (ob->depth == 32))
     {
        Eina_Rectangle *rect;

        if (!(rect = eina_rectangle_new(x, y, w, h)))
          return NULL;

#ifdef EVAS_CSERVE2
        if (evas_cserve2_use_get())
          img = (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get());
        else
#endif
          img = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());

        if (!img)
          {
             eina_rectangle_free(rect);
             return NULL;
          }

        img->cache_entry.flags.alpha = ob->destination_alpha;

#ifdef EVAS_CSERVE2
        if (evas_cserve2_use_get())
          evas_cache2_image_surface_alloc(&img->cache_entry, w, h);
        else
#endif
          evas_cache_image_surface_alloc(&img->cache_entry, w, h);

        img->extended_info = rect;

        if (cx) *cx = 0;
        if (cy) *cy = 0;
        if (cw) *cw = w;
        if (ch) *ch = h;

        /* add this cached image data to pending writes */
        ob->priv.pending_writes = 
          eina_list_append(ob->priv.pending_writes, img);
     }

   return img;
}
static void
_soft8_rectangle_draw_int(Soft8_Image * dst, RGBA_Draw_Context * dc,
                          Eina_Rectangle dr)
{
   int dst_offset;

   if (_is_empty_rectangle(&dr))
      return;
   RECTS_CLIP_TO_RECT(dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w,
                      dst->cache_entry.h);
   if (_is_empty_rectangle(&dr))
      return;

   if (dc->clip.use)
      RECTS_CLIP_TO_RECT(dr.x, dr.y, dr.w, dr.h, dc->clip.x,
                         dc->clip.y, dc->clip.w, dc->clip.h);
   if (_is_empty_rectangle(&dr))
      return;
   if (A_VAL(&dc->col.col) == 0)
      return;

   dst_offset = dr.x + (dr.y * dst->stride);

   if (!dst->cache_entry.flags.alpha)
     {
        DATA8 gry8;
        DATA8 alpha;

        alpha = A_VAL(&dc->col.col);
        gry8 = GRY_8_FROM_RGB(&dc->col.col);

        if (alpha == 0xff)
           _soft8_rectangle_draw_solid_solid(dst, dst_offset, dr.w, dr.h, gry8);
        else if (alpha > 0)
           _soft8_rectangle_draw_transp_solid
               (dst, dst_offset, dr.w, dr.h, gry8, alpha);
     }
   else
      ERR("Unsupported feature: drawing rectangle to non-opaque destination.");
}
예제 #6
0
EAPI void
evas_common_draw_context_add_cutout(RGBA_Draw_Context *dc, int x, int y, int w, int h)
{
//   if (dc->cutout.rects > 512) return;
   if (dc->clip.use)
     {
#if 1 // this is a bit faster
        int xa1, xa2, xb1, xb2;

        xa1 = x;
        xa2 = xa1 + w - 1;
        xb1 = dc->clip.x;
        if (xa2 < xb1) return;
        xb2 = xb1 + dc->clip.w - 1;
        if (xa1 >= xb2) return;
        if (xa2 > xb2) xa2 = xb2;
        if (xb1 > xa1) xa1 = xb1;
        x = xa1;
        w = xa2 - xa1 + 1;

        xa1 = y;
        xa2 = xa1 + h - 1;
        xb1 = dc->clip.y;
        if (xa2 < xb1) return;
        xb2 = xb1 + dc->clip.h - 1;
        if (xa1 >= xb2) return;
        if (xa2 > xb2) xa2 = xb2;
        if (xb1 > xa1) xa1 = xb1;
        y = xa1;
        h = xa2 - xa1 + 1;
#else
        RECTS_CLIP_TO_RECT(x, y, w, h,
			   dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
#endif
	if ((w < 1) || (h < 1)) return;
     }
   evas_common_draw_context_cutouts_add(&dc->cutout, x, y, w, h);
}
static void
rectangle_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h)
{
   RGBA_Gfx_Func func;
   int yy;
   DATA32 *ptr;

   RECTS_CLIP_TO_RECT(x, y, w, h, dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
   if ((w <= 0) || (h <= 0)) return;

   func = evas_common_gfx_func_composite_color_span_get(dc->col.col, dst, w, dc->render_op);
   ptr = dst->image.data + (y * dst->cache_entry.w) + x;
   for (yy = 0; yy < h; yy++)
     {
#ifdef EVAS_SLI
	if (((yy + y) % dc->sli.h) == dc->sli.y)
#endif
	  {
	     func(NULL, NULL, dc->col.col, ptr, w);
	  }
	ptr += dst->cache_entry.w;
     }
}
예제 #8
0
static void
rectangle_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h)
{
   RGBA_Gfx_Func func;
   int yy;
   DATA32 *ptr;

   RECTS_CLIP_TO_RECT(x, y, w, h, dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
   if ((w <= 0) || (h <= 0)) return;

#ifdef HAVE_PIXMAN
# ifdef PIXMAN_RECT
   pixman_op_t op = PIXMAN_OP_SRC; // _EVAS_RENDER_COPY
   
   if (dc->render_op == _EVAS_RENDER_BLEND)
     op = PIXMAN_OP_OVER;

   if ((dst->pixman.im) && (dc->col.pixman_color_image))
     {
        pixman_image_composite(op, dc->col.pixman_color_image, NULL, 
                               dst->pixman.im, x, y, 0, 0, 
                               x, y, w, h);
     }
   else
# endif     
#endif
     {
        func = evas_common_gfx_func_composite_color_span_get(dc->col.col, dst, w, dc->render_op);
        ptr = dst->image.data + (y * dst->cache_entry.w) + x;
        for (yy = 0; yy < h; yy++)
          {
	    func(NULL, NULL, dc->col.col, ptr, w);

	    ptr += dst->cache_entry.w;
          }
     }
}
예제 #9
0
void
evas_common_soft8_polygon_draw(Soft8_Image * dst, RGBA_Draw_Context * dc,
                   RGBA_Polygon_Point * points, int x, int y)
{
   RGBA_Polygon_Point *pt;
   RGBA_Vertex *point;
   RGBA_Edge *edges;
   int num_active_edges;
   int n;
   int i, j, k;
   int y0, y1, yi;
   int ext_x, ext_y, ext_w, ext_h;
   int *sorted_index;
   DATA8 alpha;
   DATA8 gry8;

   alpha = A_VAL(&dc->col.col);
   if (alpha == 0)
      return;
   alpha++;

   gry8 = GRY_8_FROM_RGB(&dc->col.col);

   ext_x = 0;
   ext_y = 0;
   ext_w = dst->cache_entry.w;
   ext_h = dst->cache_entry.h;
   if (dc->clip.use)
      RECTS_CLIP_TO_RECT(ext_x, ext_y, ext_w, ext_h,
                         dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);

   if ((ext_w <= 0) || (ext_h <= 0))
      return;

   n = 0;
   EINA_INLIST_FOREACH(points, pt) n++;

   if (n < 3)
      return;

   edges = malloc(sizeof(RGBA_Edge) * n);
   if (!edges)
      return;

   point = malloc(sizeof(RGBA_Vertex) * n);
   if (!point)
     {
        free(edges);
        return;
     }

   sorted_index = malloc(sizeof(int) * n);
   if (!sorted_index)
     {
        free(edges);
        free(point);
        return;
     }

   k = 0;
   EINA_INLIST_FOREACH(points, pt)
   {
      point[k].x = pt->x + x;
      point[k].y = pt->y + y;
      point[k].i = k;
      k++;
   }
static void
scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst,
					  RGBA_Draw_Context *dc,
					  int src_region_x, int src_region_y,
					  int src_region_w, int src_region_h,
					  int dst_region_x, int dst_region_y,
					  int dst_region_w, int dst_region_h)
{
   int      x, y;
   int     *lin_ptr;
   DATA32  *buf, *dptr;
   DATA32 **row_ptr;
   DATA32  *ptr, *dst_ptr, *src_data, *dst_data;
   int      dst_clip_x, dst_clip_y, dst_clip_w, dst_clip_h;
   int      m_clip_x = 0, m_clip_y = 0, m_clip_w = 0, m_clip_h = 0, mdx = 0, mdy = 0;
   int      src_w, src_h, dst_w, dst_h;
   RGBA_Gfx_Func func;
   RGBA_Image *maskobj = NULL;
   DATA8   *mask = NULL;

   if (!(RECTS_INTERSECT(dst_region_x, dst_region_y, dst_region_w, dst_region_h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
     return;
   if (!(RECTS_INTERSECT(src_region_x, src_region_y, src_region_w, src_region_h, 0, 0, src->cache_entry.w, src->cache_entry.h)))
     return;

   src_w = src->cache_entry.w;
   src_h = src->cache_entry.h;
   dst_w = dst->cache_entry.w;
   dst_h = dst->cache_entry.h;

   src_data = src->image.data;
   dst_data = dst->image.data;

   if (dc->clip.use)
     {
	dst_clip_x = dc->clip.x;
	dst_clip_y = dc->clip.y;
	dst_clip_w = dc->clip.w;
	dst_clip_h = dc->clip.h;
	if (dst_clip_x < 0)
	  {
	     dst_clip_w += dst_clip_x;
	     dst_clip_x = 0;
	  }
	if (dst_clip_y < 0)
	  {
	     dst_clip_h += dst_clip_y;
	     dst_clip_y = 0;
	  }
	if ((dst_clip_x + dst_clip_w) > dst_w)
	  dst_clip_w = dst_w - dst_clip_x;
	if ((dst_clip_y + dst_clip_h) > dst_h)
	  dst_clip_h = dst_h - dst_clip_y;
     }
   else
     {
	dst_clip_x = 0;
	dst_clip_y = 0;
	dst_clip_w = dst_w;
	dst_clip_h = dst_h;
     }

   if (dc->mask.mask)
     {
        m_clip_x = dc->mask.x;
        m_clip_y = dc->mask.y;
        m_clip_w = dc->mask.mask->cache_entry.w;
        m_clip_h = dc->mask.mask->cache_entry.h;
        RECTS_CLIP_TO_RECT(m_clip_x, m_clip_y, m_clip_w, m_clip_h,
                           dst_clip_x, dst_clip_y, dst_clip_w, dst_clip_h);
        if ((m_clip_w <= 0) || (m_clip_h <= 0)) return;
        dst_clip_x = m_clip_x;
        dst_clip_y = m_clip_y;
        dst_clip_w = m_clip_w;
        dst_clip_h = m_clip_h;
     }

   if (dst_clip_x < dst_region_x)
     {
	dst_clip_w += dst_clip_x - dst_region_x;
	dst_clip_x = dst_region_x;
     }
   if ((dst_clip_x + dst_clip_w) > (dst_region_x + dst_region_w))
     dst_clip_w = dst_region_x + dst_region_w - dst_clip_x;
   if (dst_clip_y < dst_region_y)
     {
	dst_clip_h += dst_clip_y - dst_region_y;
	dst_clip_y = dst_region_y;
     }
   if ((dst_clip_y + dst_clip_h) > (dst_region_y + dst_region_h))
     dst_clip_h = dst_region_y + dst_region_h - dst_clip_y;

   if ((src_region_w <= 0) || (src_region_h <= 0) ||
       (dst_region_w <= 0) || (dst_region_h <= 0) ||
       (dst_clip_w <= 0) || (dst_clip_h <= 0))
     return;

   /* sanitise x */
   if (src_region_x < 0)
     {
	dst_region_x -= (src_region_x * dst_region_w) / src_region_w;
	dst_region_w += (src_region_x * dst_region_w) / src_region_w;
	src_region_w += src_region_x;
	src_region_x = 0;
     }
   if (src_region_x >= src_w) return;
   if ((src_region_x + src_region_w) > src_w)
     {
	dst_region_w = (dst_region_w * (src_w - src_region_x)) / (src_region_w);
	src_region_w = src_w - src_region_x;
     }
   if (dst_region_w <= 0) return;
   if (src_region_w <= 0) return;
   if (dst_clip_x < 0)
     {
	dst_clip_w += dst_clip_x;
	dst_clip_x = 0;
     }
   if (dst_clip_w <= 0) return;
   if (dst_clip_x >= dst_w) return;
   if (dst_clip_x < dst_region_x)
     {
	dst_clip_w += (dst_clip_x - dst_region_x);
	dst_clip_x = dst_region_x;
     }
   if ((dst_clip_x + dst_clip_w) > dst_w)
     {
	dst_clip_w = dst_w - dst_clip_x;
     }
   if (dst_clip_w <= 0) return;

   /* sanitise y */
   if (src_region_y < 0)
     {
	dst_region_y -= (src_region_y * dst_region_h) / src_region_h;
	dst_region_h += (src_region_y * dst_region_h) / src_region_h;
	src_region_h += src_region_y;
	src_region_y = 0;
     }
   if (src_region_y >= src_h) return;
   if ((src_region_y + src_region_h) > src_h)
     {
	dst_region_h = (dst_region_h * (src_h - src_region_y)) / (src_region_h);
	src_region_h = src_h - src_region_y;
     }
   if (dst_region_h <= 0) return;
   if (src_region_h <= 0) return;
   if (dst_clip_y < 0)
     {
	dst_clip_h += dst_clip_y;
	dst_clip_y = 0;
     }
   if (dst_clip_h <= 0) return;
   if (dst_clip_y >= dst_h) return;
   if (dst_clip_y < dst_region_y)
     {
	dst_clip_h += (dst_clip_y - dst_region_y);
	dst_clip_y = dst_region_y;
     }
   if ((dst_clip_y + dst_clip_h) > dst_h)
     {
	dst_clip_h = dst_h - dst_clip_y;
     }
   if (dst_clip_h <= 0) return;

   /* allocate scale lookup tables */
   lin_ptr = alloca(dst_clip_w * sizeof(int));
   row_ptr = alloca(dst_clip_h * sizeof(DATA32 *));

   /* figure out dst jump */
   //dst_jump = dst_w - dst_clip_w;

   /* figure out dest start ptr */
   dst_ptr = dst_data + dst_clip_x + (dst_clip_y * dst_w);

   if (dc->mask.mask)
     {
       func = evas_common_gfx_func_composite_pixel_mask_span_get(src, dst, dst_clip_w, dc->render_op);
       maskobj = dc->mask.mask;
       mask = maskobj->mask.mask;
/*
       if (1 || dst_region_w > src_region_w || dst_region_h > src_region_h){
	       printf("Mask w/h: %d/%d\n",maskobj->cache_entry.w,
			       maskobj->cache_entry.h);
	       printf("Warning: Unscaled mask (%d/%d) // (%d/%d)\n",
			       dst_region_w,src_region_w,
			       dst_region_h,src_region_h);
       }
 */
     }
   else if (dc->mul.use)
     func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, dc->render_op);
   else
     func = evas_common_gfx_func_composite_pixel_span_get(src, dst, dst_clip_w, dc->render_op);

   if ((dst_region_w == src_region_w) && (dst_region_h == src_region_h))
     {
#ifdef HAVE_PIXMAN
# ifdef PIXMAN_IMAGE_SCALE_SAMPLE        
        if ((src->pixman.im) && (dst->pixman.im) && (!dc->mask.mask) &&
            ((!dc->mul.use) ||
                ((dc->mul.use) && (dc->mul.col == 0xffffffff))) &&
            ((dc->render_op == _EVAS_RENDER_COPY) ||
                (dc->render_op == _EVAS_RENDER_BLEND)))
          {
             pixman_op_t op = PIXMAN_OP_SRC; // _EVAS_RENDER_COPY
             if (dc->render_op == _EVAS_RENDER_BLEND)
               op = PIXMAN_OP_OVER;
             
             pixman_image_composite(op,
                                    src->pixman.im, NULL,
                                    dst->pixman.im,
                                    (dst_clip_x - dst_region_x) + src_region_x,
                                    (dst_clip_y - dst_region_y) + src_region_y,
                                    0, 0,
                                    dst_clip_x, dst_clip_y,
                                    dst_clip_w, dst_clip_h);
          }
        else if ((src->pixman.im) && (dst->pixman.im) &&
                 (dc->mask.mask)  && (dc->mask.mask->pixman.im) &&
                 ((dc->render_op == _EVAS_RENDER_COPY) ||
                     (dc->render_op == _EVAS_RENDER_BLEND)))
          {
             // In case of pixel and color operation.
             pixman_op_t op = PIXMAN_OP_SRC; // _EVAS_RENDER_COPY
             if (dc->render_op == _EVAS_RENDER_BLEND)
               op = PIXMAN_OP_OVER;
             
             pixman_image_composite(op,
                                    src->pixman.im, dc->mask.mask->pixman.im,
                                    dst->pixman.im,
                                    (dst_clip_x - dst_region_x) + src_region_x,
                                    (dst_clip_y - dst_region_y) + src_region_y,
                                    0, 0,
                                    dst_clip_x, dst_clip_y,
                                    dst_clip_w, dst_clip_h);
          }
        else
# endif          
#endif
          {
             ptr = src_data + ((dst_clip_y - dst_region_y + src_region_y) * src_w) + (dst_clip_x - dst_region_x) + src_region_x;
             if (mask)
               {
                  mdx = (m_clip_x - dc->mask.x) + (m_clip_x - dst_clip_x);
                  mdy = (m_clip_y - dc->mask.y) + (m_clip_y - dst_clip_y);
                  mask += mdx + (mdy * maskobj->cache_entry.w);
               }
             for (y = 0; y < dst_clip_h; y++)
               {
		 /* * blend here [clip_w *] ptr -> dst_ptr * */
		 func(ptr, mask, dc->mul.col, dst_ptr, dst_clip_w);

		 ptr += src_w;
		 dst_ptr += dst_w;
		 if (mask) mask += maskobj->cache_entry.w;
               }
	  }
     }
   else
     {
        /* fill scale tables */
	for (x = 0; x < dst_clip_w; x++)
          lin_ptr[x] = (((x + dst_clip_x - dst_region_x) * src_region_w) / dst_region_w) + src_region_x;
	for (y = 0; y < dst_clip_h; y++)
          row_ptr[y] = src_data + (((((y + dst_clip_y - dst_region_y) * src_region_h) / dst_region_h)
                                    + src_region_y) * src_w);
	/* scale to dst */
	dptr = dst_ptr;
#ifdef DIRECT_SCALE
	if ((!src->cache_entry.flags.alpha) &&
            (!dst->cache_entry.flags.alpha) &&
            (!dc->mul.use))
	  {
	     for (y = 0; y < dst_clip_h; y++)
	       {

		 dst_ptr = dptr;
		 for (x = 0; x < dst_clip_w; x++)
		   {
		     ptr = row_ptr[y] + lin_ptr[x];
		     *dst_ptr = *ptr;
		     dst_ptr++;
		   }

		 dptr += dst_w;
               }
	  }
	else
#endif
	  {
	    /* a scanline buffer */
             buf = alloca(dst_clip_w * sizeof(DATA32));
             for (y = 0; y < dst_clip_h; y++)
               {
		 dst_ptr = buf;
		 for (x = 0; x < dst_clip_w; x++)
		   {
		     ptr = row_ptr[y] + lin_ptr[x];
		     *dst_ptr = *ptr;
		     dst_ptr++;
		   }
		 /* * blend here [clip_w *] buf -> dptr * */
		 func(buf, NULL, dc->mul.col, dptr, dst_clip_w);

		 dptr += dst_w;
               }
	  }
     }
}
예제 #11
0
파일: evas_outbuf.c 프로젝트: jgfenix/efl
void 
evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h)
{
   Gfx_Func_Convert func = NULL;
   Eina_Rectangle rect = {0, 0, 0, 0}, pr;
   DATA32 *src;
   DATA8 *dst;
   Buffer *buff;
   int bpp = 0, bpl = 0;
   int rx = 0, ry = 0;

   /* check for valid output buffer */
   if (!ob) return;

   /* check for pending writes */
   if (!ob->priv.pending_writes) return;

   /* check for valid source data */
   if (!(src = update->image.data)) return;

   /* check for valid desination data */
   buff = &(ob->priv.buffer[ob->priv.curr]);
   if (!(dst = buff->data)) return;

   if ((ob->rotation == 0) || (ob->rotation == 180))
     {
        func = 
          evas_common_convert_func_get(0, w, h, ob->depth, 
                                       RED_MASK, GREEN_MASK, BLUE_MASK,
                                       PAL_MODE_NONE, ob->rotation);
     }
   else if ((ob->rotation == 90) || (ob->rotation == 270))
     {
        func = 
          evas_common_convert_func_get(0, h, w, ob->depth, 
                                       RED_MASK, GREEN_MASK, BLUE_MASK,
                                       PAL_MODE_NONE, ob->rotation);
     }

   /* make sure we have a valid convert function */
   if (!func) return;

   /* based on rotation, set rectangle position */
   if (ob->rotation == 0)
     {
        rect.x = x;
        rect.y = y;
     }
   else if (ob->rotation == 90)
     {
        rect.x = y;
        rect.y = (ob->w - x - w);
     }
   else if (ob->rotation == 180)
     {
        rect.x = (ob->w - x - w);
        rect.y = (ob->h - y - h);
     }
   else if (ob->rotation == 270)
     {
        rect.x = (ob->h - y - h);
        rect.y = x;
     }

   /* based on rotation, set rectangle size */
   if ((ob->rotation == 0) || (ob->rotation == 180))
     {
        rect.w = w;
        rect.h = h;
     }
   else if ((ob->rotation == 90) || (ob->rotation == 270))
     {
        rect.w = h;
        rect.h = w;
     }

   bpp = (ob->depth / 8);
   if (bpp <= 0) return;

   bpl = buff->stride;

   if (ob->rotation == 0)
     {
        RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 
                           0, 0, buff->w, buff->h);
        dst += (bpl * rect.y) + (rect.x * bpp);
        w -= rx;
     }
   else if (ob->rotation == 180)
     {
        pr = rect;
        RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 
                           0, 0, buff->w, buff->h);
        rx = pr.w - rect.w;
        ry = pr.h - rect.h;
        src += (update->cache_entry.w * ry) + rx;
        w -= rx;
     }
   else if (ob->rotation == 90)
     {
        pr = rect;
        RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 
                           0, 0, buff->w, buff->h);
        rx = pr.w - rect.w; ry = pr.h - rect.h;
        src += ry;
        w -= ry;
     }
   else if (ob->rotation == 270)
     {
        pr = rect;
        RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 
                           0, 0, buff->w, buff->h);
        rx = pr.w - rect.w; ry = pr.h - rect.h;
        src += (update->cache_entry.w * rx);
        w -= ry;
     }

   if ((rect.w <= 0) || (rect.h <= 0)) return;

   func(src, dst, (update->cache_entry.w - w), ((bpl / bpp) - rect.w),
        rect.w, rect.h, x + rx, y + ry, NULL);
}
예제 #12
0
EAPI int
evas_common_tilebuf_del_redraw(Tilebuf *tb, int x, int y, int w, int h)
{
#ifdef RECTUPDATE
   int i;

   for (i = 0; i < h; i++)
     evas_common_regionbuf_span_del(tb->rb, x, x + w - 1, y + i);
#elif defined(EVAS_RECT_SPLIT)
   rect_t r;

   if (!tb->rects.head) return 0;
   if ((w <= 0) || (h <= 0)) return 0;
   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
   if ((w <= 0) || (h <= 0)) return 0;

   x += 1;
   y += 1;
   x >>= 1;
   y >>= 1;
   w -= 1;
   w >>= 1;
   h -= 1;
   h >>= 1;

   if ((w <= 0) || (h <= 0)) return 0;

   rect_init(&r, x, y, w, h);
   //ERR("ACCOUNTING: del_redraw: %4d,%4d %3dx%3d", x, y, w, h);

   rect_list_del_split_strict(&tb->rects, r);
   tb->need_merge = 1;
   return 0;
#else
   int tx1, tx2, ty1, ty2, tfx1, tfx2, tfy1, tfy2, xx, yy;
   int num;

   num = 0;
   /* wipes out any motion vectors in tiles it touches into redraws */
   if (tilebuf_x_intersect(tb, x, w, &tx1, &tx2, &tfx1, &tfx2) &&
       tilebuf_y_intersect(tb, y, h, &ty1, &ty2, &tfy1, &tfy2))
     {
        Tilebuf_Tile    *tbt;
        int             delta_y;
        int             delta_x;

        if (!tfx1) tx1++;
	if (!tfx2) tx2--;
	if (!tfy1) ty1++;
	if (!tfy2) ty2--;

        tbt = &(TILE(tb, tx1, ty1));
        delta_x = tx2 - tx1 + 1;
        delta_y = ty2 - ty1 + 1;
	for (yy = delta_y; yy > 0; yy--)
	  {
	     Tilebuf_Tile       *tbti;

	     tbti = tbt;
	     for (xx = delta_x; xx > 0; xx--)
	       {
		  tbti->redraw = 0;
		  tbti++;
	       }
             tbt += tb->tiles.w;
	  }
	num = (tx2 - tx1 + 1) * (ty2 - ty1 + 1);
     }
   return num;
#endif
}
예제 #13
0
EAPI Tilebuf_Rect *
evas_common_tilebuf_get_render_rects(Tilebuf *tb)
{
#ifdef RECTUPDATE
   return evas_common_regionbuf_rects_get(tb->rb);
#elif defined(EVAS_RECT_SPLIT)
   list_node_t *n;
   Tilebuf_Rect *rects = NULL;

   if (tb->need_merge) {
       list_t to_merge;
       to_merge = tb->rects;
       tb->rects = list_zeroed;
       rect_list_merge_rects(&tb->rects, &to_merge, FUZZ * FUZZ);
       tb->need_merge = 0;
   }

   for (n = tb->rects.head; n; n = n->next) {
       rect_t cur;

       cur = ((rect_node_t *)n)->rect;

       cur.left <<= 1;
       cur.top <<= 1;
       cur.width <<= 1;
       cur.height <<= 1;

       RECTS_CLIP_TO_RECT(cur.left, cur.top, cur.width, cur.height,
			  0, 0, tb->outbuf_w, tb->outbuf_h);
       if ((cur.width > 0) && (cur.height > 0))
	 {
	    Tilebuf_Rect *r;

	    r = malloc(sizeof(Tilebuf_Rect));
	    r->x = cur.left;
	    r->y = cur.top;
	    r->w = cur.width;
	    r->h = cur.height;

	    rects = (Tilebuf_Rect *)eina_inlist_append(EINA_INLIST_GET(rects), EINA_INLIST_GET(r));
	 }
   }
   return rects;

#else
   Tilebuf_Rect *rects = NULL;
   Tilebuf_Tile *tbt;
   int x, y;

   tbt = &(TILE(tb, 0, 0));
   for (y = 0; y < tb->tiles.h; y++)
     {
	for (x = 0; x < tb->tiles.w; x++, tbt++)
	  {
	     if (tbt->redraw)
	       {
                  Tilebuf_Tile *tbti;
		  int can_expand_x = 1, can_expand_y = 1;
		  Tilebuf_Rect *r = NULL;
		  int xx = 0, yy = 0;
		  r = malloc(sizeof(Tilebuf_Rect));
                  r->_list_data.next = NULL;
                  r->_list_data.prev = NULL;
                  r->_list_data.last = NULL;

/* amalgamate tiles */
#if 1
                  tbti = tbt;
		  while (can_expand_x)
		    {
                       tbti++;
		       xx++;
		       if ((x + xx) >= tb->tiles.w)
			 can_expand_x = 0;
		       else if (!(tbti->redraw))
			 can_expand_x = 0;
		       if (can_expand_x)
			 tbti->redraw = 0;
		    }
                  tbti = tbt;
		  while (can_expand_y)
		    {
		       int i;

                       tbti += tb->tiles.w;
		       yy++;
		       if ((y + yy) >= tb->tiles.h)
			 can_expand_y = 0;
		       if (can_expand_y)
			 {
                            Tilebuf_Tile *tbtj;

                            tbtj = tbti;
			    for (i = x; i < x + xx; i++, tbtj++)
			      {
				 if (!(tbtj->redraw))
				   {
				      can_expand_y = 0;
				      break;
				   }
			      }
			 }
		       if (can_expand_y)
			 {
                            Tilebuf_Tile *tbtj;

                            tbtj = tbti;
			    for (i = x; i < x + xx; i++, tbtj++)
			      tbtj->redraw = 0;
			 }
		    }
		  tbt->redraw = 0;
#else
		  xx = 1;
		  yy = 1;
#endif
		  r->x = x * tb->tile_size.w;
		  r->y = y * tb->tile_size.h;
		  r->w = (xx) * tb->tile_size.w;
		  r->h = (yy) * tb->tile_size.h;
		  rects = eina_inlist_append(rects, r);
		  x = x + (xx - 1);
                  tbt += xx - 1;
	       }
	  }
     }
   return rects;
#endif
}
예제 #14
0
파일: evas_tiler.c 프로젝트: turran/efl
EAPI int
evas_common_tilebuf_add_redraw(Tilebuf *tb, int x, int y, int w, int h)
{
#ifdef RECTUPDATE
/*   
   int i;

   if ((w <= 0) || (h <= 0)) return 0;
   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
   if ((w <= 0) || (h <= 0)) return 0;
   for (i = 0; i < h; i++)
     evas_common_regionbuf_span_add(tb->rb, x, x + w - 1, y + i);
   return 1;
 */
#elif defined(EVAS_RECT_SPLIT)
   if ((w <= 0) || (h <= 0)) return 0;
   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
   if ((w <= 0) || (h <= 0)) return 0;
   // optimize a common case -> adding the exact same rect 2x in a row
   if ((tb->prev_add.x == x) && (tb->prev_add.y == y) && 
       (tb->prev_add.w == w) && (tb->prev_add.h == h)) return 1;
   tb->prev_add.x = x; tb->prev_add.y = y;
   tb->prev_add.w = w; tb->prev_add.h = h;
   tb->prev_del.w = 0; tb->prev_del.h = 0;
   return _add_redraw(&tb->rects, x, y, w, h);
#else
/*   
   int tx1, tx2, ty1, ty2, tfx1, tfx2, tfy1, tfy2, xx, yy;
   int num;

   if ((w <= 0) || (h <= 0)) return 0;
   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
   if ((w <= 0) || (h <= 0)) return 0;
   num = 0;
   // wipes out any motion vectors in tiles it touches into redraws
   if (tilebuf_x_intersect(tb, x, w, &tx1, &tx2, &tfx1, &tfx2) &&
       tilebuf_y_intersect(tb, y, h, &ty1, &ty2, &tfy1, &tfy2))
     {
        Tilebuf_Tile    *tbt;
        int             delta_x;
        int             delta_y;

        tbt = &(TILE(tb, tx1, ty1));
        delta_x = tx2 - tx1 + 1;
        delta_y = ty2 - ty1 + 1;
	for (yy = delta_y; yy > 0; yy--)
	  {
	     Tilebuf_Tile *tbti;

	     tbti = tbt;
	     for (xx = delta_x; xx > 0; xx--)
	       {
		  tbti->redraw = 1;
		  tbti++;
	       }
             tbt += tb->tiles.w;
	  }
	num = (tx2 - tx1 + 1) * (ty2 - ty1 + 1);
     }
   return num;
 */
#endif
}
예제 #15
0
파일: evas_tiler.c 프로젝트: turran/efl
EAPI int
evas_common_tilebuf_del_redraw(Tilebuf *tb, int x, int y, int w, int h)
{
#ifdef RECTUPDATE
/*   
   int i;

   for (i = 0; i < h; i++)
     evas_common_regionbuf_span_del(tb->rb, x, x + w - 1, y + i);
 */
#elif defined(EVAS_RECT_SPLIT)
   rect_t r;

   if (!tb->rects.head) return 0;
   if ((w <= 0) || (h <= 0)) return 0;
   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
   if ((w <= 0) || (h <= 0)) return 0;
   
/* we dont need to do this fuzz stuff - it actually creates overdraw bugs
 * when evas shouldnt draw at all.
   x += 1;
   y += 1;
   x >>= 1;
   y >>= 1;
   w -= 1;
   w >>= 1;
   h -= 1;
   h >>= 1;

   if ((w <= 0) || (h <= 0)) return 0;
 */
   
   // optimize a common case -> deleting the exact same rect 2x in a row
   if ((tb->prev_del.x == x) && (tb->prev_del.y == y) && 
       (tb->prev_del.w == w) && (tb->prev_del.h == h)) return 1;
   tb->prev_del.x = x; tb->prev_del.y = y;
   tb->prev_del.w = w; tb->prev_del.h = h;
   tb->prev_add.w = 0; tb->prev_add.h = 0;
   rect_init(&r, x, y, w, h);

   rect_list_del_split_strict(&tb->rects, r);
   tb->need_merge = 1;
   return 0;
#else
/*   
   int tx1, tx2, ty1, ty2, tfx1, tfx2, tfy1, tfy2, xx, yy;
   int num;

   num = 0;
   // wipes out any motion vectors in tiles it touches into redraws
   if (tilebuf_x_intersect(tb, x, w, &tx1, &tx2, &tfx1, &tfx2) &&
       tilebuf_y_intersect(tb, y, h, &ty1, &ty2, &tfy1, &tfy2))
     {
        Tilebuf_Tile    *tbt;
        int             delta_y;
        int             delta_x;

        if (!tfx1) tx1++;
	if (!tfx2) tx2--;
	if (!tfy1) ty1++;
	if (!tfy2) ty2--;

        tbt = &(TILE(tb, tx1, ty1));
        delta_x = tx2 - tx1 + 1;
        delta_y = ty2 - ty1 + 1;
	for (yy = delta_y; yy > 0; yy--)
	  {
	     Tilebuf_Tile       *tbti;

	     tbti = tbt;
	     for (xx = delta_x; xx > 0; xx--)
	       {
		  tbti->redraw = 0;
		  tbti++;
	       }
             tbt += tb->tiles.w;
	  }
	num = (tx2 - tx1 + 1) * (ty2 - ty1 + 1);
     }
   return num;
 */
#endif
}
예제 #16
0
void *
evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch) 
{
   RGBA_Image *im = NULL;
   Outbuf_Region *obr = NULL;
   Eina_Bool use_shm = EINA_TRUE;
   Eina_Bool alpha = EINA_FALSE;
   int bpl = 0;

   if ((buf->onebuf) && (buf->priv.x11.xcb.shm)) 
     {
        Eina_Rectangle *rect;

        RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, buf->w, buf->h);

        if (!(obr = calloc(1, sizeof(Outbuf_Region))))
          return NULL;

        if (!(rect = eina_rectangle_new(x, y, w, h))) 
          {
             free(obr);
             return NULL;
          }

        if ((eina_array_push(&buf->priv.onebuf_regions, rect)) &&
            (buf->priv.onebuf))
          {
             if (cx) *cx = x;
             if (cy) *cy = y;
             if (cw) *cw = w;
             if (ch) *ch = h;
             if (!buf->priv.synced) 
               {
                  _xcbob_sync(buf->priv.x11.xcb.conn);
                  buf->priv.synced = EINA_TRUE;
               }
             free(obr);
             return buf->priv.onebuf;
          }
        obr->x = 0;
        obr->y = 0;
        obr->w = buf->w;
        obr->h = buf->h;
        if (cx) *cx = x;
        if (cy) *cy = y;
        if (cw) *cw = w;
        if (ch) *ch = h;

        alpha = ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha));
        use_shm = buf->priv.x11.xcb.shm;

        if ((buf->rot == 0) &&
            (buf->priv.x11.xcb.imdepth == 32) &&
            (buf->priv.mask.r == 0xff0000) &&
            (buf->priv.mask.g == 0x00ff00) &&
            (buf->priv.mask.b == 0x0000ff))
          {
             obr->xcbob = 
               evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
                                                   buf->priv.x11.xcb.visual, 
                                                   buf->priv.x11.xcb.depth, 
                                                   buf->w, buf->h, use_shm, 
                                                   NULL);
             if (!obr->xcbob) 
               {
                  free(obr);
                  return NULL;
               }
#ifdef EVAS_CSERVE2
             if (evas_cserve2_use_get())
               {
                  im = 
                    (RGBA_Image *)evas_cache2_image_data(evas_common_image_cache2_get(), 
                                                         buf->w, buf->h, 
                                                         (DATA32 *)evas_software_xcb_output_buffer_data(obr->xcbob, &bpl), 
                                                         alpha, EVAS_COLORSPACE_ARGB8888);
               }
             else
#endif
               {
                  im = 
                    (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), 
                                                        buf->w, buf->h, 
                                                        (DATA32 *)evas_software_xcb_output_buffer_data(obr->xcbob, &bpl), 
                                                        alpha, EVAS_COLORSPACE_ARGB8888);
               }

             if (!im) 
               {
                  evas_software_xcb_output_buffer_free(obr->xcbob, EINA_FALSE);
                  free(obr);
                  return NULL;
               }
             im->extended_info = obr;
             if (buf->priv.x11.xcb.mask) 
               {
                  obr->mask = 
                    evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
                                                        buf->priv.x11.xcb.visual, 
                                                        1, buf->w, buf->h, 
                                                        use_shm, NULL);
               }
          }
        else 
          {
             int bw = 0, bh = 0;

#ifdef EVAS_CSERVE2
             if (evas_cserve2_use_get())
               {
                  im = 
                    (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get());
               }
             else
#endif
               {
                  im = 
                    (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
               }

             if (!im) 
               {
                  free(obr);
                  return NULL;
               }
             im->cache_entry.flags.alpha |= (alpha ? 1 : 0);
#ifdef EVAS_CSERVE2
             if (evas_cserve2_use_get())
               evas_cache2_image_surface_alloc(&im->cache_entry, buf->w, buf->h);
             else
#endif
               evas_cache_image_surface_alloc(&im->cache_entry, buf->w, buf->h);

             im->extended_info = obr;
             if ((buf->rot == 0) || (buf->rot == 180)) 
               {
                  bw = buf->w;
                  bh = buf->h;
               }
             else if ((buf->rot == 90) || (buf->rot == 270)) 
               {
                  bw = buf->h;
                  bh = buf->w;
               }
             obr->xcbob = 
               evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
                                                   buf->priv.x11.xcb.visual, 
                                                   buf->priv.x11.xcb.depth, 
                                                   bw, bh, use_shm, NULL);
             if (!obr->xcbob) 
               {
#ifdef EVAS_CSERVE2
                  if (evas_cserve2_use_get())
                    evas_cache2_image_close(&im->cache_entry);
                  else
#endif
                    evas_cache_image_drop(&im->cache_entry);

                  free(obr);
                  return NULL;
               }
             if (buf->priv.x11.xcb.mask) 
               {
                  obr->mask = 
                    evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
                                                        buf->priv.x11.xcb.visual, 
                                                        1, bw, bh, use_shm, 
                                                        NULL);
               }
          }
        /* FIXME: We should be able to remove this memset. */
        if ((alpha) && (im->image.data)) 
          {
             /* FIXME: Faster memset */
//             memset(im->image.data, 0, (w * h * sizeof(DATA32)));
          }
        buf->priv.onebuf = im;
        return im;
     }

   if (!(obr = calloc(1, sizeof(Outbuf_Region))))
     return NULL;

   obr->x = x;
   obr->y = y;
   obr->w = w;
   obr->h = h;
   if (cx) *cx = 0;
   if (cy) *cy = 0;
   if (cw) *cw = w;
   if (ch) *ch = h;

   use_shm = buf->priv.x11.xcb.shm;
   alpha = ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha));
   if ((buf->rot == 0) &&
       (buf->priv.x11.xcb.imdepth == 32) &&
       (buf->priv.mask.r == 0xff0000) && 
       (buf->priv.mask.g == 0x00ff00) &&
       (buf->priv.mask.b == 0x0000ff)) 
     {
        obr->xcbob = 
          _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, 
                      buf->priv.x11.xcb.depth, w, h, use_shm, NULL);
        if (!obr->xcbob) 
          {
             free(obr);
             return NULL;
          }
#ifdef EVAS_CSERVE2
        if (evas_cserve2_use_get())
          {
             im = 
               (RGBA_Image *)evas_cache2_image_data(evas_common_image_cache2_get(), 
                                                   w, h, 
                                                   (DATA32 *)evas_software_xcb_output_buffer_data(obr->xcbob, &bpl), 
                                                   alpha, EVAS_COLORSPACE_ARGB8888);
          }
        else
#endif
          {
             im = 
               (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), 
                                                   w, h, 
                                                   (DATA32 *)evas_software_xcb_output_buffer_data(obr->xcbob, &bpl), 
                                                   alpha, EVAS_COLORSPACE_ARGB8888);
          }

        if (!im) 
          {
             _unfind_xcbob(obr->xcbob, EINA_FALSE);
             free(obr);
             return NULL;
          }
        im->extended_info = obr;
        if (buf->priv.x11.xcb.mask) 
          {
             obr->mask = 
               _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, 
                           1, w, h, use_shm, NULL);
          }
     }
   else 
     {
        int bw = 0, bh = 0;

#ifdef EVAS_CSERVE2
        if (evas_cserve2_use_get())
          {
             im = 
               (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get());
          }
        else
#endif
          {
             im = 
               (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
          }

        if (!im) 
          {
             free(obr);
             return NULL;
          }
        im->cache_entry.flags.alpha |= (alpha ? 1 : 0);
#ifdef EVAS_CSERVE2
        if (evas_cserve2_use_get())
          evas_cache2_image_surface_alloc(&im->cache_entry, w, h);
        else
#endif
          evas_cache_image_surface_alloc(&im->cache_entry, w, h);

        im->extended_info = obr;
        if ((buf->rot == 0) || (buf->rot == 180)) 
          {
             bw = w;
             bh = h;
          }
        else if ((buf->rot == 90) || (buf->rot == 270)) 
          {
             bw = h;
             bh = w;
          }
        obr->xcbob = 
          _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, 
                      buf->priv.x11.xcb.depth, bw, bh, use_shm, NULL);
        if (!obr->xcbob) 
          {
#ifdef EVAS_CSERVE2
             if (evas_cserve2_use_get())
               evas_cache2_image_close(&im->cache_entry);
             else
#endif
               evas_cache_image_drop(&im->cache_entry);
             free(obr);
             return NULL;
          }
        if (buf->priv.x11.xcb.mask) 
          {
             obr->mask = 
               _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, 1, 
                           bw, bh, use_shm, NULL);
          }
     }
   /* FIXME: We should be able to remove this memset. */
   if (((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha)) && 
       (im->image.data)) 
     {
        /* FIXME: Faster memset */
//        memset(im->image.data, 0, (w * h * sizeof(DATA32)));
     }

   buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im);

   return im;
}