Skip to content
This repository has been archived by the owner on Nov 26, 2022. It is now read-only.

Commit

Permalink
AndroidIA: Adds support for gralloc1.0.
Browse files Browse the repository at this point in the history
  • Loading branch information
munish-b authored and stephan-gh committed May 10, 2019
1 parent 9da1461 commit 50df97d
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 20 deletions.
4 changes: 4 additions & 0 deletions src/egl/Android.mk
Expand Up @@ -64,6 +64,10 @@ ifeq ($(BOARD_USES_DRM_GRALLOC),true)
LOCAL_SHARED_LIBRARIES += libgralloc_drm
endif

ifeq ($(strip $(BOARD_USES_GRALLOC1)),true)
LOCAL_CFLAGS += -DHAVE_GRALLOC1
endif

ifeq ($(filter $(MESA_ANDROID_MAJOR_VERSION), 4 5 6 7),)
LOCAL_SHARED_LIBRARIES += libnativewindow
endif
Expand Down
13 changes: 12 additions & 1 deletion src/egl/drivers/dri2/egl_dri2.h
Expand Up @@ -69,6 +69,10 @@ struct zwp_linux_dmabuf_v1;
#include <hardware/gralloc.h>
#endif /* HAVE_ANDROID_PLATFORM */

#ifdef HAVE_GRALLOC1
#include <hardware/gralloc1.h>
#endif

#include "eglconfig.h"
#include "eglcontext.h"
#include "egldevice.h"
Expand Down Expand Up @@ -238,7 +242,14 @@ struct dri2_egl_display
#endif

#ifdef HAVE_ANDROID_PLATFORM
const gralloc_module_t *gralloc;
const hw_module_t *gralloc;
uint16_t gralloc_version;
#ifdef HAVE_GRALLOC1
gralloc1_device_t *gralloc1_dvc;
GRALLOC1_PFN_LOCK_FLEX pfn_lockflex;
GRALLOC1_PFN_GET_FORMAT pfn_getFormat;
GRALLOC1_PFN_UNLOCK pfn_unlock;
#endif
#endif

bool is_render_node;
Expand Down
189 changes: 170 additions & 19 deletions src/egl/drivers/dri2/platform_android.c
Expand Up @@ -49,6 +49,8 @@

#define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1))

#define GRALLOC_DRM_GET_FORMAT 1

