winsys/android: new SW winsys for Android
authorChia-I Wu <olvaffe@gmail.com>
Thu, 18 Aug 2011 02:17:10 +0000 (10:17 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Sat, 20 Aug 2011 18:01:48 +0000 (02:01 +0800)
On Android, color buffers are passed between server and clients as
opaque buffer_handle_t.  This winsys makes use of gralloc, which
provides a generic way to map and unmap buffer_handle_t for CPU access.

src/gallium/winsys/sw/android/android_sw_winsys.cpp [new file with mode: 0644]
src/gallium/winsys/sw/android/android_sw_winsys.h [new file with mode: 0644]

diff --git a/src/gallium/winsys/sw/android/android_sw_winsys.cpp b/src/gallium/winsys/sw/android/android_sw_winsys.cpp
new file mode 100644 (file)
index 0000000..49d8aa9
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.12
+ *
+ * Copyright (C) 2010-2011 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+#include "util/u_memory.h"
+#include "util/u_format.h"
+#include "state_tracker/sw_winsys.h"
+
+#include <ui/PixelFormat.h>
+#include <private/ui/sw_gralloc_handle.h>
+#include <hardware/gralloc.h>
+
+#include "android_sw_winsys.h"
+
+struct android_sw_winsys
+{
+   struct sw_winsys base;
+
+   const gralloc_module_t *grmod;
+};
+
+struct android_sw_displaytarget
+{
+   buffer_handle_t handle;
+   int stride;
+   int width, height;
+   int usage; /* gralloc usage */
+
+   void *mapped;
+};
+
+static INLINE struct android_sw_winsys *
+android_sw_winsys(struct sw_winsys *ws)
+{
+   return (struct android_sw_winsys *) ws;
+}
+
+static INLINE struct android_sw_displaytarget *
+android_sw_displaytarget(struct sw_displaytarget *dt)
+{
+   return (struct android_sw_displaytarget *) dt;
+}
+
+namespace android {
+
+static void
+android_displaytarget_display(struct sw_winsys *ws,
+                              struct sw_displaytarget *dt,
+                              void *context_private)
+{
+}
+
+static struct sw_displaytarget *
+android_displaytarget_create(struct sw_winsys *ws,
+                             unsigned tex_usage,
+                             enum pipe_format format,
+                             unsigned width, unsigned height,
+                             unsigned alignment,
+                             unsigned *stride)
+{
+   return NULL;
+}
+
+static void
+android_displaytarget_destroy(struct sw_winsys *ws,
+                              struct sw_displaytarget *dt)
+{
+   struct android_sw_displaytarget *adt = android_sw_displaytarget(dt);
+
+   assert(!adt->mapped);
+   FREE(adt);
+}
+
+static void
+android_displaytarget_unmap(struct sw_winsys *ws,
+                            struct sw_displaytarget *dt)
+{
+   struct android_sw_winsys *droid = android_sw_winsys(ws);
+   struct android_sw_displaytarget *adt = android_sw_displaytarget(dt);
+
+   if (adt->mapped) {
+      if (sw_gralloc_handle_t::validate(adt->handle) >= 0) {
+         adt->mapped = NULL;
+      }
+      else {
+         droid->grmod->unlock(droid->grmod, adt->handle);
+         adt->mapped = NULL;
+      }
+   }
+}
+
+static void *
+android_displaytarget_map(struct sw_winsys *ws,
+                          struct sw_displaytarget *dt,
+                          unsigned flags)
+{
+   struct android_sw_winsys *droid = android_sw_winsys(ws);
+   struct android_sw_displaytarget *adt = android_sw_displaytarget(dt);
+
+   if (!adt->mapped) {
+      if (sw_gralloc_handle_t::validate(adt->handle) >= 0) {
+         const sw_gralloc_handle_t *swhandle =
+            reinterpret_cast<const sw_gralloc_handle_t *>(adt->handle);
+         adt->mapped = reinterpret_cast<void *>(swhandle->base);
+      }
+      else {
+         /* lock the buffer for CPU access */
+         droid->grmod->lock(droid->grmod, adt->handle,
+               adt->usage, 0, 0, adt->width, adt->height, &adt->mapped);
+      }
+   }
+
+   return adt->mapped;
+}
+
+static struct sw_displaytarget *
+android_displaytarget_from_handle(struct sw_winsys *ws,
+                                  const struct pipe_resource *templ,
+                                  struct winsys_handle *whandle,
+                                  unsigned *stride)
+{
+   struct android_winsys_handle *ahandle =
+      (struct android_winsys_handle *) whandle;
+   struct android_sw_displaytarget *adt;
+
+   adt = CALLOC_STRUCT(android_sw_displaytarget);
+   if (!adt)
+      return NULL;
+
+   adt->handle = ahandle->handle;
+   adt->stride = ahandle->stride;
+   adt->width = templ->width0;
+   adt->height = templ->height0;
+
+   if (templ->usage & PIPE_BIND_RENDER_TARGET)
+      adt->usage |= GRALLOC_USAGE_HW_RENDER;
+   if (templ->usage & PIPE_BIND_SAMPLER_VIEW)
+      adt->usage |= GRALLOC_USAGE_HW_TEXTURE;
+   if (templ->usage & PIPE_BIND_SCANOUT)
+      adt->usage |= GRALLOC_USAGE_HW_FB;
+
+   if (templ->usage & PIPE_BIND_TRANSFER_READ)
+      adt->usage |= GRALLOC_USAGE_SW_READ_OFTEN;
+   if (templ->usage & PIPE_BIND_TRANSFER_WRITE)
+      adt->usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
+
+   if (stride)
+      *stride = adt->stride;
+
+   return reinterpret_cast<struct sw_displaytarget *>(adt);
+}
+
+static boolean
+android_displaytarget_get_handle(struct sw_winsys *ws,
+                                 struct sw_displaytarget *dt,
+                                 struct winsys_handle *whandle)
+{
+   return FALSE;
+}
+
+static boolean
+android_is_displaytarget_format_supported(struct sw_winsys *ws,
+                                          unsigned tex_usage,
+                                          enum pipe_format format)
+{
+   struct android_sw_winsys *droid = android_sw_winsys(ws);
+   int fmt;
+
+   switch (format) {
+   case PIPE_FORMAT_R8G8B8A8_UNORM:
+      fmt = PIXEL_FORMAT_RGBA_8888;
+      break;
+   case PIPE_FORMAT_R8G8B8X8_UNORM:
+      fmt = PIXEL_FORMAT_RGBX_8888;
+      break;
+   case PIPE_FORMAT_R8G8B8_UNORM:
+      fmt = PIXEL_FORMAT_RGB_888;
+      break;
+   case PIPE_FORMAT_B5G6R5_UNORM:
+      fmt = PIXEL_FORMAT_RGB_565;
+      break;
+   case PIPE_FORMAT_B8G8R8A8_UNORM:
+      fmt = PIXEL_FORMAT_BGRA_8888;
+      break;
+   case PIPE_FORMAT_A8_UNORM:
+      fmt = PIXEL_FORMAT_A_8;
+      break;
+   case PIPE_FORMAT_L8_UNORM:
+      fmt = PIXEL_FORMAT_L_8;
+      break;
+   case PIPE_FORMAT_L8A8_UNORM:
+      fmt = PIXEL_FORMAT_LA_88;
+      break;
+   default:
+      fmt = PIXEL_FORMAT_NONE;
+      break;
+   }
+
+   return (fmt != PIXEL_FORMAT_NONE);
+}
+
+static void
+android_destroy(struct sw_winsys *ws)
+{
+   struct android_sw_winsys *droid = android_sw_winsys(ws);
+
+   FREE(droid);
+}
+
+}; /* namespace android */
+
+using namespace android;
+
+struct sw_winsys *
+android_create_sw_winsys(void)
+{
+   struct android_sw_winsys *droid;
+   const hw_module_t *mod;
+
+   droid = CALLOC_STRUCT(android_sw_winsys);
+   if (!droid)
+      return NULL;
+
+   if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod)) {
+      FREE(droid);
+      return NULL;
+   }
+
+   droid->grmod = (const gralloc_module_t *) mod;
+
+   droid->base.destroy = android_destroy;
+   droid->base.is_displaytarget_format_supported =
+      android_is_displaytarget_format_supported;
+
+   droid->base.displaytarget_create = android_displaytarget_create;
+   droid->base.displaytarget_destroy = android_displaytarget_destroy;
+   droid->base.displaytarget_from_handle = android_displaytarget_from_handle;
+   droid->base.displaytarget_get_handle = android_displaytarget_get_handle;
+
+   droid->base.displaytarget_map = android_displaytarget_map;
+   droid->base.displaytarget_unmap = android_displaytarget_unmap;
+   droid->base.displaytarget_display = android_displaytarget_display;
+
+   return &droid->base;
+}
diff --git a/src/gallium/winsys/sw/android/android_sw_winsys.h b/src/gallium/winsys/sw/android/android_sw_winsys.h
new file mode 100644 (file)
index 0000000..79392dc
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.12
+ *
+ * Copyright (C) 2010-2011 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef ANDROID_SW_WINSYS
+#define ANDROID_SW_WINSYS
+
+#include <sys/cdefs.h>
+#include <hardware/gralloc.h>
+
+__BEGIN_DECLS
+
+struct sw_winsys;
+
+struct android_winsys_handle {
+   buffer_handle_t handle;
+   int stride;
+};
+
+struct sw_winsys *
+android_create_sw_winsys(void);
+
+__END_DECLS
+
+#endif /* ANDROID_SW_WINSYS */