示例#1
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);
}
示例#2
0
Outbuf *
evas_software_xcb_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, xcb_connection_t *conn, xcb_screen_t *screen, xcb_drawable_t draw, xcb_visualtype_t *vis, xcb_colormap_t cmap, int xdepth, Eina_Bool grayscale, int max_colors, xcb_drawable_t mask, Eina_Bool shape_dither, Eina_Bool alpha) 
{
   Outbuf *buf = NULL;
   Gfx_Func_Convert func_conv = NULL;
   Xcb_Output_Buffer *xob;
   const xcb_setup_t *setup;

   if (!(buf = calloc(1, sizeof(Outbuf)))) 
     return NULL;

   if (xdepth < 15) rot = 0;
   
   setup = xcb_get_setup(conn);

   buf->w = w;
   buf->h = h;
   buf->depth = depth;
   buf->rot = rot;
   buf->priv.x11.xcb.conn = conn;
   buf->priv.x11.xcb.screen = screen;
   buf->priv.x11.xcb.visual = vis;
   buf->priv.x11.xcb.cmap = cmap;
   buf->priv.x11.xcb.depth = xdepth;
   buf->priv.mask_dither = shape_dither;
   buf->priv.destination_alpha = alpha;
   buf->priv.x11.xcb.shm = evas_software_xcb_can_do_shm(conn, screen);

   xob = 
     evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
                                         buf->priv.x11.xcb.visual, 
                                         buf->priv.x11.xcb.depth, 
                                         1, 1, buf->priv.x11.xcb.shm, 
                                         NULL);
   if (!xob) buf->priv.x11.xcb.shm = 0;
   xob = 
     evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
                                         buf->priv.x11.xcb.visual, 
                                         buf->priv.x11.xcb.depth, 
                                         1, 1, buf->priv.x11.xcb.shm, 
                                         NULL);
   if (!xob) 
     {
        free(buf);
        return NULL;
     }
   buf->priv.x11.xcb.imdepth = evas_software_xcb_output_buffer_depth(xob);
   evas_software_xcb_output_buffer_free(xob, EINA_FALSE);
   
   eina_array_step_set(&buf->priv.onebuf_regions, sizeof(Eina_Array), 8);

#ifdef WORDS_BIGENDIAN
   if (setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST)
     buf->priv.x11.xcb.swap = EINA_TRUE;
