diff options
25 files changed, 543 insertions, 309 deletions
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp index 63376116a0..3ada15398c 100644 --- a/cmds/dumpsys/tests/dumpsys_test.cpp +++ b/cmds/dumpsys/tests/dumpsys_test.cpp @@ -74,7 +74,7 @@ class WriteOnFdAction : public ActionInterface<WriteOnFdFunction> { explicit WriteOnFdAction(const std::string& output) : output_(output) { } virtual Result Perform(const ArgumentTuple& args) { - int fd = ::std::tr1::get<0>(args); + int fd = ::testing::get<0>(args); android::base::WriteStringToFd(output_, fd); } diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp index 96d8c47a8a..7291ef3afa 100644 --- a/cmds/installd/otapreopt.cpp +++ b/cmds/installd/otapreopt.cpp @@ -88,6 +88,12 @@ static_assert(DEXOPT_MASK == (0x1dfe | DEXOPT_IDLE_BACKGROUND_JOB), "DEXOPT_MASK unexpected."); +template<typename T> +static constexpr bool IsPowerOfTwo(T x) { + static_assert(std::is_integral<T>::value, "T must be integral"); + // TODO: assert unsigned. There is currently many uses with signed values. + return (x & (x - 1)) == 0; +} template<typename T> static constexpr T RoundDown(T x, typename std::decay<T>::type n) { diff --git a/cmds/surfacereplayer/replayer/Android.bp b/cmds/surfacereplayer/replayer/Android.bp index 5caceec89f..7632311906 100644 --- a/cmds/surfacereplayer/replayer/Android.bp +++ b/cmds/surfacereplayer/replayer/Android.bp @@ -1,6 +1,5 @@ cc_library_shared { name: "libsurfacereplayer", - clang: true, srcs: [ "BufferQueueScheduler.cpp", "Event.cpp", @@ -16,7 +15,6 @@ cc_library_shared { "-Wno-float-equal", "-Wno-sign-conversion", "-Wno-padded", - "-std=c++14", ], static_libs: [ "libtrace_proto", @@ -41,7 +39,6 @@ cc_library_shared { cc_binary { name: "surfacereplayer", - clang: true, srcs: [ "Main.cpp", ], @@ -61,6 +58,5 @@ cc_binary { "-Wno-float-conversion", "-Wno-disabled-macro-expansion", "-Wno-float-equal", - "-std=c++14", ], } diff --git a/libs/binder/BufferedTextOutput.cpp b/libs/binder/BufferedTextOutput.cpp index 0946aca876..d516eb1d54 100644 --- a/libs/binder/BufferedTextOutput.cpp +++ b/libs/binder/BufferedTextOutput.cpp @@ -25,6 +25,7 @@ #include <private/binder/Static.h> +#include <pthread.h> #include <stdio.h> #include <stdlib.h> @@ -87,7 +88,7 @@ struct BufferedTextOutput::ThreadState Vector<sp<BufferedTextOutput::BufferState> > states; }; -static mutex_t gMutex; +static pthread_mutex_t gMutex = PTHREAD_MUTEX_INITIALIZER; static thread_store_t tls; @@ -113,7 +114,7 @@ static int32_t allocBufferIndex() { int32_t res = -1; - mutex_lock(&gMutex); + pthread_mutex_lock(&gMutex); if (gFreeBufferIndex >= 0) { res = gFreeBufferIndex; @@ -125,17 +126,17 @@ static int32_t allocBufferIndex() gTextBuffers.add(-1); } - mutex_unlock(&gMutex); + pthread_mutex_unlock(&gMutex); return res; } static void freeBufferIndex(int32_t idx) { - mutex_lock(&gMutex); + pthread_mutex_lock(&gMutex); gTextBuffers.editItemAt(idx) = gFreeBufferIndex; gFreeBufferIndex = idx; - mutex_unlock(&gMutex); + pthread_mutex_unlock(&gMutex); } // --------------------------------------------------------------------------- diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp index 961f1011e0..a8ef7a051d 100644 --- a/libs/graphicsenv/GraphicsEnv.cpp +++ b/libs/graphicsenv/GraphicsEnv.cpp @@ -56,7 +56,7 @@ void GraphicsEnv::setDriverPath(const std::string path) { mDriverPath = path; } -void GraphicsEnv::setLayerPaths(android_namespace_t* appNamespace, const std::string layerPaths) { +void GraphicsEnv::setLayerPaths(NativeLoaderNamespace* appNamespace, const std::string layerPaths) { if (mLayerPaths.empty()) { mLayerPaths = layerPaths; mAppNamespace = appNamespace; @@ -66,7 +66,7 @@ void GraphicsEnv::setLayerPaths(android_namespace_t* appNamespace, const std::st } } -android_namespace_t* GraphicsEnv::getAppNamespace() { +NativeLoaderNamespace* GraphicsEnv::getAppNamespace() { return mAppNamespace; } diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h index 213580c20b..17e8f6ba47 100644 --- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h +++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h @@ -23,6 +23,8 @@ struct android_namespace_t; namespace android { +class NativeLoaderNamespace; + class GraphicsEnv { public: static GraphicsEnv& getInstance(); @@ -35,8 +37,8 @@ public: void setDriverPath(const std::string path); android_namespace_t* getDriverNamespace(); - void setLayerPaths(android_namespace_t* appNamespace, const std::string layerPaths); - android_namespace_t* getAppNamespace(); + void setLayerPaths(NativeLoaderNamespace* appNamespace, const std::string layerPaths); + NativeLoaderNamespace* getAppNamespace(); const std::string getLayerPaths(); void setDebugLayers(const std::string layers); @@ -48,7 +50,7 @@ private: std::string mDebugLayers; std::string mLayerPaths; android_namespace_t* mDriverNamespace = nullptr; - android_namespace_t* mAppNamespace = nullptr; + NativeLoaderNamespace* mAppNamespace = nullptr; }; } // namespace android diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp index 254038b0ad..03824795ed 100644 --- a/libs/ui/GraphicBuffer.cpp +++ b/libs/ui/GraphicBuffer.cpp @@ -123,7 +123,6 @@ void GraphicBuffer::dumpAllocationsToSystemLog() ANativeWindowBuffer* GraphicBuffer::getNativeBuffer() const { - LOG_ALWAYS_FATAL_IF(this == NULL, "getNativeBuffer() called on NULL GraphicBuffer"); return static_cast<ANativeWindowBuffer*>( const_cast<GraphicBuffer*>(this)); } diff --git a/libs/vr/libpdx/service_tests.cpp b/libs/vr/libpdx/service_tests.cpp index e623abf6eb..938d73774e 100644 --- a/libs/vr/libpdx/service_tests.cpp +++ b/libs/vr/libpdx/service_tests.cpp @@ -51,22 +51,24 @@ MATCHER_P2(IoVecMatcher, ptr, size, "") { // method(IoVecMatcher(IoVecArray{{ptr1, size1}, {ptr2, size2}}))); using IoVecArray = std::vector<iovec>; MATCHER_P(IoVecMatcher, iovec_array, "") { + auto local_arg = arg; for (const iovec& item : iovec_array) { - if (arg->iov_base != item.iov_base || arg->iov_len != item.iov_len) + if (local_arg->iov_base != item.iov_base || local_arg->iov_len != item.iov_len) return false; - arg++; + local_arg++; } return true; } using IoVecData = std::vector<std::string>; MATCHER_P(IoVecDataMatcher, iovec_data, "") { + auto local_arg = arg; for (const std::string& item : iovec_data) { - std::string data{reinterpret_cast<const char*>(arg->iov_base), - arg->iov_len}; + std::string data{reinterpret_cast<const char*>(local_arg->iov_base), + local_arg->iov_len}; if (data != item) return false; - arg++; + local_arg++; } return true; } diff --git a/services/batteryservice/Android.bp b/services/batteryservice/Android.bp index 7e2f648520..66ee8ff55e 100644 --- a/services/batteryservice/Android.bp +++ b/services/batteryservice/Android.bp @@ -1,6 +1,7 @@ cc_library_headers { name: "libbatteryservice_headers", vendor_available: true, + recovery_available: true, export_include_dirs: ["include"], header_libs: ["libutils_headers"], export_header_lib_headers: ["libutils_headers"], diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index e128df700b..75d8942f69 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -160,6 +160,8 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform) const { ATRACE_CALL(); + CompositionInfo& compositionInfo = getBE().compositionInfo; + if (CC_UNLIKELY(mActiveBuffer == 0)) { // the texture has not been created yet, this Layer has // in fact never been drawn into. This happens frequently with @@ -241,6 +243,7 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight()); mTexture.setFiltering(useFiltering); mTexture.setMatrix(textureMatrix); + compositionInfo.re.texture = mTexture; engine.setupLayerTexturing(mTexture); } else { @@ -250,6 +253,23 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, engine.disableTexturing(); } +void BufferLayer::drawNow(const RenderArea& renderArea, bool useIdentityTransform) const { + CompositionInfo& compositionInfo = getBE().compositionInfo; + auto& engine(mFlinger->getRenderEngine()); + + draw(renderArea, useIdentityTransform); + + engine.setupLayerTexturing(compositionInfo.re.texture); + engine.setupLayerBlending(compositionInfo.re.preMultipliedAlpha, compositionInfo.re.opaque, + false, compositionInfo.re.color); + engine.setSourceDataSpace(compositionInfo.hwc.dataspace); + engine.setSourceY410BT2020(compositionInfo.re.Y410BT2020); + engine.drawMesh(getBE().getMesh()); + engine.disableBlending(); + engine.disableTexturing(); + engine.setSourceY410BT2020(false); +} + void BufferLayer::onLayerDisplayed(const sp<Fence>& releaseFence) { mConsumer->setReleaseFence(releaseFence); } @@ -613,37 +633,14 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& display) { const auto& viewport = display->getViewport(); Region visible = tr.transform(visibleRegion.intersect(viewport)); const auto displayId = display->getId(); - if (!hasHwcLayer(displayId)) { - ALOGE("[%s] failed to setPerFrameData: no HWC layer found (%d)", - mName.string(), displayId); - return; - } - auto& hwcInfo = getBE().mHwcLayers[displayId]; - auto& hwcLayer = hwcInfo.layer; - auto error = hwcLayer->setVisibleRegion(visible); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(), - to_string(error).c_str(), static_cast<int32_t>(error)); - visible.dump(LOG_TAG); - } - error = hwcLayer->setSurfaceDamage(surfaceDamageRegion); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(), - to_string(error).c_str(), static_cast<int32_t>(error)); - surfaceDamageRegion.dump(LOG_TAG); - } + getBE().compositionInfo.hwc.visibleRegion = visible; + getBE().compositionInfo.hwc.surfaceDamage = surfaceDamageRegion; // Sideband layers if (getBE().compositionInfo.hwc.sidebandStream.get()) { setCompositionType(displayId, HWC2::Composition::Sideband); - ALOGV("[%s] Requesting Sideband composition", mName.string()); - error = hwcLayer->setSidebandStream(getBE().compositionInfo.hwc.sidebandStream->handle()); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(), - getBE().compositionInfo.hwc.sidebandStream->handle(), to_string(error).c_str(), - static_cast<int32_t>(error)); - } + getBE().compositionInfo.compositionType = HWC2::Composition::Sideband; return; } @@ -656,31 +653,14 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& display) { setCompositionType(displayId, HWC2::Composition::Device); } - ALOGV("setPerFrameData: dataspace = %d", mCurrentDataSpace); - error = hwcLayer->setDataspace(mCurrentDataSpace); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentDataSpace, - to_string(error).c_str(), static_cast<int32_t>(error)); - } - - const HdrMetadata& metadata = mConsumer->getCurrentHdrMetadata(); - error = hwcLayer->setPerFrameMetadata(display->getSupportedPerFrameMetadata(), metadata); - if (error != HWC2::Error::None && error != HWC2::Error::Unsupported) { - ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(), - to_string(error).c_str(), static_cast<int32_t>(error)); - } - - uint32_t hwcSlot = 0; - sp<GraphicBuffer> hwcBuffer; - hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot, &hwcBuffer); + getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace; + getBE().compositionInfo.hwc.hdrMetadata = mConsumer->getCurrentHdrMetadata(); + getBE().compositionInfo.hwc.supportedPerFrameMetadata = display->getSupportedPerFrameMetadata(); auto acquireFence = mConsumer->getCurrentFence(); - error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), - getBE().compositionInfo.mBuffer->handle, to_string(error).c_str(), - static_cast<int32_t>(error)); - } + getBE().compositionInfo.mBufferSlot = mActiveBufferSlot; + getBE().compositionInfo.mBuffer = mActiveBuffer; + getBE().compositionInfo.hwc.fence = acquireFence; } bool BufferLayer::isOpaque(const Layer::State& s) const { diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index 7f5ff3f066..0886f17e91 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -101,6 +101,7 @@ public: */ void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform) const override; + void drawNow(const RenderArea& renderArea, bool useIdentityTransform) const; void onLayerDisplayed(const sp<Fence>& releaseFence) override; diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp index aebe4eae9a..bf4a859c53 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -46,16 +46,27 @@ void ColorLayer::onDraw(const RenderArea& renderArea, const Region& /* clip */, bool useIdentityTransform) const { half4 color = getColor(); if (color.a > 0) { - Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2); - computeGeometry(renderArea, mesh, useIdentityTransform); - auto& engine(mFlinger->getRenderEngine()); - engine.setupLayerBlending(getPremultipledAlpha(), false /* opaque */, - true /* disableTexture */, color); - engine.drawMesh(mesh); - engine.disableBlending(); + computeGeometry(renderArea, getBE().mMesh, useIdentityTransform); + getBE().compositionInfo.re.preMultipliedAlpha = getPremultipledAlpha(); + getBE().compositionInfo.re.opaque = false; + getBE().compositionInfo.re.disableTexture = true; + getBE().compositionInfo.re.color = color; } } +void ColorLayer::drawNow(const RenderArea& renderArea, bool useIdentityTransform) const { + CompositionInfo& compositionInfo = getBE().compositionInfo; + auto& engine(mFlinger->getRenderEngine()); + + draw(renderArea, useIdentityTransform); + + engine.setupLayerBlending(compositionInfo.re.preMultipliedAlpha, compositionInfo.re.opaque, + compositionInfo.re.disableTexture, compositionInfo.re.color); + engine.setSourceDataSpace(compositionInfo.hwc.dataspace); + engine.drawMesh(getBE().getMesh()); + engine.disableBlending(); +} + bool ColorLayer::isVisible() const { const Layer::State& s(getDrawingState()); return !isHiddenByPolicy() && s.color.a; @@ -66,43 +77,18 @@ void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& display) { const auto& viewport = display->getViewport(); Region visible = tr.transform(visibleRegion.intersect(viewport)); const auto displayId = display->getId(); - if (!hasHwcLayer(displayId)) { - ALOGE("[%s] failed to setPerFrameData: no HWC layer found (%d)", - mName.string(), displayId); - return; - } - auto& hwcInfo = getBE().mHwcLayers[displayId]; - auto& hwcLayer = hwcInfo.layer; - auto error = hwcLayer->setVisibleRegion(visible); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(), - to_string(error).c_str(), static_cast<int32_t>(error)); - visible.dump(LOG_TAG); - } + getBE().compositionInfo.hwc.visibleRegion = visible; + getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace; setCompositionType(displayId, HWC2::Composition::SolidColor); - error = hwcLayer->setDataspace(mCurrentDataSpace); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentDataSpace, - to_string(error).c_str(), static_cast<int32_t>(error)); - } - half4 color = getColor(); - error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)), - static_cast<uint8_t>(std::round(255.0f * color.g)), - static_cast<uint8_t>(std::round(255.0f * color.b)), 255}); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(), - static_cast<int32_t>(error)); - } + getBE().compositionInfo.hwc.color = { static_cast<uint8_t>(std::round(255.0f * color.r)), + static_cast<uint8_t>(std::round(255.0f * color.g)), + static_cast<uint8_t>(std::round(255.0f * color.b)), 255 }; // Clear out the transform, because it doesn't make sense absent a source buffer - error = hwcLayer->setTransform(HWC2::Transform::None); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), to_string(error).c_str(), - static_cast<int32_t>(error)); - } + getBE().compositionInfo.hwc.transform = HWC2::Transform::None; } // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h index 3408045224..8417135ed2 100644 --- a/services/surfaceflinger/ColorLayer.h +++ b/services/surfaceflinger/ColorLayer.h @@ -32,6 +32,7 @@ public: virtual const char* getTypeId() const { return "ColorLayer"; } virtual void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform) const; + void drawNow(const RenderArea& , bool ) const; bool isVisible() const override; void setPerFrameData(const sp<const DisplayDevice>& display) override; diff --git a/services/surfaceflinger/ContainerLayer.cpp b/services/surfaceflinger/ContainerLayer.cpp index f259d93c3f..320c0df86a 100644 --- a/services/surfaceflinger/ContainerLayer.cpp +++ b/services/surfaceflinger/ContainerLayer.cpp @@ -30,6 +30,8 @@ ContainerLayer::ContainerLayer(SurfaceFlinger* flinger, const sp<Client>& client void ContainerLayer::onDraw(const RenderArea&, const Region& /* clip */, bool) const {} +void ContainerLayer::drawNow(const RenderArea&, bool) const {} + bool ContainerLayer::isVisible() const { return !isHiddenByPolicy(); } diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h index 06cfbcd894..29a5c3a569 100644 --- a/services/surfaceflinger/ContainerLayer.h +++ b/services/surfaceflinger/ContainerLayer.h @@ -32,6 +32,7 @@ public: const char* getTypeId() const override { return "ContainerLayer"; } void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform) const override; + void drawNow(const RenderArea& renderArea, bool useIdentityTransform) const override; bool isVisible() const override; void setPerFrameData(const sp<const DisplayDevice>& display) override; diff --git a/services/surfaceflinger/DispSync.cpp b/services/surfaceflinger/DispSync.cpp index 37dc27d80d..eb271cdccf 100644 --- a/services/surfaceflinger/DispSync.cpp +++ b/services/surfaceflinger/DispSync.cpp @@ -28,7 +28,6 @@ #include <utils/String8.h> #include <utils/Thread.h> #include <utils/Trace.h> -#include <utils/Vector.h> #include <ui/FenceTime.h> @@ -94,7 +93,7 @@ public: nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); while (true) { - Vector<CallbackInvocation> callbackInvocations; + std::vector<CallbackInvocation> callbackInvocations; nsecs_t targetTime = 0; @@ -187,7 +186,7 @@ public: // allowing any past events to fire listener.mLastEventTime = systemTime() - mPeriod / 2 + mPhase - mWakeupLatency; - mEventListeners.push(listener); + mEventListeners.push_back(listener); mCond.signal(); @@ -198,9 +197,10 @@ public: if (kTraceDetailedInfo) ATRACE_CALL(); Mutex::Autolock lock(mMutex); - for (size_t i = 0; i < mEventListeners.size(); i++) { - if (mEventListeners[i].mCallback == callback) { - mEventListeners.removeAt(i); + for (std::vector<EventListener>::iterator it = mEventListeners.begin(); + it != mEventListeners.end(); ++it) { + if (it->mCallback == callback) { + mEventListeners.erase(it); mCond.signal(); return NO_ERROR; } @@ -213,11 +213,10 @@ public: if (kTraceDetailedInfo) ATRACE_CALL(); Mutex::Autolock lock(mMutex); - for (size_t i = 0; i < mEventListeners.size(); i++) { - if (mEventListeners[i].mCallback == callback) { - EventListener& listener = mEventListeners.editItemAt(i); - const nsecs_t oldPhase = listener.mPhase; - listener.mPhase = phase; + for (auto& eventListener : mEventListeners) { + if (eventListener.mCallback == callback) { + const nsecs_t oldPhase = eventListener.mPhase; + eventListener.mPhase = phase; // Pretend that the last time this event was handled at the same frame but with the // new offset to allow for a seamless offset change without double-firing or @@ -228,7 +227,7 @@ public: } else if (diff < -mPeriod / 2) { diff += mPeriod; } - listener.mLastEventTime -= diff; + eventListener.mLastEventTime -= diff; mCond.signal(); return NO_ERROR; } @@ -274,23 +273,23 @@ private: return nextEventTime; } - Vector<CallbackInvocation> gatherCallbackInvocationsLocked(nsecs_t now) { + std::vector<CallbackInvocation> gatherCallbackInvocationsLocked(nsecs_t now) { if (kTraceDetailedInfo) ATRACE_CALL(); ALOGV("[%s] gatherCallbackInvocationsLocked @ %" PRId64, mName, ns2us(now)); - Vector<CallbackInvocation> callbackInvocations; + std::vector<CallbackInvocation> callbackInvocations; nsecs_t onePeriodAgo = now - mPeriod; - for (size_t i = 0; i < mEventListeners.size(); i++) { - nsecs_t t = computeListenerNextEventTimeLocked(mEventListeners[i], onePeriodAgo); + for (auto& eventListener : mEventListeners) { + nsecs_t t = computeListenerNextEventTimeLocked(eventListener, onePeriodAgo); if (t < now) { CallbackInvocation ci; - ci.mCallback = mEventListeners[i].mCallback; + ci.mCallback = eventListener.mCallback; ci.mEventTime = t; - ALOGV("[%s] [%s] Preparing to fire", mName, mEventListeners[i].mName); - callbackInvocations.push(ci); - mEventListeners.editItemAt(i).mLastEventTime = t; + ALOGV("[%s] [%s] Preparing to fire", mName, eventListener.mName); + callbackInvocations.push_back(ci); + eventListener.mLastEventTime = t; } } @@ -348,7 +347,7 @@ private: return t; } - void fireCallbackInvocations(const Vector<CallbackInvocation>& callbacks) { + void fireCallbackInvocations(const std::vector<CallbackInvocation>& callbacks) { if (kTraceDetailedInfo) ATRACE_CALL(); for (size_t i = 0; i < callbacks.size(); i++) { callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime); @@ -366,7 +365,7 @@ private: int64_t mFrameNumber; - Vector<EventListener> mEventListeners; + std::vector<EventListener> mEventListeners; Mutex mMutex; Condition mCond; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 11c3db0228..4eedb1a13d 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -503,6 +503,9 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { } auto& hwcInfo = getBE().mHwcLayers[displayId]; + // Need to program geometry parts + getBE().compositionInfo.hwc.skipGeometry = false; + // enable this layer hwcInfo.forceClientComposition = false; @@ -510,8 +513,6 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { hwcInfo.forceClientComposition = true; } - auto& hwcLayer = hwcInfo.layer; - // this gives us only the "orientation" component of the transform const State& s(getDrawingState()); auto blendMode = HWC2::BlendMode::None; @@ -519,12 +520,7 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { blendMode = mPremultipliedAlpha ? HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage; } - auto error = hwcLayer->setBlendMode(blendMode); - ALOGE_IF(error != HWC2::Error::None, - "[%s] Failed to set blend mode %s:" - " %s (%d)", - mName.string(), to_string(blendMode).c_str(), to_string(error).c_str(), - static_cast<int32_t>(error)); + getBE().compositionInfo.hwc.blendMode = blendMode; // apply the layer's transform, followed by the display's global transform // here we're guaranteed that the layer's transform preserves rects @@ -567,36 +563,15 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { } const Transform& tr = display->getTransform(); Rect transformedFrame = tr.transform(frame); - error = hwcLayer->setDisplayFrame(transformedFrame); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)", mName.string(), - transformedFrame.left, transformedFrame.top, transformedFrame.right, - transformedFrame.bottom, to_string(error).c_str(), static_cast<int32_t>(error)); - } else { - hwcInfo.displayFrame = transformedFrame; - } + getBE().compositionInfo.hwc.displayFrame = transformedFrame; FloatRect sourceCrop = computeCrop(display); - error = hwcLayer->setSourceCrop(sourceCrop); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: " - "%s (%d)", - mName.string(), sourceCrop.left, sourceCrop.top, sourceCrop.right, sourceCrop.bottom, - to_string(error).c_str(), static_cast<int32_t>(error)); - } else { - hwcInfo.sourceCrop = sourceCrop; - } + getBE().compositionInfo.hwc.sourceCrop = sourceCrop; float alpha = static_cast<float>(getAlpha()); - error = hwcLayer->setPlaneAlpha(alpha); - ALOGE_IF(error != HWC2::Error::None, - "[%s] Failed to set plane alpha %.3f: " - "%s (%d)", - mName.string(), alpha, to_string(error).c_str(), static_cast<int32_t>(error)); + getBE().compositionInfo.hwc.alpha = alpha; - error = hwcLayer->setZOrder(z); - ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)", mName.string(), z, - to_string(error).c_str(), static_cast<int32_t>(error)); + getBE().compositionInfo.hwc.z = z; int type = s.type; int appId = s.appId; @@ -609,9 +584,8 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { } } - error = hwcLayer->setInfo(type, appId); - ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set info (%d)", mName.string(), - static_cast<int32_t>(error)); + getBE().compositionInfo.hwc.type = type; + getBE().compositionInfo.hwc.appId = appId; /* * Transformations are applied in this order: @@ -648,16 +622,11 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) { const uint32_t orientation = transform.getOrientation(); if (orientation & Transform::ROT_INVALID) { // we can only handle simple transformation - hwcInfo.forceClientComposition = true; + getBE().mHwcLayers[displayId].compositionType = HWC2::Composition::Client; } else { auto transform = static_cast<HWC2::Transform>(orientation); hwcInfo.transform = transform; - auto error = hwcLayer->setTransform(transform); - ALOGE_IF(error != HWC2::Error::None, - "[%s] Failed to set transform %s: " - "%s (%d)", - mName.string(), to_string(transform).c_str(), to_string(error).c_str(), - static_cast<int32_t>(error)); + getBE().compositionInfo.hwc.transform = transform; } } @@ -1498,17 +1467,16 @@ void Layer::miniDump(String8& result, int32_t displayId) const { result.appendFormat(" %s\n", name.string()); const Layer::State& layerState(getDrawingState()); - const LayerBE::HWCInfo& hwcInfo = getBE().mHwcLayers.at(displayId); if (layerState.zOrderRelativeOf != nullptr || mDrawingParent != nullptr) { result.appendFormat(" rel %6d | ", layerState.z); } else { result.appendFormat(" %10d | ", layerState.z); } result.appendFormat("%10s | ", to_string(getCompositionType(displayId)).c_str()); - result.appendFormat("%10s | ", to_string(hwcInfo.transform).c_str()); - const Rect& frame = hwcInfo.displayFrame; + result.appendFormat("%10s | ", to_string(getBE().mHwcLayers[displayId].transform).c_str()); + const Rect& frame = getBE().compositionInfo.hwc.displayFrame; result.appendFormat("%4d %4d %4d %4d | ", frame.left, frame.top, frame.right, frame.bottom); - const FloatRect& crop = hwcInfo.sourceCrop; + const FloatRect& crop = getBE().compositionInfo.hwc.sourceCrop; result.appendFormat("%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top, crop.right, crop.bottom); result.append("- - - - - - - - - - - - - - - -"); @@ -2004,6 +1972,16 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) layerInfo->set_refresh_pending(isBufferLatched()); layerInfo->set_window_type(state.type); layerInfo->set_app_id(state.appId); + layerInfo->set_curr_frame(mCurrentFrameNumber); + + for (const auto& pendingState : mPendingStates) { + auto barrierLayer = pendingState.barrierLayer.promote(); + if (barrierLayer != nullptr) { + BarrierLayerProto* barrierLayerProto = layerInfo->add_barrier_layer(); + barrierLayerProto->set_id(barrierLayer->sequence); + barrierLayerProto->set_frame_number(pendingState.frameNumber); + } + } } void Layer::writeToProto(LayerProto* layerInfo, int32_t displayId) { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 03720a9591..5107e6b32d 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -374,6 +374,16 @@ public: void draw(const RenderArea& renderArea) const; /* + * drawNow uses the renderEngine to draw the layer. This is different than the + * draw function as with the FE/BE split, the draw function runs in the FE and + * sets up state for the BE to do the actual drawing. drawNow is used to tell + * the layer to skip the state setup and just go ahead and draw the layer. This + * is used for screen captures which happens separately from the frame + * compositing path. + */ + virtual void drawNow(const RenderArea& renderArea, bool useIdentityTransform) const = 0; + + /* * doTransaction - process the transaction. This is a good place to figure * out which attributes of the surface have changed. */ @@ -462,6 +472,14 @@ public: return getBE().mHwcLayers[displayId].layer; } + bool setHwcLayer(int32_t hwcId) { + if (getBE().mHwcLayers.count(hwcId) == 0) { + return false; + } + getBE().compositionInfo.hwc.hwcLayer = getBE().mHwcLayers[hwcId].layer; + return true; + } + // ----------------------------------------------------------------------- void clearWithOpenGL(const RenderArea& renderArea) const; diff --git a/services/surfaceflinger/LayerBE.cpp b/services/surfaceflinger/LayerBE.cpp index bef051ff4d..51b615b586 100644 --- a/services/surfaceflinger/LayerBE.cpp +++ b/services/surfaceflinger/LayerBE.cpp @@ -57,7 +57,8 @@ void CompositionInfo::dumpRe(const char* tag) const { ALOGV("[%s]\tblackoutLayer=%d", tag, re.blackoutLayer); ALOGV("[%s]\tclearArea=%d", tag, re.clearArea); ALOGV("[%s]\tpreMultipliedAlpha=%d", tag, re.preMultipliedAlpha); - ALOGV("[%s]\topaque=%d\n", tag, re.opaque); + ALOGV("[%s]\topaque=%d", tag, re.opaque); + ALOGV("[%s]\tdisableTexture=%d", tag, re.disableTexture); ALOGV("[%s]\ttexture:name(%d), target(%d), size(%d/%d)", tag, re.texture.getTextureName(), re.texture.getTextureTarget(), (unsigned int)re.texture.getWidth(), (unsigned int)re.texture.getHeight()); ALOGV("[%s]\tuseIdentityTransform=%d\n", tag, re.useIdentityTransform); } diff --git a/services/surfaceflinger/LayerBE.h b/services/surfaceflinger/LayerBE.h index f610677dc0..680fbd049c 100644 --- a/services/surfaceflinger/LayerBE.h +++ b/services/surfaceflinger/LayerBE.h @@ -19,10 +19,9 @@ #include <stdint.h> #include <sys/types.h> +#include <gui/HdrMetadata.h> #include <ui/Region.h> -#include "SurfaceFlinger.h" - #include "DisplayHardware/HWComposer.h" #include "DisplayHardware/HWComposerBufferCache.h" #include "RenderEngine/Mesh.h" @@ -40,6 +39,7 @@ struct CompositionInfo { LayerBE* layer = nullptr; struct { HWC2::Layer* hwcLayer; + bool skipGeometry = true; sp<Fence> fence; HWC2::BlendMode blendMode = HWC2::BlendMode::Invalid; Rect displayFrame; @@ -52,8 +52,10 @@ struct CompositionInfo { Region visibleRegion; Region surfaceDamage; sp<NativeHandle> sidebandStream; - android_dataspace dataspace; + ui::Dataspace dataspace; hwc_color_t color; + bool supportedPerFrameMetadata = false; + HdrMetadata hdrMetadata; } hwc; struct { Mesh* mesh; @@ -61,9 +63,11 @@ struct CompositionInfo { bool clearArea = false; bool preMultipliedAlpha = false; bool opaque = false; + bool disableTexture = false; half4 color; Texture texture; bool useIdentityTransform = false; + bool Y410BT2020 = false; } re; void dump(const char* tag) const; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 7680f2a3aa..63e058ac17 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -114,6 +114,33 @@ using ui::Hdr; using ui::RenderIntent; namespace { + +#pragma clang diagnostic push +#pragma clang diagnostic error "-Wswitch-enum" + +bool isWideColorMode(const ColorMode colorMode) { + switch (colorMode) { + case ColorMode::DISPLAY_P3: + case ColorMode::ADOBE_RGB: + case ColorMode::DCI_P3: + case ColorMode::BT2020: + case ColorMode::BT2100_PQ: + case ColorMode::BT2100_HLG: + return true; + case ColorMode::NATIVE: + case ColorMode::STANDARD_BT601_625: + case ColorMode::STANDARD_BT601_625_UNADJUSTED: + case ColorMode::STANDARD_BT601_525: + case ColorMode::STANDARD_BT601_525_UNADJUSTED: + case ColorMode::STANDARD_BT709: + case ColorMode::SRGB: + return false; + } + return false; +} + +#pragma clang diagnostic pop + class ConditionalLock { public: ConditionalLock(Mutex& mutex, bool lock) : mMutex(mutex), mLocked(lock) { @@ -126,6 +153,7 @@ private: Mutex& mMutex; bool mLocked; }; + } // namespace anonymous // --------------------------------------------------------------------------- @@ -749,6 +777,7 @@ void SurfaceFlinger::init() { // set initial conditions (e.g. unblank default device) initializeDisplays(); + ALOGV("Displays initialized"); getBE().mRenderEngine->primeCache(); @@ -1429,9 +1458,13 @@ void SurfaceFlinger::updateVrFlinger() { Mutex::Autolock _l(mStateLock); - const auto display = getDefaultDisplayDeviceLocked(); + sp<DisplayDevice> display = getDefaultDisplayDeviceLocked(); LOG_ALWAYS_FATAL_IF(!display); const int currentDisplayPowerMode = display->getPowerMode(); + // This DisplayDevice will no longer be relevant once resetDisplayState() is + // called below. Clear the reference now so we don't accidentally use it + // later. + display.clear(); if (!vrFlingerRequestsDisplay) { mVrFlinger->SeizeDisplayOwnership(); @@ -1456,6 +1489,8 @@ void SurfaceFlinger::updateVrFlinger() { invalidateHwcGeometry(); // Re-enable default display. + display = getDefaultDisplayDeviceLocked(); + LOG_ALWAYS_FATAL_IF(!display); setPowerModeInternal(display, currentDisplayPowerMode, /*stateLockHeld*/ true); // Reset the timing values to account for the period of the swapped in HWC @@ -1497,7 +1532,13 @@ void SurfaceFlinger::onMessageReceived(int32_t what) { bool refreshNeeded = handleMessageTransaction(); refreshNeeded |= handleMessageInvalidate(); refreshNeeded |= mRepaintEverything; + + preComposition(); + rebuildLayerStacks(); + calculateWorkingSet(); + if (refreshNeeded && CC_LIKELY(mBootStage != BootStage::BOOTLOADER)) { + // Signal a refresh if a transaction modified the window state, // a new buffer was latched, or if HWC has requested a full // repaint @@ -1526,21 +1567,112 @@ bool SurfaceFlinger::handleMessageInvalidate() { return handlePageFlip(); } +void SurfaceFlinger::calculateWorkingSet() { + ATRACE_CALL(); + ALOGV(__FUNCTION__); + + // build the h/w work list + if (CC_UNLIKELY(mGeometryInvalid)) { + mGeometryInvalid = false; + for (const auto& [token, display] : mDisplays) { + const auto displayId = display->getId(); + if (displayId >= 0) { + const Vector<sp<Layer>>& currentLayers( + display->getVisibleLayersSortedByZ()); + for (size_t i = 0; i < currentLayers.size(); i++) { + const auto& layer = currentLayers[i]; + + if (!layer->hasHwcLayer(displayId)) { + if (!layer->createHwcLayer(getBE().mHwc.get(), displayId)) { + layer->forceClientComposition(displayId); + continue; + } + } + + layer->setGeometry(display, i); + if (mDebugDisableHWC || mDebugRegion) { + layer->forceClientComposition(displayId); + } + } + } + } + } + + // Set the per-frame data + for (const auto& [token, display] : mDisplays) { + const auto displayId = display->getId(); + if (displayId < 0) { + continue; + } + + if (mDrawingState.colorMatrixChanged) { + display->setColorTransform(mDrawingState.colorMatrix); + status_t result = getBE().mHwc->setColorTransform(displayId, mDrawingState.colorMatrix); + ALOGE_IF(result != NO_ERROR, "Failed to set color transform on " + "display %d: %d", displayId, result); + } + for (auto& layer : display->getVisibleLayersSortedByZ()) { + if (layer->isHdrY410()) { + layer->forceClientComposition(displayId); + } else if ((layer->getDataSpace() == Dataspace::BT2020_PQ || + layer->getDataSpace() == Dataspace::BT2020_ITU_PQ) && + !display->hasHDR10Support()) { + layer->forceClientComposition(displayId); + } else if ((layer->getDataSpace() == Dataspace::BT2020_HLG || + layer->getDataSpace() == Dataspace::BT2020_ITU_HLG) && + !display->hasHLGSupport()) { + layer->forceClientComposition(displayId); + } + + if (layer->getForceClientComposition(displayId)) { + ALOGV("[%s] Requesting Client composition", layer->getName().string()); + layer->setCompositionType(displayId, HWC2::Composition::Client); + continue; + } + + layer->setPerFrameData(display); + } + + if (hasWideColorDisplay) { + ColorMode colorMode; + Dataspace dataSpace; + RenderIntent renderIntent; + pickColorMode(display, &colorMode, &dataSpace, &renderIntent); + setActiveColorModeInternal(display, colorMode, dataSpace, renderIntent); + } + } + + mDrawingState.colorMatrixChanged = false; + getBE().mCompositionInfo.clear(); + + for (const auto& [token, display] : mDisplays) { + for (auto& layer : display->getVisibleLayersSortedByZ()) { + auto displayId = display->getId(); + layer->getBE().compositionInfo.compositionType = layer->getCompositionType(displayId); + if (!layer->setHwcLayer(displayId)) { + ALOGV("Need to create HWCLayer for %s", layer->getName().string()); + } + getBE().mCompositionInfo.push_back(layer->getBE().compositionInfo); + layer->getBE().compositionInfo.hwc.hwcLayer = nullptr; + } + } +} + void SurfaceFlinger::handleMessageRefresh() { ATRACE_CALL(); mRefreshPending = false; - nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC); - - preComposition(refreshStartTime); - rebuildLayerStacks(); - setUpHWComposer(); + beginFrame(); + for (auto compositionInfo : getBE().mCompositionInfo) { + setUpHWComposer(compositionInfo); + } + prepareFrame(); doDebugFlashRegions(); doTracing("handleRefresh"); logLayerStats(); doComposition(); - postComposition(refreshStartTime); + postComposition(); mHadClientComposition = false; for (const auto& [token, display] : mDisplays) { @@ -1616,14 +1748,14 @@ void SurfaceFlinger::logLayerStats() { } } -void SurfaceFlinger::preComposition(nsecs_t refreshStartTime) +void SurfaceFlinger::preComposition() { ATRACE_CALL(); ALOGV("preComposition"); bool needExtraInvalidate = false; mDrawingState.traverseInZOrder([&](Layer* layer) { - if (layer->onPreComposition(refreshStartTime)) { + if (layer->onPreComposition(mRefreshStartTime)) { needExtraInvalidate = true; } }); @@ -1692,7 +1824,7 @@ void SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase, getBE().mCompositorTiming.presentLatency = snappedCompositeToPresentLatency; } -void SurfaceFlinger::postComposition(nsecs_t refreshStartTime) +void SurfaceFlinger::postComposition() { ATRACE_CALL(); ALOGV("postComposition"); @@ -1725,11 +1857,11 @@ void SurfaceFlinger::postComposition(nsecs_t refreshStartTime) nsecs_t vsyncPhase = mPrimaryDispSync.computeNextRefresh(0); nsecs_t vsyncInterval = mPrimaryDispSync.getPeriod(); - // We use the refreshStartTime which might be sampled a little later than + // We use the mRefreshStartTime which might be sampled a little later than // when we started doing work for this frame, but that should be okay // since updateCompositorTiming has snapping logic. updateCompositorTiming( - vsyncPhase, vsyncInterval, refreshStartTime, presentFenceTime); + vsyncPhase, vsyncInterval, mRefreshStartTime, presentFenceTime); CompositorTiming compositorTiming; { std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock); @@ -1841,15 +1973,21 @@ void SurfaceFlinger::rebuildLayerStacks() { if (!drawRegion.isEmpty()) { layersSortedByZ.add(layer); } else { - // Clear out the HWC layer if this layer was - // previously visible, but no longer is - hwcLayerDestroyed = layer->destroyHwcLayer(display->getId()); + if (layer->hasHwcLayer(display->getId())) { + // Clear out the HWC layer if this layer was + // previously visible, but no longer is + hwcLayerDestroyed = layer->destroyHwcLayer( + display->getId()); + } } } else { - // WM changes display->layerStack upon sleep/awake. - // Here we make sure we delete the HWC layers even if - // WM changed their layer stack. - hwcLayerDestroyed = layer->destroyHwcLayer(display->getId()); + if (layer->hasHwcLayer(display->getId())) { + // WM changes display->layerStack upon sleep/awake. + // Here we make sure we delete the HWC layers even if + // WM changed their layer stack. + hwcLayerDestroyed = layer->destroyHwcLayer( + display->getId()); + } } // If a layer is not going to get a release fence because @@ -1951,9 +2089,124 @@ void SurfaceFlinger::pickColorMode(const sp<DisplayDevice>& display, ColorMode* display->getBestColorMode(bestDataSpace, intent, outDataSpace, outMode, outRenderIntent); } -void SurfaceFlinger::setUpHWComposer() { - ATRACE_CALL(); - ALOGV("setUpHWComposer"); +void SurfaceFlinger::configureSidebandComposition(const CompositionInfo& compositionInfo) const +{ + HWC2::Error error; + LOG_ALWAYS_FATAL_IF(compositionInfo.hwc.sidebandStream == nullptr, + "CompositionType is sideband, but sideband stream is nullptr"); + error = (compositionInfo.hwc.hwcLayer) + ->setSidebandStream(compositionInfo.hwc.sidebandStream->handle()); + if (error != HWC2::Error::None) { + ALOGE("[SF] Failed to set sideband stream %p: %s (%d)", + compositionInfo.hwc.sidebandStream->handle(), to_string(error).c_str(), + static_cast<int32_t>(error)); + } +} + +void SurfaceFlinger::configureHwcCommonData(const CompositionInfo& compositionInfo) const +{ + HWC2::Error error; + + if (!compositionInfo.hwc.skipGeometry) { + error = (compositionInfo.hwc.hwcLayer)->setBlendMode(compositionInfo.hwc.blendMode); + ALOGE_IF(error != HWC2::Error::None, + "[SF] Failed to set blend mode %s:" + " %s (%d)", + to_string(compositionInfo.hwc.blendMode).c_str(), to_string(error).c_str(), + static_cast<int32_t>(error)); + + error = (compositionInfo.hwc.hwcLayer)->setDisplayFrame(compositionInfo.hwc.displayFrame); + ALOGE_IF(error != HWC2::Error::None, + "[SF] Failed to set the display frame [%d, %d, %d, %d] %s (%d)", + compositionInfo.hwc.displayFrame.left, + compositionInfo.hwc.displayFrame.right, + compositionInfo.hwc.displayFrame.top, + compositionInfo.hwc.displayFrame.bottom, + to_string(error).c_str(), static_cast<int32_t>(error)); + + error = (compositionInfo.hwc.hwcLayer)->setSourceCrop(compositionInfo.hwc.sourceCrop); + ALOGE_IF(error != HWC2::Error::None, + "[SF] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: %s (%d)", + compositionInfo.hwc.sourceCrop.left, + compositionInfo.hwc.sourceCrop.right, + compositionInfo.hwc.sourceCrop.top, + compositionInfo.hwc.sourceCrop.bottom, + to_string(error).c_str(), static_cast<int32_t>(error)); + + error = (compositionInfo.hwc.hwcLayer)->setPlaneAlpha(compositionInfo.hwc.alpha); + ALOGE_IF(error != HWC2::Error::None, + "[SF] Failed to set plane alpha %.3f: " + "%s (%d)", + compositionInfo.hwc.alpha, + to_string(error).c_str(), static_cast<int32_t>(error)); + + + error = (compositionInfo.hwc.hwcLayer)->setZOrder(compositionInfo.hwc.z); + ALOGE_IF(error != HWC2::Error::None, + "[SF] Failed to set Z %u: %s (%d)", + compositionInfo.hwc.z, + to_string(error).c_str(), static_cast<int32_t>(error)); + + error = (compositionInfo.hwc.hwcLayer) + ->setInfo(compositionInfo.hwc.type, compositionInfo.hwc.appId); + ALOGE_IF(error != HWC2::Error::None, + "[SF] Failed to set info (%d)", + static_cast<int32_t>(error)); + + error = (compositionInfo.hwc.hwcLayer)->setTransform(compositionInfo.hwc.transform); + ALOGE_IF(error != HWC2::Error::None, + "[SF] Failed to set transform %s: " + "%s (%d)", + to_string(compositionInfo.hwc.transform).c_str(), to_string(error).c_str(), + static_cast<int32_t>(error)); + } + + error = (compositionInfo.hwc.hwcLayer)->setCompositionType(compositionInfo.compositionType); + ALOGE_IF(error != HWC2::Error::None, + "[SF] Failed to set composition type: %s (%d)", + to_string(error).c_str(), static_cast<int32_t>(error)); + + error = (compositionInfo.hwc.hwcLayer)->setDataspace(compositionInfo.hwc.dataspace); + ALOGE_IF(error != HWC2::Error::None, + "[SF] Failed to set dataspace: %s (%d)", + to_string(error).c_str(), static_cast<int32_t>(error)); + + error = (compositionInfo.hwc.hwcLayer)->setPerFrameMetadata( + compositionInfo.hwc.supportedPerFrameMetadata, compositionInfo.hwc.hdrMetadata); + ALOGE_IF(error != HWC2::Error::None && error != HWC2::Error::Unsupported, + "[SF] Failed to set hdrMetadata: %s (%d)", + to_string(error).c_str(), static_cast<int32_t>(error)); + + error = (compositionInfo.hwc.hwcLayer)->setColor(compositionInfo.hwc.color); + ALOGE_IF(error != HWC2::Error::None, + "[SF] Failed to set color: %s (%d)", + to_string(error).c_str(), static_cast<int32_t>(error)); + + error = (compositionInfo.hwc.hwcLayer)->setVisibleRegion(compositionInfo.hwc.visibleRegion); + ALOGE_IF(error != HWC2::Error::None, + "[SF] Failed to set visible region: %s (%d)", + to_string(error).c_str(), static_cast<int32_t>(error)); +} + +void SurfaceFlinger::configureDeviceComposition(const CompositionInfo& compositionInfo) const +{ + HWC2::Error error; + + error = (compositionInfo.hwc.hwcLayer)->setSurfaceDamage(compositionInfo.hwc.surfaceDamage); + ALOGE_IF(error != HWC2::Error::None, + "[SF] Failed to set surface damage: %s (%d)", + to_string(error).c_str(), static_cast<int32_t>(error)); + + error = (compositionInfo.hwc.hwcLayer)->setBuffer(compositionInfo.mBufferSlot, + compositionInfo.mBuffer, compositionInfo.hwc.fence); + ALOGE_IF(error != HWC2::Error::None, + "[SF] Failed to set buffer: %s (%d)", + to_string(error).c_str(), static_cast<int32_t>(error)); +} + +void SurfaceFlinger::beginFrame() +{ + mRefreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC); for (const auto& [token, display] : mDisplays) { bool dirty = !display->getDirtyRegion(mRepaintEverything).isEmpty(); @@ -1980,86 +2233,44 @@ void SurfaceFlinger::setUpHWComposer() { display->lastCompositionHadVisibleLayers = !empty; } } +} - // build the h/w work list - if (CC_UNLIKELY(mGeometryInvalid)) { - mGeometryInvalid = false; - for (const auto& [token, display] : mDisplays) { - const auto displayId = display->getId(); - if (displayId >= 0) { - const Vector<sp<Layer>>& currentLayers = display->getVisibleLayersSortedByZ(); - for (size_t i = 0; i < currentLayers.size(); i++) { - const auto& layer = currentLayers[i]; - if (!layer->hasHwcLayer(displayId)) { - if (!layer->createHwcLayer(getBE().mHwc.get(), displayId)) { - layer->forceClientComposition(displayId); - continue; - } - } - - layer->setGeometry(display, i); - if (mDebugDisableHWC || mDebugRegion) { - layer->forceClientComposition(displayId); - } - } - } - } - } - - // Set the per-frame data +void SurfaceFlinger::prepareFrame() +{ for (const auto& [token, display] : mDisplays) { - const auto displayId = display->getId(); - if (displayId < 0) { + if (!display->isPoweredOn()) { continue; } - if (mDrawingState.colorMatrixChanged) { - display->setColorTransform(mDrawingState.colorMatrix); - status_t result = getBE().mHwc->setColorTransform(displayId, mDrawingState.colorMatrix); - ALOGE_IF(result != NO_ERROR, "Failed to set color transform on display %d: %d", - displayId, result); - } - for (auto& layer : display->getVisibleLayersSortedByZ()) { - if (layer->isHdrY410()) { - layer->forceClientComposition(displayId); - } else if ((layer->getDataSpace() == Dataspace::BT2020_PQ || - layer->getDataSpace() == Dataspace::BT2020_ITU_PQ) && - !display->hasHDR10Support()) { - layer->forceClientComposition(displayId); - } else if ((layer->getDataSpace() == Dataspace::BT2020_HLG || - layer->getDataSpace() == Dataspace::BT2020_ITU_HLG) && - !display->hasHLGSupport()) { - layer->forceClientComposition(displayId); - } - - if (layer->getForceClientComposition(displayId)) { - ALOGV("[%s] Requesting Client composition", layer->getName().string()); - layer->setCompositionType(displayId, HWC2::Composition::Client); - continue; - } + status_t result = display->prepareFrame(*getBE().mHwc); + ALOGE_IF(result != NO_ERROR, "prepareFrame for display %d failed: %d (%s)", + display->getId(), result, strerror(-result)); + } +} - layer->setPerFrameData(display); - } +void SurfaceFlinger::setUpHWComposer(const CompositionInfo& compositionInfo) { + ATRACE_CALL(); + ALOGV("setUpHWComposer"); - if (hasWideColorDisplay) { - ColorMode colorMode; - Dataspace dataSpace; - RenderIntent renderIntent; - pickColorMode(display, &colorMode, &dataSpace, &renderIntent); - setActiveColorModeInternal(display, colorMode, dataSpace, renderIntent); - } - } + switch (compositionInfo.compositionType) + { + case HWC2::Composition::Invalid: + case HWC2::Composition::Client: + break; - mDrawingState.colorMatrixChanged = false; + case HWC2::Composition::Sideband: + configureSidebandComposition(compositionInfo); + break; - for (const auto& [token, display] : mDisplays) { - if (!display->isPoweredOn()) { - continue; - } + case HWC2::Composition::SolidColor: + configureHwcCommonData(compositionInfo); + break; - status_t result = display->prepareFrame(*getBE().mHwc); - ALOGE_IF(result != NO_ERROR, "prepareFrame for display %d failed: %d (%s)", - display->getId(), result, strerror(-result)); + case HWC2::Composition::Device: + case HWC2::Composition::Cursor: + configureHwcCommonData(compositionInfo); + configureDeviceComposition(compositionInfo); + break; } } @@ -2262,14 +2473,8 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal( if (hasWideColorDisplay) { std::vector<ColorMode> modes = getHwComposer().getColorModes(displayId); for (ColorMode colorMode : modes) { - switch (colorMode) { - case ColorMode::DISPLAY_P3: - case ColorMode::ADOBE_RGB: - case ColorMode::DCI_P3: - hasWideColorGamut = true; - break; - default: - break; + if (isWideColorMode(colorMode)) { + hasWideColorGamut = true; } std::vector<RenderIntent> renderIntents = @@ -5098,7 +5303,7 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, traverseLayers([&](Layer* layer) { if (filtering) layer->setFiltering(true); - layer->draw(renderArea, useIdentityTransform); + layer->drawNow(renderArea, useIdentityTransform); if (filtering) layer->setFiltering(false); }); } @@ -5222,7 +5427,6 @@ void SurfaceFlinger::traverseLayersInDisplay(const sp<const DisplayDevice>& disp }; // namespace android - #if defined(__gl_h_) #error "don't include gl/gl.h in this file" #endif diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index e107f425be..2978b7fe89 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -225,6 +225,8 @@ public: // use to differentiate callbacks from different hardware composer // instances. Each hardware composer instance gets a different sequence id. int32_t mComposerSequenceId; + + std::vector<CompositionInfo> mCompositionInfo; }; @@ -643,8 +645,8 @@ private: void computeVisibleRegions(const sp<const DisplayDevice>& display, Region& dirtyRegion, Region& opaqueRegion); - void preComposition(nsecs_t refreshStartTime); - void postComposition(nsecs_t refreshStartTime); + void preComposition(); + void postComposition(); void updateCompositorTiming( nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeTime, std::shared_ptr<FenceTime>& presentFenceTime); @@ -662,7 +664,19 @@ private: void pickColorMode(const sp<DisplayDevice>& display, ui::ColorMode* outMode, ui::Dataspace* outDataSpace, ui::RenderIntent* outRenderIntent) const; - void setUpHWComposer(); + void calculateWorkingSet(); + /* + * beginFrame - This function handles any pre-frame processing that needs to be + * prior to any CompositionInfo handling and is not dependent on data in + * CompositionInfo + */ + void beginFrame(); + /* prepareFrame - This function will call into the DisplayDevice to prepare a + * frame after CompositionInfo has been programmed. This provides a mechanism + * to prepare the hardware composer + */ + void prepareFrame(); + void setUpHWComposer(const CompositionInfo& compositionInfo); void doComposition(); void doDebugFlashRegions(); void doTracing(const char* where); @@ -780,6 +794,11 @@ private: // access must be protected by mInvalidateLock volatile int32_t mRepaintEverything; + // helper methods + void configureHwcCommonData(const CompositionInfo& compositionInfo) const; + void configureDeviceComposition(const CompositionInfo& compositionInfo) const; + void configureSidebandComposition(const CompositionInfo& compositionInfo) const; + // constant members (no synchronization needed for access) nsecs_t mBootTime; bool mGpuToCpuSupported; @@ -858,6 +877,7 @@ private: Mutex mHWVsyncLock; bool mPrimaryHWVsyncEnabled; bool mHWVsyncAvailable; + nsecs_t mRefreshStartTime; std::atomic<bool> mRefreshPending{false}; diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto index eb346944af..e34772fd4f 100644 --- a/services/surfaceflinger/layerproto/layers.proto +++ b/services/surfaceflinger/layerproto/layers.proto @@ -82,6 +82,10 @@ message LayerProto { optional bool is_protected = 36; // If active_buffer is not null, record its transform optional TransformProto buffer_transform = 37; + // Current frame number being rendered. + optional uint64 curr_frame = 38; + // A list of barriers that the layer is waiting to update state. + repeated BarrierLayerProto barrier_layer = 39; } message PositionProto { @@ -133,3 +137,10 @@ message ColorProto { optional float b = 3; optional float a = 4; } + +message BarrierLayerProto { + // layer id the barrier is waiting on. + optional int32 id = 1; + // frame number the barrier is waiting on. + optional uint64 frame_number = 2; +} diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp index 7f4f2c4ab3..7eaf7b2d73 100644 --- a/vulkan/libvulkan/Android.bp +++ b/vulkan/libvulkan/Android.bp @@ -43,7 +43,6 @@ cc_library_shared { ], cppflags: [ - "-std=c++14", "-Wno-c99-extensions", "-Wno-c++98-compat-pedantic", "-Wno-exit-time-destructors", @@ -82,6 +81,8 @@ cc_library_shared { "libutils", "libcutils", "libz", + "libnativebridge", + "libnativeloader", "libnativewindow", "android.hardware.graphics.common@1.0", ], diff --git a/vulkan/libvulkan/layers_extensions.cpp b/vulkan/libvulkan/layers_extensions.cpp index 3a59208446..96c556393c 100644 --- a/vulkan/libvulkan/layers_extensions.cpp +++ b/vulkan/libvulkan/layers_extensions.cpp @@ -31,6 +31,8 @@ #include <cutils/properties.h> #include <graphicsenv/GraphicsEnv.h> #include <log/log.h> +#include <nativebridge/native_bridge.h> +#include <nativeloader/native_loader.h> #include <ziparchive/zip_archive.h> // TODO(jessehall): The whole way we deal with extensions is pretty hokey, and @@ -73,12 +75,14 @@ class LayerLibrary { : path_(path), filename_(filename), dlhandle_(nullptr), + native_bridge_(false), refcount_(0) {} LayerLibrary(LayerLibrary&& other) : path_(std::move(other.path_)), filename_(std::move(other.filename_)), dlhandle_(other.dlhandle_), + native_bridge_(other.native_bridge_), refcount_(other.refcount_) { other.dlhandle_ = nullptr; other.refcount_ = 0; @@ -101,6 +105,17 @@ class LayerLibrary { const std::string GetFilename() { return filename_; } private: + // TODO(b/79940628): remove that adapter when we could use NativeBridgeGetTrampoline + // for native libraries. + template<typename Func = void*> + Func GetTrampoline(const char* name) const { + if (native_bridge_) { + return reinterpret_cast<Func>(android::NativeBridgeGetTrampoline( + dlhandle_, name, nullptr, 0)); + } + return reinterpret_cast<Func>(dlsym(dlhandle_, name)); + } + const std::string path_; // Track the filename alone so we can detect duplicates @@ -108,6 +123,7 @@ class LayerLibrary { std::mutex mutex_; void* dlhandle_; + bool native_bridge_; size_t refcount_; }; @@ -123,19 +139,23 @@ bool LayerLibrary::Open() { auto app_namespace = android::GraphicsEnv::getInstance().getAppNamespace(); if (app_namespace && !android::base::StartsWith(path_, kSystemLayerLibraryDir)) { - android_dlextinfo dlextinfo = {}; - dlextinfo.flags = ANDROID_DLEXT_USE_NAMESPACE; - dlextinfo.library_namespace = app_namespace; - dlhandle_ = android_dlopen_ext(path_.c_str(), RTLD_NOW | RTLD_LOCAL, - &dlextinfo); + std::string error_msg; + dlhandle_ = OpenNativeLibrary( + app_namespace, path_.c_str(), &native_bridge_, &error_msg); + if (!dlhandle_) { + ALOGE("failed to load layer library '%s': %s", path_.c_str(), + error_msg.c_str()); + refcount_ = 0; + return false; + } } else { - dlhandle_ = dlopen(path_.c_str(), RTLD_NOW | RTLD_LOCAL); - } - if (!dlhandle_) { - ALOGE("failed to load layer library '%s': %s", path_.c_str(), - dlerror()); - refcount_ = 0; - return false; + dlhandle_ = dlopen(path_.c_str(), RTLD_NOW | RTLD_LOCAL); + if (!dlhandle_) { + ALOGE("failed to load layer library '%s': %s", path_.c_str(), + dlerror()); + refcount_ = 0; + return false; + } } } return true; @@ -153,11 +173,11 @@ void LayerLibrary::Close() { bool LayerLibrary::EnumerateLayers(size_t library_idx, std::vector<Layer>& instance_layers) const { PFN_vkEnumerateInstanceLayerProperties enumerate_instance_layers = - reinterpret_cast<PFN_vkEnumerateInstanceLayerProperties>( - dlsym(dlhandle_, "vkEnumerateInstanceLayerProperties")); + GetTrampoline<PFN_vkEnumerateInstanceLayerProperties>( + "vkEnumerateInstanceLayerProperties"); PFN_vkEnumerateInstanceExtensionProperties enumerate_instance_extensions = - reinterpret_cast<PFN_vkEnumerateInstanceExtensionProperties>( - dlsym(dlhandle_, "vkEnumerateInstanceExtensionProperties")); + GetTrampoline<PFN_vkEnumerateInstanceExtensionProperties>( + "vkEnumerateInstanceExtensionProperties"); if (!enumerate_instance_layers || !enumerate_instance_extensions) { ALOGE("layer library '%s' missing some instance enumeration functions", path_.c_str()); @@ -166,11 +186,11 @@ bool LayerLibrary::EnumerateLayers(size_t library_idx, // device functions are optional PFN_vkEnumerateDeviceLayerProperties enumerate_device_layers = - reinterpret_cast<PFN_vkEnumerateDeviceLayerProperties>( - dlsym(dlhandle_, "vkEnumerateDeviceLayerProperties")); + GetTrampoline<PFN_vkEnumerateDeviceLayerProperties>( + "vkEnumerateDeviceLayerProperties"); PFN_vkEnumerateDeviceExtensionProperties enumerate_device_extensions = - reinterpret_cast<PFN_vkEnumerateDeviceExtensionProperties>( - dlsym(dlhandle_, "vkEnumerateDeviceExtensionProperties")); + GetTrampoline<PFN_vkEnumerateDeviceExtensionProperties>( + "vkEnumerateDeviceExtensionProperties"); // get layer counts uint32_t num_instance_layers = 0; @@ -301,10 +321,10 @@ void* LayerLibrary::GetGPA(const Layer& layer, char* name = static_cast<char*>(alloca(layer_name_len + gpa_name_len + 1)); strcpy(name, layer.properties.layerName); strcpy(name + layer_name_len, gpa_name); - if (!(gpa = dlsym(dlhandle_, name))) { + if (!(gpa = GetTrampoline(name))) { strcpy(name, "vk"); strcpy(name + 2, gpa_name); - gpa = dlsym(dlhandle_, name); + gpa = GetTrampoline(name); } return gpa; } |