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(-) (limited to 'services') 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(+) (limited to 'services') 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(-) (limited to 'services') 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 --- services/inputflinger/InputDispatcher.cpp | 29 +++++++++++++++++++++++++++++ services/inputflinger/InputDispatcher.h | 9 ++++++++- services/inputflinger/InputWindow.cpp | 11 +++++++++-- services/inputflinger/InputWindow.h | 2 ++ 4 files changed, 48 insertions(+), 3 deletions(-) (limited to 'services') 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 --- services/surfaceflinger/Android.mk | 4 ++++ services/surfaceflinger/DisplayHardware/HWComposer.cpp | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) (limited to 'services') 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 (limited to 'services') 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 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(-) (limited to 'services') 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 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(+) (limited to 'services') 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 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(-) (limited to 'services') 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(-) (limited to 'services') 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(-) (limited to 'services') 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 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(-) (limited to 'services') 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(+) (limited to 'services') 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 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(-) (limited to 'services') 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(-) (limited to 'services') 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(-) (limited to 'services') 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(-) (limited to 'services') 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(-) (limited to 'services') 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(+) (limited to 'services') 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(-) (limited to 'services') 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(+) (limited to 'services') 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(-) (limited to 'services') 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(-) (limited to 'services') 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(+) (limited to 'services') 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 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(+) (limited to 'services') 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