From b3a9e6d04da503026b33a66f276a7753dcc11a3b Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Thu, 11 Feb 2016 18:01:49 -0800 Subject: 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 bb3e1b0..158eeb4 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 -- cgit v1.1 From 25719f6e1f7e892df17b6f7eb4d6fc8c1fcc35f3 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Fri, 5 Feb 2016 19:02:56 -0800 Subject: 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 e9891a8..fb8d620 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; } // --------------------------------------------------------------------------- -- cgit v1.1 From 5243afa8fa719e3cc6d1af4333986b2d7ee5e737 Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Sat, 20 Feb 2016 11:26:13 -0800 Subject: 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 158eeb4..7504ed4 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); } -- cgit v1.1 From 28a83d4206e97c149a72408bc76c6487f57ed1b4 Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Thu, 11 Feb 2016 18:01:49 -0800 Subject: 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 bb3e1b0..158eeb4 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 -- cgit v1.1 From a5d2913b0744054cacf3cbf66bd629fdc8105e07 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Fri, 5 Feb 2016 19:02:56 -0800 Subject: 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 e9891a8..fb8d620 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; } // --------------------------------------------------------------------------- -- cgit v1.1 From a93a31018795eab0b031ebc66475f46a79b7c7ab Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Sat, 20 Feb 2016 11:26:13 -0800 Subject: 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 158eeb4..7504ed4 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); } -- cgit v1.1 From a30d7d90c4f718e46fb41a99b3d52800e1011b73 Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Tue, 15 Mar 2016 18:10:49 -0700 Subject: 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 c4660ba..7ae82e0 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 1099c84..c3c6235 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; -- cgit v1.1 From a59b827869a2ea04022dd225007f29af8d61837a Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Mon, 21 Mar 2016 10:36:54 -0700 Subject: 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 ef88181..af18e11 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); -- cgit v1.1 From 2b4df0ba7c6094da732cfd754d64241df2c153d2 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Tue, 12 Apr 2016 13:14:26 -0700 Subject: 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 a457019..40e5da1 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 1f7601a..20d65c1 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+ -- cgit v1.1 From 573fb3e32d8d479c06813b153c82f1e48e36ae4c Mon Sep 17 00:00:00 2001 From: Khalid Zubair Date: Tue, 19 Apr 2016 10:46:48 -0700 Subject: 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 28af943..8ab145a 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); -- cgit v1.1 From ec0faee33a521407bd7c0259b958ca27241677e1 Mon Sep 17 00:00:00 2001 From: Khalid Zubair Date: Wed, 20 Apr 2016 14:13:35 -0700 Subject: 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 8ab145a..3d9dcd0 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; } -- cgit v1.1 From 03a53d1c7765eeb3af0bc34c3dff02ada1953fbf Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Tue, 22 Mar 2016 16:52:13 -0700 Subject: 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 617175b..82fc659 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 0fba1bf..c9e876f 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 98355c6..1c054f5 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 fda3ffa..1b913c5 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 42457ce..0ac7fce 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; }; -- cgit v1.1 From 3ce4ffc46e31f4dd7ca89da1af0c40086f51a01e Mon Sep 17 00:00:00 2001 From: "Christopher N. Hesse" Date: Sun, 24 Apr 2016 19:30:35 +0200 Subject: 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 ++++ services/surfaceflinger/DisplayHardware/HWComposer.cpp | 16 ++++++++++++++++ 4 files changed, 33 insertions(+) diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk index e952a38..870c2bd 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 4d9eaf5..2f6bc79 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 c1ddba1..6a90083 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 a43597a..17e91d9 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), -- cgit v1.1 From bd41ea359f925cea37627cf66758f63b34950aa8 Mon Sep 17 00:00:00 2001 From: Danesh M Date: Fri, 6 May 2016 00:11:27 -0700 Subject: 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 ++- services/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 0000000..c46eaeb --- /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 6dd8bad..c346a2f 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 196ef3e..02d6f16 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 dcde512..2ef2a50 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); + } +} } -- cgit v1.1 From 09217544156808716a80e8f3922813f4b4924b79 Mon Sep 17 00:00:00 2001 From: Louis Popi Date: Wed, 11 May 2016 22:48:52 +0200 Subject: 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 0000000..450f4e1 --- /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 0000000..217bfb8 --- /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 -- cgit v1.1 From ea0ee316d82c24fe6863fb9fdb00f8fe0c02a705 Mon Sep 17 00:00:00 2001 From: Scott Mertz Date: Wed, 25 May 2016 15:50:02 -0700 Subject: 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 a2e4f4b..5b9a42f 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); -- cgit v1.1 From 54cb02ad733fb71b1bdf78590428817fb780aff8 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Tue, 26 Apr 2016 08:44:09 -0700 Subject: 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 22d7ef3..4a660d1 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) { -- cgit v1.1 From 6500d428ce816ffa0ba099221a4987ad7bfcb4ab Mon Sep 17 00:00:00 2001 From: Louis Popi Date: Wed, 4 May 2016 20:17:24 +0200 Subject: 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 0000000..67f94f4 --- /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 0000000..98cef64 --- /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 -- cgit v1.1 From 2a2eaab883bd243493407cce47382d372f207492 Mon Sep 17 00:00:00 2001 From: "Christopher N. Hesse" Date: Fri, 17 Jun 2016 16:10:21 +0200 Subject: 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 f597b73..92ccf2f 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; -- cgit v1.1 From 3bcf0caa8cca9143443814b36676b3bae33a4368 Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Thu, 26 May 2016 15:35:55 -0700 Subject: 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 5fdf94d..6bfe635 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. -- cgit v1.1 From 0c5f3af37ab6b38125984405ee022c0b1799e6a9 Mon Sep 17 00:00:00 2001 From: radhakrishna Date: Fri, 31 Oct 2014 15:48:14 +0530 Subject: 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 c346a2f..69e5c68 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); -- cgit v1.1 From e481771aa3de37a8cf01a36c5637f0cc48506205 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 27 Jan 2016 08:02:48 -0800 Subject: 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 cf22e58..1aaee92 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); -- cgit v1.1 From d70043eaf41b911c464cf62d5f79aac8697aeb6b Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 27 Jan 2016 08:02:48 -0800 Subject: 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 1aaee92..56890a2 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); -- cgit v1.1 From 839f0dd9641f23d6c0a1b1aff48e533621ded51d Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Tue, 2 Feb 2016 10:27:03 -0800 Subject: 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 56890a2..65e67d6 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; -- cgit v1.1 From a5761b164a27d2894f8abc0652dd8cda7326f564 Mon Sep 17 00:00:00 2001 From: Arne Coucheron Date: Wed, 20 Jul 2016 00:46:07 +0200 Subject: 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 69e5c68..14bd312 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) { -- cgit v1.1 From 95cda3b92faf69f2ed594ee87a7e1e7499bd0060 Mon Sep 17 00:00:00 2001 From: Haixia Shi Date: Wed, 28 Oct 2015 13:22:22 -0700 Subject: 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 73b3897..dda896e 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 ebe19a5..fabb875 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; -- cgit v1.1 From 179bd77ab69361f3f26a50e01781be9cad78a4d1 Mon Sep 17 00:00:00 2001 From: Haixia Shi Date: Wed, 28 Oct 2015 16:19:01 -0700 Subject: 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 dda896e..192d746 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 fabb875..61d891b 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; -- cgit v1.1 From c91bafb88a3abf50c369637caf79fb027b48c46e Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Wed, 7 Oct 2015 16:38:42 -0700 Subject: 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 5b9a42f..475f7e3 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"); -- cgit v1.1 From a887c19994c7873fbe651e2fe944a176576a6198 Mon Sep 17 00:00:00 2001 From: Saurabh Shah Date: Mon, 21 Mar 2016 17:25:23 -0700 Subject: 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 92ccf2f..b83149b 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 f492a42..9023ce9 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 021978d..4f5a72d 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 40e5da1..97d3163 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 -- cgit v1.1 From d67b177ff6a6dbbd950f1aaa84669351d6f26b9e Mon Sep 17 00:00:00 2001 From: Ramkumar Radhakrishnan Date: Wed, 18 May 2016 18:56:05 -0700 Subject: 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 96d4b1d..7be0328 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); -- cgit v1.1 From 1ecb999624165ea2a9cf5e16b3f7e93358d503d6 Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Wed, 13 Jul 2016 14:11:57 -0700 Subject: 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 3810da4..cfed7a9 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) { -- cgit v1.1 From 8cafa373aa14b21981627e0ba9ea96731254183d Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Sun, 24 Jul 2016 16:19:39 -0700 Subject: 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 14bd312..3e932df 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) { -- cgit v1.1 From 537364c7229cb7d5d63b4683a34e47db6aa013bd Mon Sep 17 00:00:00 2001 From: feifanz Date: Wed, 27 Apr 2016 12:23:28 +0800 Subject: 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 + .../surfaceflinger/DisplayHardware/HWComposer.h | 1 + .../ExSurfaceFlinger/ExHWComposer.cpp | 23 +++ .../surfaceflinger/ExSurfaceFlinger/ExHWComposer.h | 4 + .../surfaceflinger/ExSurfaceFlinger/ExLayer.cpp | 184 ++++++++++++++++++++- services/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 6a90083..4a6d320 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 9bdb7de..efdcd03 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 2b41098..6b228ed 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 2016ff0..06ee32b 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 fa45579..5df34ed 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 01c74a8..9d22b5f 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 02d6f16..0d6ec41 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 97d3163..693e9d9 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 20d65c1..2003d6e 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; -- cgit v1.1 From f5486d6f47d4649b983f5c4f2a6f52706c27fd09 Mon Sep 17 00:00:00 2001 From: Tatenda Chipeperekwa Date: Mon, 18 Apr 2016 16:26:19 -0700 Subject: 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 a07e69e..abbb2d7 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 -- cgit v1.1 From 534f85743096c2ac853329ab239b204d96efe665 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Mon, 1 Aug 2016 01:31:00 -0700 Subject: 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 4a6d320..2d907fa 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 4f5a72d..a49ff39 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 251423e..63138c4 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; -- cgit v1.1 From 193a8c93342e0b0677540cc70850e43317c54992 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Mon, 1 Aug 2016 13:21:58 -0700 Subject: 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 2d907fa..0bbdac0 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 6b228ed..64a67e5 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 5df34ed..875d47f 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 693e9d9..3070e45 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 -- cgit v1.1 From b86bb46b4d252bee6e9120b4f9eda5ac8619f67c Mon Sep 17 00:00:00 2001 From: dianlujitao Date: Tue, 2 Aug 2016 20:11:17 +0800 Subject: 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 abbb2d7..e618e89 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 -- cgit v1.1 From 52b8462635f1e807a88784634161f3b7598e1b7b Mon Sep 17 00:00:00 2001 From: Anjaneya Prasad Musunuri Date: Tue, 5 Jul 2016 10:35:59 +0530 Subject: 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 3e932df..6a9cdb7 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); } -- cgit v1.1 From da998f4845d4a4a783620bdd81d1c2feb9d404d3 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Wed, 3 Aug 2016 15:02:31 -0700 Subject: 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 64a67e5..a993405 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++) { -- cgit v1.1 From 542b068e322f90e7e6689daddddc493363d0b549 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Wed, 3 Aug 2016 15:28:43 -0700 Subject: 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 a49ff39..93f548f 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 63138c4..bd37ad3 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*); -- cgit v1.1 From 3b418d69a3e1b3594aec4ad065a47353da407e12 Mon Sep 17 00:00:00 2001 From: FPtje Date: Wed, 3 Aug 2016 20:37:46 -0500 Subject: 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 53ff155..6cfdceb 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) { -- cgit v1.1 From a5f80a555ab379546d4f96368b98bbf969229821 Mon Sep 17 00:00:00 2001 From: Namit Solanki Date: Fri, 29 Jul 2016 15:19:44 +0530 Subject: 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 a993405..92cc1a7 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++) { -- cgit v1.1 From 94774ac01d1953bcc7a70a7018267ee34793d3f7 Mon Sep 17 00:00:00 2001 From: Alex Naidis Date: Sun, 14 Aug 2016 21:48:27 -0400 Subject: 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 450f4e1..57eeb6e 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 3bf65a7..88e2e70 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 67f94f4..0e12557 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 -- cgit v1.1 From 07cd4cdf216f5120a7c593991d54492f8ae29f6f Mon Sep 17 00:00:00 2001 From: Pablo Ceballos Date: Wed, 13 Jul 2016 14:11:57 -0700 Subject: 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 3810da4..cfed7a9 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) { -- cgit v1.1 From 2a2b06df1b33458a95131c0c564d12bb95726c90 Mon Sep 17 00:00:00 2001 From: Abhisek Devkota Date: Wed, 17 Aug 2016 09:04:42 -0700 Subject: 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 88e2e70..56a10dd 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 -- cgit v1.1 From b7021eff8d1f415bed0ac5a84f21e6bc99ae4b85 Mon Sep 17 00:00:00 2001 From: Abhisek Devkota Date: Wed, 17 Aug 2016 09:04:42 -0700 Subject: 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 57eeb6e..3598f5a 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 -- cgit v1.1 From 60f8bdfb455f0c1ff61c32427cc7de0389517257 Mon Sep 17 00:00:00 2001 From: "Christopher N. Hesse" Date: Fri, 29 Apr 2016 16:21:35 +0200 Subject: 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 0bbdac0..25fa503 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 3070e45..441bad8 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); -- cgit v1.1 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: 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 7fa9a39..4c993c2 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; -- cgit v1.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: 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 155cfc5..5bafd53 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 4c993c2..031f848 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 */ } -- cgit v1.1