gralloc: Refactor, ion support
- Add ION support - Refactor the design Change-Id: I5b067b0aca1235ee8c01c256e025f416bb56f560
This commit is contained in:
parent
cbb0b78679
commit
9c050e95ec
@ -1 +1,7 @@
|
||||
# Empty Android.mk
|
||||
# Build only new gralloc
|
||||
|
||||
ifeq ($(TARGET_USES_ION),true)
|
||||
display-hals := libgralloc
|
||||
include $(call all-named-subdir-makefiles,$(display-hals))
|
||||
endif
|
||||
|
||||
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* 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_QSD8K_GPU_H_
|
||||
#define GRALLOC_QSD8K_GPU_H_
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <cutils/ashmem.h>
|
||||
|
||||
#include "gralloc_priv.h"
|
||||
#include "pmemalloc.h"
|
||||
|
||||
|
||||
class gpu_context_t : public alloc_device_t {
|
||||
public:
|
||||
|
||||
class Deps {
|
||||
public:
|
||||
|
||||
virtual ~Deps();
|
||||
|
||||
// ashmem
|
||||
virtual int ashmem_create_region(const char *name, size_t size) = 0;
|
||||
|
||||
// POSIX
|
||||
virtual int close(int fd) = 0;
|
||||
|
||||
// Framebuffer (locally defined)
|
||||
virtual int mapFrameBufferLocked(struct private_module_t* module) = 0;
|
||||
virtual int terminateBuffer(gralloc_module_t const* module,
|
||||
private_handle_t* hnd) = 0;
|
||||
};
|
||||
|
||||
gpu_context_t(Deps& deps, PmemAllocator& pmemAllocator,
|
||||
PmemAllocator& pmemAdspAllocator, const private_module_t* module);
|
||||
|
||||
int gralloc_alloc_framebuffer_locked(size_t size, int usage,
|
||||
buffer_handle_t* pHandle);
|
||||
int gralloc_alloc_framebuffer(size_t size, int usage,
|
||||
buffer_handle_t* pHandle);
|
||||
int gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t* pHandle, int bufferType, int format,
|
||||
int width, int height);
|
||||
int free_impl(private_handle_t const* hnd);
|
||||
int alloc_impl(int w, int h, int format, int usage,
|
||||
buffer_handle_t* pHandle, int* pStride, int bufferSize = 0);
|
||||
|
||||
static int gralloc_alloc(alloc_device_t* dev, int w, int h, int format,
|
||||
int usage, buffer_handle_t* pHandle, int* pStride);
|
||||
static int gralloc_free(alloc_device_t* dev, buffer_handle_t handle);
|
||||
static int gralloc_alloc_size(alloc_device_t* dev, int w, int h, int format,
|
||||
int usage, buffer_handle_t* pHandle, int* pStride, int bufferSize);
|
||||
static int gralloc_close(struct hw_device_t *dev);
|
||||
int get_composition_type() const { return compositionType; }
|
||||
|
||||
private:
|
||||
|
||||
Deps& deps;
|
||||
PmemAllocator& pmemAllocator;
|
||||
PmemAllocator& pmemAdspAllocator;
|
||||
int compositionType;
|
||||
int alloc_ashmem_buffer(size_t size, unsigned int postfix, void** pBase,
|
||||
int* pOffset, int* pFd);
|
||||
void getGrallocInformationFromFormat(int inputFormat, int *colorFormat, int *bufferType);
|
||||
};
|
||||
|
||||
#endif // GRALLOC_QSD8K_GPU_H
|
@ -1,231 +0,0 @@
|
||||
/*
|
||||
* 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 <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <linux/android_pmem.h>
|
||||
|
||||
#include "allocator.h"
|
||||
#include "gr.h"
|
||||
#include "gpu.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static int gralloc_alloc_buffer(alloc_device_t* dev,
|
||||
size_t size, int usage, buffer_handle_t* pHandle);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int fb_device_open(const hw_module_t* module, const char* name,
|
||||
hw_device_t** device);
|
||||
|
||||
static int gralloc_device_open(const hw_module_t* module, const char* name,
|
||||
hw_device_t** device);
|
||||
|
||||
extern int gralloc_lock(gralloc_module_t const* module,
|
||||
buffer_handle_t handle, int usage,
|
||||
int l, int t, int w, int h,
|
||||
void** vaddr);
|
||||
|
||||
extern int gralloc_unlock(gralloc_module_t const* module,
|
||||
buffer_handle_t handle);
|
||||
|
||||
extern int gralloc_register_buffer(gralloc_module_t const* module,
|
||||
buffer_handle_t handle);
|
||||
|
||||
extern int gralloc_unregister_buffer(gralloc_module_t const* module,
|
||||
buffer_handle_t handle);
|
||||
|
||||
extern int gralloc_perform(struct gralloc_module_t const* module,
|
||||
int operation, ... );
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* On-device dependency implementation */
|
||||
class PmemAllocatorDepsDeviceImpl : public PmemUserspaceAllocator::Deps,
|
||||
public PmemKernelAllocator::Deps {
|
||||
|
||||
const private_module_t* module;
|
||||
|
||||
virtual size_t getPmemTotalSize(int fd, size_t* size) {
|
||||
int err = 0;
|
||||
#ifndef TARGET_MSM7x27
|
||||
pmem_region region;
|
||||
err = ioctl(fd, PMEM_GET_TOTAL_SIZE, ®ion);
|
||||
if (err == 0) {
|
||||
*size = region.len;
|
||||
}
|
||||
#else
|
||||
#ifdef USE_ASHMEM
|
||||
if(module != NULL)
|
||||
*size = module->info.xres * module->info.yres * 2 * 2;
|
||||
else
|
||||
return -ENOMEM;
|
||||
#else
|
||||
*size = 23<<20; //23MB for 7x27
|
||||
#endif
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
virtual int connectPmem(int fd, int master_fd) {
|
||||
return ioctl(fd, PMEM_CONNECT, master_fd);
|
||||
}
|
||||
|
||||
virtual int mapPmem(int fd, int offset, size_t size) {
|
||||
struct pmem_region sub = { offset, size };
|
||||
return ioctl(fd, PMEM_MAP, &sub);
|
||||
}
|
||||
|
||||
virtual int unmapPmem(int fd, int offset, size_t size) {
|
||||
struct pmem_region sub = { offset, size };
|
||||
return ioctl(fd, PMEM_UNMAP, &sub);
|
||||
}
|
||||
|
||||
virtual int alignPmem(int fd, size_t size, int align) {
|
||||
struct pmem_allocation allocation;
|
||||
allocation.size = size;
|
||||
allocation.align = align;
|
||||
return ioctl(fd, PMEM_ALLOCATE_ALIGNED, &allocation);
|
||||
}
|
||||
|
||||
virtual int cleanPmem(int fd, unsigned long base, int offset, size_t size) {
|
||||
struct pmem_addr pmem_addr;
|
||||
pmem_addr.vaddr = base;
|
||||
pmem_addr.offset = offset;
|
||||
pmem_addr.length = size;
|
||||
return ioctl(fd, PMEM_CLEAN_INV_CACHES, &pmem_addr);
|
||||
}
|
||||
|
||||
virtual int getErrno() {
|
||||
return errno;
|
||||
}
|
||||
|
||||
virtual void* mmap(void* start, size_t length, int prot, int flags, int fd,
|
||||
off_t offset) {
|
||||
return ::mmap(start, length, prot, flags, fd, offset);
|
||||
}
|
||||
|
||||
virtual int munmap(void* start, size_t length) {
|
||||
return ::munmap(start, length);
|
||||
}
|
||||
|
||||
virtual int open(const char* pathname, int flags, int mode) {
|
||||
return ::open(pathname, flags, mode);
|
||||
}
|
||||
|
||||
virtual int close(int fd) {
|
||||
return ::close(fd);
|
||||
}
|
||||
|
||||
public:
|
||||
void setModule(const private_module_t* m) {
|
||||
module = m;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class GpuContextDepsDeviceImpl : public gpu_context_t::Deps {
|
||||
|
||||
public:
|
||||
|
||||
virtual int ashmem_create_region(const char *name, size_t size) {
|
||||
return ::ashmem_create_region(name, size);
|
||||
}
|
||||
|
||||
virtual int mapFrameBufferLocked(struct private_module_t* module) {
|
||||
return ::mapFrameBufferLocked(module);
|
||||
}
|
||||
|
||||
virtual int terminateBuffer(gralloc_module_t const* module,
|
||||
private_handle_t* hnd) {
|
||||
return ::terminateBuffer(module, hnd);
|
||||
}
|
||||
|
||||
virtual int close(int fd) {
|
||||
return ::close(fd);
|
||||
}
|
||||
};
|
||||
|
||||
static PmemAllocatorDepsDeviceImpl pmemAllocatorDeviceDepsImpl;
|
||||
static GpuContextDepsDeviceImpl gpuContextDeviceDepsImpl;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static SimpleBestFitAllocator pmemAllocMgr;
|
||||
static PmemUserspaceAllocator pmemAllocator(pmemAllocatorDeviceDepsImpl, pmemAllocMgr,
|
||||
"/dev/pmem");
|
||||
|
||||
static PmemKernelAllocator pmemAdspAllocator(pmemAllocatorDeviceDepsImpl);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static struct hw_module_methods_t gralloc_module_methods = {
|
||||
open: gralloc_device_open
|
||||
};
|
||||
|
||||
struct private_module_t HAL_MODULE_INFO_SYM = {
|
||||
base: {
|
||||
common: {
|
||||
tag: HARDWARE_MODULE_TAG,
|
||||
version_major: 1,
|
||||
version_minor: 0,
|
||||
id: GRALLOC_HARDWARE_MODULE_ID,
|
||||
name: "Graphics Memory Allocator Module",
|
||||
author: "The Android Open Source Project",
|
||||
methods: &gralloc_module_methods
|
||||
},
|
||||
registerBuffer: gralloc_register_buffer,
|
||||
unregisterBuffer: gralloc_unregister_buffer,
|
||||
lock: gralloc_lock,
|
||||
unlock: gralloc_unlock,
|
||||
perform: gralloc_perform,
|
||||
},
|
||||
framebuffer: 0,
|
||||
fbFormat: 0,
|
||||
flags: 0,
|
||||
numBuffers: 0,
|
||||
bufferMask: 0,
|
||||
lock: PTHREAD_MUTEX_INITIALIZER,
|
||||
currentBuffer: 0,
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int gralloc_device_open(const hw_module_t* module, const char* name,
|
||||
hw_device_t** device)
|
||||
{
|
||||
int status = -EINVAL;
|
||||
if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
|
||||
const private_module_t* m = reinterpret_cast<const private_module_t*>(
|
||||
module);
|
||||
pmemAllocatorDeviceDepsImpl.setModule(m);
|
||||
gpu_context_t *dev;
|
||||
dev = new gpu_context_t(gpuContextDeviceDepsImpl, pmemAllocator,
|
||||
pmemAdspAllocator, m);
|
||||
*device = &dev->common;
|
||||
status = 0;
|
||||
} else {
|
||||
status = fb_device_open(module, name, device);
|
||||
}
|
||||
return status;
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
# 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)
|
||||
|
||||
# you can use EXTRA_CFLAGS to indicate additional CFLAGS to use
|
||||
# in the build. The variables will be cleaned on exit
|
||||
#
|
||||
#
|
||||
|
||||
libgralloc_test_includes:= \
|
||||
bionic/libstdc++/include \
|
||||
external/astl/include \
|
||||
external/gtest/include \
|
||||
$(LOCAL_PATH)/..
|
||||
|
||||
libgralloc_test_static_libs := \
|
||||
libgralloc_qsd8k_host \
|
||||
libgtest_main_host \
|
||||
libgtest_host \
|
||||
libastl_host \
|
||||
liblog
|
||||
|
||||
define host-test
|
||||
$(foreach file,$(1), \
|
||||
$(eval include $(CLEAR_VARS)) \
|
||||
$(eval LOCAL_CPP_EXTENSION := .cpp) \
|
||||
$(eval LOCAL_SRC_FILES := $(file)) \
|
||||
$(eval LOCAL_C_INCLUDES := $(libgralloc_test_includes)) \
|
||||
$(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
|
||||
$(eval LOCAL_CFLAGS += $(EXTRA_CFLAGS)) \
|
||||
$(eval LOCAL_LDLIBS += $(EXTRA_LDLIBS)) \
|
||||
$(eval LOCAL_STATIC_LIBRARIES := $(libgralloc_test_static_libs)) \
|
||||
$(eval LOCAL_MODULE_TAGS := eng tests) \
|
||||
$(eval include $(BUILD_HOST_EXECUTABLE)) \
|
||||
) \
|
||||
$(eval EXTRA_CFLAGS :=) \
|
||||
$(eval EXTRA_LDLIBS :=)
|
||||
endef
|
||||
|
||||
TEST_SRC_FILES := \
|
||||
pmemalloc_test.cpp
|
||||
|
||||
$(call host-test, $(TEST_SRC_FILES))
|
@ -1,601 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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 <gtest/gtest.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "pmemalloc.h"
|
||||
|
||||
class DepsStub : public PmemUserspaceAllocator::Deps, public PmemKernelAllocator::Deps {
|
||||
|
||||
public:
|
||||
|
||||
virtual size_t getPmemTotalSize(int fd, size_t* size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int connectPmem(int fd, int master_fd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int mapPmem(int fd, int offset, size_t size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int unmapPmem(int fd, int offset, size_t size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int getErrno() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void* mmap(void* start, size_t length, int prot, int flags, int fd,
|
||||
off_t offset) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int munmap(void* start, size_t length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int open(const char* pathname, int flags, int mode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int close(int fd) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
class AllocatorStub : public PmemUserspaceAllocator::Deps::Allocator {
|
||||
virtual ssize_t setSize(size_t size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual size_t size() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual ssize_t allocate(size_t size, uint32_t flags = 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual ssize_t deallocate(size_t offset) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static const char* fakePmemDev = "/foo/bar";
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
struct Deps_InitPmemAreaLockedWithSuccessfulCompletion : public DepsStub {
|
||||
|
||||
virtual int open(const char* pathname, int flags, int mode) {
|
||||
EXPECT_EQ(fakePmemDev, pathname);
|
||||
EXPECT_EQ(O_RDWR, flags);
|
||||
EXPECT_EQ(0, mode);
|
||||
return 1234;
|
||||
}
|
||||
|
||||
virtual size_t getPmemTotalSize(int fd, size_t* size) {
|
||||
EXPECT_EQ(1234, fd);
|
||||
*size = 16 << 20;
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void* mmap(void* start, size_t length, int prot, int flags, int fd,
|
||||
off_t offset) {
|
||||
EXPECT_EQ(1234, fd);
|
||||
return (void*)0x87654321;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct Allocator_InitPmemAreaLockedWithSuccessfulCompletion : public AllocatorStub {
|
||||
|
||||
virtual ssize_t setSize(size_t size) {
|
||||
EXPECT_EQ(size_t(16 << 20), size);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(test_pmem_userspace_allocator, testInitPmemAreaLockedWithSuccessfulCompletion) {
|
||||
Deps_InitPmemAreaLockedWithSuccessfulCompletion depsMock;
|
||||
Allocator_InitPmemAreaLockedWithSuccessfulCompletion allocMock;
|
||||
PmemUserspaceAllocator pma(depsMock, allocMock, fakePmemDev);
|
||||
|
||||
int result = pma.init_pmem_area_locked();
|
||||
ASSERT_EQ(0, result);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
struct Deps_InitPmemAreaLockedWithEnomemOnMmap : public DepsStub {
|
||||
|
||||
virtual int open(const char* pathname, int flags, int mode) {
|
||||
EXPECT_EQ(fakePmemDev, pathname);
|
||||
EXPECT_EQ(O_RDWR, flags);
|
||||
EXPECT_EQ(0, mode);
|
||||
return 1234;
|
||||
}
|
||||
|
||||
virtual size_t getPmemTotalSize(int fd, size_t* size) {
|
||||
EXPECT_EQ(1234, fd);
|
||||
*size = 16 << 20;
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int getErrno() {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
virtual void* mmap(void* start, size_t length, int prot, int flags, int fd,
|
||||
off_t offset) {
|
||||
return (void*)MAP_FAILED;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct Allocator_InitPmemAreaLockedWithEnomemOnMmap : public AllocatorStub {
|
||||
|
||||
virtual ssize_t setSize(size_t size) {
|
||||
EXPECT_EQ(size_t(16 << 20), size);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(test_pmem_userspace_allocator, testInitPmemAreaLockedWthEnomemOnMmap) {
|
||||
Deps_InitPmemAreaLockedWithEnomemOnMmap depsMock;
|
||||
Allocator_InitPmemAreaLockedWithEnomemOnMmap allocMock;
|
||||
PmemUserspaceAllocator pma(depsMock, allocMock, fakePmemDev);
|
||||
|
||||
int result = pma.init_pmem_area_locked();
|
||||
ASSERT_EQ(-ENOMEM, result);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
struct Deps_InitPmemAreaLockedWithEaccesOnGetPmemTotalSize : public DepsStub {
|
||||
|
||||
virtual int open(const char* pathname, int flags, int mode) {
|
||||
EXPECT_EQ(fakePmemDev, pathname);
|
||||
EXPECT_EQ(O_RDWR, flags);
|
||||
EXPECT_EQ(0, mode);
|
||||
return 1234;
|
||||
}
|
||||
|
||||
virtual size_t getPmemTotalSize(int fd, size_t* size) {
|
||||
EXPECT_EQ(1234, fd);
|
||||
return -EACCES;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(test_pmem_userspace_allocator, testInitPmemAreaLockedWthEaccesOnGetPmemTotalSize) {
|
||||
Deps_InitPmemAreaLockedWithEaccesOnGetPmemTotalSize depsMock;
|
||||
AllocatorStub allocStub;
|
||||
PmemUserspaceAllocator pma(depsMock, allocStub, fakePmemDev);
|
||||
|
||||
int result = pma.init_pmem_area_locked();
|
||||
ASSERT_EQ(-EACCES, result);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
struct Deps_InitPmemAreaLockedWithEaccesOnOpen : public DepsStub {
|
||||
|
||||
virtual int getErrno() {
|
||||
return EACCES;
|
||||
}
|
||||
|
||||
virtual int open(const char* pathname, int flags, int mode) {
|
||||
EXPECT_EQ(fakePmemDev, pathname);
|
||||
EXPECT_EQ(O_RDWR, flags);
|
||||
EXPECT_EQ(0, mode);
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(test_pmem_userspace_allocator, testInitPmemAreaLockedWithEaccesOnOpenMaster) {
|
||||
Deps_InitPmemAreaLockedWithEaccesOnOpen depsMock;
|
||||
AllocatorStub allocStub;
|
||||
PmemUserspaceAllocator pma(depsMock, allocStub, fakePmemDev);
|
||||
|
||||
int result = pma.init_pmem_area_locked();
|
||||
ASSERT_EQ(-EACCES, result);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
typedef Deps_InitPmemAreaLockedWithSuccessfulCompletion Deps_InitPmemAreaWithSuccessfulInitialCompletion;
|
||||
|
||||
TEST(test_pmem_userspace_allocator, testInitPmemAreaWithSuccessfulInitialCompletion) {
|
||||
Deps_InitPmemAreaWithSuccessfulInitialCompletion depsMock;
|
||||
AllocatorStub allocStub;
|
||||
PmemUserspaceAllocator pma(depsMock, allocStub, fakePmemDev);
|
||||
|
||||
int result = pma.init_pmem_area();
|
||||
ASSERT_EQ(0, result);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
typedef Deps_InitPmemAreaLockedWithEaccesOnOpen Deps_InitPmemAreaWithEaccesOnInitLocked;
|
||||
|
||||
TEST(test_pmem_userspace_allocator, testInitPmemAreaWithEaccesOnInitLocked) {
|
||||
Deps_InitPmemAreaWithEaccesOnInitLocked depsMock;
|
||||
AllocatorStub allocStub;
|
||||
PmemUserspaceAllocator pma(depsMock, allocStub, fakePmemDev);
|
||||
|
||||
int result = pma.init_pmem_area();
|
||||
ASSERT_EQ(-EACCES, result);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
TEST(test_pmem_userspace_allocator, testInitPmemAreaAfterSuccessfulInitialCompletion) {
|
||||
DepsStub depsStub;
|
||||
AllocatorStub allocStub;
|
||||
PmemUserspaceAllocator pma(depsStub, allocStub, fakePmemDev);
|
||||
|
||||
pma.set_master_values(1234, 0); // Indicate that the pma has been successfully init'd
|
||||
|
||||
int result = pma.init_pmem_area();
|
||||
ASSERT_EQ(0, result);
|
||||
//XXX JMG: Add this back in maybe? ASSERT_EQ(1234, pmi.master); // Make sure the master fd wasn't changed
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
TEST(test_pmem_userspace_allocator, testInitPmemAreaAfterFailedInit) {
|
||||
DepsStub depsStub;
|
||||
AllocatorStub allocStub;
|
||||
PmemUserspaceAllocator pma(depsStub, allocStub, fakePmemDev);
|
||||
|
||||
pma.set_master_values(-EACCES, 0); // Indicate that the pma has failed init
|
||||
|
||||
int result = pma.init_pmem_area();
|
||||
ASSERT_EQ(-EACCES, result);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
struct Deps_InitPmemAreaLockedWithSuccessfulCompletionWithNoFlags : public DepsStub {
|
||||
|
||||
virtual int open(const char* pathname, int flags, int mode) {
|
||||
EXPECT_EQ(fakePmemDev, pathname);
|
||||
EXPECT_EQ(O_RDWR, flags & O_RDWR);
|
||||
EXPECT_EQ(0, mode);
|
||||
return 5678;
|
||||
}
|
||||
|
||||
virtual int connectPmem(int fd, int master_fd) {
|
||||
EXPECT_EQ(5678, fd);
|
||||
EXPECT_EQ(1234, master_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int mapPmem(int fd, int offset, size_t size) {
|
||||
EXPECT_EQ(5678, fd);
|
||||
EXPECT_EQ(0x300, offset);
|
||||
EXPECT_EQ(size_t(0x100), size);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Allocator_AllocPmemBufferWithSuccessfulCompletionWithNoFlags : public AllocatorStub {
|
||||
|
||||
virtual ssize_t allocate(size_t size, uint32_t flags = 0) {
|
||||
EXPECT_EQ(size_t(0x100), size);
|
||||
EXPECT_EQ(uint32_t(0x0), flags);
|
||||
return 0x300;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(test_pmem_userspace_allocator, testAllocPmemBufferWithSuccessfulCompletionWithNoFlags) {
|
||||
Deps_InitPmemAreaLockedWithSuccessfulCompletionWithNoFlags depsMock;
|
||||
Allocator_AllocPmemBufferWithSuccessfulCompletionWithNoFlags allocMock;
|
||||
PmemUserspaceAllocator pma(depsMock, allocMock, fakePmemDev);
|
||||
|
||||
uint8_t buf[0x300 + 0x100]; // Create a buffer to get memzero'd
|
||||
pma.set_master_values(1234, buf); // Indicate that the pma has been successfully init'd
|
||||
|
||||
void* base = 0;
|
||||
int offset = -9182, fd = -9182;
|
||||
int size = 0x100;
|
||||
int flags = 0;
|
||||
int result = pma.alloc_pmem_buffer(size, flags, &base, &offset, &fd);
|
||||
ASSERT_EQ(0, result);
|
||||
ASSERT_EQ(0x300, offset);
|
||||
ASSERT_EQ(5678, fd);
|
||||
for (int i = 0x300; i < 0x400; ++i) {
|
||||
ASSERT_EQ(uint8_t(0), buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
typedef Deps_InitPmemAreaLockedWithSuccessfulCompletionWithNoFlags Deps_InitPmemAreaLockedWithSuccessfulCompletionWithAllFlags;
|
||||
|
||||
typedef Allocator_AllocPmemBufferWithSuccessfulCompletionWithNoFlags Allocator_AllocPmemBufferWithSuccessfulCompletionWithAllFlags;
|
||||
|
||||
TEST(test_pmem_userspace_allocator, testAllocPmemBufferWithSuccessfulCompletionWithAllFlags) {
|
||||
Deps_InitPmemAreaLockedWithSuccessfulCompletionWithAllFlags depsMock;
|
||||
Allocator_AllocPmemBufferWithSuccessfulCompletionWithAllFlags allocMock;
|
||||
PmemUserspaceAllocator pma(depsMock, allocMock, fakePmemDev);
|
||||
|
||||
uint8_t buf[0x300 + 0x100]; // Create a buffer to get memzero'd
|
||||
pma.set_master_values(1234, buf); // Indicate that the pma has been successfully init'd
|
||||
|
||||
void* base = 0;
|
||||
int offset = -9182, fd = -9182;
|
||||
int size = 0x100;
|
||||
int flags = ~0;
|
||||
int result = pma.alloc_pmem_buffer(size, flags, &base, &offset, &fd);
|
||||
ASSERT_EQ(0, result);
|
||||
ASSERT_EQ(0x300, offset);
|
||||
ASSERT_EQ(5678, fd);
|
||||
for (int i = 0x300; i < 0x400; ++i) {
|
||||
ASSERT_EQ(0, buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
struct Deps_InitPmemAreaLockedWithEnodevOnOpen : public Deps_InitPmemAreaLockedWithSuccessfulCompletionWithNoFlags {
|
||||
|
||||
virtual int getErrno() {
|
||||
return ENODEV;
|
||||
}
|
||||
|
||||
virtual int open(const char* pathname, int flags, int mode) {
|
||||
EXPECT_EQ(fakePmemDev, pathname);
|
||||
EXPECT_EQ(O_RDWR, flags & O_RDWR);
|
||||
EXPECT_EQ(0, mode);
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
typedef Allocator_AllocPmemBufferWithSuccessfulCompletionWithNoFlags Allocator_AllocPmemBufferWithEnodevOnOpen;
|
||||
|
||||
TEST(test_pmem_userspace_allocator, testAllocPmemBufferWithSuccessfulCompletionWithEnodevOnOpen) {
|
||||
Deps_InitPmemAreaLockedWithEnodevOnOpen depsMock;
|
||||
Allocator_AllocPmemBufferWithEnodevOnOpen allocMock;
|
||||
PmemUserspaceAllocator pma(depsMock, allocMock, fakePmemDev);
|
||||
|
||||
uint8_t buf[0x300 + 0x100]; // Create a buffer to get memzero'd
|
||||
pma.set_master_values(1234, buf); // Indicate that the pma has been successfully init'd
|
||||
|
||||
void* base = 0;
|
||||
int offset = -9182, fd = -9182;
|
||||
int size = 0x100;
|
||||
int flags = ~0;
|
||||
int result = pma.alloc_pmem_buffer(size, flags, &base, &offset, &fd);
|
||||
ASSERT_EQ(-ENODEV, result);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
struct Deps_InitPmemAreaLockedWithEnomemOnConnectPmem : public Deps_InitPmemAreaLockedWithSuccessfulCompletionWithNoFlags {
|
||||
|
||||
virtual int getErrno() {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
virtual int connectPmem(int fd, int master_fd) {
|
||||
EXPECT_EQ(5678, fd);
|
||||
EXPECT_EQ(1234, master_fd);
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
typedef Allocator_AllocPmemBufferWithSuccessfulCompletionWithNoFlags Allocator_AllocPmemBufferWithEnomemOnConnectPmem;
|
||||
|
||||
TEST(test_pmem_userspace_allocator, testAllocPmemBufferWithSuccessfulCompletionWithEnomemOnConnectPmem) {
|
||||
Deps_InitPmemAreaLockedWithEnomemOnConnectPmem depsMock;
|
||||
Allocator_AllocPmemBufferWithEnomemOnConnectPmem allocMock;
|
||||
PmemUserspaceAllocator pma(depsMock, allocMock, fakePmemDev);
|
||||
|
||||
uint8_t buf[0x300 + 0x100]; // Create a buffer to get memzero'd
|
||||
pma.set_master_values(1234, buf); // Indicate that the pma has been successfully init'd
|
||||
|
||||
void* base = 0;
|
||||
int offset = -9182, fd = -9182;
|
||||
int size = 0x100;
|
||||
int flags = ~0;
|
||||
int result = pma.alloc_pmem_buffer(size, flags, &base, &offset, &fd);
|
||||
ASSERT_EQ(-ENOMEM, result);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
struct Deps_InitPmemAreaLockedWithEnomemOnMapPmem : public Deps_InitPmemAreaLockedWithSuccessfulCompletionWithNoFlags {
|
||||
|
||||
virtual int getErrno() {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
virtual int mapPmem(int fd, int offset, size_t size) {
|
||||
EXPECT_EQ(5678, fd);
|
||||
EXPECT_EQ(0x300, offset);
|
||||
EXPECT_EQ(size_t(0x100), size);
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
typedef Allocator_AllocPmemBufferWithSuccessfulCompletionWithNoFlags Allocator_AllocPmemBufferWithEnomemOnMapPmem;
|
||||
|
||||
TEST(test_pmem_userspace_allocator, testAllocPmemBufferWithEnomemOnMapPmem) {
|
||||
Deps_InitPmemAreaLockedWithEnomemOnMapPmem depsMock;
|
||||
Allocator_AllocPmemBufferWithEnomemOnMapPmem allocMock;
|
||||
PmemUserspaceAllocator pma(depsMock, allocMock, fakePmemDev);
|
||||
|
||||
uint8_t buf[0x300 + 0x100]; // Create a buffer to get memzero'd
|
||||
pma.set_master_values(1234, buf); // Indicate that the pma has been successfully init'd
|
||||
|
||||
void* base = 0;
|
||||
int offset = -9182, fd = -9182;
|
||||
int size = 0x100;
|
||||
int flags = ~0;
|
||||
int result = pma.alloc_pmem_buffer(size, flags, &base, &offset, &fd);
|
||||
ASSERT_EQ(-ENOMEM, result);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
struct Deps_KernelAllocPmemBufferWithSuccessfulCompletionWithNoFlags : public DepsStub {
|
||||
|
||||
void* mmapResult;
|
||||
|
||||
Deps_KernelAllocPmemBufferWithSuccessfulCompletionWithNoFlags(void* mmapResult) :
|
||||
mmapResult(mmapResult) {}
|
||||
|
||||
virtual int open(const char* pathname, int flags, int mode) {
|
||||
EXPECT_EQ(fakePmemDev, pathname);
|
||||
EXPECT_EQ(O_RDWR, flags & O_RDWR);
|
||||
EXPECT_EQ(0, mode);
|
||||
return 5678;
|
||||
}
|
||||
|
||||
virtual void* mmap(void* start, size_t length, int prot, int flags, int fd,
|
||||
off_t offset) {
|
||||
EXPECT_EQ(5678, fd);
|
||||
return mmapResult;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(test_pmem_kernel_allocator, testAllocPmemBufferWithSuccessfulCompletionWithNoFlags) {
|
||||
uint8_t buf[0x100]; // Create a buffer to get memzero'd
|
||||
Deps_KernelAllocPmemBufferWithSuccessfulCompletionWithNoFlags depsMock(buf);
|
||||
PmemKernelAllocator pma(depsMock, fakePmemDev);
|
||||
|
||||
void* base = 0;
|
||||
int offset = -9182, fd = -9182;
|
||||
int size = 0x100;
|
||||
int flags = 0;
|
||||
int result = pma.alloc_pmem_buffer(size, flags, &base, &offset, &fd);
|
||||
ASSERT_EQ(0, result);
|
||||
ASSERT_EQ(buf, base);
|
||||
ASSERT_EQ(0, offset);
|
||||
ASSERT_EQ(5678, fd);
|
||||
for (int i = 0; i < 0x100; ++i) {
|
||||
ASSERT_EQ(0, buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
typedef Deps_KernelAllocPmemBufferWithSuccessfulCompletionWithNoFlags Deps_KernelAllocPmemBufferWithSuccessfulCompletionWithAllFlags;
|
||||
|
||||
TEST(test_pmem_kernel_allocator, testAllocPmemBufferWithSuccessfulCompletionWithAllFlags) {
|
||||
uint8_t buf[0x100]; // Create a buffer to get memzero'd
|
||||
Deps_KernelAllocPmemBufferWithSuccessfulCompletionWithAllFlags depsMock(buf);
|
||||
PmemKernelAllocator pma(depsMock, fakePmemDev);
|
||||
|
||||
void* base = 0;
|
||||
int offset = -9182, fd = -9182;
|
||||
int size = 0x100;
|
||||
int flags = ~0;
|
||||
int result = pma.alloc_pmem_buffer(size, flags, &base, &offset, &fd);
|
||||
ASSERT_EQ(0, result);
|
||||
ASSERT_EQ(buf, base);
|
||||
ASSERT_EQ(0, offset);
|
||||
ASSERT_EQ(5678, fd);
|
||||
for (int i = 0; i < 0x100; ++i) {
|
||||
ASSERT_EQ(0, buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
struct Deps_KernelAllocPmemBufferWithEpermOnOpen : public DepsStub {
|
||||
|
||||
virtual int getErrno() {
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
virtual int open(const char* pathname, int flags, int mode) {
|
||||
EXPECT_EQ(fakePmemDev, pathname);
|
||||
EXPECT_EQ(O_RDWR, flags & O_RDWR);
|
||||
EXPECT_EQ(0, mode);
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
TEST(test_pmem_kernel_allocator, testAllocPmemBufferWithEpermOnOpen) {
|
||||
Deps_KernelAllocPmemBufferWithEpermOnOpen depsMock;
|
||||
PmemKernelAllocator pma(depsMock, fakePmemDev);
|
||||
|
||||
void* base = 0;
|
||||
int offset = -9182, fd = -9182;
|
||||
int size = 0x100;
|
||||
int flags = ~0;
|
||||
int result = pma.alloc_pmem_buffer(size, flags, &base, &offset, &fd);
|
||||
ASSERT_EQ(-EPERM, result);
|
||||
ASSERT_EQ(0, base);
|
||||
ASSERT_EQ(0, offset);
|
||||
ASSERT_EQ(-1, fd);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
struct Deps_KernelAllocPmemBufferWithEnomemOnMmap : DepsStub {
|
||||
|
||||
virtual int open(const char* pathname, int flags, int mode) {
|
||||
EXPECT_EQ(fakePmemDev, pathname);
|
||||
EXPECT_EQ(O_RDWR, flags & O_RDWR);
|
||||
EXPECT_EQ(0, mode);
|
||||
return 5678;
|
||||
}
|
||||
|
||||
virtual void* mmap(void* start, size_t length, int prot, int flags, int fd,
|
||||
off_t offset) {
|
||||
return (void*)MAP_FAILED;
|
||||
}
|
||||
|
||||
virtual int getErrno() {
|
||||
return ENOMEM;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
TEST(test_pmem_kernel_allocator, testAllocPmemBufferWithEnomemOnMmap) {
|
||||
Deps_KernelAllocPmemBufferWithEnomemOnMmap depsMock;
|
||||
PmemKernelAllocator pma(depsMock, fakePmemDev);
|
||||
|
||||
void* base = 0;
|
||||
int offset = -9182, fd = -9182;
|
||||
int size = 0x100;
|
||||
int flags = ~0;
|
||||
int result = pma.alloc_pmem_buffer(size, flags, &base, &offset, &fd);
|
||||
ASSERT_EQ(-ENOMEM, result);
|
||||
ASSERT_EQ(0, base);
|
||||
ASSERT_EQ(0, offset);
|
||||
ASSERT_EQ(-1, fd);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
@ -11,7 +11,9 @@
|
||||
# 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.
|
||||
ifneq ($(TARGET_USES_ION),true)
|
||||
|
||||
# Use this flag until pmem/ashmem is implemented in the new gralloc
|
||||
ifeq ($(TARGET_USES_ION),true)
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
# HAL module implemenation, not prelinked and stored in
|
||||
@ -19,48 +21,50 @@ LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_PRELINK_MODULE := false
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
|
||||
LOCAL_SHARED_LIBRARIES := liblog libcutils libGLESv1_CM libutils
|
||||
LOCAL_SHARED_LIBRARIES := liblog libcutils libGLESv1_CM libutils libmemalloc
|
||||
|
||||
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \
|
||||
hardware/qcom/display/libgralloc
|
||||
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
|
||||
LOCAL_SRC_FILES := \
|
||||
allocator.cpp \
|
||||
framebuffer.cpp \
|
||||
gpu.cpp \
|
||||
gralloc.cpp \
|
||||
mapper.cpp \
|
||||
pmemalloc.cpp
|
||||
|
||||
LOCAL_MODULE := gralloc.$(TARGET_BOARD_PLATFORM)
|
||||
LOCAL_CFLAGS:= -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).gralloc\" -DHOST -DDEBUG_CALC_FPS
|
||||
LOCAL_SRC_FILES := framebuffer.cpp \
|
||||
gpu.cpp \
|
||||
gralloc.cpp \
|
||||
mapper.cpp \
|
||||
pmemalloc.cpp \
|
||||
pmem_bestfit_alloc.cpp
|
||||
|
||||
ifneq (, $(filter msm7625_ffa msm7625_surf msm7627_ffa msm7627_surf msm7627_7x_ffa msm7627_7x_surf, $(QCOM_TARGET_PRODUCT)))
|
||||
LOCAL_CFLAGS += -DTARGET_MSM7x27
|
||||
LOCAL_MODULE := gralloc.$(TARGET_BOARD_PLATFORM)
|
||||
LOCAL_CFLAGS:= -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).gralloc\" -DHOST -DDEBUG_CALC_FPS -DUSE_ION
|
||||
|
||||
ifeq ($(call is-board-platform,msm7627_surf msm7627_6x),true)
|
||||
LOCAL_CFLAGS += -DTARGET_MSM7x27
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_HAVE_HDMI_OUT),true)
|
||||
LOCAL_CFLAGS += -DHDMI_DUAL_DISPLAY
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../liboverlay
|
||||
LOCAL_SHARED_LIBRARIES += liboverlay
|
||||
LOCAL_CFLAGS += -DHDMI_DUAL_DISPLAY
|
||||
LOCAL_C_INCLUDES += hardware/msm7k/liboverlay
|
||||
LOCAL_SHARED_LIBRARIES += liboverlay
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_USES_SF_BYPASS),true)
|
||||
LOCAL_CFLAGS += -DSF_BYPASS
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_GRALLOC_USES_ASHMEM),true)
|
||||
LOCAL_CFLAGS += -DUSE_ASHMEM
|
||||
LOCAL_CFLAGS += -DUSE_ASHMEM
|
||||
endif
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
|
||||
# Build a host library for testing
|
||||
ifeq ($(HOST_OS),linux)
|
||||
#MemAlloc Library
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := \
|
||||
gpu.cpp \
|
||||
pmemalloc.cpp
|
||||
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
LOCAL_MODULE := libgralloc_qsd8k_host
|
||||
LOCAL_CFLAGS:= -DLOG_TAG=\"gralloc-qsd8k\"
|
||||
include $(BUILD_HOST_STATIC_LIBRARY)
|
||||
endif
|
||||
endif
|
||||
LOCAL_PRELINK_MODULE := false
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
|
||||
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
|
||||
LOCAL_SHARED_LIBRARIES := liblog libcutils libutils
|
||||
LOCAL_SRC_FILES := ionalloc.cpp \
|
||||
ashmemalloc.cpp \
|
||||
alloc_controller.cpp
|
||||
LOCAL_CFLAGS:= -DLOG_TAG=\"memalloc\" -DLOG_NDDEBUG=0 -DUSE_ION
|
||||
LOCAL_MODULE := libmemalloc
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
endif #TARGET_USES_ION
|
158
libgralloc/alloc_controller.cpp
Normal file
158
libgralloc/alloc_controller.cpp
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of Code Aurora Forum, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include "gralloc_priv.h"
|
||||
#include "alloc_controller.h"
|
||||
#include "memalloc.h"
|
||||
#include "ionalloc.h"
|
||||
|
||||
using namespace gralloc;
|
||||
using android::sp;
|
||||
|
||||
sp<IAllocController> IAllocController::sController = NULL;
|
||||
sp<IAllocController> IAllocController::getInstance(void)
|
||||
{
|
||||
if(sController == NULL) {
|
||||
#ifdef USE_ION
|
||||
sController = new IonController();
|
||||
#else
|
||||
// XXX: Return pmem/ashmem controller when completed
|
||||
#endif
|
||||
}
|
||||
return sController;
|
||||
}
|
||||
|
||||
IonController::IonController()
|
||||
{
|
||||
mIonAlloc = new IonAlloc();
|
||||
}
|
||||
|
||||
static bool canFallback(int compositionType, int usage, int flags)
|
||||
{
|
||||
// Fallback to system heap when alloc fails unless
|
||||
// 1. Composition type is MDP
|
||||
// 2. Earlier alloc attempt was from system heap
|
||||
// 3. Contiguous heap requsted explicitly
|
||||
|
||||
if(compositionType == MDP_COMPOSITION)
|
||||
return false;
|
||||
if(flags & ION_HEAP_SYSTEM_ID)
|
||||
return false;
|
||||
if(usage &(GRALLOC_USAGE_PRIVATE_ADSP_HEAP|
|
||||
GRALLOC_USAGE_PRIVATE_EBI_HEAP |
|
||||
GRALLOC_USAGE_PRIVATE_SMI_HEAP))
|
||||
return false;
|
||||
//Return true by default
|
||||
return true;
|
||||
}
|
||||
|
||||
int IonController::allocate(alloc_data& data, int usage,
|
||||
int compositionType)
|
||||
{
|
||||
int ionFlags = 0;
|
||||
int ret;
|
||||
|
||||
//System heap cannot be uncached
|
||||
if (usage & GRALLOC_USAGE_PRIVATE_UNCACHED &&
|
||||
!(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP))
|
||||
data.uncached = true;
|
||||
else
|
||||
data.uncached = false;
|
||||
|
||||
if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
|
||||
ionFlags |= 1 << ION_HEAP_ADSP_ID;
|
||||
|
||||
if(usage & GRALLOC_USAGE_PRIVATE_SMI_HEAP)
|
||||
ionFlags |= 1 << ION_HEAP_SMI_ID;
|
||||
|
||||
if(usage & GRALLOC_USAGE_PRIVATE_EBI_HEAP)
|
||||
ionFlags |= 1 << ION_HEAP_EBI_ID;
|
||||
|
||||
if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP)
|
||||
ionFlags |= 1 << ION_HEAP_SYSTEM_ID;
|
||||
|
||||
// if no flags are set, default to
|
||||
// EBI heap, so that bypass can work
|
||||
// we can fall back to system heap if
|
||||
// we run out.
|
||||
if(!ionFlags)
|
||||
ionFlags = 1 << ION_HEAP_EBI_ID;
|
||||
|
||||
data.flags = ionFlags;
|
||||
ret = mIonAlloc->alloc_buffer(data);
|
||||
|
||||
// Fallback
|
||||
if(ret < 0 && canFallback(compositionType, usage, ionFlags)) {
|
||||
LOGW("Falling back to system heap");
|
||||
data.flags = 1 << ION_HEAP_SYSTEM_ID;
|
||||
ret = mIonAlloc->alloc_buffer(data);
|
||||
}
|
||||
|
||||
if(ret >= 0 )
|
||||
data.allocType = private_handle_t::PRIV_FLAGS_USES_ION;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
sp<IMemAlloc> IonController::getAllocator(int flags)
|
||||
{
|
||||
sp<IMemAlloc> memalloc;
|
||||
if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
|
||||
memalloc = mIonAlloc;
|
||||
} else {
|
||||
LOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
|
||||
}
|
||||
|
||||
return memalloc;
|
||||
}
|
||||
|
||||
int PmemAshmemController::allocate(alloc_data& data, int usage,
|
||||
int compositionType)
|
||||
{
|
||||
//XXX PMEM with ashmem fallback strategy
|
||||
return 0;
|
||||
}
|
||||
|
||||
sp<IMemAlloc> PmemAshmemController::getAllocator(int flags)
|
||||
{
|
||||
sp<IMemAlloc> memalloc;
|
||||
if (flags & private_handle_t::PRIV_FLAGS_USES_PMEM) {
|
||||
// XXX Return right allocator based on flags
|
||||
memalloc = NULL;
|
||||
} else {
|
||||
LOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
|
||||
memalloc = NULL;
|
||||
}
|
||||
|
||||
return memalloc;
|
||||
}
|
||||
|
||||
|
87
libgralloc/alloc_controller.h
Normal file
87
libgralloc/alloc_controller.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of Code Aurora Forum, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef GRALLOC_ALLOCCONTROLLER_H
|
||||
#define GRALLOC_ALLOCCONTROLLER_H
|
||||
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
namespace gralloc {
|
||||
|
||||
struct alloc_data;
|
||||
class IMemAlloc;
|
||||
class IonAlloc;
|
||||
|
||||
class IAllocController : public android::RefBase {
|
||||
|
||||
public:
|
||||
/* Allocate using a suitable method
|
||||
* Returns the type of buffer allocated
|
||||
*/
|
||||
virtual int allocate(alloc_data& data, int usage,
|
||||
int compositionType) = 0;
|
||||
|
||||
virtual android::sp<IMemAlloc> getAllocator(int flags) = 0;
|
||||
|
||||
virtual ~IAllocController() {};
|
||||
|
||||
static android::sp<IAllocController> getInstance(void);
|
||||
|
||||
private:
|
||||
static android::sp<IAllocController> sController;
|
||||
|
||||
};
|
||||
|
||||
class IonController : public IAllocController {
|
||||
|
||||
public:
|
||||
virtual int allocate(alloc_data& data, int usage,
|
||||
int compositionType);
|
||||
|
||||
virtual android::sp<IMemAlloc> getAllocator(int flags);
|
||||
|
||||
IonController();
|
||||
|
||||
private:
|
||||
android::sp<IonAlloc> mIonAlloc;
|
||||
|
||||
};
|
||||
|
||||
class PmemAshmemController : public IAllocController {
|
||||
|
||||
public:
|
||||
virtual int allocate(alloc_data& data, int usage,
|
||||
int compositionType);
|
||||
|
||||
virtual android::sp<IMemAlloc> getAllocator(int flags);
|
||||
// XXX: Pmem and ashmem alloc objects
|
||||
|
||||
};
|
||||
|
||||
} //end namespace gralloc
|
||||
#endif // GRALLOC_ALLOCCONTROLLER_H
|
140
libgralloc/ashmemalloc.cpp
Normal file
140
libgralloc/ashmemalloc.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of Code Aurora Forum, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <stdlib.h>
|
||||
#include <cutils/log.h>
|
||||
#include <linux/ashmem.h>
|
||||
#include <cutils/ashmem.h>
|
||||
#include <errno.h>
|
||||
#include "ashmemalloc.h"
|
||||
|
||||
using gralloc::AshmemAlloc;
|
||||
int AshmemAlloc::alloc_buffer(alloc_data& data)
|
||||
{
|
||||
int err = 0;
|
||||
int fd = -1;
|
||||
void* base = 0;
|
||||
int offset = 0;
|
||||
char name[ASHMEM_NAME_LEN];
|
||||
snprintf(name, ASHMEM_NAME_LEN, "gralloc-buffer-%x", data.pHandle);
|
||||
int prot = PROT_READ | PROT_WRITE;
|
||||
fd = ashmem_create_region(name, data.size);
|
||||
if (fd < 0) {
|
||||
LOGE("couldn't create ashmem (%s)", strerror(errno));
|
||||
err = -errno;
|
||||
} else {
|
||||
if (ashmem_set_prot_region(fd, prot) < 0) {
|
||||
LOGE("ashmem_set_prot_region(fd=%d, prot=%x) failed (%s)",
|
||||
fd, prot, strerror(errno));
|
||||
close(fd);
|
||||
err = -errno;
|
||||
} else {
|
||||
base = mmap(0, data.size, prot, MAP_SHARED|MAP_POPULATE|MAP_LOCKED, fd, 0);
|
||||
if (base == MAP_FAILED) {
|
||||
LOGE("alloc mmap(fd=%d, size=%d, prot=%x) failed (%s)",
|
||||
fd, data.size, prot, strerror(errno));
|
||||
close(fd);
|
||||
err = -errno;
|
||||
} else {
|
||||
memset((char*)base + offset, 0, data.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(err == 0) {
|
||||
data.fd = fd;
|
||||
data.base = base;
|
||||
data.offset = offset;
|
||||
clean_buffer(base, data.size, offset, fd);
|
||||
}
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
int AshmemAlloc::free_buffer(void* base, size_t size, int offset, int fd)
|
||||
{
|
||||
LOGD("%s:Freeing buffer size=%d base=%p fd=%d PID=%d",
|
||||
__FUNCTION__, size, base, fd, getpid());
|
||||
int err = 0;
|
||||
|
||||
if(!base) {
|
||||
LOGE("Invalid free");
|
||||
return -EINVAL;
|
||||
}
|
||||
err = unmap_buffer(base, size, offset);
|
||||
close(fd);
|
||||
return err;
|
||||
}
|
||||
|
||||
int AshmemAlloc::map_buffer(void **pBase, size_t size, int offset, int fd)
|
||||
{
|
||||
LOGD("%s: Mapping buffer fd=%d size=%d PID=%d", __FUNCTION__,
|
||||
fd, size, getpid());
|
||||
int err = 0;
|
||||
void *base = 0;
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
base = mmap(0, size, PROT_READ| PROT_WRITE,
|
||||
MAP_SHARED, fd, 0);
|
||||
*pBase = base;
|
||||
if(base == MAP_FAILED) {
|
||||
LOGD("%s: Failed to map memory in the client: %s",
|
||||
__FUNCTION__, strerror(errno));
|
||||
err = -errno;
|
||||
} else {
|
||||
LOGD("%s: Successfully mapped %d bytes", __FUNCTION__, size);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int AshmemAlloc::unmap_buffer(void *base, size_t size, int offset)
|
||||
{
|
||||
LOGD("%s: Unmapping buffer at address %p", __FUNCTION__, base);
|
||||
int err = munmap(base, size);
|
||||
if(err) {
|
||||
LOGE("%s: Failed to unmap memory at %p: %s",
|
||||
__FUNCTION__, base, strerror(errno));
|
||||
}
|
||||
return err;
|
||||
|
||||
}
|
||||
int AshmemAlloc::clean_buffer(void *base, size_t size, int offset, int fd)
|
||||
{
|
||||
// LOGD("%s: Clean buffer fd=%d base = %p size=%d PID=%d", __FUNCTION__,
|
||||
// fd, base, size, getpid());
|
||||
int err = 0;
|
||||
if (ioctl(fd, ASHMEM_CACHE_INV_RANGE, NULL)) {
|
||||
LOGE("ASHMEM_CACHE_INV_RANGE failed fd = %d", fd);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
56
libgralloc/ashmemalloc.h
Normal file
56
libgralloc/ashmemalloc.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of Code Aurora Forum, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef GRALLOC_ASHMEMALLOC_H
|
||||
#define GRALLOC_ASHMEMALLOC_H
|
||||
|
||||
#include "memalloc.h"
|
||||
#include <linux/ion.h>
|
||||
|
||||
namespace gralloc {
|
||||
class AshmemAlloc : public IMemAlloc {
|
||||
|
||||
public:
|
||||
virtual int alloc_buffer(alloc_data& data);
|
||||
|
||||
virtual int free_buffer(void *base, size_t size,
|
||||
int offset, int fd);
|
||||
|
||||
virtual int map_buffer(void **pBase, size_t size,
|
||||
int offset, int fd);
|
||||
|
||||
virtual int unmap_buffer(void *base, size_t size,
|
||||
int offset);
|
||||
|
||||
virtual int clean_buffer(void*base, size_t size,
|
||||
int offset, int fd);
|
||||
|
||||
};
|
||||
}
|
||||
#endif /* GRALLOC_ASHMEMALLOC_H */
|
@ -174,7 +174,6 @@ static int fb_setUpdateRect(struct framebuffer_device_t* dev,
|
||||
{
|
||||
if (((w|h) <= 0) || ((l|t)<0))
|
||||
return -EINVAL;
|
||||
|
||||
fb_context_t* ctx = (fb_context_t*)dev;
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
dev->common.module);
|
||||
@ -680,14 +679,13 @@ static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
|
||||
} else {
|
||||
void* fb_vaddr;
|
||||
void* buffer_vaddr;
|
||||
|
||||
m->base.lock(&m->base, m->framebuffer,
|
||||
GRALLOC_USAGE_SW_WRITE_RARELY,
|
||||
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,
|
||||
m->base.lock(&m->base, buffer,
|
||||
GRALLOC_USAGE_SW_READ_RARELY,
|
||||
0, 0, m->info.xres, m->info.yres,
|
||||
&buffer_vaddr);
|
||||
|
||||
@ -699,8 +697,8 @@ static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
|
||||
m->info.xoffset, m->info.yoffset,
|
||||
m->info.width, m->info.height);
|
||||
|
||||
m->base.unlock(&m->base, buffer);
|
||||
m->base.unlock(&m->base, m->framebuffer);
|
||||
m->base.unlock(&m->base, buffer);
|
||||
m->base.unlock(&m->base, m->framebuffer);
|
||||
}
|
||||
|
||||
LOGD_IF(FB_DEBUG, "Framebuffer state: [0] = %c [1] = %c [2] = %c",
|
||||
@ -745,7 +743,6 @@ int mapFrameBufferLocked(struct private_module_t* module)
|
||||
if (module->framebuffer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char const * const device_template[] = {
|
||||
"/dev/graphics/fb%u",
|
||||
"/dev/fb%u",
|
||||
@ -787,42 +784,42 @@ int mapFrameBufferLocked(struct private_module_t* module)
|
||||
*/
|
||||
|
||||
if(info.bits_per_pixel == 32) {
|
||||
/*
|
||||
* Explicitly request RGBA_8888
|
||||
*/
|
||||
info.bits_per_pixel = 32;
|
||||
info.red.offset = 24;
|
||||
info.red.length = 8;
|
||||
info.green.offset = 16;
|
||||
info.green.length = 8;
|
||||
info.blue.offset = 8;
|
||||
info.blue.length = 8;
|
||||
info.transp.offset = 0;
|
||||
info.transp.length = 8;
|
||||
/*
|
||||
* Explicitly request RGBA_8888
|
||||
*/
|
||||
info.bits_per_pixel = 32;
|
||||
info.red.offset = 24;
|
||||
info.red.length = 8;
|
||||
info.green.offset = 16;
|
||||
info.green.length = 8;
|
||||
info.blue.offset = 8;
|
||||
info.blue.length = 8;
|
||||
info.transp.offset = 0;
|
||||
info.transp.length = 8;
|
||||
|
||||
/* Note: the GL driver does not have a r=8 g=8 b=8 a=0 config, so if we do
|
||||
* not use the MDP for composition (i.e. hw composition == 0), ask for
|
||||
* RGBA instead of RGBX. */
|
||||
if (property_get("debug.sf.hw", property, NULL) > 0 && atoi(property) == 0)
|
||||
module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
|
||||
else if(property_get("debug.composition.type", property, NULL) > 0 && (strncmp(property, "mdp", 3) == 0))
|
||||
module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
|
||||
else
|
||||
module->fbFormat = HAL_PIXEL_FORMAT_RGBA_8888;
|
||||
/* Note: the GL driver does not have a r=8 g=8 b=8 a=0 config, so if we do
|
||||
* not use the MDP for composition (i.e. hw composition == 0), ask for
|
||||
* RGBA instead of RGBX. */
|
||||
if (property_get("debug.sf.hw", property, NULL) > 0 && atoi(property) == 0)
|
||||
module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
|
||||
else if(property_get("debug.composition.type", property, NULL) > 0 && (strncmp(property, "mdp", 3) == 0))
|
||||
module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
|
||||
else
|
||||
module->fbFormat = HAL_PIXEL_FORMAT_RGBA_8888;
|
||||
} else {
|
||||
/*
|
||||
* 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;
|
||||
module->fbFormat = HAL_PIXEL_FORMAT_RGB_565;
|
||||
/*
|
||||
* 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;
|
||||
module->fbFormat = HAL_PIXEL_FORMAT_RGB_565;
|
||||
}
|
||||
/*
|
||||
* Request NUM_BUFFERS screens (at lest 2 for page flipping)
|
||||
@ -956,7 +953,7 @@ int mapFrameBufferLocked(struct private_module_t* module)
|
||||
pthread_cond_init(&(module->avail[i].cond), NULL);
|
||||
module->avail[i].is_avail = true;
|
||||
module->avail[i].state = AVL;
|
||||
}
|
||||
}
|
||||
|
||||
/* create display update thread */
|
||||
pthread_t thread1;
|
||||
@ -1117,7 +1114,7 @@ msm_copy_buffer(buffer_handle_t handle, int fd,
|
||||
blit.req.dst.width = width;
|
||||
blit.req.dst.height = height;
|
||||
blit.req.dst.offset = 0;
|
||||
blit.req.dst.memory_id = fd;
|
||||
blit.req.dst.memory_id = fd;
|
||||
blit.req.dst.format = format;
|
||||
|
||||
blit.req.src_rect.x = blit.req.dst_rect.x = x;
|
265
libgralloc-qsd8k/gpu.cpp → libgralloc/gpu.cpp
Executable file → Normal file
265
libgralloc-qsd8k/gpu.cpp → libgralloc/gpu.cpp
Executable file → Normal file
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
* Copyright (c) 2011 Code Aurora Forum. 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.
|
||||
@ -17,27 +18,25 @@
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <cutils/properties.h>
|
||||
#ifdef HOST
|
||||
#include <linux/ashmem.h>
|
||||
#endif
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "gr.h"
|
||||
#include "gpu.h"
|
||||
#include "memalloc.h"
|
||||
#include "alloc_controller.h"
|
||||
|
||||
static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
|
||||
static const int QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7FA30C03;
|
||||
static const int QOMX_INTERLACE_FLAG = 0x49283654;
|
||||
static const int QOMX_3D_VIDEO_FLAG = 0x23784238;
|
||||
|
||||
gpu_context_t::gpu_context_t(Deps& deps, PmemAllocator& pmemAllocator,
|
||||
PmemAllocator& pmemAdspAllocator, const private_module_t* module) :
|
||||
deps(deps),
|
||||
pmemAllocator(pmemAllocator),
|
||||
pmemAdspAllocator(pmemAdspAllocator)
|
||||
using namespace gralloc;
|
||||
using android::sp;
|
||||
|
||||
gpu_context_t::gpu_context_t(const private_module_t* module,
|
||||
sp<IAllocController> alloc_ctrl ) :
|
||||
mAllocCtrl(alloc_ctrl)
|
||||
{
|
||||
// Zero out the alloc_device_t
|
||||
memset(static_cast<alloc_device_t*>(this), 0, sizeof(alloc_device_t));
|
||||
@ -72,6 +71,7 @@ gpu_context_t::gpu_context_t(Deps& deps, PmemAllocator& pmemAllocator,
|
||||
alloc = gralloc_alloc;
|
||||
allocSize = gralloc_alloc_size;
|
||||
free = gralloc_free;
|
||||
|
||||
}
|
||||
|
||||
int gpu_context_t::gralloc_alloc_framebuffer_locked(size_t size, int usage,
|
||||
@ -84,14 +84,9 @@ int gpu_context_t::gralloc_alloc_framebuffer_locked(size_t size, int usage,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
// allocate the framebuffer
|
||||
if (m->framebuffer == NULL) {
|
||||
// initialize the framebuffer, the framebuffer is mapped once
|
||||
// and forever.
|
||||
int err = deps.mapFrameBufferLocked(m);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
LOGE("%s: Invalid framebuffer", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
const uint32_t bufferMask = m->bufferMask;
|
||||
@ -102,7 +97,8 @@ int gpu_context_t::gralloc_alloc_framebuffer_locked(size_t size, int usage,
|
||||
// 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;
|
||||
return gralloc_alloc_buffer(bufferSize, newUsage, pHandle, BUFFER_TYPE_UI, m->fbFormat, m->info.xres, m->info.yres);
|
||||
return gralloc_alloc_buffer(bufferSize, newUsage, pHandle, BUFFER_TYPE_UI,
|
||||
m->fbFormat, m->info.xres, m->info.yres);
|
||||
}
|
||||
|
||||
if (bufferMask >= ((1LU<<numBuffers)-1)) {
|
||||
@ -111,11 +107,14 @@ int gpu_context_t::gralloc_alloc_framebuffer_locked(size_t size, int usage,
|
||||
}
|
||||
|
||||
// create a "fake" handles for it
|
||||
// Set the PMEM flag as well, since adreno
|
||||
// treats the FB memory as pmem
|
||||
intptr_t vaddr = intptr_t(m->framebuffer->base);
|
||||
private_handle_t* hnd = new private_handle_t(dup(m->framebuffer->fd), bufferSize,
|
||||
private_handle_t::PRIV_FLAGS_USES_PMEM |
|
||||
private_handle_t::PRIV_FLAGS_FRAMEBUFFER,
|
||||
BUFFER_TYPE_UI, m->fbFormat, m->info.xres, m->info.yres);
|
||||
BUFFER_TYPE_UI, m->fbFormat, m->info.xres,
|
||||
m->info.yres);
|
||||
|
||||
// find a free slot
|
||||
for (uint32_t i=0 ; i<numBuffers ; i++) {
|
||||
@ -129,7 +128,6 @@ int gpu_context_t::gralloc_alloc_framebuffer_locked(size_t size, int usage,
|
||||
hnd->base = vaddr;
|
||||
hnd->offset = vaddr - intptr_t(m->framebuffer->base);
|
||||
*pHandle = hnd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -144,161 +142,38 @@ int gpu_context_t::gralloc_alloc_framebuffer(size_t size, int usage,
|
||||
return err;
|
||||
}
|
||||
|
||||
int gpu_context_t::alloc_ashmem_buffer(size_t size, unsigned int postfix, void** pBase,
|
||||
int* pOffset, int* pFd)
|
||||
{
|
||||
int err = 0;
|
||||
int fd = -1;
|
||||
void* base = 0;
|
||||
int offset = 0;
|
||||
|
||||
char name[ASHMEM_NAME_LEN];
|
||||
snprintf(name, ASHMEM_NAME_LEN, "gralloc-buffer-%x", postfix);
|
||||
int prot = PROT_READ | PROT_WRITE;
|
||||
fd = ashmem_create_region(name, size);
|
||||
if (fd < 0) {
|
||||
LOGE("couldn't create ashmem (%s)", strerror(errno));
|
||||
err = -errno;
|
||||
} else {
|
||||
if (ashmem_set_prot_region(fd, prot) < 0) {
|
||||
LOGE("ashmem_set_prot_region(fd=%d, prot=%x) failed (%s)",
|
||||
fd, prot, strerror(errno));
|
||||
close(fd);
|
||||
err = -errno;
|
||||
} else {
|
||||
base = mmap(0, size, prot, MAP_SHARED|MAP_POPULATE|MAP_LOCKED, fd, 0);
|
||||
if (base == MAP_FAILED) {
|
||||
LOGE("alloc mmap(fd=%d, size=%d, prot=%x) failed (%s)",
|
||||
fd, size, prot, strerror(errno));
|
||||
close(fd);
|
||||
err = -errno;
|
||||
} else {
|
||||
memset((char*)base + offset, 0, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(err == 0) {
|
||||
*pFd = fd;
|
||||
*pBase = base;
|
||||
*pOffset = offset;
|
||||
#ifdef HOST
|
||||
if (ioctl(fd, ASHMEM_CACHE_INV_RANGE, NULL)) {
|
||||
LOGE("ASHMEM_CACHE_INV_RANGE failed fd = %d", fd);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t* pHandle,
|
||||
int bufferType, int format, int width, int height)
|
||||
int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage,
|
||||
buffer_handle_t* pHandle, int bufferType,
|
||||
int format, int width, int height)
|
||||
{
|
||||
int err = 0;
|
||||
int flags = 0;
|
||||
|
||||
int fd = -1;
|
||||
void* base = 0; // XXX JMG: This should change to just get an address from
|
||||
// the PmemAllocator rather than getting the base & offset separately
|
||||
int offset = 0;
|
||||
int lockState = 0;
|
||||
|
||||
size = roundUpToPageSize(size);
|
||||
#ifndef USE_ASHMEM
|
||||
if (usage & GRALLOC_USAGE_HW_TEXTURE) {
|
||||
// enable pmem in that case, so our software GL can fallback to
|
||||
// the copybit module.
|
||||
flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
|
||||
}
|
||||
|
||||
if (usage & GRALLOC_USAGE_HW_2D) {
|
||||
flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
|
||||
}
|
||||
#else
|
||||
// Enable use of PMEM only when MDP composition is used (and other conditions apply).
|
||||
// Else fall back on using ASHMEM
|
||||
if ((get_composition_type() == MDP_COMPOSITION) &&
|
||||
((usage & GRALLOC_USAGE_HW_TEXTURE) || (usage & GRALLOC_USAGE_HW_2D)) ) {
|
||||
flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
|
||||
}
|
||||
|
||||
if (usage & GRALLOC_USAGE_PRIVATE_EBI_HEAP) {
|
||||
flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
|
||||
}
|
||||
#endif
|
||||
if ((usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP) || (usage & GRALLOC_USAGE_PRIVATE_SMI_HEAP)
|
||||
|| (usage & GRALLOC_USAGE_EXTERNAL_DISP) || (usage & GRALLOC_USAGE_PROTECTED)) {
|
||||
flags |= private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP;
|
||||
flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM;
|
||||
}
|
||||
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
|
||||
if((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) == 0 &&
|
||||
(flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) == 0) {
|
||||
flags |= private_handle_t::PRIV_FLAGS_USES_ASHMEM;
|
||||
err = alloc_ashmem_buffer(size, (unsigned int)pHandle, &base, &offset, &fd);
|
||||
if(err >= 0)
|
||||
lockState |= private_handle_t::LOCK_STATE_MAPPED;
|
||||
}
|
||||
else if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) != 0 ||
|
||||
(flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0) {
|
||||
|
||||
PmemAllocator* pma = 0;
|
||||
|
||||
if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) != 0) {
|
||||
if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0) {
|
||||
LOGE("attempting to allocate a gralloc buffer with both the "
|
||||
"USES_PMEM and USES_PMEM_ADSP flags. Unsetting the "
|
||||
"USES_PMEM_ADSP flag.");
|
||||
flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP;
|
||||
}
|
||||
pma = &pmemAllocator;
|
||||
} else { // (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0
|
||||
pma = &pmemAdspAllocator;
|
||||
}
|
||||
|
||||
// PMEM buffers are always mmapped
|
||||
lockState |= private_handle_t::LOCK_STATE_MAPPED;
|
||||
|
||||
err = pma->alloc_pmem_buffer(size, usage, &base, &offset, &fd, format);
|
||||
if (err < 0) {
|
||||
// Pmem allocation failed. Try falling back to ashmem iff we are:
|
||||
// a. not using MDP composition
|
||||
// b. not allocating memory for a buffer to be used by overlays
|
||||
// c. The client has not explicitly requested a PMEM buffer
|
||||
if ((get_composition_type() != MDP_COMPOSITION) &&
|
||||
(bufferType != BUFFER_TYPE_VIDEO) &&
|
||||
((usage & GRALLOC_USAGE_PRIVATE_EBI_HEAP) == 0) &&
|
||||
((usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP) == 0)) {
|
||||
// the caller didn't request PMEM, so we can try something else
|
||||
flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM;
|
||||
err = 0;
|
||||
LOGE("Pmem allocation failed. Trying ashmem");
|
||||
goto try_ashmem;
|
||||
} else {
|
||||
LOGE("couldn't open pmem (%s)", strerror(errno));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try_ashmem:
|
||||
err = alloc_ashmem_buffer(size, (unsigned int)pHandle, &base, &offset, &fd);
|
||||
if (err >= 0) {
|
||||
lockState |= private_handle_t::LOCK_STATE_MAPPED;
|
||||
flags |= private_handle_t::PRIV_FLAGS_USES_ASHMEM;
|
||||
} else {
|
||||
LOGE("Ashmem fallback failed");
|
||||
}
|
||||
}
|
||||
alloc_data data;
|
||||
data.offset = 0;
|
||||
data.fd = -1;
|
||||
data.base = 0;
|
||||
data.size = size;
|
||||
if(format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED)
|
||||
data.align = 8192;
|
||||
else
|
||||
data.align = getpagesize();
|
||||
data.pHandle = (unsigned int) pHandle;
|
||||
data.bufferType = bufferType;
|
||||
err = mAllocCtrl->allocate(data, usage, compositionType);
|
||||
|
||||
if (err == 0) {
|
||||
private_handle_t* hnd = new private_handle_t(fd, size, flags, bufferType, format, width, height);
|
||||
hnd->offset = offset;
|
||||
hnd->base = int(base)+offset;
|
||||
hnd->lockState = lockState;
|
||||
flags |= data.allocType;
|
||||
private_handle_t* hnd = new private_handle_t(data.fd, size, flags,
|
||||
bufferType, format, width, height);
|
||||
|
||||
hnd->offset = data.offset;
|
||||
hnd->base = int(data.base) + data.offset;
|
||||
hnd->lockState = private_handle_t::LOCK_STATE_MAPPED;
|
||||
*pHandle = hnd;
|
||||
}
|
||||
|
||||
LOGE_IF(err, "gralloc failed err=%s", strerror(-err));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -306,7 +181,9 @@ static inline size_t ALIGN(size_t x, size_t align) {
|
||||
return (x + align-1) & ~(align-1);
|
||||
}
|
||||
|
||||
void gpu_context_t::getGrallocInformationFromFormat(int inputFormat, int *colorFormat, int *bufferType)
|
||||
void gpu_context_t::getGrallocInformationFromFormat(int inputFormat,
|
||||
int *colorFormat,
|
||||
int *bufferType)
|
||||
{
|
||||
*bufferType = BUFFER_TYPE_VIDEO;
|
||||
*colorFormat = inputFormat;
|
||||
@ -331,7 +208,7 @@ void gpu_context_t::getGrallocInformationFromFormat(int inputFormat, int *colorF
|
||||
}
|
||||
|
||||
int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
|
||||
buffer_handle_t* pHandle, int* pStride, int bufferSize) {
|
||||
buffer_handle_t* pHandle, int* pStride, size_t bufferSize) {
|
||||
if (!pHandle || !pStride)
|
||||
return -EINVAL;
|
||||
|
||||
@ -341,7 +218,6 @@ int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
|
||||
alignedh = ALIGN(h, 32);
|
||||
int colorFormat, bufferType;
|
||||
getGrallocInformationFromFormat(format, &colorFormat, &bufferType);
|
||||
|
||||
switch (colorFormat) {
|
||||
case HAL_PIXEL_FORMAT_RGBA_8888:
|
||||
case HAL_PIXEL_FORMAT_RGBX_8888:
|
||||
@ -357,7 +233,7 @@ int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
|
||||
size = alignedw * alignedh * 2;
|
||||
break;
|
||||
|
||||
// adreno formats
|
||||
// adreno formats
|
||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21
|
||||
size = ALIGN(alignedw*alignedh, 4096);
|
||||
size += ALIGN(2 * ALIGN(w/2, 32) * ALIGN(h/2, 32), 4096);
|
||||
@ -371,7 +247,7 @@ int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
|
||||
size += ALIGN( alignedw * ALIGN(h/2, 32), 8192);
|
||||
break;
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
|
||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
|
||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
|
||||
case HAL_PIXEL_FORMAT_YV12:
|
||||
if ((w&1) || (h&1)) {
|
||||
LOGE("w or h is odd for the YUV format");
|
||||
@ -404,7 +280,8 @@ int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
|
||||
if (usage & GRALLOC_USAGE_HW_FB) {
|
||||
err = gralloc_alloc_framebuffer(size, usage, pHandle);
|
||||
} else {
|
||||
err = gralloc_alloc_buffer(size, usage, pHandle, bufferType, format, alignedw, alignedh);
|
||||
err = gralloc_alloc_buffer(size, usage, pHandle, bufferType,
|
||||
format, alignedw, alignedh);
|
||||
}
|
||||
|
||||
if (err < 0) {
|
||||
@ -421,41 +298,19 @@ int gpu_context_t::free_impl(private_handle_t const* hnd) {
|
||||
// free this buffer
|
||||
const size_t bufferSize = m->finfo.line_length * m->info.yres;
|
||||
int index = (hnd->base - m->framebuffer->base) / bufferSize;
|
||||
m->bufferMask &= ~(1<<index);
|
||||
m->bufferMask &= ~(1<<index);
|
||||
} else {
|
||||
PmemAllocator* pmem_allocator = 0;
|
||||
if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM) {
|
||||
pmem_allocator = &pmemAllocator;
|
||||
} else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) {
|
||||
pmem_allocator = &pmemAdspAllocator;
|
||||
} else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM) {
|
||||
// free ashmem
|
||||
if (hnd->fd >= 0) {
|
||||
if (hnd->base) {
|
||||
int err = munmap((void*)hnd->base, hnd->size);
|
||||
LOGE_IF(err<0, "ASHMEM_UNMAP failed (%s), "
|
||||
"fd=%d, sub.offset=%d, sub.size=%d",
|
||||
strerror(errno), hnd->fd, hnd->offset, hnd->size);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pmem_allocator) {
|
||||
pmem_allocator->free_pmem_buffer(hnd->size, (void*)hnd->base,
|
||||
hnd->offset, hnd->fd);
|
||||
}
|
||||
|
||||
deps.terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd));
|
||||
sp<IMemAlloc> memalloc = mAllocCtrl->getAllocator(hnd->flags);
|
||||
int err = memalloc->free_buffer((void*)hnd->base, (size_t) hnd->size,
|
||||
hnd->offset, hnd->fd);
|
||||
if(err)
|
||||
return err;
|
||||
}
|
||||
|
||||
deps.close(hnd->fd);
|
||||
delete hnd; // XXX JMG: move this to the deps
|
||||
// XXX any additional cleanup.
|
||||
delete hnd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Static functions
|
||||
*****************************************************************************/
|
||||
|
||||
int gpu_context_t::gralloc_alloc(alloc_device_t* dev, int w, int h, int format,
|
||||
int usage, buffer_handle_t* pHandle, int* pStride)
|
||||
{
|
||||
@ -465,7 +320,6 @@ int gpu_context_t::gralloc_alloc(alloc_device_t* dev, int w, int h, int format,
|
||||
gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev);
|
||||
return gpu->alloc_impl(w, h, format, usage, pHandle, pStride, 0);
|
||||
}
|
||||
|
||||
int gpu_context_t::gralloc_alloc_size(alloc_device_t* dev, int w, int h, int format,
|
||||
int usage, buffer_handle_t* pHandle, int* pStride, int bufferSize)
|
||||
{
|
||||
@ -476,8 +330,9 @@ int gpu_context_t::gralloc_alloc_size(alloc_device_t* dev, int w, int h, int for
|
||||
return gpu->alloc_impl(w, h, format, usage, pHandle, pStride, bufferSize);
|
||||
}
|
||||
|
||||
|
||||
int gpu_context_t::gralloc_free(alloc_device_t* dev,
|
||||
buffer_handle_t handle)
|
||||
buffer_handle_t handle)
|
||||
{
|
||||
if (private_handle_t::validate(handle) < 0)
|
||||
return -EINVAL;
|
||||
@ -501,5 +356,3 @@ int gpu_context_t::gralloc_close(struct hw_device_t *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
gpu_context_t::Deps::~Deps() {}
|
81
libgralloc/gpu.h
Normal file
81
libgralloc/gpu.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* Copyright (c) 2011 Code Aurora Forum. 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_GPU_H_
|
||||
#define GRALLOC_GPU_H_
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <cutils/ashmem.h>
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
#include "gralloc_priv.h"
|
||||
|
||||
namespace gralloc {
|
||||
class IAllocController;
|
||||
class gpu_context_t : public alloc_device_t {
|
||||
public:
|
||||
gpu_context_t(const private_module_t* module,
|
||||
android::sp<IAllocController>alloc_ctrl);
|
||||
|
||||
int gralloc_alloc_framebuffer_locked(size_t size, int usage,
|
||||
buffer_handle_t* pHandle);
|
||||
|
||||
int gralloc_alloc_framebuffer(size_t size, int usage,
|
||||
buffer_handle_t* pHandle);
|
||||
|
||||
int gralloc_alloc_buffer(size_t size, int usage,
|
||||
buffer_handle_t* pHandle,
|
||||
int bufferType, int format,
|
||||
int width, int height);
|
||||
|
||||
int free_impl(private_handle_t const* hnd);
|
||||
|
||||
int alloc_impl(int w, int h, int format, int usage,
|
||||
buffer_handle_t* pHandle, int* pStride,
|
||||
size_t bufferSize = 0);
|
||||
|
||||
static int gralloc_alloc(alloc_device_t* dev, int w, int h,
|
||||
int format, int usage,
|
||||
buffer_handle_t* pHandle,
|
||||
int* pStride);
|
||||
|
||||
static int gralloc_free(alloc_device_t* dev, buffer_handle_t handle);
|
||||
|
||||
static int gralloc_alloc_size(alloc_device_t* dev,
|
||||
int w, int h, int format,
|
||||
int usage, buffer_handle_t* pHandle,
|
||||
int* pStride, int bufferSize);
|
||||
|
||||
static int gralloc_close(struct hw_device_t *dev);
|
||||
|
||||
int get_composition_type() const { return compositionType; }
|
||||
|
||||
|
||||
private:
|
||||
android::sp<IAllocController> mAllocCtrl;
|
||||
int compositionType;
|
||||
void getGrallocInformationFromFormat(int inputFormat,
|
||||
int *colorFormat,
|
||||
int *bufferType);
|
||||
};
|
||||
}
|
||||
#endif // GRALLOC_GPU_H
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* Copyright (c) 2011 Code Aurora Forum. 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.
|
113
libgralloc/gralloc.cpp
Normal file
113
libgralloc/gralloc.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (C) 2008, The Android Open Source Project
|
||||
* Copyright (c) 2011, Code Aurora Forum. 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.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <cutils/properties.h>
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
#include <linux/android_pmem.h>
|
||||
|
||||
#include "gr.h"
|
||||
#include "gpu.h"
|
||||
#include "memalloc.h"
|
||||
#include "alloc_controller.h"
|
||||
|
||||
using namespace gralloc;
|
||||
using android::sp;
|
||||
|
||||
int fb_device_open(const hw_module_t* module, const char* name,
|
||||
hw_device_t** device);
|
||||
|
||||
static int gralloc_device_open(const hw_module_t* module, const char* name,
|
||||
hw_device_t** device);
|
||||
|
||||
extern int gralloc_lock(gralloc_module_t const* module,
|
||||
buffer_handle_t handle, int usage,
|
||||
int l, int t, int w, int h,
|
||||
void** vaddr);
|
||||
|
||||
extern int gralloc_unlock(gralloc_module_t const* module,
|
||||
buffer_handle_t handle);
|
||||
|
||||
extern int gralloc_register_buffer(gralloc_module_t const* module,
|
||||
buffer_handle_t handle);
|
||||
|
||||
extern int gralloc_unregister_buffer(gralloc_module_t const* module,
|
||||
buffer_handle_t handle);
|
||||
|
||||
extern int gralloc_perform(struct gralloc_module_t const* module,
|
||||
int operation, ... );
|
||||
|
||||
// HAL module methods
|
||||
static struct hw_module_methods_t gralloc_module_methods = {
|
||||
open: gralloc_device_open
|
||||
};
|
||||
|
||||
// HAL module initialize
|
||||
struct private_module_t HAL_MODULE_INFO_SYM = {
|
||||
base: {
|
||||
common: {
|
||||
tag: HARDWARE_MODULE_TAG,
|
||||
version_major: 1,
|
||||
version_minor: 0,
|
||||
id: GRALLOC_HARDWARE_MODULE_ID,
|
||||
name: "Graphics Memory Allocator Module",
|
||||
author: "The Android Open Source Project",
|
||||
methods: &gralloc_module_methods,
|
||||
dso: 0,
|
||||
reserved: {0},
|
||||
},
|
||||
registerBuffer: gralloc_register_buffer,
|
||||
unregisterBuffer: gralloc_unregister_buffer,
|
||||
lock: gralloc_lock,
|
||||
unlock: gralloc_unlock,
|
||||
perform: gralloc_perform,
|
||||
reserved_proc: {0},
|
||||
},
|
||||
framebuffer: 0,
|
||||
fbFormat: 0,
|
||||
flags: 0,
|
||||
numBuffers: 0,
|
||||
bufferMask: 0,
|
||||
lock: PTHREAD_MUTEX_INITIALIZER,
|
||||
currentBuffer: 0,
|
||||
};
|
||||
|
||||
// Open Gralloc device
|
||||
int gralloc_device_open(const hw_module_t* module, const char* name,
|
||||
hw_device_t** device)
|
||||
{
|
||||
int status = -EINVAL;
|
||||
if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
|
||||
const private_module_t* m = reinterpret_cast<const private_module_t*>(
|
||||
module);
|
||||
gpu_context_t *dev;
|
||||
sp<IAllocController> alloc_ctrl = IAllocController::getInstance();
|
||||
dev = new gpu_context_t(m, alloc_ctrl);
|
||||
*device = &dev->common;
|
||||
status = 0;
|
||||
} else {
|
||||
status = fb_device_open(module, name, device);
|
||||
}
|
||||
return status;
|
||||
}
|
14
libgralloc-qsd8k/gralloc_priv.h → libgralloc/gralloc_priv.h
Executable file → Normal file
14
libgralloc-qsd8k/gralloc_priv.h → libgralloc/gralloc_priv.h
Executable file → Normal file
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
|
||||
* Copyright (c) 2011, Code Aurora Forum. 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.
|
||||
@ -45,6 +45,11 @@ enum {
|
||||
/* Set this for allocating uncached memory (using O_DSYNC)
|
||||
* cannot be used with the system heap */
|
||||
GRALLOC_USAGE_PRIVATE_UNCACHED = 0x00010000,
|
||||
/* This flag needs to be set when using a system heap
|
||||
* from ION. If not set, the system heap is assumed
|
||||
* to be coming from ashmem
|
||||
*/
|
||||
GRALLOC_USAGE_PRIVATE_ION = 0x00020000,
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -68,6 +73,8 @@ enum {
|
||||
#define DEVICE_PMEM_SMIPOOL "/dev/pmem_smipool"
|
||||
/*****************************************************************************/
|
||||
#ifdef __cplusplus
|
||||
|
||||
//XXX: Remove framebuffer specific classes and defines to a different header
|
||||
template <class T>
|
||||
struct Node
|
||||
{
|
||||
@ -226,7 +233,7 @@ struct private_module_t {
|
||||
float fps;
|
||||
int swapInterval;
|
||||
#ifdef __cplusplus
|
||||
Queue<struct qbuf_t> disp; // non-empty when buffer is ready for display
|
||||
Queue<struct qbuf_t> disp; // non-empty when buffer is ready for display
|
||||
#endif
|
||||
int currentIdx;
|
||||
struct avail_t avail[NUM_FRAMEBUFFERS_MAX];
|
||||
@ -262,7 +269,6 @@ struct private_handle_t : public native_handle {
|
||||
struct private_handle_t {
|
||||
native_handle_t nativeHandle;
|
||||
#endif
|
||||
|
||||
enum {
|
||||
PRIV_FLAGS_FRAMEBUFFER = 0x00000001,
|
||||
PRIV_FLAGS_USES_PMEM = 0x00000002,
|
||||
@ -324,7 +330,7 @@ struct private_handle_t {
|
||||
const private_handle_t* hnd = (const private_handle_t*)h;
|
||||
if (!h || h->version != sizeof(native_handle) ||
|
||||
h->numInts != sNumInts || h->numFds != sNumFds ||
|
||||
hnd->magic != sMagic)
|
||||
hnd->magic != sMagic)
|
||||
{
|
||||
LOGE("invalid gralloc handle (at %p)", h);
|
||||
return -EINVAL;
|
249
libgralloc/ionalloc.cpp
Normal file
249
libgralloc/ionalloc.cpp
Normal file
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of Code Aurora Forum, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <cutils/log.h>
|
||||
#include <errno.h>
|
||||
#include "ionalloc.h"
|
||||
|
||||
using gralloc::IonAlloc;
|
||||
|
||||
#define ION_DEVICE "/dev/ion"
|
||||
|
||||
int IonAlloc::open_device()
|
||||
{
|
||||
if(mIonFd == FD_INIT)
|
||||
mIonFd = open(ION_DEVICE, O_RDONLY);
|
||||
|
||||
if(mIonFd < 0 ) {
|
||||
LOGE("%s: Failed to open ion device - %s",
|
||||
__FUNCTION__, strerror(errno));
|
||||
mIonFd = FD_INIT;
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void IonAlloc::close_device()
|
||||
{
|
||||
if(mIonFd > 0)
|
||||
close(mIonFd);
|
||||
mIonFd = FD_INIT;
|
||||
}
|
||||
|
||||
int IonAlloc::alloc_buffer(alloc_data& data)
|
||||
{
|
||||
int err = 0;
|
||||
int ionSyncFd = FD_INIT;
|
||||
int iFd = FD_INIT;
|
||||
struct ion_handle_data handle_data;
|
||||
struct ion_fd_data fd_data;
|
||||
struct ion_allocation_data ionAllocData;
|
||||
|
||||
void *base = 0;
|
||||
|
||||
ionAllocData.len = data.size;
|
||||
ionAllocData.align = data.align;
|
||||
ionAllocData.flags = data.flags;
|
||||
|
||||
err = open_device();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if(data.uncached) {
|
||||
// Use the sync FD to alloc and map
|
||||
// when we need uncached memory
|
||||
ionSyncFd = open(ION_DEVICE, O_RDONLY|O_DSYNC);
|
||||
if(ionSyncFd < 0) {
|
||||
LOGE("%s: Failed to open ion device - %s",
|
||||
__FUNCTION__, strerror(errno));
|
||||
close_device();
|
||||
return -errno;
|
||||
}
|
||||
iFd = ionSyncFd;
|
||||
} else {
|
||||
iFd = mIonFd;
|
||||
}
|
||||
|
||||
err = ioctl(iFd, ION_IOC_ALLOC, &ionAllocData);
|
||||
if(err) {
|
||||
LOGE("ION_IOC_ALLOC failed with error - %s", strerror(errno));
|
||||
close_device();
|
||||
if(ionSyncFd >= 0)
|
||||
close(ionSyncFd);
|
||||
ionSyncFd = FD_INIT;
|
||||
return err;
|
||||
}
|
||||
|
||||
fd_data.handle = ionAllocData.handle;
|
||||
handle_data.handle = ionAllocData.handle;
|
||||
LOGD("%s: Trying ION_IOC_MAP pid=%d handle=%p size=%d mIonFd=%d flags=%x",
|
||||
__FUNCTION__, getpid(), ionAllocData.handle,
|
||||
ionAllocData.len, mIonFd, ionAllocData.flags);
|
||||
|
||||
err = ioctl(iFd, ION_IOC_MAP, &fd_data);
|
||||
if(err) {
|
||||
LOGE("%s: ION_IOC_MAP failed with error - %s",
|
||||
__FUNCTION__, strerror(errno));
|
||||
ioctl(mIonFd, ION_IOC_FREE, &handle_data);
|
||||
close_device();
|
||||
if(ionSyncFd >= 0)
|
||||
close(ionSyncFd);
|
||||
ionSyncFd = FD_INIT;
|
||||
return err;
|
||||
}
|
||||
|
||||
base = mmap(0, ionAllocData.len, PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED, fd_data.fd, 0);
|
||||
if(base == MAP_FAILED) {
|
||||
LOGD("%s: Failed to map the allocated memory: %s",
|
||||
__FUNCTION__, strerror(errno));
|
||||
err = -errno;
|
||||
ioctl(mIonFd, ION_IOC_FREE, &handle_data);
|
||||
close_device();
|
||||
ionSyncFd = FD_INIT;
|
||||
return err;
|
||||
}
|
||||
//Close the uncached FD since we no longer need it;
|
||||
if(ionSyncFd >= 0)
|
||||
close(ionSyncFd);
|
||||
ionSyncFd = FD_INIT;
|
||||
|
||||
// Not doing memset for ION, uncomment if needed
|
||||
// memset(base, 0, ionAllocData.len);
|
||||
// Clean cache after memset
|
||||
// clean_buffer(base, data.size, data.offset, fd_data.fd);
|
||||
data.base = base;
|
||||
data.fd = fd_data.fd;
|
||||
ioctl(mIonFd, ION_IOC_FREE, &handle_data);
|
||||
LOGD("%s: ION alloc succeeded - mIonFd=%d, SharedFD=%d PID=%d size=%d"
|
||||
" ionHandle=%p", __FUNCTION__, mIonFd, fd_data.fd, getpid(),
|
||||
ionAllocData.len, ionAllocData.handle);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int IonAlloc::free_buffer(void* base, size_t size, int offset, int fd)
|
||||
{
|
||||
LOGD("%s:Freeing buffer size=%d base=%p mIonFd=%d fd=%d PID=%d",
|
||||
__FUNCTION__, size, base, mIonFd, fd, getpid());
|
||||
int err = 0;
|
||||
err = open_device();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if(!base) {
|
||||
LOGE("Invalid free");
|
||||
return -EINVAL;
|
||||
}
|
||||
err = unmap_buffer(base, size, offset);
|
||||
close(fd);
|
||||
return err;
|
||||
}
|
||||
|
||||
int IonAlloc::map_buffer(void **pBase, size_t size, int offset, int fd)
|
||||
{
|
||||
LOGD("%s: Mapping buffer fd=%d size=%d PID=%d", __FUNCTION__,
|
||||
fd, size, getpid());
|
||||
int err = 0;
|
||||
void *base = 0;
|
||||
// It is a (quirky) requirement of ION to have opened the
|
||||
// ion fd in the process that is doing the mapping
|
||||
err = open_device();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
base = mmap(0, size, PROT_READ| PROT_WRITE,
|
||||
MAP_SHARED, fd, 0);
|
||||
*pBase = base;
|
||||
if(base == MAP_FAILED) {
|
||||
LOGD("%s: Failed to map memory in the client: %s",
|
||||
__FUNCTION__, strerror(errno));
|
||||
err = -errno;
|
||||
} else {
|
||||
LOGD("%s: Successfully mapped %d bytes", __FUNCTION__, size);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int IonAlloc::unmap_buffer(void *base, size_t size, int offset)
|
||||
{
|
||||
LOGD("%s: Unmapping buffer at address %p", __FUNCTION__, base);
|
||||
int err = munmap(base, size);
|
||||
if(err) {
|
||||
LOGE("%s: Failed to unmap memory at %p: %s",
|
||||
__FUNCTION__, base, strerror(errno));
|
||||
}
|
||||
return err;
|
||||
|
||||
}
|
||||
int IonAlloc::clean_buffer(void *base, size_t size, int offset, int fd)
|
||||
{
|
||||
// LOGD("%s: Clean buffer fd=%d base = %p size=%d PID=%d", __FUNCTION__,
|
||||
// fd, base, size, getpid());
|
||||
struct ion_flush_data flush_data;
|
||||
struct ion_fd_data fd_data;
|
||||
struct ion_handle_data handle_data;
|
||||
struct ion_handle* handle;
|
||||
int err = 0;
|
||||
|
||||
err = open_device();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
fd_data.fd = fd;
|
||||
err = ioctl(mIonFd, ION_IOC_IMPORT, &fd_data);
|
||||
if(err) {
|
||||
LOGE("%s: ION_IOC_IMPORT failed with error - %s",
|
||||
__FUNCTION__, strerror(errno));
|
||||
close_device();
|
||||
return err;
|
||||
}
|
||||
|
||||
handle_data.handle = fd_data.handle;
|
||||
flush_data.handle = fd_data.handle;
|
||||
flush_data.vaddr = base;
|
||||
flush_data.offset = offset;
|
||||
flush_data.length = size;
|
||||
err = ioctl(mIonFd, ION_IOC_CLEAN_INV_CACHES, &flush_data);
|
||||
if(err) {
|
||||
LOGE("%s: ION_IOC_CLEAN_INV_CACHES failed with error - %s",
|
||||
__FUNCTION__, strerror(errno));
|
||||
ioctl(mIonFd, ION_IOC_FREE, &handle_data);
|
||||
close_device();
|
||||
return err;
|
||||
}
|
||||
ioctl(mIonFd, ION_IOC_FREE, &handle_data);
|
||||
return err;
|
||||
}
|
||||
|
71
libgralloc/ionalloc.h
Normal file
71
libgralloc/ionalloc.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of Code Aurora Forum, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef GRALLOC_IONALLOC_H
|
||||
#define GRALLOC_IONALLOC_H
|
||||
|
||||
#include "memalloc.h"
|
||||
#include <linux/ion.h>
|
||||
|
||||
namespace gralloc {
|
||||
|
||||
class IonAlloc : public IMemAlloc {
|
||||
|
||||
public:
|
||||
virtual int alloc_buffer(alloc_data& data);
|
||||
|
||||
virtual int free_buffer(void *base, size_t size,
|
||||
int offset, int fd);
|
||||
|
||||
virtual int map_buffer(void **pBase, size_t size,
|
||||
int offset, int fd);
|
||||
|
||||
virtual int unmap_buffer(void *base, size_t size,
|
||||
int offset);
|
||||
|
||||
virtual int clean_buffer(void*base, size_t size,
|
||||
int offset, int fd);
|
||||
|
||||
IonAlloc() { mIonFd = FD_INIT; }
|
||||
|
||||
~IonAlloc() { close_device(); }
|
||||
|
||||
private:
|
||||
int mIonFd;
|
||||
|
||||
int open_device();
|
||||
|
||||
void close_device();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* GRALLOC_IONALLOC_H */
|
||||
|
194
libgralloc-qsd8k/mapper.cpp → libgralloc/mapper.cpp
Executable file → Normal file
194
libgralloc-qsd8k/mapper.cpp → libgralloc/mapper.cpp
Executable file → Normal file
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* Copyright (c) 2011 Code Aurora Forum. 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.
|
||||
@ -38,20 +39,31 @@
|
||||
|
||||
#include "gralloc_priv.h"
|
||||
#include "gr.h"
|
||||
#include "ionalloc.h"
|
||||
#include "ashmemalloc.h"
|
||||
|
||||
// we need this for now because pmem cannot mmap at an offset
|
||||
#define PMEM_HACK 1
|
||||
|
||||
/* desktop Linux needs a little help with gettid() */
|
||||
#if defined(ARCH_X86) && !defined(HAVE_ANDROID_OS)
|
||||
#define __KERNEL__
|
||||
# include <linux/unistd.h>
|
||||
pid_t gettid() { return syscall(__NR_gettid);}
|
||||
#undef __KERNEL__
|
||||
#endif
|
||||
|
||||
using gralloc::IMemAlloc;
|
||||
using gralloc::IonAlloc;
|
||||
using gralloc::AshmemAlloc;
|
||||
using android::sp;
|
||||
/*****************************************************************************/
|
||||
|
||||
// Return the type of allocator -
|
||||
// these are used for mapping/unmapping
|
||||
static sp<IMemAlloc> getAllocator(int flags)
|
||||
{
|
||||
sp<IMemAlloc> memalloc;
|
||||
if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
|
||||
memalloc = new IonAlloc();
|
||||
}
|
||||
if (flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM) {
|
||||
memalloc = new AshmemAlloc();
|
||||
}
|
||||
|
||||
// XXX Return allocator for pmem
|
||||
return memalloc;
|
||||
}
|
||||
|
||||
static int gralloc_map(gralloc_module_t const* module,
|
||||
buffer_handle_t handle,
|
||||
void** vaddr)
|
||||
@ -60,16 +72,16 @@ static int gralloc_map(gralloc_module_t const* module,
|
||||
void *mappedAddress;
|
||||
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
|
||||
size_t size = hnd->size;
|
||||
#if PMEM_HACK
|
||||
size += hnd->offset;
|
||||
#endif
|
||||
if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM) {
|
||||
mappedAddress = mmap(0, size,
|
||||
PROT_READ|PROT_WRITE, MAP_SHARED | MAP_POPULATE, hnd->fd, 0);
|
||||
} else {
|
||||
mappedAddress = mmap(0, size,
|
||||
PROT_READ|PROT_WRITE, MAP_SHARED, hnd->fd, 0);
|
||||
sp<IMemAlloc> memalloc = getAllocator(hnd->flags) ;
|
||||
int err = memalloc->map_buffer(&mappedAddress, size,
|
||||
hnd->offset, hnd->fd);
|
||||
if(err) {
|
||||
LOGE("Could not mmap handle %p, fd=%d (%s)",
|
||||
handle, hnd->fd, strerror(errno));
|
||||
hnd->base = 0;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (mappedAddress == MAP_FAILED) {
|
||||
LOGE("Could not mmap handle %p, fd=%d (%s)",
|
||||
handle, hnd->fd, strerror(errno));
|
||||
@ -77,7 +89,7 @@ static int gralloc_map(gralloc_module_t const* module,
|
||||
return -errno;
|
||||
}
|
||||
hnd->base = intptr_t(mappedAddress) + hnd->offset;
|
||||
//LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
|
||||
//LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
|
||||
// hnd->fd, hnd->offset, hnd->size, mappedAddress);
|
||||
}
|
||||
*vaddr = (void*)hnd->base;
|
||||
@ -89,15 +101,14 @@ static int gralloc_unmap(gralloc_module_t const* module,
|
||||
{
|
||||
private_handle_t* hnd = (private_handle_t*)handle;
|
||||
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
|
||||
int err = -EINVAL;
|
||||
void* base = (void*)hnd->base;
|
||||
size_t size = hnd->size;
|
||||
#if PMEM_HACK
|
||||
base = (void*)(intptr_t(base) - hnd->offset);
|
||||
size += hnd->offset;
|
||||
#endif
|
||||
//LOGD("unmapping from %p, size=%d", base, size);
|
||||
if (munmap(base, size) < 0) {
|
||||
LOGE("Could not unmap %s", strerror(errno));
|
||||
sp<IMemAlloc> memalloc = getAllocator(hnd->flags) ;
|
||||
if(memalloc != NULL)
|
||||
err = memalloc->unmap_buffer(base, size, hnd->offset);
|
||||
if (err) {
|
||||
LOGE("Could not unmap memory at address %p", base);
|
||||
}
|
||||
}
|
||||
hnd->base = 0;
|
||||
@ -106,7 +117,7 @@ static int gralloc_unmap(gralloc_module_t const* module,
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@ -121,9 +132,9 @@ int gralloc_register_buffer(gralloc_module_t const* module,
|
||||
/* NOTE: we need to initialize the buffer as not mapped/not locked
|
||||
* because it shouldn't when this function is called the first time
|
||||
* in a new process. Ideally these flags shouldn't be part of the
|
||||
* handle, but instead maintained in the kernel or at least
|
||||
* handle, but instead maintained in the kernel or at least
|
||||
* out-of-line
|
||||
*/
|
||||
*/
|
||||
|
||||
// if this handle was created in this process, then we keep it as is.
|
||||
private_handle_t* hnd = (private_handle_t*)handle;
|
||||
@ -148,7 +159,7 @@ int gralloc_unregister_buffer(gralloc_module_t const* module,
|
||||
*/
|
||||
|
||||
private_handle_t* hnd = (private_handle_t*)handle;
|
||||
|
||||
|
||||
LOGE_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK,
|
||||
"[unregister] handle %p still locked (state=%08x)",
|
||||
hnd, hnd->lockState);
|
||||
@ -215,7 +226,7 @@ int gralloc_lock(gralloc_module_t const* module,
|
||||
new_value = current_value;
|
||||
|
||||
if (current_value & private_handle_t::LOCK_STATE_WRITE) {
|
||||
// already locked for write
|
||||
// already locked for write
|
||||
LOGE("handle %p already locked for write", handle);
|
||||
return -EBUSY;
|
||||
} else if (current_value & private_handle_t::LOCK_STATE_READ_MASK) {
|
||||
@ -225,7 +236,7 @@ int gralloc_lock(gralloc_module_t const* module,
|
||||
return -EBUSY;
|
||||
} else {
|
||||
// this is not an error
|
||||
//LOGD("%p already locked for read... count = %d",
|
||||
//LOGD("%p already locked for read... count = %d",
|
||||
// handle, (current_value & ~(1<<31)));
|
||||
}
|
||||
}
|
||||
@ -237,7 +248,7 @@ int gralloc_lock(gralloc_module_t const* module,
|
||||
}
|
||||
new_value++;
|
||||
|
||||
retry = android_atomic_cmpxchg(current_value, new_value,
|
||||
retry = android_atomic_cmpxchg(current_value, new_value,
|
||||
(volatile int32_t*)&hnd->lockState);
|
||||
} while (retry);
|
||||
|
||||
@ -274,7 +285,7 @@ int gralloc_lock(gralloc_module_t const* module,
|
||||
return err;
|
||||
}
|
||||
|
||||
int gralloc_unlock(gralloc_module_t const* module,
|
||||
int gralloc_unlock(gralloc_module_t const* module,
|
||||
buffer_handle_t handle)
|
||||
{
|
||||
if (private_handle_t::validate(handle) < 0)
|
||||
@ -285,18 +296,9 @@ int gralloc_unlock(gralloc_module_t const* module,
|
||||
|
||||
if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
|
||||
int err;
|
||||
if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
|
||||
private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP)) {
|
||||
struct pmem_addr pmem_addr;
|
||||
pmem_addr.vaddr = hnd->base;
|
||||
pmem_addr.offset = hnd->offset;
|
||||
pmem_addr.length = hnd->size;
|
||||
err = ioctl( hnd->fd, PMEM_CLEAN_CACHES, &pmem_addr);
|
||||
} else if ((hnd->flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM)) {
|
||||
unsigned long addr = hnd->base + hnd->offset;
|
||||
err = ioctl(hnd->fd, ASHMEM_CACHE_FLUSH_RANGE, NULL);
|
||||
}
|
||||
|
||||
sp<IMemAlloc> memalloc = getAllocator(hnd->flags) ;
|
||||
err = memalloc->clean_buffer((void*)hnd->base,
|
||||
hnd->size, hnd->offset, hnd->fd);
|
||||
LOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%x, flags = 0x%x) err=%s\n",
|
||||
hnd, hnd->offset, hnd->size, hnd->flags, strerror(errno));
|
||||
hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
|
||||
@ -321,8 +323,8 @@ int gralloc_unlock(gralloc_module_t const* module,
|
||||
|
||||
new_value--;
|
||||
|
||||
} while (android_atomic_cmpxchg(current_value, new_value,
|
||||
(volatile int32_t*)&hnd->lockState));
|
||||
} while (android_atomic_cmpxchg(current_value, new_value,
|
||||
(volatile int32_t*)&hnd->lockState));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -337,48 +339,64 @@ int gralloc_perform(struct gralloc_module_t const* module,
|
||||
va_start(args, operation);
|
||||
|
||||
switch (operation) {
|
||||
case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: {
|
||||
int fd = va_arg(args, int);
|
||||
size_t size = va_arg(args, size_t);
|
||||
size_t offset = va_arg(args, size_t);
|
||||
void* base = va_arg(args, void*);
|
||||
case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER:
|
||||
{
|
||||
int fd = va_arg(args, int);
|
||||
size_t size = va_arg(args, size_t);
|
||||
size_t offset = va_arg(args, size_t);
|
||||
void* base = va_arg(args, void*);
|
||||
|
||||
// validate that it's indeed a pmem buffer
|
||||
pmem_region region;
|
||||
if (ioctl(fd, PMEM_GET_SIZE, ®ion) < 0) {
|
||||
native_handle_t** handle = va_arg(args, native_handle_t**);
|
||||
int memoryFlags = va_arg(args, int);
|
||||
private_handle_t* hnd = (private_handle_t*)native_handle_create(
|
||||
private_handle_t::sNumFds, private_handle_t::sNumInts);
|
||||
hnd->magic = private_handle_t::sMagic;
|
||||
hnd->fd = fd;
|
||||
unsigned int contigFlags = GRALLOC_USAGE_PRIVATE_ADSP_HEAP |
|
||||
GRALLOC_USAGE_PRIVATE_EBI_HEAP |
|
||||
GRALLOC_USAGE_PRIVATE_SMI_HEAP;
|
||||
|
||||
if (memoryFlags & contigFlags) {
|
||||
// check if the buffer is a pmem buffer
|
||||
pmem_region region;
|
||||
if (ioctl(fd, PMEM_GET_SIZE, ®ion) < 0)
|
||||
hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
|
||||
else
|
||||
hnd->flags = private_handle_t::PRIV_FLAGS_USES_PMEM |
|
||||
private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
|
||||
} else {
|
||||
if (memoryFlags & GRALLOC_USAGE_PRIVATE_ION)
|
||||
hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
|
||||
else
|
||||
hnd->flags = private_handle_t::PRIV_FLAGS_USES_ASHMEM;
|
||||
}
|
||||
|
||||
hnd->size = size;
|
||||
hnd->offset = offset;
|
||||
hnd->base = intptr_t(base) + offset;
|
||||
hnd->lockState = private_handle_t::LOCK_STATE_MAPPED;
|
||||
hnd->gpuaddr = 0;
|
||||
*handle = (native_handle_t *)hnd;
|
||||
res = 0;
|
||||
break;
|
||||
|
||||
}
|
||||
case GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_HANDLE:
|
||||
{
|
||||
native_handle_t* handle = va_arg(args, native_handle_t*);
|
||||
int w = va_arg(args, int);
|
||||
int h = va_arg(args, int);
|
||||
int f = va_arg(args, int);
|
||||
private_handle_t* hnd = (private_handle_t*)handle;
|
||||
hnd->width = w;
|
||||
hnd->height = h;
|
||||
if (hnd->format != f) {
|
||||
hnd->format = f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
native_handle_t** handle = va_arg(args, native_handle_t**);
|
||||
private_handle_t* hnd = (private_handle_t*)native_handle_create(
|
||||
private_handle_t::sNumFds, private_handle_t::sNumInts);
|
||||
hnd->magic = private_handle_t::sMagic;
|
||||
hnd->fd = fd;
|
||||
hnd->flags = private_handle_t::PRIV_FLAGS_USES_PMEM;
|
||||
hnd->size = size;
|
||||
hnd->offset = offset;
|
||||
hnd->base = intptr_t(base) + offset;
|
||||
hnd->lockState = private_handle_t::LOCK_STATE_MAPPED;
|
||||
hnd->gpuaddr = 0;
|
||||
*handle = (native_handle_t *)hnd;
|
||||
res = 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_HANDLE: {
|
||||
native_handle_t* handle = va_arg(args, native_handle_t*);
|
||||
int w = va_arg(args, int);
|
||||
int h = va_arg(args, int);
|
||||
int f = va_arg(args, int);
|
||||
private_handle_t* hnd = (private_handle_t*)handle;
|
||||
hnd->width = w;
|
||||
hnd->height = h;
|
||||
if (hnd->format != f) {
|
||||
hnd->format = f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
va_end(args);
|
85
libgralloc/memalloc.h
Normal file
85
libgralloc/memalloc.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of Code Aurora Forum, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef GRALLOC_MEMALLOC_H
|
||||
#define GRALLOC_MEMALLOC_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
namespace gralloc {
|
||||
|
||||
struct alloc_data {
|
||||
void *base;
|
||||
int fd;
|
||||
int offset;
|
||||
size_t size;
|
||||
size_t align;
|
||||
unsigned int pHandle;
|
||||
bool uncached;
|
||||
unsigned int flags;
|
||||
int bufferType;
|
||||
int allocType;
|
||||
};
|
||||
|
||||
class IMemAlloc : public android::RefBase {
|
||||
|
||||
public:
|
||||
// Allocate buffer - fill in the alloc_data
|
||||
// structure and pass it in. Mapped address
|
||||
// and fd are returned in the alloc_data struct
|
||||
virtual int alloc_buffer(alloc_data& data) = 0;
|
||||
|
||||
// Free buffer
|
||||
virtual int free_buffer(void *base, size_t size,
|
||||
int offset, int fd) = 0;
|
||||
|
||||
// Map buffer
|
||||
virtual int map_buffer(void **pBase, size_t size,
|
||||
int offset, int fd) = 0;
|
||||
|
||||
// Unmap buffer
|
||||
virtual int unmap_buffer(void *base, size_t size,
|
||||
int offset) = 0;
|
||||
|
||||
// Clean and invalidate
|
||||
virtual int clean_buffer(void *base, size_t size,
|
||||
int offset, int fd) = 0;
|
||||
|
||||
// Destructor
|
||||
virtual ~IMemAlloc() {};
|
||||
|
||||
enum {
|
||||
FD_INIT = -1,
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
} // end gralloc namespace
|
||||
#endif // GRALLOC_MEMALLOC_H
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
* Copyright (c) 2011 Code Aurora Forum. 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.
|
||||
@ -16,7 +17,7 @@
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include "allocator.h"
|
||||
#include "pmem_bestfit_alloc.h"
|
||||
|
||||
|
||||
// align all the memory blocks on a cache-line boundary
|
||||
@ -50,8 +51,7 @@ ssize_t SimpleBestFitAllocator::setSize(size_t size)
|
||||
mList.insertHead(node);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
size_t SimpleBestFitAllocator::size() const
|
||||
{
|
||||
return mHeapSize;
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
* Copyright (c) 2011 Code Aurora Forum. 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.
|
||||
@ -71,7 +72,7 @@ public:
|
||||
mFirst = newNode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void insertTail(NODE* newNode) {
|
||||
if (mLast == 0) {
|
||||
insertHead(newNode);
|
||||
@ -108,7 +109,7 @@ public:
|
||||
|
||||
private:
|
||||
struct chunk_t {
|
||||
chunk_t(size_t start, size_t size)
|
||||
chunk_t(size_t start, size_t size)
|
||||
: start(start), size(size), free(1), prev(0), next(0) {
|
||||
}
|
||||
size_t start;
|
13
libgralloc-qsd8k/pmemalloc.cpp → libgralloc/pmemalloc.cpp
Executable file → Normal file
13
libgralloc-qsd8k/pmemalloc.cpp → libgralloc/pmemalloc.cpp
Executable file → Normal file
@ -54,7 +54,8 @@ PmemAllocator::~PmemAllocator()
|
||||
}
|
||||
|
||||
|
||||
PmemUserspaceAllocator::PmemUserspaceAllocator(Deps& deps, Deps::Allocator& allocator, const char* pmemdev):
|
||||
PmemUserspaceAllocator::PmemUserspaceAllocator(Deps& deps,
|
||||
Deps::Allocator& allocator, const char* pmemdev):
|
||||
deps(deps),
|
||||
allocator(allocator),
|
||||
pmemdev(pmemdev),
|
||||
@ -201,7 +202,8 @@ int PmemUserspaceAllocator::alloc_pmem_buffer(size_t size, int usage,
|
||||
}
|
||||
|
||||
|
||||
int PmemUserspaceAllocator::free_pmem_buffer(size_t size, void* base, int offset, int fd)
|
||||
int PmemUserspaceAllocator::free_pmem_buffer(size_t size, void* base,
|
||||
int offset, int fd)
|
||||
{
|
||||
BEGIN_FUNC;
|
||||
int err = 0;
|
||||
@ -277,7 +279,6 @@ int PmemKernelAllocator::alloc_pmem_buffer(size_t size, int usage,
|
||||
int err, offset = 0;
|
||||
int openFlags = get_open_flags(usage);
|
||||
const char *device;
|
||||
|
||||
if (usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP) {
|
||||
device = DEVICE_PMEM_ADSP;
|
||||
} else if (usage & GRALLOC_USAGE_PRIVATE_SMI_HEAP) {
|
||||
@ -335,10 +336,12 @@ int PmemKernelAllocator::alloc_pmem_buffer(size_t size, int usage,
|
||||
}
|
||||
|
||||
|
||||
int PmemKernelAllocator::free_pmem_buffer(size_t size, void* base, int offset, int fd)
|
||||
int PmemKernelAllocator::free_pmem_buffer(size_t size, void* base,
|
||||
int offset, int fd)
|
||||
{
|
||||
BEGIN_FUNC;
|
||||
// The size should already be page aligned, now round it up to a power of 2
|
||||
// The size should already be page aligned,
|
||||
// now round it up to a power of 2
|
||||
// like we did when allocating.
|
||||
//size = clp2(size);
|
||||
|
0
libgralloc-qsd8k/pmemalloc.h → libgralloc/pmemalloc.h
Executable file → Normal file
0
libgralloc-qsd8k/pmemalloc.h → libgralloc/pmemalloc.h
Executable file → Normal file
Loading…
Reference in New Issue
Block a user