From b51a3f3685ef38f98e13d697bc6aa5e1c5fef730 Mon Sep 17 00:00:00 2001 From: Stanislav Vorobiov Date: Fri, 26 Apr 2013 14:00:23 +0400 Subject: [PATCH] VIGS: Refactoring for DRI2 Since we're going to support DRI2 we no longer need vigs_resource and related. All resource management is going to be on target. Also, we've temporary disabled YaGL onscreen backend and VIGS software backend, we'll enable them again once DRI2 is implemented in a basic form --- Makefile.target | 22 +-- hw/vigs_backend.h | 3 +- hw/vigs_comm.c | 358 +++++++++++++---------------------- hw/vigs_comm.h | 65 +++---- hw/vigs_device.c | 93 +--------- hw/vigs_gl_backend.c | 415 +++++++---------------------------------- hw/vigs_gl_backend.h | 16 -- hw/vigs_gl_backend_glx.c | 4 - hw/vigs_gl_backend_wgl.c | 4 - hw/vigs_id_gen.c | 30 --- hw/vigs_id_gen.h | 14 -- hw/vigs_protocol.h | 190 +++++-------------- hw/vigs_resource.c | 261 -------------------------- hw/vigs_resource.h | 31 ---- hw/vigs_server.c | 475 +++++++++++++---------------------------------- hw/vigs_server.h | 3 +- hw/vigs_surface.c | 23 +-- hw/vigs_surface.h | 42 +---- hw/winsys.h | 39 +--- hw/winsys_gl.h | 7 - hw/yagl_device.c | 6 +- 21 files changed, 435 insertions(+), 1666 deletions(-) delete mode 100644 hw/vigs_id_gen.c delete mode 100644 hw/vigs_id_gen.h delete mode 100644 hw/vigs_resource.c delete mode 100644 hw/vigs_resource.h diff --git a/Makefile.target b/Makefile.target index 6d75543..cec763f 100755 --- a/Makefile.target +++ b/Makefile.target @@ -279,12 +279,12 @@ obj-y += yagl_egl_offscreen_context.o obj-y += yagl_egl_offscreen_surface.o obj-y += yagl_egl_offscreen_image.o # EGL onscreen backend -obj-y += yagl_egl_onscreen.o -obj-y += yagl_egl_onscreen_ts.o -obj-y += yagl_egl_onscreen_display.o -obj-y += yagl_egl_onscreen_context.o -obj-y += yagl_egl_onscreen_surface.o -obj-y += yagl_egl_onscreen_image.o +#obj-y += yagl_egl_onscreen.o +#obj-y += yagl_egl_onscreen_ts.o +#obj-y += yagl_egl_onscreen_display.o +#obj-y += yagl_egl_onscreen_context.o +#obj-y += yagl_egl_onscreen_surface.o +#obj-y += yagl_egl_onscreen_image.o # EGL GLX driver ifdef CONFIG_LINUX obj-y += yagl_egl_glx.o @@ -300,11 +300,11 @@ obj-y += yagl_gles1_ogl.o # GLESv2 OpenGL driver obj-y += yagl_gles2_ogl.o # GLES onscreen common driver -obj-y += yagl_gles_onscreen.o +#obj-y += yagl_gles_onscreen.o # GLESv1_CM onscreen driver -obj-y += yagl_gles1_onscreen.o +#obj-y += yagl_gles1_onscreen.o # GLESv2 onscreen driver -obj-y += yagl_gles2_onscreen.o +#obj-y += yagl_gles2_onscreen.o endif @@ -319,13 +319,11 @@ obj-y += vigs_comm.o obj-y += vigs_server.o obj-y += vigs_backend.o obj-y += vigs_surface.o -obj-y += vigs_resource.o obj-y += vigs_utils.o -obj-y += vigs_id_gen.o obj-y += vigs_vector.o obj-y += vigs_ref.o obj-y += vigs_gl_backend.o -obj-y += vigs_sw_backend.o +#obj-y += vigs_sw_backend.o # GL GLX backend ifdef CONFIG_LINUX obj-y += vigs_gl_backend_glx.o diff --git a/hw/vigs_backend.h b/hw/vigs_backend.h index 3b9df93..8b940c1 100644 --- a/hw/vigs_backend.h +++ b/hw/vigs_backend.h @@ -15,8 +15,7 @@ struct vigs_backend uint32_t /*height*/, uint32_t /*stride*/, vigsp_surface_format /*format*/, - vigsp_offset /*vram_offset*/, - uint8_t */*data*/); + vigsp_surface_id /*id*/); void (*destroy)(struct vigs_backend */*backend*/); }; diff --git a/hw/vigs_comm.c b/hw/vigs_comm.c index 032ba37..3d96105 100644 --- a/hw/vigs_comm.c +++ b/hw/vigs_comm.c @@ -28,31 +28,28 @@ static vigsp_status vigs_comm_dispatch_init(struct vigs_comm *comm, } } -static vigsp_status vigs_comm_dispatch_reset(struct vigs_comm *comm) +static vigsp_status vigs_comm_dispatch_reset(struct vigs_comm *comm, + void *response) { VIGS_LOG_TRACE("enter"); - if (comm->comm_ops->reset(comm->user_data)) { - return vigsp_status_success; - } else { - return vigsp_status_exec_error; - } + comm->comm_ops->reset(comm->user_data); + + return vigsp_status_success; } -static vigsp_status vigs_comm_dispatch_exit(struct vigs_comm *comm) +static vigsp_status vigs_comm_dispatch_exit(struct vigs_comm *comm, + void *response) { VIGS_LOG_TRACE("enter"); - if (comm->comm_ops->exit(comm->user_data)) { - return vigsp_status_success; - } else { - return vigsp_status_exec_error; - } + comm->comm_ops->exit(comm->user_data); + + return vigsp_status_success; } -static vigsp_status vigs_comm_dispatch_create_surface(struct vigs_comm *comm, - struct vigsp_cmd_create_surface_request *request, - struct vigsp_cmd_create_surface_response *response) +static void vigs_comm_dispatch_create_surface(struct vigs_comm *comm, + struct vigsp_cmd_create_surface_request *request) { switch (request->format) { case vigsp_surface_bgrx8888: @@ -60,206 +57,96 @@ static vigsp_status vigs_comm_dispatch_create_surface(struct vigs_comm *comm, break; default: VIGS_LOG_CRITICAL("bad surface format = %d", request->format); - return vigsp_status_bad_call; - break; + return; } - VIGS_LOG_TRACE("%ux%u, strd = %u, fmt = %d, off = %d", + VIGS_LOG_TRACE("%ux%u, strd = %u, fmt = %d, id = %u", request->width, request->height, request->stride, request->format, - request->vram_offset); - - if (comm->comm_ops->create_surface(comm->user_data, - request->width, - request->height, - request->stride, - request->format, - request->vram_offset, - &response->id)) { - VIGS_LOG_TRACE("id = %u", response->id); - return vigsp_status_success; - } else { - return vigsp_status_exec_error; - } + request->id); + + comm->comm_ops->create_surface(comm->user_data, + request->width, + request->height, + request->stride, + request->format, + request->id); } -static vigsp_status vigs_comm_dispatch_destroy_surface(struct vigs_comm *comm, - struct vigsp_cmd_destroy_surface_request *request) +static void vigs_comm_dispatch_destroy_surface(struct vigs_comm *comm, + struct vigsp_cmd_destroy_surface_request *request) { VIGS_LOG_TRACE("id = %u", request->id); - if (comm->comm_ops->destroy_surface(comm->user_data, request->id)) { - return vigsp_status_success; - } else { - return vigsp_status_exec_error; - } + comm->comm_ops->destroy_surface(comm->user_data, request->id); } -static vigsp_status vigs_comm_dispatch_set_root_surface(struct vigs_comm *comm, - struct vigsp_cmd_set_root_surface_request *request) +static void vigs_comm_dispatch_set_root_surface(struct vigs_comm *comm, + struct vigsp_cmd_set_root_surface_request *request) { - VIGS_LOG_TRACE("id = %u", request->id); + VIGS_LOG_TRACE("id = %u, offset = %u", + request->id, + request->offset); - if (comm->comm_ops->set_root_surface(comm->user_data, request->id)) { - return vigsp_status_success; - } else { - return vigsp_status_exec_error; - } + comm->comm_ops->set_root_surface(comm->user_data, + request->id, + request->offset); } -static vigsp_status vigs_comm_dispatch_copy(struct vigs_comm *comm, - struct vigsp_cmd_copy_request *request) +static void vigs_comm_dispatch_update_vram(struct vigs_comm *comm, + struct vigsp_cmd_update_vram_request *request) { - VIGS_LOG_TRACE("src = %u(off = %d), dst = %u(off = %d)", - request->src.id, - request->src.vram_offset, - request->dst.id, - request->dst.vram_offset); - - if (comm->comm_ops->copy(comm->user_data, - &request->src, - &request->dst, - &request->entries[0], - request->num_entries)) { - return vigsp_status_success; - } else { - return vigsp_status_exec_error; - } -} - -static vigsp_status vigs_comm_dispatch_solid_fill(struct vigs_comm *comm, - struct vigsp_cmd_solid_fill_request *request) -{ - VIGS_LOG_TRACE("sfc = %u(off = %d), color = 0x%X", - request->sfc.id, - request->sfc.vram_offset, - request->color); + VIGS_LOG_TRACE("sfc = %u(off = %u)", + request->sfc_id, + request->offset); - if (comm->comm_ops->solid_fill(comm->user_data, - &request->sfc, - request->color, - &request->entries[0], - request->num_entries)) { - return vigsp_status_success; - } else { - return vigsp_status_exec_error; - } + comm->comm_ops->update_vram(comm->user_data, + request->sfc_id, + request->offset, + &request->rect); } -static vigsp_status vigs_comm_dispatch_update_vram(struct vigs_comm *comm, - struct vigsp_cmd_update_vram_request *request) +static void vigs_comm_dispatch_update_gpu(struct vigs_comm *comm, + struct vigsp_cmd_update_gpu_request *request) { - if (request->sfc.vram_offset < 0) { - VIGS_LOG_CRITICAL("vram_offset must be >= 0"); - return vigsp_status_bad_call; - } - - VIGS_LOG_TRACE("sfc = %u(off = %d)", - request->sfc.id, - request->sfc.vram_offset); - - if (comm->comm_ops->update_vram(comm->user_data, - &request->sfc)) { - return vigsp_status_success; - } else { - return vigsp_status_exec_error; - } -} + VIGS_LOG_TRACE("sfc = %u(off = %u)", + request->sfc_id, + request->offset); -static vigsp_status vigs_comm_dispatch_put_image(struct vigs_comm *comm, - struct vigsp_cmd_put_image_request *request, - struct vigsp_cmd_put_image_response *response) -{ - bool is_pf = false; - - VIGS_LOG_TRACE("sfc = %u(off = %d), src_va = 0x%X, src_strd = %u", - request->sfc.id, - request->sfc.vram_offset, - (uint32_t)request->src_va, - request->src_stride); - - if (comm->comm_ops->put_image(comm->user_data, - &request->sfc, - request->src_va, - request->src_stride, - &request->rect, - &is_pf)) { - response->is_pf = is_pf; - return vigsp_status_success; - } else { - return vigsp_status_exec_error; - } + comm->comm_ops->update_gpu(comm->user_data, + request->sfc_id, + request->offset, + &request->rect); } -static vigsp_status vigs_comm_dispatch_get_image(struct vigs_comm *comm, - struct vigsp_cmd_get_image_request *request, - struct vigsp_cmd_get_image_response *response) +static void vigs_comm_dispatch_copy(struct vigs_comm *comm, + struct vigsp_cmd_copy_request *request) { - bool is_pf = false; - - VIGS_LOG_TRACE("sfc = %u, dst_va = 0x%X, dst_strd = %u", - request->sfc_id, - (uint32_t)request->dst_va, - request->dst_stride); - - if (comm->comm_ops->get_image(comm->user_data, - request->sfc_id, - request->dst_va, - request->dst_stride, - &request->rect, - &is_pf)) { - response->is_pf = is_pf; - return vigsp_status_success; - } else { - return vigsp_status_exec_error; - } + VIGS_LOG_TRACE("src = %u, dst = %u", + request->src_id, + request->dst_id); + + comm->comm_ops->copy(comm->user_data, + request->src_id, + request->dst_id, + &request->entries[0], + request->num_entries); } -static vigsp_status vigs_comm_dispatch_assign_resource(struct vigs_comm *comm, - struct vigsp_cmd_assign_resource_request *request) +static void vigs_comm_dispatch_solid_fill(struct vigs_comm *comm, + struct vigsp_cmd_solid_fill_request *request) { - switch (request->res_type) { - case vigsp_resource_window: - case vigsp_resource_pixmap: - break; - default: - VIGS_LOG_CRITICAL("bad resource type = %d", request->res_type); - return vigsp_status_bad_call; - break; - } - - VIGS_LOG_TRACE("res_id = 0x%X, res_type = %d, sfc_id = %u, width = %u, height = %u", - request->res_id, - request->res_type, + VIGS_LOG_TRACE("sfc = %u, color = 0x%X", request->sfc_id, - request->width, - request->height); - - if (comm->comm_ops->assign_resource(comm->user_data, - request->res_id, - request->res_type, - request->sfc_id, - request->width, - request->height)) { - return vigsp_status_success; - } else { - return vigsp_status_exec_error; - } -} - -static vigsp_status vigs_comm_dispatch_destroy_resource(struct vigs_comm *comm, - struct vigsp_cmd_destroy_resource_request *request) -{ - VIGS_LOG_TRACE("id = 0x%X", request->id); + request->color); - if (comm->comm_ops->destroy_resource(comm->user_data, - request->id)) { - return vigsp_status_success; - } else { - return vigsp_status_exec_error; - } + comm->comm_ops->solid_fill(comm->user_data, + request->sfc_id, + request->color, + &request->entries[0], + request->num_entries); } /* @@ -281,29 +168,23 @@ static const struct vigs_dispatch_entry vigs_dispatch_table[] = VIGS_DISPATCH_ENTRY(vigsp_cmd_init, vigs_comm_dispatch_init, true, true), VIGS_DISPATCH_ENTRY(vigsp_cmd_reset, - vigs_comm_dispatch_reset, false, false), + vigs_comm_dispatch_reset, false, true), VIGS_DISPATCH_ENTRY(vigsp_cmd_exit, - vigs_comm_dispatch_exit, false, false), + vigs_comm_dispatch_exit, false, true), VIGS_DISPATCH_ENTRY(vigsp_cmd_create_surface, - vigs_comm_dispatch_create_surface, true, true), + vigs_comm_dispatch_create_surface, true, false), VIGS_DISPATCH_ENTRY(vigsp_cmd_destroy_surface, vigs_comm_dispatch_destroy_surface, true, false), VIGS_DISPATCH_ENTRY(vigsp_cmd_set_root_surface, vigs_comm_dispatch_set_root_surface, true, false), + VIGS_DISPATCH_ENTRY(vigsp_cmd_update_vram, + vigs_comm_dispatch_update_vram, true, false), + VIGS_DISPATCH_ENTRY(vigsp_cmd_update_vram, + vigs_comm_dispatch_update_gpu, true, false), VIGS_DISPATCH_ENTRY(vigsp_cmd_copy, vigs_comm_dispatch_copy, true, false), VIGS_DISPATCH_ENTRY(vigsp_cmd_solid_fill, - vigs_comm_dispatch_solid_fill, true, false), - VIGS_DISPATCH_ENTRY(vigsp_cmd_update_vram, - vigs_comm_dispatch_update_vram, true, false), - VIGS_DISPATCH_ENTRY(vigsp_cmd_put_image, - vigs_comm_dispatch_put_image, true, true), - VIGS_DISPATCH_ENTRY(vigsp_cmd_get_image, - vigs_comm_dispatch_get_image, true, true), - VIGS_DISPATCH_ENTRY(vigsp_cmd_assign_resource, - vigs_comm_dispatch_assign_resource, true, false), - VIGS_DISPATCH_ENTRY(vigsp_cmd_destroy_resource, - vigs_comm_dispatch_destroy_resource, true, false), + vigs_comm_dispatch_solid_fill, true, false) }; struct vigs_comm *vigs_comm_create(uint8_t *ram_ptr, @@ -329,38 +210,61 @@ void vigs_comm_destroy(struct vigs_comm *comm) void vigs_comm_dispatch(struct vigs_comm *comm, uint32_t ram_offset) { - struct vigsp_cmd_request_header *request_header; + struct vigsp_cmd_batch_header *batch_header = + (struct vigsp_cmd_batch_header*)(comm->ram_ptr + ram_offset); + struct vigsp_cmd_request_header *request_header = + (struct vigsp_cmd_request_header*)(batch_header + 1); struct vigsp_cmd_response_header *response_header; - vigsp_status status; - - request_header = (struct vigsp_cmd_request_header*)(comm->ram_ptr + ram_offset); - response_header = (struct vigsp_cmd_response_header*)((uint8_t*)(request_header + 1) + request_header->response_offset); - - if (request_header->cmd >= ARRAY_SIZE(vigs_dispatch_table)) { - VIGS_LOG_CRITICAL("bad command = %d", request_header->cmd); - status = vigsp_status_bad_call; - } else { - const struct vigs_dispatch_entry *dispatch_entry = - &vigs_dispatch_table[request_header->cmd]; - - if (dispatch_entry->has_request && dispatch_entry->has_response) { - vigsp_status (*func)(struct vigs_comm*, void*, void*) = - dispatch_entry->func; - status = func(comm, request_header + 1, response_header + 1); - } else if (dispatch_entry->has_request) { - vigsp_status (*func)(struct vigs_comm*, void*) = - dispatch_entry->func; - status = func(comm, request_header + 1); - } else if (dispatch_entry->has_response) { - vigsp_status (*func)(struct vigs_comm*, void*) = - dispatch_entry->func; - status = func(comm, response_header + 1); - } else { - vigsp_status (*func)(struct vigs_comm*) = - dispatch_entry->func; - status = func(comm); + vigsp_u32 i; + vigsp_status status = vigsp_status_success; + + comm->comm_ops->batch_start(comm->user_data); + + for (i = 0; i < batch_header->num_requests; ++i) { + response_header = + (struct vigsp_cmd_response_header*)((uint8_t*)(request_header + 1) + + request_header->size); + + if (status == vigsp_status_success) { + if (request_header->cmd >= ARRAY_SIZE(vigs_dispatch_table)) { + VIGS_LOG_CRITICAL("bad command = %d", request_header->cmd); + status = vigsp_status_bad_call; + } else { + const struct vigs_dispatch_entry *dispatch_entry = + &vigs_dispatch_table[request_header->cmd]; + + if (dispatch_entry->has_response && (i != (batch_header->num_requests - 1))) { + VIGS_LOG_CRITICAL("only last request in a batch is allowed to have response, bad command = %d", + request_header->cmd); + status = vigsp_status_bad_call; + } else { + if (dispatch_entry->has_request && dispatch_entry->has_response) { + vigsp_status (*func)(struct vigs_comm*, void*, void*) = + dispatch_entry->func; + status = func(comm, request_header + 1, response_header + 1); + } else if (dispatch_entry->has_request) { + vigsp_status (*func)(struct vigs_comm*, void*) = + dispatch_entry->func; + func(comm, request_header + 1); + } else if (dispatch_entry->has_response) { + vigsp_status (*func)(struct vigs_comm*, void*) = + dispatch_entry->func; + status = func(comm, response_header + 1); + } else { + vigsp_status (*func)(struct vigs_comm*) = + dispatch_entry->func; + func(comm); + } + } + } } + + request_header = (struct vigsp_cmd_request_header*)response_header; } + response_header = (struct vigsp_cmd_response_header*)request_header; + response_header->status = status; + + comm->comm_ops->batch_end(comm->user_data); } diff --git a/hw/vigs_comm.h b/hw/vigs_comm.h index 65afa77..8e47038 100644 --- a/hw/vigs_comm.h +++ b/hw/vigs_comm.h @@ -5,64 +5,51 @@ struct vigs_comm_ops { + void (*batch_start)(void */*user_data*/); + bool (*init)(void */*user_data*/); - bool (*reset)(void */*user_data*/); + void (*reset)(void */*user_data*/); - bool (*exit)(void */*user_data*/); + void (*exit)(void */*user_data*/); - bool (*create_surface)(void */*user_data*/, + void (*create_surface)(void */*user_data*/, uint32_t /*width*/, uint32_t /*height*/, uint32_t /*stride*/, vigsp_surface_format /*format*/, - vigsp_offset /*vram_offset*/, - vigsp_surface_id */*id*/); + vigsp_surface_id /*id*/); - bool (*destroy_surface)(void */*user_data*/, + void (*destroy_surface)(void */*user_data*/, vigsp_surface_id /*id*/); - bool (*set_root_surface)(void */*user_data*/, - vigsp_surface_id /*id*/); + void (*set_root_surface)(void */*user_data*/, + vigsp_surface_id /*id*/, + vigsp_offset /*offset*/); + + void (*update_vram)(void */*user_data*/, + vigsp_surface_id /*sfc_id*/, + vigsp_offset /*offset*/, + const struct vigsp_rect */*rect*/); + + void (*update_gpu)(void */*user_data*/, + vigsp_surface_id /*sfc_id*/, + vigsp_offset /*offset*/, + const struct vigsp_rect */*rect*/); - bool (*copy)(void */*user_data*/, - const struct vigsp_surface */*src*/, - const struct vigsp_surface */*dst*/, + void (*copy)(void */*user_data*/, + vigsp_surface_id /*src_id*/, + vigsp_surface_id /*dst_id*/, const struct vigsp_copy */*entries*/, uint32_t /*num_entries*/); - bool (*solid_fill)(void */*user_data*/, - const struct vigsp_surface */*sfc*/, + void (*solid_fill)(void */*user_data*/, + vigsp_surface_id /*sfc_id*/, vigsp_color /*color*/, const struct vigsp_rect */*entries*/, uint32_t /*num_entries*/); - bool (*update_vram)(void */*user_data*/, - const struct vigsp_surface */*sfc*/); - - bool (*put_image)(void */*user_data*/, - const struct vigsp_surface */*sfc*/, - target_ulong /*src_va*/, - uint32_t /*src_stride*/, - const struct vigsp_rect */*rect*/, - bool */*is_pf*/); - - bool (*get_image)(void */*user_data*/, - vigsp_surface_id /*sfc_id*/, - target_ulong /*dst_va*/, - uint32_t /*dst_stride*/, - const struct vigsp_rect */*rect*/, - bool */*is_pf*/); - - bool (*assign_resource)(void */*user_data*/, - vigsp_resource_id /*res_id*/, - vigsp_resource_type /*res_type*/, - vigsp_surface_id /*sfc_id*/, - uint32_t /*width*/, - uint32_t /*height*/); - - bool (*destroy_resource)(void */*user_data*/, - vigsp_resource_id /*res_id*/); + void (*batch_end)(void */*user_data*/); }; struct vigs_comm diff --git a/hw/vigs_device.c b/hw/vigs_device.c index 079c057..cb5ffa6 100644 --- a/hw/vigs_device.c +++ b/hw/vigs_device.c @@ -1,48 +1,14 @@ #include "vigs_device.h" #include "vigs_log.h" #include "vigs_server.h" -#include "vigs_id_gen.h" #include "vigs_backend.h" #include "hw.h" #include "console.h" -#include "kvm.h" -#include "hax.h" #define PCI_VENDOR_ID_VIGS 0x19B2 #define PCI_DEVICE_ID_VIGS 0x1011 -#define VIGS_REG_RAM_OFFSET 0 -#define VIGS_REG_CR0 8 -#define VIGS_REG_CR1 16 -#define VIGS_REG_CR2 24 -#define VIGS_REG_CR3 32 -#define VIGS_REG_CR4 40 -#define VIGS_REGS_SIZE 64 - -#define VIGS_IO_SIZE 0x4000 - -#define VIGS_MAX_USERS (VIGS_IO_SIZE / VIGS_REGS_SIZE) - -struct vigs_user -{ - /* - * For x86 only. - */ - target_ulong cr[5]; -}; - -#ifdef CONFIG_KVM -static __inline void vigs_cpu_synchronize_state(struct vigs_user *user) -{ - if (kvm_enabled()) { - memcpy(&((CPUX86State*)cpu_single_env)->cr[0], &user->cr[0], sizeof(user->cr)); - } -} -#else -static __inline void vigs_cpu_synchronize_state(struct vigs_user *user) -{ -} -#endif +#define VIGS_IO_SIZE 0x1000 typedef struct VIGSState { @@ -59,7 +25,6 @@ typedef struct VIGSState MemoryRegion io_bar; struct vigs_server *server; - struct vigs_user users[VIGS_MAX_USERS]; /* * Our display. @@ -132,49 +97,8 @@ static void vigs_io_write(void *opaque, target_phys_addr_t offset, uint64_t value, unsigned size) { VIGSState *s = opaque; - int user_index = (offset / VIGS_REGS_SIZE); - offset -= user_index * VIGS_REGS_SIZE; - assert(user_index < VIGS_MAX_USERS); - - if (user_index >= VIGS_MAX_USERS) { - VIGS_LOG_CRITICAL("bad user index = %d", user_index); - return; - } - - switch (offset) { - case VIGS_REG_RAM_OFFSET: - /* - * 'vigs_cpu_synchronize_state' is required here in order to be able to - * access target's virtual memory directly on KVM. - */ - vigs_cpu_synchronize_state(&s->users[user_index]); - vigs_server_dispatch(s->server, value); - break; - case VIGS_REG_CR0: - s->users[user_index].cr[0] = value; - VIGS_LOG_TRACE("user %d, CR0 = 0x%X", user_index, (uint32_t)s->users[user_index].cr[0]); - break; - case VIGS_REG_CR1: - s->users[user_index].cr[1] = value; - VIGS_LOG_TRACE("user %d, CR1 = 0x%X", user_index, (uint32_t)s->users[user_index].cr[1]); - break; - case VIGS_REG_CR2: - s->users[user_index].cr[2] = value; - VIGS_LOG_TRACE("user %d, CR2 = 0x%X", user_index, (uint32_t)s->users[user_index].cr[2]); - break; - case VIGS_REG_CR3: - s->users[user_index].cr[3] = value; - VIGS_LOG_TRACE("user %d, CR3 = 0x%X", user_index, (uint32_t)s->users[user_index].cr[3]); - break; - case VIGS_REG_CR4: - s->users[user_index].cr[4] = value; - VIGS_LOG_TRACE("user %d, CR4 = 0x%X", user_index, (uint32_t)s->users[user_index].cr[4]); - break; - default: - VIGS_LOG_CRITICAL("user %d, bad offset = %d", user_index, offset); - break; - } + vigs_server_dispatch(s->server, value); } static const MemoryRegionOps vigs_io_ops = @@ -223,8 +147,6 @@ static int vigs_device_init(PCIDevice *dev) TYPE_VIGS_DEVICE ".io", VIGS_IO_SIZE); - vigs_id_gen_init(); - pci_register_bar(&s->dev.pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->vram_bar); pci_register_bar(&s->dev.pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ram_bar); pci_register_bar(&s->dev.pci_dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->io_bar); @@ -232,7 +154,10 @@ static int vigs_device_init(PCIDevice *dev) if (!strcmp(vigs_backend, "gl")) { backend = vigs_gl_backend_create(s->display); } else if (!strcmp(vigs_backend, "sw")) { - backend = vigs_sw_backend_create(); + /* + * TODO: uncomment. + */ + //backend = vigs_sw_backend_create(); } if (!backend) { @@ -277,8 +202,6 @@ fail: memory_region_destroy(&s->ram_bar); memory_region_destroy(&s->vram_bar); - vigs_id_gen_cleanup(); - vigs_log_cleanup(); return -1; @@ -290,8 +213,6 @@ static void vigs_device_reset(DeviceState *d) vigs_server_reset(s->server); - vigs_id_gen_reset(); - VIGS_LOG_INFO("VIGS reset"); } @@ -305,8 +226,6 @@ static void vigs_device_exit(PCIDevice *dev) memory_region_destroy(&s->ram_bar); memory_region_destroy(&s->vram_bar); - vigs_id_gen_cleanup(); - VIGS_LOG_INFO("VIGS deinitialized"); vigs_log_cleanup(); diff --git a/hw/vigs_gl_backend.c b/hw/vigs_gl_backend.c index e199e5e..aa7b3fc 100644 --- a/hw/vigs_gl_backend.c +++ b/hw/vigs_gl_backend.c @@ -1,6 +1,5 @@ #include "vigs_gl_backend.h" #include "vigs_surface.h" -#include "vigs_id_gen.h" #include "vigs_log.h" #include "vigs_utils.h" #include "vigs_ref.h" @@ -74,22 +73,6 @@ struct vigs_gl_surface * Allocated on first access. */ GLuint tmp_tex; - - /* - * Fence that gets inserted into GL stream - * that comes from windowing system. - * - * 0 if no GL commands are pending. - */ - GLsync fence_2d; - - /* - * Fence that gets inserted into GL stream - * that comes from 3D renderer. - * - * 0 if no GL commands are pending. - */ - GLsync fence_3d; }; static __inline struct vigs_winsys_gl_surface @@ -190,88 +173,19 @@ static void vigs_gl_surface_setup_framebuffer(struct vigs_gl_surface *gl_sfc) { struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)gl_sfc->base.backend; - gl_backend->Viewport(0, 0, gl_sfc->base.width, gl_sfc->base.height); + gl_backend->Viewport(0, 0, + gl_sfc->base.ws_sfc->width, gl_sfc->base.ws_sfc->height); gl_backend->MatrixMode(GL_PROJECTION); gl_backend->LoadIdentity(); - gl_backend->Ortho(0.0, gl_sfc->base.width, 0.0, gl_sfc->base.height, -1.0, 1.0); + gl_backend->Ortho(0.0, gl_sfc->base.ws_sfc->width, + 0.0, gl_sfc->base.ws_sfc->height, + -1.0, 1.0); gl_backend->MatrixMode(GL_MODELVIEW); gl_backend->LoadIdentity(); gl_backend->Disable(GL_DEPTH_TEST); gl_backend->Disable(GL_BLEND); } -static void vigs_gl_surface_set_fence_2d(struct vigs_gl_surface *gl_sfc) -{ - struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)gl_sfc->base.backend; - - if (!gl_backend->has_arb_sync) { - gl_backend->Finish(); - return; - } - - if (gl_sfc->fence_2d) { - gl_backend->DeleteSync(gl_sfc->fence_2d); - } - - gl_sfc->fence_2d = gl_backend->FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - gl_backend->Flush(); -} - -static void vigs_gl_surface_wait_fence_2d(struct vigs_gl_surface *gl_sfc) -{ - struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)gl_sfc->base.backend; - - if (!gl_backend->has_arb_sync) { - return; - } - - if (gl_sfc->fence_2d) { - /* - * Using glClientWaitSync instead of glWaitSync because of - * nVidia bug on windows. - */ - gl_backend->ClientWaitSync(gl_sfc->fence_2d, 0, GL_TIMEOUT_IGNORED); - gl_backend->DeleteSync(gl_sfc->fence_2d); - gl_sfc->fence_2d = 0; - } -} - -static void vigs_gl_surface_set_fence_3d(struct vigs_gl_surface *gl_sfc) -{ - struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)gl_sfc->base.backend; - - if (!gl_backend->has_arb_sync) { - gl_backend->Finish(); - return; - } - - if (gl_sfc->fence_3d) { - gl_backend->DeleteSync(gl_sfc->fence_3d); - } - - gl_sfc->fence_3d = gl_backend->FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - gl_backend->Flush(); -} - -static void vigs_gl_surface_wait_fence_3d(struct vigs_gl_surface *gl_sfc) -{ - struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)gl_sfc->base.backend; - - if (!gl_backend->has_arb_sync) { - return; - } - - if (gl_sfc->fence_3d) { - /* - * Using glClientWaitSync instead of glWaitSync because of - * nVidia bug on windows. - */ - gl_backend->ClientWaitSync(gl_sfc->fence_3d, 0, GL_TIMEOUT_IGNORED); - gl_backend->DeleteSync(gl_sfc->fence_3d); - gl_sfc->fence_3d = 0; - } -} - /* * @} */ @@ -333,97 +247,6 @@ static GLuint vigs_winsys_gl_surface_get_back_texture(struct winsys_gl_surface * return vigs_sfc->back_tex; } -static void vigs_winsys_gl_surface_swap_buffers(struct winsys_gl_surface *sfc) -{ - struct vigs_winsys_gl_surface *vigs_sfc = (struct vigs_winsys_gl_surface*)sfc; - GLuint cur_fb = 0; - - if (!vigs_sfc->parent) { - return; - } - - if (!vigs_gl_surface_create_framebuffer(vigs_sfc->parent)) { - return; - } - - if (!vigs_winsys_gl_surface_create_texture(vigs_sfc, &vigs_sfc->front_tex)) { - return; - } - - vigs_gl_surface_wait_fence_2d(vigs_sfc->parent); - - vigs_sfc->backend->GetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*)&cur_fb); - - vigs_sfc->backend->BindFramebuffer(GL_READ_FRAMEBUFFER, - cur_fb); - vigs_sfc->backend->BindFramebuffer(GL_DRAW_FRAMEBUFFER, - vigs_sfc->parent->fb); - vigs_sfc->backend->FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, vigs_sfc->front_tex, 0); - - vigs_sfc->backend->BlitFramebuffer(0, 0, sfc->base.width, sfc->base.height, - 0, 0, sfc->base.width, sfc->base.height, - GL_COLOR_BUFFER_BIT, - GL_LINEAR); - - vigs_sfc->backend->BindFramebuffer(GL_FRAMEBUFFER, - cur_fb); - - vigs_gl_surface_set_fence_3d(vigs_sfc->parent); - - vigs_sfc->parent->base.is_dirty = true; -} - -static void vigs_winsys_gl_surface_copy_buffers(uint32_t width, - uint32_t height, - struct winsys_gl_surface *target, - bool is_loop) -{ - struct vigs_winsys_gl_surface *vigs_target = (struct vigs_winsys_gl_surface*)target; - GLuint cur_fb = 0; - - if (!vigs_target->parent) { - return; - } - - vigs_gl_surface_wait_fence_2d(vigs_target->parent); - - if (is_loop) { - /* - * Feedback loop is possible, no-op. - */ - } else { - if (!vigs_gl_surface_create_framebuffer(vigs_target->parent)) { - return; - } - - if (!vigs_winsys_gl_surface_create_texture(vigs_target, &vigs_target->front_tex)) { - return; - } - - vigs_target->backend->GetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*)&cur_fb); - - vigs_target->backend->BindFramebuffer(GL_READ_FRAMEBUFFER, - cur_fb); - vigs_target->backend->BindFramebuffer(GL_DRAW_FRAMEBUFFER, - vigs_target->parent->fb); - vigs_target->backend->FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, vigs_target->front_tex, 0); - - vigs_target->backend->BlitFramebuffer(0, 0, width, height, - 0, 0, width, height, - GL_COLOR_BUFFER_BIT, - GL_LINEAR); - - vigs_target->backend->BindFramebuffer(GL_FRAMEBUFFER, - cur_fb); - } - - vigs_gl_surface_set_fence_3d(vigs_target->parent); - - vigs_target->parent->base.is_dirty = true; -} - static void vigs_winsys_gl_surface_destroy(struct vigs_ref *ref) { struct vigs_winsys_gl_surface *vigs_sfc = @@ -469,8 +292,6 @@ static struct vigs_winsys_gl_surface ws_sfc->base.base.release = &vigs_winsys_gl_surface_release; ws_sfc->base.get_front_texture = &vigs_winsys_gl_surface_get_front_texture; ws_sfc->base.get_back_texture = &vigs_winsys_gl_surface_get_back_texture; - ws_sfc->base.swap_buffers = &vigs_winsys_gl_surface_swap_buffers; - ws_sfc->base.copy_buffers = &vigs_winsys_gl_surface_copy_buffers; ws_sfc->tex_internalformat = tex_internalformat; ws_sfc->tex_format = tex_format; ws_sfc->tex_type = tex_type; @@ -497,76 +318,11 @@ static void vigs_winsys_gl_surface_orphan(struct vigs_winsys_gl_surface *sfc) * @{ */ -static void vigs_gl_surface_update(struct vigs_surface *sfc, - vigsp_offset vram_offset, - uint8_t *data) -{ - struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)sfc->backend; - struct vigs_gl_surface *gl_sfc = (struct vigs_gl_surface*)sfc; - struct vigs_winsys_gl_surface *ws_sfc = get_ws_sfc(gl_sfc); - - assert(data != NULL); - - if (!gl_backend->make_current(gl_backend, true)) { - return; - } - - sfc->vram_offset = vram_offset; - sfc->data = data; - - if (!vigs_winsys_gl_surface_create_texture(ws_sfc, &ws_sfc->front_tex)) { - goto out; - } - - if (!vigs_gl_surface_create_framebuffer(gl_sfc)) { - goto out; - } - - vigs_gl_surface_wait_fence_3d(gl_sfc); - - gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_sfc->fb); - - vigs_gl_surface_setup_framebuffer(gl_sfc); - - gl_backend->Disable(GL_TEXTURE_2D); - - gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, ws_sfc->front_tex, 0); - - gl_backend->PixelZoom(1.0f, -1.0f); - gl_backend->RasterPos2f(0.0f, gl_sfc->base.height); - gl_backend->DrawPixels(gl_sfc->base.width, - gl_sfc->base.height, - ws_sfc->tex_format, - ws_sfc->tex_type, - data); - - vigs_gl_surface_set_fence_2d(gl_sfc); - - sfc->is_dirty = false; - - VIGS_LOG_TRACE("updated"); - -out: - gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0); - - gl_backend->make_current(gl_backend, false); -} - -static void vigs_gl_surface_set_data(struct vigs_surface *sfc, - vigsp_offset vram_offset, - uint8_t *data) -{ - sfc->vram_offset = vram_offset; - sfc->data = data; -} - static void vigs_gl_surface_read_pixels(struct vigs_surface *sfc, uint32_t x, uint32_t y, uint32_t width, uint32_t height, - uint32_t stride, uint8_t *pixels) { struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)sfc->backend; @@ -579,11 +335,6 @@ static void vigs_gl_surface_read_pixels(struct vigs_surface *sfc, VIGS_LOG_TRACE("x = %u, y = %u, width = %u, height = %u", x, y, width, height); - if ((width * ws_sfc->tex_bpp) != stride) { - VIGS_LOG_ERROR("Custom strides not supported yet"); - return; - } - if (!gl_backend->make_current(gl_backend, true)) { return; } @@ -604,13 +355,11 @@ static void vigs_gl_surface_read_pixels(struct vigs_surface *sfc, goto out; } - vigs_gl_surface_wait_fence_3d(gl_sfc); - vigs_vector_resize(&gl_backend->v1, 0); vigs_vector_resize(&gl_backend->v2, 0); - sfc_w = gl_sfc->base.width; - sfc_h = gl_sfc->base.height; + sfc_w = ws_sfc->base.base.width; + sfc_h = ws_sfc->base.base.height; gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_sfc->fb); @@ -670,6 +419,59 @@ out: gl_backend->make_current(gl_backend, false); } +static void vigs_gl_surface_draw_pixels(struct vigs_surface *sfc, + uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height, + uint8_t *pixels) +{ + struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)sfc->backend; + struct vigs_gl_surface *gl_sfc = (struct vigs_gl_surface*)sfc; + struct vigs_winsys_gl_surface *ws_sfc = get_ws_sfc(gl_sfc); + + VIGS_LOG_TRACE("x = %u, y = %u, width = %u, height = %u", + x, y, width, height); + + if (!gl_backend->make_current(gl_backend, true)) { + return; + } + + if (!vigs_winsys_gl_surface_create_texture(ws_sfc, &ws_sfc->front_tex)) { + goto out; + } + + if (!vigs_gl_surface_create_framebuffer(gl_sfc)) { + goto out; + } + + gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_sfc->fb); + + vigs_gl_surface_setup_framebuffer(gl_sfc); + + gl_backend->Disable(GL_TEXTURE_2D); + + gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, ws_sfc->front_tex, 0); + + gl_backend->PixelZoom(1.0f, -1.0f); + gl_backend->RasterPos2f(x, ws_sfc->base.base.height - y); + gl_backend->DrawPixels(width, + height, + ws_sfc->tex_format, + ws_sfc->tex_type, + pixels); + + gl_backend->Finish(); + + gl_sfc->base.is_dirty = true; + +out: + gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0); + + gl_backend->make_current(gl_backend, false); +} + static void vigs_gl_surface_copy(struct vigs_surface *dst, struct vigs_surface *src, const struct vigsp_copy *entries, @@ -709,12 +511,9 @@ static void vigs_gl_surface_copy(struct vigs_surface *dst, vigs_vector_resize(&gl_backend->v1, 0); vigs_vector_resize(&gl_backend->v2, 0); - src_w = gl_src->base.width; - src_h = gl_src->base.height; - dst_h = gl_dst->base.height; - - vigs_gl_surface_wait_fence_3d(gl_src); - vigs_gl_surface_wait_fence_3d(gl_dst); + src_w = ws_src->base.base.width; + src_h = ws_src->base.base.height; + dst_h = ws_dst->base.base.height; gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_dst->fb); @@ -848,7 +647,7 @@ static void vigs_gl_surface_copy(struct vigs_surface *dst, gl_backend->DisableClientState(GL_TEXTURE_COORD_ARRAY); gl_backend->DisableClientState(GL_VERTEX_ARRAY); - vigs_gl_surface_set_fence_2d(gl_dst); + gl_backend->Finish(); gl_dst->base.is_dirty = true; @@ -882,9 +681,7 @@ static void vigs_gl_surface_solid_fill(struct vigs_surface *sfc, goto out; } - sfc_h = gl_sfc->base.height; - - vigs_gl_surface_wait_fence_3d(gl_sfc); + sfc_h = ws_sfc->base.base.height; gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_sfc->fb); @@ -928,62 +725,7 @@ static void vigs_gl_surface_solid_fill(struct vigs_surface *sfc, gl_backend->DisableClientState(GL_VERTEX_ARRAY); - vigs_gl_surface_set_fence_2d(gl_sfc); - - gl_sfc->base.is_dirty = true; - -out: - gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0); - - gl_backend->make_current(gl_backend, false); -} - -static void vigs_gl_surface_put_image(struct vigs_surface *sfc, - const void *src, - uint32_t src_stride, - const struct vigsp_rect *rect) -{ - struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)sfc->backend; - struct vigs_gl_surface *gl_sfc = (struct vigs_gl_surface*)sfc; - struct vigs_winsys_gl_surface *ws_sfc = get_ws_sfc(gl_sfc); - - if (!gl_backend->make_current(gl_backend, true)) { - return; - } - - if ((rect->size.w * ws_sfc->tex_bpp) != src_stride) { - VIGS_LOG_ERROR("Custom strides not supported yet"); - goto out; - } - - if (!vigs_winsys_gl_surface_create_texture(ws_sfc, &ws_sfc->front_tex)) { - goto out; - } - - if (!vigs_gl_surface_create_framebuffer(gl_sfc)) { - goto out; - } - - vigs_gl_surface_wait_fence_3d(gl_sfc); - - gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_sfc->fb); - - vigs_gl_surface_setup_framebuffer(gl_sfc); - - gl_backend->Disable(GL_TEXTURE_2D); - - gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, ws_sfc->front_tex, 0); - - gl_backend->PixelZoom(1.0f, -1.0f); - gl_backend->RasterPos2f(rect->pos.x, gl_sfc->base.height - rect->pos.y); - gl_backend->DrawPixels(rect->size.w, - rect->size.h, - ws_sfc->tex_format, - ws_sfc->tex_type, - src); - - vigs_gl_surface_set_fence_2d(gl_sfc); + gl_backend->Finish(); gl_sfc->base.is_dirty = true; @@ -1009,15 +751,6 @@ static void vigs_gl_surface_destroy(struct vigs_surface *sfc) gl_backend->DeleteTextures(1, &gl_sfc->tmp_tex); } - if (gl_backend->has_arb_sync) { - if (gl_sfc->fence_2d) { - gl_backend->DeleteSync(gl_sfc->fence_2d); - } - if (gl_sfc->fence_3d) { - gl_backend->DeleteSync(gl_sfc->fence_3d); - } - } - gl_backend->make_current(gl_backend, false); } @@ -1035,8 +768,7 @@ static struct vigs_surface *vigs_gl_backend_create_surface(struct vigs_backend * uint32_t height, uint32_t stride, vigsp_surface_format format, - vigsp_offset vram_offset, - uint8_t *data) + vigsp_surface_id id) { struct vigs_gl_surface *gl_sfc = NULL; struct vigs_winsys_gl_surface *ws_sfc = NULL; @@ -1078,20 +810,16 @@ static struct vigs_surface *vigs_gl_backend_create_surface(struct vigs_backend * vigs_surface_init(&gl_sfc->base, &ws_sfc->base.base, backend, - vigs_id_gen(), stride, format, - vram_offset, - data); + id); ws_sfc->base.base.release(&ws_sfc->base.base); - gl_sfc->base.update = &vigs_gl_surface_update; - gl_sfc->base.set_data = &vigs_gl_surface_set_data; gl_sfc->base.read_pixels = &vigs_gl_surface_read_pixels; + gl_sfc->base.draw_pixels = &vigs_gl_surface_draw_pixels; gl_sfc->base.copy = &vigs_gl_surface_copy; gl_sfc->base.solid_fill = &vigs_gl_surface_solid_fill; - gl_sfc->base.put_image = &vigs_gl_surface_put_image; gl_sfc->base.destroy = &vigs_gl_surface_destroy; return &gl_sfc->base; @@ -1149,10 +877,6 @@ bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend) * @{ */ - /* - * ARB_sync is not mandatory, but if present gives additional - * performance. - */ /*gl_backend->has_arb_sync = (strstr(extensions, "GL_ARB_sync ") != NULL) && gl_backend->FenceSync && gl_backend->DeleteSync && @@ -1163,7 +887,6 @@ bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend) } else { VIGS_LOG_WARN("ARB_sync not supported!"); }*/ - gl_backend->has_arb_sync = false; /* * @} diff --git a/hw/vigs_gl_backend.h b/hw/vigs_gl_backend.h index 69f9b69..ee16427 100644 --- a/hw/vigs_gl_backend.h +++ b/hw/vigs_gl_backend.h @@ -82,20 +82,6 @@ struct vigs_gl_backend */ /* - * Optional GL extensions. - * @{ - */ - - GLsync (GLAPIENTRY *FenceSync)(GLenum condition, GLbitfield flags); - void (GLAPIENTRY *DeleteSync)(GLsync sync); - void (GLAPIENTRY *WaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); - GLenum (GLAPIENTRY *ClientWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); - - /* - * @} - */ - - /* * General purpose vectors. * @{ */ @@ -106,8 +92,6 @@ struct vigs_gl_backend /* * @} */ - - bool has_arb_sync; }; bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend); diff --git a/hw/vigs_gl_backend_glx.c b/hw/vigs_gl_backend_glx.c index ffb96b3..aa60dd6 100644 --- a/hw/vigs_gl_backend_glx.c +++ b/hw/vigs_gl_backend_glx.c @@ -296,10 +296,6 @@ struct vigs_backend *vigs_gl_backend_create(void *display) VIGS_GL_GET_PROC(BlendFunc, glBlendFunc); VIGS_GL_GET_PROC(CopyTexImage2D, glCopyTexImage2D); VIGS_GL_GET_PROC(BlitFramebuffer, glBlitFramebufferEXT); - VIGS_GL_GET_PROC_OPTIONAL(FenceSync, glFenceSync); - VIGS_GL_GET_PROC_OPTIONAL(DeleteSync, glDeleteSync); - VIGS_GL_GET_PROC_OPTIONAL(WaitSync, glWaitSync); - VIGS_GL_GET_PROC_OPTIONAL(ClientWaitSync, glClientWaitSync); gl_backend_glx->dpy = x_display; diff --git a/hw/vigs_gl_backend_wgl.c b/hw/vigs_gl_backend_wgl.c index 7f030e9..263e150 100644 --- a/hw/vigs_gl_backend_wgl.c +++ b/hw/vigs_gl_backend_wgl.c @@ -408,10 +408,6 @@ struct vigs_backend *vigs_gl_backend_create(void *display) VIGS_GL_GET_PROC(BlendFunc, glBlendFunc); VIGS_GL_GET_PROC(CopyTexImage2D, glCopyTexImage2D); VIGS_GL_GET_PROC(BlitFramebuffer, glBlitFramebufferEXT); - VIGS_GL_GET_PROC_OPTIONAL(FenceSync, glFenceSync); - VIGS_GL_GET_PROC_OPTIONAL(DeleteSync, glDeleteSync); - VIGS_GL_GET_PROC_OPTIONAL(WaitSync, glWaitSync); - VIGS_GL_GET_PROC_OPTIONAL(ClientWaitSync, glClientWaitSync); gl_backend_wgl->wglMakeCurrent(NULL, NULL); gl_backend_wgl->wglDeleteContext(tmp_ctx); diff --git a/hw/vigs_id_gen.c b/hw/vigs_id_gen.c deleted file mode 100644 index b90c86c..0000000 --- a/hw/vigs_id_gen.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "vigs_id_gen.h" - -static vigsp_surface_id g_id_gen_next = 0; - -void vigs_id_gen_init(void) -{ -} - -void vigs_id_gen_reset(void) -{ - g_id_gen_next = 0; -} - -void vigs_id_gen_cleanup(void) -{ -} - -vigsp_surface_id vigs_id_gen(void) -{ - if (!g_id_gen_next) - { - /* - * 0 ids are invalid. - */ - - ++g_id_gen_next; - } - - return g_id_gen_next++; -} diff --git a/hw/vigs_id_gen.h b/hw/vigs_id_gen.h deleted file mode 100644 index 94ba141..0000000 --- a/hw/vigs_id_gen.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _QEMU_VIGS_ID_GEN_H -#define _QEMU_VIGS_ID_GEN_H - -#include "vigs_types.h" - -void vigs_id_gen_init(void); - -void vigs_id_gen_reset(void); - -void vigs_id_gen_cleanup(void); - -vigsp_surface_id vigs_id_gen(void); - -#endif diff --git a/hw/vigs_protocol.h b/hw/vigs_protocol.h index 00f8a98..739490d 100644 --- a/hw/vigs_protocol.h +++ b/hw/vigs_protocol.h @@ -2,16 +2,19 @@ #define _VIGS_PROTOCOL_H_ /* - * VIGS protocol is a request-response protocol. + * VIGS protocol is a multiple request-single response protocol. * - * + Requests come one by one. - * + The response is written after the request. + * + Requests come batched. + * + The response is written after the request batch. + * + * Not all commands can be batched, only commands that don't have response + * data can be batched. */ /* * Bump this whenever protocol changes. */ -#define VIGS_PROTOCOL_VERSION 10 +#define VIGS_PROTOCOL_VERSION 11 typedef signed char vigsp_s8; typedef signed short vigsp_s16; @@ -24,10 +27,9 @@ typedef unsigned long long vigsp_u64; typedef vigsp_u32 vigsp_bool; typedef vigsp_u32 vigsp_surface_id; -typedef vigsp_s32 vigsp_offset; +typedef vigsp_u32 vigsp_offset; typedef vigsp_u32 vigsp_color; typedef vigsp_u64 vigsp_va; -typedef vigsp_u32 vigsp_resource_id; typedef enum { @@ -37,13 +39,10 @@ typedef enum vigsp_cmd_create_surface = 0x3, vigsp_cmd_destroy_surface = 0x4, vigsp_cmd_set_root_surface = 0x5, - vigsp_cmd_copy = 0x6, - vigsp_cmd_solid_fill = 0x7, - vigsp_cmd_update_vram = 0x8, - vigsp_cmd_put_image = 0x9, - vigsp_cmd_get_image = 0xA, - vigsp_cmd_assign_resource = 0xB, - vigsp_cmd_destroy_resource = 0xC, + vigsp_cmd_update_vram = 0x6, + vigsp_cmd_update_gpu = 0x7, + vigsp_cmd_copy = 0x8, + vigsp_cmd_solid_fill = 0x9, } vigsp_cmd; typedef enum @@ -62,27 +61,8 @@ typedef enum vigsp_surface_bgra8888 = 0x1, } vigsp_surface_format; -typedef enum -{ - vigsp_resource_window = 0x0, - vigsp_resource_pixmap = 0x1, -} vigsp_resource_type; - #pragma pack(1) -/* - * 'vram_offset' is both surface data offset - * and dirty flag. when it's < 0 it means surface data - * is not allocated on target or surface is not dirty. - * When it's >= 0 it means either surface data has been allocated - * or surface is dirty in case if data has been allocated before. - */ -struct vigsp_surface -{ - vigsp_surface_id id; - vigsp_offset vram_offset; -}; - struct vigsp_point { vigsp_u32 x; @@ -108,14 +88,19 @@ struct vigsp_copy struct vigsp_size size; }; +struct vigsp_cmd_batch_header +{ + vigsp_u32 num_requests; +}; + struct vigsp_cmd_request_header { vigsp_cmd cmd; /* - * Response offset counting after request header. + * Request size starting from request header. */ - vigsp_u32 response_offset; + vigsp_u32 size; }; struct vigsp_cmd_response_header @@ -171,14 +156,9 @@ struct vigsp_cmd_init_response /* * cmd_create_surface * - * Called for each surface created. Server returns 'id' of the surface, + * Called for each surface created. Client passes 'id' of the surface, * all further operations must be carried out using this is. 'id' is - * unique across whole target system, because there can be only one - * DRM master (like X.Org) on target and this master typically wants to - * share the surfaces with other processes. - * - * 'vram_offset' points to the surface data in VRAM, if any. If no surface data - * is provided then 'vram_surface' must be < 0. + * unique across whole target system. * * @{ */ @@ -189,11 +169,6 @@ struct vigsp_cmd_create_surface_request vigsp_u32 height; vigsp_u32 stride; vigsp_surface_format format; - vigsp_offset vram_offset; -}; - -struct vigsp_cmd_create_surface_response -{ vigsp_surface_id id; }; @@ -205,7 +180,7 @@ struct vigsp_cmd_create_surface_response * cmd_destroy_surface * * Destroys the surface identified by 'id'. Surface 'id' may not be used - * after this call and its data can be assigned to some other surface right + * after this call and its id can be assigned to some other surface right * after this call. * * @{ @@ -224,7 +199,8 @@ struct vigsp_cmd_destroy_surface_request * cmd_set_root_surface * * Sets surface identified by 'id' as new root surface. Root surface is the - * one that's displayed on screen. Root surface must have data. + * one that's displayed on screen. Root surface must reside in VRAM + * all the time, pass 'offset' in VRAM here. * * Pass 0 as id in order to reset the root surface. * @@ -234,47 +210,7 @@ struct vigsp_cmd_destroy_surface_request struct vigsp_cmd_set_root_surface_request { vigsp_surface_id id; -}; - -/* - * @} - */ - -/* - * cmd_copy - * - * Copies parts of surface 'src' to - * surface 'dst'. - * - * @{ - */ - -struct vigsp_cmd_copy_request -{ - struct vigsp_surface src; - struct vigsp_surface dst; - vigsp_u32 num_entries; - struct vigsp_copy entries[0]; -}; - -/* - * @} - */ - -/* - * cmd_solid_fill - * - * Fills surface 'sfc' with color 'color' at 'entries'. - * - * @{ - */ - -struct vigsp_cmd_solid_fill_request -{ - struct vigsp_surface sfc; - vigsp_color color; - vigsp_u32 num_entries; - struct vigsp_rect entries[0]; + vigsp_offset offset; }; /* @@ -284,91 +220,56 @@ struct vigsp_cmd_solid_fill_request /* * cmd_update_vram * - * Updates 'sfc' data in vram. + * Updates 'sfc_id' in vram. * * @{ */ struct vigsp_cmd_update_vram_request { - struct vigsp_surface sfc; -}; - -/* - * @} - */ - -/* - * cmd_put_image - * - * Puts image 'src_va' on surface 'sfc'. - * Host may detect page fault condition, in that case it'll - * set 'is_pf' to 1 in response, target then must fault in 'src_va' - * memory and repeat this command. - * - * @{ - */ - -struct vigsp_cmd_put_image_request -{ - struct vigsp_surface sfc; - vigsp_va src_va; - vigsp_u32 src_stride; + vigsp_surface_id sfc_id; + vigsp_offset offset; struct vigsp_rect rect; }; -struct vigsp_cmd_put_image_response -{ - vigsp_bool is_pf; -}; - /* * @} */ /* - * cmd_get_image + * cmd_update_gpu * - * Gets image 'dst_va' from surface 'sfc_id'. - * Host may detect page fault condition, in that case it'll - * set 'is_pf' to 1 in response, target then must fault in 'dst_va' - * memory and repeat this command. + * Updates 'sfc_id' in GPU. * * @{ */ -struct vigsp_cmd_get_image_request +struct vigsp_cmd_update_gpu_request { vigsp_surface_id sfc_id; - vigsp_va dst_va; - vigsp_u32 dst_stride; + vigsp_offset offset; struct vigsp_rect rect; }; -struct vigsp_cmd_get_image_response -{ - vigsp_bool is_pf; -}; - /* * @} */ /* - * cmd_assign_resource + * cmd_copy * - * Assign resource 'res_id' to refer to surface 'sfc_id'. + * Copies parts of surface 'src_id' to + * surface 'dst_id'. * * @{ */ -struct vigsp_cmd_assign_resource_request +struct vigsp_cmd_copy_request { - vigsp_resource_id res_id; - vigsp_resource_type res_type; - vigsp_surface_id sfc_id; - vigsp_u32 width; - vigsp_u32 height; + vigsp_surface_id src_id; + vigsp_surface_id dst_id; + vigsp_u32 num_entries; + struct vigsp_copy entries[0]; }; /* @@ -376,16 +277,19 @@ struct vigsp_cmd_assign_resource_request */ /* - * cmd_destroy_resource + * cmd_solid_fill * - * Destroys resource 'id'. + * Fills surface 'sfc_id' with color 'color' at 'entries'. * * @{ */ -struct vigsp_cmd_destroy_resource_request +struct vigsp_cmd_solid_fill_request { - vigsp_resource_id id; + vigsp_surface_id sfc_id; + vigsp_color color; + vigsp_u32 num_entries; + struct vigsp_rect entries[0]; }; /* diff --git a/hw/vigs_resource.c b/hw/vigs_resource.c deleted file mode 100644 index 513fe10..0000000 --- a/hw/vigs_resource.c +++ /dev/null @@ -1,261 +0,0 @@ -#include "vigs_resource.h" -#include "vigs_ref.h" -#include "vigs_surface.h" -#include "vigs_log.h" -#include "winsys.h" -#include "qemu-queue.h" - -/* - * vigs_winsys_resource - * @{ - */ - -struct vigs_winsys_resource_cb -{ - QLIST_ENTRY(vigs_winsys_resource_cb) entry; - - winsys_resource_cb cb; - void *user_data; -}; - -struct vigs_winsys_resource -{ - struct winsys_resource base; - - struct vigs_ref ref; - - struct winsys_surface *ws_sfc; - - uint32_t width; - - uint32_t height; - - QLIST_HEAD(, vigs_winsys_resource_cb) callbacks; -}; - -static void vigs_winsys_resource_acquire(struct winsys_resource *res) -{ - struct vigs_winsys_resource *vigs_res = (struct vigs_winsys_resource*)res; - vigs_ref_acquire(&vigs_res->ref); -} - -static void vigs_winsys_resource_release(struct winsys_resource *res) -{ - struct vigs_winsys_resource *vigs_res = (struct vigs_winsys_resource*)res; - vigs_ref_release(&vigs_res->ref); -} - -static void *vigs_winsys_resource_add_callback(struct winsys_resource *res, - winsys_resource_cb cb, - void *user_data) -{ - struct vigs_winsys_resource *vigs_res = (struct vigs_winsys_resource*)res; - struct vigs_winsys_resource_cb *vigs_cb; - - vigs_cb = g_malloc0(sizeof(*vigs_cb)); - - vigs_cb->cb = cb; - vigs_cb->user_data = user_data; - - QLIST_INSERT_HEAD(&vigs_res->callbacks, vigs_cb, entry); - - return vigs_cb; -} - -static void vigs_winsys_resource_remove_callback(struct winsys_resource *res, - void *cookie) -{ - struct vigs_winsys_resource_cb *vigs_cb = cookie; - QLIST_REMOVE(vigs_cb, entry); - g_free(vigs_cb); -} - -static uint32_t vigs_winsys_resource_get_width(struct winsys_resource *res) -{ - struct vigs_winsys_resource *vigs_res = (struct vigs_winsys_resource*)res; - return vigs_res->width; -} - -static uint32_t vigs_winsys_resource_get_height(struct winsys_resource *res) -{ - struct vigs_winsys_resource *vigs_res = (struct vigs_winsys_resource*)res; - return vigs_res->height; -} - -static struct winsys_surface - *vigs_winsys_resource_acquire_surface(struct winsys_resource *res) -{ - struct vigs_winsys_resource *vigs_res = (struct vigs_winsys_resource*)res; - - if (vigs_res->ws_sfc) { - vigs_res->ws_sfc->acquire(vigs_res->ws_sfc); - } - - return vigs_res->ws_sfc; -} - -static void vigs_winsys_resource_destroy(struct vigs_ref *ref) -{ - struct vigs_winsys_resource *vigs_res = - container_of(ref, struct vigs_winsys_resource, ref); - struct vigs_winsys_resource_cb *cb, *next; - - QLIST_FOREACH_SAFE(cb, &vigs_res->callbacks, entry, next) { - QLIST_REMOVE(cb, entry); - g_free(cb); - } - - if (vigs_res->ws_sfc) { - vigs_res->ws_sfc->release(vigs_res->ws_sfc); - vigs_res->ws_sfc = NULL; - } - - vigs_ref_cleanup(&vigs_res->ref); - - g_free(vigs_res); -} - -static struct vigs_winsys_resource - *vigs_winsys_resource_create(winsys_id id, - winsys_res_type type) -{ - struct vigs_winsys_resource *ws_res; - - ws_res = g_malloc0(sizeof(*ws_res)); - - ws_res->base.id = id; - ws_res->base.type = type; - ws_res->base.acquire = &vigs_winsys_resource_acquire; - ws_res->base.release = &vigs_winsys_resource_release; - ws_res->base.add_callback = &vigs_winsys_resource_add_callback; - ws_res->base.remove_callback = &vigs_winsys_resource_remove_callback; - ws_res->base.get_width = &vigs_winsys_resource_get_width; - ws_res->base.get_height = &vigs_winsys_resource_get_height; - ws_res->base.acquire_surface = &vigs_winsys_resource_acquire_surface; - - vigs_ref_init(&ws_res->ref, &vigs_winsys_resource_destroy); - - QLIST_INIT(&ws_res->callbacks); - - return ws_res; -} - -static void vigs_winsys_resource_assign(struct vigs_winsys_resource *ws_res, - struct winsys_surface *ws_sfc, - uint32_t width, - uint32_t height) -{ - struct vigs_winsys_resource_cb *vigs_cb; - - if (ws_res->ws_sfc == ws_sfc) { - return; - } - - if (ws_sfc) { - ws_sfc->acquire(ws_sfc); - } - - if (ws_res->ws_sfc) { - ws_res->ws_sfc->release(ws_res->ws_sfc); - } - - ws_res->ws_sfc = ws_sfc; - ws_res->width = width; - ws_res->height = height; - - QLIST_FOREACH(vigs_cb, &ws_res->callbacks, entry) { - vigs_cb->cb(&ws_res->base, vigs_cb->user_data); - } -} - -/* - * @} - */ - -/* - * vigs_resource - * @{ - */ - -struct vigs_resource - *vigs_resource_create(vigsp_resource_id id, - vigsp_resource_type type) -{ - struct vigs_resource *res; - - res = g_malloc0(sizeof(*res)); - - switch (type) { - case vigsp_resource_window: - res->ws_res = &vigs_winsys_resource_create(id, winsys_res_type_window)->base; - break; - case vigsp_resource_pixmap: - res->ws_res = &vigs_winsys_resource_create(id, winsys_res_type_pixmap)->base; - break; - default: - assert(false); - g_free(res); - return NULL; - } - - res->id = id; - res->type = type; - - return res; -} - -void vigs_resource_assign(struct vigs_resource *res, - struct vigs_surface *sfc, - uint32_t width, - uint32_t height) -{ - assert(sfc); - - if (res->sfc == sfc) { - return; - } - - if (res->sfc) { - if (!g_hash_table_remove(res->sfc->resource_ids, GUINT_TO_POINTER(res->id))) { - VIGS_LOG_CRITICAL("no resource id for 0x%X", res->id); - assert(false); - } - } - - g_hash_table_insert(sfc->resource_ids, GUINT_TO_POINTER(res->id), NULL); - - res->sfc = sfc; - vigs_winsys_resource_assign((struct vigs_winsys_resource*)res->ws_res, - sfc->ws_sfc, - width, - height); -} - -void vigs_resource_destroy(struct vigs_resource *res) -{ - struct vigs_winsys_resource *ws_res; - - if (res->sfc) { - if (!g_hash_table_remove(res->sfc->resource_ids, GUINT_TO_POINTER(res->id))) { - VIGS_LOG_CRITICAL("no resource id for 0x%X", res->id); - assert(false); - } - } - - ws_res = (struct vigs_winsys_resource*)res->ws_res; - - res->sfc = NULL; - vigs_winsys_resource_assign(ws_res, - NULL, - ws_res->width, - ws_res->height); - - res->ws_res->release(res->ws_res); - res->ws_res = NULL; - - g_free(res); -} - -/* - * @} - */ diff --git a/hw/vigs_resource.h b/hw/vigs_resource.h deleted file mode 100644 index 8090ea2..0000000 --- a/hw/vigs_resource.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _QEMU_VIGS_RESOURCE_H -#define _QEMU_VIGS_RESOURCE_H - -#include "vigs_types.h" - -struct winsys_resource; -struct vigs_surface; - -struct vigs_resource -{ - struct winsys_resource *ws_res; - - vigsp_resource_id id; - - vigsp_resource_type type; - - struct vigs_surface *sfc; -}; - -struct vigs_resource - *vigs_resource_create(vigsp_resource_id id, - vigsp_resource_type type); - -void vigs_resource_assign(struct vigs_resource *res, - struct vigs_surface *sfc, - uint32_t width, - uint32_t height); - -void vigs_resource_destroy(struct vigs_resource *res); - -#endif diff --git a/hw/vigs_server.c b/hw/vigs_server.c index 3893b7c..f06c43f 100644 --- a/hw/vigs_server.c +++ b/hw/vigs_server.c @@ -3,7 +3,6 @@ #include "vigs_comm.h" #include "vigs_backend.h" #include "vigs_surface.h" -#include "vigs_resource.h" #include "vigs_utils.h" #ifdef CONFIG_MARU #include "../tizen/src/hw/maru_brightness.h" @@ -16,93 +15,40 @@ static void vigs_server_surface_destroy_func(gpointer data) sfc->destroy(sfc); } -static void vigs_server_resource_destroy_func(gpointer data) -{ - struct vigs_resource *res = data; - - vigs_resource_destroy(res); -} - -static struct vigs_surface *vigs_server_get_surface(struct vigs_server *server, - const struct vigsp_surface *protocol_sfc) -{ - struct vigs_surface *sfc; - - sfc = g_hash_table_lookup(server->surfaces, GUINT_TO_POINTER(protocol_sfc->id)); - - if (sfc) { - if (protocol_sfc->vram_offset >= 0) { - sfc->update(sfc, - protocol_sfc->vram_offset, - server->vram_ptr + protocol_sfc->vram_offset); - } - - return sfc; - } - - VIGS_LOG_ERROR("surface %u not found", protocol_sfc->id); - - return NULL; -} - static void vigs_server_unuse_surface(struct vigs_server *server, struct vigs_surface *sfc) { - GHashTableIter iter; - gpointer key, value; - vigsp_resource_id *res_ids; - int i = 0; - - /* - * Remove all associated resources. - */ - - vigs_vector_resize(&server->v1, - (sizeof(*res_ids) * g_hash_table_size(sfc->resource_ids))); - - res_ids = vigs_vector_data(&server->v1); - - g_hash_table_iter_init(&iter, sfc->resource_ids); - while (g_hash_table_iter_next(&iter, &key, &value)) { - vigsp_resource_id id = GPOINTER_TO_UINT(key); - res_ids[i++] = id; - } - - while (i-- > 0) { - if (!g_hash_table_remove(server->resources, GUINT_TO_POINTER(res_ids[i]))) { - VIGS_LOG_CRITICAL("no resource for 0x%X", res_ids[i]); - assert(false); - } - } - - assert(g_hash_table_size(sfc->resource_ids) == 0); - /* * If it was root surface then root surface is now NULL. */ if (server->root_sfc == sfc) { server->root_sfc = NULL; + server->root_sfc_data = NULL; } } -static struct winsys_resource - *vigs_server_acquire_resource(struct winsys_interface *wsi, - winsys_id id) +static struct winsys_surface + *vigs_server_acquire_surface(struct winsys_interface *wsi, + winsys_id id) { struct vigs_server *server = container_of(wsi, struct vigs_server, wsi); - struct vigs_resource *res; + struct vigs_surface *res; - res = g_hash_table_lookup(server->resources, GUINT_TO_POINTER(id)); + res = g_hash_table_lookup(server->surfaces, GUINT_TO_POINTER(id)); if (!res) { return NULL; } - res->ws_res->acquire(res->ws_res); + res->ws_sfc->acquire(res->ws_sfc); + + return res->ws_sfc; +} - return res->ws_res; +static void vigs_server_dispatch_batch_start(void *user_data) +{ } static bool vigs_server_dispatch_init(void *user_data) @@ -119,7 +65,7 @@ static bool vigs_server_dispatch_init(void *user_data) return true; } -static bool vigs_server_dispatch_reset(void *user_data) +static void vigs_server_dispatch_reset(void *user_data) { struct vigs_server *server = user_data; GHashTableIter iter; @@ -127,7 +73,7 @@ static bool vigs_server_dispatch_reset(void *user_data) if (!server->initialized) { VIGS_LOG_ERROR("not initialized"); - return false; + return; } g_hash_table_iter_init(&iter, server->surfaces); @@ -139,69 +85,59 @@ static bool vigs_server_dispatch_reset(void *user_data) g_hash_table_iter_remove(&iter); } } - - return true; } -static bool vigs_server_dispatch_exit(void *user_data) +static void vigs_server_dispatch_exit(void *user_data) { struct vigs_server *server = user_data; if (!server->initialized) { VIGS_LOG_ERROR("not initialized"); - return false; + return; } vigs_server_reset(server); - - return true; } -static bool vigs_server_dispatch_create_surface(void *user_data, +static void vigs_server_dispatch_create_surface(void *user_data, uint32_t width, uint32_t height, uint32_t stride, vigsp_surface_format format, - vigsp_offset vram_offset, - vigsp_surface_id *id) + vigsp_surface_id id) { struct vigs_server *server = user_data; struct vigs_surface *sfc; if (!server->initialized) { VIGS_LOG_ERROR("not initialized"); - return false; + return; } sfc = server->backend->create_surface(server->backend, - width, - height, - stride, - format, - vram_offset, - ((vram_offset >= 0) ? server->vram_ptr + vram_offset : NULL)); + width, + height, + stride, + format, + id); if (!sfc) { - return false; + return; } if (g_hash_table_lookup(server->surfaces, GUINT_TO_POINTER(sfc->id))) { VIGS_LOG_CRITICAL("surface %u already exists", sfc->id); assert(false); sfc->destroy(sfc); - return false; + return; } g_hash_table_insert(server->surfaces, GUINT_TO_POINTER(sfc->id), sfc); - *id = sfc->id; - VIGS_LOG_TRACE("num_surfaces = %u", g_hash_table_size(server->surfaces)); - - return true; } -static bool vigs_server_dispatch_destroy_surface(void *user_data, +static void vigs_server_dispatch_destroy_surface(void *user_data, vigsp_surface_id id) { struct vigs_server *server = user_data; @@ -209,346 +145,189 @@ static bool vigs_server_dispatch_destroy_surface(void *user_data, if (!server->initialized) { VIGS_LOG_ERROR("not initialized"); - return false; + return; } sfc = g_hash_table_lookup(server->surfaces, GUINT_TO_POINTER(id)); - if (sfc) { - vigs_server_unuse_surface(server, sfc); - - g_hash_table_remove(server->surfaces, GUINT_TO_POINTER(id)); - - VIGS_LOG_TRACE("num_surfaces = %u", g_hash_table_size(server->surfaces)); - VIGS_LOG_TRACE("num_resources = %u", g_hash_table_size(server->resources)); - - return true; + if (!sfc) { + VIGS_LOG_ERROR("surface %u not found", id); + return; } - VIGS_LOG_ERROR("surface %u not found", id); + vigs_server_unuse_surface(server, sfc); - return false; + g_hash_table_remove(server->surfaces, GUINT_TO_POINTER(id)); + + VIGS_LOG_TRACE("num_surfaces = %u", g_hash_table_size(server->surfaces)); } -static bool vigs_server_dispatch_set_root_surface(void *user_data, - vigsp_surface_id id) +static void vigs_server_dispatch_set_root_surface(void *user_data, + vigsp_surface_id id, + vigsp_offset offset) { struct vigs_server *server = user_data; struct vigs_surface *sfc; if (!server->initialized) { VIGS_LOG_ERROR("not initialized"); - return false; + return; } if (id == 0) { server->root_sfc = NULL; + server->root_sfc_data = NULL; VIGS_LOG_TRACE("root surface reset"); - return true; + return; } sfc = g_hash_table_lookup(server->surfaces, GUINT_TO_POINTER(id)); - if (sfc) { - if (!sfc->data) { - VIGS_LOG_ERROR("surface %u has no data, cannot set it as root surface", id); - return false; - } - - server->root_sfc = sfc; - return true; - } - - VIGS_LOG_ERROR("surface %u not found", id); - - return false; -} - -static bool vigs_server_dispatch_copy(void *user_data, - const struct vigsp_surface *src, - const struct vigsp_surface *dst, - const struct vigsp_copy *entries, - uint32_t num_entries) -{ - struct vigs_server *server = user_data; - struct vigs_surface *vigs_src; - struct vigs_surface *vigs_dst; - - if (!server->initialized) { - VIGS_LOG_ERROR("not initialized"); - return false; - } - - vigs_src = vigs_server_get_surface(server, src); - - if (!vigs_src) { - return false; - } - - if (src->id == dst->id) { - vigs_dst = vigs_src; - } else { - vigs_dst = vigs_server_get_surface(server, dst); - - if (!vigs_dst) { - return false; - } + if (!sfc) { + VIGS_LOG_ERROR("surface %u not found", id); + return; } - vigs_dst->copy(vigs_dst, vigs_src, entries, num_entries); - - return true; + server->root_sfc = sfc; + server->root_sfc_data = server->vram_ptr + offset; } -static bool vigs_server_dispatch_solid_fill(void *user_data, - const struct vigsp_surface *sfc, - vigsp_color color, - const struct vigsp_rect *entries, - uint32_t num_entries) +static void vigs_server_dispatch_update_vram(void *user_data, + vigsp_surface_id sfc_id, + vigsp_offset offset, + const struct vigsp_rect *rect) { struct vigs_server *server = user_data; struct vigs_surface *vigs_sfc; if (!server->initialized) { VIGS_LOG_ERROR("not initialized"); - return false; + return; } - vigs_sfc = vigs_server_get_surface(server, sfc); + vigs_sfc = g_hash_table_lookup(server->surfaces, GUINT_TO_POINTER(sfc_id)); if (!vigs_sfc) { - return false; - } - - vigs_sfc->solid_fill(vigs_sfc, color, entries, num_entries); - - return true; -} - -static bool vigs_server_dispatch_update_vram(void *user_data, - const struct vigsp_surface *sfc) -{ - struct vigs_server *server = user_data; - struct vigs_surface *vigs_sfc; - - if (!server->initialized) { - VIGS_LOG_ERROR("not initialized"); - return false; - } - - vigs_sfc = g_hash_table_lookup(server->surfaces, GUINT_TO_POINTER(sfc->id)); - - if (vigs_sfc) { - assert(sfc->vram_offset >= 0); - vigs_sfc->set_data(vigs_sfc, - sfc->vram_offset, - server->vram_ptr + sfc->vram_offset); - - vigs_surface_update_vram(vigs_sfc); - - return true; + VIGS_LOG_ERROR("surface %u not found", sfc_id); + return; } - VIGS_LOG_ERROR("surface %u not found", sfc->id); - - return false; + vigs_sfc->read_pixels(vigs_sfc, + rect->pos.x, + rect->pos.y, + rect->size.w, + rect->size.h, + server->vram_ptr + offset); } -static bool vigs_server_dispatch_put_image(void *user_data, - const struct vigsp_surface *sfc, - target_ulong src_va, - uint32_t src_stride, - const struct vigsp_rect *rect, - bool *is_pf) +static void vigs_server_dispatch_update_gpu(void *user_data, + vigsp_surface_id sfc_id, + vigsp_offset offset, + const struct vigsp_rect *rect) { struct vigs_server *server = user_data; struct vigs_surface *vigs_sfc; - uint32_t size = src_stride * rect->size.h; - int ret; if (!server->initialized) { VIGS_LOG_ERROR("not initialized"); - return false; - } - - vigs_vector_resize(&server->v1, size); - - ret = cpu_memory_rw_debug(cpu_single_env, - src_va, - vigs_vector_data(&server->v1), - size, - 0); - - if (ret == -1) { - VIGS_LOG_WARN("page fault at 0x%X:%u", (uint32_t)src_va, size); - *is_pf = true; - return true; + return; } - vigs_sfc = vigs_server_get_surface(server, sfc); + vigs_sfc = g_hash_table_lookup(server->surfaces, GUINT_TO_POINTER(sfc_id)); if (!vigs_sfc) { - return false; + VIGS_LOG_ERROR("surface %u not found", sfc_id); + return; } - vigs_sfc->put_image(vigs_sfc, - vigs_vector_data(&server->v1), - src_stride, - rect); - - *is_pf = false; - - return true; + vigs_sfc->draw_pixels(vigs_sfc, + rect->pos.x, + rect->pos.y, + rect->size.w, + rect->size.h, + server->vram_ptr + offset); } -static bool vigs_server_dispatch_get_image(void *user_data, - vigsp_surface_id sfc_id, - target_ulong dst_va, - uint32_t dst_stride, - const struct vigsp_rect *rect, - bool *is_pf) +static void vigs_server_dispatch_copy(void *user_data, + vigsp_surface_id src_id, + vigsp_surface_id dst_id, + const struct vigsp_copy *entries, + uint32_t num_entries) { struct vigs_server *server = user_data; - struct vigs_surface *vigs_sfc; - uint32_t size = dst_stride * rect->size.h; - int ret; + struct vigs_surface *src; + struct vigs_surface *dst; if (!server->initialized) { VIGS_LOG_ERROR("not initialized"); - return false; + return; } - vigs_vector_resize(&server->v1, size); - - vigs_sfc = g_hash_table_lookup(server->surfaces, GUINT_TO_POINTER(sfc_id)); + src = g_hash_table_lookup(server->surfaces, GUINT_TO_POINTER(src_id)); - if (!vigs_sfc) { - VIGS_LOG_ERROR("surface %u not found", sfc_id); - return false; + if (!src) { + VIGS_LOG_ERROR("src surface %u not found", src_id); + return; } - vigs_sfc->read_pixels(vigs_sfc, rect->pos.x, rect->pos.y, - rect->size.w, rect->size.h, dst_stride, - vigs_vector_data(&server->v1)); - - ret = cpu_memory_rw_debug(cpu_single_env, - dst_va, - vigs_vector_data(&server->v1), - size, - 1); + if (src_id == dst_id) { + dst = src; + } else { + dst = g_hash_table_lookup(server->surfaces, GUINT_TO_POINTER(dst_id)); - if (ret == -1) { - VIGS_LOG_WARN("page fault at 0x%X:%u", (uint32_t)dst_va, size); - *is_pf = true; - return true; + if (!dst) { + VIGS_LOG_ERROR("dst surface %u not found", dst_id); + return; + } } - *is_pf = false; - - return true; + dst->copy(dst, src, entries, num_entries); } -static bool vigs_server_dispatch_assign_resource(void *user_data, - vigsp_resource_id res_id, - vigsp_resource_type res_type, - vigsp_surface_id sfc_id, - uint32_t width, - uint32_t height) +static void vigs_server_dispatch_solid_fill(void *user_data, + vigsp_surface_id sfc_id, + vigsp_color color, + const struct vigsp_rect *entries, + uint32_t num_entries) { struct vigs_server *server = user_data; - struct vigs_resource *res; struct vigs_surface *sfc; if (!server->initialized) { VIGS_LOG_ERROR("not initialized"); - return false; + return; } sfc = g_hash_table_lookup(server->surfaces, GUINT_TO_POINTER(sfc_id)); if (!sfc) { VIGS_LOG_ERROR("surface %u not found", sfc_id); - return false; - } - - res = g_hash_table_lookup(server->resources, GUINT_TO_POINTER(res_id)); - - if (res) { - /* - * Update resource. - */ - - if (res->type != res_type) { - VIGS_LOG_ERROR("resource type mismatch"); - return false; - } - - if (res->type != vigsp_resource_window) { - VIGS_LOG_ERROR("cannot reassign resource other than window"); - return false; - } - } else { - /* - * Create resource. - */ - - res = vigs_resource_create(res_id, res_type); - assert(res); - - if (!res) { - VIGS_LOG_CRITICAL("cannot create resource"); - return false; - } - - g_hash_table_insert(server->resources, GUINT_TO_POINTER(res_id), res); - - VIGS_LOG_TRACE("num_resources = %u", g_hash_table_size(server->resources)); + return; } - vigs_resource_assign(res, sfc, width, height); - - return true; + sfc->solid_fill(sfc, color, entries, num_entries); } -static bool vigs_server_dispatch_destroy_resource(void *user_data, - vigsp_resource_id res_id) +static void vigs_server_dispatch_batch_end(void *user_data) { - struct vigs_server *server = user_data; - - if (!server->initialized) { - VIGS_LOG_ERROR("not initialized"); - return false; - } - - if (!g_hash_table_remove(server->resources, GUINT_TO_POINTER(res_id))) { - /* - * This can happen with old X.Org servers, this is normal. - */ - VIGS_LOG_WARN("resource 0x%X not found", res_id); - } - - VIGS_LOG_TRACE("num_resources = %u", g_hash_table_size(server->resources)); - - return true; } static struct vigs_comm_ops vigs_server_dispatch_ops = { + .batch_start = &vigs_server_dispatch_batch_start, .init = &vigs_server_dispatch_init, .reset = &vigs_server_dispatch_reset, .exit = &vigs_server_dispatch_exit, .create_surface = &vigs_server_dispatch_create_surface, .destroy_surface = &vigs_server_dispatch_destroy_surface, .set_root_surface = &vigs_server_dispatch_set_root_surface, + .update_vram = &vigs_server_dispatch_update_vram, + .update_gpu = &vigs_server_dispatch_update_gpu, .copy = &vigs_server_dispatch_copy, .solid_fill = &vigs_server_dispatch_solid_fill, - .update_vram = &vigs_server_dispatch_update_vram, - .put_image = &vigs_server_dispatch_put_image, - .get_image = &vigs_server_dispatch_get_image, - .assign_resource = &vigs_server_dispatch_assign_resource, - .destroy_resource = &vigs_server_dispatch_destroy_resource, + .batch_end = &vigs_server_dispatch_batch_end }; struct vigs_server *vigs_server_create(uint8_t *vram_ptr, @@ -562,7 +341,7 @@ struct vigs_server *vigs_server_create(uint8_t *vram_ptr, server = g_malloc0(sizeof(*server)); server->wsi.ws_info = backend->ws_info; - server->wsi.acquire_resource = &vigs_server_acquire_resource; + server->wsi.acquire_surface = &vigs_server_acquire_surface; server->vram_ptr = vram_ptr; server->display_ops = display_ops; @@ -582,11 +361,6 @@ struct vigs_server *vigs_server_create(uint8_t *vram_ptr, NULL, vigs_server_surface_destroy_func); - server->resources = g_hash_table_new_full(g_direct_hash, - g_direct_equal, - NULL, - vigs_server_resource_destroy_func); - vigs_vector_init(&server->v1, 0); return server; @@ -602,7 +376,6 @@ void vigs_server_destroy(struct vigs_server *server) vigs_server_reset(server); g_hash_table_destroy(server->surfaces); - g_hash_table_destroy(server->resources); vigs_comm_destroy(server->comm); vigs_vector_cleanup(&server->v1); server->backend->destroy(server->backend); @@ -623,12 +396,8 @@ void vigs_server_reset(struct vigs_server *server) g_hash_table_iter_remove(&iter); } - /* - * There can be no resources without surfaces. - */ - assert(g_hash_table_size(server->resources) == 0); - server->root_sfc = NULL; + server->root_sfc_data = NULL; server->initialized = false; } @@ -645,20 +414,28 @@ void vigs_server_update_display(struct vigs_server *server) uint32_t sfc_bpp; uint32_t display_stride, display_bpp; uint8_t *display_data; - uint8_t *sfc_data; + uint8_t *sfc_data = server->root_sfc_data; uint32_t i, j; if (!root_sfc) { return; } - vigs_surface_update_vram(root_sfc); + if (root_sfc->is_dirty) { + root_sfc->read_pixels(root_sfc, + 0, + 0, + root_sfc->ws_sfc->width, + root_sfc->ws_sfc->height, + sfc_data); + root_sfc->is_dirty = false; + } sfc_bpp = vigs_format_bpp(root_sfc->format); server->display_ops->resize(server->display_user_data, - root_sfc->width, - root_sfc->height); + root_sfc->ws_sfc->width, + root_sfc->ws_sfc->height); display_stride = server->display_ops->get_stride(server->display_user_data); display_bpp = server->display_ops->get_bpp(server->display_user_data); @@ -670,9 +447,7 @@ void vigs_server_update_display(struct vigs_server *server) exit(1); } - sfc_data = root_sfc->data; - - for (i = 0; i < root_sfc->height; ++i) { + for (i = 0; i < root_sfc->ws_sfc->height; ++i) { uint8_t *src = sfc_data; uint8_t *dst = display_data; @@ -682,7 +457,7 @@ void vigs_server_update_display(struct vigs_server *server) #ifdef CONFIG_MARU if (brightness_level < BRIGHTNESS_MAX) { uint32_t level = brightness_tbl[brightness_level]; - for (j = 0; j < root_sfc->width; ++j) { + for (j = 0; j < root_sfc->ws_sfc->width; ++j) { *dst++ = ((uint32_t)(*src++) * level) >> 8; *dst++ = ((uint32_t)(*src++) * level) >> 8; *dst++ = ((uint32_t)(*src++) * level) >> 8; @@ -690,7 +465,7 @@ void vigs_server_update_display(struct vigs_server *server) } } else { #endif - memcpy(dst, src, root_sfc->width * 4); + memcpy(dst, src, root_sfc->ws_sfc->width * 4); #ifdef CONFIG_MARU } #endif diff --git a/hw/vigs_server.h b/hw/vigs_server.h index 8d0d4da..e34b0ba 100644 --- a/hw/vigs_server.h +++ b/hw/vigs_server.h @@ -58,8 +58,7 @@ struct vigs_server GHashTable *surfaces; struct vigs_surface *root_sfc; - - GHashTable *resources; + uint8_t *root_sfc_data; /* * General purpose vectors. diff --git a/hw/vigs_surface.c b/hw/vigs_surface.c index 51c6b9d..73e6fe5 100644 --- a/hw/vigs_surface.c +++ b/hw/vigs_surface.c @@ -4,38 +4,19 @@ void vigs_surface_init(struct vigs_surface *sfc, struct winsys_surface *ws_sfc, struct vigs_backend *backend, - vigsp_surface_id id, uint32_t stride, vigsp_surface_format format, - vigsp_offset vram_offset, - uint8_t *data) + vigsp_surface_id id) { ws_sfc->acquire(ws_sfc); sfc->ws_sfc = ws_sfc; sfc->backend = backend; - sfc->id = id; - sfc->width = ws_sfc->width; - sfc->height = ws_sfc->height; sfc->stride = stride; sfc->format = format; - sfc->vram_offset = vram_offset; - sfc->data = data; - sfc->resource_ids = g_hash_table_new(g_direct_hash, g_direct_equal); + sfc->id = id; } void vigs_surface_cleanup(struct vigs_surface *sfc) { sfc->ws_sfc->release(sfc->ws_sfc); - g_hash_table_destroy(sfc->resource_ids); -} - -void vigs_surface_update_vram(struct vigs_surface *sfc) -{ - assert(sfc->data); - if (sfc->is_dirty) { - sfc->read_pixels(sfc, 0, 0, - sfc->width, sfc->height, - sfc->stride, sfc->data); - sfc->is_dirty = false; - } } diff --git a/hw/vigs_surface.h b/hw/vigs_surface.h index 127d30b..866eeea 100644 --- a/hw/vigs_surface.h +++ b/hw/vigs_surface.h @@ -2,7 +2,6 @@ #define _QEMU_VIGS_SURFACE_H #include "vigs_types.h" -#include struct winsys_surface; struct vigs_backend; @@ -13,38 +12,24 @@ struct vigs_surface struct vigs_backend *backend; - vigsp_surface_id id; - - GHashTable *resource_ids; - - uint32_t width; - uint32_t height; uint32_t stride; vigsp_surface_format format; - - /* - * From protocol. - */ - vigsp_offset vram_offset; - - uint8_t *data; + vigsp_surface_id id; bool is_dirty; - void (*update)(struct vigs_surface */*sfc*/, - vigsp_offset /*vram_offset*/, - uint8_t */*data*/); - - void (*set_data)(struct vigs_surface */*sfc*/, - vigsp_offset /*vram_offset*/, - uint8_t */*data*/); - void (*read_pixels)(struct vigs_surface */*sfc*/, uint32_t /*x*/, uint32_t /*y*/, uint32_t /*width*/, uint32_t /*height*/, - uint32_t /*stride*/, + uint8_t */*pixels*/); + + void (*draw_pixels)(struct vigs_surface */*sfc*/, + uint32_t /*x*/, + uint32_t /*y*/, + uint32_t /*width*/, + uint32_t /*height*/, uint8_t */*pixels*/); void (*copy)(struct vigs_surface */*dst*/, @@ -57,25 +42,16 @@ struct vigs_surface const struct vigsp_rect */*entries*/, uint32_t /*num_entries*/); - void (*put_image)(struct vigs_surface */*sfc*/, - const void */*src*/, - uint32_t /*src_stride*/, - const struct vigsp_rect */*rect*/); - void (*destroy)(struct vigs_surface */*sfc*/); }; void vigs_surface_init(struct vigs_surface *sfc, struct winsys_surface *ws_sfc, struct vigs_backend *backend, - vigsp_surface_id id, uint32_t stride, vigsp_surface_format format, - vigsp_offset vram_offset, - uint8_t *data); + vigsp_surface_id id); void vigs_surface_cleanup(struct vigs_surface *sfc); -void vigs_surface_update_vram(struct vigs_surface *sfc); - #endif diff --git a/hw/winsys.h b/hw/winsys.h index 4b7e7de..ceac67f 100644 --- a/hw/winsys.h +++ b/hw/winsys.h @@ -5,12 +5,6 @@ typedef uint32_t winsys_id; -typedef enum -{ - winsys_res_type_window = 0, - winsys_res_type_pixmap = 1, -} winsys_res_type; - struct winsys_surface { uint32_t width; @@ -20,33 +14,6 @@ struct winsys_surface void (*release)(struct winsys_surface */*sfc*/); }; -struct winsys_resource; - -typedef void (*winsys_resource_cb)(struct winsys_resource */*res*/, - void */*user_data*/); - -struct winsys_resource -{ - winsys_id id; - - winsys_res_type type; - - void (*acquire)(struct winsys_resource */*res*/); - void (*release)(struct winsys_resource */*res*/); - - void *(*add_callback)(struct winsys_resource */*res*/, - winsys_resource_cb /*cb*/, - void */*user_data*/); - - void (*remove_callback)(struct winsys_resource */*res*/, - void */*cookie*/); - - uint32_t (*get_width)(struct winsys_resource */*res*/); - uint32_t (*get_height)(struct winsys_resource */*res*/); - - struct winsys_surface *(*acquire_surface)(struct winsys_resource */*res*/); -}; - struct winsys_info { }; @@ -56,10 +23,10 @@ struct winsys_interface struct winsys_info *ws_info; /* - * Acquires resource corresponding to winsys id. NULL if no such resource. + * Acquires surface corresponding to winsys id. NULL if no such surface. */ - struct winsys_resource *(*acquire_resource)(struct winsys_interface */*wsi*/, - winsys_id /*id*/); + struct winsys_surface *(*acquire_surface)(struct winsys_interface */*wsi*/, + winsys_id /*id*/); }; #endif diff --git a/hw/winsys_gl.h b/hw/winsys_gl.h index 818cc8a..9174611 100644 --- a/hw/winsys_gl.h +++ b/hw/winsys_gl.h @@ -9,13 +9,6 @@ struct winsys_gl_surface GLuint (*get_front_texture)(struct winsys_gl_surface */*sfc*/); GLuint (*get_back_texture)(struct winsys_gl_surface */*sfc*/); - - void (*swap_buffers)(struct winsys_gl_surface */*sfc*/); - - void (*copy_buffers)(uint32_t /*width*/, - uint32_t /*height*/, - struct winsys_gl_surface */*target*/, - bool /*is_loop*/); }; struct winsys_gl_info diff --git a/hw/yagl_device.c b/hw/yagl_device.c index 8aeacf5..7ab4cfc 100644 --- a/hw/yagl_device.c +++ b/hw/yagl_device.c @@ -256,11 +256,15 @@ static int yagl_device_init(PCIDevice *dev) } if (s->wsi) { + /* + * TODO: uncomment. + */ + /* egl_backend = yagl_egl_onscreen_create(s->wsi, egl_driver, &gles2_driver->base); gles1_driver = yagl_gles1_onscreen_create(gles1_driver); - gles2_driver = yagl_gles2_onscreen_create(gles2_driver); + gles2_driver = yagl_gles2_onscreen_create(gles2_driver);*/ } else { egl_backend = yagl_egl_offscreen_create(egl_driver); } -- 2.7.4