summaryrefslogtreecommitdiffstats
path: root/src/gallium/winsys/sw/dri/dri_sw_winsys.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys/sw/dri/dri_sw_winsys.c')
-rw-r--r--src/gallium/winsys/sw/dri/dri_sw_winsys.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
index 94d5092..ea1fe58 100644
--- a/src/gallium/winsys/sw/dri/dri_sw_winsys.c
+++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
@@ -34,8 +34,14 @@
#include "util/u_memory.h"
#include "state_tracker/sw_winsys.h"
+#include "state_tracker/drm_driver.h"
#include "dri_sw_winsys.h"
+#ifdef HAVE_ANDROID_PLATFORM
+#include <system/graphics.h>
+#include <system/window.h>
+#include <hardware/gralloc.h>
+#endif
struct dri_sw_displaytarget
{
@@ -45,11 +51,31 @@ struct dri_sw_displaytarget
unsigned stride;
unsigned map_flags;
+#ifdef HAVE_ANDROID_PLATFORM
+ struct ANativeWindowBuffer *androidBuffer;
+#endif
void *data;
void *mapped;
const void *front_private;
};
+#ifdef HAVE_ANDROID_PLATFORM
+const struct gralloc_module_t* get_gralloc()
+{
+ static const struct gralloc_module_t* gr_module = NULL;
+ const hw_module_t *mod;
+ int err;
+
+ if (!gr_module) {
+ err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod);
+ if (!err) {
+ gr_module = (gralloc_module_t *) mod;
+ }
+ }
+ return gr_module;
+}
+#endif
+
struct dri_sw_winsys
{
struct sw_winsys base;
@@ -125,6 +151,12 @@ dri_sw_displaytarget_destroy(struct sw_winsys *ws,
{
struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+#ifdef HAVE_ANDROID_PLATFORM
+ if (dri_sw_dt->androidBuffer) {
+ dri_sw_dt->androidBuffer->common.decRef(&dri_sw_dt->androidBuffer->common);
+ }
+#endif
+
align_free(dri_sw_dt->data);
FREE(dri_sw_dt);
@@ -136,6 +168,17 @@ dri_sw_displaytarget_map(struct sw_winsys *ws,
unsigned flags)
{
struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+#ifdef HAVE_ANDROID_PLATFORM
+ if (dri_sw_dt->androidBuffer) {
+ if (!get_gralloc()->lock(get_gralloc(), dri_sw_dt->androidBuffer->handle,
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ 0, 0, dri_sw_dt->androidBuffer->width, dri_sw_dt->androidBuffer->height,
+ (void**)&dri_sw_dt->mapped)) {
+ dri_sw_dt->map_flags = flags;
+ return dri_sw_dt->mapped;
+ }
+ }
+#endif
dri_sw_dt->mapped = dri_sw_dt->data;
if (dri_sw_dt->front_private && (flags & PIPE_TRANSFER_READ)) {
@@ -156,6 +199,11 @@ dri_sw_displaytarget_unmap(struct sw_winsys *ws,
dri_sw_ws->lf->put_image2((void *)dri_sw_dt->front_private, dri_sw_dt->data, 0, 0, dri_sw_dt->width, dri_sw_dt->height, dri_sw_dt->stride);
}
dri_sw_dt->map_flags = 0;
+#ifdef HAVE_ANDROID_PLATFORM
+ if (dri_sw_dt->androidBuffer) {
+ get_gralloc()->unlock(get_gralloc(), dri_sw_dt->androidBuffer->handle);
+ }
+#endif
dri_sw_dt->mapped = NULL;
}
@@ -165,6 +213,22 @@ dri_sw_displaytarget_from_handle(struct sw_winsys *winsys,
struct winsys_handle *whandle,
unsigned *stride)
{
+#ifdef HAVE_ANDROID_PLATFORM
+ struct dri_sw_displaytarget *dri_sw_dt;
+
+ if (whandle->type == DRM_API_HANDLE_TYPE_BUFFER) {
+ dri_sw_dt = CALLOC_STRUCT(dri_sw_displaytarget);
+ dri_sw_dt->width = templ->width0;
+ dri_sw_dt->height = templ->height0;
+ dri_sw_dt->androidBuffer = whandle->externalBuffer;
+ dri_sw_dt->stride = whandle->stride;
+
+ dri_sw_dt->androidBuffer->common.incRef(&dri_sw_dt->androidBuffer->common);
+ *stride = dri_sw_dt->stride;
+
+ return dri_sw_dt;
+ }
+#endif
assert(0);
return NULL;
}