upload android base code part4

This commit is contained in:
August 2018-08-08 17:00:29 +08:00
parent b9e30e05b1
commit 78ea2404cd
23455 changed files with 5250148 additions and 0 deletions

View file

@ -0,0 +1 @@
include $(call all-named-subdir-makefiles, gralloc/src)

View file

@ -0,0 +1 @@
mali-utgard: r8p0-00rel0 gralloc 004

View file

@ -0,0 +1,57 @@
#
# Copyright (C) 2010 ARM Limited. All rights reserved.
#
# Copyright (C) 2008 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCAL_PATH := $(call my-dir)
# HAL module implemenation, not prelinked and stored in
# hw/<OVERLAY_HARDWARE_MODULE_ID>.<ro.product.board>.so
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 21 && echo OK),OK)
LOCAL_MODULE_RELATIVE_PATH := hw
#LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/mali400
else
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
endif
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
LOCAL_MODULE := gralloc.$(TARGET_BOARD_PLATFORM)
#LOCAL_MODULE_TAGS := optional
# Mali-200/300/400MP DDK
MALI_DDK_PATH := $(LOCAL_PATH)/../driver
#SHARED_MEM_LIBS := libUMP
SHARED_MEM_LIBS := libion libhardware
LOCAL_SHARED_LIBRARIES := liblog libcutils libGLESv1_CM $(SHARED_MEM_LIBS)
LOCAL_C_INCLUDES := system/core/include/ $(MALI_DDK_PATH)/include ./
# Include the UMP header files
LOCAL_C_INCLUDES += $(MALI_DDK_PATH)/src/ump/include
LOCAL_CFLAGS := -DLOG_TAG=\"gralloc\" -DGRALLOC_32_BITS -DSTANDARD_LINUX_SCREEN -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION)
LOCAL_SRC_FILES := \
gralloc_module.cpp \
alloc_device.cpp \
framebuffer_device.cpp
#LOCAL_CFLAGS+= -DMALI_VSYNC_EVENT_REPORT_ENABLE
include $(BUILD_SHARED_LIBRARY)

View file

