From b3a9e6d04da503026b33a66f276a7753dcc11a3b Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Thu, 11 Feb 2016 18:01:49 -0800 Subject: [PATCH 01/49] BQ: Add permission check to BufferQueueConsumer::dump Bug 27046057 Change-Id: Id7bd8cf95045b497943ea39dde49e877aa6f5c4e --- libs/gui/BufferQueueConsumer.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp index bb3e1b0a4..158eeb495 100644 --- a/libs/gui/BufferQueueConsumer.cpp +++ b/libs/gui/BufferQueueConsumer.cpp @@ -26,6 +26,10 @@ #include #include +#include +#include +#include + namespace android { BufferQueueConsumer::BufferQueueConsumer(const sp& core) : @@ -572,7 +576,17 @@ sp BufferQueueConsumer::getSidebandStream() const { } void BufferQueueConsumer::dump(String8& result, const char* prefix) const { - mCore->dump(result, prefix); + const IPCThreadState* ipc = IPCThreadState::self(); + const pid_t pid = ipc->getCallingPid(); + const uid_t uid = ipc->getCallingUid(); + if ((uid != AID_SHELL) + && !PermissionCache::checkPermission(String16( + "android.permission.DUMP"), pid, uid)) { + result.appendFormat("Permission Denial: can't dump BufferQueueConsumer " + "from pid=%d, uid=%d\n", pid, uid); + } else { + mCore->dump(result, prefix); + } } } // namespace android From 25719f6e1f7e892df17b6f7eb4d6fc8c1fcc35f3 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Fri, 5 Feb 2016 19:02:56 -0800 Subject: [PATCH 02/49] Sanity check IMemory access versus underlying mmap Bug 26877992 Change-Id: Ibbf4b1061e4675e4e96bc944a865b53eaf6984fe --- libs/binder/IMemory.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp index e9891a830..fb8d620b4 100644 --- a/libs/binder/IMemory.cpp +++ b/libs/binder/IMemory.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -187,15 +188,26 @@ sp BpMemory::getMemory(ssize_t* offset, size_t* size) const if (heap != 0) { mHeap = interface_cast(heap); if (mHeap != 0) { - mOffset = o; - mSize = s; + size_t heapSize = mHeap->getSize(); + if (s <= heapSize + && o >= 0 + && (static_cast(o) <= heapSize - s)) { + mOffset = o; + mSize = s; + } else { + // Hm. + android_errorWriteWithInfoLog(0x534e4554, + "26877992", -1, NULL, 0); + mOffset = 0; + mSize = 0; + } } } } } if (offset) *offset = mOffset; if (size) *size = mSize; - return mHeap; + return (mSize > 0) ? mHeap : 0; } // --------------------------------------------------------------------------- From 5243afa8fa719e3cc6d1af4333986b2d7ee5e737 Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Sat, 20 Feb 2016 11:26:13 -0800 Subject: [PATCH 03/49] Add SN logging Bug 27046057 Change-Id: Iede7c92e59e60795df1ec7768ebafd6b090f1c27 --- libs/gui/BufferQueueConsumer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp index 158eeb495..7504ed49b 100644 --- a/libs/gui/BufferQueueConsumer.cpp +++ b/libs/gui/BufferQueueConsumer.cpp @@ -584,6 +584,7 @@ void BufferQueueConsumer::dump(String8& result, const char* prefix) const { "android.permission.DUMP"), pid, uid)) { result.appendFormat("Permission Denial: can't dump BufferQueueConsumer " "from pid=%d, uid=%d\n", pid, uid); + android_errorWriteWithInfoLog(0x534e4554, "27046057", uid, NULL, 0); } else { mCore->dump(result, prefix); } From 28a83d4206e97c149a72408bc76c6487f57ed1b4 Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Thu, 11 Feb 2016 18:01:49 -0800 Subject: [PATCH 04/49] BQ: Add permission check to BufferQueueConsumer::dump Bug 27046057 Change-Id: Id7bd8cf95045b497943ea39dde49e877aa6f5c4e --- libs/gui/BufferQueueConsumer.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp index bb3e1b0a4..158eeb495 100644 --- a/libs/gui/BufferQueueConsumer.cpp +++ b/libs/gui/BufferQueueConsumer.cpp @@ -26,6 +26,10 @@ #include #include +#include +#include +#include + namespace android { BufferQueueConsumer::BufferQueueConsumer(const sp& core) : @@ -572,7 +576,17 @@ sp BufferQueueConsumer::getSidebandStream() const { } void BufferQueueConsumer::dump(String8& result, const char* prefix) const { - mCore->dump(result, prefix); + const IPCThreadState* ipc = IPCThreadState::self(); + const pid_t pid = ipc->getCallingPid(); + const uid_t uid = ipc->getCallingUid(); + if ((uid != AID_SHELL) + && !PermissionCache::checkPermission(String16( + "android.permission.DUMP"), pid, uid)) { + result.appendFormat("Permission Denial: can't dump BufferQueueConsumer " + "from pid=%d, uid=%d\n", pid, uid); + } else { + mCore->dump(result, prefix); + } } } // namespace android From a5d2913b0744054cacf3cbf66bd629fdc8105e07 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Fri, 5 Feb 2016 19:02:56 -0800 Subject: [PATCH 05/49] Sanity check IMemory access versus underlying mmap Bug 26877992 Change-Id: Ibbf4b1061e4675e4e96bc944a865b53eaf6984fe --- libs/binder/IMemory.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp index e9891a830..fb8d620b4 100644 --- a/libs/binder/IMemory.cpp +++ b/libs/binder/IMemory.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -187,15 +188,26 @@ sp BpMemory::getMemory(ssize_t* offset, size_t* size) const if (heap != 0) { mHeap = interface_cast(heap); if (mHeap != 0) { - mOffset = o; - mSize = s; + size_t heapSize = mHeap->getSize(); + if (s <= heapSize + && o >= 0 + && (static_cast(o) <= heapSize - s)) { + mOffset = o; + mSize = s; + } else { + // Hm. + android_errorWriteWithInfoLog(0x534e4554, + "26877992", -1, NULL, 0); + mOffset = 0; + mSize = 0; + } } } } } if (offset) *offset = mOffset; if (size) *size = mSize; - return mHeap; + return (mSize > 0) ? mHeap : 0; } // --------------------------------------------------------------------------- From a93a31018795eab0b031ebc66475f46a79b7c7ab Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Sat, 20 Feb 2016 11:26:13 -0800 Subject: [PATCH 06/49] Add SN logging Bug 27046057 Change-Id: Iede7c92e59e60795df1ec7768ebafd6b090f1c27 --- libs/gui/BufferQueueConsumer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp index 158eeb495..7504ed49b 100644 --- a/libs/gui/BufferQueueConsumer.cpp +++ b/libs/gui/BufferQueueConsumer.cpp @@ -584,6 +584,7 @@ void BufferQueueConsumer::dump(String8& result, const char* prefix) const { "android.permission.DUMP"), pid, uid)) { result.appendFormat("Permission Denial: can't dump BufferQueueConsumer " "from pid=%d, uid=%d\n", pid, uid); + android_errorWriteWithInfoLog(0x534e4554, "27046057", uid, NULL, 0); } else { mCore->dump(result, prefix); } From a30d7d90c4f718e46fb41a99b3d52800e1011b73 Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Tue, 15 Mar 2016 18:10:49 -0700 Subject: [PATCH 07/49] BQ: fix some uninitialized variables Bug 27555981 Bug 27556038 Change-Id: I436b6fec589677d7e36c0e980f6e59808415dc0e --- libs/gui/IGraphicBufferConsumer.cpp | 2 +- libs/gui/IGraphicBufferProducer.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp index c4660bad8..7ae82e056 100644 --- a/libs/gui/IGraphicBufferConsumer.cpp +++ b/libs/gui/IGraphicBufferConsumer.cpp @@ -349,7 +349,7 @@ status_t BnGraphicBufferConsumer::onTransact( } case GET_RELEASED_BUFFERS: { CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); - uint64_t slotMask; + uint64_t slotMask = 0; status_t result = getReleasedBuffers(&slotMask); reply->writeInt64(static_cast(slotMask)); reply->writeInt32(result); diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 1099c84f8..c3c62358f 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -435,6 +435,7 @@ status_t BnGraphicBufferProducer::onTransact( QueueBufferOutput* const output = reinterpret_cast( reply->writeInplace(sizeof(QueueBufferOutput))); + memset(output, 0, sizeof(QueueBufferOutput)); status_t res = connect(listener, api, producerControlledByApp, output); reply->writeInt32(res); return NO_ERROR; From a59b827869a2ea04022dd225007f29af8d61837a Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Mon, 21 Mar 2016 10:36:54 -0700 Subject: [PATCH 08/49] Fix issue #27252896: Security Vulnerability -- weak binder Sending transaction to freed BBinder through weak handle can cause use of a (mostly) freed object. We need to try to safely promote to a strong reference first. Change-Id: Ic9c6940fa824980472e94ed2dfeca52a6b0fd342 (cherry picked from commit c11146106f94e07016e8e26e4f8628f9a0c73199) --- libs/binder/IPCThreadState.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index ef88181d6..af18e119a 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -1083,8 +1083,16 @@ status_t IPCThreadState::executeCommand(int32_t cmd) << reinterpret_cast(tr.data.ptr.offsets) << endl; } if (tr.target.ptr) { - sp b((BBinder*)tr.cookie); - error = b->transact(tr.code, buffer, &reply, tr.flags); + // We only have a weak reference on the target object, so we must first try to + // safely acquire a strong reference before doing anything else with it. + if (reinterpret_cast( + tr.target.ptr)->attemptIncStrong(this)) { + error = reinterpret_cast(tr.cookie)->transact(tr.code, buffer, + &reply, tr.flags); + reinterpret_cast(tr.cookie)->decStrong(this); + } else { + error = UNKNOWN_TRANSACTION; + } } else { error = the_context_object->transact(tr.code, buffer, &reply, tr.flags); From 2b4df0ba7c6094da732cfd754d64241df2c153d2 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Tue, 12 Apr 2016 13:14:26 -0700 Subject: [PATCH 09/49] surfaceflinger: Add support for secondary color matrix * Add a new binder transaction for applying a secondary color matrix using RenderEngine. This stacks with the primary color matrix (if set for a11y) to enable GPU-based display calibration. Change-Id: I766455bfb5212e2dcc8ad0cb8ebdddbda87af732 --- services/surfaceflinger/SurfaceFlinger.cpp | 33 ++++++++++++++++++++-- services/surfaceflinger/SurfaceFlinger.h | 3 ++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index a4570194a..40e5da161 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -156,6 +156,7 @@ SurfaceFlinger::SurfaceFlinger() mHWVsyncAvailable(false), mDaltonize(false), mHasColorMatrix(false), + mHasSecondaryColorMatrix(false), mHasPoweredOff(false), mFrameBuckets(), mTotalTime(0), @@ -1193,7 +1194,7 @@ void SurfaceFlinger::setUpHWComposer() { for (size_t i=0 ; cur!=end && i& layer(currentLayers[i]); layer->setGeometry(hw, *cur); - if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) { + if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix || mHasSecondaryColorMatrix) { cur->setSkip(true); } } @@ -1958,11 +1959,14 @@ void SurfaceFlinger::doDisplayComposition(const sp& hw, } } - if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) { + if (CC_LIKELY(!mDaltonize && !mHasColorMatrix && !mHasSecondaryColorMatrix)) { if (!doComposeSurfaces(hw, dirtyRegion)) return; } else { RenderEngine& engine(getRenderEngine()); mat4 colorMatrix = mColorMatrix; + if (mHasSecondaryColorMatrix) { + colorMatrix = mHasColorMatrix ? (colorMatrix * mSecondaryColorMatrix) : mSecondaryColorMatrix; + } if (mDaltonize) { colorMatrix = colorMatrix * mDaltonizer(); } @@ -2948,7 +2952,8 @@ void SurfaceFlinger::dumpAllLocked(const Vector& args, size_t& index, result.appendFormat(" h/w composer %s and %s\n", hwc.initCheck()==NO_ERROR ? "present" : "not present", (mDebugDisableHWC || mDebugRegion || mDaltonize - || mHasColorMatrix) ? "disabled" : "enabled"); + || mHasColorMatrix + || mHasSecondaryColorMatrix) ? "disabled" : "enabled"); hwc.dump(result); /* @@ -3158,6 +3163,28 @@ status_t SurfaceFlinger::onTransact( mSFEventThread->setPhaseOffset(static_cast(n)); return NO_ERROR; } + case 1030: { + // apply a secondary color matrix + // this will be combined with any other transformations + n = data.readInt32(); + mHasSecondaryColorMatrix = n ? 1 : 0; + if (n) { + // color matrix is sent as mat3 matrix followed by vec3 + // offset, then packed into a mat4 where the last row is + // the offset and extra values are 0 + for (size_t i = 0 ; i < 4; i++) { + for (size_t j = 0; j < 4; j++) { + mSecondaryColorMatrix[i][j] = data.readFloat(); + } + } + } else { + mSecondaryColorMatrix = mat4(); + } + invalidateHwcGeometry(); + repaintEverything(); + return NO_ERROR; + } + } } return err; diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 1f7601acc..20d65c1ae 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -553,6 +553,9 @@ private: mat4 mColorMatrix; bool mHasColorMatrix; + mat4 mSecondaryColorMatrix; + bool mHasSecondaryColorMatrix; + // Static screen stats bool mHasPoweredOff; static const size_t NUM_BUCKETS = 8; // < 1-7, 7+ From 573fb3e32d8d479c06813b153c82f1e48e36ae4c Mon Sep 17 00:00:00 2001 From: Khalid Zubair Date: Tue, 19 Apr 2016 10:46:48 -0700 Subject: [PATCH 10/49] sensorservice: add power usage to dumpsys Include each sensor's power usage info in the per-sensor dumpsys info section. Change-Id: If10535d1e7fe6a35d9385ce2e6083a4c5188a06d --- services/sensorservice/SensorService.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index 28af943dd..8ab145a2a 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -359,6 +359,8 @@ status_t SensorService::dump(int fd, const Vector& args) result.appendFormat("non-wakeUp | "); } + result.appendFormat("%.4f mA | ", s.getPowerUsage()); + int bufIndex = mLastEventSeen.indexOfKey(s.getHandle()); if (bufIndex >= 0) { const CircularBuffer* buf = mLastEventSeen.valueAt(bufIndex); From ec0faee33a521407bd7c0259b958ca27241677e1 Mon Sep 17 00:00:00 2001 From: Khalid Zubair Date: Wed, 20 Apr 2016 14:13:35 -0700 Subject: [PATCH 11/49] sensorservice: fix an invalid format string Change-Id: Ib41bca95e6be7831c5ce77bceaf6a3d9f8b37d41 --- services/sensorservice/SensorService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index 8ab145a2a..3d9dcd053 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -1120,7 +1120,7 @@ bool SensorService::canAccessSensor(const Sensor& sensor, const char* operation, AppOpsManager appOps; if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName) != AppOpsManager::MODE_ALLOWED) { - ALOGE("%s a sensor (%s) without enabled required app op: %D", + ALOGE("%s a sensor (%s) without enabled required app op: %d", operation, sensor.getName().string(), opCode); return false; } From 03a53d1c7765eeb3af0bc34c3dff02ada1953fbf Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Tue, 22 Mar 2016 16:52:13 -0700 Subject: [PATCH 12/49] Add new MotionEvent flag for partially obscured windows. Due to more complex window layouts resulting in lots of overlapping windows, the policy around FLAG_WINDOW_IS_OBSCURED has changed to only be set when the point at which the window was touched is obscured. Unfortunately, this doesn't prevent tapjacking attacks that overlay the dialog's text, making a potentially dangerous operation seem innocuous. To avoid this on particularly sensitive dialogs, introduce a new flag that really does tell you when your window is being even partially overlapped. We aren't exposing this as API since we plan on making the original flag more robust. This is really a workaround for system dialogs since we generally know their layout and screen position, and that they're unlikely to be overlapped by other applications. Bug: 26677796 Change-Id: I9e336afe90f262ba22015876769a9c510048fd47 --- include/input/Input.h | 13 ++++++++++ services/inputflinger/InputDispatcher.cpp | 29 +++++++++++++++++++++++ services/inputflinger/InputDispatcher.h | 9 ++++++- services/inputflinger/InputWindow.cpp | 11 +++++++-- services/inputflinger/InputWindow.h | 2 ++ 5 files changed, 61 insertions(+), 3 deletions(-) diff --git a/include/input/Input.h b/include/input/Input.h index 617175bb3..82fc6599a 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -45,6 +45,19 @@ enum { }; enum { + + /** + * This flag indicates that the window that received this motion event is partly + * or wholly obscured by another visible window above it. This flag is set to true + * even if the event did not directly pass through the obscured area. + * A security sensitive application can check this flag to identify situations in which + * a malicious application may have covered up part of its content for the purpose + * of misleading the user or hijacking touches. An appropriate response might be + * to drop the suspect touches or to take additional precautions to confirm the user's + * actual intent. + */ + AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED = 0x2, + /* Motion event is inconsistent with previously sent motion events. */ AMOTION_EVENT_FLAG_TAINTED = 0x80000000, }; diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp index 0fba1bf3e..c9e876fd2 100644 --- a/services/inputflinger/InputDispatcher.cpp +++ b/services/inputflinger/InputDispatcher.cpp @@ -1225,6 +1225,8 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, int32_t outsideTargetFlags = InputTarget::FLAG_DISPATCH_AS_OUTSIDE; if (isWindowObscuredAtPointLocked(windowHandle, x, y)) { outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED; + } else if (isWindowObscuredLocked(windowHandle)) { + outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED; } mTempTouchState.addOrUpdateWindow( @@ -1262,6 +1264,8 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, } if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) { targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED; + } else if (isWindowObscuredLocked(newTouchedWindowHandle)) { + targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED; } // Update hover state. @@ -1437,6 +1441,7 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, == InputWindowInfo::TYPE_WALLPAPER) { mTempTouchState.addOrUpdateWindow(windowHandle, InputTarget::FLAG_WINDOW_IS_OBSCURED + | InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0)); } @@ -1631,6 +1636,27 @@ bool InputDispatcher::isWindowObscuredAtPointLocked( return false; } + +bool InputDispatcher::isWindowObscuredLocked(const sp& windowHandle) const { + int32_t displayId = windowHandle->getInfo()->displayId; + const InputWindowInfo* windowInfo = windowHandle->getInfo(); + size_t numWindows = mWindowHandles.size(); + for (size_t i = 0; i < numWindows; i++) { + sp otherHandle = mWindowHandles.itemAt(i); + if (otherHandle == windowHandle) { + break; + } + + const InputWindowInfo* otherInfo = otherHandle->getInfo(); + if (otherInfo->displayId == displayId + && otherInfo->visible && !otherInfo->isTrustedOverlay() + && otherInfo->overlaps(windowInfo)) { + return true; + } + } + return false; +} + String8 InputDispatcher::checkWindowReadyForMoreInputLocked(nsecs_t currentTime, const sp& windowHandle, const EventEntry* eventEntry, const char* targetType) { @@ -1905,6 +1931,9 @@ void InputDispatcher::enqueueDispatchEntryLocked( if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) { dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED; } + if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) { + dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED; + } if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) { diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h index 98355c6bd..1c054f5ce 100644 --- a/services/inputflinger/InputDispatcher.h +++ b/services/inputflinger/InputDispatcher.h @@ -89,7 +89,7 @@ struct InputTarget { /* This flag indicates that the event is being delivered to a foreground application. */ FLAG_FOREGROUND = 1 << 0, - /* This flag indicates that the target of a MotionEvent is partly or wholly + /* This flag indicates that the MotionEvent falls within the area of the target * obscured by another visible window above it. The motion event should be * delivered with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED. */ FLAG_WINDOW_IS_OBSCURED = 1 << 1, @@ -139,6 +139,12 @@ struct InputTarget { | FLAG_DISPATCH_AS_HOVER_EXIT | FLAG_DISPATCH_AS_SLIPPERY_EXIT | FLAG_DISPATCH_AS_SLIPPERY_ENTER, + + /* This flag indicates that the target of a MotionEvent is partly or wholly + * obscured by another visible window above it. The motion event should be + * delivered with flag AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED. */ + FLAG_WINDOW_IS_PARTIALLY_OBSCURED = 1 << 14, + }; // The input channel to be targeted. @@ -1048,6 +1054,7 @@ private: const InjectionState* injectionState); bool isWindowObscuredAtPointLocked(const sp& windowHandle, int32_t x, int32_t y) const; + bool isWindowObscuredLocked(const sp& windowHandle) const; String8 getApplicationWindowLabelLocked(const sp& applicationHandle, const sp& windowHandle); diff --git a/services/inputflinger/InputWindow.cpp b/services/inputflinger/InputWindow.cpp index fda3ffa2b..1b913c51b 100644 --- a/services/inputflinger/InputWindow.cpp +++ b/services/inputflinger/InputWindow.cpp @@ -36,14 +36,16 @@ bool InputWindowInfo::touchableRegionContainsPoint(int32_t x, int32_t y) const { } bool InputWindowInfo::frameContainsPoint(int32_t x, int32_t y) const { - return x >= frameLeft && x <= frameRight - && y >= frameTop && y <= frameBottom; + return x >= frameLeft && x < frameRight + && y >= frameTop && y < frameBottom; } bool InputWindowInfo::isTrustedOverlay() const { return layoutParamsType == TYPE_INPUT_METHOD || layoutParamsType == TYPE_INPUT_METHOD_DIALOG || layoutParamsType == TYPE_MAGNIFICATION_OVERLAY + || layoutParamsType == TYPE_STATUS_BAR + || layoutParamsType == TYPE_NAVIGATION_BAR || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY; } @@ -51,6 +53,11 @@ bool InputWindowInfo::supportsSplitTouch() const { return layoutParamsFlags & FLAG_SPLIT_TOUCH; } +bool InputWindowInfo::overlaps(const InputWindowInfo* other) const { + return frameLeft < other->frameRight && frameRight > other->frameLeft + && frameTop < other->frameBottom && frameBottom > other->frameTop; +} + // --- InputWindowHandle --- diff --git a/services/inputflinger/InputWindow.h b/services/inputflinger/InputWindow.h index 42457ce41..0ac7fce54 100644 --- a/services/inputflinger/InputWindow.h +++ b/services/inputflinger/InputWindow.h @@ -146,6 +146,8 @@ struct InputWindowInfo { bool isTrustedOverlay() const; bool supportsSplitTouch() const; + + bool overlaps(const InputWindowInfo* other) const; }; From 3ce4ffc46e31f4dd7ca89da1af0c40086f51a01e Mon Sep 17 00:00:00 2001 From: "Christopher N. Hesse" Date: Sun, 24 Apr 2016 19:30:35 +0200 Subject: [PATCH 13/49] surfaceflinger: Add support for Exynos BGRA mixer Change-Id: Ibc9f784b35a7bd6d8cc6b13ff68b12418cce98c5 --- opengl/libs/Android.mk | 4 ++++ opengl/libs/EGL/eglApi.cpp | 9 +++++++++ services/surfaceflinger/Android.mk | 4 ++++ .../DisplayHardware/HWComposer.cpp | 16 ++++++++++++++++ 4 files changed, 33 insertions(+) diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk index e952a3898..870c2bd01 100644 --- a/opengl/libs/Android.mk +++ b/opengl/libs/Android.mk @@ -65,6 +65,10 @@ ifneq ($(MAX_EGL_CACHE_SIZE),) LOCAL_CFLAGS += -DMAX_EGL_CACHE_SIZE=$(MAX_EGL_CACHE_SIZE) endif +ifeq ($(BOARD_USE_BGRA_8888), true) + LOCAL_CFLAGS += -DUSE_BGRA_8888 +endif + LOCAL_REQUIRED_MODULES := $(egl.cfg_config_module) egl.cfg_config_module := diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index 4d9eaf5b3..2f6bc790f 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -462,8 +462,13 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, // modify the EGLconfig's format before setting the native window's // format. +#ifdef USE_BGRA_8888 + // by default, just pick BGRA_8888 + EGLint format = HAL_PIXEL_FORMAT_BGRA_8888; +#else // by default, just pick RGBA_8888 EGLint format = HAL_PIXEL_FORMAT_RGBA_8888; +#endif android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN; #if WORKAROUND_BUG_10194508 @@ -478,7 +483,11 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_ALPHA_SIZE, &a); if (a > 0) { // alpha-channel requested, there's really only one suitable format +#ifdef USE_BGRA_8888 + format = HAL_PIXEL_FORMAT_BGRA_8888; +#else format = HAL_PIXEL_FORMAT_RGBA_8888; +#endif } else { EGLint r, g, b; r = g = b = 0; diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index c1ddba1e4..6a9008385 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -95,6 +95,10 @@ else LOCAL_CFLAGS += -DMAX_VIRTUAL_DISPLAY_DIMENSION=0 endif +ifeq ($(BOARD_USE_BGRA_8888),true) + LOCAL_CFLAGS += -DUSE_BGRA_8888 +endif + LOCAL_CFLAGS += -fvisibility=hidden -Werror=format LOCAL_CFLAGS += -std=c++11 diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index a43597af4..17e91d929 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -435,7 +435,11 @@ status_t HWComposer::queryDisplayProperties(int disp) { } // FIXME: what should we set the format to? +#ifdef USE_BGRA_8888 + mDisplayData[disp].format = HAL_PIXEL_FORMAT_BGRA_8888; +#else mDisplayData[disp].format = HAL_PIXEL_FORMAT_RGBA_8888; +#endif mDisplayData[disp].connected = true; return NO_ERROR; } @@ -497,7 +501,11 @@ sp HWComposer::getDisplayFence(int disp) const { uint32_t HWComposer::getFormat(int disp) const { if (static_cast(disp) >= MAX_HWC_DISPLAYS || !mAllocatedDisplayIDs.hasBit(disp)) { +#ifdef USE_BGRA_8888 + return HAL_PIXEL_FORMAT_BGRA_8888; +#else return HAL_PIXEL_FORMAT_RGBA_8888; +#endif } else { return mDisplayData[disp].format; } @@ -879,7 +887,11 @@ int HWComposer::getVisualID() const { // FIXME: temporary hack until HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED // is supported by the implementation. we can only be in this case // if we have HWC 1.1 +#ifdef USE_BGRA_8888 + return HAL_PIXEL_FORMAT_BGRA_8888; +#else return HAL_PIXEL_FORMAT_RGBA_8888; +#endif //return HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; } else { return mFbDev->format; @@ -1367,7 +1379,11 @@ bool HWComposer::VSyncThread::threadLoop() { HWComposer::DisplayData::DisplayData() : configs(), currentConfig(0), +#ifdef USE_BGRA_8888 + format(HAL_PIXEL_FORMAT_BGRA_8888), +#else format(HAL_PIXEL_FORMAT_RGBA_8888), +#endif connected(false), hasFbComp(false), hasOvComp(false), capacity(0), list(NULL), From bd41ea359f925cea37627cf66758f63b34950aa8 Mon Sep 17 00:00:00 2001 From: Danesh M Date: Fri, 6 May 2016 00:11:27 -0700 Subject: [PATCH 14/49] SurfaceFlinger : Ensure position changes are drawn with correct buffer size If a single transaction has both positional and size changes, ensure we don't draw any frames using the incorrect buffer size using the updated position. Wait for the correct buffer size and then proceed. Change-Id: I8e25f21f17e0936e66bb5053f85f8336c8464c7b --- services/surfaceflinger/CleanSpec.mk | 51 +++++++++++++++++++ services/surfaceflinger/Layer.cpp | 36 ++++++++++++- services/surfaceflinger/Layer.h | 6 ++- .../surfaceflinger/tests/Transaction_test.cpp | 46 +++++++++++++++++ 4 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 services/surfaceflinger/CleanSpec.mk diff --git a/services/surfaceflinger/CleanSpec.mk b/services/surfaceflinger/CleanSpec.mk new file mode 100644 index 000000000..c46eaebbe --- /dev/null +++ b/services/surfaceflinger/CleanSpec.mk @@ -0,0 +1,51 @@ +# Copyright (C) 2016 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. +# + +# If you don't need to do a full clean build but would like to touch +# a file or delete some intermediate files, add a clean step to the end +# of the list. These steps will only be run once, if they haven't been +# run before. +# +# E.g.: +# $(call add-clean-step, touch -c external/sqlite/sqlite3.h) +# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates) +# +# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with +# files that are missing or have been moved. +# +# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory. +# Use $(OUT_DIR) to refer to the "out" directory. +# +# If you need to re-do something that's already mentioned, just copy +# the command and add it to the bottom of the list. E.g., if a change +# that you made last week required touching a file and a change you +# made today requires touching the same file, just copy the old +# touch step and add it to the end of the list. +# +# ************************************************ +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST +# ************************************************ + +# For example: +#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates) +#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates) +#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f) +#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*) + +# ************************************************ +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST +# ************************************************ +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libsurfaceflinger_intermediates) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libsurfaceflinger_ddmconnection_intermediates) diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 6dd8bad32..c346a2ffa 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -104,9 +104,12 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client, mName = name; + mCurrentState.active.x = 0; + mCurrentState.active.y = 0; mCurrentState.active.w = w; mCurrentState.active.h = h; mCurrentState.active.crop.makeInvalid(); + mCurrentState.active.isPositionPending = false; mCurrentState.z = 0; mCurrentState.alpha = 0xFF; mCurrentState.blur = 0xFF; @@ -1027,6 +1030,17 @@ uint32_t Layer::doTransaction(uint32_t flags) { if (flags & eDontUpdateGeometryState) { } else { Layer::State& editCurrentState(getCurrentState()); + // If a position change was requested, and we have the correct + // buffer size, no need to delay, update state now. + if (editCurrentState.requested.isPositionPending) { + float requestedX = editCurrentState.requested.x; + float requestedY = editCurrentState.requested.y; + if (requestedX != editCurrentState.active.x || + requestedY != editCurrentState.active.y) { + editCurrentState.requested.isPositionPending = false; + editCurrentState.transform.set(requestedX, requestedY); + } + } editCurrentState.active = c.requested; } @@ -1064,10 +1078,15 @@ uint32_t Layer::setTransactionFlags(uint32_t flags) { } bool Layer::setPosition(float x, float y) { - if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) + if ((mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y + && !mCurrentState.requested.isPositionPending) || + (mCurrentState.requested.isPositionPending && mCurrentState.requested.x == x + && mCurrentState.requested.y == y)) return false; mCurrentState.sequence++; - mCurrentState.transform.set(x, y); + mCurrentState.requested.x = x; + mCurrentState.requested.y = y; + mCurrentState.requested.isPositionPending = true; setTransactionFlags(eTransactionNeeded); return true; } @@ -1290,6 +1309,19 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) (bufWidth == front.requested.w && bufHeight == front.requested.h)) { + + // If a position change was requested along with a resize. + // Now that we have the correct buffer size, update the position as well. + if (current.requested.isPositionPending) { + float requestedX = current.requested.x; + float requestedY = current.requested.y; + if (requestedX != current.active.x || requestedY != current.active.y) { + front.transform.set(requestedX, requestedY); + current.transform.set(requestedX, requestedY); + current.requested.isPositionPending = false; + } + } + // Here we pretend the transaction happened by updating the // current and drawing states. Drawing state is only accessed // in this thread, no need to have it locked diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 196ef3eb1..02d6f1639 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -95,11 +95,15 @@ public: }; struct Geometry { + float x; + float y; uint32_t w; uint32_t h; + bool isPositionPending; Rect crop; inline bool operator ==(const Geometry& rhs) const { - return (w == rhs.w && h == rhs.h && crop == rhs.crop); + return (w == rhs.w && h == rhs.h && crop == rhs.crop && x == rhs.x && y == rhs.y + && isPositionPending == rhs.isPositionPending); } inline bool operator !=(const Geometry& rhs) const { return !operator ==(rhs); diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index dcde51201..2ef2a502c 100644 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ b/services/surfaceflinger/tests/Transaction_test.cpp @@ -249,4 +249,50 @@ TEST_F(LayerUpdateTest, LayerResizeWorks) { } } +// Ensure that if we move and resize a surface in the same +// transaction, we don't reposition the surface and draw +// using the incorrect buffer size +TEST_F(LayerUpdateTest, LayerMoveAndResizeWorks) { + sp sc; + { + SCOPED_TRACE("before resize and reposition"); + ScreenCapture::captureScreen(&sc); + sc->checkPixel( 0, 12, 63, 63, 195); + sc->checkPixel( 75, 75, 195, 63, 63); + sc->checkPixel(145, 145, 63, 63, 195); + } + + ALOGD("resizing and repositioning"); + SurfaceComposerClient::openGlobalTransaction(); + ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(64, 0)); + ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setSize(64, 128)); + SurfaceComposerClient::closeGlobalTransaction(true); + + ALOGD("resized and repositioned"); + { + // This should not reflect the new size, position or color because SurfaceFlinger + // has not yet received a buffer of the correct size. + SCOPED_TRACE("after resize, before redraw"); + ScreenCapture::captureScreen(&sc); + sc->checkPixel( 0, 12, 63, 63, 195); + sc->checkPixel( 75, 75, 195, 63, 63); + sc->checkPixel(145, 145, 63, 63, 195); + } + + ALOGD("drawing"); + fillSurfaceRGBA8(mFGSurfaceControl, 63, 195, 63); + waitForPostedBuffers(); + ALOGD("drawn"); + { + // This should reflect the new size, position and the new color. + SCOPED_TRACE("after redraw"); + ScreenCapture::captureScreen(&sc); + sc->checkPixel( 64, 0, 63, 195, 63); + // This should pass to imply that we didn't have a frame where the + // surface was moved but not yet resized even though the operations + // were part of the same transaction + sc->checkPixel( 64, 75, 63, 195, 63); + sc->checkPixel(145, 145, 63, 63, 195); + } +} } From 09217544156808716a80e8f3922813f4b4924b79 Mon Sep 17 00:00:00 2001 From: Louis Popi Date: Wed, 11 May 2016 22:48:52 +0200 Subject: [PATCH 15/49] Add dalvik heap/hwui overrides for xxhdpi phone with 3072MB RAM Change-Id: I0ebf2033341e8f09004c1e2dec5f4438aa52e5dc --- build/phone-xxhdpi-3072-dalvik-heap.mk | 25 +++++++++++++++++++++ build/phone-xxhdpi-3072-hwui-memory.mk | 30 ++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 build/phone-xxhdpi-3072-dalvik-heap.mk create mode 100644 build/phone-xxhdpi-3072-hwui-memory.mk diff --git a/build/phone-xxhdpi-3072-dalvik-heap.mk b/build/phone-xxhdpi-3072-dalvik-heap.mk new file mode 100644 index 000000000..450f4e1f8 --- /dev/null +++ b/build/phone-xxhdpi-3072-dalvik-heap.mk @@ -0,0 +1,25 @@ +# +# Copyright (C) 2016 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. +# + +# Provides overrides to configure the Dalvik heap for a 3G phone + +PRODUCT_PROPERTY_OVERRIDES += \ + dalvik.vm.heapstartsize=8m \ + dalvik.vm.heapgrowthlimit=256m \ + dalvik.vm.heapsize=512m \ + dalvik.vm.heaptargetutilization=0.75 \ + dalvik.vm.heapminfree=512k \ + dalvik.vm.heapmaxfree=8m diff --git a/build/phone-xxhdpi-3072-hwui-memory.mk b/build/phone-xxhdpi-3072-hwui-memory.mk new file mode 100644 index 000000000..217bfb845 --- /dev/null +++ b/build/phone-xxhdpi-3072-hwui-memory.mk @@ -0,0 +1,30 @@ +# +# Copyright (C) 2016 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. +# + +# Provides overrides to configure the HWUI memory limits + +PRODUCT_PROPERTY_OVERRIDES += \ + ro.hwui.texture_cache_size=72 \ + ro.hwui.layer_cache_size=48 \ + ro.hwui.path_cache_size=32 \ + ro.hwui.gradient_cache_size=1 \ + ro.hwui.drop_shadow_cache_size=6 \ + ro.hwui.r_buffer_cache_size=8 \ + ro.hwui.texture_cache_flushrate=0.4 \ + ro.hwui.text_small_cache_width=1024 \ + ro.hwui.text_small_cache_height=1024 \ + ro.hwui.text_large_cache_width=2048 \ + ro.hwui.text_large_cache_height=1024 From ea0ee316d82c24fe6863fb9fdb00f8fe0c02a705 Mon Sep 17 00:00:00 2001 From: Scott Mertz Date: Wed, 25 May 2016 15:50:02 -0700 Subject: [PATCH 16/49] dumpstate: add CM version to output Change-Id: Ibd804872d7d32ac1d26efaf30927a2359d2da287 --- cmds/dumpstate/dumpstate.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c index a2e4f4bd5..5b9a42fcb 100644 --- a/cmds/dumpstate/dumpstate.c +++ b/cmds/dumpstate/dumpstate.c @@ -272,7 +272,9 @@ static void dumpstate() { char radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX]; char network[PROPERTY_VALUE_MAX], date[80]; char build_type[PROPERTY_VALUE_MAX]; + char cm_version[PROPERTY_VALUE_MAX]; + property_get("ro.cm.version", cm_version, "(unknown)"); property_get("ro.build.display.id", build, "(unknown)"); property_get("ro.build.fingerprint", fingerprint, "(unknown)"); property_get("ro.build.type", build_type, "(unknown)"); @@ -286,6 +288,7 @@ static void dumpstate() { printf("========================================================\n"); printf("\n"); + printf("CM Version: %s\n", cm_version); printf("Build: %s\n", build); printf("Build fingerprint: '%s'\n", fingerprint); /* format is important for other tools */ printf("Bootloader: %s\n", bootloader); From 54cb02ad733fb71b1bdf78590428817fb780aff8 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Tue, 26 Apr 2016 08:44:09 -0700 Subject: [PATCH 17/49] Correctly handle dup() failure in Parcel::readNativeHandle bail out if dup() fails, instead of creating an invalid native_handle_t Bug: 28395952 Change-Id: Ia1a6198c0f45165b9c6a55a803e5f64d8afa0572 --- libs/binder/Parcel.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 22d7ef36c..4a660d1fb 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -1377,7 +1377,13 @@ native_handle* Parcel::readNativeHandle() const for (int i=0 ; err==NO_ERROR && idata[i] = dup(readFileDescriptor()); - if (h->data[i] < 0) err = BAD_VALUE; + if (h->data[i] < 0) { + for (int j = 0; j < i; j++) { + close(h->data[j]); + } + native_handle_delete(h); + return 0; + } } err = read(h->data + numFds, sizeof(int)*numInts); if (err != NO_ERROR) { From 6500d428ce816ffa0ba099221a4987ad7bfcb4ab Mon Sep 17 00:00:00 2001 From: Louis Popi Date: Wed, 4 May 2016 20:17:24 +0200 Subject: [PATCH 18/49] Add dalvik heap/hwui overrides for xxxhdpi phone with 4096MB RAM Change-Id: I8e7bd9b520c20e0cd07c9b17d74e4ae79f2769b4 --- build/phone-xxxhdpi-4096-dalvik-heap.mk | 25 +++++++++++++++++++++ build/phone-xxxhdpi-4096-hwui-memory.mk | 30 +++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 build/phone-xxxhdpi-4096-dalvik-heap.mk create mode 100644 build/phone-xxxhdpi-4096-hwui-memory.mk diff --git a/build/phone-xxxhdpi-4096-dalvik-heap.mk b/build/phone-xxxhdpi-4096-dalvik-heap.mk new file mode 100644 index 000000000..67f94f4f9 --- /dev/null +++ b/build/phone-xxxhdpi-4096-dalvik-heap.mk @@ -0,0 +1,25 @@ +# +# Copyright (C) 2016 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. +# + +# Provides overrides to configure the Dalvik heap for a 4G phone + +PRODUCT_PROPERTY_OVERRIDES += \ + dalvik.vm.heapstartsize=8m \ + dalvik.vm.heapgrowthlimit=256m \ + dalvik.vm.heapsize=512m \ + dalvik.vm.heaptargetutilization=0.25 \ + dalvik.vm.heapminfree=4m \ + dalvik.vm.heapmaxfree=16m diff --git a/build/phone-xxxhdpi-4096-hwui-memory.mk b/build/phone-xxxhdpi-4096-hwui-memory.mk new file mode 100644 index 000000000..98cef6433 --- /dev/null +++ b/build/phone-xxxhdpi-4096-hwui-memory.mk @@ -0,0 +1,30 @@ +# +# Copyright (C) 2015 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. +# + +# Provides overrides to configure the HWUI memory limits + +PRODUCT_PROPERTY_OVERRIDES += \ + ro.hwui.texture_cache_size=72 \ + ro.hwui.layer_cache_size=48 \ + ro.hwui.r_buffer_cache_size=8 \ + ro.hwui.path_cache_size=32 \ + ro.hwui.gradient_cache_size=1 \ + ro.hwui.drop_shadow_cache_size=6 \ + ro.hwui.texture_cache_flushrate=0.4 \ + ro.hwui.text_small_cache_width=1024 \ + ro.hwui.text_small_cache_height=1024 \ + ro.hwui.text_large_cache_width=2048 \ + ro.hwui.text_large_cache_height=1024 From 2a2eaab883bd243493407cce47382d372f207492 Mon Sep 17 00:00:00 2001 From: "Christopher N. Hesse" Date: Fri, 17 Jun 2016 16:10:21 +0200 Subject: [PATCH 19/49] sf: Only apply hwrotation to primary displays Change-Id: Ib51030cec5ce7609f12be9a5e46310f75442b680 --- services/surfaceflinger/DisplayDevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index f597b7324..92ccf2fd2 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -401,7 +401,7 @@ status_t DisplayDevice::orientationToTransfrom( property_get("ro.sf.hwrotation", value, "0"); int additionalRot = atoi(value); - if (additionalRot) { + if (additionalRot && mType == DISPLAY_PRIMARY) { additionalRot /= 90; if (orientation == DisplayState::eOrientationUnchanged) { orientation = additionalRot; From 3bcf0caa8cca9143443814b36676b3bae33a4368 Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Thu, 26 May 2016 15:35:55 -0700 Subject: [PATCH 20/49] Add FrameStats default constructor Bug 28592402 Change-Id: I857e46c9ab3ffae0d96923d665d13a4128a6cafa --- include/ui/FrameStats.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/ui/FrameStats.h b/include/ui/FrameStats.h index 5fdf94d92..6bfe635c7 100644 --- a/include/ui/FrameStats.h +++ b/include/ui/FrameStats.h @@ -25,6 +25,7 @@ namespace android { class FrameStats : public LightFlattenable { public: + FrameStats() : refreshPeriodNano(0) {}; /* * Approximate refresh time, in nanoseconds. From 0c5f3af37ab6b38125984405ee022c0b1799e6a9 Mon Sep 17 00:00:00 2001 From: radhakrishna Date: Fri, 31 Oct 2014 15:48:14 +0530 Subject: [PATCH 21/49] sf: Make sure HWC_BLENDING_NONE is set for opaque layer Before configuring the layers to HWC, make sure HWC_BLENDING_NONE is set if the layer is opaque Change-Id: Ie84aa9d93e98a244692a0cffc2de653a9079f8b4 Crs-fixed: 957373 --- services/surfaceflinger/Layer.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index c346a2ffa..69e5c6858 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -467,7 +467,11 @@ void Layer::setGeometry( // this gives us only the "orientation" component of the transform const State& s(getDrawingState()); +#ifdef QTI_BSP + if (!isOpaque(s)) { +#else if (!isOpaque(s) || s.alpha != 0xFF) { +#endif layer.setBlending(mPremultipliedAlpha ? HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE); From e481771aa3de37a8cf01a36c5637f0cc48506205 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 27 Jan 2016 08:02:48 -0800 Subject: [PATCH 22/49] Parcel: file descriptor leak Resolve a file descriptor leak when a request for ashmem size adjustment is not filed. Change-Id: I4ebccfd096ec5313725fd99dc3e025f9561d061f --- libs/binder/Parcel.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index cf22e587a..1aaee92c0 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -173,15 +173,14 @@ static void release_object(const sp& proc, return; } case BINDER_TYPE_FD: { - if (outAshmemSize != NULL) { - if (obj.cookie != 0) { + if (obj.cookie != 0) { // owned + if (outAshmemSize != NULL) { int size = ashmem_get_size_region(obj.handle); if (size > 0) { *outAshmemSize -= size; } - - close(obj.handle); } + close(obj.handle); #ifdef DISABLE_ASHMEM_TRACKING } else if (obj.cookie != 0) { close(obj.handle); From d70043eaf41b911c464cf62d5f79aac8697aeb6b Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 27 Jan 2016 08:02:48 -0800 Subject: [PATCH 23/49] system_server BINDER_TYPE_FD sockets using ashmem accessors check if device is a character device, before calling ashmem_get_size_region. We do not check if the st_rdev matches /dev/ashmem. So this at least eliminates making this call when associated with a socket. Bug: 26374183 Change-Id: I68ed9d1c2cd4c47228ed065e3e18eb4151f038f4 --- libs/binder/Parcel.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 1aaee92c0..56890a25c 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -42,6 +42,9 @@ #include #include #include +#include +#include +#include #ifndef INT32_MAX #define INT32_MAX ((int32_t)(2147483647)) @@ -123,8 +126,10 @@ void acquire_object(const sp& proc, return; } case BINDER_TYPE_FD: { - if (obj.cookie != 0) { - if (outAshmemSize != NULL) { + if ((obj.cookie != 0) && (outAshmemSize != NULL)) { + struct stat st; + int ret = fstat(obj.handle, &st); + if (!ret && S_ISCHR(st.st_mode)) { // If we own an ashmem fd, keep track of how much memory it refers to. int size = ashmem_get_size_region(obj.handle); if (size > 0) { @@ -175,9 +180,13 @@ static void release_object(const sp& proc, case BINDER_TYPE_FD: { if (obj.cookie != 0) { // owned if (outAshmemSize != NULL) { - int size = ashmem_get_size_region(obj.handle); - if (size > 0) { - *outAshmemSize -= size; + struct stat st; + int ret = fstat(obj.handle, &st); + if (!ret && S_ISCHR(st.st_mode)) { + int size = ashmem_get_size_region(obj.handle); + if (size > 0) { + *outAshmemSize -= size; + } } } close(obj.handle); From 839f0dd9641f23d6c0a1b1aff48e533621ded51d Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Tue, 2 Feb 2016 10:27:03 -0800 Subject: [PATCH 24/49] system_server BINDER_TYPE_FD driver ashmem accessors check if device matches the ashmem rdev, before calling ashmem_get_size_region. This eliminates making this call when associated with other driver file descriptors. Bug: 26374183 Bug: 26918423 Bug: 26871259 Change-Id: I1f88c2c93ea35a73c8e14125f3d1a6c67fa4f15b --- libs/binder/Parcel.cpp | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 56890a25c..65e67d6a7 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -18,6 +18,8 @@ //#define LOG_NDEBUG 0 #include +#include +#include #include #include @@ -98,6 +100,32 @@ enum { BLOB_ASHMEM_MUTABLE = 2, }; +static dev_t ashmem_rdev() +{ + static dev_t __ashmem_rdev; + static pthread_mutex_t __ashmem_rdev_lock = PTHREAD_MUTEX_INITIALIZER; + + pthread_mutex_lock(&__ashmem_rdev_lock); + + dev_t rdev = __ashmem_rdev; + if (!rdev) { + int fd = TEMP_FAILURE_RETRY(open("/dev/ashmem", O_RDONLY)); + if (fd >= 0) { + struct stat st; + + int ret = TEMP_FAILURE_RETRY(fstat(fd, &st)); + close(fd); + if ((ret >= 0) && S_ISCHR(st.st_mode)) { + rdev = __ashmem_rdev = st.st_rdev; + } + } + } + + pthread_mutex_unlock(&__ashmem_rdev_lock); + + return rdev; +} + void acquire_object(const sp& proc, const flat_binder_object& obj, const void* who, size_t* outAshmemSize) { @@ -129,7 +157,7 @@ void acquire_object(const sp& proc, if ((obj.cookie != 0) && (outAshmemSize != NULL)) { struct stat st; int ret = fstat(obj.handle, &st); - if (!ret && S_ISCHR(st.st_mode)) { + if (!ret && S_ISCHR(st.st_mode) && (st.st_rdev == ashmem_rdev())) { // If we own an ashmem fd, keep track of how much memory it refers to. int size = ashmem_get_size_region(obj.handle); if (size > 0) { @@ -182,7 +210,7 @@ static void release_object(const sp& proc, if (outAshmemSize != NULL) { struct stat st; int ret = fstat(obj.handle, &st); - if (!ret && S_ISCHR(st.st_mode)) { + if (!ret && S_ISCHR(st.st_mode) && (st.st_rdev == ashmem_rdev())) { int size = ashmem_get_size_region(obj.handle); if (size > 0) { *outAshmemSize -= size; From a5761b164a27d2894f8abc0652dd8cda7326f564 Mon Sep 17 00:00:00 2001 From: Arne Coucheron Date: Wed, 20 Jul 2016 00:46:07 +0200 Subject: [PATCH 25/49] sf: Fix blending mode for legacy BSP * After 0c5f3af, glitches when blending is observed on A family devices. Modify ifdef to not include QCOM_BSP_LEGACY. Change-Id: Ibb53df5709abbb0e7132065aec23a14f7accf4b3 --- services/surfaceflinger/Layer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 69e5c6858..14bd312a2 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -467,7 +467,7 @@ void Layer::setGeometry( // this gives us only the "orientation" component of the transform const State& s(getDrawingState()); -#ifdef QTI_BSP +#if defined(QCOM_BSP) && !defined(QCOM_BSP_LEGACY) if (!isOpaque(s)) { #else if (!isOpaque(s) || s.alpha != 0xFF) { From 95cda3b92faf69f2ed594ee87a7e1e7499bd0060 Mon Sep 17 00:00:00 2001 From: Haixia Shi Date: Wed, 28 Oct 2015 13:22:22 -0700 Subject: [PATCH 26/49] SF: use first sample timestamp as reference. Do not use the absolute 64-bit nsecs_t timestamp directly in phase and error calculations. Compared to the estimated vsync period, the timestamp tend to many orders of magnitudes larger, and consequently the integer modulo operation used to calculate phase and error can be very sensitive to tiny fluctuation in vsync period. Bug: 25113115 Test: set kTraceDetailedInfo=true; see Phase and Error are stable in systrace Change-Id: I687703eec31b1072c606898c0424a96c0a8ca033 --- services/surfaceflinger/DispSync.cpp | 8 ++++++-- services/surfaceflinger/DispSync.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/services/surfaceflinger/DispSync.cpp b/services/surfaceflinger/DispSync.cpp index 73b389730..dda896ebf 100644 --- a/services/surfaceflinger/DispSync.cpp +++ b/services/surfaceflinger/DispSync.cpp @@ -317,6 +317,7 @@ void DispSync::reset() { mNumResyncSamples = 0; mFirstResyncSample = 0; + mResyncReferenceTime = 0; mNumResyncSamplesSincePresent = 0; resetErrorLocked(); } @@ -356,6 +357,9 @@ bool DispSync::addResyncSample(nsecs_t timestamp) { size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES; mResyncSamples[idx] = timestamp; + if (mNumResyncSamples == 0) { + mResyncReferenceTime = timestamp; + } if (mNumResyncSamples < MAX_RESYNC_SAMPLES) { mNumResyncSamples++; @@ -432,7 +436,7 @@ void DispSync::updateModelLocked() { double scale = 2.0 * M_PI / double(mPeriod); for (size_t i = 0; i < mNumResyncSamples; i++) { size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES; - nsecs_t sample = mResyncSamples[idx]; + nsecs_t sample = mResyncSamples[idx] - mResyncReferenceTime; double samplePhase = double(sample % mPeriod) * scale; sampleAvgX += cos(samplePhase); sampleAvgY += sin(samplePhase); @@ -472,7 +476,7 @@ void DispSync::updateErrorLocked() { nsecs_t sqErrSum = 0; for (size_t i = 0; i < NUM_PRESENT_SAMPLES; i++) { - nsecs_t sample = mPresentTimes[i]; + nsecs_t sample = mPresentTimes[i] - mResyncReferenceTime; if (sample > mPhase) { nsecs_t sampleErr = (sample - mPhase) % period; if (sampleErr > period / 2) { diff --git a/services/surfaceflinger/DispSync.h b/services/surfaceflinger/DispSync.h index ebe19a5b8..fabb875a2 100644 --- a/services/surfaceflinger/DispSync.h +++ b/services/surfaceflinger/DispSync.h @@ -154,6 +154,7 @@ private: // These member variables are the state used during the resynchronization // process to store information about the hardware vsync event times used // to compute the model. + nsecs_t mResyncReferenceTime; nsecs_t mResyncSamples[MAX_RESYNC_SAMPLES]; size_t mFirstResyncSample; size_t mNumResyncSamples; From 179bd77ab69361f3f26a50e01781be9cad78a4d1 Mon Sep 17 00:00:00 2001 From: Haixia Shi Date: Wed, 28 Oct 2015 16:19:01 -0700 Subject: [PATCH 27/49] SF: more DispSync improvements. Pass the reference time to DispSyncThread. Since the phase offset is calculated using timestamps relative to the reference time, we must also adjust the phase offset by the same reference time when computing the next refresh time. Always reset phase offset to zero when updating the reference time because the reference time equals the first timestamp. After beginResync() we need to keep HW vsync enabled until the model is updated. Bug: 25113115 Change-Id: I8eae227bee91c24a99bf8e57fbebceb98d29c77d Test: check in systrace that app/sf vsync events have correct phase --- services/surfaceflinger/DispSync.cpp | 34 ++++++++++++++++++---------- services/surfaceflinger/DispSync.h | 8 ++++++- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/services/surfaceflinger/DispSync.cpp b/services/surfaceflinger/DispSync.cpp index dda896ebf..192d74608 100644 --- a/services/surfaceflinger/DispSync.cpp +++ b/services/surfaceflinger/DispSync.cpp @@ -57,15 +57,17 @@ public: mStop(false), mPeriod(0), mPhase(0), + mReferenceTime(0), mWakeupLatency(0) { } virtual ~DispSyncThread() {} - void updateModel(nsecs_t period, nsecs_t phase) { + void updateModel(nsecs_t period, nsecs_t phase, nsecs_t referenceTime) { Mutex::Autolock lock(mMutex); mPeriod = period; mPhase = phase; + mReferenceTime = referenceTime; mCond.signal(); } @@ -247,7 +249,7 @@ private: ref = lastEventTime; } - nsecs_t phase = mPhase + listener.mPhase; + nsecs_t phase = mReferenceTime + mPhase + listener.mPhase; nsecs_t t = (((ref - phase) / mPeriod) + 1) * mPeriod + phase; if (t - listener.mLastEventTime < mPeriod / 2) { @@ -267,6 +269,7 @@ private: nsecs_t mPeriod; nsecs_t mPhase; + nsecs_t mReferenceTime; nsecs_t mWakeupLatency; Vector mEventListeners; @@ -315,9 +318,11 @@ DispSync::~DispSync() {} void DispSync::reset() { Mutex::Autolock lock(mMutex); + mPhase = 0; + mReferenceTime = 0; + mModelUpdated = false; mNumResyncSamples = 0; mFirstResyncSample = 0; - mResyncReferenceTime = 0; mNumResyncSamplesSincePresent = 0; resetErrorLocked(); } @@ -343,12 +348,13 @@ bool DispSync::addPresentFence(const sp& fence) { updateErrorLocked(); - return mPeriod == 0 || mError > kErrorThreshold; + return !mModelUpdated || mError > kErrorThreshold; } void DispSync::beginResync() { Mutex::Autolock lock(mMutex); + mModelUpdated = false; mNumResyncSamples = 0; } @@ -358,7 +364,8 @@ bool DispSync::addResyncSample(nsecs_t timestamp) { size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES; mResyncSamples[idx] = timestamp; if (mNumResyncSamples == 0) { - mResyncReferenceTime = timestamp; + mPhase = 0; + mReferenceTime = timestamp; } if (mNumResyncSamples < MAX_RESYNC_SAMPLES) { @@ -382,7 +389,7 @@ bool DispSync::addResyncSample(nsecs_t timestamp) { return mThread->hasAnyEventListeners(); } - return mPeriod == 0 || mError > kErrorThreshold; + return !mModelUpdated || mError > kErrorThreshold; } void DispSync::endResync() { @@ -411,7 +418,8 @@ void DispSync::setPeriod(nsecs_t period) { Mutex::Autolock lock(mMutex); mPeriod = period; mPhase = 0; - mThread->updateModel(mPeriod, mPhase); + mReferenceTime = 0; + mThread->updateModel(mPeriod, mPhase, mReferenceTime); } nsecs_t DispSync::getPeriod() { @@ -436,7 +444,7 @@ void DispSync::updateModelLocked() { double scale = 2.0 * M_PI / double(mPeriod); for (size_t i = 0; i < mNumResyncSamples; i++) { size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES; - nsecs_t sample = mResyncSamples[idx] - mResyncReferenceTime; + nsecs_t sample = mResyncSamples[idx] - mReferenceTime; double samplePhase = double(sample % mPeriod) * scale; sampleAvgX += cos(samplePhase); sampleAvgY += sin(samplePhase); @@ -459,12 +467,13 @@ void DispSync::updateModelLocked() { // Artificially inflate the period if requested. mPeriod += mPeriod * mRefreshSkipCount; - mThread->updateModel(mPeriod, mPhase); + mThread->updateModel(mPeriod, mPhase, mReferenceTime); + mModelUpdated = true; } } void DispSync::updateErrorLocked() { - if (mPeriod == 0) { + if (!mModelUpdated) { return; } @@ -476,7 +485,7 @@ void DispSync::updateErrorLocked() { nsecs_t sqErrSum = 0; for (size_t i = 0; i < NUM_PRESENT_SAMPLES; i++) { - nsecs_t sample = mPresentTimes[i] - mResyncReferenceTime; + nsecs_t sample = mPresentTimes[i] - mReferenceTime; if (sample > mPhase) { nsecs_t sampleErr = (sample - mPhase) % period; if (sampleErr > period / 2) { @@ -510,7 +519,8 @@ void DispSync::resetErrorLocked() { nsecs_t DispSync::computeNextRefresh(int periodOffset) const { Mutex::Autolock lock(mMutex); nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); - return (((now - mPhase) / mPeriod) + periodOffset + 1) * mPeriod + mPhase; + nsecs_t phase = mReferenceTime + mPhase; + return (((now - phase) / mPeriod) + periodOffset + 1) * mPeriod + phase; } void DispSync::dump(String8& result) const { diff --git a/services/surfaceflinger/DispSync.h b/services/surfaceflinger/DispSync.h index fabb875a2..61d891b7b 100644 --- a/services/surfaceflinger/DispSync.h +++ b/services/surfaceflinger/DispSync.h @@ -146,15 +146,21 @@ private: // number of nanoseconds from time 0 to the first vsync event. nsecs_t mPhase; + // mReferenceTime is the reference time of the modeled vsync events. + // It is the nanosecond timestamp of the first vsync event after a resync. + nsecs_t mReferenceTime; + // mError is the computed model error. It is based on the difference // between the estimated vsync event times and those observed in the // mPresentTimes array. nsecs_t mError; + // Whether we have updated the vsync event model since the last resync. + bool mModelUpdated; + // These member variables are the state used during the resynchronization // process to store information about the hardware vsync event times used // to compute the model. - nsecs_t mResyncReferenceTime; nsecs_t mResyncSamples[MAX_RESYNC_SAMPLES]; size_t mFirstResyncSample; size_t mNumResyncSamples; From c91bafb88a3abf50c369637caf79fb027b48c46e Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Wed, 7 Oct 2015 16:38:42 -0700 Subject: [PATCH 28/49] DO NOT MERGE: dumpstate: execute procrank using su procrank is a setuid binary which only exists on userdebug/eng builds. Instead of executing the setuid binary, run the binary using the su command. This eliminates one more setuid binary, and allows the tightening of the SELinux policy. Bug: 18342188 (cherry picked from commit 2b1f88b6ac78e330ff006da6fecf8bc9d976ec67) Bug: 25951005 Change-Id: I90c86f89974b3878273a29277b2a5d5d7c4b81c7 --- cmds/dumpstate/dumpstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c index 5b9a42fcb..475f7e359 100644 --- a/cmds/dumpstate/dumpstate.c +++ b/cmds/dumpstate/dumpstate.c @@ -305,7 +305,7 @@ static void dumpstate() { dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd); dump_file("MEMORY INFO", "/proc/meminfo"); run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-t", NULL); - run_command("PROCRANK", 20, "procrank", NULL); + run_command("PROCRANK", 20, SU_PATH, "root", "procrank", NULL); dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat"); dump_file("VMALLOC INFO", "/proc/vmallocinfo"); dump_file("SLAB INFO", "/proc/slabinfo"); From a887c19994c7873fbe651e2fe944a176576a6198 Mon Sep 17 00:00:00 2001 From: Saurabh Shah Date: Mon, 21 Mar 2016 17:25:23 -0700 Subject: [PATCH 29/49] SF: Add support for all flips of panel mount Add support for all flips of panel mount, H, V, HV (180). Property persist.panel.mountflip can be set to 1 for H-Flip, 2 for V-Flip, 3 for HV-Flip (180 / inverse mount). Change-Id: Ide7b8378ad6a423e5d7335fedc27d480a25b53ae CRs-fixed: 990622 --- services/surfaceflinger/DisplayDevice.cpp | 12 ++++++------ services/surfaceflinger/DisplayDevice.h | 8 ++++---- services/surfaceflinger/LayerBlur.cpp | 3 +-- services/surfaceflinger/SurfaceFlinger.cpp | 5 ++--- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 92ccf2fd2..b83149bb9 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -142,10 +142,10 @@ DisplayDevice::DisplayDevice( break; } - mPanelInverseMounted = false; - // Check if panel is inverse mounted (contents show up HV flipped) - property_get("persist.panel.inversemounted", property, "0"); - mPanelInverseMounted = !!atoi(property); + mPanelMountFlip = 0; + // 1: H-Flip, 2: V-Flip, 3: 180 (HV Flip) + property_get("persist.panel.mountflip", property, "0"); + mPanelMountFlip = atoi(property); // initialize the display orientation transform. setProjection(DisplayState::eOrientationDefault, mViewport, mFrame); @@ -428,8 +428,8 @@ status_t DisplayDevice::orientationToTransfrom( return BAD_VALUE; } - if (DISPLAY_PRIMARY == mHwcDisplayId && isPanelInverseMounted()) { - flags = flags ^ Transform::ROT_180; + if (DISPLAY_PRIMARY == mHwcDisplayId) { + flags = flags ^ getPanelMountFlip(); } tr->set(flags, w, h); diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index f492a427a..9023ce93f 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -126,8 +126,8 @@ public: int32_t getHwcDisplayId() const { return mHwcDisplayId; } const wp& getDisplayToken() const { return mDisplayToken; } - bool isPanelInverseMounted() const { - return mPanelInverseMounted; + uint32_t getPanelMountFlip() const { + return mPanelMountFlip; } // We pass in mustRecompose so we can keep VirtualDisplaySurface's state @@ -230,8 +230,8 @@ private: int mPowerMode; // Current active config int mActiveConfig; - // Panel is inverse mounted - int mPanelInverseMounted; + // Panel's mount flip, H, V or 180 (HV) + uint32_t mPanelMountFlip; }; }; // namespace android diff --git a/services/surfaceflinger/LayerBlur.cpp b/services/surfaceflinger/LayerBlur.cpp index 021978d1c..4f5a72dc6 100644 --- a/services/surfaceflinger/LayerBlur.cpp +++ b/services/surfaceflinger/LayerBlur.cpp @@ -238,8 +238,7 @@ bool LayerBlur::captureScreen(const sp& hw, FBO& fbo, Textu texture.getTextureName(), 0); mFlinger->getRenderEngine().clearWithColor(0.0f, 0.0f, 0.0f, 1.0f); - if (hw->isPanelInverseMounted()) - rotation = Transform::ROT_180; + rotation = (Transform::orientation_flags)(rotation ^ hw->getPanelMountFlip()); mFlinger->renderScreenImplLocked( hw, Rect(0,0,width,height), diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 40e5da161..97d3163eb 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3463,10 +3463,9 @@ void SurfaceFlinger::renderScreenImplLocked( // make sure to clear all GL error flags engine.checkErrors(); - if (DisplayDevice::DISPLAY_PRIMARY == hw->getDisplayType() && - hw->isPanelInverseMounted()) { + if (DisplayDevice::DISPLAY_PRIMARY == hw->getDisplayType()) { rotation = (Transform::orientation_flags) - (rotation ^ Transform::ROT_180); + (rotation ^ hw->getPanelMountFlip()); } // set-up our viewport From d67b177ff6a6dbbd950f1aaa84669351d6f26b9e Mon Sep 17 00:00:00 2001 From: Ramkumar Radhakrishnan Date: Wed, 18 May 2016 18:56:05 -0700 Subject: [PATCH 30/49] SF: Fix NULL pointer dereferencing in dumpDrawCycle() Check for NULL before dereferencing a pointer in dumpDrawCycle() Change-Id: I1f06214577d0065c988877acb0f1b4378080690f CRs-Fixed: 1018335 --- services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.cpp b/services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.cpp index 96d4b1d1e..7be0328b6 100644 --- a/services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.cpp +++ b/services/surfaceflinger/ExSurfaceFlinger/ExSurfaceFlinger.cpp @@ -335,6 +335,10 @@ void ExSurfaceFlinger::dumpDrawCycle(bool prePrepare) { gettimeofday(&tv, NULL); ptm = localtime(&tv.tv_sec); + if (ptm == NULL) { + return; + } + strftime (hms, sizeof (hms), "%H:%M:%S", ptm); millis = tv.tv_usec / 1000; snprintf(timeStamp, sizeof(timeStamp), "Timestamp: %s.%03ld", hms, millis); From 1ecb999624165ea2a9cf5e16b3f7e93358d503d6 Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Wed, 13 Jul 2016 14:11:57 -0700 Subject: [PATCH 31/49] Region: Detect malicious overflow in unflatten Bug 29983260 Change-Id: Ib6e1cb8ae279010c5e9960aaa03513f55b7d873b --- libs/ui/Region.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp index 3810da404..cfed7a984 100644 --- a/libs/ui/Region.cpp +++ b/libs/ui/Region.cpp @@ -795,6 +795,11 @@ status_t Region::unflatten(void const* buffer, size_t size) { return NO_MEMORY; } + if (numRects > (UINT32_MAX / sizeof(Rect))) { + android_errorWriteWithInfoLog(0x534e4554, "29983260", -1, NULL, 0); + return NO_MEMORY; + } + Region result; result.mStorage.clear(); for (size_t r = 0; r < numRects; ++r) { From 8cafa373aa14b21981627e0ba9ea96731254183d Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Sun, 24 Jul 2016 16:19:39 -0700 Subject: [PATCH 32/49] surfaceflinger: Fix the fix of the opaque check fix * Use the right define. Change-Id: I78e2aea4bf4ff933ec828cffee1a3e925622ad31 --- services/surfaceflinger/Layer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 14bd312a2..3e932df74 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -467,7 +467,7 @@ void Layer::setGeometry( // this gives us only the "orientation" component of the transform const State& s(getDrawingState()); -#if defined(QCOM_BSP) && !defined(QCOM_BSP_LEGACY) +#if defined(QTI_BSP) && !defined(QCOM_BSP_LEGACY) if (!isOpaque(s)) { #else if (!isOpaque(s) || s.alpha != 0xFF) { From 537364c7229cb7d5d63b4683a34e47db6aa013bd Mon Sep 17 00:00:00 2001 From: feifanz Date: Wed, 27 Apr 2016 12:23:28 +0800 Subject: [PATCH 33/49] SF: Add support to draw S3D framebuffer target Add support to draw S3D framebuffer target in case HWC driver can not handle due to resource or capability issue. Change-Id: I536fa4a03e246d51891045b692d5dc5be88f2adf CRs-fixed: 999055 --- services/surfaceflinger/Android.mk | 1 + .../DisplayHardware/HWComposer.h | 1 + .../ExSurfaceFlinger/ExHWComposer.cpp | 23 +++ .../ExSurfaceFlinger/ExHWComposer.h | 4 + .../ExSurfaceFlinger/ExLayer.cpp | 184 +++++++++++++++++- .../surfaceflinger/ExSurfaceFlinger/ExLayer.h | 32 +++ services/surfaceflinger/Layer.h | 10 + services/surfaceflinger/SurfaceFlinger.cpp | 6 + services/surfaceflinger/SurfaceFlinger.h | 3 + 9 files changed, 263 insertions(+), 1 deletion(-) diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 6a9008385..4a6d32044 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -120,6 +120,7 @@ ifeq ($(TARGET_USES_QCOM_BSP), true) LOCAL_C_INCLUDES += $(call project-path-for,qcom-display)/libgralloc LOCAL_C_INCLUDES += $(call project-path-for,qcom-display)/libqdutils LOCAL_SHARED_LIBRARIES += libqdutils + LOCAL_SHARED_LIBRARIES += libqdMetaData LOCAL_CFLAGS += -DQTI_BSP LOCAL_SRC_FILES += \ ExSurfaceFlinger/ExLayer.cpp \ diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 9bdb7dea6..efdcd03a3 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -306,6 +306,7 @@ public: }; friend class VSyncThread; + friend class ExHWComposer; // for debugging ---------------------------------------------------------- void dump(String8& out) const; diff --git a/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp b/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp index 2b4109877..6b228ed85 100644 --- a/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp +++ b/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp @@ -31,6 +31,8 @@ #include "ExHWComposer.h" #ifdef QTI_BSP #include +#include +#include #endif namespace android { @@ -74,4 +76,25 @@ bool ExHWComposer::isCompositionTypeBlit(const int32_t compType) const { return false; } +#ifdef QTI_BSP +uint32_t ExHWComposer::getS3DFlag(int disp) const { + const DisplayData& disp_data(mDisplayData[disp]); + + for (size_t i=0 ; inumHwLayers-1; i++) { + const hwc_layer_1_t &l = disp_data.list->hwLayers[i]; + private_handle_t *pvt_handle = static_cast + (const_cast(l.handle)); + + if (pvt_handle != NULL) { + struct S3DSFRender_t s3dRender; + getMetaData(pvt_handle, GET_S3D_RENDER, &s3dRender); + if (s3dRender.DisplayId == static_cast(disp) && s3dRender.GpuRender) { + return s3dRender.GpuS3dFormat; + } + } + } + return 0; +} +#endif + }; // namespace android diff --git a/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.h b/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.h index 2016ff063..06ee32b89 100644 --- a/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.h +++ b/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.h @@ -43,6 +43,10 @@ public: virtual ~ExHWComposer(); +#ifdef QTI_BSP + uint32_t getS3DFlag(int disp) const; +#endif + protected: bool mVDSEnabled; inline bool isVDSEnabled() const { return mVDSEnabled; }; diff --git a/services/surfaceflinger/ExSurfaceFlinger/ExLayer.cpp b/services/surfaceflinger/ExSurfaceFlinger/ExLayer.cpp index fa4557909..5df34edf6 100644 --- a/services/surfaceflinger/ExSurfaceFlinger/ExLayer.cpp +++ b/services/surfaceflinger/ExSurfaceFlinger/ExLayer.cpp @@ -36,10 +36,12 @@ #include #ifdef QTI_BSP #include +#include #include #endif #include "ExLayer.h" +#include "RenderEngine/RenderEngine.h" namespace android { @@ -70,12 +72,18 @@ static Rect getAspectRatio(const sp& hw, ExLayer::ExLayer(SurfaceFlinger* flinger, const sp& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags) +#ifdef QTI_BSP + : Layer(flinger, client, name, w, h, flags), + mMeshLeftTop(Mesh::TRIANGLE_FAN, 4, 2, 2), + mMeshRightBottom(Mesh::TRIANGLE_FAN, 4, 2, 2) { +#else : Layer(flinger, client, name, w, h, flags) { - +#endif char property[PROPERTY_VALUE_MAX] = {0}; mDebugLogs = false; mIsGPUAllowedForProtected = false; + mIsHDMIPrimary = false; if((property_get("persist.debug.qdframework.logs", property, NULL) > 0) && (!strncmp(property, "1", PROPERTY_VALUE_MAX ) || (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) { @@ -88,6 +96,12 @@ ExLayer::ExLayer(SurfaceFlinger* flinger, const sp& client, (atoi(property) == 1)) { mIsGPUAllowedForProtected = true; } + + if ((property_get("persist.sys.is_hdmi_primary", property, NULL) > 0) && + (atoi(property) == 1)) { + mIsHDMIPrimary = true; + } + } ExLayer::~ExLayer() { @@ -204,4 +218,172 @@ bool ExLayer::canAllowGPUForProtected() const { } } +void ExLayer::drawWithOpenGL(const sp& hw, + const Region& /* clip */, bool useIdentityTransform) const { + const State& s(getDrawingState()); +#ifdef QTI_BSP + uint32_t s3d_fmt = 0; + private_handle_t *pvt_handle = static_cast + (const_cast(mActiveBuffer->handle)); + if (pvt_handle != NULL) { + struct S3DSFRender_t s3dRender; + getMetaData(pvt_handle, GET_S3D_RENDER, &s3dRender); + + if ((s3dRender.DisplayId == static_cast(hw->getHwcDisplayId()) || + mIsHDMIPrimary) && s3dRender.GpuRender) { + clearMetaData(pvt_handle, SET_S3D_RENDER); + s3d_fmt = s3dRender.GpuS3dFormat; + } + } +#endif + computeGeometry(hw, mMesh, useIdentityTransform); + + /* + * NOTE: the way we compute the texture coordinates here produces + * different results than when we take the HWC path -- in the later case + * the "source crop" is rounded to texel boundaries. + * This can produce significantly different results when the texture + * is scaled by a large amount. + * + * The GL code below is more logical (imho), and the difference with + * HWC is due to a limitation of the HWC API to integers -- a question + * is suspend is whether we should ignore this problem or revert to + * GL composition when a buffer scaling is applied (maybe with some + * minimal value)? Or, we could make GL behave like HWC -- but this feel + * like more of a hack. + */ + Rect win(s.active.w, s.active.h); + if(!s.active.crop.isEmpty()) { + win = s.active.crop; + } +#ifdef QTI_BSP + win = s.transform.transform(win); + win.intersect(hw->getViewport(), &win); + win = s.transform.inverse().transform(win); + win.intersect(Rect(s.active.w, s.active.h), &win); + win = reduce(win, s.activeTransparentRegion); +#else + win = reduce(win, s.activeTransparentRegion); +#endif + float left = float(win.left) / float(s.active.w); + float top = float(win.top) / float(s.active.h); + float right = float(win.right) / float(s.active.w); + float bottom = float(win.bottom) / float(s.active.h); + + // TODO: we probably want to generate the texture coords with the mesh + // here we assume that we only have 4 vertices + Mesh::VertexArray texCoords(mMesh.getTexCoordArray()); + texCoords[0] = vec2(left, 1.0f - top); + texCoords[1] = vec2(left, 1.0f - bottom); + texCoords[2] = vec2(right, 1.0f - bottom); + texCoords[3] = vec2(right, 1.0f - top); + +#ifdef QTI_BSP + computeGeometryS3D(hw, mMesh, mMeshLeftTop, mMeshRightBottom, s3d_fmt); +#endif + + RenderEngine& engine(mFlinger->getRenderEngine()); + engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha); + +#ifdef QTI_BSP + if (s3d_fmt != HWC_S3DMODE_NONE) { + engine.setScissor(0, 0, hw->getWidth(), hw->getHeight()); + engine.drawMesh(mMeshLeftTop); + engine.drawMesh(mMeshRightBottom); + } else { +#endif + engine.drawMesh(mMesh); +#ifdef QTI_BSP + } +#endif + + engine.disableBlending(); +} + +#ifdef QTI_BSP +void ExLayer::computeGeometryS3D(const sp& hw, Mesh& mesh, + Mesh& meshLeftTop, Mesh &meshRightBottom, uint32_t s3d_fmt) const +{ + Mesh::VertexArray position(mesh.getPositionArray()); + Mesh::VertexArray positionLeftTop(meshLeftTop.getPositionArray()); + Mesh::VertexArray positionRightBottom(meshRightBottom.getPositionArray()); + Mesh::VertexArray texCoords(mesh.getTexCoordArray()); + Mesh::VertexArray texCoordsLeftTop(meshLeftTop.getTexCoordArray()); + Mesh::VertexArray texCoordsRightBottom(meshRightBottom.getTexCoordArray()); + + Rect scissor = hw->getBounds(); + + if(s3d_fmt == HWC_S3DMODE_NONE) { + return; + } + + uint32_t count = mesh.getVertexCount(); + while(count--) { + positionLeftTop[count] = positionRightBottom[count] = position[count]; + texCoordsLeftTop[count] = texCoordsRightBottom[count] = texCoords[count]; + } + + switch (s3d_fmt) { + case HWC_S3DMODE_LR: + case HWC_S3DMODE_RL: + { + positionLeftTop[0].x = (position[0].x - scissor.left) / 2.0f + scissor.left; + positionLeftTop[1].x = (position[1].x - scissor.left) / 2.0f + scissor.left; + positionLeftTop[2].x = (position[2].x - scissor.left) / 2.0f + scissor.left; + positionLeftTop[3].x = (position[3].x - scissor.left) / 2.0f + scissor.left; + + positionRightBottom[0].x = positionLeftTop[0].x + scissor.getWidth()/2; + positionRightBottom[1].x = positionLeftTop[1].x + scissor.getWidth()/2; + positionRightBottom[2].x = positionLeftTop[2].x + scissor.getWidth()/2; + positionRightBottom[3].x = positionLeftTop[3].x + scissor.getWidth()/2; + + if(isYuvLayer()) { + texCoordsLeftTop[0].x = texCoords[0].x / 2.0f; + texCoordsLeftTop[1].x = texCoords[1].x / 2.0f; + texCoordsLeftTop[2].x = texCoords[2].x / 2.0f; + texCoordsLeftTop[3].x = texCoords[3].x / 2.0f; + + texCoordsRightBottom[0].x = texCoordsLeftTop[0].x + 0.5f; + texCoordsRightBottom[1].x = texCoordsLeftTop[1].x + 0.5f; + texCoordsRightBottom[2].x = texCoordsLeftTop[2].x + 0.5f; + texCoordsRightBottom[3].x = texCoordsLeftTop[3].x + 0.5f; + } + break; + } + case HWC_S3DMODE_TB: + { + positionRightBottom[0].y = (position[0].y - scissor.top) / 2.0f + scissor.top; + positionRightBottom[1].y = (position[1].y - scissor.top) / 2.0f + scissor.top; + positionRightBottom[2].y = (position[2].y - scissor.top) / 2.0f + scissor.top; + positionRightBottom[3].y = (position[3].y - scissor.top) / 2.0f + scissor.top; + + positionLeftTop[0].y = positionRightBottom[0].y + scissor.getHeight() / 2.0f; + positionLeftTop[1].y = positionRightBottom[1].y + scissor.getHeight() / 2.0f; + positionLeftTop[2].y = positionRightBottom[2].y + scissor.getHeight() / 2.0f; + positionLeftTop[3].y = positionRightBottom[3].y + scissor.getHeight() / 2.0f; + + positionLeftTop[0].x = positionRightBottom[0].x = position[0].x; + positionLeftTop[1].x = positionRightBottom[1].x = position[1].x; + positionLeftTop[2].x = positionRightBottom[2].x = position[2].x; + positionLeftTop[3].x = positionRightBottom[3].x = position[3].x; + + if(isYuvLayer()) { + texCoordsRightBottom[0].y = texCoords[0].y / 2.0f; + texCoordsRightBottom[1].y = texCoords[1].y / 2.0f; + texCoordsRightBottom[2].y = texCoords[2].y / 2.0f; + texCoordsRightBottom[3].y = texCoords[3].y / 2.0f; + + texCoordsLeftTop[0].y = texCoordsRightBottom[0].y + 0.5f; + texCoordsLeftTop[1].y = texCoordsRightBottom[1].y + 0.5f; + texCoordsLeftTop[2].y = texCoordsRightBottom[2].y + 0.5f; + texCoordsLeftTop[3].y = texCoordsRightBottom[3].y + 0.5f; + } + break; + } + default: + break; + } +} +#endif + }; // namespace android diff --git a/services/surfaceflinger/ExSurfaceFlinger/ExLayer.h b/services/surfaceflinger/ExSurfaceFlinger/ExLayer.h index 01c74a810..9d22b5f52 100644 --- a/services/surfaceflinger/ExSurfaceFlinger/ExLayer.h +++ b/services/surfaceflinger/ExSurfaceFlinger/ExLayer.h @@ -43,6 +43,22 @@ class ExSurfaceFlinger; class ExLayer : public Layer { public: +#ifdef QTI_BSP + enum { + /* + * HWC S3D_MODE is set by HWC driver to indicate that HWC driver can not support + * S3D standalone, need surfaceflinger help to draw layers twice to construct + * S3D framebuffer target. + */ + HWC_S3DMODE_NONE = 0x00000000, + HWC_S3DMODE_LR = 0x00000001, + HWC_S3DMODE_RL = 0x00000002, + HWC_S3DMODE_TB = 0x00000003, + HWC_S3DMODE_FP = 0x00000004, + HWC_S3DMODE_MAX = 0x00000005, + }; +#endif + ExLayer(SurfaceFlinger* flinger, const sp& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags); virtual ~ExLayer(); @@ -57,11 +73,27 @@ public: HWComposer::HWCLayerInterface& layer); virtual bool canAllowGPUForProtected() const; +#ifdef QTI_BSP + virtual void computeGeometryS3D(const sp& hw, Mesh& mesh, + Mesh& meshLeftTop, Mesh &meshRightBottom, uint32_t s3d_fmt) const; +#endif protected: bool mDebugLogs; bool isDebug() { return mDebugLogs; } bool mIsGPUAllowedForProtected; + bool mIsHDMIPrimary; + +private: +#ifdef QTI_BSP + // The mesh used to draw the layer in GLES composition mode for s3d left/top + mutable Mesh mMeshLeftTop; + // The mesh used to draw the layer in GLES composition mode for s3d right/bottom + mutable Mesh mMeshRightBottom; + + virtual void drawWithOpenGL(const sp& hw, const Region& clip, + bool useIdentityTransform) const; }; +#endif }; // namespace android diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 02d6f1639..0d6ec41ee 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -162,8 +162,13 @@ public: uint32_t getTransactionFlags(uint32_t flags); uint32_t setTransactionFlags(uint32_t flags); +#ifdef QTI_BSP + virtual void computeGeometry(const sp& hw, Mesh& mesh, + bool useIdentityTransform) const; +#else void computeGeometry(const sp& hw, Mesh& mesh, bool useIdentityTransform) const; +#endif Rect computeBounds(const Region& activeTransparentRegion) const; Rect computeBounds() const; @@ -392,9 +397,14 @@ private: // drawing void clearWithOpenGL(const sp& hw, const Region& clip, float r, float g, float b, float alpha) const; +#ifdef QTI_BSP + virtual void drawWithOpenGL(const sp& hw, const Region& clip, + bool useIdentityTransform) const; +#else void drawWithOpenGL(const sp& hw, const Region& clip, bool useIdentityTransform) const; +#endif // Temporary - Used only for LEGACY camera mode. uint32_t getProducerStickyTransform() const; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 97d3163eb..693e9d90f 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -74,6 +74,7 @@ #include "DisplayHardware/FramebufferSurface.h" #include "DisplayHardware/HWComposer.h" +#include "ExSurfaceFlinger/ExHWComposer.h" #include "DisplayHardware/VirtualDisplaySurface.h" #include "Effects/Daltonizer.h" @@ -2003,7 +2004,12 @@ bool SurfaceFlinger::doComposeSurfaces(const sp& hw, const } // Never touch the framebuffer if we don't have any framebuffer layers +#ifdef QTI_BSP + const bool hasHwcComposition = hwc.hasHwcComposition(id) | + (reinterpret_cast(&hwc))->getS3DFlag(id); +#else const bool hasHwcComposition = hwc.hasHwcComposition(id); +#endif if (hasHwcComposition) { // when using overlays, we assume a fully transparent framebuffer // NOTE: we could reduce how much we need to clear, for instance diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 20d65c1ae..2003d6efa 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -146,6 +146,9 @@ private: friend class DisplayEventConnection; friend class Layer; friend class LayerDim; +#ifdef QTI_BSP + friend class ExLayer; +#endif friend class MonitoredProducer; friend class LayerBlur; From f5486d6f47d4649b983f5c4f2a6f52706c27fd09 Mon Sep 17 00:00:00 2001 From: Tatenda Chipeperekwa Date: Mon, 18 Apr 2016 16:26:19 -0700 Subject: [PATCH 34/49] sf: Allow HWC composition of virtual displays for HDMI primary Allow HWC composition of virtual displays for HDMI primary only when the output pixel format of the HDMI display is RGB. CRs-Fixed: 1007249 Change-Id: I9680b162d844e9e6397f919e8dcc1b1a948d182c --- services/surfaceflinger/DisplayUtils.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/services/surfaceflinger/DisplayUtils.cpp b/services/surfaceflinger/DisplayUtils.cpp index a07e69eda..abbb2d76c 100644 --- a/services/surfaceflinger/DisplayUtils.cpp +++ b/services/surfaceflinger/DisplayUtils.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -45,6 +45,8 @@ #include #include #include +#include +#include #endif #include #include @@ -176,8 +178,21 @@ bool DisplayUtils::canAllocateHwcDisplayIdForVDS(int usage) { #ifdef QTI_BSP #ifdef FORCE_HWC_COPY_FOR_VIRTUAL_DISPLAYS - // Reserve hardware acceleration for WFD use-case - flag_mask = GRALLOC_USAGE_PRIVATE_WFD; + int hdmi_node = qdutils::getHDMINode(); + if(hdmi_node == HWC_DISPLAY_PRIMARY) { + int active_config = qdutils::getActiveConfig(HWC_DISPLAY_PRIMARY); + if(active_config >= 0) { + qdutils::DisplayAttributes attr = qdutils::getDisplayAttributes(active_config, + HWC_DISPLAY_PRIMARY); + if(!attr.is_yuv) { + // Reserve hardware acceleration for WFD use-case + flag_mask = GRALLOC_USAGE_PRIVATE_WFD; + } + } + } else { + // Reserve hardware acceleration for WFD use-case + flag_mask = GRALLOC_USAGE_PRIVATE_WFD; + } #else // Don't allocate HWC display unless we force HWC copy, otherwise // incompatible buffers are sent to the media stack From 534f85743096c2ac853329ab239b204d96efe665 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Mon, 1 Aug 2016 01:31:00 -0700 Subject: [PATCH 35/49] surfaceflinger: Cleanups for blur * Dynamically load it so no direct linkage or headers are required. Change-Id: I4eba035f527ae4f0fa2485e24a8586145baf0adc --- services/surfaceflinger/Android.mk | 6 -- services/surfaceflinger/LayerBlur.cpp | 93 ++++++++++++++++++++++----- services/surfaceflinger/LayerBlur.h | 38 +++++++++-- 3 files changed, 109 insertions(+), 28 deletions(-) diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 4a6d32044..2d907fab2 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -129,12 +129,6 @@ ifeq ($(TARGET_USES_QCOM_BSP), true) ExSurfaceFlinger/ExHWComposer.cpp endif -ifeq ($(TARGET_HAVE_UI_BLUR),true) - LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/ui - LOCAL_SHARED_LIBRARIES += libuiblur - LOCAL_CFLAGS += -DUI_BLUR -endif - LOCAL_MODULE := libsurfaceflinger LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code diff --git a/services/surfaceflinger/LayerBlur.cpp b/services/surfaceflinger/LayerBlur.cpp index 4f5a72dc6..a49ff39d6 100644 --- a/services/surfaceflinger/LayerBlur.cpp +++ b/services/surfaceflinger/LayerBlur.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -90,16 +91,11 @@ static void setupMesh(Mesh& mesh, int width, int height, int viewportHeight) { texCoords[3] = vec2(1.0f, 1.0f); } - LayerBlur::LayerBlur(SurfaceFlinger* flinger, const sp& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags) - : Layer(flinger, client, name, w, h, flags), mBlurMaskSampling(1), mBlurMaskAlphaThreshold(0.0f) - ,mLastFrameSequence(0) + : Layer(flinger, client, name, w, h, flags), mBlurMaskSampling(1), + mBlurMaskAlphaThreshold(0.0f) ,mLastFrameSequence(0) { -#ifdef UI_BLUR - mBlurToken = qtiblur::initBlurToken(); -#endif - GLuint texnames[3]; mFlinger->getRenderEngine().genTextures(3, texnames); mTextureCapture.init(Texture::TEXTURE_2D, texnames[0]); @@ -108,9 +104,6 @@ LayerBlur::LayerBlur(SurfaceFlinger* flinger, const sp& client, } LayerBlur::~LayerBlur() { -#ifdef UI_BLUR - qtiblur::releaseBlurToken(mBlurToken); -#endif releaseFbo(mFboCapture); releaseFbo(mFboMasking); @@ -168,18 +161,15 @@ void LayerBlur::onDraw(const sp& hw, const Region& /*clip*/ // blur size_t outTexWidth = mTextureBlur.getWidth(); size_t outTexHeight = mTextureBlur.getHeight(); -#ifdef UI_BLUR - if (!qtiblur::blur(mBlurToken, - s.blur, + if (mBlurImpl.blur(s.blur, mTextureCapture.getTextureName(), mTextureCapture.getWidth(), mTextureCapture.getHeight(), mTextureBlur.getTextureName(), &outTexWidth, - &outTexHeight)) { + &outTexHeight) != OK) { return; } -#endif // mTextureBlur now has "Blurred image" mTextureBlur.setDimensions(outTexWidth, outTexHeight); @@ -411,6 +401,79 @@ void LayerBlur::ensureFbo(FBO& fbo, int width, int height, int textureName) { } } +// --------------------------------------------------------------------------- + +void* LayerBlur::BlurImpl::sLibHandle = NULL; + +LayerBlur::BlurImpl::initBlurTokenFn LayerBlur::BlurImpl::initBlurToken = NULL; +LayerBlur::BlurImpl::releaseBlurTokenFn LayerBlur::BlurImpl::releaseBlurToken = NULL; +LayerBlur::BlurImpl::blurFn LayerBlur::BlurImpl::doBlur = NULL; +Mutex LayerBlur::BlurImpl::sLock; + +void LayerBlur::BlurImpl::closeBlurImpl() { + if (sLibHandle != NULL) { + dlclose(sLibHandle); + sLibHandle = NULL; + } +} + +status_t LayerBlur::BlurImpl::initBlurImpl() { + if (sLibHandle != NULL) { + return OK; + } + sLibHandle = dlopen("libuiblur.so", RTLD_NOW); + if (sLibHandle == NULL) { + return NO_INIT; + } + + // happy happy joy joy! + + initBlurToken = (initBlurTokenFn)dlsym(sLibHandle, + "_ZN7qtiblur13initBlurTokenEv"); + releaseBlurToken = (releaseBlurTokenFn)dlsym(sLibHandle, + "_ZN7qtiblur16releaseBlurTokenEPv"); + + if (sizeof(size_t) == 4) { + doBlur = (blurFn)dlsym(sLibHandle, + "_ZN7qtiblur4blurEPvijjjjPjS1_"); + } else if (sizeof(size_t) == 8) { + doBlur = (blurFn)dlsym(sLibHandle, + "_ZN7qtiblur4blurEPvijmmjPmS1_"); + } + + if (!initBlurToken || !releaseBlurToken || !doBlur) { + ALOGE("dlsym failed for blur impl!: %s", dlerror()); + closeBlurImpl(); + return NO_INIT; + } + + return OK; +} + +LayerBlur::BlurImpl::BlurImpl() { + Mutex::Autolock _l(sLock); + if (initBlurImpl() == OK) { + mToken = initBlurToken(); + } +} + +LayerBlur::BlurImpl::~BlurImpl() { + Mutex::Autolock _l(sLock); + if (mToken != NULL) { + releaseBlurToken(mToken); + } +} + +status_t LayerBlur::BlurImpl::blur(int level, uint32_t inId, size_t inWidth, size_t inHeight, + uint32_t outId, size_t* outWidth, size_t* outHeight) { + Mutex::Autolock _l(sLock); + if (mToken == NULL) { + return NO_INIT; + } + return doBlur(mToken, level, inId, inWidth, inHeight, + outId, outWidth, outHeight) ? OK : NO_INIT; +} + // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/LayerBlur.h b/services/surfaceflinger/LayerBlur.h index 251423e81..63138c4c2 100644 --- a/services/surfaceflinger/LayerBlur.h +++ b/services/surfaceflinger/LayerBlur.h @@ -20,15 +20,12 @@ #ifndef ANDROID_LAYER_BLUR_H #define ANDROID_LAYER_BLUR_H +#include #include #include #include "Layer.h" -#ifdef UI_BLUR -#include "Blur.h" // libuiblur.so -#endif - // --------------------------------------------------------------------------- namespace android { @@ -58,9 +55,36 @@ public: virtual bool setBlurMaskAlphaThreshold(float alpha) { mBlurMaskAlphaThreshold = alpha; return true; } private: -#ifdef UI_BLUR - qtiblur::BLUR_TOKEN mBlurToken; -#endif + class BlurImpl { + public: + + BlurImpl(); + ~BlurImpl(); + + status_t blur(int level, uint32_t inId, size_t inWidth, size_t inheight, + uint32_t outId, size_t* outWidth, size_t* outHeight); + + protected: + static status_t initBlurImpl(); + static void closeBlurImpl(); + static void* sLibHandle; + + typedef void* (*initBlurTokenFn)(); + typedef void* (*releaseBlurTokenFn)(void*); + typedef void* (*blurFn)(void*, int, uint32_t, size_t, size_t, uint32_t, size_t*, size_t*); + + static initBlurTokenFn initBlurToken; + static releaseBlurTokenFn releaseBlurToken; + static blurFn doBlur; + + static Mutex sLock; + + private: + void* mToken; + }; + + BlurImpl mBlurImpl; + wp mBlurMaskLayer; int32_t mBlurMaskSampling; float mBlurMaskAlphaThreshold; From 193a8c93342e0b0677540cc70850e43317c54992 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Mon, 1 Aug 2016 13:21:58 -0700 Subject: [PATCH 36/49] surfaceflinger: Isolate S3D code to msm8996 only Change-Id: Ie4b77b55eb306c795b452c59d8ae3383bd2804bc --- services/surfaceflinger/Android.mk | 3 +++ services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp | 2 +- services/surfaceflinger/ExSurfaceFlinger/ExLayer.cpp | 8 ++++---- services/surfaceflinger/SurfaceFlinger.cpp | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 2d907fab2..0bbdac015 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -122,6 +122,9 @@ ifeq ($(TARGET_USES_QCOM_BSP), true) LOCAL_SHARED_LIBRARIES += libqdutils LOCAL_SHARED_LIBRARIES += libqdMetaData LOCAL_CFLAGS += -DQTI_BSP + ifeq ($(call is-board-platform-in-list,msm8996),true) + LOCAL_CFLAGS += -DSDM_TARGET + endif LOCAL_SRC_FILES += \ ExSurfaceFlinger/ExLayer.cpp \ ExSurfaceFlinger/ExSurfaceFlinger.cpp \ diff --git a/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp b/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp index 6b228ed85..64a67e5db 100644 --- a/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp +++ b/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp @@ -76,7 +76,7 @@ bool ExHWComposer::isCompositionTypeBlit(const int32_t compType) const { return false; } -#ifdef QTI_BSP +#if defined(QTI_BSP) && defined(SDM_TARGET) uint32_t ExHWComposer::getS3DFlag(int disp) const { const DisplayData& disp_data(mDisplayData[disp]); diff --git a/services/surfaceflinger/ExSurfaceFlinger/ExLayer.cpp b/services/surfaceflinger/ExSurfaceFlinger/ExLayer.cpp index 5df34edf6..875d47fd6 100644 --- a/services/surfaceflinger/ExSurfaceFlinger/ExLayer.cpp +++ b/services/surfaceflinger/ExSurfaceFlinger/ExLayer.cpp @@ -221,7 +221,7 @@ bool ExLayer::canAllowGPUForProtected() const { void ExLayer::drawWithOpenGL(const sp& hw, const Region& /* clip */, bool useIdentityTransform) const { const State& s(getDrawingState()); -#ifdef QTI_BSP +#if defined(QTI_BSP) && defined(SDM_TARGET) uint32_t s3d_fmt = 0; private_handle_t *pvt_handle = static_cast (const_cast(mActiveBuffer->handle)); @@ -278,14 +278,14 @@ void ExLayer::drawWithOpenGL(const sp& hw, texCoords[2] = vec2(right, 1.0f - bottom); texCoords[3] = vec2(right, 1.0f - top); -#ifdef QTI_BSP +#if defined(QTI_BSP) && defined(SDM_TARGET) computeGeometryS3D(hw, mMesh, mMeshLeftTop, mMeshRightBottom, s3d_fmt); #endif RenderEngine& engine(mFlinger->getRenderEngine()); engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha); -#ifdef QTI_BSP +#if defined(QTI_BSP) && defined(SDM_TARGET) if (s3d_fmt != HWC_S3DMODE_NONE) { engine.setScissor(0, 0, hw->getWidth(), hw->getHeight()); engine.drawMesh(mMeshLeftTop); @@ -293,7 +293,7 @@ void ExLayer::drawWithOpenGL(const sp& hw, } else { #endif engine.drawMesh(mMesh); -#ifdef QTI_BSP +#if defined(QTI_BSP) && defined(SDM_TARGET) } #endif diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 693e9d90f..3070e45fd 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2004,7 +2004,7 @@ bool SurfaceFlinger::doComposeSurfaces(const sp& hw, const } // Never touch the framebuffer if we don't have any framebuffer layers -#ifdef QTI_BSP +#if defined(QTI_BSP) && defined(SDM_TARGET) const bool hasHwcComposition = hwc.hasHwcComposition(id) | (reinterpret_cast(&hwc))->getS3DFlag(id); #else From b86bb46b4d252bee6e9120b4f9eda5ac8619f67c Mon Sep 17 00:00:00 2001 From: dianlujitao Date: Tue, 2 Aug 2016 20:11:17 +0800 Subject: [PATCH 37/49] sf: Fix compliation for non-8996 platforms Change-Id: I3edad5934ef9d9ec523e091fa2c959bbc9770f29 --- services/surfaceflinger/DisplayUtils.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/services/surfaceflinger/DisplayUtils.cpp b/services/surfaceflinger/DisplayUtils.cpp index abbb2d76c..e618e89fa 100644 --- a/services/surfaceflinger/DisplayUtils.cpp +++ b/services/surfaceflinger/DisplayUtils.cpp @@ -45,9 +45,11 @@ #include #include #include +#ifdef SDM_TARGET #include #include #endif +#endif #include #include @@ -178,6 +180,7 @@ bool DisplayUtils::canAllocateHwcDisplayIdForVDS(int usage) { #ifdef QTI_BSP #ifdef FORCE_HWC_COPY_FOR_VIRTUAL_DISPLAYS +#ifdef SDM_TARGET int hdmi_node = qdutils::getHDMINode(); if(hdmi_node == HWC_DISPLAY_PRIMARY) { int active_config = qdutils::getActiveConfig(HWC_DISPLAY_PRIMARY); @@ -190,9 +193,12 @@ bool DisplayUtils::canAllocateHwcDisplayIdForVDS(int usage) { } } } else { +#endif // Reserve hardware acceleration for WFD use-case flag_mask = GRALLOC_USAGE_PRIVATE_WFD; +#ifdef SDM_TARGET } +#endif #else // Don't allocate HWC display unless we force HWC copy, otherwise // incompatible buffers are sent to the media stack From 52b8462635f1e807a88784634161f3b7598e1b7b Mon Sep 17 00:00:00 2001 From: Anjaneya Prasad Musunuri Date: Tue, 5 Jul 2016 10:35:59 +0530 Subject: [PATCH 38/49] surfaceflinger: Add check for number of queued buffers Pop buffer item from shadow queue only when number of queued buffer items is greater than zero. Change-Id: I039bc133842293c29e3e130efd65f521ef0049c6 CRs-Fixed: 1009466 --- services/surfaceflinger/Layer.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 3e932df74..6a9cdb7a4 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1448,11 +1448,16 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) // Remove any stale buffers that have been dropped during // updateTexImage - while (mQueueItems[0].mFrameNumber != currentFrameNumber) { + while ((mQueuedFrames > 0) && (mQueueItems[0].mFrameNumber != currentFrameNumber)) { mQueueItems.removeAt(0); android_atomic_dec(&mQueuedFrames); } + if (mQueuedFrames == 0) { + ALOGE("[%s] mQueuedFrames is zero !!", mName.string()); + return outDirtyRegion; + } + mQueueItems.removeAt(0); } From da998f4845d4a4a783620bdd81d1c2feb9d404d3 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Wed, 3 Aug 2016 15:02:31 -0700 Subject: [PATCH 39/49] surfaceflinger: Unbreak casting and other use cases * If QCOM WFD isn't in use, we'll get -1 here. Don't try and dig into the array because we'll get some random memory back. Change-Id: Ib14642fea760dc0e659473bb183c5e0116622302 --- services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp b/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp index 64a67e5db..a9934051e 100644 --- a/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp +++ b/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp @@ -78,6 +78,10 @@ bool ExHWComposer::isCompositionTypeBlit(const int32_t compType) const { #if defined(QTI_BSP) && defined(SDM_TARGET) uint32_t ExHWComposer::getS3DFlag(int disp) const { + if (disp < 0) { + return 0; + } + const DisplayData& disp_data(mDisplayData[disp]); for (size_t i=0 ; inumHwLayers-1; i++) { From 542b068e322f90e7e6689daddddc493363d0b549 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Wed, 3 Aug 2016 15:28:43 -0700 Subject: [PATCH 40/49] surfaceflinger: Fix uninitialized variable * And don't try to reinit the lib after a failure. Change-Id: Ic055a48670ed8cf01e27b16c5d4ddf214db53d20 --- services/surfaceflinger/LayerBlur.cpp | 9 ++++++++- services/surfaceflinger/LayerBlur.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/services/surfaceflinger/LayerBlur.cpp b/services/surfaceflinger/LayerBlur.cpp index a49ff39d6..93f548f0a 100644 --- a/services/surfaceflinger/LayerBlur.cpp +++ b/services/surfaceflinger/LayerBlur.cpp @@ -404,6 +404,7 @@ void LayerBlur::ensureFbo(FBO& fbo, int width, int height, int textureName) { // --------------------------------------------------------------------------- void* LayerBlur::BlurImpl::sLibHandle = NULL; +bool LayerBlur::BlurImpl::sUnsupported = false; LayerBlur::BlurImpl::initBlurTokenFn LayerBlur::BlurImpl::initBlurToken = NULL; LayerBlur::BlurImpl::releaseBlurTokenFn LayerBlur::BlurImpl::releaseBlurToken = NULL; @@ -421,8 +422,13 @@ status_t LayerBlur::BlurImpl::initBlurImpl() { if (sLibHandle != NULL) { return OK; } + if (sUnsupported) { + return NO_INIT; + } + sLibHandle = dlopen("libuiblur.so", RTLD_NOW); if (sLibHandle == NULL) { + sUnsupported = true; return NO_INIT; } @@ -444,13 +450,14 @@ status_t LayerBlur::BlurImpl::initBlurImpl() { if (!initBlurToken || !releaseBlurToken || !doBlur) { ALOGE("dlsym failed for blur impl!: %s", dlerror()); closeBlurImpl(); + sUnsupported = true; return NO_INIT; } return OK; } -LayerBlur::BlurImpl::BlurImpl() { +LayerBlur::BlurImpl::BlurImpl() : mToken(NULL) { Mutex::Autolock _l(sLock); if (initBlurImpl() == OK) { mToken = initBlurToken(); diff --git a/services/surfaceflinger/LayerBlur.h b/services/surfaceflinger/LayerBlur.h index 63138c4c2..bd37ad37d 100644 --- a/services/surfaceflinger/LayerBlur.h +++ b/services/surfaceflinger/LayerBlur.h @@ -68,6 +68,7 @@ private: static status_t initBlurImpl(); static void closeBlurImpl(); static void* sLibHandle; + static bool sUnsupported; typedef void* (*initBlurTokenFn)(); typedef void* (*releaseBlurTokenFn)(void*); From 3b418d69a3e1b3594aec4ad065a47353da407e12 Mon Sep 17 00:00:00 2001 From: FPtje Date: Wed, 3 Aug 2016 20:37:46 -0500 Subject: [PATCH 41/49] Fixed stylus eraser being rejected by palm rejection The stylus eraser appeared not to work, i.e. Android did not respond to input from the eraser. It turned out that all input except stylus input is rejected when palm rejection is activated. The problem was that the eraser itself activates palm rejection when it hovers. The solution is to allow the eraser during palm rejection. This solution makes sense because the eraser input works in the exact same way as normal stylus input. Change-Id: I9c7451112ce7dbca14a1e1694eedca2d4ed041a1 --- services/inputflinger/InputReader.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp index 53ff1557b..6cfdcebfc 100644 --- a/services/inputflinger/InputReader.cpp +++ b/services/inputflinger/InputReader.cpp @@ -6167,7 +6167,8 @@ nsecs_t TouchInputMapper::mLastStylusTime = 0; bool TouchInputMapper::rejectPalm(nsecs_t when) { return (when - mLastStylusTime < mConfig.stylusPalmRejectionTime) && - mPointerSimple.currentProperties.toolType != AMOTION_EVENT_TOOL_TYPE_STYLUS; + mPointerSimple.currentProperties.toolType != AMOTION_EVENT_TOOL_TYPE_STYLUS && + mPointerSimple.currentProperties.toolType != AMOTION_EVENT_TOOL_TYPE_ERASER; } void TouchInputMapper::cancelTouch(nsecs_t when) { From a5f80a555ab379546d4f96368b98bbf969229821 Mon Sep 17 00:00:00 2001 From: Namit Solanki Date: Fri, 29 Jul 2016 15:19:44 +0530 Subject: [PATCH 42/49] surfaceflinger: Access s3d flags only for valid display ID. - Check if display id is within display ID range. Negative display ids lead to undefined behavior in CTS tests. Change-Id: I2db8caf8d7ac65700e5bc37c180763357cc90aad CRs-Fixed: 1043297 --- services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp b/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp index a9934051e..92cc1a784 100644 --- a/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp +++ b/services/surfaceflinger/ExSurfaceFlinger/ExHWComposer.cpp @@ -82,6 +82,9 @@ uint32_t ExHWComposer::getS3DFlag(int disp) const { return 0; } + if (!mHwc || uint32_t(disp) >= MAX_HWC_DISPLAYS || !mAllocatedDisplayIDs.hasBit(disp)) + return 0; + const DisplayData& disp_data(mDisplayData[disp]); for (size_t i=0 ; inumHwLayers-1; i++) { From 94774ac01d1953bcc7a70a7018267ee34793d3f7 Mon Sep 17 00:00:00 2001 From: Alex Naidis Date: Sun, 14 Aug 2016 21:48:27 -0400 Subject: [PATCH 43/49] dalvik: rework 3 and 4-GB dalvik heap configurations The previous configuration sets target utilization as .25, which is geared towards low memory devices. This path increases it to .75 and makes us pass the check: (heaptargetutilization / 2) * heapsize = heapgrowthlimit Example: heapgrowthlimit: 256m heapsize: 512m heaptargetutilization: 0.75 0.75/2 * 512 = 192 To pass the check this has to be true: 192 = 256 (WRONG) Check not passed. This new configuration is optimized for higher RAM devices and passes the check: heapgrowthlimit: 384m heapsize: 1024m heaptargetutilization: 0.75 0.75/2 * 1024 = 384 384 = 384 (TRUE) Check passed. Change-Id: I6839339382229da80546761c3746a032081ff2cd Signed-off-by: Alex Naidis --- build/phone-xxhdpi-3072-dalvik-heap.mk | 4 ++-- build/phone-xxxhdpi-3072-dalvik-heap.mk | 4 ++-- build/phone-xxxhdpi-4096-dalvik-heap.mk | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build/phone-xxhdpi-3072-dalvik-heap.mk b/build/phone-xxhdpi-3072-dalvik-heap.mk index 450f4e1f8..57eeb6eb9 100644 --- a/build/phone-xxhdpi-3072-dalvik-heap.mk +++ b/build/phone-xxhdpi-3072-dalvik-heap.mk @@ -18,8 +18,8 @@ PRODUCT_PROPERTY_OVERRIDES += \ dalvik.vm.heapstartsize=8m \ - dalvik.vm.heapgrowthlimit=256m \ - dalvik.vm.heapsize=512m \ + dalvik.vm.heapgrowthlimit=384m \ + dalvik.vm.heapsize=1024m \ dalvik.vm.heaptargetutilization=0.75 \ dalvik.vm.heapminfree=512k \ dalvik.vm.heapmaxfree=8m diff --git a/build/phone-xxxhdpi-3072-dalvik-heap.mk b/build/phone-xxxhdpi-3072-dalvik-heap.mk index 3bf65a783..88e2e709e 100644 --- a/build/phone-xxxhdpi-3072-dalvik-heap.mk +++ b/build/phone-xxxhdpi-3072-dalvik-heap.mk @@ -18,8 +18,8 @@ PRODUCT_PROPERTY_OVERRIDES += \ dalvik.vm.heapstartsize=8m \ - dalvik.vm.heapgrowthlimit=256m \ - dalvik.vm.heapsize=512m \ + dalvik.vm.heapgrowthlimit=384m \ + dalvik.vm.heapsize=1024m \ dalvik.vm.heaptargetutilization=0.75 \ dalvik.vm.heapminfree=2m \ dalvik.vm.heapmaxfree=8m diff --git a/build/phone-xxxhdpi-4096-dalvik-heap.mk b/build/phone-xxxhdpi-4096-dalvik-heap.mk index 67f94f4f9..0e125574f 100644 --- a/build/phone-xxxhdpi-4096-dalvik-heap.mk +++ b/build/phone-xxxhdpi-4096-dalvik-heap.mk @@ -18,8 +18,8 @@ PRODUCT_PROPERTY_OVERRIDES += \ dalvik.vm.heapstartsize=8m \ - dalvik.vm.heapgrowthlimit=256m \ - dalvik.vm.heapsize=512m \ - dalvik.vm.heaptargetutilization=0.25 \ + dalvik.vm.heapgrowthlimit=384m \ + dalvik.vm.heapsize=1024m \ + dalvik.vm.heaptargetutilization=0.75 \ dalvik.vm.heapminfree=4m \ dalvik.vm.heapmaxfree=16m From 07cd4cdf216f5120a7c593991d54492f8ae29f6f Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Wed, 13 Jul 2016 14:11:57 -0700 Subject: [PATCH 44/49] Region: Detect malicious overflow in unflatten Bug 29983260 Change-Id: Ib6e1cb8ae279010c5e9960aaa03513f55b7d873b --- libs/ui/Region.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp index 3810da404..cfed7a984 100644 --- a/libs/ui/Region.cpp +++ b/libs/ui/Region.cpp @@ -795,6 +795,11 @@ status_t Region::unflatten(void const* buffer, size_t size) { return NO_MEMORY; } + if (numRects > (UINT32_MAX / sizeof(Rect))) { + android_errorWriteWithInfoLog(0x534e4554, "29983260", -1, NULL, 0); + return NO_MEMORY; + } + Region result; result.mStorage.clear(); for (size_t r = 0; r < numRects; ++r) { From 2a2b06df1b33458a95131c0c564d12bb95726c90 Mon Sep 17 00:00:00 2001 From: Abhisek Devkota Date: Wed, 17 Aug 2016 09:04:42 -0700 Subject: [PATCH 45/49] Fix xxxhdpi 3072 heap sizes Bootloops on shamu with current values Fix for 94774ac01d1953bcc7a70a7018267ee34793d3f7 Change-Id: Iade253bd8bc5074486d2d69bb9c738844615b08d --- build/phone-xxxhdpi-3072-dalvik-heap.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/phone-xxxhdpi-3072-dalvik-heap.mk b/build/phone-xxxhdpi-3072-dalvik-heap.mk index 88e2e709e..56a10dde4 100644 --- a/build/phone-xxxhdpi-3072-dalvik-heap.mk +++ b/build/phone-xxxhdpi-3072-dalvik-heap.mk @@ -18,8 +18,8 @@ PRODUCT_PROPERTY_OVERRIDES += \ dalvik.vm.heapstartsize=8m \ - dalvik.vm.heapgrowthlimit=384m \ - dalvik.vm.heapsize=1024m \ + dalvik.vm.heapgrowthlimit=288m \ + dalvik.vm.heapsize=768m \ dalvik.vm.heaptargetutilization=0.75 \ dalvik.vm.heapminfree=2m \ dalvik.vm.heapmaxfree=8m From b7021eff8d1f415bed0ac5a84f21e6bc99ae4b85 Mon Sep 17 00:00:00 2001 From: Abhisek Devkota Date: Wed, 17 Aug 2016 09:04:42 -0700 Subject: [PATCH 46/49] Fix xxhdpi 3072 heap sizes Bootloops on r7 with current values Fix for 94774ac01d1953bcc7a70a7018267ee34793d3f7 Change-Id: I248a9375735a261715668494da0d0ab5a6440d42 --- build/phone-xxhdpi-3072-dalvik-heap.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/phone-xxhdpi-3072-dalvik-heap.mk b/build/phone-xxhdpi-3072-dalvik-heap.mk index 57eeb6eb9..3598f5a1b 100644 --- a/build/phone-xxhdpi-3072-dalvik-heap.mk +++ b/build/phone-xxhdpi-3072-dalvik-heap.mk @@ -18,8 +18,8 @@ PRODUCT_PROPERTY_OVERRIDES += \ dalvik.vm.heapstartsize=8m \ - dalvik.vm.heapgrowthlimit=384m \ - dalvik.vm.heapsize=1024m \ + dalvik.vm.heapgrowthlimit=288m \ + dalvik.vm.heapsize=768m \ dalvik.vm.heaptargetutilization=0.75 \ dalvik.vm.heapminfree=512k \ dalvik.vm.heapmaxfree=8m From 60f8bdfb455f0c1ff61c32427cc7de0389517257 Mon Sep 17 00:00:00 2001 From: "Christopher N. Hesse" Date: Fri, 29 Apr 2016 16:21:35 +0200 Subject: [PATCH 47/49] surfaceflinger: Add support for Exynos HWC services Change-Id: I600e946a22064d64549e266c5a3cf452d0cf6299 --- services/surfaceflinger/Android.mk | 18 ++++++++++++ services/surfaceflinger/SurfaceFlinger.cpp | 32 ++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 0bbdac015..25fa503be 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -132,6 +132,24 @@ ifeq ($(TARGET_USES_QCOM_BSP), true) ExSurfaceFlinger/ExHWComposer.cpp endif +ifeq ($(BOARD_USES_HWC_SERVICES), true) + LOCAL_CFLAGS += -DUSES_HWC_SERVICES + LOCAL_SHARED_LIBRARIES += libExynosHWCService + LOCAL_C_INCLUDES += \ + $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \ + $(TOP)/hardware/samsung_slsi-$(TARGET_SLSI_VARIANT)/$(TARGET_BOARD_PLATFORM)/libhwcService \ + $(TOP)/hardware/samsung_slsi-$(TARGET_SLSI_VARIANT)/$(TARGET_BOARD_PLATFORM)/include \ + $(TOP)/hardware/samsung_slsi-$(TARGET_SLSI_VARIANT)/$(TARGET_SOC)/include \ + $(TOP)/hardware/samsung_slsi-$(TARGET_SLSI_VARIANT)/$(TARGET_SOC)/libhwcmodule \ + $(TOP)/hardware/samsung_slsi-$(TARGET_SLSI_VARIANT)/exynos/libhwc \ + $(TOP)/hardware/samsung_slsi-$(TARGET_SLSI_VARIANT)/exynos/include \ + $(TOP)/hardware/samsung_slsi-$(TARGET_SLSI_VARIANT)/exynos/libexynosutils \ + $(TOP)/system/core/libsync/include + +LOCAL_ADDITIONAL_DEPENDENCIES := \ + $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr +endif + LOCAL_MODULE := libsurfaceflinger LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 3070e45fd..441bad892 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -83,6 +83,10 @@ #include #include "DisplayUtils.h" +#ifdef USES_HWC_SERVICES +#include "ExynosHWCService.h" +#endif + #define DISPLAY_COUNT 1 /* @@ -131,6 +135,10 @@ static sp lastSurfaceViewLayer; // --------------------------------------------------------------------------- +#ifdef USES_HWC_SERVICES +static bool notifyPSRExit = true; +#endif + SurfaceFlinger::SurfaceFlinger() : BnSurfaceComposer(), mTransactionFlags(0), @@ -313,6 +321,14 @@ void SurfaceFlinger::bootFinished() // formerly we would just kill the process, but we now ask it to exit so it // can choose where to stop the animation. property_set("service.bootanim.exit", "1"); + +#ifdef USES_HWC_SERVICES + sp sm = defaultServiceManager(); + sp hwc = + interface_cast(sm->getService(String16("Exynos.HWCService"))); + ALOGD("boot finished. Inform HWC"); + hwc->setBootFinished(); +#endif } void SurfaceFlinger::deleteTextureAsync(uint32_t texture) { @@ -799,6 +815,19 @@ void SurfaceFlinger::signalTransaction() { } void SurfaceFlinger::signalLayerUpdate() { +#ifdef USES_HWC_SERVICES + if (notifyPSRExit) { + notifyPSRExit = false; + sp sm = defaultServiceManager(); + sp hwcService = + interface_cast( + sm->getService(String16("Exynos.HWCService"))); + if (hwcService != NULL) + hwcService->notifyPSRExit(); + else + ALOGE("HWCService::notifyPSRExit failed"); + } +#endif mEventQueue.invalidate(); } @@ -983,6 +1012,9 @@ void SurfaceFlinger::handleMessageRefresh() { doDebugFlashRegions(); doComposition(); postComposition(); +#ifdef USES_HWC_SERVICES + notifyPSRExit = true; +#endif } previousExpectedPresent = mPrimaryDispSync.computeNextRefresh(0); From dbee7f4650dfb419d12ebaf13e96bc54ae880b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Mon, 1 Aug 2016 16:05:17 -0700 Subject: [PATCH 48/49] DO NOT MERGE ServiceManager: Restore basic uid check Prevent apps from registering services without relying on selinux checks. Bug: 29431260 Change-Id: I38c6e8bc7f7cba1cbd3568e8fed1ae7ac2054a9b (cherry picked from commit f03ba2c0d878071603d73b7f8e9a4a468364ac27) --- cmds/servicemanager/service_manager.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c index 7fa9a39f7..4c993c236 100644 --- a/cmds/servicemanager/service_manager.c +++ b/cmds/servicemanager/service_manager.c @@ -107,9 +107,14 @@ static bool check_mac_perms_from_lookup(pid_t spid, const char *perm, const char return allowed; } -static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid) +static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid) { const char *perm = "add"; + + if (uid >= AID_APP) { + return 0; /* Don't allow apps to register services */ + } + return check_mac_perms_from_lookup(spid, perm, str8(name, name_len)) ? 1 : 0; } @@ -204,7 +209,7 @@ int do_add_service(struct binder_state *bs, if (!handle || (len == 0) || (len > 127)) return -1; - if (!svc_can_register(s, len, spid)) { + if (!svc_can_register(s, len, spid, uid)) { ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n", str8(s, len), handle, uid); return -1; From 390c2d3512fcbf0f4e1890baef12f3bd1d23dc56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Thu, 18 Aug 2016 15:42:35 -0700 Subject: [PATCH 49/49] ServiceManager: Allow system services running as secondary users to add services This should be reverted when all system services have been cleaned up to not do this. A process looking up a service while running in the background will see the service registered by the active user (assuming the service is registered on every user switch), not the service registered by the user that the process itself belongs to. BUG: 30795333 Change-Id: I1b74d58be38ed358f43c163692f9e704f8f31dbe (cherry picked from commit e6bbe69ba739c8a08837134437aaccfea5f1d943) --- cmds/servicemanager/Android.mk | 2 +- cmds/servicemanager/service_manager.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cmds/servicemanager/Android.mk b/cmds/servicemanager/Android.mk index 155cfc503..5bafd5343 100644 --- a/cmds/servicemanager/Android.mk +++ b/cmds/servicemanager/Android.mk @@ -18,7 +18,7 @@ LOCAL_MODULE_TAGS := optional include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) -LOCAL_SHARED_LIBRARIES := liblog libselinux +LOCAL_SHARED_LIBRARIES := liblog libcutils libselinux LOCAL_SRC_FILES := service_manager.c binder.c LOCAL_CFLAGS += $(svc_c_flags) LOCAL_MODULE := servicemanager diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c index 4c993c236..031f84897 100644 --- a/cmds/servicemanager/service_manager.c +++ b/cmds/servicemanager/service_manager.c @@ -8,6 +8,8 @@ #include #include +#include + #include #include @@ -111,7 +113,7 @@ static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, u { const char *perm = "add"; - if (uid >= AID_APP) { + if (multiuser_get_app_id(uid) >= AID_APP) { return 0; /* Don't allow apps to register services */ }