From: Stanislav Vorobiov Date: Thu, 18 Jul 2013 09:04:26 +0000 (+0400) Subject: Merge branch 'tizen-vigs-develop' into develop X-Git-Tag: TizenStudio_2.0_p2.3~759^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=18dc3d756e645ca442373ed109e14b5a65ec0231;p=sdk%2Femulator%2Fqemu.git Merge branch 'tizen-vigs-develop' into develop Conflicts: configure hw/Makefile.objs hw/qdev-properties.c hw/qdev.h hw/virtio-balloon.c hw/virtio-balloon.h hw/virtio-blk.c hw/virtio-blk.h hw/virtio-net.c hw/virtio-net.h hw/virtio-pci.h hw/virtio-serial-bus.c hw/virtio-serial.h hw/virtio/virtio-mmio.c tizen/emulator_configure.sh tizen/src/hw/maru_board.c --- 18dc3d756e645ca442373ed109e14b5a65ec0231 diff --cc configure index 3f4493f,437fc24..4263e07 --- a/configure +++ b/configure @@@ -233,10 -218,9 +233,11 @@@ opengl=" efence="no" yagl="no" yagl_stats="no" +glx="" + vigs="no" zlib="yes" guest_agent="yes" +want_tools="yes" libiscsi="" coroutine="" seccomp="" @@@ -905,17 -868,13 +906,21 @@@ for opt d ;; --disable-yagl-stats) yagl_stats="no" ;; + --enable-opengl) opengl="yes" + ;; + --enable-vigs) vigs="yes" + ;; + --disable-vigs) vigs="no" + ;; --disable-opengl) opengl="no" ;; - --enable-opengl) opengl="yes" + --disable-vhost-scsi) vhost_scsi="no" + ;; + --enable-vhost-scsi) vhost_scsi="yes" + ;; + --disable-glx) glx="no" + ;; + --enable-glx) glx="yes" ;; --disable-rbd) rbd="no" ;; @@@ -3640,7 -3248,7 +3647,8 @@@ echo "OpenGL support $opengl echo "EFence support $efence" echo "YaGL support $yagl" echo "YaGL stats $yagl_stats" +echo "GLX support $glx" + echo "VIGS support $vigs" echo "libiscsi support $libiscsi" echo "build guest agent $guest_agent" echo "seccomp support $seccomp" diff --cc hw/vigs_device.c index 0000000,0e0e402..28192fe mode 000000,100644..100644 --- a/hw/vigs_device.c +++ b/hw/vigs_device.c @@@ -1,0 -1,336 +1,343 @@@ + #include "vigs_device.h" + #include "vigs_log.h" + #include "vigs_server.h" + #include "vigs_backend.h" + #include "vigs_regs.h" -#include "hw.h" -#include "console.h" ++#include "hw/hw.h" ++#include "ui/console.h" + + #define PCI_VENDOR_ID_VIGS 0x19B2 + #define PCI_DEVICE_ID_VIGS 0x1011 + + #define VIGS_IO_SIZE 0x1000 + + typedef struct VIGSState + { + VIGSDevice dev; + + void *display; + + MemoryRegion vram_bar; + uint32_t vram_size; + + MemoryRegion ram_bar; + uint32_t ram_size; + + MemoryRegion io_bar; + + struct vigs_server *server; + + /* - * Our display. ++ * Our console. + */ - DisplayState *ds; ++ QemuConsole *con; + + uint32_t reg_int; + } VIGSState; + + #define TYPE_VIGS_DEVICE "vigs" + + extern const char *vigs_backend; + + static void vigs_update_irq(VIGSState *s) + { + if ((s->reg_int & VIGS_REG_INT_VBLANK_ENABLE) == 0) { + qemu_irq_lower(s->dev.pci_dev.irq[0]); + return; + } + + if (s->reg_int & VIGS_REG_INT_VBLANK_PENDING) { + qemu_irq_raise(s->dev.pci_dev.irq[0]); + } else { + qemu_irq_lower(s->dev.pci_dev.irq[0]); + } + } + + static void vigs_hw_update(void *opaque) + { + VIGSState *s = opaque; ++ DisplaySurface *ds = qemu_console_surface(s->con); + - if (!ds_get_data(s->ds)) { ++ if (!surface_data(ds)) { + return; + } + + vigs_server_update_display(s->server); + - dpy_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds)); ++ dpy_gfx_update(s->con, 0, 0, surface_width(ds), surface_height(ds)); + + if (s->reg_int & VIGS_REG_INT_VBLANK_ENABLE) { + s->reg_int |= VIGS_REG_INT_VBLANK_PENDING; + vigs_update_irq(s); + } + } + + static void vigs_hw_invalidate(void *opaque) + { + } + + static void vigs_dpy_resize(void *user_data, + uint32_t width, + uint32_t height) + { + VIGSState *s = user_data; ++ DisplaySurface *ds = qemu_console_surface(s->con); + - if ((width != ds_get_width(s->ds)) || - (height != ds_get_height(s->ds))) ++ if ((width != surface_width(ds)) || ++ (height != surface_height(ds))) + { - qemu_console_resize(s->ds, width, height); ++ qemu_console_resize(s->con, width, height); + } + } + + static uint32_t vigs_dpy_get_stride(void *user_data) + { + VIGSState *s = user_data; ++ DisplaySurface *ds = qemu_console_surface(s->con); + - return ds_get_linesize(s->ds); ++ return surface_stride(ds); + } + + static uint32_t vigs_dpy_get_bpp(void *user_data) + { + VIGSState *s = user_data; ++ DisplaySurface *ds = qemu_console_surface(s->con); + - return ds_get_bytes_per_pixel(s->ds); ++ return surface_bytes_per_pixel(ds); + } + + static uint8_t *vigs_dpy_get_data(void *user_data) + { + VIGSState *s = user_data; ++ DisplaySurface *ds = qemu_console_surface(s->con); + - return ds_get_data(s->ds); ++ return surface_data(ds); + } + -static uint64_t vigs_io_read(void *opaque, target_phys_addr_t offset, ++static uint64_t vigs_io_read(void *opaque, hwaddr offset, + unsigned size) + { + VIGSState *s = opaque; + + switch (offset) { + case VIGS_REG_INT: + return s->reg_int; + default: + VIGS_LOG_CRITICAL("Bad register 0x%X read", (uint32_t)offset); + break; + } + + return 0; + } + -static void vigs_io_write(void *opaque, target_phys_addr_t offset, ++static void vigs_io_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) + { + VIGSState *s = opaque; + + switch (offset) { + case VIGS_REG_EXEC: + vigs_server_dispatch(s->server, value); + break; + case VIGS_REG_INT: + if (((s->reg_int & VIGS_REG_INT_VBLANK_PENDING) == 0) && + (value & VIGS_REG_INT_VBLANK_PENDING)) { + VIGS_LOG_CRITICAL("Attempt to set VBLANK_PENDING"); + value &= ~VIGS_REG_INT_VBLANK_PENDING; + } + + if (((s->reg_int & VIGS_REG_INT_VBLANK_ENABLE) == 0) && + (value & VIGS_REG_INT_VBLANK_ENABLE)) { + VIGS_LOG_DEBUG("VBLANK On"); + } else if (((value & VIGS_REG_INT_VBLANK_ENABLE) == 0) && + (s->reg_int & VIGS_REG_INT_VBLANK_ENABLE)) { + VIGS_LOG_DEBUG("VBLANK Off"); + } + + s->reg_int = value & VIGS_REG_INT_MASK; + if ((value & VIGS_REG_INT_VBLANK_ENABLE) == 0) { + s->reg_int &= ~VIGS_REG_INT_VBLANK_PENDING; + } + vigs_update_irq(s); + break; + default: + VIGS_LOG_CRITICAL("Bad register 0x%X write", (uint32_t)offset); + break; + } + } + ++static struct GraphicHwOps vigs_hw_ops = ++{ ++ .invalidate = vigs_hw_invalidate, ++ .gfx_update = vigs_hw_update ++}; ++ + static const MemoryRegionOps vigs_io_ops = + { + .read = vigs_io_read, + .write = vigs_io_write, + .endianness = DEVICE_NATIVE_ENDIAN, + }; + + static struct vigs_display_ops vigs_dpy_ops = + { + .resize = vigs_dpy_resize, + .get_stride = vigs_dpy_get_stride, + .get_bpp = vigs_dpy_get_bpp, + .get_data = vigs_dpy_get_data, + }; + + static int vigs_device_init(PCIDevice *dev) + { + VIGSState *s = DO_UPCAST(VIGSState, dev.pci_dev, dev); + struct vigs_backend *backend = NULL; + + vigs_log_init(); + + if (s->vram_size < 16 * 1024 * 1024) { + VIGS_LOG_WARN("\"vram_size\" is too small, defaulting to 16mb"); + s->vram_size = 16 * 1024 * 1024; + } + + if (s->ram_size < 1 * 1024 * 1024) { + VIGS_LOG_WARN("\"ram_size\" is too small, defaulting to 1mb"); + s->ram_size = 1 * 1024 * 1024; + } + + pci_config_set_interrupt_pin(dev->config, 1); + + memory_region_init_ram(&s->vram_bar, + TYPE_VIGS_DEVICE ".vram", + s->vram_size); + + memory_region_init_ram(&s->ram_bar, + TYPE_VIGS_DEVICE ".ram", + s->ram_size); + + memory_region_init_io(&s->io_bar, + &vigs_io_ops, + s, + 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); + + if (!strcmp(vigs_backend, "gl")) { + backend = vigs_gl_backend_create(s->display); + } else if (!strcmp(vigs_backend, "sw")) { + backend = vigs_sw_backend_create(); + } + + if (!backend) { + goto fail; + } + - s->ds = graphic_console_init(vigs_hw_update, - vigs_hw_invalidate, - NULL, - NULL, - s); ++ s->con = graphic_console_init(DEVICE(dev), &vigs_hw_ops, s); + - if (!s->ds) { ++ if (!s->con) { + goto fail; + } + + s->server = vigs_server_create(memory_region_get_ram_ptr(&s->vram_bar), + memory_region_get_ram_ptr(&s->ram_bar), + &vigs_dpy_ops, + s, + backend); + + if (!s->server) { + goto fail; + } + + s->dev.wsi = &s->server->wsi; + + VIGS_LOG_INFO("VIGS initialized"); + + VIGS_LOG_DEBUG("vram_size = %u", s->vram_size); + VIGS_LOG_DEBUG("ram_size = %u", s->ram_size); + + return 0; + + fail: + if (backend) { + backend->destroy(backend); + } + + memory_region_destroy(&s->io_bar); + memory_region_destroy(&s->ram_bar); + memory_region_destroy(&s->vram_bar); + + vigs_log_cleanup(); + + return -1; + } + + static void vigs_device_reset(DeviceState *d) + { + VIGSState *s = container_of(d, VIGSState, dev.pci_dev.qdev); + + vigs_server_reset(s->server); + + s->reg_int = 0; + + VIGS_LOG_INFO("VIGS reset"); + } + + static void vigs_device_exit(PCIDevice *dev) + { + VIGSState *s = DO_UPCAST(VIGSState, dev.pci_dev, dev); + + vigs_server_destroy(s->server); + + memory_region_destroy(&s->io_bar); + memory_region_destroy(&s->ram_bar); + memory_region_destroy(&s->vram_bar); + + VIGS_LOG_INFO("VIGS deinitialized"); + + vigs_log_cleanup(); + } + + static Property vigs_properties[] = { + { + .name = "display", + .info = &qdev_prop_ptr, + .offset = offsetof(VIGSState, display), + }, + DEFINE_PROP_UINT32("vram_size", VIGSState, vram_size, + 32 * 1024 * 1024), + DEFINE_PROP_UINT32("ram_size", VIGSState, ram_size, + 1 * 1024 * 1024), + DEFINE_PROP_END_OF_LIST(), + }; + + static void vigs_class_init(ObjectClass *klass, void *data) + { + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->init = vigs_device_init; + k->exit = vigs_device_exit; + k->vendor_id = PCI_VENDOR_ID_VIGS; + k->device_id = PCI_DEVICE_ID_VIGS; + k->class_id = PCI_CLASS_DISPLAY_VGA; + dc->reset = vigs_device_reset; + dc->props = vigs_properties; + dc->desc = "VIGS device"; + } + + static TypeInfo vigs_device_info = + { + .name = TYPE_VIGS_DEVICE, + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(VIGSState), + .class_init = vigs_class_init, + }; + + static void vigs_register_types(void) + { + type_register_static(&vigs_device_info); + } + + type_init(vigs_register_types) diff --cc hw/vigs_device.h index 0000000,97e7993..6a591a7 mode 000000,100644..100644 --- a/hw/vigs_device.h +++ b/hw/vigs_device.h @@@ -1,0 -1,16 +1,16 @@@ + #ifndef _QEMU_VIGS_DEVICE_H + #define _QEMU_VIGS_DEVICE_H + + #include "qemu-common.h" -#include "pci.h" ++#include "hw/pci/pci.h" + + struct winsys_interface; + + typedef struct VIGSDevice + { + PCIDevice pci_dev; + + struct winsys_interface *wsi; + } VIGSDevice; + + #endif diff --cc hw/yagl_apis/egl/yagl_egl_api_ps.h index 5ae5fbf,c69af91..d6ff9d3 --- a/hw/yagl_apis/egl/yagl_egl_api_ps.h +++ b/hw/yagl_apis/egl/yagl_egl_api_ps.h @@@ -2,11 -2,10 +2,10 @@@ #define _QEMU_YAGL_EGL_API_PS_H #include "yagl_api.h" - #include "qemu-thread.h" --#include "qemu-queue.h" ++#include "qemu/queue.h" struct yagl_egl_interface; - struct yagl_egl_driver_ps; + struct yagl_egl_backend; struct yagl_egl_display; struct yagl_egl_api_ps diff --cc hw/yagl_apis/egl/yagl_egl_display.h index 0faaa8c,6990436..6e3fae7 --- a/hw/yagl_apis/egl/yagl_egl_display.h +++ b/hw/yagl_apis/egl/yagl_egl_display.h @@@ -3,11 -3,10 +3,10 @@@ #include "yagl_types.h" #include "yagl_resource_list.h" - #include "qemu-thread.h" --#include "qemu-queue.h" ++#include "qemu/queue.h" #include - struct yagl_egl_driver_ps; + struct yagl_egl_backend; struct yagl_egl_config; struct yagl_egl_native_config; struct yagl_egl_surface; diff --cc hw/yagl_apis/gles1/yagl_gles1_context.c index 0000000,c318656..dc03c69 mode 000000,100644..100644 --- a/hw/yagl_apis/gles1/yagl_gles1_context.c +++ b/hw/yagl_apis/gles1/yagl_gles1_context.c @@@ -1,0 -1,1236 +1,1237 @@@ + #include + #include + #include "yagl_gles1_context.h" + #include "yagl_apis/gles/yagl_gles_array.h" + #include "yagl_apis/gles/yagl_gles_buffer.h" + #include "yagl_log.h" + #include "yagl_process.h" + #include "yagl_thread.h" + #include "yagl_sharegroup.h" + #include "yagl_gles1_driver.h" ++#include "exec/user/abitypes.h" + + #define YAGL_GLES1_NUM_COMP_TEX_FORMATS 10 + #define YAGL_TARGET_INT_MAX \ - ((1ll << ((sizeof(target_int) * 8) - 1)) - 1) ++ ((1ll << ((sizeof(abi_int) * 8) - 1)) - 1) + + static void yagl_gles1_vertex_array_apply(struct yagl_gles_array *array) + { + struct yagl_gles1_driver *driver = ((YaglGles1Context *)array->ctx)->driver; + GLenum type = array->type; + GLsizei stride = array->stride; + + if (array->vbo) { + yagl_object_name old_buffer_name = 0; + GLvoid *pointer = (GLvoid *)(uintptr_t)array->offset; + + yagl_gles_buffer_bind(array->vbo, + array->type, + array->need_convert, + GL_ARRAY_BUFFER, + &old_buffer_name); + + if (array->type == GL_BYTE) { + type = GL_SHORT; + pointer = (GLvoid *)(uintptr_t)(array->offset * sizeof(GLshort)); + stride = array->stride * sizeof(GLshort); + } else if (array->type == GL_FIXED) { + type = GL_FLOAT; + } + + driver->VertexPointer(array->size, type, stride, pointer); + + driver->base.BindBuffer(GL_ARRAY_BUFFER, old_buffer_name); + } else { + assert(array->host_data); + + if (array->type == GL_BYTE) { + type = GL_SHORT; + stride = 0; + } else if (array->type == GL_FIXED) { + type = GL_FLOAT; + } + + driver->VertexPointer(array->size, type, stride, array->host_data); + } + } + + static void yagl_gles1_normal_array_apply(struct yagl_gles_array *array) + { + struct yagl_gles1_driver *driver = ((YaglGles1Context *)array->ctx)->driver; + GLenum type = array->type == GL_FIXED ? GL_FLOAT : array->type; + + if (array->vbo) { + yagl_object_name old_buffer_name = 0; + + yagl_gles_buffer_bind(array->vbo, + array->type, + array->need_convert, + GL_ARRAY_BUFFER, + &old_buffer_name); + + driver->NormalPointer(type, + array->stride, + (GLvoid *)(uintptr_t)array->offset); + + driver->base.BindBuffer(GL_ARRAY_BUFFER, old_buffer_name); + } else { + assert(array->host_data); + + driver->NormalPointer(type, + array->stride, + array->host_data); + } + } + + static void yagl_gles1_color_array_apply(struct yagl_gles_array *array) + { + struct yagl_gles1_driver *driver = ((YaglGles1Context *)array->ctx)->driver; + GLenum type = array->type == GL_FIXED ? GL_FLOAT : array->type; + + if (array->vbo) { + yagl_object_name old_buffer_name = 0; + + yagl_gles_buffer_bind(array->vbo, + array->type, + array->need_convert, + GL_ARRAY_BUFFER, + &old_buffer_name); + + driver->ColorPointer(array->size, + type, + array->stride, + (GLvoid *)(uintptr_t)array->offset); + + driver->base.BindBuffer(GL_ARRAY_BUFFER, old_buffer_name); + } else { + assert(array->host_data); + + driver->ColorPointer(array->size, + type, + array->stride, + array->host_data); + } + } + + static void yagl_gles1_tex_coord_array_apply(struct yagl_gles_array *array) + { + YaglGles1Context *gles1_ctx = (YaglGles1Context *)array->ctx; + struct yagl_gles1_driver *driver = gles1_ctx->driver; + GLenum type = array->type; + GLsizei stride = array->stride; + int tex_id = array->index - YAGL_GLES1_ARRAY_TEX_COORD; + + if (tex_id != gles1_ctx->client_active_texture) { + driver->ClientActiveTexture(tex_id + GL_TEXTURE0); + } + + if (array->vbo) { + yagl_object_name old_buffer_name = 0; + GLvoid *pointer = (GLvoid *)(uintptr_t)array->offset; + + yagl_gles_buffer_bind(array->vbo, + array->type, + array->need_convert, + GL_ARRAY_BUFFER, + &old_buffer_name); + + if (array->type == GL_BYTE) { + type = GL_SHORT; + pointer = (GLvoid *)(uintptr_t)(array->offset * sizeof(GLshort)); + stride = array->stride * sizeof(GLshort); + } else if (array->type == GL_FIXED) { + type = GL_FLOAT; + } + + driver->TexCoordPointer(array->size, type, stride, pointer); + + driver->base.BindBuffer(GL_ARRAY_BUFFER, old_buffer_name); + } else { + assert(array->host_data); + + if (array->type == GL_BYTE) { + type = GL_SHORT; + stride = 0; + } else if (array->type == GL_FIXED) { + type = GL_FLOAT; + } + + driver->TexCoordPointer(array->size, type, stride, array->host_data); + } + + if (tex_id != gles1_ctx->client_active_texture) { + driver->ClientActiveTexture(gles1_ctx->client_active_texture + + GL_TEXTURE0); + } + } + + static void yagl_gles1_point_size_array_apply(struct yagl_gles_array *array) + { + + } + + static void yagl_gles1_context_prepare(YaglGles1Context *gles1_ctx) + { + struct yagl_gles_driver *gles_driver = &gles1_ctx->driver->base; + GLint i, num_texture_units = 0; + struct yagl_gles_array *arrays; + const gchar *extns = NULL; + int num_arrays; + + YAGL_LOG_FUNC_ENTER(yagl_gles2_context_prepare, "%p", gles1_ctx); + + gles_driver->GetIntegerv(GL_MAX_TEXTURE_UNITS, &num_texture_units); + + /* + * We limit this by 32 for conformance. + */ + if (num_texture_units > 32) { + num_texture_units = 32; + } + + /* Each texture unit has its own client-side array state */ + num_arrays = YAGL_GLES1_ARRAY_TEX_COORD + num_texture_units; + + arrays = g_new(struct yagl_gles_array, num_arrays); + + yagl_gles_array_init(&arrays[YAGL_GLES1_ARRAY_VERTEX], + YAGL_GLES1_ARRAY_VERTEX, + &gles1_ctx->base, + &yagl_gles1_vertex_array_apply); + + yagl_gles_array_init(&arrays[YAGL_GLES1_ARRAY_COLOR], + YAGL_GLES1_ARRAY_COLOR, + &gles1_ctx->base, + &yagl_gles1_color_array_apply); + + yagl_gles_array_init(&arrays[YAGL_GLES1_ARRAY_NORMAL], + YAGL_GLES1_ARRAY_NORMAL, + &gles1_ctx->base, + &yagl_gles1_normal_array_apply); + + yagl_gles_array_init(&arrays[YAGL_GLES1_ARRAY_POINTSIZE], + YAGL_GLES1_ARRAY_POINTSIZE, + &gles1_ctx->base, + &yagl_gles1_point_size_array_apply); + + for (i = YAGL_GLES1_ARRAY_TEX_COORD; i < num_arrays; ++i) { + yagl_gles_array_init(&arrays[i], + i, + &gles1_ctx->base, + &yagl_gles1_tex_coord_array_apply); + } + + yagl_gles_context_prepare(&gles1_ctx->base, arrays, + num_arrays, num_texture_units); + + gles_driver->GetIntegerv(GL_MAX_CLIP_PLANES, &gles1_ctx->max_clip_planes); + + if (gles1_ctx->max_clip_planes < 6) { + YAGL_LOG_WARN("host GL_MAX_CLIP_PLANES=%d is less then required 6", + gles1_ctx->max_clip_planes); + } else { + /* According to OpenGLES 1.1 docs on khrnos website we only need + * to support 6 planes. This will protect us from bogus + * GL_MAX_CLIP_PLANES value reported by some drivers */ + gles1_ctx->max_clip_planes = 6; + } + + gles_driver->GetIntegerv(GL_MAX_LIGHTS, &gles1_ctx->max_lights); + + gles_driver->GetIntegerv(GL_MAX_TEXTURE_SIZE, &gles1_ctx->max_tex_size); + + extns = (const gchar *)gles_driver->GetString(GL_EXTENSIONS); + + gles1_ctx->framebuffer_object = + (g_strstr_len(extns, -1, "GL_EXT_framebuffer_object ") != NULL) || + (g_strstr_len(extns, -1, "GL_ARB_framebuffer_object ") != NULL); + + gles1_ctx->matrix_palette = + (g_strstr_len(extns, -1, "GL_ARB_vertex_blend ") != NULL) && + (g_strstr_len(extns, -1, "GL_ARB_matrix_palette ") != NULL); + + YAGL_LOG_FUNC_EXIT(NULL); + } + + static void yagl_gles1_context_activate(struct yagl_client_context *ctx) + { + YaglGles1Context *gles1_ctx = (YaglGles1Context *)ctx; + + if (!gles1_ctx->prepared) { + yagl_gles1_context_prepare(gles1_ctx); + gles1_ctx->prepared = true; + } + + yagl_gles_context_activate(&gles1_ctx->base); + } + + static void yagl_gles1_context_deactivate(struct yagl_client_context *ctx) + { + YaglGles1Context *gles1_ctx = (YaglGles1Context *)ctx; + + yagl_gles_context_deactivate(&gles1_ctx->base); + } + + static void yagl_gles1_context_destroy(struct yagl_client_context *ctx) + { + YaglGles1Context *gles1_ctx = (YaglGles1Context *)ctx; + + YAGL_LOG_FUNC_ENTER(gles1_ctx->driver_ps->common->ps->id, + 0, + yagl_gles1_context_destroy, + "%p", + gles1_ctx); + + yagl_gles_context_cleanup(&gles1_ctx->base); + yagl_client_context_cleanup(&gles1_ctx->base.base); + + g_free(gles1_ctx); + + YAGL_LOG_FUNC_EXIT(NULL); + } + + static bool yagl_gles1_context_get_param_count(struct yagl_gles_context *ctx, + GLenum pname, + int *count) + { + YaglGles1Context *gles1_ctx = (YaglGles1Context *)ctx; + + switch (pname) { + case GL_COMPRESSED_TEXTURE_FORMATS: + *count = YAGL_GLES1_NUM_COMP_TEX_FORMATS; + break; + case GL_ACTIVE_TEXTURE: + case GL_ALPHA_BITS: + case GL_ALPHA_TEST: + case GL_ALPHA_TEST_FUNC: + case GL_ALPHA_TEST_REF: + case GL_ARRAY_BUFFER_BINDING: + case GL_BLEND: + case GL_BLEND_DST: + case GL_BLEND_SRC: + case GL_BLUE_BITS: + case GL_CLIENT_ACTIVE_TEXTURE: + case GL_COLOR_ARRAY: + case GL_COLOR_ARRAY_BUFFER_BINDING: + case GL_COLOR_ARRAY_SIZE: + case GL_COLOR_ARRAY_STRIDE: + case GL_COLOR_ARRAY_TYPE: + case GL_COLOR_LOGIC_OP: + case GL_COLOR_MATERIAL: + case GL_CULL_FACE: + case GL_CULL_FACE_MODE: + case GL_DEPTH_BITS: + case GL_DEPTH_CLEAR_VALUE: + case GL_DEPTH_FUNC: + case GL_DEPTH_TEST: + case GL_DEPTH_WRITEMASK: + case GL_ELEMENT_ARRAY_BUFFER_BINDING: + case GL_FOG: + case GL_FOG_DENSITY: + case GL_FOG_END: + case GL_FOG_HINT: + case GL_FOG_MODE: + case GL_FOG_START: + case GL_FRONT_FACE: + case GL_GENERATE_MIPMAP_HINT: + case GL_GREEN_BITS: + case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: + case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: + case GL_LIGHT_MODEL_TWO_SIDE: + case GL_LIGHTING: + case GL_LINE_SMOOTH: + case GL_LINE_SMOOTH_HINT: + case GL_LINE_WIDTH: + case GL_LOGIC_OP_MODE: + case GL_MATRIX_MODE: + case GL_MAX_CLIP_PLANES: + case GL_MAX_LIGHTS: + case GL_MAX_MODELVIEW_STACK_DEPTH: + case GL_MAX_PROJECTION_STACK_DEPTH: + case GL_MAX_TEXTURE_SIZE: + case GL_MAX_TEXTURE_STACK_DEPTH: + case GL_MAX_TEXTURE_UNITS: + case GL_MODELVIEW_STACK_DEPTH: + case GL_MULTISAMPLE: + case GL_NORMAL_ARRAY: + case GL_NORMAL_ARRAY_BUFFER_BINDING: + case GL_NORMAL_ARRAY_STRIDE: + case GL_NORMAL_ARRAY_TYPE: + case GL_NORMALIZE: + case GL_NUM_COMPRESSED_TEXTURE_FORMATS: + case GL_PACK_ALIGNMENT: + case GL_PERSPECTIVE_CORRECTION_HINT: + case GL_POINT_FADE_THRESHOLD_SIZE: + case GL_POINT_SIZE: + case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: + case GL_POINT_SIZE_ARRAY_OES: + case GL_POINT_SIZE_ARRAY_STRIDE_OES: + case GL_POINT_SIZE_ARRAY_TYPE_OES: + case GL_POINT_SIZE_MAX: + case GL_POINT_SIZE_MIN: + case GL_POINT_SMOOTH: + case GL_POINT_SMOOTH_HINT: + case GL_POINT_SPRITE_OES: + case GL_POLYGON_OFFSET_FACTOR: + case GL_POLYGON_OFFSET_FILL: + case GL_POLYGON_OFFSET_UNITS: + case GL_PROJECTION_STACK_DEPTH: + case GL_RED_BITS: + case GL_RESCALE_NORMAL: + case GL_SAMPLE_ALPHA_TO_COVERAGE: + case GL_SAMPLE_ALPHA_TO_ONE: + case GL_SAMPLE_BUFFERS: + case GL_SAMPLE_COVERAGE: + case GL_SAMPLE_COVERAGE_INVERT: + case GL_SAMPLE_COVERAGE_VALUE: + case GL_SAMPLES: + case GL_SCISSOR_TEST: + case GL_SHADE_MODEL: + case GL_STENCIL_BITS: + case GL_STENCIL_CLEAR_VALUE: + case GL_STENCIL_FAIL: + case GL_STENCIL_FUNC: + case GL_STENCIL_PASS_DEPTH_FAIL: + case GL_STENCIL_PASS_DEPTH_PASS: + case GL_STENCIL_REF: + case GL_STENCIL_TEST: + case GL_STENCIL_VALUE_MASK: + case GL_STENCIL_WRITEMASK: + case GL_SUBPIXEL_BITS: + case GL_TEXTURE_2D: + case GL_TEXTURE_BINDING_2D: + case GL_TEXTURE_COORD_ARRAY: + case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: + case GL_TEXTURE_COORD_ARRAY_SIZE: + case GL_TEXTURE_COORD_ARRAY_STRIDE: + case GL_TEXTURE_COORD_ARRAY_TYPE: + case GL_TEXTURE_STACK_DEPTH: + case GL_UNPACK_ALIGNMENT: + case GL_VERTEX_ARRAY: + case GL_VERTEX_ARRAY_BUFFER_BINDING: + case GL_VERTEX_ARRAY_SIZE: + case GL_VERTEX_ARRAY_STRIDE: + case GL_VERTEX_ARRAY_TYPE: + /* GL_OES_blend_equation_separate */ + case GL_BLEND_EQUATION_RGB_OES: + case GL_BLEND_EQUATION_ALPHA_OES: + /* OES_blend_func_separate */ + case GL_BLEND_DST_RGB_OES: + case GL_BLEND_SRC_RGB_OES: + case GL_BLEND_DST_ALPHA_OES: + case GL_BLEND_SRC_ALPHA_OES: + *count = 1; + break; + case GL_DEPTH_RANGE: + case GL_ALIASED_LINE_WIDTH_RANGE: + case GL_ALIASED_POINT_SIZE_RANGE: + case GL_MAX_VIEWPORT_DIMS: + case GL_SMOOTH_LINE_WIDTH_RANGE: + case GL_SMOOTH_POINT_SIZE_RANGE: + *count = 2; + break; + case GL_CURRENT_NORMAL: + case GL_POINT_DISTANCE_ATTENUATION: + *count = 3; + break; + case GL_COLOR_WRITEMASK: + case GL_CURRENT_COLOR: + case GL_FOG_COLOR: + case GL_COLOR_CLEAR_VALUE: + case GL_LIGHT_MODEL_AMBIENT: + case GL_CURRENT_TEXTURE_COORDS: + case GL_SCISSOR_BOX: + case GL_VIEWPORT: + *count = 4; + break; + case GL_MODELVIEW_MATRIX: + case GL_PROJECTION_MATRIX: + case GL_TEXTURE_MATRIX: + *count = 16; + break; + /* GL_OES_framebuffer_object */ + case GL_FRAMEBUFFER_BINDING_OES: + case GL_RENDERBUFFER_BINDING_OES: + case GL_MAX_RENDERBUFFER_SIZE_OES: + if (!gles1_ctx->framebuffer_object) { + return false; + } + *count = 1; + break; + /* GL_OES_matrix_palette */ + case GL_MAX_PALETTE_MATRICES_OES: + case GL_MAX_VERTEX_UNITS_OES: + case GL_CURRENT_PALETTE_MATRIX_OES: + case GL_MATRIX_INDEX_ARRAY_SIZE_OES: + case GL_MATRIX_INDEX_ARRAY_TYPE_OES: + case GL_MATRIX_INDEX_ARRAY_STRIDE_OES: + case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES: + case GL_WEIGHT_ARRAY_SIZE_OES: + case GL_WEIGHT_ARRAY_TYPE_OES: + case GL_WEIGHT_ARRAY_STRIDE_OES: + case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES: + if (!gles1_ctx->matrix_palette) { + return false; + } + *count = 1; + break; + default: + if ((pname >= GL_CLIP_PLANE0 && + pname < (GL_CLIP_PLANE0 + gles1_ctx->max_clip_planes - 1)) || + (pname >= GL_LIGHT0 && + pname < (GL_LIGHT0 + gles1_ctx->max_lights - 1))) { + *count = 1; + break; + } + return false; + } + + return true; + } + + static unsigned yagl_gles1_array_idx_from_pname(YaglGles1Context *ctx, + GLenum pname) + { + switch (pname) { + case GL_VERTEX_ARRAY: + case GL_VERTEX_ARRAY_BUFFER_BINDING: + case GL_VERTEX_ARRAY_SIZE: + case GL_VERTEX_ARRAY_STRIDE: + case GL_VERTEX_ARRAY_TYPE: + return YAGL_GLES1_ARRAY_VERTEX; + case GL_COLOR_ARRAY: + case GL_COLOR_ARRAY_BUFFER_BINDING: + case GL_COLOR_ARRAY_SIZE: + case GL_COLOR_ARRAY_STRIDE: + case GL_COLOR_ARRAY_TYPE: + return YAGL_GLES1_ARRAY_COLOR; + case GL_NORMAL_ARRAY: + case GL_NORMAL_ARRAY_BUFFER_BINDING: + case GL_NORMAL_ARRAY_STRIDE: + case GL_NORMAL_ARRAY_TYPE: + return YAGL_GLES1_ARRAY_NORMAL; + case GL_TEXTURE_COORD_ARRAY: + case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: + case GL_TEXTURE_COORD_ARRAY_SIZE: + case GL_TEXTURE_COORD_ARRAY_STRIDE: + case GL_TEXTURE_COORD_ARRAY_TYPE: + return YAGL_GLES1_ARRAY_TEX_COORD + ctx->client_active_texture; + case GL_POINT_SIZE_ARRAY_TYPE_OES: + case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: + case GL_POINT_SIZE_ARRAY_OES: + case GL_POINT_SIZE_ARRAY_STRIDE_OES: + return YAGL_GLES1_ARRAY_POINTSIZE; + default: + exit(1); + } + } + + static void yagl_gles1_compressed_texture_formats_fill(GLint *params) + { + params[0] = GL_PALETTE4_RGB8_OES; + params[1] = GL_PALETTE4_RGBA8_OES; + params[2] = GL_PALETTE4_R5_G6_B5_OES; + params[3] = GL_PALETTE4_RGBA4_OES; + params[4] = GL_PALETTE4_RGB5_A1_OES; + params[5] = GL_PALETTE8_RGB8_OES; + params[6] = GL_PALETTE8_RGBA8_OES; + params[7] = GL_PALETTE8_R5_G6_B5_OES; + params[8] = GL_PALETTE8_RGBA4_OES; + params[9] = GL_PALETTE8_RGB5_A1_OES; + } + + static bool yagl_gles1_context_get_integerv(struct yagl_gles_context *ctx, + GLenum pname, + GLint *params) + { + YaglGles1Context *gles1_ctx = (YaglGles1Context *)ctx; + + switch (pname) { + case GL_MAX_CLIP_PLANES: + params[0] = gles1_ctx->max_clip_planes; + break; + case GL_MAX_LIGHTS: + params[0] = gles1_ctx->max_lights; + break; + case GL_MAX_TEXTURE_SIZE: + params[0] = gles1_ctx->max_tex_size; + break; + case GL_VERTEX_ARRAY: + case GL_NORMAL_ARRAY: + case GL_COLOR_ARRAY: + case GL_TEXTURE_COORD_ARRAY: + case GL_POINT_SIZE_ARRAY_OES: + params[0] = ctx->arrays[yagl_gles1_array_idx_from_pname(gles1_ctx, pname)].enabled; + break; + case GL_VERTEX_ARRAY_BUFFER_BINDING: + case GL_COLOR_ARRAY_BUFFER_BINDING: + case GL_NORMAL_ARRAY_BUFFER_BINDING: + case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: + case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: + params[0] = ctx->arrays[yagl_gles1_array_idx_from_pname(gles1_ctx, pname)].vbo_local_name; + break; + case GL_VERTEX_ARRAY_STRIDE: + case GL_COLOR_ARRAY_STRIDE: + case GL_NORMAL_ARRAY_STRIDE: + case GL_TEXTURE_COORD_ARRAY_STRIDE: + case GL_POINT_SIZE_ARRAY_STRIDE_OES: + params[0] = ctx->arrays[yagl_gles1_array_idx_from_pname(gles1_ctx, pname)].stride; + break; + case GL_VERTEX_ARRAY_TYPE: + case GL_COLOR_ARRAY_TYPE: + case GL_NORMAL_ARRAY_TYPE: + case GL_TEXTURE_COORD_ARRAY_TYPE: + case GL_POINT_SIZE_ARRAY_TYPE_OES: + params[0] = ctx->arrays[yagl_gles1_array_idx_from_pname(gles1_ctx, pname)].type; + break; + case GL_VERTEX_ARRAY_SIZE: + case GL_COLOR_ARRAY_SIZE: + case GL_TEXTURE_COORD_ARRAY_SIZE: + params[0] = ctx->arrays[yagl_gles1_array_idx_from_pname(gles1_ctx, pname)].size; + break; + case GL_FRAMEBUFFER_BINDING_OES: + params[0] = ctx->fbo_local_name; + break; + case GL_RENDERBUFFER_BINDING_OES: + params[0] = ctx->rbo_local_name; + break; + case GL_NUM_COMPRESSED_TEXTURE_FORMATS: + params[0] = YAGL_GLES1_NUM_COMP_TEX_FORMATS; + break; + case GL_COMPRESSED_TEXTURE_FORMATS: + yagl_gles1_compressed_texture_formats_fill(params); + break; + case GL_ALPHA_TEST_REF: + { + /* According to spec, GL_ALPHA_TEST_REF must be scaled to + * -INT_MAX..+INT_MAX range, but driver might not do it, we do + * it manually here */ + GLfloat tmp; + + ctx->driver->GetFloatv(GL_ALPHA_TEST_REF, &tmp); + params[0] = (GLint)(tmp * (GLfloat)YAGL_TARGET_INT_MAX) - 1; + break; + } + default: + return false; + } + + return true; + } + + static bool yagl_gles1_context_get_booleanv(struct yagl_gles_context *ctx, + GLenum pname, + GLboolean *params) + { + if (pname == GL_COMPRESSED_TEXTURE_FORMATS) { + GLint tmp[YAGL_GLES1_NUM_COMP_TEX_FORMATS]; + int i; + + if (yagl_gles1_context_get_integerv(ctx, pname, &tmp[0])) { + for (i = 0; i < YAGL_GLES1_NUM_COMP_TEX_FORMATS; ++i) { + params[i] = (tmp[i] != 0) ? GL_TRUE : GL_FALSE; + } + return true; + } + } else { + GLint tmp; + + if (yagl_gles1_context_get_integerv(ctx, pname, &tmp)) { + params[0] = ((tmp != 0) ? GL_TRUE : GL_FALSE); + return true; + } + } + + return false; + } + + static bool yagl_gles1_context_get_floatv(struct yagl_gles_context *ctx, + GLenum pname, + GLfloat *params) + { + if (pname == GL_COMPRESSED_TEXTURE_FORMATS) { + GLint tmp[YAGL_GLES1_NUM_COMP_TEX_FORMATS]; + int i; + + if (yagl_gles1_context_get_integerv(ctx, pname, &tmp[0])) { + for (i = 0; i < YAGL_GLES1_NUM_COMP_TEX_FORMATS; ++i) { + params[i] = (GLfloat)tmp[i]; + } + return true; + } + } else { + GLint tmp; + + if (yagl_gles1_context_get_integerv(ctx, pname, &tmp)) { + params[0] = (GLfloat)tmp; + return true; + } + } + + return false; + } + + static bool yagl_gles1_context_is_enabled(struct yagl_gles_context *ctx, + GLboolean* retval, + GLenum cap) + { + if (cap == GL_POINT_SIZE_ARRAY_OES) { + *retval = ctx->arrays[YAGL_GLES1_ARRAY_POINTSIZE].enabled; + return true; + } + + return false; + } + + static GLchar *yagl_gles1_context_get_extensions(struct yagl_gles_context *ctx) + { + YaglGles1Context *gles1_ctx = (YaglGles1Context *)ctx; + + const GLchar *default_ext = + "GL_OES_blend_subtract GL_OES_blend_equation_separate " + "GL_OES_blend_func_separate GL_OES_element_index_uint " + "GL_OES_texture_mirrored_repeat " + "GL_EXT_texture_format_BGRA8888 GL_OES_point_sprite " + "GL_OES_point_size_array GL_OES_stencil_wrap " + "GL_OES_compressed_paletted_texture " + "GL_OES_depth_texture "; + const GLchar *framebuffer_object_ext = + "GL_OES_framebuffer_object GL_OES_depth24 GL_OES_depth32 " + "GL_OES_rgb8_rgba8 GL_OES_stencil1 GL_OES_stencil4 " + "GL_OES_stencil8 GL_OES_EGL_image "; + const GLchar *pack_depth_stencil = "GL_OES_packed_depth_stencil "; + const GLchar *texture_npot = "GL_OES_texture_npot "; + const GLchar *texture_filter_anisotropic = "GL_EXT_texture_filter_anisotropic "; + const GLchar *matrix_palette = "GL_OES_matrix_palette "; + + size_t len = strlen(default_ext); + GLchar *str; + + if (gles1_ctx->base.texture_npot) { + len += strlen(texture_npot); + } + + if (gles1_ctx->base.texture_filter_anisotropic) { + len += strlen(texture_filter_anisotropic); + } + + if (gles1_ctx->framebuffer_object) { + len += strlen(framebuffer_object_ext); + + if (gles1_ctx->base.pack_depth_stencil) { + len += strlen(pack_depth_stencil); + } + } + + if (gles1_ctx->matrix_palette) { + len += strlen(matrix_palette); + } + + str = g_malloc0(len + 1); + + g_strlcpy(str, default_ext, len + 1); + + if (gles1_ctx->base.texture_npot) { + g_strlcat(str, texture_npot, len + 1); + } + + if (gles1_ctx->base.texture_filter_anisotropic) { + g_strlcat(str, texture_filter_anisotropic, len + 1); + } + + if (gles1_ctx->framebuffer_object) { + g_strlcat(str, framebuffer_object_ext, len + 1); + + if (gles1_ctx->base.pack_depth_stencil) { + g_strlcat(str, pack_depth_stencil, len + 1); + } + } + + if (gles1_ctx->matrix_palette) { + g_strlcat(str, matrix_palette, len + 1); + } + + return str; + } + + static void yagl_gles1_draw_arrays_psize(struct yagl_gles_context *ctx, + GLint first, + GLsizei count) + { + struct yagl_gles1_driver *gles1_driver = ((YaglGles1Context *)ctx)->driver; + struct yagl_gles_array *parray = &ctx->arrays[YAGL_GLES1_ARRAY_POINTSIZE]; + unsigned i = 0; + const unsigned stride = parray->stride; + GLsizei points_cnt; + GLint arr_offset; + void *next_psize_p; + GLfloat cur_psize; + + if (parray->vbo) { + next_psize_p = parray->vbo->data + parray->offset + first * stride; + } else { + next_psize_p = parray->host_data + first * stride; + } + + while (i < count) { + points_cnt = 0; + arr_offset = i; + cur_psize = *((GLfloat *)next_psize_p); + + do { + ++points_cnt; + ++i; + next_psize_p += stride; + } while (i < count && cur_psize == *((GLfloat *)next_psize_p)); + + gles1_driver->PointSize(cur_psize); + + ctx->driver->DrawArrays(GL_POINTS, first + arr_offset, points_cnt); + } + } + + static inline void *yagl_get_next_psize_p(struct yagl_gles_buffer *ebo, + struct yagl_gles_array *parray, + GLenum type, + unsigned idx, + const GLvoid *indices) + { + unsigned idx_val; + + if (ebo) { + if (type == GL_UNSIGNED_SHORT) { + idx_val = ((uint16_t *)(ebo->data + (uintptr_t)indices))[idx]; + } else { + idx_val = ((uint8_t *)(ebo->data + (uintptr_t)indices))[idx]; + } + } else { + if (type == GL_UNSIGNED_SHORT) { + idx_val = ((uint16_t *)indices)[idx]; + } else { + idx_val = ((uint8_t *)indices)[idx]; + } + } + + if (parray->vbo) { + return parray->vbo->data + parray->offset + idx_val * parray->stride; + } else { + return parray->host_data + idx_val * parray->stride; + } + } + + static void yagl_gles1_draw_elem_psize(struct yagl_gles_context *ctx, + GLsizei count, + GLenum type, + const GLvoid *indices) + { + struct yagl_gles1_driver *gles1_driver = ((YaglGles1Context *)ctx)->driver; + struct yagl_gles_array *parray = &ctx->arrays[YAGL_GLES1_ARRAY_POINTSIZE]; + unsigned i = 0, el_size; + GLsizei points_cnt; + GLint arr_offset; + GLfloat cur_psize; + void *next_psize_p; + + switch (type) { + case GL_UNSIGNED_BYTE: + el_size = 1; + break; + case GL_UNSIGNED_SHORT: + el_size = 2; + break; + default: + el_size = 0; + break; + } + + assert(el_size > 0); + + next_psize_p = yagl_get_next_psize_p(ctx->ebo, parray, type, i, indices); + + while (i < count) { + points_cnt = 0; + arr_offset = i; + cur_psize = *((GLfloat *)next_psize_p); + + do { + ++points_cnt; + ++i; + next_psize_p = yagl_get_next_psize_p(ctx->ebo, + parray, + type, + i, + indices); + } while (i < count && cur_psize == *((GLfloat *)next_psize_p)); + + gles1_driver->PointSize(cur_psize); + + ctx->driver->DrawElements(GL_POINTS, + points_cnt, + type, + indices + arr_offset * el_size); + } + } + + static void yagl_gles1_context_draw_arrays(struct yagl_gles_context *ctx, + GLenum mode, + GLint first, + GLsizei count) + { + if (!ctx->arrays[YAGL_GLES1_ARRAY_VERTEX].enabled) { + return; + } + + if (mode == GL_POINTS && ctx->arrays[YAGL_GLES1_ARRAY_POINTSIZE].enabled) { + yagl_gles1_draw_arrays_psize(ctx, first, count); + } else { + ctx->driver->DrawArrays(mode, first, count); + } + } + + static void yagl_gles1_context_draw_elements(struct yagl_gles_context *ctx, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices) + { + if (!ctx->arrays[YAGL_GLES1_ARRAY_VERTEX].enabled) { + return; + } + + if (mode == GL_POINTS && ctx->arrays[YAGL_GLES1_ARRAY_POINTSIZE].enabled) { + yagl_gles1_draw_elem_psize(ctx, count, type, indices); + } else { + ctx->driver->DrawElements(mode, count, type, indices); + } + } + + typedef struct YaglGles1PalFmtDesc { + GLenum uncomp_format; + GLenum pixel_type; + unsigned pixel_size; + unsigned bits_per_index; + } YaglGles1PalFmtDesc; + + static inline int yagl_log2(int val) + { + int ret = 0; + + if (val > 0) { + while (val >>= 1) { + ret++; + } + } + + return ret; + } + + static inline bool yagl_gles1_tex_dims_valid(GLsizei width, + GLsizei height, + int max_size) + { + if (width < 0 || height < 0 || width > max_size || height > max_size || + (width & (width - 1)) || (height & (height - 1))) { + return false; + } + + return true; + } + + static void yagl_gles1_cpal_format_get_descr(GLenum format, + YaglGles1PalFmtDesc *desc) + { + assert(format >= GL_PALETTE4_RGB8_OES && format <= GL_PALETTE8_RGB5_A1_OES); + + switch (format) { + case GL_PALETTE4_RGB8_OES: + desc->uncomp_format = GL_RGB; + desc->bits_per_index = 4; + desc->pixel_type = GL_UNSIGNED_BYTE; + desc->pixel_size = 3; + break; + case GL_PALETTE4_RGBA8_OES: + desc->uncomp_format = GL_RGBA; + desc->bits_per_index = 4; + desc->pixel_type = GL_UNSIGNED_BYTE; + desc->pixel_size = 4; + break; + case GL_PALETTE4_R5_G6_B5_OES: + desc->uncomp_format = GL_RGB; + desc->bits_per_index = 4; + desc->pixel_type = GL_UNSIGNED_SHORT_5_6_5; + desc->pixel_size = 2; + break; + case GL_PALETTE4_RGBA4_OES: + desc->uncomp_format = GL_RGBA; + desc->bits_per_index = 4; + desc->pixel_type = GL_UNSIGNED_SHORT_4_4_4_4; + desc->pixel_size = 2; + break; + case GL_PALETTE4_RGB5_A1_OES: + desc->uncomp_format = GL_RGBA; + desc->bits_per_index = 4; + desc->pixel_type = GL_UNSIGNED_SHORT_5_5_5_1; + desc->pixel_size = 2; + break; + case GL_PALETTE8_RGB8_OES: + desc->uncomp_format = GL_RGB; + desc->bits_per_index = 8; + desc->pixel_type = GL_UNSIGNED_BYTE; + desc->pixel_size = 3; + break; + case GL_PALETTE8_RGBA8_OES: + desc->uncomp_format = GL_RGBA; + desc->bits_per_index = 8; + desc->pixel_type = GL_UNSIGNED_BYTE; + desc->pixel_size = 4; + break; + case GL_PALETTE8_R5_G6_B5_OES: + desc->uncomp_format = GL_RGB; + desc->bits_per_index = 8; + desc->pixel_type = GL_UNSIGNED_SHORT_5_6_5; + desc->pixel_size = 2; + break; + case GL_PALETTE8_RGBA4_OES: + desc->uncomp_format = GL_RGBA; + desc->bits_per_index = 8; + desc->pixel_type = GL_UNSIGNED_SHORT_4_4_4_4; + desc->pixel_size = 2; + break; + case GL_PALETTE8_RGB5_A1_OES: + desc->uncomp_format = GL_RGBA; + desc->bits_per_index = 8; + desc->pixel_type = GL_UNSIGNED_SHORT_5_5_5_1; + desc->pixel_size = 2; + break; + } + } + + static GLsizei yagl_gles1_cpal_tex_size(YaglGles1PalFmtDesc *fmt_desc, + unsigned width, + unsigned height, + unsigned max_level) + { + GLsizei size; + + /* Palette table size */ + size = (1 << fmt_desc->bits_per_index) * fmt_desc->pixel_size; + + /* Texture palette indices array size for each miplevel */ + do { + if (fmt_desc->bits_per_index == 4) { + size += (width * height + 1) / 2; + } else { + size += width * height; + } + + width >>= 1; + if (width == 0) { + width = 1; + } + + height >>= 1; + if (height == 0) { + height = 1; + } + } while (max_level--); + + return size; + } + + static void yagl_gles1_cpal_tex_uncomp_and_apply(struct yagl_gles_context *ctx, + YaglGles1PalFmtDesc *fmt_desc, + unsigned max_level, + unsigned width, + unsigned height, + const GLvoid *data) + { + uint8_t *tex_img_data = NULL; + uint8_t *img; + const uint8_t *indices; + unsigned cur_level, i; + unsigned num_of_texels = width * height; + GLint saved_alignment; + + if (!data) { + for (cur_level = 0; cur_level <= max_level; ++cur_level) { + ctx->driver->TexImage2D(GL_TEXTURE_2D, + cur_level, + fmt_desc->uncomp_format, + width, height, + 0, + fmt_desc->uncomp_format, + fmt_desc->pixel_type, + NULL); + width >>= 1; + height >>= 1; + + if (width == 0) { + width = 1; + } + + if (height == 0) { + height = 1; + } + } + + return; + } + + /* Jump over palette data to first image data */ + indices = data + (1 << fmt_desc->bits_per_index) * fmt_desc->pixel_size; + + /* 0 level image is the largest */ + tex_img_data = g_malloc(num_of_texels * fmt_desc->pixel_size); + + /* We will pass tightly packed data to glTexImage2D */ + ctx->driver->GetIntegerv(GL_UNPACK_ALIGNMENT, &saved_alignment); + + if (saved_alignment != 1) { + ctx->driver->PixelStorei(GL_UNPACK_ALIGNMENT, 1); + } + + for (cur_level = 0; cur_level <= max_level; ++cur_level) { + img = tex_img_data; + + if (fmt_desc->bits_per_index == 4) { + unsigned cur_idx; + + for (i = 0; i < num_of_texels; ++i) { + if ((i % 2) == 0) { + cur_idx = indices[i / 2] >> 4; + } else { + cur_idx = indices[i / 2] & 0xf; + } + + memcpy(img, + data + cur_idx * fmt_desc->pixel_size, + fmt_desc->pixel_size); + + img += fmt_desc->pixel_size; + } + + indices += (num_of_texels + 1) / 2; + } else { + for (i = 0; i < num_of_texels; ++i) { + memcpy(img, + data + indices[i] * fmt_desc->pixel_size, + fmt_desc->pixel_size); + img += fmt_desc->pixel_size; + } + + indices += num_of_texels; + } + + ctx->driver->TexImage2D(GL_TEXTURE_2D, + cur_level, + fmt_desc->uncomp_format, + width, height, + 0, + fmt_desc->uncomp_format, + fmt_desc->pixel_type, + tex_img_data); + + width >>= 1; + if (width == 0) { + width = 1; + } + + height >>= 1; + if (height == 0) { + height = 1; + } + + num_of_texels = width * height; + } + + g_free(tex_img_data); + + if (saved_alignment != 1) { + ctx->driver->PixelStorei(GL_UNPACK_ALIGNMENT, saved_alignment); + } + } + + static GLenum yagl_gles1_compressed_tex_image(struct yagl_gles_context *ctx, + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const GLvoid *data) + { + const int max_tex_size = ((YaglGles1Context *)ctx)->max_tex_size; + YaglGles1PalFmtDesc fmt_desc; + + if (target != GL_TEXTURE_2D) { + return GL_INVALID_ENUM; + } + + switch (internalformat) { + case GL_PALETTE4_RGB8_OES ... GL_PALETTE8_RGB5_A1_OES: + yagl_gles1_cpal_format_get_descr(internalformat, &fmt_desc); + + if ((level > 0) || (-level > yagl_log2(max_tex_size)) || + !yagl_gles1_tex_dims_valid(width, height, max_tex_size) || + border != 0 || (imageSize != + yagl_gles1_cpal_tex_size(&fmt_desc, width, height, -level))) { + return GL_INVALID_VALUE; + } + + yagl_gles1_cpal_tex_uncomp_and_apply(ctx, + &fmt_desc, + -level, + width, + height, + data); + break; + default: + return GL_INVALID_ENUM; + } + + return GL_NO_ERROR; + } + + YaglGles1Context *yagl_gles1_context_create(struct yagl_sharegroup *sg, + struct yagl_gles1_driver *driver) + { + YaglGles1Context *gles1_ctx; + + YAGL_LOG_FUNC_ENTER(driver_ps->common->ps->id, + 0, + yagl_gles1_context_create, + NULL); + + gles1_ctx = g_new0(YaglGles1Context, 1); + + yagl_client_context_init(&gles1_ctx->base.base, yagl_client_api_gles1, sg); + + gles1_ctx->base.base.activate = &yagl_gles1_context_activate; + gles1_ctx->base.base.deactivate = &yagl_gles1_context_deactivate; + gles1_ctx->base.base.destroy = &yagl_gles1_context_destroy; + + yagl_gles_context_init(&gles1_ctx->base, &driver->base); + + gles1_ctx->base.get_param_count = &yagl_gles1_context_get_param_count; + gles1_ctx->base.get_booleanv = &yagl_gles1_context_get_booleanv; + gles1_ctx->base.get_integerv = &yagl_gles1_context_get_integerv; + gles1_ctx->base.get_floatv = &yagl_gles1_context_get_floatv; + gles1_ctx->base.get_extensions = &yagl_gles1_context_get_extensions; + gles1_ctx->base.draw_arrays = &yagl_gles1_context_draw_arrays; + gles1_ctx->base.draw_elements = &yagl_gles1_context_draw_elements; + gles1_ctx->base.compressed_tex_image = &yagl_gles1_compressed_tex_image; + gles1_ctx->base.is_enabled = &yagl_gles1_context_is_enabled; + + gles1_ctx->driver = driver; + gles1_ctx->prepared = false; + gles1_ctx->sg = sg; + + gles1_ctx->client_active_texture = 0; + gles1_ctx->max_clip_planes = 0; + gles1_ctx->max_lights = 0; + + YAGL_LOG_FUNC_EXIT("%p", gles1_ctx); + + return gles1_ctx; + } diff --cc hw/yagl_compiled_transfer.c index cc85c49,44c5a1d..d89062f --- a/hw/yagl_compiled_transfer.c +++ b/hw/yagl_compiled_transfer.c @@@ -3,17 -3,16 +3,16 @@@ #include "yagl_thread.h" #include "yagl_process.h" #include "yagl_log.h" --#include "cpu-all.h" ++#include "exec/cpu-all.h" #define YAGL_TARGET_PAGE_VA(addr) ((addr) & ~(TARGET_PAGE_SIZE - 1)) #define YAGL_TARGET_PAGE_OFFSET(addr) ((addr) & (TARGET_PAGE_SIZE - 1)) - static target_phys_addr_t yagl_pa(struct yagl_thread_state *ts, - target_ulong va) -static target_phys_addr_t yagl_pa(target_ulong va) ++static hwaddr yagl_pa(target_ulong va) { -- target_phys_addr_t ret = - cpu_get_phys_page_debug(ts->current_env, va); ++ hwaddr ret = + cpu_get_phys_page_debug(cur_ts->current_env, va); if (ret == -1) { return 0; @@@ -45,7 -42,7 +42,7 @@@ struct yagl_compiled_transfe while (len) { target_ulong start_page_va = YAGL_TARGET_PAGE_VA(cur_va); - target_phys_addr_t start_page_pa = yagl_pa(ts, start_page_va); - target_phys_addr_t start_page_pa = yagl_pa(start_page_va); ++ hwaddr start_page_pa = yagl_pa(start_page_va); target_ulong end_page_va; struct yagl_compiled_transfer_section section; @@@ -58,7 -55,7 +55,7 @@@ while (end_page_va < last_page_va) { target_ulong next_page_va = end_page_va + TARGET_PAGE_SIZE; - target_phys_addr_t next_page_pa = yagl_pa(ts, next_page_va); - target_phys_addr_t next_page_pa = yagl_pa(next_page_va); ++ hwaddr next_page_pa = yagl_pa(next_page_va); if (!next_page_pa) { YAGL_LOG_ERROR("yagl_pa of va 0x%X failed", (uint32_t)next_page_va); diff --cc hw/yagl_compiled_transfer.h index 0c67924,1f7b2fc..dca6400 --- a/hw/yagl_compiled_transfer.h +++ b/hw/yagl_compiled_transfer.h @@@ -9,7 -9,7 +9,7 @@@ struct yagl_compiled_transfer_sectio * For 'cpy_physical_memory_unmap'. */ void *map_base; -- target_phys_addr_t map_len; ++ hwaddr map_len; /* * For actual I/O. diff --cc hw/yagl_device.c index a1723e7,8aeacf5..8bbb5ae --- a/hw/yagl_device.c +++ b/hw/yagl_device.c @@@ -3,9 -3,22 +3,22 @@@ #include "yagl_handle_gen.h" #include "yagl_marshal.h" #include "yagl_stats.h" - #include "cpu-all.h" - #include "hw.h" - #include "pci.h" + #include "yagl_process.h" + #include "yagl_thread.h" + #include "yagl_egl_driver.h" + #include "yagl_drivers/gles1_ogl/yagl_gles1_ogl.h" + #include "yagl_drivers/gles2_ogl/yagl_gles2_ogl.h" + #include "yagl_drivers/gles1_onscreen/yagl_gles1_onscreen.h" + #include "yagl_drivers/gles2_onscreen/yagl_gles2_onscreen.h" + #include "yagl_backends/egl_offscreen/yagl_egl_offscreen.h" + #include "yagl_backends/egl_onscreen/yagl_egl_onscreen.h" -#include "cpu-all.h" -#include "hw.h" -#include "pci.h" ++#include "exec/cpu-all.h" ++#include "hw/hw.h" ++#include "hw/pci/pci.h" + #include + #include "winsys.h" + #include "yagl_gles1_driver.h" + #include "yagl_gles2_driver.h" #define PCI_VENDOR_ID_YAGL 0x19B1 #define PCI_DEVICE_ID_YAGL 0x1010 @@@ -42,17 -57,17 +57,17 @@@ typedef struct YaGLStat static void yagl_device_operate(YaGLState *s, int user_index, -- target_phys_addr_t buff_pa) ++ hwaddr buff_pa) { yagl_pid target_pid; yagl_tid target_tid; -- target_phys_addr_t buff_len = YAGL_MARSHAL_SIZE; ++ hwaddr buff_len = YAGL_MARSHAL_SIZE; uint8_t *buff = NULL, *tmp = NULL; - YAGL_LOG_FUNC_ENTER_NPT(yagl_device_operate, - "user_index = %d, buff_ptr = 0x%X", - user_index, - (uint32_t)buff_pa); + YAGL_LOG_FUNC_ENTER(yagl_device_operate, + "user_index = %d, buff_ptr = 0x%X", + user_index, + (uint32_t)buff_pa); if (buff_pa && s->users[user_index].buff) { YAGL_LOG_CRITICAL("user %d is already activated", user_index); @@@ -160,13 -175,13 +175,13 @@@ out YAGL_LOG_FUNC_EXIT(NULL); } --static uint64_t yagl_device_read(void *opaque, target_phys_addr_t offset, ++static uint64_t yagl_device_read(void *opaque, hwaddr offset, unsigned size) { return 0; } --static void yagl_device_write(void *opaque, target_phys_addr_t offset, ++static void yagl_device_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { YaGLState *s = (YaGLState*)opaque; diff --cc hw/yagl_event.h index 6771d90,6771d90..f6a0eb9 --- a/hw/yagl_event.h +++ b/hw/yagl_event.h @@@ -2,7 -2,7 +2,7 @@@ #define _QEMU_YAGL_EVENT_H #include "yagl_types.h" --#include "qemu-thread.h" ++#include "qemu/thread.h" struct yagl_event { diff --cc hw/yagl_marshal.h index 44eafb8,e5ae7b1..859b99c --- a/hw/yagl_marshal.h +++ b/hw/yagl_marshal.h @@@ -2,7 -2,7 +2,7 @@@ #define _QEMU_YAGL_MARSHAL_H #include "yagl_types.h" --#include "exec-memory.h" ++#include "exec/memory.h" /* * All marshalling/unmarshalling must be done with 8-byte alignment, diff --cc hw/yagl_mem_transfer.c index 48d5548,8a957f3..21518f8 --- a/hw/yagl_mem_transfer.c +++ b/hw/yagl_mem_transfer.c @@@ -2,10 -2,9 +2,9 @@@ #include "yagl_process.h" #include "yagl_thread.h" #include "yagl_log.h" --#include "cpu-all.h" ++#include "exec/cpu-all.h" - struct yagl_mem_transfer - *yagl_mem_transfer_create(struct yagl_thread_state *ts) + struct yagl_mem_transfer *yagl_mem_transfer_create(void) { struct yagl_mem_transfer *mt; @@@ -28,12 -25,10 +25,10 @@@ bool yagl_mem_prepare(struct yagl_mem_t { bool res = true; int l; -- target_phys_addr_t page_pa; ++ hwaddr page_pa; target_ulong page_va; - YAGL_LOG_FUNC_ENTER_TS(mt->ts, yagl_mem_prepare, "va = 0x%X, len = %d", (uint32_t)va, len); - - assert(mt->ts->current_env); + YAGL_LOG_FUNC_ENTER(yagl_mem_prepare, "va = 0x%X, len = %d", (uint32_t)va, len); if (len >= 0) { int max_pages = ((len + TARGET_PAGE_SIZE - 1) / TARGET_PAGE_SIZE) + 1; diff --cc hw/yagl_mem_transfer.h index 2b2c7ab,e29a872..bdcdab8 --- a/hw/yagl_mem_transfer.h +++ b/hw/yagl_mem_transfer.h @@@ -5,9 -5,7 +5,7 @@@ struct yagl_mem_transfer { - struct yagl_thread_state *ts; - -- target_phys_addr_t *pages; ++ hwaddr *pages; int max_pages; target_ulong va; diff --cc hw/yagl_process.c index d51aacf,38629bf7..6fc526c --- a/hw/yagl_process.c +++ b/hw/yagl_process.c @@@ -1,11 -1,9 +1,9 @@@ #include "yagl_process.h" #include "yagl_thread.h" #include "yagl_server.h" - #include "yagl_egl_driver.h" - #include "yagl_api.h" #include "yagl_log.h" #include "yagl_stats.h" --#include "kvm.h" ++#include "sysemu/kvm.h" struct yagl_process_state *yagl_process_state_create(struct yagl_server_state *ss, diff --cc hw/yagl_process.h index fd6e875,fd6e875..95033f1 --- a/hw/yagl_process.h +++ b/hw/yagl_process.h @@@ -2,7 -2,7 +2,7 @@@ #define _QEMU_YAGL_PROCESS_H #include "yagl_types.h" --#include "qemu-queue.h" ++#include "qemu/queue.h" struct yagl_server_state; struct yagl_thread_state; diff --cc hw/yagl_resource.h index ba20ee6,ba20ee6..2986b1e --- a/hw/yagl_resource.h +++ b/hw/yagl_resource.h @@@ -3,7 -3,7 +3,7 @@@ #include "yagl_types.h" #include "yagl_ref.h" --#include "qemu-queue.h" ++#include "qemu/queue.h" struct yagl_resource { diff --cc hw/yagl_resource_list.h index c050c8c,c050c8c..76ead76 --- a/hw/yagl_resource_list.h +++ b/hw/yagl_resource_list.h @@@ -2,7 -2,7 +2,7 @@@ #define _QEMU_YAGL_RESOURCE_LIST_H #include "yagl_types.h" --#include "qemu-queue.h" ++#include "qemu/queue.h" /* * reference counted resource management. diff --cc hw/yagl_server.h index 3fc11d4,23106a0..25204e8 --- a/hw/yagl_server.h +++ b/hw/yagl_server.h @@@ -2,7 -2,7 +2,7 @@@ #define _QEMU_YAGL_SERVER_H #include "yagl_types.h" --#include "qemu-queue.h" ++#include "qemu/queue.h" struct yagl_api; struct yagl_process_state; diff --cc hw/yagl_thread.c index 0b27c34,8e6a9ac..2efb266 --- a/hw/yagl_thread.c +++ b/hw/yagl_thread.c @@@ -6,8 -6,10 +6,10 @@@ #include "yagl_marshal.h" #include "yagl_stats.h" #include "yagl_mem_transfer.h" --#include "kvm.h" --#include "hax.h" ++#include "sysemu/kvm.h" ++#include "sysemu/hax.h" + + YAGL_DEFINE_TLS(struct yagl_thread_state*, cur_ts); #ifdef CONFIG_KVM static __inline void yagl_cpu_synchronize_state(struct yagl_process_state *ps) diff --cc hw/yagl_thread.h index db59552,ecfbd9a..7938c8b --- a/hw/yagl_thread.h +++ b/hw/yagl_thread.h @@@ -3,8 -3,9 +3,9 @@@ #include "yagl_types.h" #include "yagl_event.h" - #include "qemu-queue.h" - #include "qemu-thread.h" + #include "yagl_tls.h" -#include "qemu-queue.h" -#include "qemu-thread.h" ++#include "qemu/queue.h" ++#include "qemu/thread.h" struct yagl_process_state; struct yagl_mem_transfer; diff --cc tizen/emulator_configure.sh index 9840f51,696d206..0befdb5 --- a/tizen/emulator_configure.sh +++ b/tizen/emulator_configure.sh @@@ -90,10 -114,12 +114,13 @@@ set_target() if [ -z "$YAGL_EN" ] && [ "$targetos" != "Darwin" ] ; then yagl_enable yes fi + if [ -z "$VIGS_EN" ] && [ "$targetos" != "Darwin" ] ; then + vigs_enable yes + fi ;; all) - EMUL_TARGET_LIST="i386-softmmu,arm-softmmu" +# EMUL_TARGET_LIST="i386-softmmu,arm-softmmu" + EMUL_TARGET_LIST="i386-softmmu" if [ -z "$VIRTIOGL_EN" ] ; then virtgl_enable yes fi diff --cc tizen/src/hw/maru_board.c index bdc60dd,13c00b7..d5feb2f --- a/tizen/src/hw/maru_board.c +++ b/tizen/src/hw/maru_board.c @@@ -69,11 -66,21 +69,20 @@@ #include "maru_common.h" #include "guest_debug.h" #include "maru_pm.h" + #if defined(__linux__) + #include + #endif + #include "vigs_device.h" + #include "../tizen/src/hw/maru_brightness.h" + extern int enable_yagl; + extern const char *yagl_backend; + extern int enable_vigs; + extern const char *vigs_backend; -int codec_init(PCIBus *bus); - - #define MAX_IDE_BUS 2 +int codec_init(PCIBus *bus); + static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 }; static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 }; static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; @@@ -116,15 -185,19 +125,25 @@@ static void maru_x86_machine_init(Memor MemoryRegion *ram_memory; MemoryRegion *pci_memory; MemoryRegion *rom_memory; + DeviceState *icc_bridge; void *fw_cfg = NULL; + #if defined(__linux__) + Display *display = XOpenDisplay(0); + if (!display) { + fprintf(stderr, "Cannot open X display\n"); + exit(1); + } + #else + void *display = NULL; + #endif + struct winsys_interface *vigs_wsi = NULL; - pc_cpus_init(cpu_model); + icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); + object_property_add_child(qdev_get_machine(), "icc-bridge", + OBJECT(icc_bridge), NULL); + + pc_cpus_init(cpu_model, icc_bridge); + pc_acpi_init("acpi-dsdt.aml"); if (kvmclock_enabled) { kvmclock_create(); @@@ -271,16 -354,34 +290,35 @@@ if (pci_enabled) { codec_init(pci_bus); } + + if (enable_vigs) { + pci_maru_brightness_init(pci_bus); + PCIDevice *pci_dev = pci_create(pci_bus, -1, "vigs"); + qdev_prop_set_ptr(&pci_dev->qdev, "display", display); + qdev_init_nofail(&pci_dev->qdev); + vigs_wsi = DO_UPCAST(VIGSDevice, pci_dev, pci_dev)->wsi; + } + + if (enable_yagl) { + PCIDevice *pci_dev = pci_create(pci_bus, -1, "yagl"); + qdev_prop_set_ptr(&pci_dev->qdev, "display", display); + if (vigs_wsi && + (strcmp(yagl_backend, "vigs") == 0) && + (strcmp(vigs_backend, "gl") == 0)) { + qdev_prop_set_ptr(&pci_dev->qdev, "winsys_gl_interface", vigs_wsi); + } + qdev_init_nofail(&pci_dev->qdev); + } } -static void maru_x86_board_init(ram_addr_t ram_size, - const char *boot_device, - const char *kernel_filename, - const char *kernel_cmdline, - const char *initrd_filename, - const char *cpu_model) +static void maru_x86_board_init(QEMUMachineInitArgs *args) { + ram_addr_t ram_size = args->ram_size; + const char *cpu_model = args->cpu_model; + const char *kernel_filename = args->kernel_filename; + const char *kernel_cmdline = args->kernel_cmdline; + const char *initrd_filename = args->initrd_filename; + const char *boot_device = args->boot_device; maru_x86_machine_init(get_system_memory(), get_system_io(), ram_size, boot_device, diff --cc vl.c index 7597c60,371bf8f..f874408 --- a/vl.c +++ b/vl.c @@@ -204,10 -201,12 +204,13 @@@ int skin_disabled = 0 //virtio-gl extern int enable_gl; extern int enable_yagl; + const char *yagl_backend = NULL; + int enable_vigs = 0; + char *vigs_backend = NULL; #endif -static const char *data_dir; +static const char *data_dir[16]; +static int data_dir_idx; const char *bios_name = NULL; enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB; DisplayType display_type = DT_DEFAULT; @@@ -261,12 -260,10 +264,11 @@@ int ctrl_grab = 0 unsigned int nb_prom_envs = 0; const char *prom_envs[MAX_PROM_ENVS]; int boot_menu; +bool boot_strict; uint8_t *boot_splash_filedata; -int boot_splash_filedata_size; +size_t boot_splash_filedata_size; uint8_t qemu_extra_params_fw[2]; - typedef struct FWBootEntry FWBootEntry; struct FWBootEntry {