@ -0,0 +1,864 @@
/*
* Copyright (C) 2010 ARM Limited. All rights reserved.
*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <cutils/log.h>
#include <cutils/atomic.h>
#include <hardware/hardware.h>
#include <hardware/gralloc.h>
#include <sys/ioctl.h>
#include "alloc_device.h"
#include "gralloc_priv.h"
#include "gralloc_helper.h"
#include "framebuffer_device.h"
#if GRALLOC_ARM_UMP_MODULE
#include <ump/ump.h>
#include <ump/ump_ref_drv.h>
#endif
#if GRALLOC_ARM_DMA_BUF_MODULE
#include <linux/ion.h>
#include <ion/ion.h>
#endif
#define GRALLOC_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1))
aw_mem_info_data aw_mem_info =
{
.dram_size = 0,
.secure_level = 3,
.ion_flush_cache_range = 0,
.carveout_enable = 0
};
#define ION_IOC_SUNXI_FLUSH_RANGE 5
int aw_flush_cache(int ion_client, void* start_vaddr, int shared_fd, size_t size)
{
if (aw_mem_info.ion_flush_cache_range) {
sunxi_cache_range range;
struct ion_custom_data custom_data;
/* clean and invalid user cache */
range.start = (unsigned long)start_vaddr;
range.end = (unsigned long)start_vaddr + size;
return ioctl(ion_client, ION_IOC_SUNXI_FLUSH_RANGE, &range);
} else {
return ion_sync_fd(ion_client, shared_fd);
}
}
#if GRALLOC_SIMULATE_FAILURES
#include <cutils/properties.h>
/* system property keys for controlling simulated UMP allocation failures */
#define PROP_MALI_TEST_GRALLOC_FAIL_FIRST "mali.test.gralloc.fail_first"
#define PROP_MALI_TEST_GRALLOC_FAIL_INTERVAL "mali.test.gralloc.fail_interval"
static int __ump_alloc_should_fail()
{
static unsigned int call_count = 0;
unsigned int first_fail = 0;
int fail_period = 0;
int fail = 0;
++call_count;
/* read the system properties that control failure simulation */
{
char prop_value[PROPERTY_VALUE_MAX];
if (property_get(PROP_MALI_TEST_GRALLOC_FAIL_FIRST, prop_value, "0") > 0)
{
sscanf(prop_value, "%11u", &first_fail);
}
if (property_get(PROP_MALI_TEST_GRALLOC_FAIL_INTERVAL, prop_value, "0") > 0)
{
sscanf(prop_value, "%11u", &fail_period);
}
}
/* failure simulation is enabled by setting the first_fail property to non-zero */
if (first_fail > 0)
{
LOGI("iteration %u (fail=%u, period=%u)\n", call_count, first_fail, fail_period);
fail = (call_count == first_fail) ||
(call_count > first_fail && fail_period > 0 && 0 == (call_count - first_fail) % fail_period);
if (fail)
{
AERR("failed ump_ref_drv_allocate on iteration #%d\n", call_count);
}
}
return fail;
}
#endif
#ifndef ION_HEAP_SECURE_MASK
#define ION_HEAP_TYPE_SUNXI_START (ION_HEAP_TYPE_CUSTOM + 1)
#define ION_HEAP_TYPE_SECURE (ION_HEAP_TYPE_SUNXI_START)
#define ION_HEAP_SECURE_MASK (1<<ION_HEAP_TYPE_SECURE)
#endif /* ION_HEAP_SECURE_MASK */
static char heap_system[] = "SYSTEM";
static char heap_system_contig[] = "SYSTEM_CONTIG";
static char heap_dma[] = "DMA";
static char heap_secure[] = "SECURE";
static char heap_carveout[] = "CARVEOUT";
static char *get_heap_type_name(int heap_mask)
{
switch(heap_mask)
{
case ION_HEAP_SYSTEM_MASK:
return heap_system;
case ION_HEAP_SYSTEM_CONTIG_MASK:
return heap_system_contig;
case ION_HEAP_TYPE_DMA_MASK:
return heap_dma;
case ION_HEAP_SECURE_MASK:
return heap_secure;
case ION_HEAP_CARVEOUT_MASK:
return heap_carveout;
default:
AERR("Invalid heap mask %d!\n", heap_mask);
break;
}
return NULL;
}
static int aw_ion_alloc(int *pfd, size_t len, size_t align, unsigned int heap_mask, unsigned int flags, ion_user_handle_t *handle, int usage)
{
int ret;
ret = ion_alloc(*pfd, len, align, heap_mask, flags, handle);
if (ret != 0)
{
AERR("%s(line:%d)Failed to ion_alloc from ion_client:%d via heap type %s(mask:%d) for %d Bytes %sbuffer, err = %d, usage = 0x%.8x\n", __func__, __LINE__, *pfd, get_heap_type_name(heap_mask), heap_mask, (int)len, flags ? "cached " : "uncached ", errno, usage);
}
else
{
AINF("ion_alloc from ion_client:%d via heap type %s(mask:%d) for %d Bytes %sbuffer successfully, usage = 0x%.8x\n", *pfd, get_heap_type_name(heap_mask), heap_mask, (int)len, flags ? "cached " : "uncached ", usage);
}
return ret;
}
static int gralloc_alloc_buffer(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle)
{
#if GRALLOC_ARM_DMA_BUF_MODULE
{
private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
ion_user_handle_t ion_hnd;
void *cpu_ptr = MAP_FAILED;
int shared_fd;
int ret;
unsigned int heap_mask;
int lock_state = 0;
int map_mask = 0;
int flags = 0;
int default_heap_mask;
if (aw_mem_info.carveout_enable)
{
default_heap_mask = ION_HEAP_CARVEOUT_MASK;
}
else if (aw_mem_info.iommu_enabled)
{
default_heap_mask = ION_HEAP_SYSTEM_MASK;
}
else
{
default_heap_mask = ION_HEAP_TYPE_DMA_MASK;
}
if ((usage & GRALLOC_USAGE_PROTECTED) && (aw_mem_info.secure_level == 1))
{
#if defined(ION_HEAP_SECURE_MASK)
heap_mask = ION_HEAP_SECURE_MASK;
#else
AERR("The platform does NOT support protected ION memory.");
return -1;
#endif
}
else if (usage & (GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_HW_2D | GRALLOC_USAGE_HW_FB))
{
heap_mask = default_heap_mask;
}
else if (aw_mem_info.dram_size <= 512)
{
heap_mask = ION_HEAP_SYSTEM_MASK;
}
else
{
heap_mask = default_heap_mask;
}
if ((usage & GRALLOC_USAGE_SW_READ_OFTEN)==GRALLOC_USAGE_SW_READ_OFTEN ||
(usage & GRALLOC_USAGE_SW_WRITE_OFTEN)==GRALLOC_USAGE_SW_WRITE_OFTEN)
{
if (heap_mask != ION_HEAP_SECURE_MASK)
{
flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
}
}
ret = aw_ion_alloc(&(m->ion_client), size, 0, heap_mask, flags, &(ion_hnd), usage);
if (ret != 0)
{
switch(heap_mask)
{
case ION_HEAP_SECURE_MASK:
return -1;
case ION_HEAP_CARVEOUT_MASK:
case ION_HEAP_TYPE_DMA_MASK:
if (usage & (GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_HW_2D | GRALLOC_USAGE_HW_FB))
{
if (size <= 0x40000000)
{
heap_mask = ION_HEAP_SYSTEM_CONTIG_MASK;
}
else
{
return -1;
}
}
else
{
heap_mask = ION_HEAP_SYSTEM_MASK;
}
break;
default:
heap_mask = default_heap_mask;
break;
}
ret = aw_ion_alloc(&(m->ion_client), size, 0, heap_mask, flags, &(ion_hnd), usage);
if (ret != 0)
{
return -1;
}
}
ret = ion_share(m->ion_client, ion_hnd, &shared_fd);
if (ret != 0)
{
AERR("ion_share( %d ) failed", m->ion_client);
if (0 != ion_free(m->ion_client, ion_hnd))
{
AERR("ion_free( %d ) failed", m->ion_client);
}
return -1;
}
if (!(usage & GRALLOC_USAGE_PROTECTED))
{
map_mask = PROT_READ | PROT_WRITE;
}
else
{
map_mask = PROT_WRITE;
}
cpu_ptr = mmap(NULL, size, map_mask, MAP_SHARED, shared_fd, 0);
if (MAP_FAILED == cpu_ptr)
{
AERR("ion_map( %d ) failed", m->ion_client);
if (0 != ion_free(m->ion_client, ion_hnd))
{
AERR("ion_free( %d ) failed", m->ion_client);
}
close(shared_fd);
return -1;
}
else
{
if (heap_mask != ION_HEAP_SECURE_MASK)
{
memset(cpu_ptr, 0x0, size);
if (flags & (ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC))
if (aw_flush_cache(m->ion_client, (void *)cpu_ptr, shared_fd, size))
AERR("Failed to flush Cache, err = %d\n", errno);
}
}
lock_state = private_handle_t::LOCK_STATE_MAPPED;
private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_ION | (heap_mask == ION_HEAP_SYSTEM_MASK ? 0 :
private_handle_t::PRIV_FLAGS_USES_CONFIG), usage, size, cpu_ptr, lock_state);
if (NULL != hnd)
{
hnd->share_fd = shared_fd;
hnd->ion_hnd = ion_hnd;
*pHandle = hnd;
return 0;
}
else
{
AERR("Gralloc out of mem for ion_client:%d", m->ion_client);
}
close(shared_fd);
ret = munmap(cpu_ptr, size);
if (0 != ret)
{
AERR("munmap failed for base:%p size: %lu", cpu_ptr, (unsigned long)size);
}
ret = ion_free(m->ion_client, ion_hnd);
if (0 != ret)
{
AERR("ion_free( %d ) failed", m->ion_client);
}
return -1;
}
#endif
#if GRALLOC_ARM_UMP_MODULE
MALI_IGNORE(dev);
{
ump_handle ump_mem_handle;
void *cpu_ptr;
ump_secure_id ump_id;
ump_alloc_constraints constraints;
size = round_up_to_page_size(size);
if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN)
{
constraints = UMP_REF_DRV_CONSTRAINT_USE_CACHE;
}
else
{
constraints = UMP_REF_DRV_CONSTRAINT_NONE;
}
#ifdef GRALLOC_SIMULATE_FAILURES
/* if the failure condition matches, fail this iteration */
if (__ump_alloc_should_fail())
{
ump_mem_handle = UMP_INVALID_MEMORY_HANDLE;
}
else
#endif
{
if (usage & GRALLOC_USAGE_PROTECTED)
{
AERR("gralloc_alloc_buffer() does not support to allocate protected UMP memory.");
}
else
{
ump_mem_handle = ump_ref_drv_allocate(size, constraints);
if (UMP_INVALID_MEMORY_HANDLE != ump_mem_handle)
{
cpu_ptr = ump_mapped_pointer_get(ump_mem_handle);
if (NULL != cpu_ptr)
{
ump_id = ump_secure_id_get(ump_mem_handle);
if (UMP_INVALID_SECURE_ID != ump_id)
{
private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_UMP, usage, size, cpu_ptr,
private_handle_t::LOCK_STATE_MAPPED, ump_id, ump_mem_handle);
if (NULL != hnd)
{
*pHandle = hnd;
return 0;
}
else
{
AERR("gralloc_alloc_buffer() failed to allocate handle. ump_handle = %p, ump_id = %d", ump_mem_handle, ump_id);
}
}
else
{
AERR("gralloc_alloc_buffer() failed to retrieve valid secure id. ump_handle = %p", ump_mem_handle);
}
ump_mapped_pointer_release(ump_mem_handle);
}
else
{
AERR("gralloc_alloc_buffer() failed to map UMP memory. ump_handle = %p", ump_mem_handle);
}
ump_reference_release(ump_mem_handle);
}
else
{
AERR("gralloc_alloc_buffer() failed to allocate UMP memory. size:%d constraints: %d", size, constraints);
}
}
}
return -1;
}
#endif
}
static int gralloc_alloc_framebuffer_locked(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle)
{
private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
// allocate the framebuffer
if (m->framebuffer == NULL)
{
// initialize the framebuffer, the framebuffer is mapped once and forever.
int err = init_frame_buffer_locked(m);
if (err < 0)
{
return err;
}
}
const uint32_t bufferMask = m->bufferMask;
const uint32_t numBuffers = m->numBuffers;
const size_t bufferSize = m->finfo.line_length * m->info.yres;
if (numBuffers == 1)
{
// If we have only one buffer, we never use page-flipping. Instead,
// we return a regular buffer which will be memcpy'ed to the main
// screen when post is called.
int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
AERR("fallback to single buffering. Virtual Y-res too small %d", m->info.yres);
return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle);
}
if (bufferMask >= ((1LU << numBuffers) - 1))
{
// We ran out of buffers.
return -ENOMEM;
}
void *vaddr = m->framebuffer->base;
// find a free slot
for (uint32_t i = 0 ; i < numBuffers ; i++)
{
if ((bufferMask & (1LU << i)) == 0)
{
m->bufferMask |= (1LU << i);
break;
}
vaddr = (void *)((uintptr_t)vaddr + bufferSize);
}
// The entire framebuffer memory is already mapped, now create a buffer object for parts of this memory
private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, usage, size, vaddr,
0, dup(m->framebuffer->fd), (uintptr_t)vaddr - (uintptr_t) m->framebuffer->base);
#if GRALLOC_ARM_UMP_MODULE
hnd->ump_id = m->framebuffer->ump_id;
/* create a backing ump memory handle if the framebuffer is exposed as a secure ID */
if ((int)UMP_INVALID_SECURE_ID != hnd->ump_id)
{
hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id);
if ((int)UMP_INVALID_MEMORY_HANDLE == hnd->ump_mem_handle)
{
AINF("warning: unable to create UMP handle from secure ID %i\n", hnd->ump_id);
}
}
#endif
#if GRALLOC_ARM_DMA_BUF_MODULE
{
#ifdef FBIOGET_DMABUF
struct fb_dmabuf_export fb_dma_buf;
if (ioctl(m->framebuffer->fd, FBIOGET_DMABUF, &fb_dma_buf) == 0)
{
AINF("framebuffer accessed with dma buf (fd 0x%x)\n", (int)fb_dma_buf.fd);
hnd->share_fd = fb_dma_buf.fd;
}
#endif
}
#endif
*pHandle = hnd;
return 0;
}
static int gralloc_alloc_framebuffer(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle)
{
private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
pthread_mutex_lock(&m->lock);
int err = gralloc_alloc_framebuffer_locked(dev, size, usage, pHandle);
pthread_mutex_unlock(&m->lock);
return err;
}
static int alloc_device_alloc(alloc_device_t *dev, int w, int h, int format, int usage, buffer_handle_t *pHandle, int *pStride)
{
if (!pHandle || !pStride)
{
return -EINVAL;
}
size_t size;
size_t stride;
struct timespec time;
int aw_byte_align[3];
clock_gettime(CLOCK_REALTIME, &time);
if (format == HAL_PIXEL_FORMAT_YCbCr_420_888)
{
format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
}
if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP || format == HAL_PIXEL_FORMAT_YV12
/* HAL_PIXEL_FORMAT_YCbCr_420_SP, HAL_PIXEL_FORMAT_YCbCr_420_P, HAL_PIXEL_FORMAT_YCbCr_422_I are not defined in Android.
* To enable Mali DDK EGLImage support for those formats, firstly, you have to add them in Android system/core/include/system/graphics.h.
* Then, define SUPPORT_LEGACY_FORMAT in the same header file(Mali DDK will also check this definition).
*/
#ifdef SUPPORT_LEGACY_FORMAT
|| format == HAL_PIXEL_FORMAT_YCbCr_420_SP || format == HAL_PIXEL_FORMAT_YCbCr_420_P || format == HAL_PIXEL_FORMAT_YCbCr_422_I
#endif
)
{
switch (format)
{
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
stride = GRALLOC_ALIGN(w, 16);
size = GRALLOC_ALIGN(h, 16) * (stride + GRALLOC_ALIGN(stride / 2, 16));
break;
case HAL_PIXEL_FORMAT_YV12:
#ifdef SUPPORT_LEGACY_FORMAT
case HAL_PIXEL_FORMAT_YCbCr_420_P:
#endif
stride = GRALLOC_ALIGN(w, 16);
size = GRALLOC_ALIGN(h, 2) * (stride + GRALLOC_ALIGN(stride / 2, 16));
break;
#ifdef SUPPORT_LEGACY_FORMAT
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
stride = GRALLOC_ALIGN(w, 16);
size = GRALLOC_ALIGN(h, 16) * (stride + GRALLOC_ALIGN(stride / 2, 16));
break;
case HAL_PIXEL_FORMAT_YCbCr_422_I:
stride = GRALLOC_ALIGN(w, 16);
size = h * stride * 2;
break;
#endif
default:
return -EINVAL;
}
aw_byte_align[0] = 16;
aw_byte_align[1] = 16;
aw_byte_align[2] = 16;
} else if (format == HAL_PIXEL_FORMAT_BLOB)
{
if(h != 1) {
ALOGE("%s: Buffers with RAW_OPAQUE/BLOB formats \
must have height==1 ", __FUNCTION__);
return 0;
}
size = w;
} else
{
int bpp = 0;
switch (format)
{
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
bpp = 4;
break;
case HAL_PIXEL_FORMAT_RGB_888:
bpp = 3;
break;
case HAL_PIXEL_FORMAT_RGB_565:
#if PLATFORM_SDK_VERSION < 19
case HAL_PIXEL_FORMAT_RGBA_5551:
case HAL_PIXEL_FORMAT_RGBA_4444:
#endif
bpp = 2;
break;
default:
return -EINVAL;
}
size_t bpr = GRALLOC_ALIGN(w * bpp, 64);
size = bpr * h;
stride = bpr / bpp;
aw_byte_align[0] = 64;
aw_byte_align[1] = 0;
aw_byte_align[2] = 0;
}
int err;
err = gralloc_alloc_buffer(dev, size, usage, pHandle);
if (err < 0)
{
return err;
}
/* match the framebuffer format */
if (usage & GRALLOC_USAGE_HW_FB)
{
#ifdef GRALLOC_16_BITS
format = HAL_PIXEL_FORMAT_RGB_565;
#else
format = HAL_PIXEL_FORMAT_BGRA_8888;
#endif
}
private_handle_t *hnd = (private_handle_t *)*pHandle;
int private_usage = usage & (GRALLOC_USAGE_PRIVATE_0 |
GRALLOC_USAGE_PRIVATE_1);
switch (private_usage)
{
case 0:
hnd->yuv_info = MALI_YUV_BT601_NARROW;
break;
case GRALLOC_USAGE_PRIVATE_1:
hnd->yuv_info = MALI_YUV_BT601_WIDE;
break;
case GRALLOC_USAGE_PRIVATE_0:
hnd->yuv_info = MALI_YUV_BT709_NARROW;
break;
case (GRALLOC_USAGE_PRIVATE_0 | GRALLOC_USAGE_PRIVATE_1):
hnd->yuv_info = MALI_YUV_BT709_WIDE;
break;
}
hnd->width = w;
hnd->height = h;
hnd->format = format;
hnd->stride = stride;
hnd->aw_byte_align[0] = aw_byte_align[0];
hnd->aw_byte_align[1] = aw_byte_align[1];
hnd->aw_byte_align[2] = aw_byte_align[2];
hnd->aw_buf_id = (long long )time.tv_sec * 1000 * 1000 * 1000 + time.tv_nsec;
*pStride = stride;
return 0;
}
static int alloc_device_free(alloc_device_t *dev, buffer_handle_t handle)
{
if (private_handle_t::validate(handle) < 0)
{
return -EINVAL;
}
private_handle_t *hnd = (private_handle_t *)handle;
/* Guarantee aw_buf_id is invalid after calling alloc_device_free */
hnd->aw_buf_id = -1;
if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
{
// free this buffer
private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
const size_t bufferSize = m->finfo.line_length * m->info.yres;
int index = ((uintptr_t)hnd->base - (uintptr_t)m->framebuffer->base) / bufferSize;
m->bufferMask &= ~(1 << index);
close(hnd->fd);
#if GRALLOC_ARM_UMP_MODULE
if ((int)UMP_INVALID_MEMORY_HANDLE != hnd->ump_mem_handle)
{
ump_reference_release((ump_handle)hnd->ump_mem_handle);
}
#endif
}
else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP)
{
#if GRALLOC_ARM_UMP_MODULE
/* Buffer might be unregistered so we need to check for invalid ump handle*/
if ((int)UMP_INVALID_MEMORY_HANDLE != hnd->ump_mem_handle)
{
ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle);
ump_reference_release((ump_handle)hnd->ump_mem_handle);
}
#else
AERR("Can't free ump memory for handle:0x%p. Not supported.", hnd);
#endif
}
else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
{
#if GRALLOC_ARM_DMA_BUF_MODULE
private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
/* Buffer might be unregistered so we need to check for invalid ump handle*/
if (0 != hnd->base)
{
if (0 != munmap((void *)hnd->base, hnd->size))
{
AERR("Failed to munmap handle 0x%p", hnd);
}
}
close(hnd->share_fd);
if (0 != ion_free(m->ion_client, hnd->ion_hnd))
{
AERR("Failed to ion_free( ion_client: %d ion_hnd: %p )", m->ion_client, (void *)(uintptr_t)hnd->ion_hnd);
}
memset((void *)hnd, 0, sizeof(*hnd));
#else
AERR("Can't free dma_buf memory for handle:0x%x. Not supported.", (unsigned int)hnd);
#endif
}
delete hnd;
return 0;
}
static int alloc_device_close(struct hw_device_t *device)
{
alloc_device_t *dev = reinterpret_cast<alloc_device_t *>(device);
if (dev)
{
#if GRALLOC_ARM_DMA_BUF_MODULE
private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
if (0 != ion_close(m->ion_client))
{
AERR("Failed to close ion_client: %d", m->ion_client);
}
close(m->ion_client);
#endif
delete dev;
#if GRALLOC_ARM_UMP_MODULE
ump_close(); // Our UMP memory refs will be released automatically here...
#endif
}
return 0;
}
int alloc_device_open(hw_module_t const *module, const char *name, hw_device_t **device)
{
MALI_IGNORE(name);
alloc_device_t *dev;
dev = new alloc_device_t;
if (NULL == dev)
{
return -1;
}
#if GRALLOC_ARM_UMP_MODULE
ump_result ump_res = ump_open();
if (UMP_OK != ump_res)
{
AERR("UMP open failed with %d", ump_res);
delete dev;
return -1;
}
#endif
/* initialize our state here */
memset(dev, 0, sizeof(*dev));
/* initialize the procs */
dev->common.tag = HARDWARE_DEVICE_TAG;
dev->common.version = 0;
dev->common.module = const_cast<hw_module_t *>(module);
dev->common.close = alloc_device_close;
dev->alloc = alloc_device_alloc;
dev->free = alloc_device_free;
#if GRALLOC_ARM_DMA_BUF_MODULE
private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
m->ion_client = ion_open();
if (m->ion_client < 0)
{
AERR("ion_open failed with %s", strerror(errno));
delete dev;
return -1;
}
#endif
*device = &dev->common;
return 0;
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (C) 2010 ARM Limited. All rights reserved.
*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <hardware/hardware.h>
#ifndef AWAR
#define AWAR(fmt, args...) __android_log_print(ANDROID_LOG_WARN, "[Gralloc-Warning]", "%s:%d " fmt,__func__,__LINE__,##args)
#endif
#ifndef AINF
#define AINF(fmt, args...) __android_log_print(ANDROID_LOG_INFO, "[Gralloc]", fmt,##args)
#endif
#ifndef AERR
#define AERR(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, "[Gralloc-ERROR]", "%s:%d " fmt,__func__,__LINE__,##args)
#endif
#ifndef AERR_IF
#define AERR_IF( eq, fmt, args...) if ( (eq) ) AERR( fmt, args )
#endif
// Create an alloc device
int alloc_device_open(hw_module_t const *module, const char *name, hw_device_t **device);

View file

@ -0,0 +1,505 @@
/*
* Copyright (C) 2010 ARM Limited. All rights reserved.
*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <stdlib.h>
#include <cutils/log.h>
#include <cutils/atomic.h>
#include <hardware/hardware.h>
#include <hardware/gralloc.h>
#include <GLES/gl.h>
#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE
#include "gralloc_vsync_report.h"
#endif
#include "alloc_device.h"
#include "gralloc_priv.h"
#include "gralloc_helper.h"
// numbers of buffers for page flipping
#define NUM_BUFFERS NUM_FB_BUFFERS
static int swapInterval = 1;
enum
{
PAGE_FLIP = 0x00000001,
};
static int fb_set_swap_interval(struct framebuffer_device_t *dev, int interval)
{
if (interval < dev->minSwapInterval)
{
interval = dev->minSwapInterval;
}
else if (interval > dev->maxSwapInterval)
{
interval = dev->maxSwapInterval;
}
swapInterval = interval;
return 0;
}
static int fb_post(struct framebuffer_device_t *dev, buffer_handle_t buffer)
{
if (private_handle_t::validate(buffer) < 0)
{
return -EINVAL;
}
private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(buffer);
private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
if (m->currentBuffer)
{
m->base.unlock(&m->base, m->currentBuffer);
m->currentBuffer = 0;
}
if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
{
m->base.lock(&m->base, buffer, private_module_t::PRIV_USAGE_LOCKED_FOR_POST,
0, 0, m->info.xres, m->info.yres, NULL);
const size_t offset = (uintptr_t)hnd->base - (uintptr_t)m->framebuffer->base;
int interrupt;
m->info.activate = FB_ACTIVATE_VBL;
m->info.yoffset = offset / m->finfo.line_length;
#ifdef STANDARD_LINUX_SCREEN
#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
#define S3CFB_SET_VSYNC_INT _IOW('F', 206, unsigned int)
if (ioctl(m->framebuffer->fd, FBIOPAN_DISPLAY, &m->info) == -1)
{
AERR("FBIOPAN_DISPLAY failed for fd: %d", m->framebuffer->fd);
m->base.unlock(&m->base, buffer);
return 0;
}
if (swapInterval == 1)
{
// enable VSYNC
interrupt = 1;
if (ioctl(m->framebuffer->fd, S3CFB_SET_VSYNC_INT, &interrupt) < 0)
{
// AERR("S3CFB_SET_VSYNC_INT enable failed for fd: %d", m->framebuffer->fd);
return 0;
}
// wait for VSYNC
#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE
gralloc_mali_vsync_report(MALI_VSYNC_EVENT_BEGIN_WAIT);
#endif
int crtc = 0;
if (ioctl(m->framebuffer->fd, FBIO_WAITFORVSYNC, &crtc) < 0)
{
AERR("FBIO_WAITFORVSYNC failed for fd: %d", m->framebuffer->fd);
#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE
gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT);
#endif
return 0;
}
#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE
gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT);
#endif
// disable VSYNC
interrupt = 0;
if (ioctl(m->framebuffer->fd, S3CFB_SET_VSYNC_INT, &interrupt) < 0)
{
AERR("S3CFB_SET_VSYNC_INT disable failed for fd: %d", m->framebuffer->fd);
return 0;
}
}
#else
/*Standard Android way*/
#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE
gralloc_mali_vsync_report(MALI_VSYNC_EVENT_BEGIN_WAIT);
#endif
if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1)
{
AERR("FBIOPUT_VSCREENINFO failed for fd: %d", m->framebuffer->fd);
#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE
gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT);
#endif
m->base.unlock(&m->base, buffer);
return -errno;
}
#ifdef MALI_VSYNC_EVENT_REPORT_ENABLE
gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT);
#endif
#endif
m->currentBuffer = buffer;
}
else
{
void *fb_vaddr;
void *buffer_vaddr;
m->base.lock(&m->base, m->framebuffer, GRALLOC_USAGE_SW_WRITE_RARELY,
0, 0, m->info.xres, m->info.yres, &fb_vaddr);
m->base.lock(&m->base, buffer, GRALLOC_USAGE_SW_READ_RARELY,
0, 0, m->info.xres, m->info.yres, &buffer_vaddr);
memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres);
m->base.unlock(&m->base, buffer);
m->base.unlock(&m->base, m->framebuffer);
}
return 0;
}
int init_frame_buffer_locked(struct private_module_t *module)
{
if (module->framebuffer)
{
return 0; // Nothing to do, already initialized
}
char const *const device_template[] =
{
"/dev/graphics/fb%u",
"/dev/fb%u",
NULL
};
int fd = -1;
int i = 0;
char name[64];
while ((fd == -1) && device_template[i])
{
snprintf(name, 64, device_template[i], 0);
fd = open(name, O_RDWR, 0);
i++;
}
if (fd < 0)
{
return -errno;
}
struct fb_fix_screeninfo finfo;
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
{
return -errno;
}
struct fb_var_screeninfo info;
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
{
return -errno;
}
info.reserved[0] = 0;
info.reserved[1] = 0;
info.reserved[2] = 0;
info.xoffset = 0;
info.yoffset = 0;
info.activate = FB_ACTIVATE_NOW;
#ifdef GRALLOC_16_BITS
/*
* Explicitly request 5/6/5
*/
info.bits_per_pixel = 16;
info.red.offset = 11;
info.red.length = 5;
info.green.offset = 5;
info.green.length = 6;
info.blue.offset = 0;
info.blue.length = 5;
info.transp.offset = 0;
info.transp.length = 0;
#else
/*
* Explicitly request 8/8/8
*/
info.bits_per_pixel = 32;
info.red.offset = 16;
info.red.length = 8;
info.green.offset = 8;
info.green.length = 8;
info.blue.offset = 0;
info.blue.length = 8;
info.transp.offset = 0;
info.transp.length = 0;
#endif
/*
* Request NUM_BUFFERS screens (at lest 2 for page flipping)
*/
info.yres_virtual = info.yres * NUM_BUFFERS;
uint32_t flags = PAGE_FLIP;
if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1)
{
info.yres_virtual = info.yres;
flags &= ~PAGE_FLIP;
AWAR("FBIOPUT_VSCREENINFO failed, page flipping not supported fd: %d", fd);
}
if (info.yres_virtual < info.yres * 2)
{
// we need at least 2 for page-flipping
info.yres_virtual = info.yres;
flags &= ~PAGE_FLIP;
AWAR("page flipping not supported (yres_virtual=%d, requested=%d)", info.yres_virtual, info.yres * 2);
}
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
{
return -errno;
}
int refreshRate = 0;
if (info.pixclock > 0)
{
refreshRate = 1000000000000000LLU /
(
uint64_t(info.upper_margin + info.lower_margin + info.yres + info.hsync_len)
* (info.left_margin + info.right_margin + info.xres + info.vsync_len)
* info.pixclock
);
}
else
{
AWAR("fbdev pixclock is zero for fd: %d", fd);
}
if (refreshRate == 0)
{
refreshRate = 60 * 1000; // 60 Hz
}
if (int(info.width) <= 0 || int(info.height) <= 0)
{
// the driver doesn't return that information
// default to 160 dpi
info.width = ((info.xres * 25.4f) / 160.0f + 0.5f);
info.height = ((info.yres * 25.4f) / 160.0f + 0.5f);
}
float xdpi = (info.xres * 25.4f) / info.width;
float ydpi = (info.yres * 25.4f) / info.height;
float fps = refreshRate / 1000.0f;
AINF("using (fd=%d)\n"
"id = %s\n"
"xres = %d px\n"
"yres = %d px\n"
"xres_virtual = %d px\n"
"yres_virtual = %d px\n"
"bpp = %d\n"
"r = %2u:%u\n"
"g = %2u:%u\n"
"b = %2u:%u\n",
fd,
finfo.id,
info.xres,
info.yres,
info.xres_virtual,
info.yres_virtual,
info.bits_per_pixel,
info.red.offset, info.red.length,
info.green.offset, info.green.length,
info.blue.offset, info.blue.length);
AINF("width = %d mm (%f dpi)\n"
"height = %d mm (%f dpi)\n"
"refresh rate = %.2f Hz\n",
info.width, xdpi,
info.height, ydpi,
fps);
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
{
return -errno;
}
if (finfo.smem_len <= 0)
{
return -errno;
}
module->flags = flags;
module->info = info;
module->finfo = finfo;
module->xdpi = xdpi;
module->ydpi = ydpi;
module->fps = fps;
/*
* map the framebuffer
*/
size_t fbSize = round_up_to_page_size(finfo.line_length * info.yres_virtual);
void *vaddr = mmap(0, fbSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (vaddr == MAP_FAILED)
{
AERR("Error mapping the framebuffer (%s)", strerror(errno));
return -errno;
}
memset(vaddr, 0, fbSize);
// Create a "fake" buffer object for the entire frame buffer memory, and store it in the module
module->framebuffer = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, 0, fbSize, vaddr,
0, dup(fd), 0);
module->numBuffers = info.yres_virtual / info.yres;
module->bufferMask = 0;
#if GRALLOC_ARM_UMP_MODULE
#ifdef IOCTL_GET_FB_UMP_SECURE_ID
ioctl(fd, IOCTL_GET_FB_UMP_SECURE_ID, &module->framebuffer->ump_id);
#endif
if ((int)UMP_INVALID_SECURE_ID != module->framebuffer->ump_id)
{
AINF("framebuffer accessed with UMP secure ID %i\n", module->framebuffer->ump_id);
}
#endif
return 0;
}
static int init_frame_buffer(struct private_module_t *module)
{
pthread_mutex_lock(&module->lock);
int err = init_frame_buffer_locked(module);
pthread_mutex_unlock(&module->lock);
return err;
}
static int fb_close(struct hw_device_t *device)
{
framebuffer_device_t *dev = reinterpret_cast<framebuffer_device_t *>(device);
if (dev)
{
#if GRALLOC_ARM_UMP_MODULE
ump_close();
#endif
free(dev);
}
return 0;
}
int compositionComplete(struct framebuffer_device_t *dev)
{
MALI_IGNORE(dev);
/* By doing a finish here we force the GL driver to start rendering
all the drawcalls up to this point, and to wait for the rendering to be complete.*/
glFinish();
/* The rendering of the backbuffer is now completed.
When SurfaceFlinger later does a call to eglSwapBuffer(), the swap will be done
synchronously in the same thread, and not asynchronoulsy in a background thread later.
The SurfaceFlinger requires this behaviour since it releases the lock on all the
SourceBuffers (Layers) after the compositionComplete() function returns.
However this "bad" behaviour by SurfaceFlinger should not affect performance,
since the Applications that render the SourceBuffers (Layers) still get the
full renderpipeline using asynchronous rendering. So they perform at maximum speed,
and because of their complexity compared to the Surface flinger jobs, the Surface flinger
is normally faster even if it does everyhing synchronous and serial.
*/
return 0;
}
int framebuffer_device_open(hw_module_t const *module, const char *name, hw_device_t **device)
{
int status = -EINVAL;
alloc_device_t *gralloc_device;
status = gralloc_open(module, &gralloc_device);
if (status < 0)
{
return status;
}
private_module_t *m = (private_module_t *)module;
status = init_frame_buffer(m);
if (status < 0)
{
gralloc_close(gralloc_device);
return status;
}
/* initialize our state here */
framebuffer_device_t *dev = (framebuffer_device_t *)malloc(sizeof(framebuffer_device_t));
memset(dev, 0, sizeof(*dev));
/* initialize the procs */
dev->common.tag = HARDWARE_DEVICE_TAG;
dev->common.version = 0;
dev->common.module = const_cast<hw_module_t *>(module);
dev->common.close = fb_close;
dev->setSwapInterval = fb_set_swap_interval;
dev->post = fb_post;
dev->setUpdateRect = 0;
dev->compositionComplete = &compositionComplete;
int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);
const_cast<uint32_t &>(dev->flags) = 0;
const_cast<uint32_t &>(dev->width) = m->info.xres;
const_cast<uint32_t &>(dev->height) = m->info.yres;
const_cast<int &>(dev->stride) = stride;
#ifdef GRALLOC_16_BITS
const_cast<int &>(dev->format) = HAL_PIXEL_FORMAT_RGB_565;
#else
const_cast<int &>(dev->format) = HAL_PIXEL_FORMAT_BGRA_8888;
#endif
const_cast<float &>(dev->xdpi) = m->xdpi;
const_cast<float &>(dev->ydpi) = m->ydpi;
const_cast<float &>(dev->fps) = m->fps;
const_cast<int &>(dev->minSwapInterval) = 0;
const_cast<int &>(dev->maxSwapInterval) = 1;
*device = &dev->common;
status = 0;
MALI_IGNORE(name);
return status;
}

