You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

471 lines
14 KiB

/*
* 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