/* * 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 #include #include #include #include #include #include #include #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¡¢afbc¡¢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