View file

@ -0,0 +1,25 @@
/*
* Copyright (C) 2010 ARM Limited. All rights reserved.
*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <hardware/hardware.h>
// Create a framebuffer device
int framebuffer_device_open(hw_module_t const *module, const char *name, hw_device_t **device);
// Initialize the framebuffer (must keep module lock before calling
int init_frame_buffer_locked(struct private_module_t *module);

View file

@ -0,0 +1,29 @@
/*
* Copyright (C) 2010 ARM Limited. All rights reserved.
*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GRALLOC_HELPER_H_
#define GRALLOC_HELPER_H_
#include <sys/mman.h>
inline size_t round_up_to_page_size(size_t x)
{
return (x + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
}
#endif /* GRALLOC_HELPER_H_ */

View file

@ -0,0 +1,545 @@
/*
* Copyright (C) 2010 ARM Limited. All rights reserved.
*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <cutils/log.h>
#include <cutils/atomic.h>
#include <hardware/hardware.h>
#include <hardware/gralloc.h>
#include <sys/sysinfo.h>
#include "gralloc_priv.h"
#include "alloc_device.h"
#include "framebuffer_device.h"
#if GRALLOC_ARM_UMP_MODULE
#include <ump/ump_ref_drv.h>
static int s_ump_is_open = 0;
#endif
#if GRALLOC_ARM_DMA_BUF_MODULE
#include <linux/ion.h>
#include <ion/ion.h>
#include <sys/mman.h>
#endif
static pthread_mutex_t s_map_lock = PTHREAD_MUTEX_INITIALIZER;
extern aw_mem_info_data aw_mem_info;
static void get_dram_size(void)
{
struct sysinfo s_info;
int err;
err = sysinfo(&s_info);
if(err)
AERR("%s(%d): Failed to get dram size!\n", __func__, __LINE__);
else
aw_mem_info.dram_size = s_info.totalram/1024/1024;
}
static void get_secure_level(void)
{
char secure_level[PROPERTY_VALUE_MAX] = {0};
property_get("ro.sys.widevine_oemcrypto_level", secure_level, "3");
if(atoi(secure_level))
aw_mem_info.secure_level = atoi(secure_level);
}
static void get_ion_flush_cache_range(void)
{
char ion_flush_cache_range[PROPERTY_VALUE_MAX] = {0};
property_get("ro.sys.ion_flush_cache_range", ion_flush_cache_range, "0");
if(atoi(ion_flush_cache_range) == 1)
aw_mem_info.ion_flush_cache_range = 1;
}
static void get_carveout_enable(void)
{
char carveout_enable[PROPERTY_VALUE_MAX] = {0};
property_get("ro.sys.gralloc_carveout_enable", carveout_enable, "0");
if(atoi(carveout_enable) == 1)
aw_mem_info.carveout_enable = 1;
}
static void get_iommu_type(void)
{
char iomem_type[PROPERTY_VALUE_MAX] = {0};
/*
* ro.kernel.iomem.type
* 0xaf10: IOMMU
* 0xfa01: CMA
*/
property_get("ro.kernel.iomem.type", iomem_type, "0xfa01");
if (!strncmp(iomem_type, "0xaf10", 6))
aw_mem_info.iommu_enabled = true;
else
aw_mem_info.iommu_enabled = false;
}
static int gralloc_device_open(const hw_module_t *module, const char *name, hw_device_t **device)
{
int status = -EINVAL;
if (!strncmp(name, GRALLOC_HARDWARE_GPU0, MALI_GRALLOC_HARDWARE_MAX_STR_LEN))
{
status = alloc_device_open(module, name, device);
}
// else if (!strncmp(name, GRALLOC_HARDWARE_FB0, MALI_GRALLOC_HARDWARE_MAX_STR_LEN))
// {
// status = framebuffer_device_open(module, name, device);
// }
get_dram_size();
get_secure_level();
get_ion_flush_cache_range();
get_carveout_enable();
get_iommu_type();
if (get_gralloc_debug())
{
AINF("Dram size is %d MB\n", aw_mem_info.dram_size);
AINF("Secure level is %d\n", aw_mem_info.secure_level);
AINF("ION flush Cache range: %s\n", aw_mem_info.ion_flush_cache_range == 1 ? "Yes" : "No");
AINF("Carveout enable: %s\n", aw_mem_info.carveout_enable == 1 ? "Yes" : "No");
AINF("IOMMU is %s\n", aw_mem_info.iommu_enabled ? "enabled" : "disabled");
}
return status;
}
static int gralloc_register_buffer(gralloc_module_t const *module, buffer_handle_t handle)
{
MALI_IGNORE(module);
if (private_handle_t::validate(handle) < 0)
{
AERR("Registering invalid buffer 0x%p, returning error", handle);
return -EINVAL;
}
// if this handle was created in this process, then we keep it as is.
private_handle_t *hnd = (private_handle_t *)handle;
int retval = -EINVAL;
pthread_mutex_lock(&s_map_lock);
#if GRALLOC_ARM_UMP_MODULE
if (!s_ump_is_open)
{
ump_result res = ump_open(); // MJOLL-4012: UMP implementation needs a ump_close() for each ump_open
if (res != UMP_OK)
{
pthread_mutex_unlock(&s_map_lock);
AERR("Failed to open UMP library with res=%d", res);
return retval;
}
s_ump_is_open = 1;
}
#endif
hnd->pid = getpid();
if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
{
AERR("Can't register buffer 0x%p as it is a framebuffer", handle);
}
else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP)
{
#if GRALLOC_ARM_UMP_MODULE
hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id);
if (UMP_INVALID_MEMORY_HANDLE != (ump_handle)hnd->ump_mem_handle)
{
hnd->base = ump_mapped_pointer_get((ump_handle)hnd->ump_mem_handle);
if (0 != hnd->base)
{
hnd->writeOwner = 0;
hnd->lockState &= ~(private_handle_t::LOCK_STATE_UNREGISTERED);
pthread_mutex_unlock(&s_map_lock);
return 0;
}
else
{
AERR("Failed to map UMP handle 0x%x", hnd->ump_mem_handle);
}
ump_reference_release((ump_handle)hnd->ump_mem_handle);
}
else
{
AERR("Failed to create UMP handle 0x%x", hnd->ump_mem_handle);
}
#else
AERR("Gralloc does not support UMP. Unable to register UMP memory for handle 0x%p", hnd);
#endif
}
else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
{
#if GRALLOC_ARM_DMA_BUF_MODULE
int ret;
unsigned char *mappedAddress;
size_t size = hnd->size;
hw_module_t *pmodule = NULL;
private_module_t *m = NULL;
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0)
{
m = reinterpret_cast<private_module_t *>(pmodule);
}
else
{
AERR("Could not get gralloc module for handle: 0x%p", hnd);
retval = -errno;
goto cleanup;
}
/* the test condition is set to m->ion_client <= 0 here, because:
* 1) module structure are initialized to 0 if no initial value is applied
* 2) a second user process should get a ion fd greater than 0.
*/
if (m->ion_client <= 0)
{
/* a second user process must obtain a client handle first via ion_open before it can obtain the shared ion buffer*/
m->ion_client = ion_open();
if (m->ion_client < 0)
{
AERR("Could not open ion device for handle: 0x%p", hnd);
retval = -errno;
goto cleanup;
}
}
mappedAddress = (unsigned char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_fd, 0);
if (MAP_FAILED == mappedAddress)
{
AERR("mmap( share_fd:%d ) failed with %s", hnd->share_fd, strerror(errno));
retval = -errno;
goto cleanup;
}
hnd->base = mappedAddress + hnd->offset;
hnd->lockState &= ~(private_handle_t::LOCK_STATE_UNREGISTERED);
pthread_mutex_unlock(&s_map_lock);
return 0;
#endif
}
else
{
AERR("registering non-UMP buffer not supported. flags = %d", hnd->flags);
}
#if GRALLOC_ARM_DMA_BUF_MODULE
cleanup:
#endif
pthread_mutex_unlock(&s_map_lock);
return retval;
}
static void unmap_buffer(private_handle_t *hnd)
{
if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP)
{
#if GRALLOC_ARM_UMP_MODULE
ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle);
ump_reference_release((ump_handle)hnd->ump_mem_handle);
hnd->ump_mem_handle = (int)UMP_INVALID_MEMORY_HANDLE;
#else
AERR("Can't unregister UMP buffer for handle 0x%p. Not supported", hnd);
#endif
}
else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
{
#if GRALLOC_ARM_DMA_BUF_MODULE
void *base = (void *)hnd->base;
size_t size = hnd->size;
if (munmap(base, size) < 0)
{
AERR("Could not munmap base:0x%p size:%lu '%s'", base, (unsigned long)size, strerror(errno));
}
#else
AERR("Can't unregister DMA_BUF buffer for hnd %p. Not supported", hnd);
#endif
}
else
{
AERR("Unregistering unknown buffer is not supported. Flags = %d", hnd->flags);
}
hnd->base = 0;
hnd->lockState = 0;
hnd->writeOwner = 0;
}
static int gralloc_unregister_buffer(gralloc_module_t const *module, buffer_handle_t handle)
{
MALI_IGNORE(module);
if (private_handle_t::validate(handle) < 0)
{
AERR("unregistering invalid buffer 0x%p, returning error", handle);
return -EINVAL;
}
private_handle_t *hnd = (private_handle_t *)handle;
AERR_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK, "[unregister] handle %p still locked (state=%08x)", hnd, hnd->lockState);
if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
{
AERR("Can't unregister buffer 0x%p as it is a framebuffer", handle);
}
else if (hnd->pid == getpid()) // never unmap buffers that were not registered in this process
{
pthread_mutex_lock(&s_map_lock);
hnd->lockState &= ~(private_handle_t::LOCK_STATE_MAPPED);
/* if handle is still locked, the unmapping would not happen until unlocked*/
if (!(hnd->lockState & private_handle_t::LOCK_STATE_WRITE))
{
unmap_buffer(hnd);
}
hnd->lockState |= private_handle_t::LOCK_STATE_UNREGISTERED;
pthread_mutex_unlock(&s_map_lock);
}
else
{
AERR("Trying to unregister buffer 0x%p from process %d that was not created in current process: %d", hnd, hnd->pid, getpid());
}
return 0;
}
static int gralloc_lock(gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t, int w, int h, void **vaddr)
{
if (private_handle_t::validate(handle) < 0)
{
AERR("Locking invalid buffer 0x%p, returning error", handle);
return -EINVAL;
}
private_handle_t *hnd = (private_handle_t *)handle;
pthread_mutex_lock(&s_map_lock);
if (hnd->lockState & private_handle_t::LOCK_STATE_UNREGISTERED)
{
AERR("Locking on an unregistered buffer 0x%p, returning error", hnd);
pthread_mutex_unlock(&s_map_lock);
return -EINVAL;
}
if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP || hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
{
hnd->writeOwner = (usage & GRALLOC_USAGE_SW_WRITE_OFTEN) == GRALLOC_USAGE_SW_WRITE_OFTEN;
}
hnd->lockState |= private_handle_t::LOCK_STATE_WRITE;
pthread_mutex_unlock(&s_map_lock);
if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
{
*vaddr = (void *)hnd->base;
}
MALI_IGNORE(module);
MALI_IGNORE(l);
MALI_IGNORE(t);
MALI_IGNORE(w);
MALI_IGNORE(h);
return 0;
}
static int gralloc_unlock(gralloc_module_t const *module, buffer_handle_t handle)
{
MALI_IGNORE(module);
if (private_handle_t::validate(handle) < 0)
{
AERR("Unlocking invalid buffer 0x%p, returning error", handle);
return -EINVAL;
}
private_handle_t *hnd = (private_handle_t *)handle;
if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP && hnd->writeOwner)
{
#if GRALLOC_ARM_UMP_MODULE
ump_cpu_msync_now((ump_handle)hnd->ump_mem_handle, UMP_MSYNC_CLEAN_AND_INVALIDATE, (void *)hnd->base, hnd->size);
#else
AERR("Buffer 0x%p is UMP type but it is not supported", hnd);
#endif
}
else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION && hnd->writeOwner)
{
#if GRALLOC_ARM_DMA_BUF_MODULE
hw_module_t *pmodule = NULL;
private_module_t *m = NULL;
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0)
{
m = reinterpret_cast<private_module_t *>(pmodule);
if (aw_flush_cache(m->ion_client, (void *)hnd->base, hnd->share_fd, (size_t)hnd->size))
AERR("Failed to flush Cache, err = %d\n", errno);
}
else
{
AERR("Couldnot get gralloc module for handle 0x%p\n", handle);
}
#endif
}
pthread_mutex_lock(&s_map_lock);
hnd->lockState &= ~(private_handle_t::LOCK_STATE_WRITE);
/* if the handle has already been unregistered, unmap it here*/
if (hnd->lockState & private_handle_t::LOCK_STATE_UNREGISTERED)
{
unmap_buffer(hnd);
}
pthread_mutex_unlock(&s_map_lock);
return 0;
}
#define GRALLOC_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1))
static int gralloc_lock_ycbcr(struct gralloc_module_t const* module,
buffer_handle_t handle, int usage,
int l, int t, int w, int h,
struct android_ycbcr *ycbcr)
{
private_handle_t* hnd = (private_handle_t*)handle;
int ystride = GRALLOC_ALIGN(hnd->width, 16);
int cstride, aligned_height;
switch (hnd->format)
{
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
aligned_height = GRALLOC_ALIGN(hnd->height, 16);
ycbcr->y = hnd->base;
ycbcr->cr = (void *)((uintptr_t)hnd->base + ystride * aligned_height);
ycbcr->cb = (void *)((uintptr_t)ycbcr->cr + 1);
ycbcr->ystride = ystride;
ycbcr->cstride = ystride;
ycbcr->chroma_step = 2;
break;
case HAL_PIXEL_FORMAT_YV12:
cstride = GRALLOC_ALIGN(ystride / 2, 16);
aligned_height = GRALLOC_ALIGN(hnd->height, 2);
ycbcr->y = hnd->base;
ycbcr->cr = (void *)((uintptr_t)hnd->base + ystride * aligned_height);
ycbcr->cb = (void *)((uintptr_t)ycbcr->cr + cstride * aligned_height / 2);
ycbcr->ystride = ystride;
ycbcr->cstride = cstride;
ycbcr->chroma_step = 1;
break;
default:
AERR("%s: Invalid format 0x%x", __FUNCTION__, hnd->format);
return -EINVAL;
}
MALI_IGNORE(module);
MALI_IGNORE(usage);
MALI_IGNORE(l);
MALI_IGNORE(t);
MALI_IGNORE(w);
MALI_IGNORE(h);
return 0;
}
// There is one global instance of the module
static struct hw_module_methods_t gralloc_module_methods =
{
.open = gralloc_device_open
};
private_module_t::private_module_t()
{
#define INIT_ZERO(obj) (memset(&(obj),0,sizeof((obj))))
base.common.tag = HARDWARE_MODULE_TAG;
base.common.version_major = 1;
base.common.version_minor = 0;
base.common.id = GRALLOC_HARDWARE_MODULE_ID;
base.common.name = "Graphics Memory Allocator Module";
base.common.author = "ARM Ltd.";
base.common.methods = &gralloc_module_methods;
base.common.dso = NULL;
INIT_ZERO(base.common.reserved);
base.registerBuffer = gralloc_register_buffer;
base.unregisterBuffer = gralloc_unregister_buffer;
base.lock = gralloc_lock;
base.unlock = gralloc_unlock;
base.lock_ycbcr = gralloc_lock_ycbcr;
base.perform = NULL;
INIT_ZERO(base.reserved_proc);
framebuffer = NULL;
flags = 0;
numBuffers = 0;
bufferMask = 0;
pthread_mutex_init(&(lock), NULL);
currentBuffer = NULL;
INIT_ZERO(info);
INIT_ZERO(finfo);
xdpi = 0.0f;
ydpi = 0.0f;
fps = 0.0f;
#undef INIT_ZERO
};
/*
* HAL_MODULE_INFO_SYM will be initialized using the default constructor
* implemented above
*/
struct private_module_t HAL_MODULE_INFO_SYM;

