diff options
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 }; // --------------------------------------------------------------------------- |