diff options
author | Alexander Larsson <alexl@redhat.com> | 2010-04-19 16:31:45 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2010-04-23 16:41:42 +0200 |
commit | 4f5a09a73d4659e6aaf6537bf9c582df7fe39f00 (patch) | |
tree | 611f839c79fffc4583ebd27199d2f7695718777b /server/red_worker.c | |
parent | 774e5bd36f4fc156dd744a455ff7ddda27441568 (diff) | |
download | spice-4f5a09a73d4659e6aaf6537bf9c582df7fe39f00.tar.gz spice-4f5a09a73d4659e6aaf6537bf9c582df7fe39f00.tar.xz spice-4f5a09a73d4659e6aaf6537bf9c582df7fe39f00.zip |
Make each surface its own depth/format
Surface creation now specifies the exact format, not only the bit depth
of each surface which is used for rendering.
Additionally we now actually store the surfaces in that format, instead
of converting everything to 32bpp when drawing or e.g. handling palettes.
Diffstat (limited to 'server/red_worker.c')
-rw-r--r-- | server/red_worker.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/server/red_worker.c b/server/red_worker.c index af3a8883..7d6df888 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -872,7 +872,7 @@ typedef struct DrawContext { uint32_t width; uint32_t height; int32_t stride; - uint8_t depth; + uint32_t format; void *line_0; } DrawContext; @@ -3573,6 +3573,7 @@ static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable) uint8_t *dest; int dest_stride; RedSurface *surface; + int bpp; if (!drawable->qxl_drawable->self_bitmap) { return TRUE; @@ -3581,9 +3582,11 @@ static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable) surface = &worker->surfaces[drawable->surface_id]; + bpp = SPICE_SURFACE_FMT_DEPTH(surface->context.format) / 8; + width = drawable->qxl_drawable->bbox.right - drawable->qxl_drawable->bbox.left; height = drawable->qxl_drawable->bbox.bottom - drawable->qxl_drawable->bbox.top; - dest_stride = width * sizeof(uint32_t); + dest_stride = SPICE_ALIGN(width * bpp, 4); image = spice_malloc_n_m(height, dest_stride, sizeof(QXLImage)); dest = (uint8_t *)(image + 1); @@ -3594,7 +3597,19 @@ static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable) QXL_SET_IMAGE_ID(image, QXL_IMAGE_GROUP_RED, ++worker->bits_unique); image->bitmap.flags = QXL_BITMAP_DIRECT | (surface->context.top_down ? QXL_BITMAP_TOP_DOWN : 0); - image->bitmap.format = SPICE_BITMAP_FMT_32BIT; + switch (surface->context.format) { + case SPICE_SURFACE_FMT_32_xRGB: + image->bitmap.format = SPICE_BITMAP_FMT_32BIT; + break; + case SPICE_SURFACE_FMT_32_ARGB: + image->bitmap.format = SPICE_BITMAP_FMT_RGBA; + break; + case SPICE_SURFACE_FMT_16_555: + image->bitmap.format = SPICE_BITMAP_FMT_16BIT; + break; + default: + ASSERT(0); /* not supported yet */ + } image->bitmap.stride = dest_stride; image->descriptor.width = image->bitmap.x = width; image->descriptor.height = image->bitmap.y = height; @@ -3801,7 +3816,8 @@ static inline void red_process_drawable(RedWorker *worker, QXLDrawable *drawable } static inline void red_create_surface(RedWorker *worker, uint32_t surface_id,uint32_t width, - uint32_t height, int32_t stride, uint8_t depth, void *line_0); + uint32_t height, int32_t stride, uint32_t format, + void *line_0); static inline void red_process_surface(RedWorker *worker, QXLSurfaceCmd *surface, uint32_t group_id) { @@ -3820,13 +3836,13 @@ static inline void red_process_surface(RedWorker *worker, QXLSurfaceCmd *surface uint32_t height = surface->u.surface_create.height; int32_t stride = surface->u.surface_create.stride; QXLReleaseInfoExt release_info_ext; - + data = (uint8_t *)get_virt(&worker->mem_slots, saved_data, height * abs(stride), group_id); if (stride < 0) { data -= (int32_t)(stride * (height - 1)); } red_create_surface(worker, surface_id, surface->u.surface_create.width, - height, stride, surface->u.surface_create.depth, data); + height, stride, surface->u.surface_create.format, data); release_info_ext.group_id = group_id; release_info_ext.info = &surface->release_info; worker->qxl->release_resource(worker->qxl, release_info_ext); @@ -7881,7 +7897,7 @@ static inline void *create_canvas_for_surface(RedWorker *worker, RedSurface *sur } static SurfaceCreateItem *get_surface_create_item(uint32_t surface_id, uint32_t width, - uint32_t height, uint8_t depth, uint32_t flags) + uint32_t height, uint32_t format, uint32_t flags) { SurfaceCreateItem *create; @@ -7892,7 +7908,7 @@ static SurfaceCreateItem *get_surface_create_item(uint32_t surface_id, uint32_t create->surface_create.width = width; create->surface_create.height = height; create->surface_create.flags = flags; - create->surface_create.depth = depth; + create->surface_create.format = format; red_pipe_item_init(&create->pipe_item, PIPE_ITEM_TYPE_CREATE_SURFACE); @@ -7911,7 +7927,7 @@ static inline void __red_create_surface_item(RedWorker *worker, int surface_id, surface = &worker->surfaces[surface_id]; create = get_surface_create_item(surface_id, surface->context.width, surface->context.height, - surface->context.depth, flags); + surface->context.format, flags); worker->display_channel->surface_client_created[surface_id] = TRUE; @@ -7924,26 +7940,24 @@ static inline void red_create_surface_item(RedWorker *worker, int surface_id) __red_create_surface_item(worker, surface_id, SPICE_SURFACE_FLAGS_PRIMARY); } else { __red_create_surface_item(worker, surface_id, 0); - } + } } static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, uint32_t width, - uint32_t height, int32_t stride, uint8_t depth, void *line_0) + uint32_t height, int32_t stride, uint32_t format, + void *line_0) { uint32_t i; RedSurface *surface = &worker->surfaces[surface_id]; if (stride >= 0) { PANIC("Untested path stride >= 0"); } - if (depth != 16 && depth != 32) { - PANIC("As for now support just 32/16 depth surfaces"); - } PANIC_ON(surface->context.canvas); surface->context.canvas_draws_on_surface = FALSE; surface->context.width = width; surface->context.height = height; - surface->context.depth = depth; + surface->context.format = format; surface->context.stride = stride; surface->context.line_0 = line_0; memset(line_0 + (int32_t)(stride * (height - 1)), 0, height*abs(stride)); @@ -7957,7 +7971,7 @@ static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, ui if (worker->renderer != RED_RENDERER_INVALID) { surface->context.canvas = create_canvas_for_surface(worker, surface, worker->renderer, width, height, stride, - surface->context.depth, line_0); + surface->context.format, line_0); if (!surface->context.canvas) { PANIC("drawing canvas creating failed - can`t create same type canvas"); } @@ -7969,7 +7983,7 @@ static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, ui for (i = 0; i < worker->num_renderers; i++) { surface->context.canvas = create_canvas_for_surface(worker, surface, worker->renderers[i], width, height, stride, - surface->context.depth, line_0); + surface->context.format, line_0); if (surface->context.canvas) { //no need canvas check worker->renderer = worker->renderers[i]; red_create_surface_item(worker, surface_id); @@ -9043,7 +9057,7 @@ static inline void handle_dev_create_primary_surface(RedWorker *worker) line_0 -= (int32_t)(surface.stride * (surface.height -1)); } - red_create_surface(worker, 0, surface.width, surface.height, surface.stride, surface.depth, + red_create_surface(worker, 0, surface.width, surface.height, surface.stride, surface.format, line_0); if (worker->display_channel) { |