View file

@ -0,0 +1,390 @@
/*
* Copyright (C) 2010 ARM Limited. All rights reserved.
*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GRALLOC_PRIV_H_
#define GRALLOC_PRIV_H_
#include <stdint.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <linux/fb.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/ion.h>
#include <sys/ioctl.h>
#include <hardware/gralloc.h>
#include <cutils/native_handle.h>
#include <alloc_device.h>
#include <utils/Log.h>
#include <cutils/properties.h>
#ifdef MALI_600
#define GRALLOC_ARM_UMP_MODULE 0
#define GRALLOC_ARM_DMA_BUF_MODULE 1
#else
/* NOTE:
* If your framebuffer device driver is integrated with UMP, you will have to
* change this IOCTL definition to reflect your integration with the framebuffer
* device.
* Expected return value is a UMP secure id backing your framebuffer device memory.
*/
/*#define IOCTL_GET_FB_UMP_SECURE_ID _IOR('F', 311, unsigned int)*/
#define GRALLOC_ARM_UMP_MODULE 0
#define GRALLOC_ARM_DMA_BUF_MODULE 1
/* NOTE:
* If your framebuffer device driver is integrated with dma_buf, you will have to
* change this IOCTL definition to reflect your integration with the framebuffer
* device.
* Expected return value is a structure filled with a file descriptor
* backing your framebuffer device memory.
*/
#if GRALLOC_ARM_DMA_BUF_MODULE
struct fb_dmabuf_export
{
__u32 fd;
__u32 flags;
};
/*#define FBIOGET_DMABUF _IOR('F', 0x21, struct fb_dmabuf_export)*/
typedef int ion_user_handle_t;
#define ION_INVALID_HANDLE 0
#endif /* GRALLOC_ARM_DMA_BUF_MODULE */
#endif
/* the max string size of GRALLOC_HARDWARE_GPU0 & GRALLOC_HARDWARE_FB0
* 8 is big enough for "gpu0" & "fb0" currently
*/
#define MALI_GRALLOC_HARDWARE_MAX_STR_LEN 8
/*
*Numbers of buffers for page flipping (at least 2).
*NUM_FRAMEBUFFER_SURFACE_BUFFERS should be equal to NUM_FB_BUFFERS
*in android/device/softwinner/<board-name>-common/BoardConfigCommon.mk.
*/
#define NUM_FB_BUFFERS 3
#if GRALLOC_ARM_UMP_MODULE
#include <ump/ump.h>
#endif
#define MALI_IGNORE(x) (void)x
typedef enum
{
MALI_YUV_NO_INFO,
MALI_YUV_BT601_NARROW,
MALI_YUV_BT601_WIDE,
MALI_YUV_BT709_NARROW,
MALI_YUV_BT709_WIDE,
} mali_gralloc_yuv_info;
struct private_handle_t;
struct private_module_t
{
gralloc_module_t base;
private_handle_t *framebuffer;
uint32_t flags;
uint32_t numBuffers;
uint32_t bufferMask;
pthread_mutex_t lock;
buffer_handle_t currentBuffer;
int ion_client;
struct fb_var_screeninfo info;
struct fb_fix_screeninfo finfo;
float xdpi;
float ydpi;
float fps;
enum
{
// flag to indicate we'll post this buffer
PRIV_USAGE_LOCKED_FOR_POST = 0x80000000
};
/* default constructor */
private_module_t();
};
#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,
/* This flag is used to tell hwcomposer if the current buffer is physical continous, zero means not physical continous */
PRIV_FLAGS_USES_CONFIG = 0x00000008,
};
enum
{
LOCK_STATE_WRITE = 1 << 31,
LOCK_STATE_MAPPED = 1 << 30,
LOCK_STATE_UNREGISTERED = 1 << 29,
LOCK_STATE_READ_MASK = 0x3FFFFFFF
};
// ints
#if GRALLOC_ARM_DMA_BUF_MODULE
/*shared file descriptor for dma_buf sharing*/
int share_fd;
#endif
int magic;
int flags;
int usage;
int size;
int width;
int height;
int format;
int stride;
int aw_byte_align[3];
union
{
void *base;
uint64_t padding;
};
int lockState;
int writeOwner;
int pid;
mali_gralloc_yuv_info yuv_info;
// Following members are for UMP memory only
#if GRALLOC_ARM_UMP_MODULE
int ump_id;
int ump_mem_handle;
#endif
// Following members is for framebuffer only
int fd;
int offset;
#if GRALLOC_ARM_DMA_BUF_MODULE
ion_user_handle_t ion_hnd;
#endif
long long aw_buf_id;
#if GRALLOC_ARM_DMA_BUF_MODULE
#define GRALLOC_ARM_NUM_FDS 1
#else
#define GRALLOC_ARM_NUM_FDS 0
#endif
#ifdef __cplusplus
static const int sNumFds = GRALLOC_ARM_NUM_FDS;
static const int sMagic = 0x3141592;
#if GRALLOC_ARM_UMP_MODULE
private_handle_t(int flags, int usage, int size, void *base, int lock_state, ump_secure_id secure_id, ump_handle handle):
#if GRALLOC_ARM_DMA_BUF_MODULE
share_fd(-1),
#endif
magic(sMagic),
flags(flags),
usage(usage),
size(size),
width(0),
height(0),
format(0),
stride(0),
base(base),
lockState(lock_state),
writeOwner(0),
pid(getpid()),
yuv_info(MALI_YUV_NO_INFO),
ump_id((int)secure_id),
ump_mem_handle((int)handle),
fd(0),
offset(0)
#if GRALLOC_ARM_DMA_BUF_MODULE
,
ion_hnd(ION_INVALID_HANDLE)
#endif
{
version = sizeof(native_handle);
numFds = sNumFds;
numInts = (sizeof(private_handle_t) - sizeof(native_handle)) / sizeof(int) - sNumFds;
}
#endif
#if GRALLOC_ARM_DMA_BUF_MODULE
private_handle_t(int flags, int usage, int size, void *base, int lock_state):
share_fd(-1),
magic(sMagic),
flags(flags),
usage(usage),
size(size),
width(0),
height(0),
format(0),
stride(0),
base(base),
lockState(lock_state),
writeOwner(0),
pid(getpid()),
yuv_info(MALI_YUV_NO_INFO),
#if GRALLOC_ARM_UMP_MODULE
ump_id((int)UMP_INVALID_SECURE_ID),
ump_mem_handle((int)UMP_INVALID_MEMORY_HANDLE),
#endif
fd(0),
offset(0),
ion_hnd(ION_INVALID_HANDLE)
{
version = sizeof(native_handle);
numFds = sNumFds;
numInts = (sizeof(private_handle_t) - sizeof(native_handle)) / sizeof(int) - sNumFds;
}
#endif
private_handle_t(int flags, int usage, int size, void *base, int lock_state, int fb_file, int fb_offset):
#if GRALLOC_ARM_DMA_BUF_MODULE
share_fd(-1),
#endif
magic(sMagic),
flags(flags),
usage(usage),
size(size),
width(0),
height(0),
format(0),
stride(0),
base(base),
lockState(lock_state),
writeOwner(0),
pid(getpid()),
yuv_info(MALI_YUV_NO_INFO),
#if GRALLOC_ARM_UMP_MODULE
ump_id((int)UMP_INVALID_SECURE_ID),
ump_mem_handle((int)UMP_INVALID_MEMORY_HANDLE),
#endif
fd(fb_file),
offset(fb_offset)
#if GRALLOC_ARM_DMA_BUF_MODULE
,
ion_hnd(ION_INVALID_HANDLE)
#endif
{
version = sizeof(native_handle);
numFds = sNumFds;
numInts = (sizeof(private_handle_t) - sizeof(native_handle)) / sizeof(int) - sNumFds;
}
~private_handle_t()
{
magic = 0;
}
bool usesPhysicallyContiguousMemory()
{
return (flags & PRIV_FLAGS_FRAMEBUFFER) ? true : false;
}
static int validate(const native_handle *h)
{
const private_handle_t *hnd = (const private_handle_t *)h;
if (!h || h->version != sizeof(native_handle) || h->numFds != sNumFds ||
h->numInts != (sizeof(private_handle_t) - sizeof(native_handle)) / sizeof(int) - sNumFds ||
hnd->magic != sMagic)
{
return -EINVAL;
}
return 0;
}
static private_handle_t *dynamicCast(const native_handle *in)
{
if (validate(in) == 0)
{
return (private_handle_t *) in;
}
return NULL;
}
#endif
};
typedef struct
{
int dram_size; /* MB */
/*
* For allwinner platforms, there are just two secure levels:
* 1: the system is with secure os.
* 3: the system is without secure os.
*/
int secure_level;
/* This flag is used to flush cache on ARMv7 */
bool ion_flush_cache_range;
/* If CARVEOUT HEAP is available, this should be true. */
bool carveout_enable;
/*
* ro.kernel.iomem.type = 0xaf10 -> IOMMU is enabled
* ro.kernel.iomem.type = 0xfa01 -> IOMMU is disabled
*/
bool iommu_enabled;
}
aw_mem_info_data;
typedef struct {
long start;
long end;
}sunxi_cache_range;
int aw_flush_cache(int ion_client, void* start_vaddr, int shared_fd, size_t size);
static inline bool get_gralloc_debug(void)
{
char gralloc_debug[PROPERTY_VALUE_MAX] = {0};
property_get("debug.gralloc.showmsg", gralloc_debug, "0");
if(atoi(gralloc_debug))
return true;
return false;
}
#endif /* GRALLOC_PRIV_H_ */

