Merge "[binder] Switch on -Wzero-as-null-pointer-constant warning"
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp
index 6337611..3ada153 100644
--- a/cmds/dumpsys/tests/dumpsys_test.cpp
+++ b/cmds/dumpsys/tests/dumpsys_test.cpp
@@ -74,7 +74,7 @@
     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 96d8c47..7291ef3 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -88,6 +88,12 @@
               "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 5caceec..7632311 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 @@
 	"-Wno-float-equal",
 	"-Wno-sign-conversion",
 	"-Wno-padded",
-	"-std=c++14",
     ],
     static_libs: [
         "libtrace_proto",
@@ -41,7 +39,6 @@
 
 cc_binary {
     name: "surfacereplayer",
-    clang: true,
     srcs: [
         "Main.cpp",
     ],
@@ -61,6 +58,5 @@
 	"-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 0946aca..d516eb1 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 @@
     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 @@
 {
     int32_t res = -1;
     
-    mutex_lock(&gMutex);
+    pthread_mutex_lock(&gMutex);
     
     if (gFreeBufferIndex >= 0) {
         res = gFreeBufferIndex;
@@ -125,17 +126,17 @@
         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 961f101..a8ef7a0 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -56,7 +56,7 @@
     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 @@
     }
 }
 
-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 213580c..17e8f6b 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -23,6 +23,8 @@
 
 namespace android {
 
+class NativeLoaderNamespace;
+
 class GraphicsEnv {
 public:
     static GraphicsEnv& getInstance();
@@ -35,8 +37,8 @@
     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 @@
     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 254038b..0382479 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -123,7 +123,6 @@
 
 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 e623abf..938d737 100644
--- a/libs/vr/libpdx/service_tests.cpp
+++ b/libs/vr/libpdx/service_tests.cpp
@@ -51,22 +51,24 @@
 //             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 7e2f648..66ee8ff 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 e128df7..75d8942 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -160,6 +160,8 @@
                          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 @@
         mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
         mTexture.setFiltering(useFiltering);
         mTexture.setMatrix(textureMatrix);
+        compositionInfo.re.texture = mTexture;
 
         engine.setupLayerTexturing(mTexture);
     } else {
@@ -250,6 +253,23 @@
     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 @@
     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 @@
         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 7f5ff3f..0886f17 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -101,6 +101,7 @@
      */
     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 aebe4ea..bf4a859 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -46,16 +46,27 @@
                         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 @@
     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 3408045..8417135 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -32,6 +32,7 @@
     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 f259d93..320c0df 100644
--- a/services/surfaceflinger/ContainerLayer.cpp
+++ b/services/surfaceflinger/ContainerLayer.cpp
@@ -30,6 +30,8 @@
 
 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 06cfbcd..29a5c3a 100644
--- a/services/surfaceflinger/ContainerLayer.h
+++ b/services/surfaceflinger/ContainerLayer.h
@@ -32,6 +32,7 @@
     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 37dc27d..eb271cd 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 @@
         nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
 
         while (true) {
-            Vector<CallbackInvocation> callbackInvocations;
+            std::vector<CallbackInvocation> callbackInvocations;
 
             nsecs_t targetTime = 0;
 
@@ -187,7 +186,7 @@
         // 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 @@
         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 @@
         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 @@
                 } else if (diff < -mPeriod / 2) {
                     diff += mPeriod;
                 }
-                listener.mLastEventTime -= diff;
+                eventListener.mLastEventTime -= diff;
                 mCond.signal();
                 return NO_ERROR;
             }
@@ -274,23 +273,23 @@
         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 @@
         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 @@
 
     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 11c3db0..4eedb1a 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -503,6 +503,9 @@
     }
     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 @@
         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 @@
         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 @@
     }
     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 @@
         }
     }
 
-    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 @@
     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 @@
     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 @@
     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 03720a9..5107e6b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -374,6 +374,16 @@
     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 @@
         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 bef051f..51b615b 100644
--- a/services/surfaceflinger/LayerBE.cpp
+++ b/services/surfaceflinger/LayerBE.cpp
@@ -57,7 +57,8 @@
     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 f610677..680fbd0 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 @@
     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 @@
         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 @@
         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 7680f2a..63e058a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -114,6 +114,33 @@
 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 @@
     Mutex& mMutex;
     bool mLocked;
 };
+
 }  // namespace anonymous
 
 // ---------------------------------------------------------------------------
@@ -749,6 +777,7 @@
 
     // set initial conditions (e.g. unblank default device)
     initializeDisplays();
+    ALOGV("Displays initialized");
 
     getBE().mRenderEngine->primeCache();
 
@@ -1429,9 +1458,13 @@
 
     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 @@
     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 @@
             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 @@
     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::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 @@
     getBE().mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
 }
 
-void SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
+void SurfaceFlinger::postComposition()
 {
     ATRACE_CALL();
     ALOGV("postComposition");
@@ -1725,11 +1857,11 @@
     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 @@
                         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 @@
     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,78 +2233,10 @@
             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
-    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;
-
+void SurfaceFlinger::prepareFrame()
+{
     for (const auto& [token, display] : mDisplays) {
         if (!display->isPoweredOn()) {
             continue;
@@ -2063,6 +2248,32 @@
     }
 }
 
+void SurfaceFlinger::setUpHWComposer(const CompositionInfo& compositionInfo) {
+    ATRACE_CALL();
+    ALOGV("setUpHWComposer");
+
+    switch (compositionInfo.compositionType)
+    {
+        case HWC2::Composition::Invalid:
+        case HWC2::Composition::Client:
+            break;
+
+        case HWC2::Composition::Sideband:
+            configureSidebandComposition(compositionInfo);
+            break;
+
+        case HWC2::Composition::SolidColor:
+            configureHwcCommonData(compositionInfo);
+            break;
+
+        case HWC2::Composition::Device:
+        case HWC2::Composition::Cursor:
+            configureHwcCommonData(compositionInfo);
+            configureDeviceComposition(compositionInfo);
+            break;
+    }
+}
+
 void SurfaceFlinger::doComposition() {
     ATRACE_CALL();
     ALOGV("doComposition");
@@ -2262,14 +2473,8 @@
     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 @@
 
     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 @@
 
 }; // 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 e107f42..2978b7f 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -225,6 +225,8 @@
     // 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 @@
     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 @@
     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 @@
     // 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 @@
     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 eb34694..e34772f 100644
--- a/services/surfaceflinger/layerproto/layers.proto
+++ b/services/surfaceflinger/layerproto/layers.proto
@@ -82,6 +82,10 @@
   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 @@
   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 7f4f2c4..7eaf7b2 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -43,7 +43,6 @@
     ],
 
     cppflags: [
-        "-std=c++14",
         "-Wno-c99-extensions",
         "-Wno-c++98-compat-pedantic",
         "-Wno-exit-time-destructors",
@@ -82,6 +81,8 @@
         "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 3a59208..96c5563 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 @@
         : 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 @@
     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 @@
 
     std::mutex mutex_;
     void* dlhandle_;
+    bool native_bridge_;
     size_t refcount_;
 };
 
@@ -123,19 +139,23 @@
         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 @@
 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 @@
 
     // 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 @@
     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;
 }