struct droid_yuv_format {
/* Lookup keys */
int native; /* HAL_PIXEL_FORMAT_ */
Expand All @@ -59,6 +61,14 @@ struct droid_yuv_format {
int fourcc; /* __DRI_IMAGE_FOURCC_ */
};

/* This enumeration can be deleted if Android defined it in
* system/core/include/system/graphics.h
*/
enum {
HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL = 0x100,
HAL_PIXEL_FORMAT_NV12 = 0x10F,
};

/* The following table is used to look up a DRI image FourCC based
* on native format and information contained in android_ycbcr struct. */
static const struct droid_yuv_format droid_yuv_formats[] = {
Expand All @@ -67,6 +77,8 @@ static const struct droid_yuv_format droid_yuv_formats[] = {
{ HAL_PIXEL_FORMAT_YCbCr_420_888, 0, 1, __DRI_IMAGE_FOURCC_YUV420 },
{ HAL_PIXEL_FORMAT_YCbCr_420_888, 1, 1, __DRI_IMAGE_FOURCC_YVU420 },
{ HAL_PIXEL_FORMAT_YV12, 1, 1, __DRI_IMAGE_FOURCC_YVU420 },
{ HAL_PIXEL_FORMAT_NV12, 0, 2, __DRI_IMAGE_FOURCC_NV12 },
{ HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL, 0, 2, __DRI_IMAGE_FOURCC_NV12 },
/* HACK: See droid_create_image_from_prime_fd() and
* https://issuetracker.google.com/32077885. */
{ HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 0, 2, __DRI_IMAGE_FOURCC_NV12 },
Expand Down Expand Up @@ -249,6 +261,51 @@ droid_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf)
return EGL_TRUE;
}

static int
droid_resolve_format(struct dri2_egl_display *dri2_dpy,
struct ANativeWindowBuffer *buf)
{
int format = -1;
int ret;

if (buf->format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
return buf->format;
#ifdef HAVE_GRALLOC1
if(dri2_dpy->gralloc_version == HARDWARE_MODULE_API_VERSION(1, 0)) {

if (!dri2_dpy->pfn_getFormat) {
_eglLog(_EGL_WARNING, "Gralloc does not support getFormat");
return -1;
}
ret = dri2_dpy->pfn_getFormat(dri2_dpy->gralloc1_dvc, buf->handle,
&format);
if (ret) {
_eglLog(_EGL_WARNING, "gralloc->getFormat failed: %d", ret);
return -1;
}
} else {
#else
const gralloc_module_t *gralloc0;
gralloc0 = dri2_dpy->gralloc;

if (!gralloc0->perform) {
_eglLog(_EGL_WARNING, "gralloc->perform not supported");
return -1;
}
ret = gralloc0->perform(dri2_dpy->gralloc,
GRALLOC_DRM_GET_FORMAT,
buf->handle, &format);
if (ret){
_eglLog(_EGL_WARNING, "gralloc->perform failed with error: %d", ret);
return -1;
}
#endif
#ifdef HAVE_GRALLOC1
}
#endif
return format;
}

static EGLBoolean
droid_window_enqueue_buffer(_EGLDisplay *disp, struct dri2_egl_surface *dri2_surf)
{
Expand Down Expand Up @@ -731,6 +788,31 @@ droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
return EGL_TRUE;
}

static int get_ycbcr_from_flexlayout(struct android_flex_layout *outFlexLayout, struct android_ycbcr *ycbcr)
{

for( int i = 0; i < outFlexLayout->num_planes; i++) {
switch(outFlexLayout->planes[i].component){
case FLEX_COMPONENT_Y:
ycbcr->y = outFlexLayout->planes[i].top_left;
ycbcr->ystride = outFlexLayout->planes[i].v_increment;
break;
case FLEX_COMPONENT_Cb:
ycbcr->cb = outFlexLayout->planes[i].top_left;
ycbcr->cstride = outFlexLayout->planes[i].v_increment;
break;
case FLEX_COMPONENT_Cr:
ycbcr->cr = outFlexLayout->planes[i].top_left;
ycbcr->chroma_step = outFlexLayout->planes[i].h_increment;
break;
default:
_eglLog(_EGL_WARNING,"unknown component 0x%x", __func__, outFlexLayout->planes[i].component);
break;
}
}
return 0;
}

#if ANDROID_API_LEVEL >= 23
static EGLBoolean
droid_set_damage_region(_EGLDriver *drv,
Expand Down Expand Up @@ -774,30 +856,70 @@ droid_create_image_from_prime_fd_yuv(_EGLDisplay *disp, _EGLContext *ctx,
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct android_ycbcr ycbcr;
#ifdef HAVE_GRALLOC1
struct android_flex_layout outFlexLayout;
gralloc1_rect_t accessRegion;
#endif
size_t offsets[3];
size_t pitches[3];
int is_ycrcb;
int fourcc;
int ret;

if (!dri2_dpy->gralloc->lock_ycbcr) {
_eglLog(_EGL_WARNING, "Gralloc does not support lock_ycbcr");
int format = droid_resolve_format(dri2_dpy, buf);
if (format < 0) {
_eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
return NULL;
}

memset(&ycbcr, 0, sizeof(ycbcr));
ret = dri2_dpy->gralloc->lock_ycbcr(dri2_dpy->gralloc, buf->handle,
0, 0, 0, 0, 0, &ycbcr);
if (ret) {
/* HACK: See droid_create_image_from_prime_fd() and
* https://issuetracker.google.com/32077885.*/
if (buf->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
return NULL;

_eglLog(_EGL_WARNING, "gralloc->lock_ycbcr failed: %d", ret);
return NULL;
}
dri2_dpy->gralloc->unlock(dri2_dpy->gralloc, buf->handle);
#ifdef HAVE_GRALLOC1
if(dri2_dpy->gralloc_version == HARDWARE_MODULE_API_VERSION(1, 0)) {
if (!dri2_dpy->pfn_lockflex) {
_eglLog(_EGL_WARNING, "Gralloc does not support lockflex");
return NULL;
}

ret = dri2_dpy->pfn_lockflex(dri2_dpy->gralloc1_dvc, buf->handle,
0, 0, &accessRegion, &outFlexLayout, -1);
if (ret) {
_eglLog(_EGL_WARNING, "gralloc->lockflex failed: %d", ret);
return NULL;
}
ret = get_ycbcr_from_flexlayout(&outFlexLayout, &ycbcr);
if (ret) {
_eglLog(_EGL_WARNING, "gralloc->lockflex failed: %d", ret);
return NULL;
}
int outReleaseFence = 0;
dri2_dpy->pfn_unlock(dri2_dpy->gralloc1_dvc, buf->handle, &outReleaseFence);
} else {
#endif
const gralloc_module_t *gralloc0;
gralloc0 = dri2_dpy->gralloc;

if (!gralloc0->lock_ycbcr) {
_eglLog(_EGL_WARNING, "Gralloc does not support lock_ycbcr");
return NULL;
}

ret = gralloc0->lock_ycbcr(gralloc0, buf->handle,
0, 0, 0, 0, 0, &ycbcr);

if (ret) {
/* HACK: See droid_create_image_from_prime_fd() and
* https://issuetracker.google.com/32077885.*/
if (buf->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
return NULL;

_eglLog(_EGL_WARNING, "gralloc->lock_ycbcr failed: %d", ret);
return NULL;
}

gralloc0->unlock(dri2_dpy->gralloc, buf->handle);
#ifdef HAVE_GRALLOC1
}
#endif

/* When lock_ycbcr's usage argument contains no SW_READ/WRITE flags
* it will return the .y/.cb/.cr pointers based on a NULL pointer,
Expand All @@ -822,10 +944,10 @@ droid_create_image_from_prime_fd_yuv(_EGLDisplay *disp, _EGLContext *ctx,

/* .chroma_step is the byte distance between the same chroma channel
* values of subsequent pixels, assumed to be the same for Cb and Cr. */
fourcc = get_fourcc_yuv(buf->format, is_ycrcb, ycbcr.chroma_step);
fourcc = get_fourcc_yuv(format, is_ycrcb, ycbcr.chroma_step);
if (fourcc == -1) {
_eglLog(_EGL_WARNING, "unsupported YUV format, native = %x, is_ycrcb = %d, chroma_step = %d",
buf->format, is_ycrcb, ycbcr.chroma_step);
format, is_ycrcb, ycbcr.chroma_step);
return NULL;
}

Expand Down Expand Up @@ -871,9 +993,16 @@ static _EGLImage *
droid_create_image_from_prime_fd(_EGLDisplay *disp, _EGLContext *ctx,
struct ANativeWindowBuffer *buf, int fd)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
unsigned int pitch;

if (is_yuv(buf->format)) {
int format = droid_resolve_format(dri2_dpy, buf);
if (format < 0) {
_eglLog(_EGL_WARNING, "Could not resolve buffer format");
return NULL;
}

if (is_yuv(format)) {
_EGLImage *image;

image = droid_create_image_from_prime_fd_yuv(disp, ctx, buf, fd);
Expand All @@ -888,13 +1017,13 @@ droid_create_image_from_prime_fd(_EGLDisplay *disp, _EGLContext *ctx,
return image;
}

const int fourcc = get_fourcc(buf->format);
const int fourcc = get_fourcc(format);
if (fourcc == -1) {
_eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
return NULL;
}

pitch = buf->stride * get_format_bpp(buf->format);
pitch = buf->stride * get_format_bpp(format);
if (pitch == 0) {
_eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
return NULL;
Expand Down Expand Up @@ -1530,6 +1659,7 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp)
_EGLDevice *dev;
struct dri2_egl_display *dri2_dpy;
const char *err;
hw_device_t *device;
int ret;

/* Not supported yet */
Expand All @@ -1547,6 +1677,27 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp)
err = "DRI2: failed to get gralloc module";
goto cleanup;
}
dri2_dpy->gralloc_version = dri2_dpy->gralloc->module_api_version;
#ifdef HAVE_GRALLOC1
if (dri2_dpy->gralloc_version == HARDWARE_MODULE_API_VERSION(1, 0)) {
ret = dri2_dpy->gralloc->methods->open(dri2_dpy->gralloc, GRALLOC_HARDWARE_MODULE_ID, &device);
if (ret) {
err = "Failed to open hw_device device";
goto cleanup;
} else {
dri2_dpy->gralloc1_dvc = (gralloc1_device_t *)device;

dri2_dpy->pfn_lockflex = (GRALLOC1_PFN_LOCK_FLEX)\
dri2_dpy->gralloc1_dvc->getFunction(dri2_dpy->gralloc1_dvc, GRALLOC1_FUNCTION_LOCK_FLEX);

dri2_dpy->pfn_getFormat = (GRALLOC1_PFN_GET_FORMAT)\
dri2_dpy->gralloc1_dvc->getFunction(dri2_dpy->gralloc1_dvc, GRALLOC1_FUNCTION_GET_FORMAT);

dri2_dpy->pfn_unlock = (GRALLOC1_PFN_UNLOCK)\
dri2_dpy->gralloc1_dvc->getFunction(dri2_dpy->gralloc1_dvc, GRALLOC1_FUNCTION_UNLOCK);
}
}
#endif

disp->DriverData = (void *) dri2_dpy;

Expand Down

0 comments on commit 50df97d

Please sign in to comment.