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); }
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); } } } }