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
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
# 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
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
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*/);
};
}
}
-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:
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);
}
/*
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,
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);
}
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
#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
{
MemoryRegion io_bar;
struct vigs_server *server;
- struct vigs_user users[VIGS_MAX_USERS];
/*
* Our display.
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 =
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);
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) {
memory_region_destroy(&s->ram_bar);
memory_region_destroy(&s->vram_bar);
- vigs_id_gen_cleanup();
-
vigs_log_cleanup();
return -1;
vigs_server_reset(s->server);
- vigs_id_gen_reset();
-
VIGS_LOG_INFO("VIGS reset");
}
memory_region_destroy(&s->ram_bar);
memory_region_destroy(&s->vram_bar);
- vigs_id_gen_cleanup();
-
VIGS_LOG_INFO("VIGS deinitialized");
vigs_log_cleanup();
#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"
* 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
{
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;
- }
-}
-
/*
* @}
*/
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 =
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;
* @{
*/
-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;
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;
}
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);
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,
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);
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;
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);
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;
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);
}
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;
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;
* @{
*/
- /*
- * 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 &&
} else {
VIGS_LOG_WARN("ARB_sync not supported!");
}*/
- gl_backend->has_arb_sync = false;
/*
* @}
*/
/*
- * 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.
* @{
*/
/*
* @}
*/
-
- bool has_arb_sync;
};
bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend);
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;
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);
+++ /dev/null
-#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++;
-}
+++ /dev/null
-#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
#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;
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
{
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
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;
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
/*
* 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.
*
* @{
*/
vigsp_u32 height;
vigsp_u32 stride;
vigsp_surface_format format;
- vigsp_offset vram_offset;
-};
-
-struct vigsp_cmd_create_surface_response
-{
vigsp_surface_id id;
};
* 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.
*
* @{
* 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.
*
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;
};
/*
/*
* 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];
};
/*
*/
/*
- * 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];
};
/*
+++ /dev/null
-#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);
-}
-
-/*
- * @}
- */
+++ /dev/null
-#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
#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"
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)
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;
if (!server->initialized) {
VIGS_LOG_ERROR("not initialized");
- return false;
+ return;
}
g_hash_table_iter_init(&iter, server->surfaces);
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;
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,
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;
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;
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);
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;
}
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);
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;
#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;
}
} else {
#endif
- memcpy(dst, src, root_sfc->width * 4);
+ memcpy(dst, src, root_sfc->ws_sfc->width * 4);
#ifdef CONFIG_MARU
}
#endif
GHashTable *surfaces;
struct vigs_surface *root_sfc;
-
- GHashTable *resources;
+ uint8_t *root_sfc_data;
/*
* General purpose vectors.
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;
- }
}
#define _QEMU_VIGS_SURFACE_H
#include "vigs_types.h"
-#include <glib.h>
struct winsys_surface;
struct vigs_backend;
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*/,
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
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;
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
{
};
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
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
}
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);
}