From 693a01229d1ce1f72387cb16d0f7a6d9a8ae2d7b Mon Sep 17 00:00:00 2001 From: Stanislav Vorobiov Date: Mon, 23 Jun 2014 11:47:32 +0400 Subject: [PATCH] YaGL/VIGS: QOM'ify YaGL and VIGS devices can now be created entirely from QEMU command line, it's also possible to tweak all their parameters via QEMU command line and even have 2 or more separate instances Change-Id: Ic1ae18f9ac6078f872d28519443e17974abefe82 Signed-off-by: Stanislav Vorobiov --- hw/vigs/Makefile.objs | 2 + hw/vigs/display.c | 131 +++++++++++++++++++++++++++++++++++++++ hw/vigs/display.h | 20 ++++++ hw/vigs/vigs_device.c | 166 ++++++++++++++++++++++++++++++-------------------- hw/vigs/vigs_device.h | 45 -------------- hw/vigs/winsys.c | 29 +++++++++ hw/vigs/winsys.h | 13 ++++ hw/vigs/work_queue.c | 113 ++++++++++++++++++++++++++++++++++ hw/vigs/work_queue.h | 14 +++++ hw/yagl/yagl_device.c | 122 +++++++++++++++++++++++-------------- vl.c | 14 +++-- 11 files changed, 508 insertions(+), 161 deletions(-) create mode 100644 hw/vigs/display.c create mode 100644 hw/vigs/display.h delete mode 100644 hw/vigs/vigs_device.h create mode 100644 hw/vigs/winsys.c diff --git a/hw/vigs/Makefile.objs b/hw/vigs/Makefile.objs index ab8ef51..92bb3df 100644 --- a/hw/vigs/Makefile.objs +++ b/hw/vigs/Makefile.objs @@ -15,6 +15,8 @@ obj-y += vigs_gl_pool.o obj-y += vigs_gl_backend.o obj-y += vigs_sw_backend.o obj-y += work_queue.o +obj-y += winsys.o +obj-y += display.o # GL GLX backend ifdef CONFIG_LINUX obj-y += vigs_gl_backend_glx.o diff --git a/hw/vigs/display.c b/hw/vigs/display.c new file mode 100644 index 0000000..961e7aa --- /dev/null +++ b/hw/vigs/display.c @@ -0,0 +1,131 @@ +#include "display.h" +#include "qom/object_interfaces.h" +#if defined(CONFIG_LINUX) +#include + +static int x_error_handler(Display *dpy, XErrorEvent *e) +{ + return 0; +} +#endif + +static void displayobject_instance_finalize(Object *obj) +{ + DisplayObject *dobj = DISPLAYOBJECT(obj); + + dobj->dpy = NULL; +} + +static void displayobject_complete(UserCreatable *obj, Error **errp) +{ + DisplayObject *dobj = DISPLAYOBJECT(obj); + +#if defined(CONFIG_LINUX) + XSetErrorHandler(x_error_handler); + XInitThreads(); + + dobj->dpy = XOpenDisplay(0); + + if (!dobj->dpy) { + error_setg(errp, "Cannot open X display"); + } +#else + dobj->dpy = NULL; +#endif +} + +static void displayobject_class_init(ObjectClass *klass, void *class_data) +{ + UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass); + ucc->complete = displayobject_complete; +} + +static const TypeInfo displayobject_info = { + .name = TYPE_DISPLAYOBJECT, + .parent = TYPE_OBJECT, + .class_init = displayobject_class_init, + .instance_size = sizeof(DisplayObject), + .instance_finalize = displayobject_instance_finalize, + .interfaces = (InterfaceInfo[]) { + {TYPE_USER_CREATABLE}, + {} + }, +}; + +static void displayobject_register_types(void) +{ + type_register_static(&displayobject_info); +} + +type_init(displayobject_register_types) + +struct query_object_arg +{ + DisplayObject *dobj; + bool ambiguous; +}; + +static int query_object(Object *object, void *opaque) +{ + struct query_object_arg *arg = opaque; + DisplayObject *dobj; + + dobj = (DisplayObject*)object_dynamic_cast(object, TYPE_DISPLAYOBJECT); + + if (dobj) { + if (arg->dobj) { + arg->ambiguous = true; + } + arg->dobj = dobj; + } + + return 0; +} + +DisplayObject *displayobject_create(bool *ambiguous) +{ + Object *container = container_get(object_get_root(), "/objects"); + struct query_object_arg arg = { NULL, false }; + + object_child_foreach(container, query_object, &arg); + + *ambiguous = arg.ambiguous; + + if (!arg.dobj) { + Error *err = NULL; + + arg.dobj = DISPLAYOBJECT(object_new(TYPE_DISPLAYOBJECT)); + + user_creatable_complete(&arg.dobj->base, &err); + + if (err) { + error_free(err); + return NULL; + } + + object_property_add_child(container, "dpy0", &arg.dobj->base, &err); + + object_unref(&arg.dobj->base); + + if (err) { + error_free(err); + return NULL; + } + } + + return arg.dobj; +} + +DisplayObject *displayobject_find(const char *id) +{ + Object *container = container_get(object_get_root(), "/objects"); + Object *child; + + child = object_property_get_link(container, id, NULL); + + if (!child) { + return NULL; + } + + return (DisplayObject*)object_dynamic_cast(child, TYPE_DISPLAYOBJECT); +} diff --git a/hw/vigs/display.h b/hw/vigs/display.h new file mode 100644 index 0000000..710e988 --- /dev/null +++ b/hw/vigs/display.h @@ -0,0 +1,20 @@ +#ifndef _QEMU_DISPLAY_H +#define _QEMU_DISPLAY_H + +#include "qemu-common.h" + +#define TYPE_DISPLAYOBJECT "display" + +typedef struct { + Object base; + void *dpy; +} DisplayObject; + +#define DISPLAYOBJECT(obj) \ + OBJECT_CHECK(DisplayObject, obj, TYPE_DISPLAYOBJECT) + +DisplayObject *displayobject_create(bool *ambiguous); + +DisplayObject *displayobject_find(const char *id); + +#endif diff --git a/hw/vigs/vigs_device.c b/hw/vigs/vigs_device.c index 442768a..464bd10 100644 --- a/hw/vigs/vigs_device.c +++ b/hw/vigs/vigs_device.c @@ -27,21 +27,19 @@ * */ -#include "vigs_device.h" #include "vigs_log.h" #include "vigs_server.h" #include "vigs_backend.h" #include "vigs_regs.h" #include "vigs_fenceman.h" +#include "display.h" #include "work_queue.h" +#include "winsys.h" #include "hw/hw.h" +#include "hw/pci/pci.h" #include "ui/console.h" #include "qemu/main-loop.h" -#ifdef __linux__ -#include -#endif - #define PCI_VENDOR_ID_VIGS 0x19B2 #define PCI_DEVICE_ID_VIGS 0x1011 @@ -53,19 +51,14 @@ #define VIGS_EXTRA_INVALIDATION (0) #endif -#ifdef __linux__ -Display *vigs_display = NULL; -#else -void *vigs_display = NULL; -#endif - -struct work_queue *vigs_render_queue = NULL; -struct winsys_interface *vigs_wsi = NULL; - typedef struct VIGSState { - VIGSDevice dev; + PCIDevice dev; + char *display; + char *render_queue; + char *backend; + char *wsi; MemoryRegion vram_bar; uint32_t vram_size; @@ -80,8 +73,6 @@ typedef struct VIGSState struct vigs_server *server; - char *backend; - /* * Our console. */ @@ -94,8 +85,6 @@ typedef struct VIGSState #define TYPE_VIGS_DEVICE "vigs" -extern const char *vigs_backend; - static void vigs_update_irq(VIGSState *s) { bool raise = false; @@ -110,9 +99,9 @@ static void vigs_update_irq(VIGSState *s) } if (raise) { - pci_set_irq(&s->dev.pci_dev, 1); + pci_set_irq(&s->dev, 1); } else { - pci_set_irq(&s->dev.pci_dev, 0); + pci_set_irq(&s->dev, 0); } } @@ -299,35 +288,85 @@ static struct vigs_display_ops vigs_dpy_ops = .fence_ack = vigs_fence_ack, }; -#ifdef __linux__ -static int x_error_handler(Display *dpy, XErrorEvent *e) +static int vigs_device_init(PCIDevice *dev) { - return 0; -} + VIGSState *s = DO_UPCAST(VIGSState, dev, dev); + DisplayObject *dobj = NULL; + WorkQueueObject *wqobj = NULL; + WSIObject *wsiobj = NULL; + struct vigs_backend *backend = NULL; -static Display *get_display(void) -{ - XSetErrorHandler(x_error_handler); - XInitThreads(); + if (s->display) { + dobj = displayobject_find(s->display); + + if (!dobj) { + error_report("display '%s' not found", s->display); + return -1; + } + } else { + bool ambiguous; - Display *display = XOpenDisplay(0); + dobj = displayobject_create(&ambiguous); - if (!display) { - fprintf(stderr, "Cannot open X display\n"); - exit(1); + if (ambiguous) { + error_report("ambiguous display, set 'display' property"); + return -1; + } + + if (!dobj) { + error_report("unable to create display"); + return -1; + } } - return display; -} -#endif + if (s->render_queue) { + wqobj = workqueueobject_find(s->render_queue); -static int vigs_device_init(PCIDevice *dev) -{ - VIGSState *s = DO_UPCAST(VIGSState, dev.pci_dev, dev); - struct vigs_backend *backend = NULL; + if (!wqobj) { + error_report("work queue '%s' not found", s->render_queue); + return -1; + } + } else { + bool ambiguous; + + wqobj = workqueueobject_create(&ambiguous); + + if (ambiguous) { + error_report("ambiguous work queue, set 'render_queue' property"); + return -1; + } + + if (!dobj) { + error_report("unable to create work queue"); + return -1; + } + } + + if (!s->backend) { + error_report("'backend' property not set"); + return -1; + } + + if (strcmp(s->backend, "gl") && strcmp(s->backend, "sw")) { + error_report("backend '%s' not found", s->backend); + return -1; + } + + if (s->wsi) { + Error *err = NULL; - if (!vigs_render_queue) { - vigs_render_queue = work_queue_create("render_queue"); + wsiobj = WSIOBJECT(object_new(TYPE_WSIOBJECT)); + + object_property_add_child(container_get(object_get_root(), "/objects"), + s->wsi, &wsiobj->base, &err); + + object_unref(&wsiobj->base); + + if (err) { + qerror_report_err(err); + error_free(err); + return -1; + } } vigs_log_init(); @@ -358,27 +397,14 @@ static int vigs_device_init(PCIDevice *dev) TYPE_VIGS_DEVICE ".io", VIGS_IO_SIZE); - 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); + pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->vram_bar); + pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ram_bar); + pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->io_bar); - if (!s->backend) { - VIGS_LOG_INFO("No backend is specified, defaulting to \"sw\""); - // choose "sw" backend as default. - backend = vigs_sw_backend_create(); - } else if (!strcmp(s->backend, "gl")) { - VIGS_LOG_INFO("vigs uses \"gl\" backend"); -#ifdef __linux__ - if (!vigs_display) { - vigs_display = get_display(); - } -#endif - backend = vigs_gl_backend_create(vigs_display); + if (!strcmp(s->backend, "gl")) { + backend = vigs_gl_backend_create(dobj->dpy); } else if (!strcmp(s->backend, "sw")) { - VIGS_LOG_INFO("vigs uses \"sw\" backend"); backend = vigs_sw_backend_create(); - } else { - VIGS_LOG_CRITICAL("Unknown backend=\"%s\" is specified", s->backend); } if (!backend) { @@ -400,13 +426,18 @@ static int vigs_device_init(PCIDevice *dev) &vigs_dpy_ops, s, backend, - vigs_render_queue); + wqobj->wq); if (!s->server) { goto fail; } - vigs_wsi = s->dev.wsi = &s->server->wsi; + if (wsiobj) { + wsiobj->wsi = &s->server->wsi; + if (!strcmp(s->backend, "gl")) { + wsiobj->gl_wsi = &s->server->wsi; + } + } VIGS_LOG_INFO("VIGS initialized"); @@ -439,13 +470,13 @@ fail: static void vigs_device_reset(DeviceState *d) { - VIGSState *s = container_of(d, VIGSState, dev.pci_dev.qdev); + VIGSState *s = container_of(d, VIGSState, dev.qdev); vigs_server_reset(s->server); vigs_fenceman_reset(s->fenceman); - pci_set_irq(&s->dev.pci_dev, 0); + pci_set_irq(&s->dev, 0); s->reg_con = 0; s->reg_int = 0; @@ -455,7 +486,7 @@ static void vigs_device_reset(DeviceState *d) static void vigs_device_exit(PCIDevice *dev) { - VIGSState *s = DO_UPCAST(VIGSState, dev.pci_dev, dev); + VIGSState *s = DO_UPCAST(VIGSState, dev, dev); vigs_server_destroy(s->server); @@ -473,11 +504,14 @@ static void vigs_device_exit(PCIDevice *dev) } static Property vigs_properties[] = { + DEFINE_PROP_STRING("display", VIGSState, display), + DEFINE_PROP_STRING("render_queue", VIGSState, render_queue), + DEFINE_PROP_STRING("backend", VIGSState, backend), + DEFINE_PROP_STRING("wsi", VIGSState, wsi), DEFINE_PROP_UINT32("vram_size", VIGSState, vram_size, 32 * 1024 * 1024), DEFINE_PROP_UINT32("ram_size", VIGSState, ram_size, 1 * 1024 * 1024), - DEFINE_PROP_STRING("backend", VIGSState, backend), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/vigs/vigs_device.h b/hw/vigs/vigs_device.h deleted file mode 100644 index c40cb39..0000000 --- a/hw/vigs/vigs_device.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * vigs - * - * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: - * Stanislav Vorobiov - * Jinhyung Jo - * YeongKyoon Lee - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Contributors: - * - S-Core Co., Ltd - * - */ - -#ifndef _QEMU_VIGS_DEVICE_H -#define _QEMU_VIGS_DEVICE_H - -#include "qemu-common.h" -#include "hw/pci/pci.h" - -struct winsys_interface; - -typedef struct VIGSDevice -{ - PCIDevice pci_dev; - - struct winsys_interface *wsi; -} VIGSDevice; - -#endif diff --git a/hw/vigs/winsys.c b/hw/vigs/winsys.c new file mode 100644 index 0000000..f486868 --- /dev/null +++ b/hw/vigs/winsys.c @@ -0,0 +1,29 @@ +#include "winsys.h" +#include "qom/object_interfaces.h" + +static const TypeInfo wsiobject_info = { + .name = TYPE_WSIOBJECT, + .parent = TYPE_OBJECT, + .instance_size = sizeof(WSIObject) +}; + +static void wsiobject_register_types(void) +{ + type_register_static(&wsiobject_info); +} + +type_init(wsiobject_register_types) + +WSIObject *wsiobject_find(const char *id) +{ + Object *container = container_get(object_get_root(), "/objects"); + Object *child; + + child = object_property_get_link(container, id, NULL); + + if (!child) { + return NULL; + } + + return (WSIObject*)object_dynamic_cast(child, TYPE_WSIOBJECT); +} diff --git a/hw/vigs/winsys.h b/hw/vigs/winsys.h index 95bdea0..c480e07 100644 --- a/hw/vigs/winsys.h +++ b/hw/vigs/winsys.h @@ -36,4 +36,17 @@ struct winsys_interface uint32_t /*fence_seq*/); }; +#define TYPE_WSIOBJECT "wsi" + +typedef struct { + Object base; + struct winsys_interface *wsi; + struct winsys_interface *gl_wsi; +} WSIObject; + +#define WSIOBJECT(obj) \ + OBJECT_CHECK(WSIObject, obj, TYPE_WSIOBJECT) + +WSIObject *wsiobject_find(const char *id); + #endif diff --git a/hw/vigs/work_queue.c b/hw/vigs/work_queue.c index 1bc53fa..7eaf778 100644 --- a/hw/vigs/work_queue.c +++ b/hw/vigs/work_queue.c @@ -1,4 +1,5 @@ #include "work_queue.h" +#include "qom/object_interfaces.h" static void *work_queue_run(void *arg) { @@ -105,3 +106,115 @@ void work_queue_destroy(struct work_queue *wq) g_free(wq); } + +static void workqueueobject_instance_finalize(Object *obj) +{ + WorkQueueObject *wqobj = WORKQUEUEOBJECT(obj); + + work_queue_destroy(wqobj->wq); + + wqobj->wq = NULL; +} + +static void workqueueobject_complete(UserCreatable *obj, Error **errp) +{ + WorkQueueObject *wqobj = WORKQUEUEOBJECT(obj); + + wqobj->wq = work_queue_create("render_queue"); +} + +static void workqueueobject_class_init(ObjectClass *klass, void *class_data) +{ + UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass); + ucc->complete = workqueueobject_complete; +} + +static const TypeInfo workqueueobject_info = { + .name = TYPE_WORKQUEUEOBJECT, + .parent = TYPE_OBJECT, + .class_init = workqueueobject_class_init, + .instance_size = sizeof(WorkQueueObject), + .instance_finalize = workqueueobject_instance_finalize, + .interfaces = (InterfaceInfo[]) { + {TYPE_USER_CREATABLE}, + {} + }, +}; + +static void workqueueobject_register_types(void) +{ + type_register_static(&workqueueobject_info); +} + +type_init(workqueueobject_register_types) + +struct query_object_arg +{ + WorkQueueObject *wqobj; + bool ambiguous; +}; + +static int query_object(Object *object, void *opaque) +{ + struct query_object_arg *arg = opaque; + WorkQueueObject *wqobj; + + wqobj = (WorkQueueObject*)object_dynamic_cast(object, TYPE_WORKQUEUEOBJECT); + + if (wqobj) { + if (arg->wqobj) { + arg->ambiguous = true; + } + arg->wqobj = wqobj; + } + + return 0; +} + +WorkQueueObject *workqueueobject_create(bool *ambiguous) +{ + Object *container = container_get(object_get_root(), "/objects"); + struct query_object_arg arg = { NULL, false }; + + object_child_foreach(container, query_object, &arg); + + *ambiguous = arg.ambiguous; + + if (!arg.wqobj) { + Error *err = NULL; + + arg.wqobj = WORKQUEUEOBJECT(object_new(TYPE_WORKQUEUEOBJECT)); + + user_creatable_complete(&arg.wqobj->base, &err); + + if (err) { + error_free(err); + return NULL; + } + + object_property_add_child(container, "wq0", &arg.wqobj->base, &err); + + object_unref(&arg.wqobj->base); + + if (err) { + error_free(err); + return NULL; + } + } + + return arg.wqobj; +} + +WorkQueueObject *workqueueobject_find(const char *id) +{ + Object *container = container_get(object_get_root(), "/objects"); + Object *child; + + child = object_property_get_link(container, id, NULL); + + if (!child) { + return NULL; + } + + return (WorkQueueObject*)object_dynamic_cast(child, TYPE_WORKQUEUEOBJECT); +} diff --git a/hw/vigs/work_queue.h b/hw/vigs/work_queue.h index af27ee2..f0babe4 100644 --- a/hw/vigs/work_queue.h +++ b/hw/vigs/work_queue.h @@ -42,4 +42,18 @@ void work_queue_wait(struct work_queue *wq); void work_queue_destroy(struct work_queue *wq); +#define TYPE_WORKQUEUEOBJECT "work_queue" + +typedef struct { + Object base; + struct work_queue *wq; +} WorkQueueObject; + +#define WORKQUEUEOBJECT(obj) \ + OBJECT_CHECK(WorkQueueObject, obj, TYPE_WORKQUEUEOBJECT) + +WorkQueueObject *workqueueobject_create(bool *ambiguous); + +WorkQueueObject *workqueueobject_find(const char *id); + #endif diff --git a/hw/yagl/yagl_device.c b/hw/yagl/yagl_device.c index 733ed40..b77151f 100644 --- a/hw/yagl/yagl_device.c +++ b/hw/yagl/yagl_device.c @@ -41,7 +41,10 @@ #include "exec/cpu-all.h" #include "hw/hw.h" #include "hw/pci/pci.h" +#include "qemu/error-report.h" #include +#include "vigs/display.h" +#include "vigs/work_queue.h" #include "vigs/winsys.h" #include "yagl_gles_driver.h" @@ -56,15 +59,6 @@ #define YAGL_MAX_USERS (YAGL_MEM_SIZE / YAGL_REGS_SIZE) -#ifdef __linux__ -extern Display *vigs_display; -#else -extern void *vigs_display; -#endif - -extern struct work_queue *vigs_render_queue; -extern struct winsys_interface *vigs_wsi; - struct yagl_user { bool activated; @@ -76,6 +70,9 @@ typedef struct YaGLState { PCIDevice dev; + char *display; + char *render_queue; + char *wsi; MemoryRegion iomem; struct yagl_server_state *ss; struct yagl_user users[YAGL_MAX_USERS]; @@ -214,28 +211,6 @@ static void yagl_device_write(void *opaque, hwaddr offset, } } -#ifdef __linux__ -static int x_error_handler(Display *dpy, XErrorEvent *e) -{ - return 0; -} - -static Display *get_display(void) -{ - XSetErrorHandler(x_error_handler); - XInitThreads(); - - Display *display = XOpenDisplay(0); - - if (!display) { - fprintf(stderr, "Cannot open X display\n"); - exit(1); - } - - return display; -} -#endif - static const MemoryRegionOps yagl_device_ops = { .read = yagl_device_read, @@ -246,10 +221,67 @@ static const MemoryRegionOps yagl_device_ops = static int yagl_device_init(PCIDevice *dev) { YaGLState *s = DO_UPCAST(YaGLState, dev, dev); + DisplayObject *dobj = NULL; + WorkQueueObject *wqobj = NULL; + WSIObject *wsiobj = NULL; struct yagl_egl_driver *egl_driver = NULL; struct yagl_egl_backend *egl_backend = NULL; struct yagl_gles_driver *gles_driver = NULL; + if (s->display) { + dobj = displayobject_find(s->display); + + if (!dobj) { + error_report("display '%s' not found", s->display); + return -1; + } + } else { + bool ambiguous; + + dobj = displayobject_create(&ambiguous); + + if (ambiguous) { + error_report("ambiguous display, set 'display' property"); + return -1; + } + + if (!dobj) { + error_report("unable to create display"); + return -1; + } + } + + if (s->render_queue) { + wqobj = workqueueobject_find(s->render_queue); + + if (!wqobj) { + error_report("work queue '%s' not found", s->render_queue); + return -1; + } + } else { + bool ambiguous; + + wqobj = workqueueobject_create(&ambiguous); + + if (ambiguous) { + error_report("ambiguous work queue, set 'render_queue' property"); + return -1; + } + + if (!dobj) { + error_report("unable to create work queue"); + return -1; + } + } + + if (s->wsi) { + wsiobj = wsiobject_find(s->wsi); + if (!wsiobj) { + error_report("winsys interface '%s' not found", s->wsi); + return -1; + } + } + yagl_log_init(); YAGL_LOG_FUNC_ENTER(yagl_device_init, NULL); @@ -262,17 +294,7 @@ static int yagl_device_init(PCIDevice *dev) yagl_handle_gen_init(); - if (!vigs_render_queue) { - vigs_render_queue = work_queue_create("render_queue"); - } - -#ifdef __linux__ - if (!vigs_display) { - vigs_display = get_display(); - } -#endif - - egl_driver = yagl_egl_driver_create(vigs_display); + egl_driver = yagl_egl_driver_create(dobj->dpy); if (!egl_driver) { goto fail; @@ -285,9 +307,8 @@ static int yagl_device_init(PCIDevice *dev) goto fail; } - // FIXME: How can we gurantee that vigs is initialized before ? - if (vigs_wsi) { - egl_backend = yagl_egl_onscreen_create(vigs_wsi, + if (wsiobj && wsiobj->gl_wsi) { + egl_backend = yagl_egl_onscreen_create(wsiobj->gl_wsi, egl_driver, gles_driver); gles_driver = yagl_gles_onscreen_create(gles_driver); @@ -305,7 +326,8 @@ static int yagl_device_init(PCIDevice *dev) egl_driver = NULL; s->ss = yagl_server_state_create(egl_backend, gles_driver, - vigs_render_queue, vigs_wsi); + wqobj->wq, + (wsiobj ? wsiobj->gl_wsi : NULL)); /* * Owned/destroyed by server state. @@ -376,6 +398,13 @@ static void yagl_device_exit(PCIDevice *dev) yagl_log_cleanup(); } +static Property yagl_properties[] = { + DEFINE_PROP_STRING("display", YaGLState, display), + DEFINE_PROP_STRING("render_queue", YaGLState, render_queue), + DEFINE_PROP_STRING("wsi", YaGLState, wsi), + DEFINE_PROP_END_OF_LIST(), +}; + static void yagl_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -387,6 +416,7 @@ static void yagl_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_YAGL; k->class_id = PCI_CLASS_OTHERS; dc->reset = yagl_device_reset; + dc->props = yagl_properties; dc->desc = "YaGL device"; } diff --git a/vl.c b/vl.c index 5c1f583..9458e3a 100644 --- a/vl.c +++ b/vl.c @@ -146,11 +146,11 @@ int qemu_main(int argc, char **argv, char **envp); #ifdef CONFIG_MARU int skin_disabled = 0; -extern int enable_yagl; +static int enable_yagl= 0; extern int enable_spice; -const char *yagl_backend = NULL; -int enable_vigs = 0; -char *vigs_backend = NULL; +static const char *yagl_backend = NULL; +static int enable_vigs = 0; +static char *vigs_backend = NULL; #endif static const char *data_dir[16]; @@ -4618,7 +4618,10 @@ int main(int argc, char **argv, char **envp) PCIDevice *pci_dev = pci_create(pci_bus, -1, "vigs"); if (vigs_backend) { qdev_prop_set_string(&pci_dev->qdev, "backend", vigs_backend); + } else { + qdev_prop_set_string(&pci_dev->qdev, "backend", "gl"); } + qdev_prop_set_string(&pci_dev->qdev, "wsi", "wsi0"); qdev_init_nofail(&pci_dev->qdev); } #endif @@ -4627,6 +4630,9 @@ int main(int argc, char **argv, char **envp) if (enable_yagl) { PCIBus *pci_bus = (PCIBus *) object_resolve_path_type("", TYPE_PCI_BUS, NULL); PCIDevice *pci_dev = pci_create(pci_bus, -1, "yagl"); + if (enable_vigs) { + qdev_prop_set_string(&pci_dev->qdev, "wsi", "wsi0"); + } qdev_init_nofail(&pci_dev->qdev); } #endif -- 2.7.4