summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/binder/Android.mk43
-rw-r--r--libs/binder/IMemory.cpp29
-rw-r--r--libs/binder/MemoryHeapIon.cpp191
-rw-r--r--libs/gui/ISurfaceComposer.cpp8
-rw-r--r--libs/gui/Surface.cpp23
-rw-r--r--libs/gui/SurfaceComposerClient.cpp11
-rw-r--r--libs/ui/GraphicBuffer.cpp1
-rw-r--r--libs/ui/GraphicBufferMapper.cpp13
8 files changed, 303 insertions, 16 deletions
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
index d5860ef6c..b12eda8e9 100644
--- a/libs/binder/Android.mk
+++ b/libs/binder/Android.mk
@@ -38,11 +38,31 @@ sources := \
Static.cpp \
TextOutput.cpp \
+ifeq ($(BOARD_NEEDS_MEMORYHEAPION),true)
+sources += \
+ MemoryHeapIon.cpp
+endif
+
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
+
+ifeq ($(BOARD_NEEDS_MEMORYHEAPION),true)
+LOCAL_SHARED_LIBRARIES += libion_exynos
+LOCAL_CFLAGS += -DUSE_MEMORY_HEAP_ION
+
+ifeq ($(TARGET_SLSI_VARIANT),cm)
+SLSI_DIR := samsung_slsi-cm
+PLATFORM_DIR := $(TARGET_BOARD_PLATFORM)
+else
+SLSI_DIR := samsung_slsi
+PLATFORM_DIR := $(TARGET_BOARD_PLATFORM)-$(TARGET_SLSI_VARIANT)
+endif
+LOCAL_C_INCLUDES += hardware/$(SLSI_DIR)/$(PLATFORM_DIR)/include
+endif
+
LOCAL_MODULE := libbinder
-LOCAL_SHARED_LIBRARIES := liblog libcutils libutils
+LOCAL_SHARED_LIBRARIES += liblog libcutils libutils
LOCAL_SRC_FILES := $(sources)
ifneq ($(TARGET_USES_64_BIT_BINDER),true)
ifneq ($(TARGET_IS_64_BIT),true)
@@ -53,9 +73,30 @@ LOCAL_CFLAGS += -Werror
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
+
+ifeq ($(BOARD_NEEDS_MEMORYHEAPION),true)
+LOCAL_SHARED_LIBRARIES += libion_exynos
+LOCAL_CFLAGS += -DUSE_MEMORY_HEAP_ION
+
+ifeq ($(TARGET_SLSI_VARIANT),cm)
+SLSI_DIR := samsung_slsi-cm
+PLATFORM_DIR := $(TARGET_BOARD_PLATFORM)
+else
+SLSI_DIR := samsung_slsi
+PLATFORM_DIR := $(TARGET_BOARD_PLATFORM)-$(TARGET_SLSI_VARIANT)
+endif
+LOCAL_C_INCLUDES += hardware/$(SLSI_DIR)/$(PLATFORM_DIR)/include
+endif
+
LOCAL_MODULE := libbinder
LOCAL_STATIC_LIBRARIES += libutils
LOCAL_SRC_FILES := $(sources)
+ifeq ($(BOARD_NEEDS_MEMORYHEAPPMEM),true)
+LOCAL_C_INCLUDES += \
+ $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_ADDITIONAL_DEPENDENCIES := \
+ $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+endif
ifneq ($(TARGET_USES_64_BIT_BINDER),true)
ifneq ($(TARGET_IS_64_BIT),true)
LOCAL_CFLAGS += -DBINDER_IPC_32BIT=1
diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp
index e9891a830..3f2198abf 100644
--- a/libs/binder/IMemory.cpp
+++ b/libs/binder/IMemory.cpp
@@ -32,6 +32,10 @@
#include <binder/Parcel.h>
#include <utils/CallStack.h>
+#ifdef USE_MEMORY_HEAP_ION
+#include "ion.h"
+#endif
+
#define VERBOSE 0
namespace android {
@@ -300,6 +304,14 @@ void BpMemoryHeap::assertReallyMapped() const
IInterface::asBinder(this).get(),
parcel_fd, size, err, strerror(-err));
+#ifdef USE_MEMORY_HEAP_ION
+ ion_client ion_client_num = -1;
+ if (flags & USE_ION_FD) {
+ ion_client_num = ion_client_create();
+ ALOGE_IF(ion_client_num < 0, "BpMemoryHeap : ion client creation error");
+ }
+#endif
+
int fd = dup( parcel_fd );
ALOGE_IF(fd==-1, "cannot dup fd=%d, size=%zd, err=%d (%s)",
parcel_fd, size, err, strerror(errno));
@@ -312,7 +324,16 @@ void BpMemoryHeap::assertReallyMapped() const
Mutex::Autolock _l(mLock);
if (mHeapId == -1) {
mRealHeap = true;
- mBase = mmap(0, size, access, MAP_SHARED, fd, offset);
+
+#ifdef USE_MEMORY_HEAP_ION
+ if (flags & USE_ION_FD) {
+ if (ion_client_num < 0)
+ mBase = MAP_FAILED;
+ else
+ mBase = ion_map(fd, size, offset);
+ } else
+#endif
+ mBase = mmap(0, size, access, MAP_SHARED, fd, offset);
if (mBase == MAP_FAILED) {
ALOGE("cannot map BpMemoryHeap (binder=%p), size=%zd, fd=%d (%s)",
IInterface::asBinder(this).get(), size, fd, strerror(errno));
@@ -324,6 +345,12 @@ void BpMemoryHeap::assertReallyMapped() const
android_atomic_write(fd, &mHeapId);
}
}
+#ifdef USE_MEMORY_HEAP_ION
+ if (ion_client_num < 0)
+ ion_client_num = -1;
+ else
+ ion_client_destroy(ion_client_num);
+#endif
}
}
diff --git a/libs/binder/MemoryHeapIon.cpp b/libs/binder/MemoryHeapIon.cpp
new file mode 100644
index 000000000..c547395dc
--- /dev/null
+++ b/libs/binder/MemoryHeapIon.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright Samsung Electronics Co.,LTD.
+ * Copyright (C) 2011 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.
+ */
+/*!
+ * \file MemoryHeapIon.cpp
+ * \brief source file for MemoryHeapIon
+ * \author MinGu, Jeon(mingu85.jeon)
+ * \date 2011/11/20
+ *
+ * <b>Revision History: </b>
+ * - 2011/11/20 : MinGu, Jeon(mingu85.jeon)) \n
+ * Initial version
+ * - 2012/11/29 : MinGu, Jeon(mingu85.jeon)) \n
+ * Change name
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+#include <binder/MemoryHeapBase.h>
+#include <binder/IMemory.h>
+#include <binder/MemoryHeapIon.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include "ion.h"
+
+#define HEAP_MASK_FILTER ((1 << 16) - (2))
+#define FLAG_MASK_FILTER (~(HEAP_MASK_FILTER) - (1))
+
+namespace android {
+
+uint32_t ion_HeapMask_valid_check(uint32_t flags)
+{
+ uint32_t heap_mask, result;
+ result = 0;
+
+ heap_mask = flags & HEAP_MASK_FILTER;
+
+ switch(heap_mask) {
+ case MHB_ION_HEAP_SYSTEM_MASK:
+ return ION_HEAP_SYSTEM_MASK;
+ case MHB_ION_HEAP_SYSTEM_CONTIG_MASK:
+ return ION_HEAP_SYSTEM_CONTIG_MASK;
+ case MHB_ION_HEAP_EXYNOS_CONTIG_MASK:
+ return ION_HEAP_EXYNOS_CONTIG_MASK;
+ case MHB_ION_HEAP_EXYNOS_MASK:
+ return ION_HEAP_EXYNOS_MASK;
+ default:
+ ALOGE("MemoryHeapIon : Heap Mask flag is default (flags:%x)", flags);
+ return 0;
+ break;
+ }
+ ALOGE("MemoryHeapIon : Heap Mask flag is wrong (flags:%x)", flags);
+ return 0;
+}
+
+uint32_t ion_FlagMask_valid_check(uint32_t flags)
+{
+ uint32_t flag_mask, result;
+ result = 0;
+
+ flag_mask = flags & FLAG_MASK_FILTER;
+
+ if (flag_mask & MHB_ION_FLAG_CACHED)
+ result |= ION_FLAG_CACHED;
+ if (flag_mask & MHB_ION_FLAG_CACHED_NEEDS_SYNC)
+ result |= ION_FLAG_CACHED_NEEDS_SYNC;
+ if (flag_mask & MHB_ION_FLAG_PRESERVE_KMAP)
+ result |= ION_FLAG_PRESERVE_KMAP;
+ if (flag_mask & MHB_ION_EXYNOS_VIDEO_MASK)
+ result |= ION_EXYNOS_VIDEO_MASK;
+ if (flag_mask & MHB_ION_EXYNOS_MFC_INPUT_MASK)
+ result |= ION_EXYNOS_MFC_INPUT_MASK;
+ if (flag_mask & MHB_ION_EXYNOS_MFC_OUTPUT_MASK)
+ result |= ION_EXYNOS_MFC_OUTPUT_MASK;
+ if (flag_mask & MHB_ION_EXYNOS_GSC_MASK)
+ result |= ION_EXYNOS_GSC_MASK;
+ if (flag_mask & MHB_ION_EXYNOS_FIMD_VIDEO_MASK)
+ result |= ION_EXYNOS_FIMD_VIDEO_MASK;
+
+ return result;
+}
+
+MemoryHeapIon::MemoryHeapIon(size_t size, uint32_t flags,
+ __attribute__((unused))char const *name):MemoryHeapBase()
+{
+ void* base = NULL;
+ int fd = -1;
+ uint32_t isReadOnly, heapMask, flagMask;
+
+ mIonClient = ion_client_create();
+
+ if (mIonClient < 0) {
+ ALOGE("MemoryHeapIon : ION client creation failed : %s", strerror(errno));
+ mIonClient = -1;
+ } else {
+ isReadOnly = flags & (IMemoryHeap::READ_ONLY);
+ heapMask = ion_HeapMask_valid_check(flags);
+ flagMask = ion_FlagMask_valid_check(flags);
+
+ if (heapMask) {
+ ALOGD("MemoryHeapIon : Allocated with size:%d, heap:0x%X , flag:0x%X", size, heapMask, flagMask);
+ fd = ion_alloc(mIonClient, size, 0, heapMask, flagMask);
+ if (fd < 0) {
+ ALOGE("MemoryHeapIon : ION Reserve memory allocation failed(size[%u]) : %s", size, strerror(errno));
+ if (errno == ENOMEM) { // Out of reserve memory. So re-try allocating in system heap
+ ALOGD("MemoryHeapIon : Re-try Allocating in default heap - SYSTEM heap");
+ fd = ion_alloc(mIonClient, size, 0, ION_HEAP_SYSTEM_MASK, ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC | ION_FLAG_PRESERVE_KMAP);
+ }
+ }
+ } else {
+ fd = ion_alloc(mIonClient, size, 0, ION_HEAP_SYSTEM_MASK, ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC | ION_FLAG_PRESERVE_KMAP);
+ ALOGD("MemoryHeapIon : Allocated with default heap - SYSTEM heap");
+ }
+
+ flags = isReadOnly | heapMask | flagMask;
+
+ if (fd < 0) {
+ ALOGE("MemoryHeapIon : ION memory allocation failed(size[%u]) : %s", size, strerror(errno));
+ } else {
+ flags |= USE_ION_FD;
+ base = ion_map(fd, size, 0);
+ if (base != MAP_FAILED) {
+ init(fd, base, size, flags, NULL);
+ } else {
+ ALOGE("MemoryHeapIon : ION mmap failed(size[%u], fd[%d]) : %s", size, fd, strerror(errno));
+ ion_free(fd);
+ }
+ }
+ }
+}
+
+MemoryHeapIon::MemoryHeapIon(int fd, size_t size, uint32_t flags,
+ __attribute__((unused))uint32_t offset):MemoryHeapBase()
+{
+ void* base = NULL;
+ int dup_fd = -1;
+
+ mIonClient = ion_client_create();
+
+ if (mIonClient < 0) {
+ ALOGE("MemoryHeapIon : ION client creation failed : %s", strerror(errno));
+ mIonClient = -1;
+ } else {
+ if (fd >= 0) {
+ dup_fd = dup(fd);
+ if (dup_fd == -1) {
+ ALOGE("MemoryHeapIon : cannot dup fd (size[%u], fd[%d]) : %s", size, fd, strerror(errno));
+ } else {
+ flags |= USE_ION_FD;
+ base = ion_map(dup_fd, size, 0);
+ if (base != MAP_FAILED) {
+ init(dup_fd, base, size, flags, NULL);
+ } else {
+ ALOGE("MemoryHeapIon : ION mmap failed(size[%u], fd[%d]): %s", size, fd, strerror(errno));
+ ion_free(dup_fd);
+ }
+ }
+ } else {
+ ALOGE("MemoryHeapIon : fd parameter error(fd : %d)", fd);
+ }
+ }
+}
+
+MemoryHeapIon::~MemoryHeapIon()
+{
+ if (mIonClient != -1) {
+ ion_unmap(getBase(), getSize());
+ ion_client_destroy(mIonClient);
+ mIonClient = -1;
+ }
+}
+
+};
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 78886d5bb..0ad63394c 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -103,7 +103,8 @@ public:
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform,
- ISurfaceComposer::Rotation rotation)
+ ISurfaceComposer::Rotation rotation,
+ bool isCpuConsumer)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -116,6 +117,7 @@ public:
data.writeUint32(maxLayerZ);
data.writeInt32(static_cast<int32_t>(useIdentityTransform));
data.writeInt32(static_cast<int32_t>(rotation));
+ data.writeInt32(isCpuConsumer);
remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
return reply.readInt32();
}
@@ -361,11 +363,13 @@ status_t BnSurfaceComposer::onTransact(
uint32_t maxLayerZ = data.readUint32();
bool useIdentityTransform = static_cast<bool>(data.readInt32());
int32_t rotation = data.readInt32();
+ bool isCpuConsumer = data.readInt32();
status_t res = captureScreen(display, producer,
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
useIdentityTransform,
- static_cast<ISurfaceComposer::Rotation>(rotation));
+ static_cast<ISurfaceComposer::Rotation>(rotation),
+ isCpuConsumer);
reply->writeInt32(res);
return NO_ERROR;
}
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 4b76f9834..1abb6c375 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -1023,6 +1023,7 @@ status_t Surface::lock(
}
// figure out if we can copy the frontbuffer back
+ int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
const bool canCopyBack = (frontBuffer != 0 &&
backBuffer->width == frontBuffer->width &&
@@ -1030,15 +1031,23 @@ status_t Surface::lock(
backBuffer->format == frontBuffer->format);
if (canCopyBack) {
- // copy the area that is invalid and not repainted this round
- const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
+ Mutex::Autolock lock(mMutex);
+ Region oldDirtyRegion;
+ if(mSlots[backBufferSlot].dirtyRegion.isEmpty()) {
+ oldDirtyRegion.set(bounds);
+ } else {
+ for(int i = 0 ; i < NUM_BUFFER_SLOTS; i++ ) {
+ if(i != backBufferSlot && !mSlots[i].dirtyRegion.isEmpty())
+ oldDirtyRegion.orSelf(mSlots[i].dirtyRegion);
+ }
+ }
+ const Region copyback(oldDirtyRegion.subtract(newDirtyRegion));
if (!copyback.isEmpty())
copyBlt(backBuffer, frontBuffer, copyback);
} else {
// if we can't copy-back anything, modify the user's dirty
// region to make sure they redraw the whole buffer
newDirtyRegion.set(bounds);
- mDirtyRegion.clear();
Mutex::Autolock lock(mMutex);
for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
mSlots[i].dirtyRegion.clear();
@@ -1048,15 +1057,9 @@ status_t Surface::lock(
{ // scope for the lock
Mutex::Autolock lock(mMutex);
- int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
- if (backBufferSlot >= 0) {
- Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
- mDirtyRegion.subtract(dirtyRegion);
- dirtyRegion = newDirtyRegion;
- }
+ mSlots[backBufferSlot].dirtyRegion = newDirtyRegion;
}
- mDirtyRegion.orSelf(newDirtyRegion);
if (inOutDirtyBounds) {
*inOutDirtyBounds = newDirtyRegion.getBounds();
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 6ad47d8b7..9955faf26 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -683,6 +683,12 @@ status_t SurfaceComposerClient::getAnimationFrameStats(FrameStats* outStats) {
// ----------------------------------------------------------------------------
+#ifndef FORCE_SCREENSHOT_CPU_PATH
+#define SS_CPU_CONSUMER false
+#else
+#define SS_CPU_CONSUMER true
+#endif
+
status_t ScreenshotClient::capture(
const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer,
@@ -691,7 +697,8 @@ status_t ScreenshotClient::capture(
sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == NULL) return NO_INIT;
return s->captureScreen(display, producer, sourceCrop,
- reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform);
+ reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform,
+ ISurfaceComposer::eRotateNone, SS_CPU_CONSUMER);
}
ScreenshotClient::ScreenshotClient()
@@ -729,7 +736,7 @@ status_t ScreenshotClient::update(const sp<IBinder>& display,
status_t err = s->captureScreen(display, mProducer, sourceCrop,
reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform,
- static_cast<ISurfaceComposer::Rotation>(rotation));
+ static_cast<ISurfaceComposer::Rotation>(rotation), true);
if (err == NO_ERROR) {
err = mCpuConsumer->lockNextBuffer(&mBuffer);
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index e55db30f8..0d7772724 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -112,6 +112,7 @@ void GraphicBuffer::free_handle()
GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
allocator.free(handle);
}
+ handle = NULL;
mWrappedBuffer = 0;
}
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 90a1c1110..0580e160f 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -190,5 +190,18 @@ status_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd)
return err;
}
+#ifdef EXYNOS4_ENHANCEMENTS
+status_t GraphicBufferMapper::getphys(buffer_handle_t handle, void** paddr)
+{
+ status_t err;
+
+ err = mAllocMod->getphys(mAllocMod, handle, paddr);
+
+ ALOGW_IF(err, "getphys(%p) fail %d(%s)", handle, err, strerror(-err));
+ return err;
+}
+#endif
+
+
// ---------------------------------------------------------------------------
}; // namespace android