summaryrefslogtreecommitdiffstats
path: root/server/red_worker.c
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2010-04-19 16:31:45 +0200
committerAlexander Larsson <alexl@redhat.com>2010-04-23 16:41:42 +0200
commit4f5a09a73d4659e6aaf6537bf9c582df7fe39f00 (patch)
tree611f839c79fffc4583ebd27199d2f7695718777b /server/red_worker.c
parent774e5bd36f4fc156dd744a455ff7ddda27441568 (diff)
downloadspice-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.c50
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) {