summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/dumpstate/utils.c32
-rw-r--r--data/etc/com.stericsson.hardware.fm.receiver.xml20
-rw-r--r--data/etc/com.stericsson.hardware.fm.transmitter.xml20
-rw-r--r--include/binder/IMemory.h3
-rw-r--r--include/binder/MemoryHeapBaseIon.h51
-rw-r--r--include/binder/MemoryHeapPmem.h79
-rw-r--r--include/gui/SurfaceComposerClient.h17
-rw-r--r--include/media/hardware/HardwareAPI.h2
-rw-r--r--include/ui/FramebufferNativeWindow.h10
-rw-r--r--include/ui/GraphicBuffer.h5
-rw-r--r--include/ui/GraphicBufferAllocator.h5
-rw-r--r--include/ui/GraphicBufferMapper.h6
-rw-r--r--libs/binder/Android.mk18
-rw-r--r--libs/binder/IMemory.cpp29
-rw-r--r--libs/binder/MemoryHeapBaseIon.cpp96
-rw-r--r--libs/binder/MemoryHeapPmem.cpp248
-rw-r--r--libs/gui/Android.mk2
-rw-r--r--libs/gui/SurfaceComposerClient.cpp75
-rw-r--r--libs/ui/Android.mk19
-rw-r--r--libs/ui/FramebufferNativeWindow.cpp25
-rw-r--r--libs/ui/GraphicBufferAllocator.cpp10
-rw-r--r--libs/ui/GraphicBufferMapper.cpp13
-rw-r--r--services/sensorservice/Android.mk5
-rw-r--r--services/sensorservice/RotationVectorSensor2.cpp126
-rw-r--r--services/sensorservice/RotationVectorSensor2.h63
-rw-r--r--services/sensorservice/SensorDevice.cpp49
-rw-r--r--services/sensorservice/SensorService.cpp13
-rw-r--r--services/surfaceflinger/Android.mk12
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp22
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp426
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp36
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h7
32 files changed, 1453 insertions, 91 deletions
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index 8f132d5..2ef541d 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -133,12 +133,23 @@ void do_dmesg() {
}
void do_showmap(int pid, const char *name) {
+ static bool ran = false, skip = false;
char title[255];
char arg[255];
sprintf(title, "SHOW MAP %d (%s)", pid, name);
sprintf(arg, "%d", pid);
- run_command(title, 10, SU_PATH, "root", "showmap", arg, NULL);
+
+ if (skip) {
+ /* Skip due to non-zero exit status on first run. */
+ printf("------ %s: Skipped. ------\n", title);
+ } else {
+ int status = run_command(title, 10, SU_PATH, "root", "showmap", arg, NULL);
+ if (!ran) {
+ ran = true;
+ skip = !WIFEXITED(status) || WEXITSTATUS(status) != 0;
+ }
+ }
}
/* prints the contents of a file */
@@ -197,14 +208,29 @@ int run_command(const char *title, int timeout_seconds, const char *command, ...
/* handle child case */
if (pid == 0) {
const char *args[1024] = {command};
- size_t arg;
+ size_t arg = 1;
+ char sucmd[255];
+ bool su = false;
+
+ if (strcmp(command, SU_PATH) == 0) {
+ /* Need to transform calls to su from:
+ * su LOGIN COMMAND ...
+ * to:
+ * su -c 'COMMAND "$@"' -- LOGIN COMMAND ... */
+ args[arg++] = "-c";
+ args[arg++] = sucmd;
+ args[arg++] = "--";
+ sucmd[0] = '\0';
+ su = true;
+ }
va_list ap;
va_start(ap, command);
if (title) printf("------ %s (%s", title, command);
- for (arg = 1; arg < sizeof(args) / sizeof(args[0]); ++arg) {
+ for (; arg < sizeof(args) / sizeof(args[0]); ++arg) {
args[arg] = va_arg(ap, const char *);
if (args[arg] == NULL) break;
+ if (su && arg == 5) snprintf(sucmd, sizeof(sucmd), "%s \"$@\"", args[arg]);
if (title) printf(" %s", args[arg]);
}
if (title) printf(") ------\n");
diff --git a/data/etc/com.stericsson.hardware.fm.receiver.xml b/data/etc/com.stericsson.hardware.fm.receiver.xml
new file mode 100644
index 0000000..13092fa
--- /dev/null
+++ b/data/etc/com.stericsson.hardware.fm.receiver.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<!-- This is the standard feature indicating that the device includes FM receiver. -->
+<permissions>
+ <feature name="com.stericsson.hardware.fm.receiver" />
+</permissions>
diff --git a/data/etc/com.stericsson.hardware.fm.transmitter.xml b/data/etc/com.stericsson.hardware.fm.transmitter.xml
new file mode 100644
index 0000000..9b51c03
--- /dev/null
+++ b/data/etc/com.stericsson.hardware.fm.transmitter.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<!-- This is the standard feature indicating that the device includes FM transmitter. -->
+<permissions>
+ <feature name="com.stericsson.hardware.fm.transmitter" />
+</permissions>
diff --git a/include/binder/IMemory.h b/include/binder/IMemory.h
index 2d0db00..62ac9e3 100644
--- a/include/binder/IMemory.h
+++ b/include/binder/IMemory.h
@@ -36,7 +36,8 @@ public:
// flags returned by getFlags()
enum {
- READ_ONLY = 0x00000001
+ READ_ONLY = 0x00000001,
+ USE_ION_FD = 0x00000008
};
virtual int getHeapID() const = 0;
diff --git a/include/binder/MemoryHeapBaseIon.h b/include/binder/MemoryHeapBaseIon.h
new file mode 100644
index 0000000..0fe99c7
--- /dev/null
+++ b/include/binder/MemoryHeapBaseIon.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright 2011, Samsung Electronics Co. LTD
+ *
+ * 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 MemoryHeapBaseIon.h
+ * \brief header file for MemoryHeapBaseIon
+ * \author MinGu, Jeon(mingu85.jeon)
+ * \date 2011/11/20
+ *
+ * <b>Revision History: </b>
+ * - 2011/11/21 : MinGu, Jeon(mingu85.jeon)) \n
+ * Initial version
+ */
+
+#ifndef ANDROID_MEMORY_HEAP_BASE_ION_H
+#define ANDROID_MEMORY_HEAP_BASE_ION_H
+
+#include <binder/IMemory.h>
+#include <binder/MemoryHeapBase.h>
+#include <stdlib.h>
+
+namespace android {
+
+class MemoryHeapBaseIon : public MemoryHeapBase
+{
+public:
+ enum {
+ USE_ION_FD = IMemoryHeap::USE_ION_FD
+ };
+ MemoryHeapBaseIon(size_t size, uint32_t flags = 0, char const* name = NULL);
+ MemoryHeapBaseIon(int fd, size_t size, uint32_t flags = 0, uint32_t offset = 0);
+ ~MemoryHeapBaseIon();
+private:
+ int mIonClient;
+};
+
+};
+#endif
diff --git a/include/binder/MemoryHeapPmem.h b/include/binder/MemoryHeapPmem.h
new file mode 100644
index 0000000..e1660c4
--- /dev/null
+++ b/include/binder/MemoryHeapPmem.h
@@ -0,0 +1,79 @@
+/*
+ * 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 ANDROID_MEMORY_HEAP_PMEM_H
+#define ANDROID_MEMORY_HEAP_PMEM_H
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <binder/MemoryHeapBase.h>
+#include <binder/IMemory.h>
+#include <utils/SortedVector.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class MemoryHeapBase;
+
+// ---------------------------------------------------------------------------
+
+class MemoryHeapPmem : public MemoryHeapBase
+{
+public:
+ class MemoryPmem : public BnMemory {
+ public:
+ MemoryPmem(const sp<MemoryHeapPmem>& heap);
+ ~MemoryPmem();
+ protected:
+ const sp<MemoryHeapPmem>& getHeap() const { return mClientHeap; }
+ private:
+ friend class MemoryHeapPmem;
+ virtual void revoke() = 0;
+ sp<MemoryHeapPmem> mClientHeap;
+ };
+
+ MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap, uint32_t flags = 0);
+ ~MemoryHeapPmem();
+
+ /* HeapInterface additions */
+ virtual sp<IMemory> mapMemory(size_t offset, size_t size);
+
+ /* make the whole heap visible (you know who you are) */
+ virtual status_t slap();
+
+ /* hide (revoke) the whole heap (the client will see the garbage page) */
+ virtual status_t unslap();
+
+ /* revoke all allocations made by this heap */
+ virtual void revoke();
+
+private:
+ /* use this to create your own IMemory for mapMemory */
+ virtual sp<MemoryPmem> createMemory(size_t offset, size_t size);
+ void remove(const wp<MemoryPmem>& memory);
+
+private:
+ sp<MemoryHeapBase> mParentHeap;
+ mutable Mutex mLock;
+ SortedVector< wp<MemoryPmem> > mAllocations;
+};
+
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_MEMORY_HEAP_PMEM_H
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index ae5d69a..7eb6b64 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -72,6 +72,16 @@ public:
/* triggers screen on and waits for it to complete */
static void unblankDisplay(const sp<IBinder>& display);
+ // TODO: Remove me. Do not use.
+ // This is a compatibility shim for one product whose drivers are depending on
+ // this legacy function (when they shouldn't).
+ static status_t getDisplayInfo(int32_t displayId, DisplayInfo* info);
+
+#if defined(ICS_CAMERA_BLOB) || defined(MR0_CAMERA_BLOB)
+ static ssize_t getDisplayWidth(int32_t displayId);
+ static ssize_t getDisplayHeight(int32_t displayId);
+ static ssize_t getDisplayOrientation(int32_t displayId);
+#endif
// ------------------------------------------------------------------------
// surface creation / destruction
@@ -105,6 +115,8 @@ public:
//! Close a composer transaction on all active SurfaceComposerClients.
static void closeGlobalTransaction(bool synchronous = false);
+ static int setOrientation(int32_t dpy, int orientation, uint32_t flags);
+
//! Flag the currently open transaction as an animation transaction.
static void setAnimationTransaction();
@@ -162,6 +174,11 @@ class ScreenshotClient
public:
ScreenshotClient();
+ // TODO: Remove me. Do not use.
+ // This is a compatibility shim for one product whose drivers are depending on
+ // this legacy function (when they shouldn't).
+ status_t update();
+
// frees the previous screenshot and capture a new one
status_t update(const sp<IBinder>& display);
status_t update(const sp<IBinder>& display,
diff --git a/include/media/hardware/HardwareAPI.h b/include/media/hardware/HardwareAPI.h
index cc43bf6..a1bb233 100644
--- a/include/media/hardware/HardwareAPI.h
+++ b/include/media/hardware/HardwareAPI.h
@@ -18,7 +18,7 @@
#define HARDWARE_API_H_
-#include <OMXPluginBase.h>
+#include <media/hardware/OMXPluginBase.h>
#include <system/window.h>
#include <utils/RefBase.h>
diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h
index 5ec738f..02f3c8b 100644
--- a/include/ui/FramebufferNativeWindow.h
+++ b/include/ui/FramebufferNativeWindow.h
@@ -31,6 +31,10 @@
#define MIN_NUM_FRAME_BUFFERS 2
#define MAX_NUM_FRAME_BUFFERS 3
+#ifdef SAMSUNG_HDMI_SUPPORT
+#include "SecHdmiClient.h"
+#endif
+
extern "C" EGLNativeWindowType android_createDisplaySurface(void);
// ---------------------------------------------------------------------------
@@ -39,6 +43,9 @@ namespace android {
class Surface;
class NativeBuffer;
+#ifdef SAMSUNG_HDMI_SUPPORT
+class SecHdmiClient;
+#endif
// ---------------------------------------------------------------------------
@@ -88,6 +95,9 @@ private:
int32_t mBufferHead;
int32_t mCurrentBufferIndex;
bool mUpdateOnDemand;
+#ifdef SAMSUNG_HDMI_SUPPORT
+ SecHdmiClient *mHdmiClient;
+#endif
};
// ---------------------------------------------------------------------------
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index f318cd8..1c84d0e 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -64,7 +64,10 @@ public:
USAGE_HW_2D = GRALLOC_USAGE_HW_2D,
USAGE_HW_COMPOSER = GRALLOC_USAGE_HW_COMPOSER,
USAGE_HW_VIDEO_ENCODER = GRALLOC_USAGE_HW_VIDEO_ENCODER,
- USAGE_HW_MASK = GRALLOC_USAGE_HW_MASK
+ USAGE_HW_MASK = GRALLOC_USAGE_HW_MASK,
+#ifdef EXYNOS4_ENHANCEMENTS
+ USAGE_HW_FIMC1 = GRALLOC_USAGE_HW_FIMC1
+#endif
};
GraphicBuffer();
diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index 479cd3e..6342aac 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -56,7 +56,10 @@ public:
USAGE_HW_TEXTURE = GRALLOC_USAGE_HW_TEXTURE,
USAGE_HW_RENDER = GRALLOC_USAGE_HW_RENDER,
USAGE_HW_2D = GRALLOC_USAGE_HW_2D,
- USAGE_HW_MASK = GRALLOC_USAGE_HW_MASK
+ USAGE_HW_MASK = GRALLOC_USAGE_HW_MASK,
+#ifdef EXYNOS4_ENHANCEMENTS
+ USAGE_HW_FIMC1 = GRALLOC_USAGE_HW_FIMC1
+#endif
};
static inline GraphicBufferAllocator& get() { return getInstance(); }
diff --git a/include/ui/GraphicBufferMapper.h b/include/ui/GraphicBufferMapper.h
index 697a02a..1fdecab 100644
--- a/include/ui/GraphicBufferMapper.h
+++ b/include/ui/GraphicBufferMapper.h
@@ -46,7 +46,11 @@ public:
int usage, const Rect& bounds, void** vaddr);
status_t unlock(buffer_handle_t handle);
-
+
+#ifdef EXYNOS4_ENHANCEMENTS
+ status_t getphys(buffer_handle_t handle, void** paddr);
+#endif
+
// dumps information about the mapping of this handle
void dump(buffer_handle_t handle);
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
index d449298..c72e930 100644
--- a/libs/binder/Android.mk
+++ b/libs/binder/Android.mk
@@ -29,17 +29,33 @@ sources := \
ProcessState.cpp \
Static.cpp
+ifeq ($(BOARD_NEEDS_MEMORYHEAPPMEM),true)
+sources += \
+ MemoryHeapPmem.cpp
+endif
+
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
+
+ifeq ($(BOARD_USE_V4L2_ION), true)
+LOCAL_CFLAGS += -DUSE_V4L2_ION
+sources += \
+ MemoryHeapBaseIon.cpp
+LOCAL_C_INCLUDES := hardware/samsung/exynos4/hal/include
+LOCAL_SHARED_LIBRARIES := libsecion
+endif
+
LOCAL_LDLIBS += -lpthread
LOCAL_MODULE := libbinder
-LOCAL_SHARED_LIBRARIES := liblog libcutils libutils
+LOCAL_SHARED_LIBRARIES += liblog libcutils libutils
LOCAL_SRC_FILES := $(sources)
+
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_LDLIBS += -lpthread
LOCAL_MODULE := libbinder
LOCAL_SRC_FILES := $(sources)
+
include $(BUILD_STATIC_LIBRARY)
diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp
index cd2451a..8fea1b2 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_V4L2_ION
+#include "ion.h"
+#endif
+
#define VERBOSE 0
namespace android {
@@ -301,6 +305,14 @@ void BpMemoryHeap::assertReallyMapped() const
ALOGE_IF(err, "binder=%p transaction failed fd=%d, size=%ld, err=%d (%s)",
asBinder().get(), parcel_fd, size, err, strerror(-err));
+#ifdef USE_V4L2_ION
+ int ion_client = -1;
+ if (flags & USE_ION_FD) {
+ ion_client = ion_client_create();
+ ALOGE_IF(ion_client < 0, "BpMemoryHeap : ion client creation error");
+ }
+#endif
+
int fd = dup( parcel_fd );
ALOGE_IF(fd==-1, "cannot dup fd=%d, size=%ld, err=%d (%s)",
parcel_fd, size, err, strerror(errno));
@@ -313,7 +325,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_V4L2_ION
+ if (flags & USE_ION_FD) {
+ if (ion_client < 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=%ld, fd=%d (%s)",
asBinder().get(), size, fd, strerror(errno));
@@ -325,6 +346,12 @@ void BpMemoryHeap::assertReallyMapped() const
android_atomic_write(fd, &mHeapId);
}
}
+#ifdef USE_V4L2_ION
+ if (ion_client < 0)
+ ion_client = -1;
+ else
+ ion_client_destroy(ion_client);
+#endif
}
}
diff --git a/libs/binder/MemoryHeapBaseIon.cpp b/libs/binder/MemoryHeapBaseIon.cpp
new file mode 100644
index 0000000..fe7dbb8
--- /dev/null
+++ b/libs/binder/MemoryHeapBaseIon.cpp
@@ -0,0 +1,96 @@
+/*
+ * 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 MemoryHeapBaseIon.cpp
+ * \brief source file for MemoryHeapBaseIon
+ * \author MinGu, Jeon(mingu85.jeon)
+ * \date 2011/11/20
+ *
+ * <b>Revision History: </b>
+ * - 2011/11/20 : MinGu, Jeon(mingu85.jeon)) \n
+ * Initial version
+ */
+
+#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/MemoryHeapBaseIon.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include "ion.h"
+
+namespace android {
+
+MemoryHeapBaseIon::MemoryHeapBaseIon(size_t size, uint32_t flags, char const *name)
+{
+ mIonClient = ion_client_create();
+ if (mIonClient < 0) {
+ mIonClient = -1;
+ ALOGE("MemoryHeapBaseIon : ION client creation failed");
+ }
+ void* base = NULL;
+ int fd = ion_alloc(mIonClient, size, 0, ION_HEAP_EXYNOS_MASK);
+
+ if (fd < 0) {
+ ALOGE("MemoryHeapBaseIon : ION memory allocation failed");
+ } else {
+ flags |= USE_ION_FD;
+ base = ion_map(fd, size, 0);
+ if (base != MAP_FAILED)
+ init(fd, base, size, flags, NULL);
+ else
+ ALOGE("MemoryHeapBaseIon : mmap failed");
+ }
+}
+
+MemoryHeapBaseIon::MemoryHeapBaseIon(int fd, size_t size, uint32_t flags, uint32_t offset)
+{
+ ALOGE_IF(fd < 0, "MemoryHeapBaseIon : file discriptor error. fd is not for ION Memory");
+ mIonClient = ion_client_create();
+ if (mIonClient < 0) {
+ mIonClient = -1;
+ ALOGE("MemoryHeapBaseIon : ION client creation failed");
+ }
+ void* base = NULL;
+ if (fd >= 0) {
+ int dup_fd = dup(fd);
+ flags |= USE_ION_FD;
+ base = ion_map(dup_fd, size, 0);
+ if (base != MAP_FAILED)
+ init(dup_fd, base, size, flags, NULL);
+ else
+ ALOGE("MemoryHeapBaseIon : mmap failed");
+ }
+}
+
+MemoryHeapBaseIon::~MemoryHeapBaseIon()
+{
+ if (mIonClient != -1) {
+ ion_unmap(getBase(), getSize());
+ ion_free(getHeapID());
+ ion_client_destroy(mIonClient);
+ mIonClient = -1;
+ }
+}
+
+};
diff --git a/libs/binder/MemoryHeapPmem.cpp b/libs/binder/MemoryHeapPmem.cpp
new file mode 100644
index 0000000..66bcf4d
--- /dev/null
+++ b/libs/binder/MemoryHeapPmem.cpp
@@ -0,0 +1,248 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "MemoryHeapPmem"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+
+#include <binder/MemoryHeapPmem.h>
+#include <binder/MemoryHeapBase.h>
+
+#ifdef HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+MemoryHeapPmem::MemoryPmem::MemoryPmem(const sp<MemoryHeapPmem>& heap)
+ : BnMemory(), mClientHeap(heap)
+{
+}
+
+MemoryHeapPmem::MemoryPmem::~MemoryPmem() {
+ if (mClientHeap != NULL) {
+ mClientHeap->remove(this);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+class SubRegionMemory : public MemoryHeapPmem::MemoryPmem {
+public:
+ SubRegionMemory(const sp<MemoryHeapPmem>& heap, ssize_t offset, size_t size);
+ virtual ~SubRegionMemory();
+ virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const;
+private:
+ friend class MemoryHeapPmem;
+ void revoke();
+ size_t mSize;
+ ssize_t mOffset;
+};
+
+SubRegionMemory::SubRegionMemory(const sp<MemoryHeapPmem>& heap,
+ ssize_t offset, size_t size)
+ : MemoryHeapPmem::MemoryPmem(heap), mSize(size), mOffset(offset)
+{
+#ifndef NDEBUG
+ void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + offset);
+ memset(start_ptr, 0xda, size);
+#endif
+
+#ifdef HAVE_ANDROID_OS
+ if (size > 0) {
+ const size_t pagesize = getpagesize();
+ size = (size + pagesize-1) & ~(pagesize-1);
+ int our_fd = heap->heapID();
+ struct pmem_region sub = { offset, size };
+ int err = ioctl(our_fd, PMEM_MAP, &sub);
+ ALOGE_IF(err<0, "PMEM_MAP failed (%s), "
+ "mFD=%d, sub.offset=%lu, sub.size=%lu",
+ strerror(errno), our_fd, sub.offset, sub.len);
+}
+#endif
+}
+
+sp<IMemoryHeap> SubRegionMemory::getMemory(ssize_t* offset, size_t* size) const
+{
+ if (offset) *offset = mOffset;
+ if (size) *size = mSize;
+ return getHeap();
+}
+
+SubRegionMemory::~SubRegionMemory()
+{
+ revoke();
+}
+
+
+void SubRegionMemory::revoke()
+{
+ // NOTE: revoke() doesn't need to be protected by a lock because it
+ // can only be called from MemoryHeapPmem::revoke(), which means
+ // that we can't be in ~SubRegionMemory(), or in ~SubRegionMemory(),
+ // which means MemoryHeapPmem::revoke() wouldn't have been able to
+ // promote() it.
+
+#ifdef HAVE_ANDROID_OS
+ if (mSize != 0) {
+ const sp<MemoryHeapPmem>& heap(getHeap());
+ int our_fd = heap->heapID();
+ struct pmem_region sub;
+ sub.offset = mOffset;
+ sub.len = mSize;
+ int err = ioctl(our_fd, PMEM_UNMAP, &sub);
+ ALOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
+ "mFD=%d, sub.offset=%lu, sub.size=%lu",
+ strerror(errno), our_fd, sub.offset, sub.len);
+ mSize = 0;
+ }
+#endif
+}
+
+// ---------------------------------------------------------------------------
+
+MemoryHeapPmem::MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap,
+ uint32_t flags)
+ : MemoryHeapBase()
+{
+ char const * const device = pmemHeap->getDevice();
+#ifdef HAVE_ANDROID_OS
+ if (device) {
+ int fd = open(device, O_RDWR | (flags & NO_CACHING ? O_SYNC : 0));
+ ALOGE_IF(fd<0, "couldn't open %s (%s)", device, strerror(errno));
+ if (fd >= 0) {
+ int err = ioctl(fd, PMEM_CONNECT, pmemHeap->heapID());
+ if (err < 0) {
+ ALOGE("PMEM_CONNECT failed (%s), mFD=%d, sub-fd=%d",
+ strerror(errno), fd, pmemHeap->heapID());
+ close(fd);
+ } else {
+ // everything went well...
+ mParentHeap = pmemHeap;
+ MemoryHeapBase::init(fd,
+ pmemHeap->getBase(),
+ pmemHeap->getSize(),
+ pmemHeap->getFlags() | flags,
+ device);
+ }
+ }
+ }
+#else
+ mParentHeap = pmemHeap;
+ MemoryHeapBase::init(
+ dup(pmemHeap->heapID()),
+ pmemHeap->getBase(),
+ pmemHeap->getSize(),
+ pmemHeap->getFlags() | flags,
+ device);
+#endif
+}
+
+MemoryHeapPmem::~MemoryHeapPmem()
+{
+}
+
+sp<IMemory> MemoryHeapPmem::mapMemory(size_t offset, size_t size)
+{
+ sp<MemoryPmem> memory = createMemory(offset, size);
+ if (memory != 0) {
+ Mutex::Autolock _l(mLock);
+ mAllocations.add(memory);
+ }
+ return memory;
+}
+
+sp<MemoryHeapPmem::MemoryPmem> MemoryHeapPmem::createMemory(
+ size_t offset, size_t size)
+{
+ sp<SubRegionMemory> memory;
+ if (heapID() > 0)
+ memory = new SubRegionMemory(this, offset, size);
+ return memory;
+}
+
+status_t MemoryHeapPmem::slap()
+{
+#ifdef HAVE_ANDROID_OS
+ size_t size = getSize();
+ const size_t pagesize = getpagesize();
+ size = (size + pagesize-1) & ~(pagesize-1);
+ int our_fd = getHeapID();
+ struct pmem_region sub = { 0, size };
+ int err = ioctl(our_fd, PMEM_MAP, &sub);
+ ALOGE_IF(err<0, "PMEM_MAP failed (%s), "
+ "mFD=%d, sub.offset=%lu, sub.size=%lu",
+ strerror(errno), our_fd, sub.offset, sub.len);
+ return -errno;
+#else
+ return NO_ERROR;
+#endif
+}
+
+status_t MemoryHeapPmem::unslap()
+{
+#ifdef HAVE_ANDROID_OS
+ size_t size = getSize();
+ const size_t pagesize = getpagesize();
+ size = (size + pagesize-1) & ~(pagesize-1);
+ int our_fd = getHeapID();
+ struct pmem_region sub = { 0, size };
+ int err = ioctl(our_fd, PMEM_UNMAP, &sub);
+ ALOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
+ "mFD=%d, sub.offset=%lu, sub.size=%lu",
+ strerror(errno), our_fd, sub.offset, sub.len);
+ return -errno;
+#else
+ return NO_ERROR;
+#endif
+}
+
+void MemoryHeapPmem::revoke()
+{
+ SortedVector< wp<MemoryPmem> > allocations;
+
+ { // scope for lock
+ Mutex::Autolock _l(mLock);
+ allocations = mAllocations;
+ }
+
+ ssize_t count = allocations.size();
+ for (ssize_t i=0 ; i<count ; i++) {
+ sp<MemoryPmem> memory(allocations[i].promote());
+ if (memory != 0)
+ memory->revoke();
+ }
+}
+
+void MemoryHeapPmem::remove(const wp<MemoryPmem>& memory)
+{
+ Mutex::Autolock _l(mLock);
+ mAllocations.remove(memory);
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index d970a33..8706dbc 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -54,7 +54,7 @@ ifneq ($(filter generic%,$(TARGET_DEVICE)),)
LOCAL_CFLAGS += -DUSE_FENCE_SYNC
endif
-ifeq ($(TARGET_BOARD_PLATFORM), msm8960)
+ifeq ($(call is-vendor-board-platform,QCOM),true)
LOCAL_CFLAGS += -DUSE_NATIVE_FENCE_SYNC
endif
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 80dd6ee..e6b4b21 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -393,6 +393,15 @@ void Composer::setDisplayProjection(const sp<IBinder>& token,
mForceSynchronous = true; // TODO: do we actually still need this?
}
+status_t Composer::setOrientation(int orientation) {
+ sp<ISurfaceComposer> sm(ComposerService::getComposerService());
+ sp<IBinder> token(sm->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
+ DisplayState& s(getDisplayStateLocked(token));
+ s.orientation = orientation;
+ mForceSynchronous = true; // TODO: do we actually still need this?
+ return NO_ERROR;
+}
+
// ---------------------------------------------------------------------------
SurfaceComposerClient::SurfaceComposerClient()
@@ -441,6 +450,30 @@ void SurfaceComposerClient::dispose() {
mStatus = NO_INIT;
}
+/* Create ICS/MR0-compatible constructors */
+extern "C" sp<SurfaceControl> _ZN7android21SurfaceComposerClient13createSurfaceERKNS_7String8Ejjij(
+ const String8& name,
+ uint32_t w,
+ uint32_t h,
+ PixelFormat format,
+ uint32_t flags);
+extern "C" sp<SurfaceControl> _ZN7android21SurfaceComposerClient13createSurfaceEijjij(
+ uint32_t display,
+ uint32_t w,
+ uint32_t h,
+ PixelFormat format,
+ uint32_t flags)
+{
+ String8 name;
+ const size_t SIZE = 128;
+ char buffer[SIZE];
+ snprintf(buffer, SIZE, "<pid_%d>", getpid());
+ name.append(buffer);
+
+ return _ZN7android21SurfaceComposerClient13createSurfaceERKNS_7String8Ejjij(name,
+ w, h, format, flags);
+}
+
sp<SurfaceControl> SurfaceComposerClient::createSurface(
const String8& name,
uint32_t w,
@@ -547,6 +580,11 @@ status_t SurfaceComposerClient::setMatrix(SurfaceID id, float dsdx, float dtdx,
return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy);
}
+status_t SurfaceComposerClient::setOrientation(int32_t dpy, int orientation, uint32_t flags)
+{
+ return Composer::getInstance().setOrientation(orientation);
+}
+
// ----------------------------------------------------------------------------
void SurfaceComposerClient::setDisplaySurface(const sp<IBinder>& token,
@@ -583,12 +621,49 @@ void SurfaceComposerClient::unblankDisplay(const sp<IBinder>& token) {
ComposerService::getComposerService()->unblank(token);
}
+// TODO: Remove me. Do not use.
+// This is a compatibility shim for one product whose drivers are depending on
+// this legacy function (when they shouldn't).
+status_t SurfaceComposerClient::getDisplayInfo(
+ int32_t displayId, DisplayInfo* info)
+{
+ return getDisplayInfo(getBuiltInDisplay(displayId), info);
+}
+
+#if defined(ICS_CAMERA_BLOB) || defined(MR0_CAMERA_BLOB)
+ssize_t SurfaceComposerClient::getDisplayWidth(int32_t displayId) {
+ DisplayInfo info;
+ getDisplayInfo(getBuiltInDisplay(displayId), &info);
+ return info.w;
+}
+
+ssize_t SurfaceComposerClient::getDisplayHeight(int32_t displayId) {
+ DisplayInfo info;
+ getDisplayInfo(getBuiltInDisplay(displayId), &info);
+ return info.h;
+}
+
+ssize_t SurfaceComposerClient::getDisplayOrientation(int32_t displayId) {
+ DisplayInfo info;
+ getDisplayInfo(getBuiltInDisplay(displayId), &info);
+ return info.orientation;
+}
+#endif
+
// ----------------------------------------------------------------------------
ScreenshotClient::ScreenshotClient()
: mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) {
}
+// TODO: Remove me. Do not use.
+// This is a compatibility shim for one product whose drivers are depending on
+// this legacy function (when they shouldn't).
+status_t ScreenshotClient::update() {
+ sp<ISurfaceComposer> sm(ComposerService::getComposerService());
+ return update(sm->getBuiltInDisplay(0));
+}
+
status_t ScreenshotClient::update(const sp<IBinder>& display) {
sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (s == NULL) return NO_INIT;
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index 0d2e44c..5d5e082 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -36,6 +36,25 @@ ifneq ($(BOARD_FRAMEBUFFER_FORCE_FORMAT),)
LOCAL_CFLAGS += -DFRAMEBUFFER_FORCE_FORMAT=$(BOARD_FRAMEBUFFER_FORCE_FORMAT)
endif
+ifeq ($(TARGET_SOC),exynos4210)
+ LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4210
+endif
+
+ifeq ($(TARGET_SOC),exynos4x12)
+ LOCAL_CFLAGS += -DSAMSUNG_EXYNOS4x12
+endif
+
+ifeq ($(TARGET_SOC),exynos5250)
+ LOCAL_CFLAGS += -DSAMSUNG_EXYNOS5250
+endif
+
+ifeq ($(BOARD_USES_SAMSUNG_HDMI),true)
+LOCAL_CFLAGS += -DSAMSUNG_HDMI_SUPPORT
+LOCAL_SHARED_LIBRARIES += libhdmiclient
+LOCAL_C_INCLUDES += hardware/samsung/$(TARGET_BOARD_PLATFORM)/libhdmi/libhdmiservice
+LOCAL_C_INCLUDES += hardware/samsung/$(TARGET_BOARD_PLATFORM)/include
+endif
+
LOCAL_MODULE:= libui
include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 31a69b2..7ff6618 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -76,6 +76,11 @@ FramebufferNativeWindow::FramebufferNativeWindow()
: BASE(), fbDev(0), grDev(0), mUpdateOnDemand(false)
{
hw_module_t const* module;
+
+#ifdef SAMSUNG_HDMI_SUPPORT
+ mHdmiClient = android::SecHdmiClient::getInstance();
+#endif
+
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
int stride;
int err;
@@ -154,6 +159,7 @@ FramebufferNativeWindow::FramebufferNativeWindow()
ANativeWindow::queueBuffer = queueBuffer;
ANativeWindow::query = query;
ANativeWindow::perform = perform;
+ ANativeWindow::cancelBuffer = NULL;
ANativeWindow::dequeueBuffer_DEPRECATED = dequeueBuffer_DEPRECATED;
ANativeWindow::lockBuffer_DEPRECATED = lockBuffer_DEPRECATED;
@@ -287,6 +293,25 @@ int FramebufferNativeWindow::queueBuffer(ANativeWindow* window,
self->front = static_cast<NativeBuffer*>(buffer);
self->mNumFreeBuffers++;
self->mCondition.broadcast();
+#ifdef SAMSUNG_HDMI_SUPPORT
+#if defined(SAMSUNG_EXYNOS4210) || defined(SAMSUNG_EXYNOS4x12)
+ if (self->mHdmiClient != NULL)
+ self->mHdmiClient->blit2Hdmi(buffer->width, buffer->height,
+ HAL_PIXEL_FORMAT_BGRA_8888,
+ 0, 0, 0,
+ 0, 0,
+ android::SecHdmiClient::HDMI_MODE_UI,
+ 0);
+#elif defined(SAMSUNG_EXYNOS5250)
+ if (self->mHdmiClient != NULL)
+ self->mHdmiClient->blit2Hdmi(buffer->width, buffer->height,
+ HAL_PIXEL_FORMAT_BGRA_8888,
+ 0, 0, 0,
+ 0, 0,
+ android::SecHdmiClient::HDMI_MODE_MIRROR,
+ 0);
+#endif
+#endif
return res;
}
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index fb43410..2ea5696 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -199,6 +199,16 @@ status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat forma
w = h = 1;
// we have a h/w allocator and h/w buffer is requested
+
+#ifdef EXYNOS4_ENHANCEMENTS
+ if ((format == 0x101) || (format == 0x105) || (format == 0x107)) {
+ // 0x101 = HAL_PIXEL_FORMAT_YCbCr_420_P (Samsung-specific pixel format)
+ // 0x105 = HAL_PIXEL_FORMAT_YCbCr_420_SP (Samsung-specific pixel format)
+ // 0x107 = HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED (Samsung-specific pixel format)
+ usage |= GRALLOC_USAGE_HW_FIMC1; // Exynos HWC wants FIMC-friendly memory allocation
+ }
+#endif
+
status_t err;
// If too many async frees are queued up then wait for some of them to
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 967da98..19c549d 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -95,5 +95,18 @@ status_t GraphicBufferMapper::unlock(buffer_handle_t handle)
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
diff --git a/services/sensorservice/Android.mk b/services/sensorservice/Android.mk
index e0cfaa6..40fe6e1 100644
--- a/services/sensorservice/Android.mk
+++ b/services/sensorservice/Android.mk
@@ -9,6 +9,7 @@ LOCAL_SRC_FILES:= \
LinearAccelerationSensor.cpp \
OrientationSensor.cpp \
RotationVectorSensor.cpp \
+ RotationVectorSensor2.cpp \
SensorDevice.cpp \
SensorFusion.cpp \
SensorInterface.cpp \
@@ -25,7 +26,9 @@ LOCAL_SHARED_LIBRARIES := \
libui \
libgui
-
+ifneq ($(BOARD_SYSFS_LIGHT_SENSOR),)
+ LOCAL_CFLAGS += -DSYSFS_LIGHT_SENSOR=\"$(BOARD_SYSFS_LIGHT_SENSOR)\"
+endif
LOCAL_MODULE:= libsensorservice
diff --git a/services/sensorservice/RotationVectorSensor2.cpp b/services/sensorservice/RotationVectorSensor2.cpp
new file mode 100644
index 0000000..f2873dd
--- /dev/null
+++ b/services/sensorservice/RotationVectorSensor2.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2012 The CyanogenMod 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 <stdint.h>
+#include <math.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+
+#include <hardware/sensors.h>
+
+#include "RotationVectorSensor2.h"
+#include "vec.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+ANDROID_SINGLETON_STATIC_INSTANCE(RotationVectorSensor2)
+
+RotationVectorSensor2::RotationVectorSensor2()
+ : mSensorDevice(SensorDevice::getInstance()),
+ mEnabled(false), mHasData(false)
+{
+ sensor_t const* list;
+ ssize_t count = mSensorDevice.getSensorList(&list);
+ if (count > 0) {
+ for (size_t i=0 ; i<size_t(count) ; i++) {
+ if (list[i].type == SENSOR_TYPE_ORIENTATION) {
+ mOrientation = Sensor(list + i);
+ }
+ }
+ }
+}
+
+bool RotationVectorSensor2::process(sensors_event_t* outEvent,
+ const sensors_event_t& event)
+{
+ if (mHasData && event.type == SENSOR_TYPE_ACCELEROMETER) {
+ *outEvent = event;
+ outEvent->data[0] = mData[1];
+ outEvent->data[1] = mData[2];
+ outEvent->data[2] = mData[3];
+ outEvent->data[3] = mData[0];
+ outEvent->sensor = '_rv2';
+ outEvent->type = SENSOR_TYPE_ROTATION_VECTOR;
+
+ mHasData = false;
+ return true;
+ }
+ return false;
+}
+
+status_t RotationVectorSensor2::activate(void* ident, bool enabled) {
+ mEnabled = enabled;
+ return mSensorDevice.activate(this, mOrientation.getHandle(), enabled);
+}
+
+status_t RotationVectorSensor2::setDelay(void* ident, int handle, int64_t ns) {
+ return mSensorDevice.setDelay(this, mOrientation.getHandle(), ns);
+}
+
+Sensor RotationVectorSensor2::getSensor() const {
+ sensor_t hwSensor;
+ hwSensor.name = "Rotation Vector Sensor 2";
+ hwSensor.vendor = "CyanogenMod Project";
+ hwSensor.version = 1;
+ hwSensor.handle = '_rv2';
+ hwSensor.type = SENSOR_TYPE_ROTATION_VECTOR;
+ hwSensor.maxRange = 1;
+ hwSensor.resolution = 1.0f / (1<<24);
+ hwSensor.power = mOrientation.getPowerUsage();
+ hwSensor.minDelay = mOrientation.getMinDelay();
+ Sensor sensor(&hwSensor);
+ return sensor;
+}
+
+void RotationVectorSensor2::process(const sensors_event_t& event) {
+ if (event.type == SENSOR_TYPE_ORIENTATION) {
+ const vec3_t v(event.data);
+
+ // Convert euler angle to quarternion
+ const float deg2rad = M_PI / 180;
+ float halfAzi = (v[0] / 2) * deg2rad;
+ float halfPitch = (v[1] / 2) * deg2rad;
+ float halfRoll = (-v[2] / 2) * deg2rad; // roll is reverse
+
+ float c1 = cosf(halfAzi);
+ float s1 = sinf(halfAzi);
+ float c2 = cosf(halfPitch);
+ float s2 = sinf(halfPitch);
+ float c3 = cosf(halfRoll);
+ float s3 = sinf(halfRoll);
+ mData[0] = c1*c2*c3 - s1*s2*s3;
+ mData[1] = c1*s2*c3 - s1*c2*s3;
+ mData[2] = c1*c2*s3 + s1*s2*c3;
+ mData[3] = s1*c2*c3 + c1*s2*s3;
+
+ // Misc fixes (a.k.a. "magic")
+ if (v[0] < 180) {
+ mData[1] = -mData[1];
+ mData[3] = -mData[3];
+ } else {
+ mData[2] = -mData[2];
+ }
+
+ mHasData = true;
+ }
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
diff --git a/services/sensorservice/RotationVectorSensor2.h b/services/sensorservice/RotationVectorSensor2.h
new file mode 100644
index 0000000..872ec12
--- /dev/null
+++ b/services/sensorservice/RotationVectorSensor2.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2012 The CyanogenMod 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 ANDROID_ROTATION_VECTOR_SENSOR2_H
+#define ANDROID_ROTATION_VECTOR_SENSOR2_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <gui/Sensor.h>
+
+#include "SensorDevice.h"
+#include "SensorInterface.h"
+
+#include "quat.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+class RotationVectorSensor2 : public SensorInterface,
+ public Singleton<RotationVectorSensor2> {
+ friend class Singleton<RotationVectorSensor2>;
+
+ SensorDevice& mSensorDevice;
+
+ Sensor mOrientation;
+ bool mEnabled;
+ bool mHasData;
+ quat_t mData;
+
+public:
+ RotationVectorSensor2();
+ virtual bool process(sensors_event_t* outEvent,
+ const sensors_event_t& event);
+ virtual status_t activate(void* ident, bool enabled);
+ virtual status_t setDelay(void* ident, int handle, int64_t ns);
+ virtual Sensor getSensor() const;
+ virtual bool isVirtual() const { return true; }
+ bool isEnabled() const { return mEnabled; }
+
+ // Incoming data
+ void process(const sensors_event_t& event);
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_ROTATION_VECTOR2_SENSOR_H
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index a9e3ef4..709febf 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -31,11 +31,37 @@
#include "SensorDevice.h"
#include "SensorService.h"
+#ifdef SYSFS_LIGHT_SENSOR
+#include <fcntl.h>
+#endif
+
namespace android {
// ---------------------------------------------------------------------------
ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
+#ifdef SYSFS_LIGHT_SENSOR
+#define DUMMY_ALS_HANDLE 0xdeadbeef
+static ssize_t addDummyLightSensor(sensor_t const **list, ssize_t count) {
+ struct sensor_t dummy_light = {
+ name : "CyanogenMod dummy light sensor",
+ vendor : "CyanogenMod",
+ version : 1,
+ handle : DUMMY_ALS_HANDLE,
+ type : SENSOR_TYPE_LIGHT,
+ maxRange : 20,
+ resolution : 0.1,
+ power : 20,
+ };
+ void * new_list = malloc((count+1)*sizeof(sensor_t));
+ new_list = memcpy(new_list, *list, count*sizeof(sensor_t));
+ ((sensor_t *)new_list)[count] = dummy_light;
+ *list = (sensor_t const *)new_list;
+ count++;
+ return count;
+}
+#endif
+
SensorDevice::SensorDevice()
: mSensorDevice(0),
mSensorModule(0)
@@ -55,6 +81,9 @@ SensorDevice::SensorDevice()
if (mSensorDevice) {
sensor_t const* list;
ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
+#ifdef SYSFS_LIGHT_SENSOR
+ count = addDummyLightSensor(&list, count);
+#endif
mActivationCount.setCapacity(count);
Info model;
for (size_t i=0 ; i<size_t(count) ; i++) {
@@ -95,7 +124,11 @@ void SensorDevice::dump(String8& result, char* buffer, size_t SIZE)
ssize_t SensorDevice::getSensorList(sensor_t const** list) {
if (!mSensorModule) return NO_INIT;
ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list);
+#ifdef SYSFS_LIGHT_SENSOR
+ return addDummyLightSensor(list, count);
+#else
return count;
+#endif
}
status_t SensorDevice::initCheck() const {
@@ -117,6 +150,22 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled)
status_t err(NO_ERROR);
bool actuateHardware = false;
+#ifdef SYSFS_LIGHT_SENSOR
+ if (handle == DUMMY_ALS_HANDLE) {
+ int nwr, ret, fd;
+ char value[2];
+
+ fd = open(SYSFS_LIGHT_SENSOR, O_RDWR);
+ if(fd < 0)
+ return -ENODEV;
+
+ nwr = snprintf(value, 2, "%d\n", enabled ? 1 : 0);
+ write(fd, value, nwr);
+ close(fd);
+ return 0;
+ }
+#endif
+
Info& info( mActivationCount.editValueFor(handle) );
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index e3dcd02..8ff0872 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -45,6 +45,7 @@
#include "LinearAccelerationSensor.h"
#include "OrientationSensor.h"
#include "RotationVectorSensor.h"
+#include "RotationVectorSensor2.h"
#include "SensorFusion.h"
#include "SensorService.h"
@@ -136,6 +137,12 @@ void SensorService::onFirstRef()
if (orientationIndex >= 0) {
mUserSensorList.removeItemsAt(orientationIndex);
}
+ } else if (orientationIndex != -1) {
+ // If we don't have a gyro but have a orientation sensor from
+ // elsewhere, we can compute rotation vector from that.
+ // (Google Maps expects rotation vector sensor to exist.)
+
+ registerVirtualSensor( &RotationVectorSensor2::getInstance() );
}
// debugging sensor list
@@ -272,6 +279,12 @@ bool SensorService::threadLoop()
fusion.process(event[i]);
}
}
+ RotationVectorSensor2& rv2(RotationVectorSensor2::getInstance());
+ if (rv2.isEnabled()) {
+ for (size_t i=0 ; i<size_t(count) ; i++) {
+ rv2.process(event[i]);
+ }
+ }
for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
if (count + k >= minBufferSize) {
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 5a57697..dac8467 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -38,6 +38,10 @@ ifeq ($(TARGET_DISABLE_TRIPLE_BUFFERING),true)
LOCAL_CFLAGS += -DTARGET_DISABLE_TRIPLE_BUFFERING
endif
+ifeq ($(BOARD_EGL_NEEDS_LEGACY_FB),true)
+ LOCAL_CFLAGS += -DBOARD_EGL_NEEDS_LEGACY_FB
+endif
+
ifneq ($(NUM_FRAMEBUFFER_SURFACE_BUFFERS),)
LOCAL_CFLAGS += -DNUM_FRAMEBUFFER_SURFACE_BUFFERS=$(NUM_FRAMEBUFFER_SURFACE_BUFFERS)
endif
@@ -53,6 +57,14 @@ LOCAL_SHARED_LIBRARIES := \
libui \
libgui
+ifeq ($(BOARD_USES_SAMSUNG_HDMI),true)
+ LOCAL_CFLAGS += -DSAMSUNG_HDMI_SUPPORT
+ LOCAL_SHARED_LIBRARIES += libTVOut libhdmiclient
+ LOCAL_C_INCLUDES += hardware/samsung/$(TARGET_BOARD_PLATFORM)/libhdmi/libhdmiservice
+ LOCAL_C_INCLUDES += hardware/samsung/$(TARGET_BOARD_PLATFORM)/include
+endif
+
+
LOCAL_MODULE:= libsurfaceflinger
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index ce98b67..395402d 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -28,6 +28,9 @@
#include <ui/PixelFormat.h>
#include <gui/SurfaceTextureClient.h>
+#ifdef BOARD_EGL_NEEDS_LEGACY_FB
+#include <ui/FramebufferNativeWindow.h>
+#endif
#include <GLES/gl.h>
#include <EGL/egl.h>
@@ -123,7 +126,11 @@ EGLSurface DisplayDevice::getEGLSurface() const {
void DisplayDevice::init(EGLConfig config)
{
+#ifndef BOARD_EGL_NEEDS_LEGACY_FB
ANativeWindow* const window = mNativeWindow.get();
+#else
+ ANativeWindow* const window = new FramebufferNativeWindow();
+#endif
int format;
window->query(window, NATIVE_WINDOW_FORMAT, &format);
@@ -343,6 +350,20 @@ status_t DisplayDevice::orientationToTransfrom(
int orientation, int w, int h, Transform* tr)
{
uint32_t flags = 0;
+ char value[PROPERTY_VALUE_MAX];
+ property_get("ro.sf.hwrotation", value, "0");
+ int additionalRot = atoi(value);
+
+ if (additionalRot) {
+ additionalRot /= 90;
+ if (orientation == DisplayState::eOrientationUnchanged) {
+ orientation = additionalRot;
+ } else {
+ orientation += additionalRot;
+ orientation %= 4;
+ }
+ }
+
switch (orientation) {
case DisplayState::eOrientationDefault:
flags = Transform::ROT_0;
@@ -359,6 +380,7 @@ status_t DisplayDevice::orientationToTransfrom(
default:
return BAD_VALUE;
}
+
tr->set(flags, w, h);
return NO_ERROR;
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 2eb74b7..3ed8d97 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -17,7 +17,7 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
// Uncomment this to remove support for HWC_DEVICE_API_VERSION_0_3 and older
-#define HWC_REMOVE_DEPRECATED_VERSIONS 1
+// #define HWC_REMOVE_DEPRECATED_VERSIONS 1
#include <stdint.h>
#include <stdio.h>
@@ -48,8 +48,28 @@
namespace android {
+// ---------------------------------------------------------------------------
+// Support for HWC_DEVICE_API_VERSION_0_3 and older:
+// Since v0.3 is deprecated and support will be dropped soon, as much as
+// possible the code is written to target v1.0. When using a v0.3 HWC, we
+// allocate v0.3 structures, but assign them to v1.0 pointers.
+
+#if HWC_REMOVE_DEPRECATED_VERSIONS
+// We need complete types to satisfy semantic checks, even though the code
+// paths that use these won't get executed at runtime (and will likely be dead-
+// code-eliminated). When we remove the code to support v0.3 we can remove
+// these as well.
+typedef hwc_layer_1_t hwc_layer_t;
+typedef hwc_display_contents_1_t hwc_layer_list_t;
+typedef hwc_composer_device_1_t hwc_composer_device_t;
+#endif
+
+// This function assumes we've already rejected HWC's with lower-than-required
+// versions. Don't use it for the initial "does HWC meet requirements" check!
+
#define MIN_HWC_HEADER_VERSION 0
+
static uint32_t hwcApiVersion(const hwc_composer_device_1_t* hwc) {
uint32_t hwcVersion = hwc->common.version;
if (MIN_HWC_HEADER_VERSION == 0 &&
@@ -75,6 +95,106 @@ static bool hwcHasApiVersion(const hwc_composer_device_1_t* hwc,
return hwcApiVersion(hwc) >= (version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK);
}
+static bool hwcHasVsyncEvent(const hwc_composer_device_1_t* hwc) {
+ return hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_0_3);
+}
+
+static size_t sizeofHwcLayerList(const hwc_composer_device_1_t* hwc,
+ size_t numLayers) {
+ if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
+ return sizeof(hwc_display_contents_1_t) + numLayers*sizeof(hwc_layer_1_t);
+ } else {
+ return sizeof(hwc_layer_list_t) + numLayers*sizeof(hwc_layer_t);
+ }
+}
+
+static int hwcEventControl(hwc_composer_device_1_t* hwc, int dpy,
+ int event, int enabled) {
+ if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
+ return hwc->eventControl(hwc, dpy, event, enabled);
+ } else {
+ hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
+ return hwc0->methods->eventControl(hwc0, event, enabled);
+ }
+}
+
+static int hwcBlank(hwc_composer_device_1_t* hwc, int dpy, int blank) {
+ if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
+ return hwc->blank(hwc, dpy, blank);
+ } else {
+ if (blank) {
+ hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
+ return hwc0->set(hwc0, NULL, NULL, NULL);
+ } else {
+ // HWC 0.x turns the screen on at the next set()
+ return NO_ERROR;
+ }
+ }
+}
+
+static int hwcPrepare(hwc_composer_device_1_t* hwc,
+ size_t numDisplays, hwc_display_contents_1_t** displays) {
+ if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
+ return hwc->prepare(hwc, numDisplays, displays);
+ } else {
+ hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
+ hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(displays[0]);
+ // In the past, SurfaceFlinger would pass a NULL list when doing full
+ // OpenGL ES composition. I don't know what, if any, dependencies there
+ // are on this behavior, so I'm playing it safe and preserving it.
+ // ... and I'm removing it. NULL layers kill the Tegra compositor (RC, Nov 2012)
+ /*if (list0->numHwLayers == 0)
+ return hwc0->prepare(hwc0, NULL);
+ else*/
+ return hwc0->prepare(hwc0, list0);
+ }
+}
+static int hwcSet(hwc_composer_device_1_t* hwc, EGLDisplay dpy, EGLSurface sur,
+ size_t numDisplays, hwc_display_contents_1_t** displays) {
+ int err;
+ if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
+ displays[0]->dpy = dpy;
+ displays[0]->sur = sur;
+ err = hwc->set(hwc, numDisplays, displays);
+ } else {
+ hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
+ hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(displays[0]);
+ err = hwc0->set(hwc0, dpy, sur, list0);
+ }
+ return err;
+}
+
+static uint32_t& hwcFlags(hwc_composer_device_1_t* hwc,
+ hwc_display_contents_1_t* display) {
+ if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
+ return display->flags;
+ } else {
+ hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(display);
+ return list0->flags;
+ }
+}
+
+static size_t& hwcNumHwLayers(hwc_composer_device_1_t* hwc,
+ hwc_display_contents_1_t* display) {
+ if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
+ return display->numHwLayers;
+ } else {
+ hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(display);
+ return list0->numHwLayers;
+ }
+}
+
+static void hwcDump(hwc_composer_device_1_t* hwc, char* buff, int buff_len) {
+ if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
+ if (hwc->dump)
+ hwc->dump(hwc, buff, buff_len);
+ } else if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_0_1)) {
+ hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
+ if (hwc0->dump)
+ hwc0->dump(hwc0, buff, buff_len);
+ }
+}
+
// ---------------------------------------------------------------------------
struct HWComposer::cb_context {
@@ -137,32 +257,48 @@ HWComposer::HWComposer(
ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER,
(hwcApiVersion(mHwc) >> 24) & 0xff,
(hwcApiVersion(mHwc) >> 16) & 0xff);
- if (mHwc->registerProcs) {
- mCBContext->hwc = this;
- mCBContext->procs.invalidate = &hook_invalidate;
- mCBContext->procs.vsync = &hook_vsync;
- if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
- mCBContext->procs.hotplug = &hook_hotplug;
- else
- mCBContext->procs.hotplug = NULL;
- memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
- mHwc->registerProcs(mHwc, &mCBContext->procs);
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+ if (mHwc->registerProcs) {
+ mCBContext->hwc = this;
+ mCBContext->procs.invalidate = &hook_invalidate;
+ mCBContext->procs.vsync = &hook_vsync;
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
+ mCBContext->procs.hotplug = &hook_hotplug;
+ else
+ mCBContext->procs.hotplug = NULL;
+ memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
+ mHwc->registerProcs(mHwc, &mCBContext->procs);
+ }
+ } else {
+ hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(mHwc);
+ if (hwc0->registerProcs) {
+ mCBContext->hwc = this;
+ mCBContext->procs.invalidate = &hook_invalidate;
+ mCBContext->procs.vsync = &hook_vsync;
+ memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
+ hwc0->registerProcs(hwc0, &mCBContext->procs);
+ }
}
// don't need a vsync thread if we have a hardware composer
needVSyncThread = false;
// always turn vsync off when we start
- eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
+ if (hwcHasVsyncEvent(mHwc)) {
+ eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
- // the number of displays we actually have depends on the
- // hw composer version
- if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_2)) {
- // 1.2 adds support for virtual displays
- mNumDisplays = MAX_DISPLAYS;
- } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
- // 1.1 adds support for multiple displays
- mNumDisplays = HWC_NUM_DISPLAY_TYPES;
+ // the number of displays we actually have depends on the
+ // hw composer version
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_2)) {
+ // 1.2 adds support for virtual displays
+ mNumDisplays = MAX_DISPLAYS;
+ } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
+ // 1.1 adds support for multiple displays
+ mNumDisplays = HWC_NUM_DISPLAY_TYPES;
+ } else {
+ mNumDisplays = 1;
+ }
} else {
+ needVSyncThread = true;
mNumDisplays = 1;
}
}
@@ -233,9 +369,10 @@ void HWComposer::loadHwcModule()
return;
}
- if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0) ||
+ if (HWC_REMOVE_DEPRECATED_VERSIONS &&
+ (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0) ||
hwcHeaderVersion(mHwc) < MIN_HWC_HEADER_VERSION ||
- hwcHeaderVersion(mHwc) > HWC_HEADER_VERSION) {
+ hwcHeaderVersion(mHwc) > HWC_HEADER_VERSION)) {
ALOGE("%s device version %#x unsupported, will not be used",
HWC_HARDWARE_COMPOSER, mHwc->common.version);
hwc_close_1(mHwc);
@@ -455,22 +592,26 @@ void HWComposer::eventControl(int disp, int event, int enabled) {
return;
}
status_t err = NO_ERROR;
- if (mHwc && !mDebugForceFakeVSync) {
- // NOTE: we use our own internal lock here because we have to call
- // into the HWC with the lock held, and we want to make sure
- // that even if HWC blocks (which it shouldn't), it won't
- // affect other threads.
- Mutex::Autolock _l(mEventControlLock);
- const int32_t eventBit = 1UL << event;
- const int32_t newValue = enabled ? eventBit : 0;
- const int32_t oldValue = mDisplayData[disp].events & eventBit;
- if (newValue != oldValue) {
- ATRACE_CALL();
- err = mHwc->eventControl(mHwc, disp, event, enabled);
- if (!err) {
- int32_t& events(mDisplayData[disp].events);
- events = (events & ~eventBit) | newValue;
+ if (mHwc && !mDebugForceFakeVSync && hwcHasVsyncEvent(mHwc)) {
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+ // NOTE: we use our own internal lock here because we have to call
+ // into the HWC with the lock held, and we want to make sure
+ // that even if HWC blocks (which it shouldn't), it won't
+ // affect other threads.
+ Mutex::Autolock _l(mEventControlLock);
+ const int32_t eventBit = 1UL << event;
+ const int32_t newValue = enabled ? eventBit : 0;
+ const int32_t oldValue = mDisplayData[disp].events & eventBit;
+ if (newValue != oldValue) {
+ ATRACE_CALL();
+ err = hwcEventControl(mHwc, disp, event, enabled);
+ if (!err) {
+ int32_t& events(mDisplayData[disp].events);
+ events = (events & ~eventBit) | newValue;
+ }
}
+ } else {
+ err = hwcEventControl(mHwc, disp, event, enabled);
}
// error here should not happen -- not sure what we should
// do if it does.
@@ -495,8 +636,7 @@ status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {
numLayers++;
}
if (disp.capacity < numLayers || disp.list == NULL) {
- size_t size = sizeof(hwc_display_contents_1_t)
- + numLayers * sizeof(hwc_layer_1_t);
+ size_t size = sizeofHwcLayerList(mHwc, numLayers);
free(disp.list);
disp.list = (hwc_display_contents_1_t*)malloc(size);
disp.capacity = numLayers;
@@ -519,9 +659,11 @@ status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {
disp.framebufferTarget->acquireFenceFd = -1;
disp.framebufferTarget->releaseFenceFd = -1;
}
- disp.list->retireFenceFd = -1;
- disp.list->flags = HWC_GEOMETRY_CHANGED;
- disp.list->numHwLayers = numLayers;
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+ disp.list->retireFenceFd = -1;
+ }
+ hwcFlags(mHwc, disp.list) = HWC_GEOMETRY_CHANGED;
+ hwcNumHwLayers(mHwc, disp.list) = numLayers;
}
return NO_ERROR;
}
@@ -568,7 +710,7 @@ status_t HWComposer::prepare() {
}
if (!disp.connected && disp.list != NULL) {
ALOGW("WARNING: disp %d: connected, non-null list, layers=%d",
- i, disp.list->numHwLayers);
+ i, hwcNumHwLayers(mHwc, disp.list));
}
mLists[i] = disp.list;
if (mLists[i]) {
@@ -579,27 +721,51 @@ status_t HWComposer::prepare() {
// garbage data to catch improper use
mLists[i]->dpy = (hwc_display_t)0xDEADBEEF;
mLists[i]->sur = (hwc_surface_t)0xDEADBEEF;
- } else {
+ } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
mLists[i]->dpy = EGL_NO_DISPLAY;
mLists[i]->sur = EGL_NO_SURFACE;
}
}
}
-
- int err = mHwc->prepare(mHwc, mNumDisplays, mLists);
+ int err = hwcPrepare(mHwc, mNumDisplays, mLists);
ALOGE_IF(err, "HWComposer: prepare failed (%s)", strerror(-err));
if (err == NO_ERROR) {
- // here we're just making sure that "skip" layers are set
- // to HWC_FRAMEBUFFER and we're also counting how many layers
- // we have of each type.
- for (size_t i=0 ; i<mNumDisplays ; i++) {
- DisplayData& disp(mDisplayData[i]);
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+ // here we're just making sure that "skip" layers are set
+ // to HWC_FRAMEBUFFER and we're also counting how many layers
+ // we have of each type.
+ for (size_t i=0 ; i<mNumDisplays ; i++) {
+ DisplayData& disp(mDisplayData[i]);
+ disp.hasFbComp = false;
+ disp.hasOvComp = false;
+ if (disp.list) {
+ for (size_t i=0 ; i<hwcNumHwLayers(mHwc, disp.list) ; i++) {
+ hwc_layer_1_t& l = disp.list->hwLayers[i];
+
+ //ALOGD("prepare: %d, type=%d, handle=%p",
+ // i, l.compositionType, l.handle);
+
+ if (l.flags & HWC_SKIP_LAYER) {
+ l.compositionType = HWC_FRAMEBUFFER;
+ }
+ if (l.compositionType == HWC_FRAMEBUFFER) {
+ disp.hasFbComp = true;
+ }
+ if (l.compositionType == HWC_OVERLAY) {
+ disp.hasOvComp = true;
+ }
+ }
+ }
+ }
+ } else {
+ DisplayData& disp(mDisplayData[0]);
disp.hasFbComp = false;
disp.hasOvComp = false;
if (disp.list) {
- for (size_t i=0 ; i<disp.list->numHwLayers ; i++) {
- hwc_layer_1_t& l = disp.list->hwLayers[i];
+ hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(disp.list);
+ for (size_t i=0 ; i<hwcNumHwLayers(mHwc, disp.list) ; i++) {
+ hwc_layer_t& l = list0->hwLayers[i];
//ALOGD("prepare: %d, type=%d, handle=%p",
// i, l.compositionType, l.handle);
@@ -610,12 +776,19 @@ status_t HWComposer::prepare() {
if (l.compositionType == HWC_FRAMEBUFFER) {
disp.hasFbComp = true;
}
+ // If the composition type is BLIT, we set this to
+ // trigger a FLIP
+ if(l.compositionType == HWC_BLIT) {
+ disp.hasFbComp = true;
+ }
if (l.compositionType == HWC_OVERLAY) {
disp.hasOvComp = true;
}
}
}
+
}
+
}
return (status_t)err;
}
@@ -651,24 +824,32 @@ int HWComposer::getAndResetReleaseFenceFd(int32_t id) {
status_t HWComposer::commit() {
int err = NO_ERROR;
if (mHwc) {
- if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
- // On version 1.0, the OpenGL ES target surface is communicated
- // by the (dpy, sur) fields and we are guaranteed to have only
- // a single display.
- mLists[0]->dpy = eglGetCurrentDisplay();
- mLists[0]->sur = eglGetCurrentSurface(EGL_DRAW);
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+ if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
+ // On version 1.0, the OpenGL ES target surface is communicated
+ // by the (dpy, sur) fields and we are guaranteed to have only
+ // a single display.
+ mLists[0]->dpy = eglGetCurrentDisplay();
+ mLists[0]->sur = eglGetCurrentSurface(EGL_DRAW);
+ }
+ err = hwcSet(mHwc, mLists[0]->dpy, mLists[0]->sur, mNumDisplays,
+ const_cast<hwc_display_contents_1_t**>(mLists));
+ } else {
+ err = hwcSet(mHwc, eglGetCurrentDisplay(), eglGetCurrentSurface(EGL_DRAW), mNumDisplays,
+ const_cast<hwc_display_contents_1_t**>(mLists));
}
- err = mHwc->set(mHwc, mNumDisplays, mLists);
for (size_t i=0 ; i<mNumDisplays ; i++) {
DisplayData& disp(mDisplayData[i]);
if (disp.list) {
- if (disp.list->retireFenceFd != -1) {
- close(disp.list->retireFenceFd);
- disp.list->retireFenceFd = -1;
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+ if (disp.list->retireFenceFd != -1) {
+ close(disp.list->retireFenceFd);
+ disp.list->retireFenceFd = -1;
+ }
}
- disp.list->flags &= ~HWC_GEOMETRY_CHANGED;
+ hwcFlags(mHwc, disp.list) &= ~HWC_GEOMETRY_CHANGED;
}
}
}
@@ -678,8 +859,10 @@ status_t HWComposer::commit() {
status_t HWComposer::release(int disp) {
LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES);
if (mHwc) {
- eventControl(disp, HWC_EVENT_VSYNC, 0);
- return (status_t)mHwc->blank(mHwc, disp, 1);
+ if (hwcHasVsyncEvent(mHwc)) {
+ eventControl(disp, HWC_EVENT_VSYNC, 0);
+ }
+ return (status_t)hwcBlank(mHwc, disp, 1);
}
return NO_ERROR;
}
@@ -687,7 +870,7 @@ status_t HWComposer::release(int disp) {
status_t HWComposer::acquire(int disp) {
LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES);
if (mHwc) {
- return (status_t)mHwc->blank(mHwc, disp, 0);
+ return (status_t)hwcBlank(mHwc, disp, 0);
}
return NO_ERROR;
}
@@ -780,6 +963,96 @@ private:
}
};
+// #if !HWC_REMOVE_DEPRECATED_VERSIONS
+/*
+ * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_0_3
+ * This implements the HWCLayer side of HWCIterableLayer.
+ */
+class HWCLayerVersion0 : public Iterable<HWCLayerVersion0, hwc_layer_t> {
+public:
+ HWCLayerVersion0(hwc_layer_t* layer)
+ : Iterable<HWCLayerVersion0, hwc_layer_t>(layer) { }
+
+ virtual int32_t getCompositionType() const {
+ return getLayer()->compositionType;
+ }
+ virtual uint32_t getHints() const {
+ return getLayer()->hints;
+ }
+ virtual int getAndResetReleaseFenceFd() {
+ // not supported on VERSION_03
+ return -1;
+ }
+ virtual void setAcquireFenceFd(int fenceFd) {
+ if (fenceFd != -1) {
+ ALOGE("HWC 0.x can't handle acquire fences");
+ close(fenceFd);
+ }
+ }
+
+ virtual void setDefaultState() {
+ getLayer()->compositionType = HWC_FRAMEBUFFER;
+ getLayer()->hints = 0;
+ getLayer()->flags = HWC_SKIP_LAYER;
+ getLayer()->handle = 0;
+ getLayer()->transform = 0;
+ getLayer()->blending = HWC_BLENDING_NONE;
+ getLayer()->visibleRegionScreen.numRects = 0;
+ getLayer()->visibleRegionScreen.rects = NULL;
+ }
+ virtual void setPerFrameDefaultState() {
+ //getLayer()->compositionType = HWC_FRAMEBUFFER;
+ }
+ virtual void setSkip(bool skip) {
+ if (skip) {
+ getLayer()->flags |= HWC_SKIP_LAYER;
+ } else {
+ getLayer()->flags &= ~HWC_SKIP_LAYER;
+ }
+ }
+ virtual void setBlending(uint32_t blending) {
+ getLayer()->blending = blending;
+ }
+ virtual void setTransform(uint32_t transform) {
+ getLayer()->transform = transform;
+ }
+ virtual void setFrame(const Rect& frame) {
+ reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
+ }
+ virtual void setCrop(const Rect& crop) {
+ reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
+ }
+ virtual void setVisibleRegionScreen(const Region& reg) {
+ // Region::getSharedBuffer creates a reference to the underlying
+ // SharedBuffer of this Region, this reference is freed
+ // in onDisplayed()
+ hwc_region_t& visibleRegion = getLayer()->visibleRegionScreen;
+ SharedBuffer const* sb = reg.getSharedBuffer(&visibleRegion.numRects);
+ visibleRegion.rects = reinterpret_cast<hwc_rect_t const *>(sb->data());
+ }
+ virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
+ if (buffer == 0 || buffer->handle == 0) {
+ getLayer()->compositionType = HWC_FRAMEBUFFER;
+ getLayer()->flags |= HWC_SKIP_LAYER;
+ getLayer()->handle = 0;
+ } else {
+ getLayer()->handle = buffer->handle;
+ }
+ }
+ virtual void onDisplayed() {
+ hwc_region_t& visibleRegion = getLayer()->visibleRegionScreen;
+ SharedBuffer const* sb = SharedBuffer::bufferFromData(visibleRegion.rects);
+ if (sb) {
+ sb->release();
+ // not technically needed but safer
+ visibleRegion.numRects = 0;
+ visibleRegion.rects = NULL;
+ }
+
+ }
+};
+// #endif // !HWC_REMOVE_DEPRECATED_VERSIONS
+
/*
* Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_1_0.
* This implements the HWCLayer side of HWCIterableLayer.
@@ -876,10 +1149,15 @@ HWComposer::LayerListIterator HWComposer::getLayerIterator(int32_t id, size_t in
return LayerListIterator();
}
const DisplayData& disp(mDisplayData[id]);
- if (!mHwc || !disp.list || index > disp.list->numHwLayers) {
+ if (!mHwc || !disp.list || index > hwcNumHwLayers(mHwc,disp.list)) {
return LayerListIterator();
}
- return LayerListIterator(new HWCLayerVersion1(disp.list->hwLayers), index);
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+ return LayerListIterator(new HWCLayerVersion1(disp.list->hwLayers), index);
+ } else {
+ hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(disp.list);
+ return LayerListIterator(new HWCLayerVersion0(list0->hwLayers), index);
+ }
}
/*
@@ -897,7 +1175,7 @@ HWComposer::LayerListIterator HWComposer::end(int32_t id) {
if (uint32_t(id) <= 31 && mAllocatedDisplayIDs.hasBit(id)) {
const DisplayData& disp(mDisplayData[id]);
if (mHwc && disp.list) {
- numLayers = disp.list->numHwLayers;
+ numLayers = hwcNumHwLayers(mHwc, disp.list);
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
// with HWC 1.1, the last layer is always the HWC_FRAMEBUFFER_TARGET,
// which we ignore when iterating through the layer list.
@@ -964,6 +1242,7 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE) const {
"HWC",
"BACKGROUND",
"FB TARGET",
+ "FB_BLIT",
"UNKNOWN"};
if (type >= NELEM(compositionTypeName))
type = NELEM(compositionTypeName) - 1;
@@ -979,9 +1258,8 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE) const {
}
}
}
-
- if (mHwc && mHwc->dump) {
- mHwc->dump(mHwc, buffer, SIZE);
+ if (mHwc) {
+ hwcDump(mHwc, buffer, SIZE);
result.append(buffer);
}
}
@@ -1035,7 +1313,7 @@ bool HWComposer::VSyncThread::threadLoop() {
err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
} while (err<0 && errno == EINTR);
- if (err == 0) {
+ if (err == 0 && mEnabled) {
mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 842471f..00efd49 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -68,6 +68,9 @@
#include "DisplayHardware/GraphicBufferAlloc.h"
#include "DisplayHardware/HWComposer.h"
+#ifdef SAMSUNG_HDMI_SUPPORT
+#include "SecTVOutService.h"
+#endif
#define EGL_VERSION_HW_ANDROID 0x3143
@@ -121,6 +124,16 @@ SurfaceFlinger::SurfaceFlinger()
}
ALOGI_IF(mDebugRegion, "showupdates enabled");
ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
+
+#ifdef SAMSUNG_HDMI_SUPPORT
+ ALOGD(">>> Run service");
+ android::SecTVOutService::instantiate();
+#if defined(SAMSUNG_EXYNOS5250)
+ mHdmiClient = SecHdmiClient::getInstance();
+ mHdmiClient->setHdmiEnable(1);
+#endif
+#endif
+
}
void SurfaceFlinger::onFirstRef()
@@ -128,7 +141,6 @@ void SurfaceFlinger::onFirstRef()
mEventQueue.init(this);
run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
-
// Wait for the main thread to be done with its initialization
mReadyToRunBarrier.wait();
}
@@ -665,10 +677,21 @@ status_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo*
info->orientation = 0;
}
- info->w = hwc.getWidth(type);
- info->h = hwc.getHeight(type);
- info->xdpi = xdpi;
- info->ydpi = ydpi;
+ char value[PROPERTY_VALUE_MAX];
+ property_get("ro.sf.hwrotation", value, "0");
+ int additionalRot = atoi(value) / 90;
+ if ((type == DisplayDevice::DISPLAY_PRIMARY) && (additionalRot & DisplayState::eOrientationSwapMask)) {
+ info->h = hwc.getWidth(type);
+ info->w = hwc.getHeight(type);
+ info->xdpi = ydpi;
+ info->ydpi = xdpi;
+ }
+ else {
+ info->w = hwc.getWidth(type);
+ info->h = hwc.getHeight(type);
+ info->xdpi = xdpi;
+ info->ydpi = ydpi;
+ }
info->fps = float(1e9 / hwc.getRefreshPeriod(type));
// All non-virtual displays are currently considered secure.
@@ -1596,6 +1619,9 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
layer->draw(hw, clip);
break;
}
+ case HWC_BLIT:
+ //Do nothing
+ break;
case HWC_FRAMEBUFFER_TARGET: {
// this should not happen as the iterator shouldn't
// let us get there.
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b0d3bac..e8c4b9c 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -50,6 +50,10 @@
#include "DisplayHardware/HWComposer.h"
+#ifdef SAMSUNG_HDMI_SUPPORT
+#include "SecHdmiClient.h"
+#endif
+
namespace android {
// ---------------------------------------------------------------------------
@@ -458,6 +462,9 @@ private:
*/
sp<IBinder> mExtDisplayToken;
+#if defined(SAMSUNG_HDMI_SUPPORT) && defined(SAMSUNG_EXYNOS5250)
+ SecHdmiClient * mHdmiClient;
+#endif
};
// ---------------------------------------------------------------------------