summaryrefslogtreecommitdiffstats
path: root/server/red_worker.c
diff options
context:
space:
mode:
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) {