#else
   if (setup->image_byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
     buf->priv.x11.xcb.swap = EINA_TRUE;
#endif
   if (setup->bitmap_format_bit_order == XCB_IMAGE_ORDER_MSB_FIRST)
     buf->priv.x11.xcb.bit_swap = EINA_TRUE;

   if (((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) || 
        (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) && (xdepth > 8)) 
     {
        buf->priv.mask.r = (DATA32)vis->red_mask;
        buf->priv.mask.g = (DATA32)vis->green_mask;
        buf->priv.mask.b = (DATA32)vis->blue_mask;
        if (buf->priv.x11.xcb.swap) 
          {
             SWAP32(buf->priv.mask.r);
             SWAP32(buf->priv.mask.g);
             SWAP32(buf->priv.mask.b);
          }
     }
   else if ((vis->_class == XCB_VISUAL_CLASS_PSEUDO_COLOR) || 
            (vis->_class == XCB_VISUAL_CLASS_STATIC_COLOR) || 
            (vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) || 
            (vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY) || 
            (xdepth <= 8)) 
     {
        Convert_Pal_Mode pm = PAL_MODE_RGB332;

        if ((vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) || 
            (vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY))
          grayscale = EINA_TRUE;
        if (grayscale) 
          {
             if (max_colors >= 256)
               pm = PAL_MODE_GRAY256;
             else if (max_colors >= 64)
               pm = PAL_MODE_GRAY64;
             else if (max_colors >= 16)
               pm = PAL_MODE_GRAY16;
             else if (max_colors >= 4)
               pm = PAL_MODE_GRAY4;
             else
               pm = PAL_MODE_MONO;
          }
        else 
          {
             if (max_colors >= 256)
               pm = PAL_MODE_RGB332;
             else if (max_colors >= 216)
               pm = PAL_MODE_RGB666;
             else if (max_colors >= 128)
               pm = PAL_MODE_RGB232;
             else if (max_colors >= 64)
               pm = PAL_MODE_RGB222;
             else if (max_colors >= 32)
               pm = PAL_MODE_RGB221;
             else if (max_colors >= 16)
               pm = PAL_MODE_RGB121;
             else if (max_colors >= 8)
               pm = PAL_MODE_RGB111;
             else if (max_colors >= 4)
               pm = PAL_MODE_GRAY4;
             else
               pm = PAL_MODE_MONO;
          }
        /* FIXME: Only allocate once per display & colormap */
        buf->priv.pal = 
          evas_software_xcb_color_allocate(conn, cmap, vis, pm);
        if (!buf->priv.pal) 
          {
             free(buf);
             return NULL;
          }
     }
   if ((buf->rot == 0) || (buf->rot == 180))
     {
        w = buf->w;
        h = buf->h;
     }
   else if ((buf->rot == 90) || (buf->rot == 270)) 
     {
        w = buf->h;
        h = buf->w;
     }

   if (buf->priv.pal) 
     {
        func_conv = 
          evas_common_convert_func_get(0, w, h, xdepth, 
                                       buf->priv.mask.r, 
                                       buf->priv.mask.g, 
                                       buf->priv.mask.b, 
                                       buf->priv.pal->colors, buf->rot);
     }
   else 
     {
        func_conv = 
          evas_common_convert_func_get(0, w, h, xdepth, 
                                       buf->priv.mask.r, 
                                       buf->priv.mask.g, 
                                       buf->priv.mask.b, 
                                       PAL_MODE_NONE, buf->rot);
     }
   if (!func_conv) 
     {
        ERR("XCB Engine"
            " {"
            "  At depth         %i:"
            "  RGB format mask: %08x, %08x, %08x"
            "  Palette mode:    %i"
            "  Not supported by any compiled in converters!"
            " }", buf->priv.x11.xcb.depth, buf->priv.mask.r,
            buf->priv.mask.g, buf->priv.mask.b,
            buf->priv.pal ? (int)buf->priv.pal->colors : -1);
     }

   evas_software_xcb_outbuf_drawable_set(buf, draw);
   evas_software_xcb_outbuf_mask_set(buf, mask);

   return buf;
}
Outbuf *
evas_fb_outbuf_fb_setup_fb(int w, int h, int rot, Outbuf_Depth depth, int vt_no, int dev_no, int refresh)
{
   /* create outbuf struct */
   /* setup window and/or fb */
   /* if (dithered) create backbuf */
   Outbuf *buf;
   int fb_fd = -1;
   int fb_depth;

   fb_depth = -1;
   if (depth == OUTBUF_DEPTH_RGB_16BPP_565_565_DITHERED) fb_depth = 16;
   else if (depth == OUTBUF_DEPTH_RGB_16BPP_555_555_DITHERED) fb_depth = 15;
   else if (depth == OUTBUF_DEPTH_RGB_16BPP_565_444_DITHERED) fb_depth = 16;
   else if (depth == OUTBUF_DEPTH_RGB_16BPP_444_444_DITHERED) fb_depth = 12;
   else if (depth == OUTBUF_DEPTH_RGB_32BPP_888_8888) fb_depth = 32;
   else if (depth == OUTBUF_DEPTH_INHERIT) fb_depth = 0;
   buf = calloc(1, sizeof(Outbuf));
   if (!buf)
     return NULL;

   fb_init(vt_no, dev_no);
   if (rot == 0 || rot == 180)
     buf->priv.fb.fb = fb_setmode(w, h, fb_depth, refresh);
   else if (rot == 90 || rot == 270)
     buf->priv.fb.fb = fb_setmode(h, w, fb_depth, refresh);
   if (!buf->priv.fb.fb) buf->priv.fb.fb = fb_getmode();
   if (!buf->priv.fb.fb)
     {
	free(buf);
	return NULL;
     }
   fb_fd = fb_postinit(buf->priv.fb.fb);

   if (rot == 0 || rot == 180)
     {
 	buf->w = buf->priv.fb.fb->width;
	buf->h = buf->priv.fb.fb->height;
     }
   else if (rot == 90 || rot == 270)
     {
 	buf->w = buf->priv.fb.fb->height;
	buf->h = buf->priv.fb.fb->width;
     }

   buf->depth = depth;
   buf->rot = rot;

     {
	Gfx_Func_Convert conv_func;
	int i;

	buf->priv.mask.r = 0;
	for (i = 0; i < (int)buf->priv.fb.fb->fb_var.red.length; i++)
	  buf->priv.mask.r |= (1 << (buf->priv.fb.fb->fb_var.red.offset + i));
	buf->priv.mask.g = 0;
	for (i = 0; i < (int)buf->priv.fb.fb->fb_var.green.length; i++)
	  buf->priv.mask.g |= (1 << (buf->priv.fb.fb->fb_var.green.offset + i));
	buf->priv.mask.b = 0;
	for (i = 0; i < (int)buf->priv.fb.fb->fb_var.blue.length; i++)
	  buf->priv.mask.b |= (1 << (buf->priv.fb.fb->fb_var.blue.offset + i));

	conv_func = NULL;
	if (buf->rot == 0 || buf->rot == 180)
	  conv_func = evas_common_convert_func_get(0, buf->w, buf->h,
				       buf->priv.fb.fb->fb_var.bits_per_pixel,
				       buf->priv.mask.r,
				       buf->priv.mask.g,
				       buf->priv.mask.b,
				       PAL_MODE_NONE,
				       buf->rot);
	else if (buf->rot == 90 || buf->rot == 270)
	  conv_func = evas_common_convert_func_get(0, buf->h, buf->w,
				       buf->priv.fb.fb->fb_var.bits_per_pixel,
				       buf->priv.mask.r,
				       buf->priv.mask.g,
				       buf->priv.mask.b,
				       PAL_MODE_NONE,
				       buf->rot);
       if (!conv_func)
	  {
	     free(buf);
	     return NULL;
	  }
     }
//   if (buf->priv.fb.fb->fb_var.bits_per_pixel < 24)
//     buf->priv.back_buf = evas_common_image_create(buf->w, buf->h);

   return buf;
}
void
evas_fb_outbuf_fb_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, int y, int w, int h)
{
   if (!buf->priv.fb.fb) return;
   if (buf->priv.back_buf)
     {
	if (update != buf->priv.back_buf)
	  evas_common_blit_rectangle(update, buf->priv.back_buf,
			 0, 0, w, h, x, y);
	evas_fb_outbuf_fb_update(buf, x, y, w, h);
     }
   else
     {
	Gfx_Func_Convert conv_func;
	DATA8 *data;

	data = NULL;
	conv_func = NULL;
	if (buf->rot == 0)
	  {
	     data = (DATA8 *)buf->priv.fb.fb->mem +
	       buf->priv.fb.fb->mem_offset +
	       buf->priv.fb.fb->bpp *
	       (x + (y * buf->priv.fb.fb->width));
	     conv_func = evas_common_convert_func_get(data, w, h,
					  buf->priv.fb.fb->fb_var.bits_per_pixel,
					  buf->priv.mask.r, buf->priv.mask.g,
					  buf->priv.mask.b, PAL_MODE_NONE,
					  buf->rot);
	  }
        else if (buf->rot == 180)  
          {
             data = (DATA8 *)buf->priv.fb.fb->mem +
               buf->priv.fb.fb->mem_offset +
               buf->priv.fb.fb->bpp *  
               (buf->w - x - w + ((buf->h - y - h) * buf->priv.fb.fb->width));
             conv_func = evas_common_convert_func_get(data, w, h,
                                          buf->priv.fb.fb->fb_var.bits_per_pixel,
                                          buf->priv.mask.r, buf->priv.mask.g,
                                          buf->priv.mask.b, PAL_MODE_NONE,
                                          buf->rot);
          }
	else if (buf->rot == 270)
	  {
	     data = (DATA8 *)buf->priv.fb.fb->mem +
	       buf->priv.fb.fb->mem_offset +
	       buf->priv.fb.fb->bpp *
	       (buf->h - y - h + (x * buf->priv.fb.fb->width));
	     conv_func = evas_common_convert_func_get(data, h, w,
					  buf->priv.fb.fb->fb_var.bits_per_pixel,
					  buf->priv.mask.r, buf->priv.mask.g,
					  buf->priv.mask.b, PAL_MODE_NONE,
					  buf->rot);
	  }
	else if (buf->rot == 90)
	  {
	     data = (DATA8 *)buf->priv.fb.fb->mem +
	       buf->priv.fb.fb->mem_offset +
	       buf->priv.fb.fb->bpp *
	       (y + ((buf->w - x - w) * buf->priv.fb.fb->width));
	     conv_func = evas_common_convert_func_get(data, h, w,
					  buf->priv.fb.fb->fb_var.bits_per_pixel,
					  buf->priv.mask.r, buf->priv.mask.g,
					  buf->priv.mask.b, PAL_MODE_NONE,
					  buf->rot);
	  }
	if (conv_func)
	  {
	     DATA32 *src_data;

	     src_data = update->image.data;
	     if (buf->rot == 0 || buf->rot == 180)
	       {
		  conv_func(src_data, data,
			    0,
			    buf->priv.fb.fb->width - w,
			    w, h,
			    x, y, NULL);
	       }
	     else if (buf->rot == 90 || buf->rot == 270)
	       {
		  conv_func(src_data, data,
			    0,
			    buf->priv.fb.fb->width - h,
			    h, w,
			    x, y, NULL);
	       }
	  }
     }
}
void
evas_fb_outbuf_fb_update(Outbuf *buf, int x, int y, int w, int h)
{
   if (!(buf->priv.back_buf)) return;
   if (buf->priv.fb.fb)
     {
	Gfx_Func_Convert conv_func;
	DATA8 *data;

	data = NULL;
	conv_func = NULL;
        if (buf->rot == 0)
	  {
	     data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset +
	       buf->priv.fb.fb->bpp *
	       (x + (y * buf->priv.fb.fb->width));
	     conv_func = evas_common_convert_func_get(data, w, h, buf->priv.fb.fb->fb_var.bits_per_pixel,
					  buf->priv.mask.r, buf->priv.mask.g,
					  buf->priv.mask.b, PAL_MODE_NONE,
					  buf->rot);
	  }
        else if (buf->rot == 180)
          {
             data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset +
               buf->priv.fb.fb->bpp *
               (buf->w - x - w + ((buf->h - y - h) * buf->priv.fb.fb->width));
             conv_func = evas_common_convert_func_get(data, w, h, buf->priv.fb.fb->fb_var.bits_per_pixel,
                                          buf->priv.mask.r, buf->priv.mask.g,
                                          buf->priv.mask.b, PAL_MODE_NONE,
                                          buf->rot);
          }
	else if (buf->rot == 270)
	  {
	     data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset +
	       buf->priv.fb.fb->bpp *
	       (buf->h - y - h + (x * buf->priv.fb.fb->width));
	     conv_func = evas_common_convert_func_get(data, h, w, buf->priv.fb.fb->fb_var.bits_per_pixel,
					  buf->priv.mask.r, buf->priv.mask.g,
					  buf->priv.mask.b, PAL_MODE_NONE,
					  buf->rot);
	  }
	else if (buf->rot == 90)
	  {
	     data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset +
	       buf->priv.fb.fb->bpp *
	       (y + ((buf->w - x - w) * buf->priv.fb.fb->width));
	     conv_func = evas_common_convert_func_get(data, h, w, buf->priv.fb.fb->fb_var.bits_per_pixel,
					  buf->priv.mask.r, buf->priv.mask.g,
					  buf->priv.mask.b, PAL_MODE_NONE,
					  buf->rot);
	  }
	if (conv_func)
	  {
	     DATA32 *src_data;

	     src_data = buf->priv.back_buf->image.data + (y * buf->w) + x;
	     if (buf->rot == 0 || buf->rot == 180)
	       {
		  conv_func(src_data, data,
			    buf->w - w,
			    buf->priv.fb.fb->width - w,
			    w, h,
			    x, y, NULL);
	       }
	     else if (buf->rot == 90 || buf->rot == 270)
	       {
		  conv_func(src_data, data,
			    buf->w - w,
			    buf->priv.fb.fb->width - h,
			    h, w,
			    x, y, NULL);
	       }
	  }
     }
}