|
|
/*
|
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd.. 2018-2019. All rights reserved.
|
|
|
* Description: Gralloc base class
|
|
|
* Author: Hisilicon
|
|
|
* Created: 2019.11.07
|
|
|
*/
|
|
|
|
|
|
#ifndef _GRALLOC_PRI_H_
|
|
|
#define _GRALLOC_PRI_H_
|
|
|
|
|
|
#include <string.h>
|
|
|
#include <stdlib.h>
|
|
|
#include <unistd.h>
|
|
|
#include <errno.h>
|
|
|
|
|
|
#include <sys/mman.h>
|
|
|
#include <sys/types.h>
|
|
|
#include <linux/fb.h>
|
|
|
|
|
|
#include <log/log.h>
|
|
|
|
|
|
#include "hardware/gralloc.h"
|
|
|
#include "hardware/gralloc1.h"
|
|
|
|
|
|
#define GRALLOC_PRI_VERSION_0_1
|
|
|
|
|
|
/* fd and int number in gralloc handle */
|
|
|
#define GRALLOC_NUM_FDS 2
|
|
|
#define GRALLOC_NUM_INTS ((sizeof(struct private_handle_t) - sizeof(native_handle)) / sizeof(int) - GRALLOC_NUM_FDS)
|
|
|
#define GRALLOC_MAGIC 0x3141592
|
|
|
|
|
|
/* attribute region definition */
|
|
|
typedef enum {
|
|
|
GRALLOC_BUFFER_ATTR_MEDIA = 0, /* media external buffer info */
|
|
|
GRALLOC_BUFFER_ATTR_CROP, /* crop info */
|
|
|
GRALLOC_BUFFER_ATTR_COMPRESSION, /* comrpression flag */
|
|
|
GRALLOC_BUFFER_ATTR_AFBC, /* afbc info if format is afbc */
|
|
|
GRALLOC_BUFFER_ATTR_HFBC, /* hfbc info if format id hfbc */
|
|
|
GRALLOC_BUFFER_ATTR_COMPOSE, /* composition device info */
|
|
|
GRALLOC_BUFFER_ATTR_LAST,
|
|
|
}gralloc_buf_attr;
|
|
|
|
|
|
/* private buffer address for media or other modules that requires to
|
|
|
save some private info with current frame */
|
|
|
struct attr_private_buffer {
|
|
|
int32_t fd;
|
|
|
uint32_t offset;
|
|
|
uint32_t size;
|
|
|
void* ptr;
|
|
|
}__attribute__((packed));
|
|
|
|
|
|
struct attr_crop {
|
|
|
int crop_top;
|
|
|
int crop_left;
|
|
|
int crop_height;
|
|
|
int crop_width;
|
|
|
}__attribute__((packed));
|
|
|
|
|
|
typedef enum {
|
|
|
COMPRESSION_FLAG_LINEAR = 0,
|
|
|
COMPRESSION_FLAG_AFBC,
|
|
|
COMPRESSION_FLAG_HFBC,
|
|
|
}compression_flag;
|
|
|
|
|
|
struct attr_afbc {
|
|
|
uint32_t header_size;
|
|
|
uint32_t header_stride;
|
|
|
uint32_t use_yuv_transform;
|
|
|
uint32_t use_sparse_alloc;
|
|
|
uint32_t disp_width; /* display width for yuv format */
|
|
|
uint32_t disp_height; /* display height for yuv format */
|
|
|
}__attribute__((packed));
|
|
|
|
|
|
struct attr_hfbc {
|
|
|
uint32_t disp_width;
|
|
|
uint32_t disp_height;
|
|
|
uint32_t bit_depth;
|
|
|
uint32_t luma_stride;
|
|
|
|
|
|
uint32_t luma_header_offset;
|
|
|
uint32_t luma_data_offset;
|
|
|
|
|
|
uint32_t chroma_header_offset;
|
|
|
uint32_t chroma_data_offset;
|
|
|
|
|
|
uint32_t luma_data2_offset; /* for 10bit, luma data address for part2 if exist */
|
|
|
uint32_t chroma_data2_offset; /* for 10bit, chroma data address for part2 if exist */
|
|
|
}__attribute__((packed));
|
|
|
|
|
|
struct attr_region {
|
|
|
struct attr_private_buffer media_private_buffer;
|
|
|
|
|
|
struct attr_crop crop;
|
|
|
|
|
|
unsigned long long compression_flag; /* buffer compression flag : linear<61><72>afbc<62><63>hfbc */
|
|
|
|
|
|
union { /* afbc info or hfbc info */
|
|
|
struct attr_afbc afbc;
|
|
|
struct attr_hfbc hfbc;
|
|
|
};
|
|
|
|
|
|
int composed; /* composition device: 0 is gpu, 1 is hwc */
|
|
|
} __attribute__((packed));
|
|
|
|
|
|
typedef struct attr_region attr_region;
|
|
|
|
|
|
/* private usages definition */
|
|
|
#define GRALLOC_USAGE_PRI_YUV10BIT GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA
|
|
|
#define GRALLOC_USAGE_PRI_VDP GRALLOC1_CONSUMER_USAGE_PRIVATE_2
|
|
|
#define GRALLOC_USAGE_PRI_FASTOUTPUT GRALLOC1_CONSUMER_USAGE_RENDERSCRIPT
|
|
|
#define GRALLOC_USAGE_PRI_NO_AFBC GRALLOC1_CONSUMER_USAGE_PRIVATE_1
|
|
|
#define GRALLOC_USAGE_PRI_HFBC GRALLOC1_CONSUMER_USAGE_PRIVATE_0
|
|
|
|
|
|
/* gpu capability definition */
|
|
|
typedef enum {
|
|
|
GRALLOC_GPU_CAPABILITY_FORMAT_LINEAR = (1ULL << 0),
|
|
|
GRALLOC_GPU_CAPABILITY_FORMAT_LINEAR_PRI_10BIT = (1ULL << 1),
|
|
|
GRALLOC_GPU_CAPABILITY_FORMAT_TILE_8BIT_ONLY = (1ULL << 2),
|
|
|
GRALLOC_GPU_CAPABILITY_FORMAT_TILE = (1ULL << 3),
|
|
|
GRALLOC_GPU_CAPABILITY_FORMAT_HFBC = (1ULL << 4),
|
|
|
GRALLOC_GPU_CAPABILITY_FORMAT_AFBC = (1ULL << 5),
|
|
|
} gralloc_gpu_capabiltiy;
|
|
|
|
|
|
/* return info */
|
|
|
#define GRALLOC_SUCCESS 0
|
|
|
#define GRALLOC_FAILURE (-1)
|
|
|
#define GRALLOC_ERROR_INFO() ALOGE("GRALLOC: Error func = %s, line = %d", __FUNCTION__, __LINE__)
|
|
|
|
|
|
/* fb device info */
|
|
|
#define NUM_FB_DEVICES 4
|
|
|
#define NUM_FB_BUFFERS 3
|
|
|
|
|
|
/* private handle definition */
|
|
|
#ifdef __cplusplus
|
|
|
struct private_handle_t;
|
|
|
#else
|
|
|
typedef struct private_handle_t private_handle_t;
|
|
|
#endif
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
struct private_handle_t : public native_handle {
|
|
|
#else
|
|
|
struct private_handle_t {
|
|
|
struct native_handle nativeHandle;
|
|
|
#endif
|
|
|
|
|
|
enum {
|
|
|
PRIV_FLAGS_FRAMEBUFFER = 0x00000001,
|
|
|
PRIV_FLAGS_USES_UMP = 0x00000002,
|
|
|
PRIV_FLAGS_USES_ION = 0x00000004,
|
|
|
PRIV_FLAGS_USES_ION_DMA_HEAP = 0x00000008,
|
|
|
PRIV_FLAGS_USES_ION_COMPOUND_HEAP = 0x0000000f
|
|
|
};
|
|
|
|
|
|
enum {
|
|
|
LOCK_STATE_WRITE = 1 << 31,
|
|
|
LOCK_STATE_MAPPED = 1 << 30,
|
|
|
LOCK_STATE_READ_MASK = 0x3FFFFFFF
|
|
|
};
|
|
|
|
|
|
/*
|
|
|
* Shared file descriptor for dma_buf sharing. This must be the first element in the
|
|
|
* structure so that binder knows where it is and can properly share it between
|
|
|
* processes.
|
|
|
* DO NOT MOVE THIS ELEMENT!
|
|
|
*/
|
|
|
int fd;
|
|
|
int attr_fd;
|
|
|
|
|
|
int magic;
|
|
|
int format;
|
|
|
unsigned int flags;
|
|
|
int width;
|
|
|
int height;
|
|
|
int pixel_stride;
|
|
|
int bytes_stride;
|
|
|
int layer_count;
|
|
|
|
|
|
unsigned long long consumer_usage;
|
|
|
unsigned long long producer_usage;
|
|
|
|
|
|
/* Master Memory */
|
|
|
union { int hnd; unsigned long long padding_A; };
|
|
|
union { void *base; unsigned long long padding_B; };
|
|
|
unsigned int addr;
|
|
|
int size;
|
|
|
union { off_t offset; unsigned long long padding_C; };
|
|
|
|
|
|
/* Shared Memory */
|
|
|
union { int attr_hnd; unsigned long long padding_D; };
|
|
|
union { void *attr_base; unsigned long long padding_E; };
|
|
|
unsigned int attr_addr;
|
|
|
int attr_size;
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
|
private_handle_t(unsigned int _flags, int _size, void *_base, unsigned long long _consumer_usage,
|
|
|
unsigned long long _producer_usage, int _fd, off_t _offset)
|
|
|
: fd(_fd),
|
|
|
attr_fd(-1),
|
|
|
magic(GRALLOC_MAGIC),
|
|
|
format(0),
|
|
|
flags(_flags),
|
|
|
width(0),
|
|
|
height(0),
|
|
|
pixel_stride(0),
|
|
|
bytes_stride(0),
|
|
|
layer_count(1),
|
|
|
consumer_usage(_consumer_usage),
|
|
|
producer_usage(_producer_usage),
|
|
|
hnd(-1),
|
|
|
base(_base),
|
|
|
addr(-1),
|
|
|
size(_size),
|
|
|
offset(_offset),
|
|
|
attr_hnd(-1),
|
|
|
attr_base(MAP_FAILED),
|
|
|
attr_addr(-1),
|
|
|
attr_size(0)
|
|
|
{
|
|
|
version = sizeof(native_handle);
|
|
|
numFds = GRALLOC_NUM_FDS;
|
|
|
numInts = GRALLOC_NUM_INTS;
|
|
|
}
|
|
|
|
|
|
private_handle_t(unsigned int _flags, int _size, unsigned long long _consumer_usage,
|
|
|
unsigned long long _producer_usage, int _fd, int _format, int _pixel_stride,
|
|
|
int _bytes_stride, int _width, int _height, int _layer_count)
|
|
|
: fd(_fd),
|
|
|
attr_fd(-1),
|
|
|
magic(GRALLOC_MAGIC),
|
|
|
format(_format),
|
|
|
flags(_flags),
|
|
|
width(_width),
|
|
|
height(_height),
|
|
|
pixel_stride(_pixel_stride),
|
|
|
bytes_stride(_bytes_stride),
|
|
|
layer_count(_layer_count),
|
|
|
consumer_usage(_consumer_usage),
|
|
|
producer_usage(_producer_usage),
|
|
|
hnd(-1),
|
|
|
base(NULL),
|
|
|
addr(-1),
|
|
|
size(_size),
|
|
|
offset(0),
|
|
|
attr_hnd(-1),
|
|
|
attr_base(MAP_FAILED),
|
|
|
attr_addr(-1),
|
|
|
attr_size(0)
|
|
|
{
|
|
|
version = sizeof(native_handle);
|
|
|
numFds = GRALLOC_NUM_FDS;
|
|
|
numInts = GRALLOC_NUM_INTS;
|
|
|
}
|
|
|
|
|
|
~private_handle_t()
|
|
|
{
|
|
|
magic = 0;
|
|
|
}
|
|
|
|
|
|
static int validate(const native_handle *h)
|
|
|
{
|
|
|
const private_handle_t *hnd = (const private_handle_t *)h;
|
|
|
|
|
|
if (h == NULL || h->version != sizeof(native_handle) ||
|
|
|
h->numFds != GRALLOC_NUM_FDS || hnd->magic != GRALLOC_MAGIC) {
|
|
|
GRALLOC_ERROR_INFO();
|
|
|
return GRALLOC_FAILURE;
|
|
|
}
|
|
|
|
|
|
return GRALLOC_SUCCESS;
|
|
|
}
|
|
|
|
|
|
static private_handle_t* dynamicCast(const native_handle *h)
|
|
|
{
|
|
|
if (validate(h) == GRALLOC_SUCCESS) {
|
|
|
return (private_handle_t*)h;
|
|
|
}
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
};
|
|
|
|
|
|
/* gralloc module definition */
|
|
|
typedef struct private_module_t {
|
|
|
gralloc_module_t base;
|
|
|
|
|
|
struct private_handle_t *framebuffer[NUM_FB_DEVICES];
|
|
|
unsigned int numBuffers[NUM_FB_DEVICES];
|
|
|
unsigned int bufferMask[NUM_FB_DEVICES];
|
|
|
struct fb_var_screeninfo vinfo[NUM_FB_DEVICES];
|
|
|
struct fb_fix_screeninfo finfo[NUM_FB_DEVICES];
|
|
|
float xdpi[NUM_FB_DEVICES];
|
|
|
float ydpi[NUM_FB_DEVICES];
|
|
|
float fps[NUM_FB_DEVICES];
|
|
|
int swapInterval[NUM_FB_DEVICES];
|
|
|
pthread_mutex_t lock;
|
|
|
|
|
|
int client;
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
enum {
|
|
|
PRIV_USAGE_LOCKED_FOR_POST = 0x80000000
|
|
|
};
|
|
|
#endif
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
private_module_t();
|
|
|
#endif
|
|
|
}private_module_t;
|
|
|
|
|
|
/* external function to read and write share memory */
|
|
|
static inline int gralloc_buffer_attr_write(const struct private_handle_t *handle,
|
|
|
gralloc_buf_attr attr, const void *val)
|
|
|
{
|
|
|
if (handle == NULL || val == NULL || attr >= GRALLOC_BUFFER_ATTR_LAST) {
|
|
|
GRALLOC_ERROR_INFO();
|
|
|
return GRALLOC_FAILURE;
|
|
|
}
|
|
|
|
|
|
if (handle->attr_base != MAP_FAILED) {
|
|
|
attr_region *region = (attr_region *)handle->attr_base;
|
|
|
if (region == NULL) {
|
|
|
GRALLOC_ERROR_INFO();
|
|
|
return GRALLOC_FAILURE;
|
|
|
}
|
|
|
switch (attr) {
|
|
|
case GRALLOC_BUFFER_ATTR_MEDIA:
|
|
|
region->media_private_buffer = *(struct attr_private_buffer *)val;
|
|
|
break;
|
|
|
|
|
|
case GRALLOC_BUFFER_ATTR_CROP:
|
|
|
region->crop = *(struct attr_crop *)val;
|
|
|
break;
|
|
|
|
|
|
case GRALLOC_BUFFER_ATTR_COMPRESSION:
|
|
|
region->compression_flag = *(int *)val;
|
|
|
break;
|
|
|
|
|
|
case GRALLOC_BUFFER_ATTR_AFBC:
|
|
|
region->afbc = *(struct attr_afbc *)val;
|
|
|
break;
|
|
|
|
|
|
case GRALLOC_BUFFER_ATTR_HFBC:
|
|
|
region->hfbc = *(struct attr_hfbc *)val;
|
|
|
break;
|
|
|
|
|
|
case GRALLOC_BUFFER_ATTR_COMPOSE:
|
|
|
region->composed = *(int *)val;
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
GRALLOC_ERROR_INFO();
|
|
|
return GRALLOC_FAILURE;
|
|
|
}
|
|
|
} else {
|
|
|
GRALLOC_ERROR_INFO();
|
|
|
return GRALLOC_FAILURE;
|
|
|
}
|
|
|
|
|
|
return GRALLOC_SUCCESS;
|
|
|
}
|
|
|
|
|
|
static inline int gralloc_buffer_attr_read(const struct private_handle_t *handle, gralloc_buf_attr attr, void *val)
|
|
|
{
|
|
|
if (handle == NULL || val == NULL || attr >= GRALLOC_BUFFER_ATTR_LAST) {
|
|
|
GRALLOC_ERROR_INFO();
|
|
|
return GRALLOC_FAILURE;
|
|
|
}
|
|
|
|
|
|
if (handle->attr_base != MAP_FAILED) {
|
|
|
attr_region *region = (attr_region *)handle->attr_base;
|
|
|
if (region == NULL) {
|
|
|
GRALLOC_ERROR_INFO();
|
|
|
return GRALLOC_FAILURE;
|
|
|
}
|
|
|
switch (attr) {
|
|
|
case GRALLOC_BUFFER_ATTR_MEDIA: {
|
|
|
struct attr_private_buffer buf = region->media_private_buffer;
|
|
|
buf.fd = handle->attr_fd;
|
|
|
buf.ptr = (void *)((char*)region + buf.offset);
|
|
|
*(struct attr_private_buffer *)val = buf;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
case GRALLOC_BUFFER_ATTR_CROP:
|
|
|
*(struct attr_crop *)val = region->crop;
|
|
|
break;
|
|
|
|
|
|
case GRALLOC_BUFFER_ATTR_COMPRESSION:
|
|
|
*(int*)val = region->compression_flag;
|
|
|
break;
|
|
|
|
|
|
case GRALLOC_BUFFER_ATTR_AFBC:
|
|
|
*(struct attr_afbc *)val = region->afbc;
|
|
|
break;
|
|
|
|
|
|
case GRALLOC_BUFFER_ATTR_HFBC:
|
|
|
*(struct attr_hfbc *)val = region->hfbc;
|
|
|
break;
|
|
|
|
|
|
case GRALLOC_BUFFER_ATTR_COMPOSE:
|
|
|
*(int*)val = region->composed;
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
GRALLOC_ERROR_INFO();
|
|
|
return GRALLOC_FAILURE;
|
|
|
}
|
|
|
} else {
|
|
|
GRALLOC_ERROR_INFO();
|
|
|
return GRALLOC_FAILURE;
|
|
|
}
|
|
|
|
|
|
return GRALLOC_SUCCESS;
|
|
|
}
|
|
|
|
|
|
/* get capability for gpu on differenty chip */
|
|
|
static inline unsigned long long gralloc_get_gpu_capability(void)
|
|
|
{
|
|
|
const char* gpu_cap_dir = "/sys/class/misc/mali0/device/capability";
|
|
|
char caps_info[PAGE_SIZE];
|
|
|
char *str_save = NULL;
|
|
|
char *token = NULL;
|
|
|
char *context = NULL;
|
|
|
unsigned long long capabiltiy = GRALLOC_GPU_CAPABILITY_FORMAT_LINEAR;
|
|
|
|
|
|
FILE* file = fopen(gpu_cap_dir, "r");
|
|
|
if (file == NULL) {
|
|
|
ALOGI ("gralloc can not access gpu capability dir");
|
|
|
return capabiltiy;
|
|
|
}
|
|
|
|
|
|
while (fgets(caps_info, PAGE_SIZE, file)) {
|
|
|
ALOGI("gralloc gpu capability info:%s", caps_info);
|
|
|
|
|
|
if (strstr(caps_info, "compression ability:") == NULL) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
context = strstr(caps_info, "compression ability:") + strlen("compression ability:");
|
|
|
/* compression ability: linear afbc hfbc tile_8bit_only */
|
|
|
token = strtok_r(context, " ", &str_save);
|
|
|
while (token != NULL) {
|
|
|
if (strncmp(token, "linear", strlen("linear")) == 0) {
|
|
|
capabiltiy |= GRALLOC_GPU_CAPABILITY_FORMAT_LINEAR;
|
|
|
} else if (strncmp(token, "tile_8bit_only", strlen("tile_8bit_only")) == 0) {
|
|
|
capabiltiy |= GRALLOC_GPU_CAPABILITY_FORMAT_TILE_8BIT_ONLY;
|
|
|
} else if (strncmp(token, "tile", strlen("tile")) == 0) {
|
|
|
capabiltiy |= GRALLOC_GPU_CAPABILITY_FORMAT_TILE;
|
|
|
} else if (strncmp(token, "hfbc", strlen("hfbc")) == 0) {
|
|
|
capabiltiy |= GRALLOC_GPU_CAPABILITY_FORMAT_HFBC;
|
|
|
} else if (strncmp(token, "afbc", strlen("afbc")) == 0) {
|
|
|
capabiltiy |= GRALLOC_GPU_CAPABILITY_FORMAT_AFBC;
|
|
|
}
|
|
|
|
|
|
token = strtok_r(NULL, " ", &str_save);
|
|
|
}
|
|
|
|
|
|
fseek(file, strlen(caps_info), SEEK_CUR);
|
|
|
}
|
|
|
|
|
|
fclose(file);
|
|
|
|
|
|
ALOGI("gralloc get gpu capability:0x%llx", capabiltiy);
|
|
|
return capabiltiy;
|
|
|
}
|
|
|
#endif
|
|
|
|