View file

@ -0,0 +1,41 @@
/*
* Copyright (C) 2011 ARM Limited. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GRALLOC_VSYNC_REPORT_H_
#define GRALLOC_VSYNC_REPORT_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef enum mali_vsync_event
{
MALI_VSYNC_EVENT_BEGIN_WAIT = 0,
MALI_VSYNC_EVENT_END_WAIT
} mali_vsync_event;
extern void _mali_base_arch_vsync_event_report(mali_vsync_event);
inline void gralloc_mali_vsync_report(mali_vsync_event event)
{
_mali_base_arch_vsync_event_report(event);
}
#ifdef __cplusplus
}
#endif
#endif /* GRALLOC_VSYNC_REPORT_H_ */

View file

@ -0,0 +1,13 @@
mali400: r8p1-00rel0 um android oreo_mr1 arm 003
Fix mali-utgard prerotate issue on Android O;
Build parameters:
VARIANT=mali400-r1p1-gles-linux-android-oreo-prerotate-no_profiling-dma_buf-rgb_is_xrgb-no_Werror-egl_wait_sync
TARGET_TOOLCHAIN=arm-linux-gcc-vfp
TARGET_PLATFORM=default_7a
CONFIG=release
CROSS_COMPILE=arm-linux-androideabi-
MD5 Info:
8c08974b16b879e04a122c70f7afb4b7 lib/libGLES_mali.so

View file

@ -0,0 +1,14 @@
mali400: r8p1-00rel0 um android oreo_mr1 arm64 003
Fix mali-utgard prerotate issue on Android O;
Build parameters:
VARIANT=mali400-r1p1-gles-linux-android-oreo-prerotate-no_profiling-dma_buf-rgb_is_xrgb-no_Werror-egl_wait_sync
TARGET_TOOLCHAIN=aarch64-linux-gcc
TARGET_PLATFORM=default_8a
CONFIG=release
CROSS_COMPILE=aarch64-linux-
MD5 Info:
5e47d50472785b632c0835cb36836196 lib/libGLES_mali.so
955a65789eb92586d356385c1714b4d6 lib64/libGLES_mali.so