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/binder/Parcel.cpp88
-rw-r--r--libs/gui/Android.mk4
-rw-r--r--libs/gui/BufferQueueProducer.cpp18
-rw-r--r--libs/gui/ISurfaceComposer.cpp8
-rw-r--r--libs/gui/LayerState.cpp8
-rw-r--r--libs/gui/Sensor.cpp6
-rw-r--r--libs/gui/Surface.cpp23
-rw-r--r--libs/gui/SurfaceComposerClient.cpp79
-rw-r--r--libs/gui/SurfaceControl.cpp20
-rw-r--r--libs/ui/Android.mk4
-rw-r--r--libs/ui/GraphicBuffer.cpp5
-rw-r--r--libs/ui/GraphicBufferMapper.cpp13
15 files changed, 505 insertions, 34 deletions
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
index d5860ef..b12eda8 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 fb8d620..f59867a 100644
--- a/libs/binder/IMemory.cpp
+++ b/libs/binder/IMemory.cpp
@@ -33,6 +33,10 @@
#include <binder/Parcel.h>
#include <utils/CallStack.h>
+#ifdef USE_MEMORY_HEAP_ION
+#include "ion.h"
+#endif
+
#define VERBOSE 0
namespace android {
@@ -312,6 +316,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));
@@ -324,7 +336,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));
@@ -336,6 +357,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 0000000..26c5566
--- /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:%zu, 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[%zu]) : %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[%zu]) : %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[%zu], 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[%zu], 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[%zu], 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/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 4a660d1..65e67d6 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -18,6 +18,8 @@
//#define LOG_NDEBUG 0
#include <binder/Parcel.h>
+#include <fcntl.h>
+#include <pthread.h>
#include <binder/IPCThreadState.h>
#include <binder/Binder.h>
@@ -42,6 +44,9 @@
#include <stdlib.h>
#include <stdint.h>
#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
#ifndef INT32_MAX
#define INT32_MAX ((int32_t)(2147483647))
@@ -95,6 +100,32 @@ enum {
BLOB_ASHMEM_MUTABLE = 2,
};
+static dev_t ashmem_rdev()
+{
+ static dev_t __ashmem_rdev;
+ static pthread_mutex_t __ashmem_rdev_lock = PTHREAD_MUTEX_INITIALIZER;
+
+ pthread_mutex_lock(&__ashmem_rdev_lock);
+
+ dev_t rdev = __ashmem_rdev;
+ if (!rdev) {
+ int fd = TEMP_FAILURE_RETRY(open("/dev/ashmem", O_RDONLY));
+ if (fd >= 0) {
+ struct stat st;
+
+ int ret = TEMP_FAILURE_RETRY(fstat(fd, &st));
+ close(fd);
+ if ((ret >= 0) && S_ISCHR(st.st_mode)) {
+ rdev = __ashmem_rdev = st.st_rdev;
+ }
+ }
+ }
+
+ pthread_mutex_unlock(&__ashmem_rdev_lock);
+
+ return rdev;
+}
+
void acquire_object(const sp<ProcessState>& proc,
const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
{
@@ -123,8 +154,10 @@ void acquire_object(const sp<ProcessState>& proc,
return;
}
case BINDER_TYPE_FD: {
- if (obj.cookie != 0) {
- if (outAshmemSize != NULL) {
+ if ((obj.cookie != 0) && (outAshmemSize != NULL)) {
+ struct stat st;
+ int ret = fstat(obj.handle, &st);
+ if (!ret && S_ISCHR(st.st_mode) && (st.st_rdev == ashmem_rdev())) {
// If we own an ashmem fd, keep track of how much memory it refers to.
int size = ashmem_get_size_region(obj.handle);
if (size > 0) {
@@ -173,15 +206,22 @@ static void release_object(const sp<ProcessState>& proc,
return;
}
case BINDER_TYPE_FD: {
- if (outAshmemSize != NULL) {
- if (obj.cookie != 0) {
- int size = ashmem_get_size_region(obj.handle);
- if (size > 0) {
- *outAshmemSize -= size;
+ if (obj.cookie != 0) { // owned
+ if (outAshmemSize != NULL) {
+ struct stat st;
+ int ret = fstat(obj.handle, &st);
+ if (!ret && S_ISCHR(st.st_mode) && (st.st_rdev == ashmem_rdev())) {
+ int size = ashmem_get_size_region(obj.handle);
+ if (size > 0) {
+ *outAshmemSize -= size;
+ }
}
-
- close(obj.handle);
}
+ close(obj.handle);
+#ifdef DISABLE_ASHMEM_TRACKING
+ } else if (obj.cookie != 0) {
+ close(obj.handle);
+#endif
}
return;
}
@@ -532,7 +572,11 @@ status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
flat_binder_object* flat
= reinterpret_cast<flat_binder_object*>(mData + off);
+#ifndef DISABLE_ASHMEM_TRACKING
acquire_object(proc, *flat, this, &mOpenAshmemSize);
+#else
+ acquire_object(proc, *flat, this);
+#endif
if (flat->type == BINDER_TYPE_FD) {
// If this is a file descriptor, we need to dup it so the
@@ -1052,7 +1096,11 @@ restart_write:
// Need to write meta-data?
if (nullMetaData || val.binder != 0) {
mObjects[mObjectsSize] = mDataPos;
+#ifndef DISABLE_ASHMEM_TRACKING
acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize);
+#else
+ acquire_object(ProcessState::self(), val, this);
+#endif
mObjectsSize++;
}
@@ -1641,7 +1689,11 @@ void Parcel::releaseObjects()
i--;
const flat_binder_object* flat
= reinterpret_cast<flat_binder_object*>(data+objects[i]);
+#ifndef DISABLE_ASHMEM_TRACKING
release_object(proc, *flat, this, &mOpenAshmemSize);
+#else
+ release_object(proc, *flat, this);
+#endif
}
}
@@ -1655,7 +1707,11 @@ void Parcel::acquireObjects()
i--;
const flat_binder_object* flat
= reinterpret_cast<flat_binder_object*>(data+objects[i]);
+#ifndef DISABLE_ASHMEM_TRACKING
acquire_object(proc, *flat, this, &mOpenAshmemSize);
+#else
+ acquire_object(proc, *flat, this);
+#endif
}
}
@@ -1837,7 +1893,11 @@ status_t Parcel::continueWrite(size_t desired)
// will need to rescan because we may have lopped off the only FDs
mFdsKnown = false;
}
+#ifndef DISABLE_ASHMEM_TRACKING
release_object(proc, *flat, this, &mOpenAshmemSize);
+#else
+ release_object(proc, *flat, this);
+#endif
}
binder_size_t* objects =
(binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
@@ -1922,7 +1982,9 @@ void Parcel::initState()
mFdsKnown = true;
mAllowFds = true;
mOwner = NULL;
+#ifndef DISABLE_ASHMEM_TRACKING
mOpenAshmemSize = 0;
+#endif
}
void Parcel::scanForFds() const
@@ -1945,12 +2007,20 @@ size_t Parcel::getBlobAshmemSize() const
// This used to return the size of all blobs that were written to ashmem, now we're returning
// the ashmem currently referenced by this Parcel, which should be equivalent.
// TODO: Remove method once ABI can be changed.
+#ifndef DISABLE_ASHMEM_TRACKING
return mOpenAshmemSize;
+#else
+ return 0;
+#endif
}
size_t Parcel::getOpenAshmemSize() const
{
+#ifndef DISABLE_ASHMEM_TRACKING
return mOpenAshmemSize;
+#else
+ return 0;
+#endif
}
// --- Parcel::Blob ---
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index 8a965dd..76aec6e 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -91,6 +91,10 @@ ifeq ($(TARGET_BOARD_PLATFORM), tegra3)
LOCAL_CFLAGS += -DDONT_USE_FENCE_SYNC
endif
+ifeq ($(TARGET_NO_SENSOR_PERMISSION_CHECK),true)
+LOCAL_CPPFLAGS += -DNO_SENSOR_PERMISSION_CHECK
+endif
+
include $(BUILD_SHARED_LIBRARY)
ifeq (,$(ONE_SHOT_MAKEFILE))
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 87e5b4d..a941e2d 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -696,15 +696,6 @@ status_t BufferQueueProducer::queueBuffer(int slot,
mCore->validateConsistencyLocked();
} // Autolock scope
- // Wait without lock held
- if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
- // Waiting here allows for two full buffers to be queued but not a
- // third. In the event that frames take varying time, this makes a
- // small trade-off in favor of latency rather than throughput.
- mLastQueueBufferFence->waitForever("Throttling EGL Production");
- mLastQueueBufferFence = fence;
- }
-
// Don't send the GraphicBuffer through the callback, and don't send
// the slot number, since the consumer shouldn't need it
item.mGraphicBuffer.clear();
@@ -728,6 +719,15 @@ status_t BufferQueueProducer::queueBuffer(int slot,
mCallbackCondition.broadcast();
}
+ // Wait without lock held
+ if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
+ // Waiting here allows for two full buffers to be queued but not a
+ // third. In the event that frames take varying time, this makes a
+ // small trade-off in favor of latency rather than throughput.
+ mLastQueueBufferFence->waitForever("Throttling EGL Production");
+ mLastQueueBufferFence = fence;
+ }
+
return NO_ERROR;
}
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 78886d5..0ad6339 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/LayerState.cpp b/libs/gui/LayerState.cpp
index 00323dc..85452e6 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -32,6 +32,10 @@ status_t layer_state_t::write(Parcel& output) const
output.writeUint32(w);
output.writeUint32(h);
output.writeUint32(layerStack);
+ output.writeFloat(blur);
+ output.writeStrongBinder(blurMaskSurface);
+ output.writeUint32(blurMaskSampling);
+ output.writeFloat(blurMaskAlphaThreshold);
output.writeFloat(alpha);
output.writeUint32(flags);
output.writeUint32(mask);
@@ -52,6 +56,10 @@ status_t layer_state_t::read(const Parcel& input)
w = input.readUint32();
h = input.readUint32();
layerStack = input.readUint32();
+ blur = input.readFloat();
+ blurMaskSurface = input.readStrongBinder();
+ blurMaskSampling = input.readUint32();
+ blurMaskAlphaThreshold = input.readFloat();
alpha = input.readFloat();
flags = static_cast<uint8_t>(input.readUint32());
mask = static_cast<uint8_t>(input.readUint32());
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index 235cbbd..e423a8e 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -118,9 +118,11 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
break;
case SENSOR_TYPE_HEART_RATE: {
mStringType = SENSOR_STRING_TYPE_HEART_RATE;
+#ifndef NO_SENSOR_PERMISSION_CHECK
mRequiredPermission = SENSOR_PERMISSION_BODY_SENSORS;
AppOpsManager appOps;
mRequiredAppOp = appOps.permissionToOpCode(String16(SENSOR_PERMISSION_BODY_SENSORS));
+#endif
mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
} break;
case SENSOR_TYPE_LIGHT:
@@ -221,6 +223,7 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor->stringType) {
mStringType = hwSensor->stringType;
}
+#ifndef NO_SENSOR_PERMISSION_CHECK
if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor->requiredPermission) {
mRequiredPermission = hwSensor->requiredPermission;
if (!strcmp(mRequiredPermission, SENSOR_PERMISSION_BODY_SENSORS)) {
@@ -228,6 +231,7 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
mRequiredAppOp = appOps.permissionToOpCode(String16(SENSOR_PERMISSION_BODY_SENSORS));
}
}
+#endif
if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
mFlags = static_cast<uint32_t>(hwSensor->flags);
@@ -267,6 +271,7 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
}
}
+#ifndef NO_SENSOR_PERMISSION_CHECK
if (mRequiredPermission.length() > 0) {
// If the sensor is protected by a permission we need to know if it is
// a runtime one to determine whether we can use the permission cache.
@@ -277,6 +282,7 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
String16(mRequiredPermission));
}
}
+#endif
}
Sensor::~Sensor()
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 4b76f98..1abb6c3 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 6ad47d8..82bdd6b 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -144,6 +144,14 @@ public:
uint32_t w, uint32_t h);
status_t setLayer(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
uint32_t z);
+ status_t setBlur(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
+ float blur);
+ status_t setBlurMaskSurface(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
+ const sp<IBinder>& maskSurfaceId);
+ status_t setBlurMaskSampling(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
+ uint32_t blurMaskSampling);
+ status_t setBlurMaskAlphaThreshold(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
+ float alpha);
status_t setFlags(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
uint32_t flags, uint32_t mask);
status_t setTransparentRegionHint(
@@ -303,6 +311,50 @@ status_t Composer::setLayer(const sp<SurfaceComposerClient>& client,
return NO_ERROR;
}
+status_t Composer::setBlur(const sp<SurfaceComposerClient>& client,
+ const sp<IBinder>& id, float blur) {
+ Mutex::Autolock _l(mLock);
+ layer_state_t* s = getLayerStateLocked(client, id);
+ if (!s)
+ return BAD_INDEX;
+ s->what |= layer_state_t::eBlurChanged;
+ s->blur = blur;
+ return NO_ERROR;
+}
+
+status_t Composer::setBlurMaskSurface(const sp<SurfaceComposerClient>& client,
+ const sp<IBinder>& id, const sp<IBinder>& maskSurfaceId) {
+ Mutex::Autolock _l(mLock);
+ layer_state_t* s = getLayerStateLocked(client, id);
+ if (!s)
+ return BAD_INDEX;
+ s->what |= layer_state_t::eBlurMaskSurfaceChanged;
+ s->blurMaskSurface = maskSurfaceId;
+ return NO_ERROR;
+}
+
+status_t Composer::setBlurMaskSampling(const sp<SurfaceComposerClient>& client,
+ const sp<IBinder>& id, uint32_t blurMaskSampling) {
+ Mutex::Autolock _l(mLock);
+ layer_state_t* s = getLayerStateLocked(client, id);
+ if (!s)
+ return BAD_INDEX;
+ s->what |= layer_state_t::eBlurMaskSamplingChanged;
+ s->blurMaskSampling = blurMaskSampling;
+ return NO_ERROR;
+}
+
+status_t Composer::setBlurMaskAlphaThreshold(const sp<SurfaceComposerClient>& client,
+ const sp<IBinder>& id, float alpha) {
+ Mutex::Autolock _l(mLock);
+ layer_state_t* s = getLayerStateLocked(client, id);
+ if (!s)
+ return BAD_INDEX;
+ s->what |= layer_state_t::eBlurMaskAlphaThresholdChanged;
+ s->blurMaskAlphaThreshold = alpha;
+ return NO_ERROR;
+}
+
status_t Composer::setFlags(const sp<SurfaceComposerClient>& client,
const sp<IBinder>& id, uint32_t flags,
uint32_t mask) {
@@ -574,6 +626,22 @@ status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, uint32_t z) {
return getComposer().setLayer(this, id, z);
}
+status_t SurfaceComposerClient::setBlur(const sp<IBinder>& id, float blur) {
+ return getComposer().setBlur(this, id, blur);
+}
+
+status_t SurfaceComposerClient::setBlurMaskSurface(const sp<IBinder>& id, const sp<IBinder>& maskSurfaceId) {
+ return getComposer().setBlurMaskSurface(this, id, maskSurfaceId);
+}
+
+status_t SurfaceComposerClient::setBlurMaskSampling(const sp<IBinder>& id, uint32_t blurMaskSampling) {
+ return getComposer().setBlurMaskSampling(this, id, blurMaskSampling);
+}
+
+status_t SurfaceComposerClient::setBlurMaskAlphaThreshold(const sp<IBinder>& id, float alpha) {
+ return getComposer().setBlurMaskAlphaThreshold(this, id, alpha);
+}
+
status_t SurfaceComposerClient::hide(const sp<IBinder>& id) {
return getComposer().setFlags(this, id,
layer_state_t::eLayerHidden,
@@ -683,6 +751,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 +765,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 +804,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/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 1983027..8212b90 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -99,6 +99,26 @@ status_t SurfaceControl::setLayer(uint32_t layer) {
if (err < 0) return err;
return mClient->setLayer(mHandle, layer);
}
+status_t SurfaceControl::setBlur(float blur) {
+ status_t err = validate();
+ if (err < 0) return err;
+ return mClient->setBlur(mHandle, blur);
+}
+status_t SurfaceControl::setBlurMaskSurface(const sp<SurfaceControl>& maskSurface) {
+ status_t err = validate();
+ if (err < 0) return err;
+ return mClient->setBlurMaskSurface(mHandle, maskSurface != 0 ? maskSurface->mHandle : 0);
+}
+status_t SurfaceControl::setBlurMaskSampling(uint32_t blurMaskSampling) {
+ status_t err = validate();
+ if (err < 0) return err;
+ return mClient->setBlurMaskSampling(mHandle, blurMaskSampling);
+}
+status_t SurfaceControl::setBlurMaskAlphaThreshold(float alpha) {
+ status_t err = validate();
+ if (err < 0) return err;
+ return mClient->setBlurMaskAlphaThreshold(mHandle, alpha);
+}
status_t SurfaceControl::setPosition(float x, float y) {
status_t err = validate();
if (err < 0) return err;
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index 1ce8626..a8eb67b 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -56,6 +56,10 @@ ifneq ($(BOARD_FRAMEBUFFER_FORCE_FORMAT),)
LOCAL_CFLAGS += -DFRAMEBUFFER_FORCE_FORMAT=$(BOARD_FRAMEBUFFER_FORCE_FORMAT)
endif
+ifeq ($(BOARD_EGL_NEEDS_HANDLE_VALUE),true)
+LOCAL_CFLAGS += -DEGL_NEEDS_HANDLE
+endif
+
LOCAL_MODULE := libui
include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index e55db30..992c1fe 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -112,6 +112,11 @@ void GraphicBuffer::free_handle()
GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
allocator.free(handle);
}
+
+#ifndef EGL_NEEDS_HANDLE
+ handle = NULL;
+#endif
+
mWrappedBuffer = 0;
}
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 90a1c11..0580e16 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