summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build/phone-xhdpi-1024-dalvik-heap.mk2
-rw-r--r--build/phone-xhdpi-2048-dalvik-heap.mk2
-rw-r--r--build/tablet-10in-xhdpi-2048-dalvik-heap.mk2
-rw-r--r--build/tablet-7in-hdpi-1024-dalvik-heap.mk2
-rw-r--r--cmds/dumpstate/dumpstate.c9
-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/gui/BufferQueue.h37
-rw-r--r--include/gui/IGraphicBufferAlloc.h3
-rw-r--r--include/gui/ISurfaceTexture.h14
-rw-r--r--include/gui/SurfaceComposerClient.h6
-rw-r--r--include/gui/SurfaceTextureClient.h15
-rw-r--r--include/media/openmax/OMX_IVCommon.h1
-rw-r--r--include/ui/GraphicBuffer.h17
-rw-r--r--include/ui/GraphicBufferAllocator.h6
-rw-r--r--include/ui/GraphicBufferMapper.h5
-rw-r--r--include/utils/Trace.h2
-rw-r--r--libs/gui/Android.mk4
-rw-r--r--libs/gui/BufferQueue.cpp138
-rw-r--r--libs/gui/IGraphicBufferAlloc.cpp21
-rw-r--r--libs/gui/ISurfaceTexture.cpp51
-rw-r--r--libs/gui/SurfaceComposerClient.cpp20
-rw-r--r--libs/gui/SurfaceTextureClient.cpp64
-rw-r--r--libs/ui/GraphicBuffer.cpp43
-rw-r--r--libs/ui/GraphicBufferAllocator.cpp157
-rw-r--r--libs/ui/GraphicBufferMapper.cpp13
-rw-r--r--libs/utils/Trace.cpp4
-rw-r--r--opengl/libs/EGL/egl.cpp6
-rw-r--r--opengl/libs/EGL/eglApi.cpp5
-rw-r--r--opengl/specs/EGL_ANDROID_native_fence_sync.txt21
-rw-r--r--services/surfaceflinger/Android.mk3
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp1
-rw-r--r--services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.cpp15
-rw-r--r--services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.h5
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp13
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h1
-rw-r--r--services/surfaceflinger/Layer.cpp30
-rw-r--r--services/surfaceflinger/Layer.h6
-rw-r--r--services/surfaceflinger/LayerBase.cpp8
-rw-r--r--services/surfaceflinger/LayerBase.h2
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp93
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h6
42 files changed, 815 insertions, 78 deletions
diff --git a/build/phone-xhdpi-1024-dalvik-heap.mk b/build/phone-xhdpi-1024-dalvik-heap.mk
index 221227d..20f365f 100644
--- a/build/phone-xhdpi-1024-dalvik-heap.mk
+++ b/build/phone-xhdpi-1024-dalvik-heap.mk
@@ -21,5 +21,5 @@ PRODUCT_PROPERTY_OVERRIDES += \
dalvik.vm.heapgrowthlimit=96m \
dalvik.vm.heapsize=256m \
dalvik.vm.heaptargetutilization=0.75 \
- dalvik.vm.heapminfree=512k \
+ dalvik.vm.heapminfree=2m \
dalvik.vm.heapmaxfree=8m
diff --git a/build/phone-xhdpi-2048-dalvik-heap.mk b/build/phone-xhdpi-2048-dalvik-heap.mk
index 042a6e6..324e883 100644
--- a/build/phone-xhdpi-2048-dalvik-heap.mk
+++ b/build/phone-xhdpi-2048-dalvik-heap.mk
@@ -22,5 +22,5 @@ PRODUCT_PROPERTY_OVERRIDES += \
dalvik.vm.heapgrowthlimit=192m \
dalvik.vm.heapsize=512m \
dalvik.vm.heaptargetutilization=0.75 \
- dalvik.vm.heapminfree=512k \
+ dalvik.vm.heapminfree=2m \
dalvik.vm.heapmaxfree=8m
diff --git a/build/tablet-10in-xhdpi-2048-dalvik-heap.mk b/build/tablet-10in-xhdpi-2048-dalvik-heap.mk
index 1721fcc..f154450 100644
--- a/build/tablet-10in-xhdpi-2048-dalvik-heap.mk
+++ b/build/tablet-10in-xhdpi-2048-dalvik-heap.mk
@@ -21,5 +21,5 @@ PRODUCT_PROPERTY_OVERRIDES += \
dalvik.vm.heapgrowthlimit=192m \
dalvik.vm.heapsize=512m \
dalvik.vm.heaptargetutilization=0.75 \
- dalvik.vm.heapminfree=512k \
+ dalvik.vm.heapminfree=2m \
dalvik.vm.heapmaxfree=8m
diff --git a/build/tablet-7in-hdpi-1024-dalvik-heap.mk b/build/tablet-7in-hdpi-1024-dalvik-heap.mk
index 5bbd2b0..5c8ce3e 100644
--- a/build/tablet-7in-hdpi-1024-dalvik-heap.mk
+++ b/build/tablet-7in-hdpi-1024-dalvik-heap.mk
@@ -21,5 +21,5 @@ PRODUCT_PROPERTY_OVERRIDES += \
dalvik.vm.heapgrowthlimit=64m \
dalvik.vm.heapsize=384m \
dalvik.vm.heaptargetutilization=0.75 \
- dalvik.vm.heapminfree=512k \
+ dalvik.vm.heapminfree=2m \
dalvik.vm.heapmaxfree=8m
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index f3fcca0..8718bb6 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -188,6 +188,12 @@ static void dumpstate() {
run_command("WIFI NETWORKS", 20,
SU_PATH, "root", "wpa_cli", "list_networks", NULL);
+#ifdef FWDUMP_bcmdhd
+ run_command("DUMP WIFI INTERNAL COUNTERS", 20,
+ SU_PATH, "root", "wlutil", "counters", NULL);
+#endif
+ dump_file("INTERRUPTS (1)", "/proc/interrupts");
+
property_get("dhcp.wlan0.gateway", network, "");
if (network[0])
run_command("PING GATEWAY", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL);
@@ -197,12 +203,13 @@ static void dumpstate() {
property_get("dhcp.wlan0.dns2", network, "");
if (network[0])
run_command("PING DNS2", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL);
-#ifdef FWDUMP_bcm4329
+#ifdef FWDUMP_bcmdhd
run_command("DUMP WIFI STATUS", 20,
SU_PATH, "root", "dhdutil", "-i", "wlan0", "dump", NULL);
run_command("DUMP WIFI INTERNAL COUNTERS", 20,
SU_PATH, "root", "wlutil", "counters", NULL);
#endif
+ dump_file("INTERRUPTS (2)", "/proc/interrupts");
print_properties();
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/gui/BufferQueue.h b/include/gui/BufferQueue.h
index 9e265ba..cd38cfe 100644
--- a/include/gui/BufferQueue.h
+++ b/include/gui/BufferQueue.h
@@ -33,6 +33,23 @@
namespace android {
// ----------------------------------------------------------------------------
+#ifdef QCOM_BSP
+/*
+ * Structure to hold the buffer geometry
+ */
+struct QBufGeometry {
+ int mWidth;
+ int mHeight;
+ int mFormat;
+ QBufGeometry(): mWidth(0), mHeight(0), mFormat(0) {}
+ void set(int w, int h, int f) {
+ mWidth = w;
+ mHeight = h;
+ mFormat = f;
+ }
+};
+#endif
+
class BufferQueue : public BnSurfaceTexture {
public:
enum { MIN_UNDEQUEUED_BUFFERS = 2 };
@@ -148,6 +165,21 @@ public:
// The default mode is asynchronous.
virtual status_t setSynchronousMode(bool enabled);
+#ifdef QCOM_BSP
+ // setBufferSize enables us to specify user defined sizes for the buffers
+ // that need to be allocated by surfaceflinger for its client. This is
+ // useful for cases where the client doesn't want the gralloc to calculate
+ // buffer size. client should reset this value to 0, if it wants gralloc
+ // to calculate the size for the buffer. this will take effect from next
+ // dequeue buffer.
+ virtual status_t setBuffersSize(int size);
+
+ // update buffer width, height and format for a native buffer
+ // dynamically from the client which will take effect in the next
+ // queue buffer.
+ virtual status_t updateBuffersGeometry(int w, int h, int f);
+#endif
+
// connect attempts to connect a producer client API to the BufferQueue.
// This must be called before any other ISurfaceTexture methods are called
// except for getAllocator.
@@ -537,6 +569,11 @@ private:
// mTransformHint is used to optimize for screen rotations
uint32_t mTransformHint;
+
+#ifdef QCOM_BSP
+ // holds the updated buffer geometry info of the new video resolution.
+ QBufGeometry mNextBufferInfo;
+#endif
};
// ----------------------------------------------------------------------------
diff --git a/include/gui/IGraphicBufferAlloc.h b/include/gui/IGraphicBufferAlloc.h
index cee41d9..adc0b7f 100644
--- a/include/gui/IGraphicBufferAlloc.h
+++ b/include/gui/IGraphicBufferAlloc.h
@@ -38,6 +38,9 @@ public:
*/
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
PixelFormat format, uint32_t usage, status_t* error) = 0;
+#ifdef QCOM_BSP
+ virtual void setGraphicBufferSize(int size) = 0;
+#endif
};
// ----------------------------------------------------------------------------
diff --git a/include/gui/ISurfaceTexture.h b/include/gui/ISurfaceTexture.h
index ae7c5c2..f2a6510 100644
--- a/include/gui/ISurfaceTexture.h
+++ b/include/gui/ISurfaceTexture.h
@@ -164,6 +164,20 @@ public:
// The default mode is asynchronous.
virtual status_t setSynchronousMode(bool enabled) = 0;
+#ifdef QCOM_BSP
+ // setBufferSize enables to specify the user defined size of the buffer
+ // that needs to be allocated by surfaceflinger for its client. This is
+ // useful for cases where the client doesn't want the gralloc to calculate
+ // buffer size. client should reset this value to 0, if it wants gralloc to
+ // calculate the size for the buffer. this will take effect from next
+ // dequeue buffer.
+ virtual status_t setBuffersSize(int size) = 0;
+
+ // update buffer width, height and format information from the client
+ // which will take effect in the next queue buffer.
+ virtual status_t updateBuffersGeometry(int w, int h, int f) = 0;
+#endif
+
// connect attempts to connect a client API to the SurfaceTexture. This
// must be called before any other ISurfaceTexture methods are called except
// for getAllocator.
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index 1bbad60..7eb6b64 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -77,6 +77,12 @@ public:
// 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
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index 50fd1ba..f2b523d 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -93,6 +93,10 @@ private:
int dispatchSetCrop(va_list args);
int dispatchSetPostTransformCrop(va_list args);
int dispatchSetUsage(va_list args);
+#ifdef QCOM_BSP
+ int dispatchUpdateBuffersGeometry(va_list args);
+ int dispatchSetBuffersSize(va_list args);
+#endif
int dispatchLock(va_list args);
int dispatchUnlockAndPost(va_list args);
@@ -103,7 +107,10 @@ protected:
virtual int perform(int operation, va_list args);
virtual int query(int what, int* value) const;
virtual int setSwapInterval(int interval);
-
+#ifdef QCOM_BSP
+ virtual int updateBuffersGeometry(int w, int h, int f);
+ virtual int setBuffersSize(int size);
+#endif
virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer);
virtual int connect(int api);
@@ -161,6 +168,12 @@ private:
// at the next deuque operation. It is initialized to 0.
uint32_t mReqUsage;
+#ifdef QCOM_BSP
+ // mReqSize is the size of the buffer that will be requested
+ // at the next dequeue operation. It is initialized to 0.
+ uint32_t mReqSize;
+#endif
+
// mTimestamp is the timestamp that will be used for the next buffer queue
// operation. It defaults to NATIVE_WINDOW_TIMESTAMP_AUTO, which means that
// a timestamp is auto-generated when queueBuffer is called.
diff --git a/include/media/openmax/OMX_IVCommon.h b/include/media/openmax/OMX_IVCommon.h
index effbaae..24f91ce 100644
--- a/include/media/openmax/OMX_IVCommon.h
+++ b/include/media/openmax/OMX_IVCommon.h
@@ -160,6 +160,7 @@ typedef enum OMX_COLOR_FORMATTYPE {
OMX_TI_COLOR_FormatYUV420PackedSemiPlanar = 0x7F000100,
OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00,
OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7FA30C03,
+ OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m = 0x7FA30C04,
OMX_COLOR_FormatMax = 0x7FFFFFFF
} OMX_COLOR_FORMATTYPE;
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 1c84d0e..af85063 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -72,6 +72,12 @@ public:
GraphicBuffer();
+#ifdef QCOM_BSP
+ // creates buffer of bufferSize
+ GraphicBuffer(uint32_t w, uint32_t h,
+ PixelFormat format, uint32_t usage, uint32_t bufferSize);
+#endif
+
// creates w * h buffer
GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage);
@@ -97,6 +103,10 @@ public:
status_t lock(uint32_t usage, void** vaddr);
status_t lock(uint32_t usage, const Rect& rect, void** vaddr);
status_t unlock();
+#ifdef QCOM_BSP
+ status_t perform(buffer_handle_t hnd, int operation,
+ uint32_t w, uint32_t h, PixelFormat format);
+#endif
ANativeWindowBuffer* getNativeBuffer() const;
@@ -133,9 +143,12 @@ private:
GraphicBuffer& operator = (const GraphicBuffer& rhs);
const GraphicBuffer& operator = (const GraphicBuffer& rhs) const;
- status_t initSize(uint32_t w, uint32_t h, PixelFormat format,
+ status_t initSize(uint32_t w, uint32_t h, PixelFormat format,
uint32_t usage);
-
+#ifdef QCOM_BSP
+ status_t initSize(uint32_t w, uint32_t h, PixelFormat format,
+ uint32_t usage, uint32_t bufferSize);
+#endif
void free_handle();
// Flattenable interface
diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index 0f2a492..a4d5b8c 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -68,6 +68,11 @@ public:
status_t alloc(uint32_t w, uint32_t h, PixelFormat format, int usage,
buffer_handle_t* handle, int32_t* stride);
+#ifdef QCOM_BSP
+ status_t alloc(uint32_t w, uint32_t h, PixelFormat format, int usage,
+ buffer_handle_t* handle, int32_t* stride, uint32_t bufferSize);
+#endif
+
status_t free(buffer_handle_t handle);
void dump(String8& res) const;
@@ -87,6 +92,7 @@ private:
static KeyedVector<buffer_handle_t, alloc_rec_t> sAllocList;
friend class Singleton<GraphicBufferAllocator>;
+ friend class BufferLiberatorThread;
GraphicBufferAllocator();
~GraphicBufferAllocator();
diff --git a/include/ui/GraphicBufferMapper.h b/include/ui/GraphicBufferMapper.h
index 1fdecab..858fb1b 100644
--- a/include/ui/GraphicBufferMapper.h
+++ b/include/ui/GraphicBufferMapper.h
@@ -51,6 +51,11 @@ public:
status_t getphys(buffer_handle_t handle, void** paddr);
#endif
+#ifdef QCOM_BSP
+ status_t perform(buffer_handle_t handle, int operation,
+ uint32_t w, uint32_t h, uint32_t format);
+#endif
+
// dumps information about the mapping of this handle
void dump(buffer_handle_t handle);
diff --git a/include/utils/Trace.h b/include/utils/Trace.h
index 93e2285..41bce00 100644
--- a/include/utils/Trace.h
+++ b/include/utils/Trace.h
@@ -54,6 +54,8 @@
#define ATRACE_TAG_CAMERA (1<<10)
#define ATRACE_TAG_LAST ATRACE_TAG_CAMERA
+#define ATRACE_TAG_NOT_READY (1LL<<63) // Reserved for use during init
+
#define ATRACE_TAG_VALID_MASK ((ATRACE_TAG_LAST - 1) | ATRACE_TAG_LAST)
#ifndef ATRACE_TAG
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index d970a33..084ea0d 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -54,9 +54,11 @@ ifneq ($(filter generic%,$(TARGET_DEVICE)),)
LOCAL_CFLAGS += -DUSE_FENCE_SYNC
endif
-ifeq ($(TARGET_BOARD_PLATFORM), msm8960)
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+ifneq ($(TARGET_QCOM_DISPLAY_VARIANT),legacy)
LOCAL_CFLAGS += -DUSE_NATIVE_FENCE_SYNC
endif
+endif
include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 590946a..acf6cec 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -64,6 +64,70 @@ static const char* scalingModeName(int scalingMode) {
}
}
+#ifdef QCOM_BSP
+/*
+ * Checks if memory needs to be reallocated for this buffer.
+ *
+ * @param: Geometry of the current buffer.
+ * @param: Required Geometry.
+ * @param: Geometry of the updated buffer.
+ *
+ * @return True if a memory reallocation is required.
+ */
+static bool needNewBuffer(const QBufGeometry currentGeometry,
+ const QBufGeometry requiredGeometry,
+ const QBufGeometry updatedGeometry)
+{
+ // no allocation required if there is change in resoultion or format.
+ if (updatedGeometry.mWidth && updatedGeometry.mHeight &&
+ updatedGeometry.mFormat) {
+ return false;
+ }
+ // If the current buffer info matches the updated info,
+ // we do not require any memory allocation.
+ if (currentGeometry.mWidth != requiredGeometry.mWidth ||
+ currentGeometry.mHeight != requiredGeometry.mHeight ||
+ currentGeometry.mFormat != requiredGeometry.mFormat) {
+ // Current and required geometry do not match. Allocation
+ // required.
+ return true;
+ }
+ return false;
+}
+
+/*
+ * Geometry update for the currently queued buffer is required or not.
+ *
+ * @param: buffer currently queued buffer.
+ * @param: Updated width
+ * @param: Updated height
+ * @param: Updated format
+ *
+ * @return True if a buffer needs to be updated with new attributes.
+ */
+static bool isBufferGeometryUpdateRequired(sp<GraphicBuffer> buffer,
+ const QBufGeometry updatedGeometry)
+{
+ if (buffer == 0) {
+ ALOGW("isBufferGeometryUpdateRequired: graphic buffer is NULL");
+ return false;
+ }
+
+ if (!updatedGeometry.mWidth || !updatedGeometry.mHeight ||
+ !updatedGeometry.mFormat) {
+ // No update required. Return.
+ return false;
+ }
+ if (buffer->width == updatedGeometry.mWidth &&
+ buffer->height == updatedGeometry.mHeight &&
+ buffer->format == updatedGeometry.mFormat) {
+ // The buffer has already been updated. Return.
+ return false;
+ }
+ return true;
+}
+#endif
+
BufferQueue::BufferQueue(bool allowSynchronousMode,
const sp<IGraphicBufferAlloc>& allocator) :
mDefaultWidth(1),
@@ -94,6 +158,9 @@ BufferQueue::BufferQueue(bool allowSynchronousMode,
} else {
mGraphicBufferAlloc = allocator;
}
+#ifdef QCOM_BSP
+ mNextBufferInfo.set(0, 0, 0);
+#endif
}
BufferQueue::~BufferQueue() {
@@ -195,6 +262,15 @@ status_t BufferQueue::setBufferCount(int bufferCount) {
return OK;
}
+#ifdef QCOM_BSP
+status_t BufferQueue::setBuffersSize(int size) {
+ ST_LOGV("setBuffersSize: size=%d", size);
+ Mutex::Autolock lock(mMutex);
+ mGraphicBufferAlloc->setGraphicBufferSize(size);
+ return NO_ERROR;
+}
+#endif
+
int BufferQueue::query(int what, int* outValue)
{
ATRACE_CALL();
@@ -314,9 +390,8 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence,
* the consumer may still have pending reads of the
* buffers in flight.
*/
- bool isOlder = mSlots[i].mFrameNumber <
- mSlots[found].mFrameNumber;
- if (found < 0 || isOlder) {
+ if ((found < 0) ||
+ mSlots[i].mFrameNumber < mSlots[found].mFrameNumber) {
found = i;
}
}
@@ -379,10 +454,29 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence,
mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
+#ifdef QCOM_BSP
+ QBufGeometry currentGeometry;
+ if (buffer != NULL)
+ currentGeometry.set(buffer->width, buffer->height, buffer->format);
+ else
+ currentGeometry.set(0, 0, 0);
+
+ QBufGeometry requiredGeometry;
+ requiredGeometry.set(w, h, format);
+
+ QBufGeometry updatedGeometry;
+ updatedGeometry.set(mNextBufferInfo.mWidth, mNextBufferInfo.mHeight,
+ mNextBufferInfo.mFormat);
+#endif
+
if ((buffer == NULL) ||
+#ifdef QCOM_BSP
+ needNewBuffer(currentGeometry, requiredGeometry, updatedGeometry) ||
+#else
(uint32_t(buffer->width) != w) ||
(uint32_t(buffer->height) != h) ||
(uint32_t(buffer->format) != format) ||
+#endif
((uint32_t(buffer->usage) & usage) != usage))
{
mSlots[buf].mAcquireCalled = false;
@@ -445,6 +539,15 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence,
return returnFlags;
}
+#ifdef QCOM_BSP
+status_t BufferQueue::updateBuffersGeometry(int w, int h, int f) {
+ ST_LOGV("updateBuffersGeometry: w=%d h=%d f=%d", w, h, f);
+ Mutex::Autolock lock(mMutex);
+ mNextBufferInfo.set(w, h, f);
+ return NO_ERROR;
+}
+#endif
+
status_t BufferQueue::setSynchronousMode(bool enabled) {
ATRACE_CALL();
ST_LOGV("setSynchronousMode: enabled=%d", enabled);
@@ -518,7 +621,31 @@ status_t BufferQueue::queueBuffer(int buf,
return -EINVAL;
}
+#ifdef QCOM_BSP
+ // Update the buffer Geometry if required
+ QBufGeometry updatedGeometry;
+ updatedGeometry.set(mNextBufferInfo.mWidth,
+ mNextBufferInfo.mHeight, mNextBufferInfo.mFormat);
+#endif
const sp<GraphicBuffer>& graphicBuffer(mSlots[buf].mGraphicBuffer);
+#ifdef QCOM_BSP
+ // Update the geometry of this buffer without reallocation.
+ if(isBufferGeometryUpdateRequired(graphicBuffer, updatedGeometry)) {
+ status_t res = graphicBuffer->perform(graphicBuffer->handle,
+ GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_GEOMETRY,
+ updatedGeometry.mWidth,
+ updatedGeometry.mHeight,
+ updatedGeometry.mFormat);
+ if(res == NO_ERROR) {
+ graphicBuffer->width = updatedGeometry.mWidth;
+ graphicBuffer->height = updatedGeometry.mHeight;
+ graphicBuffer->format = updatedGeometry.mFormat;
+ // set flags to destroy old eglImage and create new eglImage.
+ mSlots[buf].mAcquireCalled = false;
+ mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
+ }
+ }
+#endif
Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
Rect croppedCrop;
crop.intersect(bufferRect, &croppedCrop);
@@ -548,6 +675,8 @@ status_t BufferQueue::queueBuffer(int buf,
Fifo::iterator front(mQueue.begin());
// buffer currently queued is freed
mSlots[*front].mBufferState = BufferSlot::FREE;
+ // reset the frame number of the freed buffer
+ mSlots[*front].mFrameNumber = 0;
// and we record the new buffer index in the queued list
*front = buf;
}
@@ -681,6 +810,9 @@ status_t BufferQueue::disconnect(int api) {
if (mConnectedApi == api) {
drainQueueAndFreeBuffersLocked();
mConnectedApi = NO_CONNECTED_API;
+#ifdef QCOM_BSP
+ mNextBufferInfo.set(0, 0, 0);
+#endif
mDequeueCondition.broadcast();
listener = mConsumerListener;
} else {
diff --git a/libs/gui/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp
index 139f219..8afb509 100644
--- a/libs/gui/IGraphicBufferAlloc.cpp
+++ b/libs/gui/IGraphicBufferAlloc.cpp
@@ -32,6 +32,9 @@ namespace android {
enum {
CREATE_GRAPHIC_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
+#ifdef QCOM_BSP
+ SET_GRAPHIC_BUFFER_SIZE,
+#endif
};
class BpGraphicBufferAlloc : public BpInterface<IGraphicBufferAlloc>
@@ -63,6 +66,16 @@ public:
*error = result;
return graphicBuffer;
}
+
+#ifdef QCOM_BSP
+ virtual void setGraphicBufferSize(int size) {
+ Parcel data, reply;
+ data.writeInterfaceToken(
+ IGraphicBufferAlloc::getInterfaceDescriptor());
+ data.writeInt32(size);
+ remote()->transact(SET_GRAPHIC_BUFFER_SIZE, data, &reply);
+ }
+#endif
};
IMPLEMENT_META_INTERFACE(GraphicBufferAlloc, "android.ui.IGraphicBufferAlloc");
@@ -108,6 +121,14 @@ status_t BnGraphicBufferAlloc::onTransact(
}
return NO_ERROR;
} break;
+#ifdef QCOM_BSP
+ case SET_GRAPHIC_BUFFER_SIZE: {
+ CHECK_INTERFACE(IGraphicBufferAlloc, data, reply);
+ int size = data.readInt32();
+ setGraphicBufferSize(size);
+ return NO_ERROR;
+ } break;
+#endif
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/ISurfaceTexture.cpp b/libs/gui/ISurfaceTexture.cpp
index a0b1e74..ce31a5b 100644
--- a/libs/gui/ISurfaceTexture.cpp
+++ b/libs/gui/ISurfaceTexture.cpp
@@ -38,6 +38,10 @@ enum {
CANCEL_BUFFER,
QUERY,
SET_SYNCHRONOUS_MODE,
+#ifdef QCOM_BSP
+ UPDATE_BUFFERS_GEOMETRY,
+ SET_BUFFERS_SIZE,
+#endif
CONNECT,
DISCONNECT,
};
@@ -156,6 +160,35 @@ public:
return result;
}
+#ifdef QCOM_BSP
+ virtual status_t updateBuffersGeometry(int w, int h, int f) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
+ data.writeInt32(w);
+ data.writeInt32(h);
+ data.writeInt32(f);
+ status_t result = remote()->transact(UPDATE_BUFFERS_GEOMETRY,
+ data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ result = reply.readInt32();
+ return result;
+ }
+
+ virtual status_t setBuffersSize(int size) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
+ data.writeInt32(size);
+ status_t result = remote()->transact(SET_BUFFERS_SIZE, data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ result = reply.readInt32();
+ return result;
+ }
+#endif
+
virtual status_t connect(int api, QueueBufferOutput* output) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
@@ -266,6 +299,24 @@ status_t BnSurfaceTexture::onTransact(
reply->writeInt32(res);
return NO_ERROR;
} break;
+#ifdef QCOM_BSP
+ case UPDATE_BUFFERS_GEOMETRY: {
+ CHECK_INTERFACE(ISurfaceTexture, data, reply);
+ int w = data.readInt32();
+ int h = data.readInt32();
+ int f = data.readInt32();
+ status_t res = updateBuffersGeometry(w, h, f);
+ reply->writeInt32(res);
+ return NO_ERROR;
+ } break;
+ case SET_BUFFERS_SIZE: {
+ CHECK_INTERFACE(ISurfaceTexture, data, reply);
+ int size = data.readInt32();
+ status_t res = setBuffersSize(size);
+ reply->writeInt32(res);
+ return NO_ERROR;
+ } break;
+#endif
case CONNECT: {
CHECK_INTERFACE(ISurfaceTexture, data, reply);
int api = data.readInt32();
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 0301f72..e6b4b21 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -630,6 +630,26 @@ status_t SurfaceComposerClient::getDisplayInfo(
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()
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index afdbf04..5de963c 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -80,6 +80,9 @@ void SurfaceTextureClient::init() {
mReqHeight = 0;
mReqFormat = 0;
mReqUsage = 0;
+#ifdef QCOM_BSP
+ mReqSize = 0;
+#endif
mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
mCrop.clear();
mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
@@ -400,6 +403,14 @@ int SurfaceTextureClient::perform(int operation, va_list args)
case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
res = dispatchSetBuffersFormat(args);
break;
+#ifdef QCOM_BSP
+ case NATIVE_WINDOW_SET_BUFFERS_SIZE:
+ res = dispatchSetBuffersSize(args);
+ break;
+ case NATIVE_WINDOW_UPDATE_BUFFERS_GEOMETRY:
+ res = dispatchUpdateBuffersGeometry(args);
+ break;
+#endif
case NATIVE_WINDOW_LOCK:
res = dispatchLock(args);
break;
@@ -451,6 +462,7 @@ int SurfaceTextureClient::dispatchSetBuffersGeometry(va_list args) {
int w = va_arg(args, int);
int h = va_arg(args, int);
int f = va_arg(args, int);
+
int err = setBuffersDimensions(w, h);
if (err != 0) {
return err;
@@ -461,6 +473,7 @@ int SurfaceTextureClient::dispatchSetBuffersGeometry(va_list args) {
int SurfaceTextureClient::dispatchSetBuffersDimensions(va_list args) {
int w = va_arg(args, int);
int h = va_arg(args, int);
+
return setBuffersDimensions(w, h);
}
@@ -475,6 +488,20 @@ int SurfaceTextureClient::dispatchSetBuffersFormat(va_list args) {
return setBuffersFormat(f);
}
+#ifdef QCOM_BSP
+int SurfaceTextureClient::dispatchSetBuffersSize(va_list args) {
+ int size = va_arg(args, int);
+ return setBuffersSize(size);
+}
+
+int SurfaceTextureClient::dispatchUpdateBuffersGeometry(va_list args) {
+ int w = va_arg(args, int);
+ int h = va_arg(args, int);
+ int f = va_arg(args, int);
+ return updateBuffersGeometry(w, h, f);
+}
+#endif
+
int SurfaceTextureClient::dispatchSetScalingMode(va_list args) {
int m = va_arg(args, int);
return setScalingMode(m);
@@ -530,6 +557,9 @@ int SurfaceTextureClient::disconnect(int api) {
mReqWidth = 0;
mReqHeight = 0;
mReqUsage = 0;
+#ifdef QCOM_BSP
+ mReqSize = 0;
+#endif
mCrop.clear();
mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
mTransform = 0;
@@ -630,6 +660,40 @@ int SurfaceTextureClient::setBuffersFormat(int format)
return NO_ERROR;
}
+#ifdef QCOM_BSP
+int SurfaceTextureClient::setBuffersSize(int size)
+{
+ ATRACE_CALL();
+ ALOGV("SurfaceTextureClient::setBuffersSize");
+
+ if (size<0)
+ return BAD_VALUE;
+
+ Mutex::Autolock lock(mMutex);
+ if(mReqSize != (uint32_t)size) {
+ mReqSize = size;
+ return mSurfaceTexture->setBuffersSize(size);
+ }
+ return NO_ERROR;
+}
+
+int SurfaceTextureClient::updateBuffersGeometry(int w, int h, int f)
+{
+ ATRACE_CALL();
+ ALOGV("SurfaceTextureClient::updateBuffersGeometry");
+
+ if (w<0 || h<0 || f<0)
+ return BAD_VALUE;
+
+ if ((w && !h) || (!w && h))
+ return BAD_VALUE;
+
+ Mutex::Autolock lock(mMutex);
+ status_t err = mSurfaceTexture->updateBuffersGeometry(w, h, f);
+ return err;
+}
+#endif
+
int SurfaceTextureClient::setScalingMode(int mode)
{
ATRACE_CALL();
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index b9cab85..219375e 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -60,6 +60,22 @@ GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
mInitCheck = initSize(w, h, reqFormat, reqUsage);
}
+#ifdef QCOM_BSP
+GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
+ PixelFormat reqFormat, uint32_t reqUsage, uint32_t bufferSize)
+ : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
+ mInitCheck(NO_ERROR), mIndex(-1)
+{
+ width =
+ height =
+ stride =
+ format =
+ usage = 0;
+ handle = NULL;
+ mInitCheck = initSize(w, h, reqFormat, reqUsage, bufferSize);
+}
+#endif
+
GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
PixelFormat inFormat, uint32_t inUsage,
uint32_t inStride, native_handle_t* inHandle, bool keepOwnership)
@@ -154,6 +170,23 @@ status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format,
return err;
}
+#ifdef QCOM_BSP
+status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format,
+ uint32_t reqUsage, uint32_t bufferSize)
+{
+ GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
+ status_t err = allocator.alloc(w, h, format,
+ reqUsage, &handle, &stride, bufferSize);
+ if (err == NO_ERROR) {
+ this->width = w;
+ this->height = h;
+ this->format = format;
+ this->usage = reqUsage;
+ }
+ return err;
+}
+#endif
+
status_t GraphicBuffer::lock(uint32_t usage, void** vaddr)
{
const Rect lockBounds(width, height);
@@ -180,6 +213,16 @@ status_t GraphicBuffer::unlock()
return res;
}
+#ifdef QCOM_BSP
+status_t GraphicBuffer::perform(buffer_handle_t hnd, int operation,
+ uint32_t w, uint32_t h, PixelFormat format)
+{
+ status_t res = getBufferMapper().perform(hnd,
+ GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_GEOMETRY, w, h, format);
+ return res;
+}
+#endif
+
size_t GraphicBuffer::getFlattenedSize() const {
return (8 + (handle ? handle->numInts : 0))*sizeof(int);
}
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index c1b246f..470f58a 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -90,9 +90,119 @@ void GraphicBufferAllocator::dumpToSystemLog()
ALOGD("%s", s.string());
}
+class BufferLiberatorThread : public Thread {
+public:
+
+ static void queueCaptiveBuffer(buffer_handle_t handle) {
+ size_t queueSize;
+ {
+ Mutex::Autolock lock(sMutex);
+ if (sThread == NULL) {
+ sThread = new BufferLiberatorThread;
+ sThread->run("BufferLiberator");
+ }
+
+ sThread->mQueue.push_back(handle);
+ sThread->mQueuedCondition.signal();
+ queueSize = sThread->mQueue.size();
+ }
+ }
+
+ static void waitForLiberation() {
+ Mutex::Autolock lock(sMutex);
+
+ waitForLiberationLocked();
+ }
+
+ static void maybeWaitForLiberation() {
+ Mutex::Autolock lock(sMutex);
+ if (sThread != NULL) {
+ if (sThread->mQueue.size() > 8) {
+ waitForLiberationLocked();
+ }
+ }
+ }
+
+private:
+
+ BufferLiberatorThread() {}
+
+ virtual bool threadLoop() {
+ buffer_handle_t handle;
+ { // Scope for mutex
+ Mutex::Autolock lock(sMutex);
+ while (mQueue.isEmpty()) {
+ mQueuedCondition.wait(sMutex);
+ }
+ handle = mQueue[0];
+ }
+
+ status_t err;
+ GraphicBufferAllocator& gba(GraphicBufferAllocator::get());
+ { // Scope for tracing
+ ATRACE_NAME("gralloc::free");
+ err = gba.mAllocDev->free(gba.mAllocDev, handle);
+ }
+ ALOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err));
+
+ if (err == NO_ERROR) {
+ Mutex::Autolock _l(GraphicBufferAllocator::sLock);
+ KeyedVector<buffer_handle_t, GraphicBufferAllocator::alloc_rec_t>&
+ list(GraphicBufferAllocator::sAllocList);
+ list.removeItem(handle);
+ }
+
+ { // Scope for mutex
+ Mutex::Autolock lock(sMutex);
+ mQueue.removeAt(0);
+ mFreedCondition.broadcast();
+ }
+
+ return true;
+ }
+
+ static void waitForLiberationLocked() {
+ if (sThread == NULL) {
+ return;
+ }
+
+ const nsecs_t timeout = 500 * 1000 * 1000;
+ nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t timeToStop = now + timeout;
+ while (!sThread->mQueue.isEmpty() && now < timeToStop) {
+ sThread->mFreedCondition.waitRelative(sMutex, timeToStop - now);
+ now = systemTime(SYSTEM_TIME_MONOTONIC);
+ }
+
+ if (!sThread->mQueue.isEmpty()) {
+ ALOGW("waitForLiberationLocked timed out");
+ }
+ }
+
+ static Mutex sMutex;
+ static sp<BufferLiberatorThread> sThread;
+ Vector<buffer_handle_t> mQueue;
+ Condition mQueuedCondition;
+ Condition mFreedCondition;
+};
+
+Mutex BufferLiberatorThread::sMutex;
+sp<BufferLiberatorThread> BufferLiberatorThread::sThread;
+
status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format,
int usage, buffer_handle_t* handle, int32_t* stride)
{
+#ifdef QCOM_BSP
+ status_t err = alloc(w, h, format, usage, handle, stride, 0);
+ return err;
+}
+
+status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h,
+ PixelFormat format, int usage,
+ buffer_handle_t* handle,
+ int32_t* stride, uint32_t bufferSize)
+{
+#endif
ATRACE_CALL();
// make sure to not allocate a N x 0 or 0 x N buffer, since this is
// allowed from an API stand-point allocate a 1x1 buffer instead.
@@ -100,7 +210,6 @@ 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
- status_t err;
#ifdef EXYNOS4_ENHANCEMENTS
if ((format == 0x101) || (format == 0x105) || (format == 0x107)) {
@@ -111,11 +220,39 @@ status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat forma
}
#endif
+ status_t err;
+
+ // If too many async frees are queued up then wait for some of them to
+ // complete before attempting to allocate more memory. This is exercised
+ // by the android.opengl.cts.GLSurfaceViewTest CTS test.
+ BufferLiberatorThread::maybeWaitForLiberation();
+
+#ifdef QCOM_BSP
+ err = mAllocDev->allocSize(mAllocDev, w, h,
+ format, usage, handle, stride, bufferSize);
+#else
err = mAllocDev->alloc(mAllocDev, w, h, format, usage, handle, stride);
+#endif
+
+ if (err != NO_ERROR) {
+ ALOGW("WOW! gralloc alloc failed, waiting for pending frees!");
+ BufferLiberatorThread::waitForLiberation();
+#ifdef QCOM_BSP
+ err = mAllocDev->allocSize(mAllocDev, w, h,
+ format, usage, handle, stride, bufferSize);
+#else
+ err = mAllocDev->alloc(mAllocDev, w, h, format, usage, handle, stride);
+#endif
+ }
+#ifdef QCOM_BSP
+ ALOGW_IF(err, "alloc(%u, %u, %d, %08x, %d ...) failed %d (%s)",
+ w, h, format, usage, bufferSize, err, strerror(-err));
+#else
ALOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)",
w, h, format, usage, err, strerror(-err));
-
+#endif
+
if (err == NO_ERROR) {
Mutex::Autolock _l(sLock);
KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
@@ -138,21 +275,11 @@ status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat forma
return err;
}
+
status_t GraphicBufferAllocator::free(buffer_handle_t handle)
{
- ATRACE_CALL();
- status_t err;
-
- err = mAllocDev->free(mAllocDev, handle);
-
- ALOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err));
- if (err == NO_ERROR) {
- Mutex::Autolock _l(sLock);
- KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
- list.removeItem(handle);
- }
-
- return err;
+ BufferLiberatorThread::queueCaptiveBuffer(handle);
+ return NO_ERROR;
}
// ---------------------------------------------------------------------------
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 19c549d..d16a1bb 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -108,5 +108,18 @@ status_t GraphicBufferMapper::getphys(buffer_handle_t handle, void** paddr)
}
#endif
+#ifdef QCOM_BSP
+status_t GraphicBufferMapper::perform(buffer_handle_t handle, int operation,
+ uint32_t w, uint32_t h, uint32_t format)
+{
+ ATRACE_CALL();
+ status_t err;
+
+ err = mAllocMod->perform(mAllocMod, operation, w, h, format, handle);
+
+ ALOGW_IF(err, "perform(...) failed %d (%s)", err, strerror(-err));
+ return err;
+}
+#endif
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/libs/utils/Trace.cpp b/libs/utils/Trace.cpp
index 5cd5731..f5aaea3 100644
--- a/libs/utils/Trace.cpp
+++ b/libs/utils/Trace.cpp
@@ -25,7 +25,7 @@ namespace android {
volatile int32_t Tracer::sIsReady = 0;
int Tracer::sTraceFD = -1;
-uint64_t Tracer::sEnabledTags = 0;
+uint64_t Tracer::sEnabledTags = ATRACE_TAG_NOT_READY;
Mutex Tracer::sMutex;
void Tracer::changeCallback() {
@@ -46,7 +46,7 @@ void Tracer::init() {
sTraceFD = open(traceFileName, O_WRONLY);
if (sTraceFD == -1) {
ALOGE("error opening trace file: %s (%d)", strerror(errno), errno);
- // sEnabledTags remains zero indicating that no tracing can occur
+ sEnabledTags = 0; // no tracing can occur
} else {
loadSystemProperty();
}
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 96e1cba..0d4bed5 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -124,6 +124,12 @@ void initEglTraceLevel() {
void initEglDebugLevel() {
int propertyLevel = 0;
char value[PROPERTY_VALUE_MAX];
+
+ // check system property only on userdebug or eng builds
+ property_get("ro.debuggable", value, "0");
+ if (value[0] == '0')
+ return;
+
property_get("debug.egl.debug_proc", value, "");
if (strlen(value) > 0) {
long pid = getpid();
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 23e89da..ed1b472 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -760,8 +760,8 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso && cnx->egl.eglGetProcAddress) {
- found = true;
// Extensions are independent of the bound context
+ addr =
cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] =
cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] =
#if EGL_TRACE
@@ -769,10 +769,13 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
gHooksTrace.ext.extensions[slot] =
#endif
cnx->egl.eglGetProcAddress(procname);
+ if (addr) found = true;
}
if (found) {
+#if USE_FAST_TLS_KEY
addr = gExtensionForwarders[slot];
+#endif
sGLExtentionMap.add(name, addr);
sGLExtentionSlot++;
}
diff --git a/opengl/specs/EGL_ANDROID_native_fence_sync.txt b/opengl/specs/EGL_ANDROID_native_fence_sync.txt
index 8273be4..ee05b40 100644
--- a/opengl/specs/EGL_ANDROID_native_fence_sync.txt
+++ b/opengl/specs/EGL_ANDROID_native_fence_sync.txt
@@ -100,10 +100,10 @@ Changes to Chapter 3 of the EGL 1.2 Specification (EGL Functions and Errors)
EGL_SYNC_TYPE_KHR EGL_SYNC_NATIVE_FENCE_ANDROID
EGL_SYNC_STATUS_KHR EGL_UNSIGNALED_KHR
EGL_SYNC_CONDITION_KHR EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR
- EGL_SYNC_NATIVE_FENCE_FD_ANDROID EGL_NO_NATIVE_FENCE_ANDROID
+ EGL_SYNC_NATIVE_FENCE_FD_ANDROID EGL_NO_NATIVE_FENCE_FD_ANDROID
If the EGL_SYNC_NATIVE_FENCE_FD_ANDROID attribute is not
- EGL_NO_NATIVE_FENCE_ANDROID then the EGL_SYNC_CONDITION_KHR attribute is
+ EGL_NO_NATIVE_FENCE_FD_ANDROID then the EGL_SYNC_CONDITION_KHR attribute is
set to EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID and the EGL_SYNC_STATUS_KHR
attribute is set to reflect the signal status of the native fence object.
Additionally, the EGL implementation assumes ownership of the file
@@ -114,7 +114,7 @@ Changes to Chapter 3 of the EGL 1.2 Specification (EGL Functions and Errors)
"When a fence sync object is created or when an EGL native fence sync
object is created with the EGL_SYNC_NATIVE_FENCE_FD_ANDROID attribute set
- to EGL_NO_NATIVE_FENCE_ANDROID, eglCreateSyncKHR also inserts a fence
+ to EGL_NO_NATIVE_FENCE_FD_ANDROID, eglCreateSyncKHR also inserts a fence
command into the command stream of the bound client API's current context
(i.e., the context returned by eglGetCurrentContext), and associates it
with the newly created sync object.
@@ -157,8 +157,9 @@ Changes to Chapter 3 of the EGL 1.2 Specification (EGL Functions and Errors)
empty (containing only EGL_NONE), EGL_NO_SYNC_KHR is returned and an
EGL_BAD_ATTRIBUTE error is generated.
* If <type> is EGL_SYNC_NATIVE_FENCE_ANDROID and <attrib_list> contains
- an attribute other than EGL_SYNC_NATIVE_FENCE_FD_ANDROID, EGL_NO_SYNC_KHR is
- returned and an EGL_BAD_ATTRIBUTE error is generated.
+ an attribute other than EGL_SYNC_NATIVE_FENCE_FD_ANDROID,
+ EGL_NO_SYNC_KHR is returned and an EGL_BAD_ATTRIBUTE error is
+ generated.
* If <type> is not a supported type of sync object,
EGL_NO_SYNC_KHR is returned and an EGL_BAD_ATTRIBUTE error is
generated.
@@ -193,8 +194,8 @@ Changes to Chapter 3 of the EGL 1.2 Specification (EGL Functions and Errors)
"If no errors are generated, EGL_TRUE is returned, and <sync> will no
longer be the handle of a valid sync object. Additionally, if <sync> is an
EGL native fence sync object and the EGL_SYNC_NATIVE_FENCE_FD_ANDROID
- attribute is not EGL_NO_NATIVE_FENCE_ANDROID then that file descriptor is
- closed."
+ attribute is not EGL_NO_NATIVE_FENCE_FD_ANDROID then that file descriptor
+ is closed."
Add the following after the last paragraph of Section 3.8.1 (Sync
Objects), added by KHR_fence_sync
@@ -213,11 +214,11 @@ Changes to Chapter 3 of the EGL 1.2 Specification (EGL Functions and Errors)
------
* If <sync> is not a valid sync object for <dpy>,
- EGL_NO_NATIVE_FENCE_ANDROID is returned and an EGL_BAD_PARAMETER
+ EGL_NO_NATIVE_FENCE_FD_ANDROID is returned and an EGL_BAD_PARAMETER
error is generated.
* If the EGL_SYNC_NATIVE_FENCE_FD_ANDROID attribute of <sync> is
- EGL_NO_NATIVE_FENCE_ANDROID, EGL_NO_NATIVE_FENCE_ANDROID is returned
- and an EGL_BAD_PARAMETER error is generated.
+ EGL_NO_NATIVE_FENCE_FD_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID is
+ returned and an EGL_BAD_PARAMETER error is generated.
* If <dpy> does not match the display passed to eglCreateSyncKHR
when <sync> was created, the behaviour is undefined."
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index dac8467..b3fa5fb 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -23,9 +23,6 @@ LOCAL_SRC_FILES:= \
LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
-ifeq ($(TARGET_BOARD_PLATFORM),omap3)
- LOCAL_CFLAGS += -DNO_RGBX_8888
-endif
ifeq ($(TARGET_BOARD_PLATFORM),omap4)
LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY
endif
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 395402d..a6b51a9 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -80,6 +80,7 @@ DisplayDevice::DisplayDevice(
EGLConfig config)
: mFlinger(flinger),
mType(type), mHwcDisplayId(-1),
+ mDisplayToken(displayToken),
mNativeWindow(nativeWindow),
mFramebufferSurface(framebufferSurface),
mDisplay(EGL_NO_DISPLAY),
diff --git a/services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.cpp b/services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.cpp
index 965ff01..0c94c7d 100644
--- a/services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.cpp
+++ b/services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.cpp
@@ -26,6 +26,9 @@ namespace android {
// ----------------------------------------------------------------------------
GraphicBufferAlloc::GraphicBufferAlloc() {
+#ifdef QCOM_BSP
+ mBufferSize = 0;
+#endif
}
GraphicBufferAlloc::~GraphicBufferAlloc() {
@@ -33,7 +36,13 @@ GraphicBufferAlloc::~GraphicBufferAlloc() {
sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
PixelFormat format, uint32_t usage, status_t* error) {
+#ifdef QCOM_BSP
+ sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format,
+ usage, mBufferSize));
+#else
sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
+#endif
+
status_t err = graphicBuffer->initCheck();
*error = err;
if (err != 0 || graphicBuffer->handle == 0) {
@@ -48,6 +57,12 @@ sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h
return graphicBuffer;
}
+#ifdef QCOM_BSP
+void GraphicBufferAlloc::setGraphicBufferSize(int size) {
+ mBufferSize = size;
+}
+#endif
+
// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------
diff --git a/services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.h b/services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.h
index b08750c..521383d 100644
--- a/services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.h
+++ b/services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.h
@@ -35,6 +35,11 @@ public:
virtual ~GraphicBufferAlloc();
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
PixelFormat format, uint32_t usage, status_t* error);
+#ifdef QCOM_BSP
+ virtual void setGraphicBufferSize(int size);
+private:
+ int mBufferSize;
+#endif
};
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 379fb16..9b4f2ab 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -776,11 +776,6 @@ 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;
}
@@ -1000,6 +995,9 @@ public:
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;
@@ -1073,7 +1071,9 @@ public:
virtual void setAcquireFenceFd(int fenceFd) {
getLayer()->acquireFenceFd = fenceFd;
}
-
+ virtual void setPerFrameDefaultState() {
+ //getLayer()->compositionType = HWC_FRAMEBUFFER;
+ }
virtual void setDefaultState() {
getLayer()->compositionType = HWC_FRAMEBUFFER;
getLayer()->hints = 0;
@@ -1237,7 +1237,6 @@ 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;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index a78ffac..7c67407 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -141,6 +141,7 @@ public:
virtual int32_t getCompositionType() const = 0;
virtual uint32_t getHints() const = 0;
virtual int getAndResetReleaseFenceFd() = 0;
+ virtual void setPerFrameDefaultState() = 0;
virtual void setDefaultState() = 0;
virtual void setSkip(bool skip) = 0;
virtual void setBlending(uint32_t blending) = 0;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 064f689..c1561b2 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -63,6 +63,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client)
mFormat(PIXEL_FORMAT_NONE),
mGLExtensions(GLExtensions::getInstance()),
mOpaqueLayer(true),
+ mNeedsDithering(false),
mSecure(false),
mProtectedByApp(false)
{
@@ -110,7 +111,8 @@ void Layer::onFirstRef()
mSurfaceTexture->setDefaultMaxBufferCount(3);
#endif
- updateTransformHint();
+ const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
+ updateTransformHint(hw);
}
Layer::~Layer()
@@ -193,6 +195,23 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,
mSurfaceTexture->setDefaultBufferFormat(format);
mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
+ int displayMinColorDepth;
+ int layerRedsize;
+ switch (mFlinger->getUseDithering()) {
+ case 0:
+ mNeedsDithering = false;
+ break;
+ case 1:
+ displayMinColorDepth = mFlinger->getMinColorDepth();
+ // we use the red index
+ layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
+ mNeedsDithering = (layerRedsize > displayMinColorDepth);
+ break;
+ case 2:
+ mNeedsDithering = true;
+ break;
+ }
+
return NO_ERROR;
}
@@ -767,15 +786,12 @@ uint32_t Layer::getEffectiveUsage(uint32_t usage) const
return usage;
}
-void Layer::updateTransformHint() const {
+void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
uint32_t orientation = 0;
if (!mFlinger->mDebugDisableTransformHint) {
- // The transform hint is used to improve performance on the main
- // display -- we can only have a single transform hint, it cannot
+ // The transform hint is used to improve performance, but we can
+ // only have a single transform hint, it cannot
// apply to all displays.
- // This is why we use the default display here. This is not an
- // oversight.
- sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
const Transform& planeTransform(hw->getTransform());
orientation = planeTransform.getOrientation();
if (orientation & Transform::ROT_INVALID) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 6f75d8c..a3d6ab9 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -77,6 +77,7 @@ public:
virtual uint32_t doTransaction(uint32_t transactionFlags);
virtual Region latchBuffer(bool& recomputeVisibleRegions);
virtual bool isOpaque() const;
+ virtual bool needsDithering() const { return mNeedsDithering; }
virtual bool isSecure() const { return mSecure; }
virtual bool isProtected() const;
virtual void onRemoved();
@@ -91,8 +92,8 @@ public:
inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
// Updates the transform hint in our SurfaceTexture to match
- // the current orientation of the default display device.
- virtual void updateTransformHint() const;
+ // the current orientation of the display device.
+ virtual void updateTransformHint(const sp<const DisplayDevice>& hw) const;
protected:
virtual void onFirstRef();
@@ -142,6 +143,7 @@ private:
PixelFormat mFormat;
const GLExtensions& mGLExtensions;
bool mOpaqueLayer;
+ bool mNeedsDithering;
// page-flip thread (currently main thread)
bool mSecure; // no screenshots
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index db4ef87..612e47b 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -300,6 +300,7 @@ void LayerBase::setGeometry(
void LayerBase::setPerFrameData(const sp<const DisplayDevice>& hw,
HWComposer::HWCLayerInterface& layer) {
+ layer.setPerFrameDefaultState();
// we have to set the visible region on every frame because
// we currently free it during onLayerDisplayed(), which is called
// after HWComposer::commit() -- every frame.
@@ -353,6 +354,7 @@ void LayerBase::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region&
glDisable(GL_TEXTURE_EXTERNAL_OES);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
+ glDisable(GL_DITHER);
LayerMesh mesh;
computeGeometry(hw, &mesh);
@@ -427,6 +429,12 @@ void LayerBase::drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region&
texCoords[i].v = 1.0f - texCoords[i].v;
}
+ if (needsDithering()) {
+ glEnable(GL_DITHER);
+ } else {
+ glDisable(GL_DITHER);
+ }
+
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 00c4ffe..4d5a5b0 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -246,7 +246,7 @@ public:
* Updates the SurfaceTexture's transform hint, for layers that have
* a SurfaceTexture.
*/
- virtual void updateTransformHint() const { }
+ virtual void updateTransformHint(const sp<const DisplayDevice>& hw) const { }
/** always call base class first */
virtual void dump(String8& result, char* scratch, size_t size) const;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 67b1316..1842949 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -104,7 +104,8 @@ SurfaceFlinger::SurfaceFlinger()
mLastSwapBufferTime(0),
mDebugInTransaction(0),
mLastTransactionTime(0),
- mBootFinished(false)
+ mBootFinished(false),
+ mUseDithering(0)
{
ALOGI("SurfaceFlinger is starting");
@@ -122,8 +123,13 @@ SurfaceFlinger::SurfaceFlinger()
mDebugDDMS = 0;
}
}
+
+ property_get("persist.sys.use_dithering", value, "1");
+ mUseDithering = atoi(value);
+
ALOGI_IF(mDebugRegion, "showupdates enabled");
ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
+ ALOGI_IF(mUseDithering, "use dithering");
#ifdef SAMSUNG_HDMI_SUPPORT
ALOGD(">>> Run service");
@@ -429,7 +435,11 @@ void SurfaceFlinger::initializeGL(EGLDisplay display) {
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glEnableClientState(GL_VERTEX_ARRAY);
glShadeModel(GL_FLAT);
- glDisable(GL_DITHER);
+ if (mUseDithering == 2) {
+ glEnable(GL_DITHER);
+ } else {
+ glDisable(GL_DITHER);
+ }
glDisable(GL_CULL_FACE);
struct pack565 {
@@ -467,6 +477,9 @@ void SurfaceFlinger::initializeGL(EGLDisplay display) {
ALOGI("extensions: %s", extensions.getExtension());
ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
+
+ // XXX Assume bit depth for red is equal to minimum depth of all colors
+ mMinColorDepth = r;
}
status_t SurfaceFlinger::readyToRun()
@@ -564,6 +577,10 @@ uint32_t SurfaceFlinger::getMaxTextureSize() const {
return mMaxTextureSize;
}
+uint32_t SurfaceFlinger::getMinColorDepth() const {
+ return mMinColorDepth;
+}
+
uint32_t SurfaceFlinger::getMaxViewportDims() const {
return mMaxViewportDims[0] < mMaxViewportDims[1] ?
mMaxViewportDims[0] : mMaxViewportDims[1];
@@ -1092,7 +1109,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
if (transactionFlags & eTraversalNeeded) {
for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer = currentLayers[i];
+ const sp<LayerBase>& layer(currentLayers[i]);
uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
if (!trFlags) continue;
@@ -1165,18 +1182,6 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
disp->setProjection(state.orientation,
state.viewport, state.frame);
}
-
- // Walk through all the layers in currentLayers,
- // and update their transform hint.
- //
- // TODO: we could be much more clever about which
- // layers we touch and how often we do these updates
- // (e.g. only touch the layers associated with this
- // display, and only on a rotation).
- for (size_t i = 0; i < count; i++) {
- const sp<LayerBase>& layerBase = currentLayers[i];
- layerBase->updateTransformHint();
- }
}
}
}
@@ -1231,6 +1236,61 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
}
}
+ if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
+ // The transform hint might have changed for some layers
+ // (either because a display has changed, or because a layer
+ // as changed).
+ //
+ // Walk through all the layers in currentLayers,
+ // and update their transform hint.
+ //
+ // If a layer is visible only on a single display, then that
+ // display is used to calculate the hint, otherwise we use the
+ // default display.
+ //
+ // NOTE: we do this here, rather than in rebuildLayerStacks() so that
+ // the hint is set before we acquire a buffer from the surface texture.
+ //
+ // NOTE: layer transactions have taken place already, so we use their
+ // drawing state. However, SurfaceFlinger's own transaction has not
+ // happened yet, so we must use the current state layer list
+ // (soon to become the drawing state list).
+ //
+ sp<const DisplayDevice> disp;
+ uint32_t currentlayerStack = 0;
+ for (size_t i=0; i<count; i++) {
+ // NOTE: we rely on the fact that layers are sorted by
+ // layerStack first (so we don't have to traverse the list
+ // of displays for every layer).
+ const sp<LayerBase>& layerBase(currentLayers[i]);
+ uint32_t layerStack = layerBase->drawingState().layerStack;
+ if (i==0 || currentlayerStack != layerStack) {
+ currentlayerStack = layerStack;
+ // figure out if this layerstack is mirrored
+ // (more than one display) if so, pick the default display,
+ // if not, pick the only display it's on.
+ disp.clear();
+ for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
+ sp<const DisplayDevice> hw(mDisplays[dpy]);
+ if (hw->getLayerStack() == currentlayerStack) {
+ if (disp == NULL) {
+ disp = hw;
+ } else {
+ disp = getDefaultDisplayDevice();
+ break;
+ }
+ }
+ }
+ }
+ if (disp != NULL) {
+ // presumably this means this layer is using a layerStack
+ // that is not visible on any display
+ layerBase->updateTransformHint(disp);
+ }
+ }
+ }
+
+
/*
* Perform our own transaction if needed
*/
@@ -1576,9 +1636,6 @@ 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 e8c4b9c..050d10f 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -324,8 +324,12 @@ private:
static EGLContext createGLContext(EGLDisplay disp, EGLConfig config);
void initializeGL(EGLDisplay display);
uint32_t getMaxTextureSize() const;
+ uint32_t getMinColorDepth() const;
uint32_t getMaxViewportDims() const;
+ // 0: surface doesn't need dithering, 1: use if necessary, 2: use permanently
+ inline int getUseDithering() const { return mUseDithering; }
+
/* ------------------------------------------------------------------------
* Display and layer stack management
*/
@@ -423,6 +427,7 @@ private:
sp<EventThread> mEventThread;
GLint mMaxViewportDims[2];
GLint mMaxTextureSize;
+ GLint mMinColorDepth;
EGLContext mEGLContext;
EGLConfig mEGLConfig;
EGLDisplay mEGLDisplay;
@@ -448,6 +453,7 @@ private:
volatile nsecs_t mDebugInTransaction;
nsecs_t mLastTransactionTime;
bool mBootFinished;
+ int mUseDithering;
// these are thread safe
mutable MessageQueue mEventQueue;