Merge changes from topic "surfaceflinger-arc"

* changes:
  SF: Cleanups to use std::atomic/std::mutex
  SF: Allow SurfaceFlinger creation to be altered
diff --git a/libs/binder/include/binder/AppOpsManager.h b/libs/binder/include/binder/AppOpsManager.h
index 7870c7b..37237df 100644
--- a/libs/binder/include/binder/AppOpsManager.h
+++ b/libs/binder/include/binder/AppOpsManager.h
@@ -108,7 +108,7 @@
         OP_MANAGE_IPSEC_TUNNELS = 75,
         OP_START_FOREGROUND = 76,
         OP_BLUETOOTH_SCAN = 77,
-        OP_USE_FACE = 78,
+        OP_USE_BIOMETRIC = 78,
     };
 
     AppOpsManager();
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp
index f16cde6..896c5c1 100644
--- a/libs/binder/ndk/ibinder.cpp
+++ b/libs/binder/ndk/ibinder.cpp
@@ -198,13 +198,8 @@
 
     return new AIBinder_Weak{wp<AIBinder>(binder)};
 }
-void AIBinder_Weak_delete(AIBinder_Weak** weakBinder) {
-    if (weakBinder == nullptr) {
-        return;
-    }
-
-    delete *weakBinder;
-    *weakBinder = nullptr;
+void AIBinder_Weak_delete(AIBinder_Weak* weakBinder) {
+    delete weakBinder;
 }
 AIBinder* AIBinder_Weak_promote(AIBinder_Weak* weakBinder) {
     if (weakBinder == nullptr) {
@@ -437,6 +432,11 @@
     return ret;
 }
 
+static void DestroyParcel(AParcel** parcel) {
+    delete *parcel;
+    *parcel = nullptr;
+}
+
 binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, AParcel** in,
                                   AParcel** out, binder_flags_t flags) {
     if (in == nullptr) {
@@ -447,7 +447,7 @@
     using AutoParcelDestroyer = std::unique_ptr<AParcel*, void (*)(AParcel**)>;
     // This object is the input to the transaction. This function takes ownership of it and deletes
     // it.
-    AutoParcelDestroyer forIn(in, AParcel_delete);
+    AutoParcelDestroyer forIn(in, DestroyParcel);
 
     if (!isUserCommand(code)) {
         LOG(ERROR) << __func__ << ": Only user-defined transactions can be made from the NDK.";
@@ -492,11 +492,6 @@
     return new AIBinder_DeathRecipient(onBinderDied);
 }
 
-void AIBinder_DeathRecipient_delete(AIBinder_DeathRecipient** recipient) {
-    if (recipient == nullptr) {
-        return;
-    }
-
-    delete *recipient;
-    *recipient = nullptr;
+void AIBinder_DeathRecipient_delete(AIBinder_DeathRecipient* recipient) {
+    delete recipient;
 }
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
index 5081248..871335d 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -300,7 +300,7 @@
 /**
  * Deletes the weak reference. This will have no impact on the lifetime of the binder.
  */
-void AIBinder_Weak_delete(AIBinder_Weak** weakBinder);
+void AIBinder_Weak_delete(AIBinder_Weak* weakBinder);
 
 /**
  * If promotion succeeds, result will have one strong refcount added to it. Otherwise, this returns
@@ -323,7 +323,7 @@
  * Deletes a binder death recipient. It is not necessary to call AIBinder_unlinkToDeath before
  * calling this as these will all be automatically unlinked.
  */
-void AIBinder_DeathRecipient_delete(AIBinder_DeathRecipient** recipient);
+void AIBinder_DeathRecipient_delete(AIBinder_DeathRecipient* recipient);
 
 __END_DECLS
 
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel.h b/libs/binder/ndk/include_ndk/android/binder_parcel.h
index 8628025..271810a 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel.h
@@ -45,9 +45,9 @@
 typedef struct AParcel AParcel;
 
 /**
- * Cleans up a parcel and sets it to nullptr.
+ * Cleans up a parcel.
  */
-void AParcel_delete(AParcel** parcel);
+void AParcel_delete(AParcel* parcel);
 
 /**
  * Writes an AIBinder to the next location in a non-null parcel. Can be null.
diff --git a/libs/binder/ndk/include_ndk/android/binder_status.h b/libs/binder/ndk/include_ndk/android/binder_status.h
index 6389a1b..1a6a6f0 100644
--- a/libs/binder/ndk/include_ndk/android/binder_status.h
+++ b/libs/binder/ndk/include_ndk/android/binder_status.h
@@ -177,7 +177,7 @@
 /**
  * Deletes memory associated with the status instance.
  */
-void AStatus_delete(AStatus** status);
+void AStatus_delete(AStatus* status);
 
 __END_DECLS
 
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index a063657..385e898 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -27,13 +27,8 @@
 using ::android::sp;
 using ::android::status_t;
 
-void AParcel_delete(AParcel** parcel) {
-    if (parcel == nullptr) {
-        return;
-    }
-
-    delete *parcel;
-    *parcel = nullptr;
+void AParcel_delete(AParcel* parcel) {
+    delete parcel;
 }
 
 binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder) {
diff --git a/libs/binder/ndk/status.cpp b/libs/binder/ndk/status.cpp
index deb0392..e0ae469 100644
--- a/libs/binder/ndk/status.cpp
+++ b/libs/binder/ndk/status.cpp
@@ -66,18 +66,11 @@
     return status->get()->exceptionMessage().c_str();
 }
 
-void AStatus_delete(AStatus** status) {
-    if (status == nullptr) {
-        return;
-    }
-
-    delete *status;
-    *status = nullptr;
+void AStatus_delete(AStatus* status) {
+    delete status;
 }
 
 binder_status_t PruneStatusT(status_t status) {
-    if (status > 0) return status;
-
     switch (status) {
         case ::android::OK:
             return STATUS_OK;
diff --git a/libs/binder/ndk/test/iface.cpp b/libs/binder/ndk/test/iface.cpp
index 80700df..0dc3cc4 100644
--- a/libs/binder/ndk/test/iface.cpp
+++ b/libs/binder/ndk/test/iface.cpp
@@ -81,7 +81,7 @@
         int32_t out;
         CHECK(STATUS_OK == AParcel_readInt32(parcelOut, &out));
 
-        AParcel_delete(&parcelOut);
+        AParcel_delete(parcelOut);
 
         return out;
     }
@@ -92,7 +92,7 @@
 };
 
 IFoo::~IFoo() {
-    AIBinder_Weak_delete(&mWeakBinder);
+    AIBinder_Weak_delete(mWeakBinder);
 }
 
 binder_status_t IFoo::addService(const char* instance) {
@@ -106,7 +106,7 @@
         // or one strong refcount here
         binder = AIBinder_new(IFoo::kClass, static_cast<void*>(new IFoo_Class_Data{this}));
         if (mWeakBinder != nullptr) {
-            AIBinder_Weak_delete(&mWeakBinder);
+            AIBinder_Weak_delete(mWeakBinder);
         }
         mWeakBinder = AIBinder_Weak_new(binder);
     }
diff --git a/libs/binder/ndk/test/main_client.cpp b/libs/binder/ndk/test/main_client.cpp
index 2dcccfe..c07462e 100644
--- a/libs/binder/ndk/test/main_client.cpp
+++ b/libs/binder/ndk/test/main_client.cpp
@@ -66,7 +66,7 @@
     EXPECT_EQ(STATUS_OK, AIBinder_unlinkToDeath(binder, recipient, nullptr));
     EXPECT_EQ(STATUS_NAME_NOT_FOUND, AIBinder_unlinkToDeath(binder, recipient, nullptr));
 
-    AIBinder_DeathRecipient_delete(&recipient);
+    AIBinder_DeathRecipient_delete(recipient);
     AIBinder_decStrong(binder);
 }
 
@@ -114,7 +114,7 @@
     // assert because would need to decStrong if non-null and we shouldn't need to add a no-op here
     ASSERT_NE(nullptr, AIBinder_Weak_promote(wBinder));
 
-    AIBinder_Weak_delete(&wBinder);
+    AIBinder_Weak_delete(wBinder);
 }
 
 TEST(NdkBinder, AddServiceMultipleTimes) {
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 08fbfff..f99bc53 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -104,16 +104,13 @@
 
     virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
                                    Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
-                                   int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform,
-                                   ISurfaceComposer::Rotation rotation) {
+                                   bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(display);
         data.write(sourceCrop);
         data.writeUint32(reqWidth);
         data.writeUint32(reqHeight);
-        data.writeInt32(minLayerZ);
-        data.writeInt32(maxLayerZ);
         data.writeInt32(static_cast<int32_t>(useIdentityTransform));
         data.writeInt32(static_cast<int32_t>(rotation));
         status_t result = remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
@@ -653,13 +650,11 @@
             data.read(sourceCrop);
             uint32_t reqWidth = data.readUint32();
             uint32_t reqHeight = data.readUint32();
-            int32_t minLayerZ = data.readInt32();
-            int32_t maxLayerZ = data.readInt32();
             bool useIdentityTransform = static_cast<bool>(data.readInt32());
             int32_t rotation = data.readInt32();
 
             status_t res = captureScreen(display, &outBuffer, sourceCrop, reqWidth, reqHeight,
-                                         minLayerZ, maxLayerZ, useIdentityTransform,
+                                         useIdentityTransform,
                                          static_cast<ISurfaceComposer::Rotation>(rotation));
             reply->writeInt32(res);
             if (res == NO_ERROR) {
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 4caadd1..09ea0f6 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -876,13 +876,12 @@
 // ----------------------------------------------------------------------------
 
 status_t ScreenshotClient::capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth,
-                                   uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ,
-                                   bool useIdentityTransform, uint32_t rotation,
+                                   uint32_t reqHeight, bool useIdentityTransform, uint32_t rotation,
                                    sp<GraphicBuffer>* outBuffer) {
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
     if (s == nullptr) return NO_INIT;
-    status_t ret = s->captureScreen(display, outBuffer, sourceCrop, reqWidth, reqHeight, minLayerZ,
-                                    maxLayerZ, useIdentityTransform,
+    status_t ret = s->captureScreen(display, outBuffer, sourceCrop, reqWidth, reqHeight,
+                                    useIdentityTransform,
                                     static_cast<ISurfaceComposer::Rotation>(rotation));
     if (ret != NO_ERROR) {
         return ret;
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 46103c4..a55cfe0 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -193,8 +193,7 @@
      */
     virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
                                    Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
-                                   int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform,
-                                   Rotation rotation = eRotateNone) = 0;
+                                   bool useIdentityTransform, Rotation rotation = eRotateNone) = 0;
 
     /**
      * Capture a subtree of the layer hierarchy, potentially ignoring the root node.
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 662acc9..314b118 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -326,8 +326,7 @@
     // if cropping isn't required, callers may pass in a default Rect, e.g.:
     //   capture(display, producer, Rect(), reqWidth, ...);
     static status_t capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth,
-                            uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ,
-                            bool useIdentityTransform, uint32_t rotation,
+                            uint32_t reqHeight, bool useIdentityTransform, uint32_t rotation,
                             sp<GraphicBuffer>* outBuffer);
     static status_t captureLayers(const sp<IBinder>& layerHandle, Rect sourceCrop, float frameScale,
                                   sp<GraphicBuffer>* outBuffer);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 243f27f..bc80899 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -135,7 +135,7 @@
             ISurfaceComposer::eDisplayIdMain));
     sp<GraphicBuffer> outBuffer;
     ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, Rect(),
-            64, 64, 0, 0x7fffffff, false));
+            64, 64, false));
 
     ASSERT_EQ(NO_ERROR, native_window_api_connect(anw.get(),
             NATIVE_WINDOW_API_CPU));
@@ -166,7 +166,7 @@
         ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf, -1));
     }
     ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, Rect(),
-            64, 64, 0, 0x7fffffff, false));
+            64, 64, false));
 }
 
 TEST_F(SurfaceTest, ConcreteTypeIsSurface) {
@@ -599,7 +599,6 @@
     status_t captureScreen(const sp<IBinder>& /*display*/,
             sp<GraphicBuffer>* /*outBuffer*/,
             Rect /*sourceCrop*/, uint32_t /*reqWidth*/, uint32_t /*reqHeight*/,
-            int32_t /*minLayerZ*/, int32_t /*maxLayerZ*/,
             bool /*useIdentityTransform*/,
             Rotation /*rotation*/) override { return NO_ERROR; }
     virtual status_t captureLayers(const sp<IBinder>& /*parentHandle*/,
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
index 1f2c517..44276ba 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
@@ -440,6 +440,10 @@
 Status<std::vector<size_t>> ProducerQueue::AllocateBuffers(
     uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
     uint64_t usage, size_t buffer_count) {
+  if (buffer_count == 0) {
+    return {std::vector<size_t>()};
+  }
+
   if (capacity() + buffer_count > kMaxQueueCapacity) {
     ALOGE(
         "ProducerQueue::AllocateBuffers: queue is at capacity: %zu, cannot "
@@ -481,10 +485,13 @@
     }
   }
 
-  if (buffer_slots.size() == 0) {
-    // Error out if no buffer is allocated and improted.
-    ALOGE_IF(TRACE, "ProducerQueue::AllocateBuffers: no buffer allocated.");
-    ErrorStatus(ENOMEM);
+  if (buffer_slots.size() != buffer_count) {
+    // Error out if the count of imported buffer(s) is not correct.
+    ALOGE(
+        "ProducerQueue::AllocateBuffers: requested to import %zu "
+        "buffers, but actually imported %zu buffers.",
+        buffer_count, buffer_slots.size());
+    return ErrorStatus(ENOMEM);
   }
 
   return {std::move(buffer_slots)};
@@ -503,11 +510,6 @@
     return status.error_status();
   }
 
-  if (status.get().size() == 0) {
-    ALOGE_IF(TRACE, "ProducerQueue::AllocateBuffer: no buffer allocated.");
-    ErrorStatus(ENOMEM);
-  }
-
   return {status.get()[0]};
 }
 
diff --git a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
index 2975f56..046df54 100644
--- a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
+++ b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
@@ -562,6 +562,30 @@
   ASSERT_EQ(cs2, ps2);
 }
 
+TEST_F(BufferHubQueueTest, TestAllocateTwoBuffers) {
+  ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{}));
+  ASSERT_EQ(producer_queue_->capacity(), 0);
+  auto status = producer_queue_->AllocateBuffers(
+      kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat,
+      kBufferUsage, /*buffer_count=*/2);
+  ASSERT_TRUE(status.ok());
+  std::vector<size_t> buffer_slots = status.take();
+  ASSERT_EQ(buffer_slots.size(), 2);
+  ASSERT_EQ(producer_queue_->capacity(), 2);
+}
+
+TEST_F(BufferHubQueueTest, TestAllocateZeroBuffers) {
+  ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{}));
+  ASSERT_EQ(producer_queue_->capacity(), 0);
+  auto status = producer_queue_->AllocateBuffers(
+      kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat,
+      kBufferUsage, /*buffer_count=*/0);
+  ASSERT_TRUE(status.ok());
+  std::vector<size_t> buffer_slots = status.take();
+  ASSERT_EQ(buffer_slots.size(), 0);
+  ASSERT_EQ(producer_queue_->capacity(), 0);
+}
+
 TEST_F(BufferHubQueueTest, TestUsageSetMask) {
   const uint32_t set_mask = GRALLOC_USAGE_SW_WRITE_OFTEN;
   ASSERT_TRUE(
diff --git a/libs/vr/libpdx/private/pdx/rpc/variant.h b/libs/vr/libpdx/private/pdx/rpc/variant.h
index bdcb293..0a4802e 100644
--- a/libs/vr/libpdx/private/pdx/rpc/variant.h
+++ b/libs/vr/libpdx/private/pdx/rpc/variant.h
@@ -553,7 +553,7 @@
   template <typename T>
   constexpr std::int32_t index_of() const {
     static_assert(HasType<T>::value, "T is not an element type of Variant.");
-    return value_.template index(DecayedTypeTag<T>{});
+    return value_.index(DecayedTypeTag<T>{});
   }
 
   // Returns the index of the active type. If the Variant is empty -1 is
@@ -575,7 +575,7 @@
   template <typename T>
   T* get() {
     if (is<T>())
-      return &value_.template get(DecayedTypeTag<T>{});
+      return &value_.get(DecayedTypeTag<T>{});
     else
       return nullptr;
   }
@@ -589,7 +589,7 @@
   template <std::size_t I>
   TypeForIndex<I>* get() {
     if (is<TypeForIndex<I>>())
-      return &value_.template get(TypeTagForIndex<I>{});
+      return &value_.get(TypeTagForIndex<I>{});
     else
       return nullptr;
   }
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index a7f3a52..f87fcdc 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -46,7 +46,9 @@
         "libhidlbase",
         "libhidltransport",
         "libhwbinder",
+        "libfmq",
         "android.hardware.sensors@1.0",
+        "android.hardware.sensors@2.0",
     ],
 
     static_libs: ["android.hardware.sensors@1.0-convert"],
diff --git a/services/sensorservice/RecentEventLogger.cpp b/services/sensorservice/RecentEventLogger.cpp
index 1025a88..cec2ae5 100644
--- a/services/sensorservice/RecentEventLogger.cpp
+++ b/services/sensorservice/RecentEventLogger.cpp
@@ -26,6 +26,7 @@
 
 namespace {
     constexpr size_t LOG_SIZE = 10;
+    constexpr size_t LOG_SIZE_MED = 30;  // debugging for slower sensors
     constexpr size_t LOG_SIZE_LARGE = 50;  // larger samples for debugging
 }// unnamed namespace
 
@@ -98,10 +99,16 @@
 
 
 size_t RecentEventLogger::logSizeBySensorType(int sensorType) {
-    return (sensorType == SENSOR_TYPE_STEP_COUNTER ||
-            sensorType == SENSOR_TYPE_SIGNIFICANT_MOTION ||
-            sensorType == SENSOR_TYPE_ACCELEROMETER ||
-            sensorType == SENSOR_TYPE_LIGHT) ? LOG_SIZE_LARGE : LOG_SIZE;
+    if (sensorType == SENSOR_TYPE_STEP_COUNTER ||
+        sensorType == SENSOR_TYPE_SIGNIFICANT_MOTION ||
+        sensorType == SENSOR_TYPE_ACCELEROMETER ||
+        sensorType == SENSOR_TYPE_LIGHT) {
+        return LOG_SIZE_LARGE;
+    }
+    if (sensorType == SENSOR_TYPE_PROXIMITY) {
+        return LOG_SIZE_MED;
+    }
+    return LOG_SIZE;
 }
 
 RecentEventLogger::SensorEventLog::SensorEventLog(const sensors_event_t& e) : mEvent(e) {
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index ae3f42f..25ed21c 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -13,7 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #include "SensorDevice.h"
+
+#include "android/hardware/sensors/2.0/types.h"
 #include "SensorService.h"
 
 #include <android-base/logging.h>
@@ -26,8 +29,10 @@
 #include <cinttypes>
 #include <thread>
 
+using namespace android::hardware::sensors;
 using namespace android::hardware::sensors::V1_0;
 using namespace android::hardware::sensors::V1_0::implementation;
+using android::hardware::sensors::V2_0::EventQueueFlagBits;
 using android::hardware::hidl_vec;
 using android::SensorDeviceUtils::HidlServiceRegistrationWaiter;
 
@@ -86,32 +91,90 @@
            (checkReturn(mSensors->unregisterDirectChannel(-1)) != Result::INVALID_OPERATION);
 }
 
+SensorDevice::~SensorDevice() {
+    if (mEventQueueFlag != nullptr) {
+        hardware::EventFlag::deleteEventFlag(&mEventQueueFlag);
+        mEventQueueFlag = nullptr;
+    }
+}
+
 bool SensorDevice::connectHidlService() {
+    HalConnectionStatus status = connectHidlServiceV2_0();
+    if (status == HalConnectionStatus::DOES_NOT_EXIST) {
+        status = connectHidlServiceV1_0();
+    }
+    return (status == HalConnectionStatus::CONNECTED);
+}
+
+SensorDevice::HalConnectionStatus SensorDevice::connectHidlServiceV1_0() {
     // SensorDevice will wait for HAL service to start if HAL is declared in device manifest.
     size_t retry = 10;
+    HalConnectionStatus connectionStatus = HalConnectionStatus::UNKNOWN;
 
     while (retry-- > 0) {
-        mSensors = ISensors::getService();
-        if (mSensors == nullptr) {
+        sp<V1_0::ISensors> sensors = V1_0::ISensors::getService();
+        if (sensors == nullptr) {
             // no sensor hidl service found
+            connectionStatus = HalConnectionStatus::DOES_NOT_EXIST;
             break;
         }
 
+        mSensors = new SensorServiceUtil::SensorsWrapperV1_0(sensors);
         mRestartWaiter->reset();
         // Poke ISensor service. If it has lingering connection from previous generation of
         // system server, it will kill itself. There is no intention to handle the poll result,
         // which will be done since the size is 0.
         if(mSensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) {
             // ok to continue
+            connectionStatus = HalConnectionStatus::CONNECTED;
             break;
         }
 
         // hidl service is restarting, pointer is invalid.
         mSensors = nullptr;
+        connectionStatus = HalConnectionStatus::FAILED_TO_CONNECT;
         ALOGI("%s unsuccessful, remaining retry %zu.", __FUNCTION__, retry);
         mRestartWaiter->wait();
     }
-    return (mSensors != nullptr);
+
+    return connectionStatus;
+}
+
+SensorDevice::HalConnectionStatus SensorDevice::connectHidlServiceV2_0() {
+    HalConnectionStatus connectionStatus = HalConnectionStatus::UNKNOWN;
+    sp<V2_0::ISensors> sensors = V2_0::ISensors::getService();
+
+    if (sensors == nullptr) {
+        connectionStatus = HalConnectionStatus::DOES_NOT_EXIST;
+    } else {
+        mSensors = new SensorServiceUtil::SensorsWrapperV2_0(sensors);
+
+        mEventQueue = std::make_unique<EventMessageQueue>(
+                SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT,
+                true /* configureEventFlagWord */);
+
+        mWakeLockQueue = std::make_unique<WakeLockQueue>(
+                SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT,
+                true /* configureEventFlagWord */);
+
+        hardware::EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag);
+
+        CHECK(mSensors != nullptr && mEventQueue != nullptr &&
+                mWakeLockQueue != nullptr && mEventQueueFlag != nullptr);
+
+        status_t status = StatusFromResult(checkReturn(mSensors->initializeMessageQueues(
+                *mEventQueue->getDesc(),
+                *mWakeLockQueue->getDesc())));
+
+        if (status != NO_ERROR) {
+            connectionStatus = HalConnectionStatus::FAILED_TO_CONNECT;
+            ALOGE("Failed to initialize message queues (%s)", strerror(-status));
+        } else {
+            connectionStatus = HalConnectionStatus::CONNECTED;
+        }
+    }
+
+    return connectionStatus;
 }
 
 void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
@@ -171,6 +234,19 @@
 }
 
 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
+    ssize_t eventsRead = 0;
+    if (mSensors->supportsMessageQueues()) {
+        eventsRead = pollFmq(buffer, count);
+    } else if (mSensors->supportsPolling()) {
+        eventsRead = pollHal(buffer, count);
+    } else {
+        ALOGE("Must support polling or FMQ");
+        eventsRead = -1;
+    }
+    return eventsRead;
+}
+
+ssize_t SensorDevice::pollHal(sensors_event_t* buffer, size_t count) {
     if (mSensors == nullptr) return NO_INIT;
 
     ssize_t err;
@@ -216,6 +292,46 @@
     return err;
 }
 
+ssize_t SensorDevice::pollFmq(sensors_event_t* buffer, size_t maxNumEventsToRead) {
+    if (mSensors == nullptr) {
+        return NO_INIT;
+    }
+
+    ssize_t eventsRead = 0;
+    size_t availableEvents = mEventQueue->availableToRead();
+
+    if (availableEvents == 0) {
+        uint32_t eventFlagState = 0;
+
+        // Wait for events to become available. This is necessary so that the Event FMQ's read() is
+        // able to be called with the correct number of events to read. If the specified number of
+        // events is not available, then read() would return no events, possibly introducing
+        // additional latency in delivering events to applications.
+        mEventQueueFlag->wait(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS),
+                              &eventFlagState);
+        availableEvents = mEventQueue->availableToRead();
+
+        if (availableEvents == 0) {
+            ALOGW("Event FMQ wake without any events");
+        }
+    }
+
+    size_t eventsToRead = std::min({availableEvents, maxNumEventsToRead, mEventBuffer.size()});
+    if (eventsToRead > 0) {
+        if (mEventQueue->read(mEventBuffer.data(), eventsToRead)) {
+            for (size_t i = 0; i < eventsToRead; i++) {
+                convertToSensorEvent(mEventBuffer[i], &buffer[i]);
+            }
+            eventsRead = eventsToRead;
+        } else {
+            ALOGW("Failed to read %zu events, currently %zu events available",
+                    eventsToRead, availableEvents);
+        }
+    }
+
+    return eventsRead;
+}
+
 void SensorDevice::autoDisable(void *ident, int handle) {
     Mutex::Autolock _l(mLock);
     ssize_t activationIndex = mActivationCount.indexOfKey(handle);
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index 6d75051..2caebf9 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -19,20 +19,22 @@
 
 #include "SensorDeviceUtils.h"
 #include "SensorServiceUtils.h"
+#include "SensorsWrapper.h"
 
+#include <fmq/MessageQueue.h>
+#include <sensor/SensorEventQueue.h>
 #include <sensor/Sensor.h>
 #include <stdint.h>
 #include <sys/types.h>
 #include <utils/KeyedVector.h>
 #include <utils/Singleton.h>
 #include <utils/String8.h>
+#include <utils/Timers.h>
 
 #include <string>
 #include <unordered_map>
 #include <algorithm> //std::max std::min
 
-#include "android/hardware/sensors/1.0/ISensors.h"
-
 #include "RingBuffer.h"
 
 // ---------------------------------------------------------------------------
@@ -69,6 +71,8 @@
         int mCount;   // number of transport errors observed
     };
 
+    ~SensorDevice();
+
     ssize_t getSensorList(sensor_t const** list);
 
     void handleDynamicSensorConnection(int handle, bool connected);
@@ -103,7 +107,7 @@
 private:
     friend class Singleton<SensorDevice>;
 
-    sp<hardware::sensors::V1_0::ISensors> mSensors;
+    sp<SensorServiceUtil::ISensorsWrapper> mSensors;
     Vector<sensor_t> mSensorList;
     std::unordered_map<int32_t, sensor_t*> mConnectedDynamicSensors;
 
@@ -164,6 +168,18 @@
     SensorDevice();
     bool connectHidlService();
 
+    enum HalConnectionStatus {
+        CONNECTED, // Successfully connected to the HAL
+        DOES_NOT_EXIST, // Could not find the HAL
+        FAILED_TO_CONNECT, // Found the HAL but failed to connect/initialize
+        UNKNOWN,
+    };
+    HalConnectionStatus connectHidlServiceV1_0();
+    HalConnectionStatus connectHidlServiceV2_0();
+
+    ssize_t pollHal(sensors_event_t* buffer, size_t count);
+    ssize_t pollFmq(sensors_event_t* buffer, size_t count);
+
     static void handleHidlDeath(const std::string &detail);
     template<typename T>
     static Return<T> checkReturn(Return<T> &&ret) {
@@ -189,6 +205,15 @@
             sensors_event_t *dst);
 
     bool mIsDirectReportSupported;
+
+    typedef hardware::MessageQueue<Event, hardware::kSynchronizedReadWrite> EventMessageQueue;
+    typedef hardware::MessageQueue<uint32_t, hardware::kSynchronizedReadWrite> WakeLockQueue;
+    std::unique_ptr<EventMessageQueue> mEventQueue;
+    std::unique_ptr<WakeLockQueue> mWakeLockQueue;
+
+    hardware::EventFlag* mEventQueueFlag;
+
+    std::array<Event, SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT> mEventBuffer;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 372b609..3822ee1 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -306,7 +306,7 @@
     int handle = s->getSensor().getHandle();
     int type = s->getSensor().getType();
     if (mSensors.add(handle, s, isDebug, isVirtual)){
-        mRecentEvent.emplace(handle, new RecentEventLogger(type));
+        mRecentEvent.emplace(handle, new SensorServiceUtil::RecentEventLogger(type));
         return s->getSensor();
     } else {
         return mSensors.getNonSensor();
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index f71723d..db945bb 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -59,7 +59,6 @@
 namespace android {
 // ---------------------------------------------------------------------------
 class SensorInterface;
-using namespace SensorServiceUtil;
 
 class SensorService :
         public BinderService<SensorService>,
@@ -277,7 +276,7 @@
     static uint8_t sHmacGlobalKey[128];
     static bool sHmacGlobalKeyIsValid;
 
-    SensorList mSensors;
+    SensorServiceUtil::SensorList mSensors;
     status_t mInitCheck;
 
     // Socket buffersize used to initialize BitTube. This size depends on whether batching is
@@ -294,7 +293,7 @@
     bool mWakeLockAcquired;
     sensors_event_t *mSensorEventBuffer, *mSensorEventScratch;
     wp<const SensorEventConnection> * mMapFlushEventsToConnections;
-    std::unordered_map<int, RecentEventLogger*> mRecentEvent;
+    std::unordered_map<int, SensorServiceUtil::RecentEventLogger*> mRecentEvent;
     SortedVector< wp<SensorDirectConnection> > mDirectConnections;
     Mode mCurrentOperatingMode;
 
diff --git a/services/sensorservice/SensorsWrapper.h b/services/sensorservice/SensorsWrapper.h
new file mode 100644
index 0000000..f3fa164
--- /dev/null
+++ b/services/sensorservice/SensorsWrapper.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSORS_WRAPPER_H
+#define ANDROID_SENSORS_WRAPPER_H
+
+#include "android/hardware/sensors/1.0/ISensors.h"
+#include "android/hardware/sensors/2.0/ISensors.h"
+
+#include <utils/LightRefBase.h>
+
+namespace android {
+namespace SensorServiceUtil {
+
+using ::android::hardware::MQDescriptorSync;
+using ::android::hardware::Return;
+using ::android::hardware::sensors::V1_0::Event;
+using ::android::hardware::sensors::V1_0::ISensors;
+using ::android::hardware::sensors::V1_0::OperationMode;
+using ::android::hardware::sensors::V1_0::RateLevel;
+using ::android::hardware::sensors::V1_0::Result;
+using ::android::hardware::sensors::V1_0::SharedMemInfo;
+
+/*
+ * The ISensorsWrapper interface includes all function from supported Sensors HAL versions. This
+ * allows for the SensorDevice to use the ISensorsWrapper interface to interact with the Sensors
+ * HAL regardless of the current version of the Sensors HAL that is loaded. Each concrete
+ * instantiation of ISensorsWrapper must correspond to a specific Sensors HAL version. This design
+ * is beneficial because only the functions that change between Sensors HAL versions must be newly
+ * newly implemented, any previously implemented function that does not change may remain the same.
+ *
+ * Functions that exist across all versions of the Sensors HAL should be implemented as pure
+ * virtual functions which forces the concrete instantiations to implement the functions.
+ *
+ * Functions that do not exist across all versions of the Sensors HAL should include a default
+ * implementation that generates an error if called. The default implementation should never
+ * be called and must be overridden by Sensors HAL versions that support the function.
+ */
+class ISensorsWrapper : public VirtualLightRefBase {
+public:
+    virtual bool supportsPolling() const = 0;
+
+    virtual bool supportsMessageQueues() const = 0;
+
+    virtual Return<void> getSensorsList(ISensors::getSensorsList_cb _hidl_cb) = 0;
+
+    virtual Return<Result> setOperationMode(OperationMode mode) = 0;
+
+    virtual Return<Result> activate(int32_t sensorHandle, bool enabled) = 0;
+
+    virtual Return<Result> batch(int32_t sensorHandle, int64_t samplingPeriodNs,
+                                 int64_t maxReportLatencyNs) = 0;
+
+    virtual Return<Result> flush(int32_t sensorHandle) = 0;
+
+    virtual Return<Result> injectSensorData(const Event& event) = 0;
+
+    virtual Return<void> registerDirectChannel(const SharedMemInfo& mem,
+                                               ISensors::registerDirectChannel_cb _hidl_cb) = 0;
+
+    virtual Return<Result> unregisterDirectChannel(int32_t channelHandle) = 0;
+
+    virtual Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle,
+                                            RateLevel rate,
+                                            ISensors::configDirectReport_cb _hidl_cb) = 0;
+
+    virtual Return<void> poll(int32_t maxCount, ISensors::poll_cb _hidl_cb) {
+        (void)maxCount;
+        (void)_hidl_cb;
+        // TODO (b/111070257): Generate an assert-level error since this should never be called
+        // directly
+        return Return<void>();
+    }
+
+    virtual Return<Result> initializeMessageQueues(const MQDescriptorSync<Event>& eventQueueDesc,
+                                                   const MQDescriptorSync<uint32_t>& wakeLockDesc) {
+        (void)eventQueueDesc;
+        (void)wakeLockDesc;
+        // TODO (b/111070257): Generate an assert-level error since this should never be called
+        // directly
+        return Result::INVALID_OPERATION;
+    }
+};
+
+template<typename T>
+class SensorsWrapperBase : public ISensorsWrapper {
+public:
+    SensorsWrapperBase(sp<T> sensors) :
+        mSensors(sensors) { };
+
+    Return<void> getSensorsList(ISensors::getSensorsList_cb _hidl_cb) override {
+        return mSensors->getSensorsList(_hidl_cb);
+    }
+
+    Return<Result> setOperationMode(OperationMode mode) override {
+        return mSensors->setOperationMode(mode);
+    }
+
+    Return<Result> activate(int32_t sensorHandle, bool enabled) override {
+        return mSensors->activate(sensorHandle, enabled);
+    }
+
+    Return<Result> batch(int32_t sensorHandle, int64_t samplingPeriodNs,
+                         int64_t maxReportLatencyNs) override {
+        return mSensors->batch(sensorHandle, samplingPeriodNs, maxReportLatencyNs);
+    }
+
+    Return<Result> flush(int32_t sensorHandle) override {
+        return mSensors->flush(sensorHandle);
+    }
+
+    Return<Result> injectSensorData(const Event& event) override {
+        return mSensors->injectSensorData(event);
+    }
+
+    Return<void> registerDirectChannel(const SharedMemInfo& mem,
+                                       ISensors::registerDirectChannel_cb _hidl_cb) override {
+        return mSensors->registerDirectChannel(mem, _hidl_cb);
+    }
+
+    Return<Result> unregisterDirectChannel(int32_t channelHandle) override {
+        return mSensors->unregisterDirectChannel(channelHandle);
+    }
+
+    Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle,
+                                    RateLevel rate,
+                                    ISensors::configDirectReport_cb _hidl_cb) override {
+        return mSensors->configDirectReport(sensorHandle, channelHandle, rate, _hidl_cb);
+    }
+
+protected:
+    sp<T> mSensors;
+};
+
+class SensorsWrapperV1_0 : public SensorsWrapperBase<hardware::sensors::V1_0::ISensors> {
+public:
+    SensorsWrapperV1_0(sp<hardware::sensors::V1_0::ISensors> sensors) :
+        SensorsWrapperBase(sensors) { };
+
+    bool supportsPolling() const override {
+        return true;
+    }
+
+    bool supportsMessageQueues() const override {
+        return false;
+    }
+
+    Return<void> poll(int32_t maxCount,
+                      hardware::sensors::V1_0::ISensors::poll_cb _hidl_cb) override {
+        return mSensors->poll(maxCount, _hidl_cb);
+    }
+};
+
+class SensorsWrapperV2_0 : public SensorsWrapperBase<hardware::sensors::V2_0::ISensors> {
+public:
+    SensorsWrapperV2_0(sp<hardware::sensors::V2_0::ISensors> sensors)
+        : SensorsWrapperBase(sensors) { };
+
+    bool supportsPolling() const override {
+        return false;
+    }
+
+    bool supportsMessageQueues() const override {
+        return true;
+    }
+
+    Return<Result> initializeMessageQueues(
+            const MQDescriptorSync<Event>& eventQueueDesc,
+            const MQDescriptorSync<uint32_t>& wakeLockDesc) override {
+        return mSensors->initializeMessageQueues(eventQueueDesc, wakeLockDesc);
+    }
+};
+
+}; // namespace SensorServiceUtil
+}; // namespace android
+
+#endif // ANDROID_SENSORS_WRAPPER_H
diff --git a/services/surfaceflinger/LayerStats.cpp b/services/surfaceflinger/LayerStats.cpp
index 04ab121..9c2d312 100644
--- a/services/surfaceflinger/LayerStats.cpp
+++ b/services/surfaceflinger/LayerStats.cpp
@@ -57,7 +57,7 @@
 }
 
 void LayerStats::traverseLayerTreeStatsLocked(
-        const std::vector<std::unique_ptr<LayerProtoParser::Layer>>& layerTree,
+        const std::vector<LayerProtoParser::Layer*>& layerTree,
         const LayerProtoParser::LayerGlobal& layerGlobal,
         std::vector<std::string>* const outLayerShapeVec) {
     for (const auto& layer : layerTree) {
@@ -82,7 +82,7 @@
         base::StringAppendF(&key, ",%s",
                             destinationSize(layer->hwcFrame.bottom - layer->hwcFrame.top,
                                             layerGlobal.resolution[1], false));
-        base::StringAppendF(&key, ",%s", scaleRatioWH(layer.get()).c_str());
+        base::StringAppendF(&key, ",%s", scaleRatioWH(layer).c_str());
         base::StringAppendF(&key, ",%s", alpha(static_cast<float>(layer->color.a)));
 
         outLayerShapeVec->push_back(key);
@@ -98,7 +98,7 @@
     std::vector<std::string> layerShapeVec;
 
     std::lock_guard<std::mutex> lock(mMutex);
-    traverseLayerTreeStatsLocked(layerTree, layerGlobal, &layerShapeVec);
+    traverseLayerTreeStatsLocked(layerTree.topLevelLayers, layerGlobal, &layerShapeVec);
 
     std::string layerShapeKey =
             base::StringPrintf("%d,%s,%s,%s", static_cast<int32_t>(layerShapeVec.size()),
diff --git a/services/surfaceflinger/LayerStats.h b/services/surfaceflinger/LayerStats.h
index 7a190fd..944073b 100644
--- a/services/surfaceflinger/LayerStats.h
+++ b/services/surfaceflinger/LayerStats.h
@@ -38,7 +38,7 @@
 private:
     // Traverse layer tree to get all visible layers' stats
     void traverseLayerTreeStatsLocked(
-            const std::vector<std::unique_ptr<LayerProtoParser::Layer>>& layerTree,
+            const std::vector<LayerProtoParser::Layer*>& layerTree,
             const LayerProtoParser::LayerGlobal& layerGlobal,
             std::vector<std::string>* const outLayerShapeVec);
     // Convert layer's top-left position into 8x8 percentage of the display
diff --git a/services/surfaceflinger/RenderEngine/Description.cpp b/services/surfaceflinger/RenderEngine/Description.cpp
index b7522da..9696d28 100644
--- a/services/surfaceflinger/RenderEngine/Description.cpp
+++ b/services/surfaceflinger/RenderEngine/Description.cpp
@@ -23,76 +23,33 @@
 namespace android {
 namespace renderengine {
 
-void Description::setPremultipliedAlpha(bool premultipliedAlpha) {
-    mPremultipliedAlpha = premultipliedAlpha;
-}
-
-void Description::setOpaque(bool opaque) {
-    mOpaque = opaque;
-}
-
-void Description::setTexture(const Texture& texture) {
-    mTexture = texture;
-    mTextureEnabled = true;
-}
-
-void Description::disableTexture() {
-    mTextureEnabled = false;
-}
-
-void Description::setColor(const half4& color) {
-    mColor = color;
-}
-
-void Description::setProjectionMatrix(const mat4& mtx) {
-    mProjectionMatrix = mtx;
-}
-
-void Description::setColorMatrix(const mat4& mtx) {
-    mColorMatrix = mtx;
-}
-
-void Description::setInputTransformMatrix(const mat3& matrix) {
-    mInputTransformMatrix = matrix;
-}
-
-void Description::setOutputTransformMatrix(const mat4& matrix) {
-    mOutputTransformMatrix = matrix;
+Description::TransferFunction Description::dataSpaceToTransferFunction(ui::Dataspace dataSpace) {
+    ui::Dataspace transfer = static_cast<ui::Dataspace>(dataSpace & ui::Dataspace::TRANSFER_MASK);
+    switch (transfer) {
+        case ui::Dataspace::TRANSFER_ST2084:
+            return Description::TransferFunction::ST2084;
+        case ui::Dataspace::TRANSFER_HLG:
+            return Description::TransferFunction::HLG;
+        case ui::Dataspace::TRANSFER_LINEAR:
+            return Description::TransferFunction::LINEAR;
+        default:
+            return Description::TransferFunction::SRGB;
+    }
 }
 
 bool Description::hasInputTransformMatrix() const {
-    const mat3 identity;
-    return mInputTransformMatrix != identity;
+    const mat4 identity;
+    return inputTransformMatrix != identity;
 }
 
 bool Description::hasOutputTransformMatrix() const {
     const mat4 identity;
-    return mOutputTransformMatrix != identity;
+    return outputTransformMatrix != identity;
 }
 
 bool Description::hasColorMatrix() const {
     const mat4 identity;
-    return mColorMatrix != identity;
-}
-
-const mat4& Description::getColorMatrix() const {
-    return mColorMatrix;
-}
-
-void Description::setY410BT2020(bool enable) {
-    mY410BT2020 = enable;
-}
-
-void Description::setInputTransferFunction(TransferFunction transferFunction) {
-    mInputTransferFunction = transferFunction;
-}
-
-void Description::setOutputTransferFunction(TransferFunction transferFunction) {
-    mOutputTransferFunction = transferFunction;
-}
-
-void Description::setDisplayMaxLuminance(const float maxLuminance) {
-    mDisplayMaxLuminance = maxLuminance;
+    return colorMatrix != identity;
 }
 
 }  // namespace renderengine
diff --git a/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.cpp
index bf3b183..813c9e6 100644
--- a/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.cpp
@@ -398,9 +398,9 @@
         mDisplayP3ToSrgb = mat4(ColorSpaceConnector(displayP3, srgb).getTransform());
 
         // no chromatic adaptation needed since all color spaces use D65 for their white points.
-        mSrgbToXyz = srgb.getRGBtoXYZ();
-        mDisplayP3ToXyz = displayP3.getRGBtoXYZ();
-        mBt2020ToXyz = bt2020.getRGBtoXYZ();
+        mSrgbToXyz = mat4(srgb.getRGBtoXYZ());
+        mDisplayP3ToXyz = mat4(displayP3.getRGBtoXYZ());
+        mBt2020ToXyz = mat4(bt2020.getRGBtoXYZ());
         mXyzToSrgb = mat4(srgb.getXYZtoRGB());
         mXyzToDisplayP3 = mat4(displayP3.getXYZtoRGB());
         mXyzToBt2020 = mat4(bt2020.getXYZtoRGB());
@@ -680,19 +680,19 @@
     }
 
     glViewport(0, 0, vpw, vph);
-    mState.setProjectionMatrix(m);
+    mState.projectionMatrix = m;
     mVpWidth = vpw;
     mVpHeight = vph;
 }
 
 void GLES20RenderEngine::setupLayerBlending(bool premultipliedAlpha, bool opaque,
                                             bool disableTexture, const half4& color) {
-    mState.setPremultipliedAlpha(premultipliedAlpha);
-    mState.setOpaque(opaque);
-    mState.setColor(color);
+    mState.isPremultipliedAlpha = premultipliedAlpha;
+    mState.isOpaque = opaque;
+    mState.color = color;
 
     if (disableTexture) {
-        mState.disableTexture();
+        mState.textureEnabled = false;
     }
 
     if (color.a < 1.0f || !opaque) {
@@ -704,7 +704,7 @@
 }
 
 void GLES20RenderEngine::setSourceY410BT2020(bool enable) {
-    mState.setY410BT2020(enable);
+    mState.isY410BT2020 = enable;
 }
 
 void GLES20RenderEngine::setSourceDataSpace(Dataspace source) {
@@ -716,7 +716,7 @@
 }
 
 void GLES20RenderEngine::setDisplayMaxLuminance(const float maxLuminance) {
-    mState.setDisplayMaxLuminance(maxLuminance);
+    mState.displayMaxLuminance = maxLuminance;
 }
 
 void GLES20RenderEngine::setupLayerTexturing(const Texture& texture) {
@@ -731,22 +731,24 @@
     glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
     glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
 
-    mState.setTexture(texture);
+    mState.texture = texture;
+    mState.textureEnabled = true;
 }
 
 void GLES20RenderEngine::setupLayerBlackedOut() {
     glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
     Texture texture(Texture::TEXTURE_2D, mProtectedTexName);
     texture.setDimensions(1, 1); // FIXME: we should get that from somewhere
-    mState.setTexture(texture);
+    mState.texture = texture;
+    mState.textureEnabled = true;
 }
 
 void GLES20RenderEngine::setupColorTransform(const mat4& colorTransform) {
-    mState.setColorMatrix(colorTransform);
+    mState.colorMatrix = colorTransform;
 }
 
 void GLES20RenderEngine::disableTexturing() {
-    mState.disableTexture();
+    mState.textureEnabled = false;
 }
 
 void GLES20RenderEngine::disableBlending() {
@@ -754,10 +756,10 @@
 }
 
 void GLES20RenderEngine::setupFillWithColor(float r, float g, float b, float a) {
-    mState.setPremultipliedAlpha(true);
-    mState.setOpaque(false);
-    mState.setColor(half4(r, g, b, a));
-    mState.disableTexture();
+    mState.isPremultipliedAlpha = true;
+    mState.isOpaque = false;
+    mState.color = half4(r, g, b, a);
+    mState.textureEnabled = false;
     glDisable(GL_BLEND);
 }
 
@@ -791,26 +793,26 @@
             // The supported input color spaces are standard RGB, Display P3 and BT2020.
             switch (inputStandard) {
                 case Dataspace::STANDARD_DCI_P3:
-                    managedState.setInputTransformMatrix(mDisplayP3ToXyz);
+                    managedState.inputTransformMatrix = mDisplayP3ToXyz;
                     break;
                 case Dataspace::STANDARD_BT2020:
-                    managedState.setInputTransformMatrix(mBt2020ToXyz);
+                    managedState.inputTransformMatrix = mBt2020ToXyz;
                     break;
                 default:
-                    managedState.setInputTransformMatrix(mSrgbToXyz);
+                    managedState.inputTransformMatrix = mSrgbToXyz;
                     break;
             }
 
             // The supported output color spaces are BT2020, Display P3 and standard RGB.
             switch (outputStandard) {
                 case Dataspace::STANDARD_BT2020:
-                    managedState.setOutputTransformMatrix(mXyzToBt2020);
+                    managedState.outputTransformMatrix = mXyzToBt2020;
                     break;
                 case Dataspace::STANDARD_DCI_P3:
-                    managedState.setOutputTransformMatrix(mXyzToDisplayP3);
+                    managedState.outputTransformMatrix = mXyzToDisplayP3;
                     break;
                 default:
-                    managedState.setOutputTransformMatrix(mXyzToSrgb);
+                    managedState.outputTransformMatrix = mXyzToSrgb;
                     break;
             }
         } else if (inputStandard != outputStandard) {
@@ -825,9 +827,9 @@
             // - sRGB
             // - Display P3
             if (outputStandard == Dataspace::STANDARD_BT709) {
-                managedState.setOutputTransformMatrix(mDisplayP3ToSrgb);
+                managedState.outputTransformMatrix = mDisplayP3ToSrgb;
             } else if (outputStandard == Dataspace::STANDARD_DCI_P3) {
-                managedState.setOutputTransformMatrix(mSrgbToDisplayP3);
+                managedState.outputTransformMatrix = mSrgbToDisplayP3;
             }
         }
 
@@ -837,32 +839,10 @@
         // - the input transfer function doesn't match the output transfer function.
         if (managedState.hasColorMatrix() || managedState.hasOutputTransformMatrix() ||
             inputTransfer != outputTransfer) {
-            switch (inputTransfer) {
-                case Dataspace::TRANSFER_ST2084:
-                    managedState.setInputTransferFunction(Description::TransferFunction::ST2084);
-                    break;
-                case Dataspace::TRANSFER_HLG:
-                    managedState.setInputTransferFunction(Description::TransferFunction::HLG);
-                    break;
-                case Dataspace::TRANSFER_LINEAR:
-                    managedState.setInputTransferFunction(Description::TransferFunction::LINEAR);
-                    break;
-                default:
-                    managedState.setInputTransferFunction(Description::TransferFunction::SRGB);
-                    break;
-            }
-
-            switch (outputTransfer) {
-                case Dataspace::TRANSFER_ST2084:
-                    managedState.setOutputTransferFunction(Description::TransferFunction::ST2084);
-                    break;
-                case Dataspace::TRANSFER_HLG:
-                    managedState.setOutputTransferFunction(Description::TransferFunction::HLG);
-                    break;
-                default:
-                    managedState.setOutputTransferFunction(Description::TransferFunction::SRGB);
-                    break;
-            }
+            managedState.inputTransferFunction =
+                Description::dataSpaceToTransferFunction(inputTransfer);
+            managedState.outputTransferFunction =
+                Description::dataSpaceToTransferFunction(outputTransfer);
         }
 
         ProgramCache::getInstance().useProgram(managedState);
diff --git a/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.h
index 3078d3d..fa01410 100644
--- a/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.h
@@ -130,9 +130,9 @@
 
     mat4 mSrgbToDisplayP3;
     mat4 mDisplayP3ToSrgb;
-    mat3 mSrgbToXyz;
-    mat3 mBt2020ToXyz;
-    mat3 mDisplayP3ToXyz;
+    mat4 mSrgbToXyz;
+    mat4 mBt2020ToXyz;
+    mat4 mDisplayP3ToXyz;
     mat4 mXyzToSrgb;
     mat4 mXyzToDisplayP3;
     mat4 mXyzToBt2020;
diff --git a/services/surfaceflinger/RenderEngine/gl/Program.cpp b/services/surfaceflinger/RenderEngine/gl/Program.cpp
index c8d6cf9..da67f92 100644
--- a/services/surfaceflinger/RenderEngine/gl/Program.cpp
+++ b/services/surfaceflinger/RenderEngine/gl/Program.cpp
@@ -129,28 +129,28 @@
 
     if (mSamplerLoc >= 0) {
         glUniform1i(mSamplerLoc, 0);
-        glUniformMatrix4fv(mTextureMatrixLoc, 1, GL_FALSE, desc.mTexture.getMatrix().asArray());
+        glUniformMatrix4fv(mTextureMatrixLoc, 1, GL_FALSE, desc.texture.getMatrix().asArray());
     }
     if (mColorLoc >= 0) {
-        const float color[4] = {desc.mColor.r, desc.mColor.g, desc.mColor.b, desc.mColor.a};
+        const float color[4] = {desc.color.r, desc.color.g, desc.color.b, desc.color.a};
         glUniform4fv(mColorLoc, 1, color);
     }
     if (mInputTransformMatrixLoc >= 0) {
-        mat4 inputTransformMatrix = mat4(desc.mInputTransformMatrix);
+        mat4 inputTransformMatrix = desc.inputTransformMatrix;
         glUniformMatrix4fv(mInputTransformMatrixLoc, 1, GL_FALSE, inputTransformMatrix.asArray());
     }
     if (mOutputTransformMatrixLoc >= 0) {
         // The output transform matrix and color matrix can be combined as one matrix
         // that is applied right before applying OETF.
-        mat4 outputTransformMatrix = desc.mColorMatrix * desc.mOutputTransformMatrix;
+        mat4 outputTransformMatrix = desc.colorMatrix * desc.outputTransformMatrix;
         glUniformMatrix4fv(mOutputTransformMatrixLoc, 1, GL_FALSE,
                            outputTransformMatrix.asArray());
     }
     if (mDisplayMaxLuminanceLoc >= 0) {
-        glUniform1f(mDisplayMaxLuminanceLoc, desc.mDisplayMaxLuminance);
+        glUniform1f(mDisplayMaxLuminanceLoc, desc.displayMaxLuminance) ;
     }
     // these uniforms are always present
-    glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, desc.mProjectionMatrix.asArray());
+    glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, desc.projectionMatrix.asArray());
 }
 
 }  // namespace gl
diff --git a/services/surfaceflinger/RenderEngine/gl/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/gl/ProgramCache.cpp
index a19c1f1..9254aa0 100644
--- a/services/surfaceflinger/RenderEngine/gl/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/gl/ProgramCache.cpp
@@ -130,19 +130,19 @@
 ProgramCache::Key ProgramCache::computeKey(const Description& description) {
     Key needs;
     needs.set(Key::TEXTURE_MASK,
-              !description.mTextureEnabled
+              !description.textureEnabled
                       ? Key::TEXTURE_OFF
-                      : description.mTexture.getTextureTarget() == GL_TEXTURE_EXTERNAL_OES
+                      : description.texture.getTextureTarget() == GL_TEXTURE_EXTERNAL_OES
                               ? Key::TEXTURE_EXT
-                              : description.mTexture.getTextureTarget() == GL_TEXTURE_2D
+                              : description.texture.getTextureTarget() == GL_TEXTURE_2D
                                       ? Key::TEXTURE_2D
                                       : Key::TEXTURE_OFF)
             .set(Key::ALPHA_MASK,
-                 (description.mColor.a < 1) ? Key::ALPHA_LT_ONE : Key::ALPHA_EQ_ONE)
+                 (description.color.a < 1) ? Key::ALPHA_LT_ONE : Key::ALPHA_EQ_ONE)
             .set(Key::BLEND_MASK,
-                 description.mPremultipliedAlpha ? Key::BLEND_PREMULT : Key::BLEND_NORMAL)
+                 description.isPremultipliedAlpha ? Key::BLEND_PREMULT : Key::BLEND_NORMAL)
             .set(Key::OPACITY_MASK,
-                 description.mOpaque ? Key::OPACITY_OPAQUE : Key::OPACITY_TRANSLUCENT)
+                 description.isOpaque ? Key::OPACITY_OPAQUE : Key::OPACITY_TRANSLUCENT)
             .set(Key::Key::INPUT_TRANSFORM_MATRIX_MASK,
                  description.hasInputTransformMatrix() ?
                      Key::INPUT_TRANSFORM_MATRIX_ON : Key::INPUT_TRANSFORM_MATRIX_OFF)
@@ -151,10 +151,10 @@
                      Key::OUTPUT_TRANSFORM_MATRIX_ON : Key::OUTPUT_TRANSFORM_MATRIX_OFF);
 
     needs.set(Key::Y410_BT2020_MASK,
-              description.mY410BT2020 ? Key::Y410_BT2020_ON : Key::Y410_BT2020_OFF);
+              description.isY410BT2020 ? Key::Y410_BT2020_ON : Key::Y410_BT2020_OFF);
 
     if (needs.hasTransformMatrix() || (needs.getInputTF() != needs.getOutputTF())) {
-        switch (description.mInputTransferFunction) {
+        switch (description.inputTransferFunction) {
             case Description::TransferFunction::LINEAR:
             default:
                 needs.set(Key::INPUT_TF_MASK, Key::INPUT_TF_LINEAR);
@@ -170,7 +170,7 @@
                 break;
         }
 
-        switch (description.mOutputTransferFunction) {
+        switch (description.outputTransferFunction) {
             case Description::TransferFunction::LINEAR:
             default:
                 needs.set(Key::OUTPUT_TF_MASK, Key::OUTPUT_TF_LINEAR);
diff --git a/services/surfaceflinger/RenderEngine/gl/ProgramCache.h b/services/surfaceflinger/RenderEngine/gl/ProgramCache.h
index ea77a2d..47963eb 100644
--- a/services/surfaceflinger/RenderEngine/gl/ProgramCache.h
+++ b/services/surfaceflinger/RenderEngine/gl/ProgramCache.h
@@ -29,7 +29,7 @@
 
 namespace renderengine {
 
-class Description;
+struct Description;
 
 namespace gl {
 
diff --git a/services/surfaceflinger/RenderEngine/include/renderengine/private/Description.h b/services/surfaceflinger/RenderEngine/include/renderengine/private/Description.h
index a6301ae..efab8ff 100644
--- a/services/surfaceflinger/RenderEngine/include/renderengine/private/Description.h
+++ b/services/surfaceflinger/RenderEngine/include/renderengine/private/Description.h
@@ -17,84 +17,60 @@
 #ifndef SF_RENDER_ENGINE_DESCRIPTION_H_
 #define SF_RENDER_ENGINE_DESCRIPTION_H_
 
+#include <ui/GraphicTypes.h>
 #include <renderengine/Texture.h>
 
 namespace android {
 namespace renderengine {
 
-namespace gl {
-class Program;
-class ProgramCache;
-}
-
 /*
- * This holds the state of the rendering engine. This class is used
- * to generate a corresponding GLSL program and set the appropriate
- * uniform.
- *
- * Program and ProgramCache are friends and access the state directly
+ * This is the structure that holds the state of the rendering engine.
+ * This class is used to generate a corresponding GLSL program and set the
+ * appropriate uniform.
  */
-class Description {
-public:
-    Description() = default;
-    ~Description() = default;
-
-    void setPremultipliedAlpha(bool premultipliedAlpha);
-    void setOpaque(bool opaque);
-    void setTexture(const Texture& texture);
-    void disableTexture();
-    void setColor(const half4& color);
-    void setProjectionMatrix(const mat4& mtx);
-    void setColorMatrix(const mat4& mtx);
-    void setInputTransformMatrix(const mat3& matrix);
-    void setOutputTransformMatrix(const mat4& matrix);
-    bool hasInputTransformMatrix() const;
-    bool hasOutputTransformMatrix() const;
-    bool hasColorMatrix() const;
-    const mat4& getColorMatrix() const;
-
-    void setY410BT2020(bool enable);
-
+struct Description {
     enum class TransferFunction : int {
         LINEAR,
         SRGB,
         ST2084,
         HLG,  // Hybrid Log-Gamma for HDR.
     };
-    void setInputTransferFunction(TransferFunction transferFunction);
-    void setOutputTransferFunction(TransferFunction transferFunction);
-    void setDisplayMaxLuminance(const float maxLuminance);
 
-private:
-    friend class gl::Program;
-    friend class gl::ProgramCache;
+    static TransferFunction dataSpaceToTransferFunction(ui::Dataspace dataSpace);
+
+    Description() = default;
+    ~Description() = default;
+
+    bool hasInputTransformMatrix() const;
+    bool hasOutputTransformMatrix() const;
+    bool hasColorMatrix() const;
 
     // whether textures are premultiplied
-    bool mPremultipliedAlpha = false;
+    bool isPremultipliedAlpha = false;
     // whether this layer is marked as opaque
-    bool mOpaque = true;
+    bool isOpaque = true;
 
     // Texture this layer uses
-    Texture mTexture;
-    bool mTextureEnabled = false;
+    Texture texture;
+    bool textureEnabled = false;
 
     // color used when texturing is disabled or when setting alpha.
-    half4 mColor;
+    half4 color;
 
     // true if the sampled pixel values are in Y410/BT2020 rather than RGBA
-    bool mY410BT2020 = false;
+    bool isY410BT2020 = false;
 
     // transfer functions for the input/output
-    TransferFunction mInputTransferFunction = TransferFunction::LINEAR;
-    TransferFunction mOutputTransferFunction = TransferFunction::LINEAR;
+    TransferFunction inputTransferFunction = TransferFunction::LINEAR;
+    TransferFunction outputTransferFunction = TransferFunction::LINEAR;
 
-    float mDisplayMaxLuminance;
+    float displayMaxLuminance;
 
     // projection matrix
-    mat4 mProjectionMatrix;
-    mat4 mColorMatrix;
-    mat3 mInputTransformMatrix;
-    mat4 mOutputTransformMatrix;
+    mat4 projectionMatrix;
+    mat4 colorMatrix;
+    mat4 inputTransformMatrix;
+    mat4 outputTransformMatrix;
 };
 
 }  // namespace renderengine
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e2605b2..157cbea 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4618,10 +4618,12 @@
                         mGraphicBufferProducerList.size(), mMaxGraphicBufferProducerListSize);
     colorizer.reset(result);
 
-    LayersProto layersProto = dumpProtoInfo(LayerVector::StateSet::Current);
-    auto layerTree = LayerProtoParser::generateLayerTree(layersProto);
-    result.append(LayerProtoParser::layersToString(std::move(layerTree)).c_str());
-    result.append("\n");
+    {
+        LayersProto layersProto = dumpProtoInfo(LayerVector::StateSet::Current);
+        auto layerTree = LayerProtoParser::generateLayerTree(layersProto);
+        result.append(LayerProtoParser::layerTreeToString(layerTree).c_str());
+        result.append("\n");
+    }
 
     result.append("\nFrame-Composition information:\n");
     dumpFrameCompositionInfo(result);
@@ -4685,6 +4687,12 @@
     result.append("\n");
 
     /*
+     * Tracing state
+     */
+    mTracing.dump(result);
+    result.append("\n");
+
+    /*
      * HWC layer minidump
      */
     for (const auto& [token, display] : mDisplays) {
@@ -5073,12 +5081,12 @@
             case 1025: { // Set layer tracing
                 n = data.readInt32();
                 if (n) {
-                    ALOGV("LayerTracing enabled");
+                    ALOGD("LayerTracing enabled");
                     mTracing.enable();
                     doTracing("tracing.enable");
                     reply->writeInt32(NO_ERROR);
                 } else {
-                    ALOGV("LayerTracing disabled");
+                    ALOGD("LayerTracing disabled");
                     status_t err = mTracing.disable();
                     reply->writeInt32(err);
                 }
@@ -5189,8 +5197,8 @@
 
 status_t SurfaceFlinger::captureScreen(const sp<IBinder>& displayToken,
                                        sp<GraphicBuffer>* outBuffer, Rect sourceCrop,
-                                       uint32_t reqWidth, uint32_t reqHeight, int32_t minLayerZ,
-                                       int32_t maxLayerZ, bool useIdentityTransform,
+                                       uint32_t reqWidth, uint32_t reqHeight,
+                                       bool useIdentityTransform,
                                        ISurfaceComposer::Rotation rotation) {
     ATRACE_CALL();
 
@@ -5220,7 +5228,7 @@
     DisplayRenderArea renderArea(display, sourceCrop, reqWidth, reqHeight, renderAreaRotation);
 
     auto traverseLayers = std::bind(std::mem_fn(&SurfaceFlinger::traverseLayersInDisplay), this,
-                                    display, minLayerZ, maxLayerZ, std::placeholders::_1);
+                                    display, std::placeholders::_1);
     return captureScreenCommon(renderArea, traverseLayers, outBuffer, useIdentityTransform);
 }
 
@@ -5516,19 +5524,14 @@
 }
 
 void SurfaceFlinger::traverseLayersInDisplay(const sp<const DisplayDevice>& display,
-                                             int32_t minLayerZ, int32_t maxLayerZ,
                                              const LayerVector::Visitor& visitor) {
     // We loop through the first level of layers without traversing,
-    // as we need to interpret min/max layer Z in the top level Z space.
+    // as we need to determine which layers belong to the requested display.
     for (const auto& layer : mDrawingState.layersSortedByZ) {
         if (!layer->belongsToDisplay(display->getLayerStack(), false)) {
             continue;
         }
-        const Layer::State& state(layer->getDrawingState());
         // relative layers are traversed in Layer::traverseInZOrder
-        if (state.zOrderRelativeOf != nullptr || state.z < minLayerZ || state.z > maxLayerZ) {
-            continue;
-        }
         layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
             if (!layer->belongsToDisplay(display->getLayerStack(), false)) {
                 return;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index a300857..e2be544 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -439,8 +439,7 @@
             ISurfaceComposer::VsyncSource vsyncSource = eVsyncSourceApp);
     virtual status_t captureScreen(const sp<IBinder>& displayToken, sp<GraphicBuffer>* outBuffer,
                                    Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
-                                   int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform,
-                                   ISurfaceComposer::Rotation rotation);
+                                   bool useIdentityTransform, ISurfaceComposer::Rotation rotation);
     virtual status_t captureLayers(const sp<IBinder>& parentHandle, sp<GraphicBuffer>* outBuffer,
                                    const Rect& sourceCrop, float frameScale, bool childrenOnly);
     virtual status_t getDisplayStats(const sp<IBinder>& displayToken, DisplayStatInfo* stats);
@@ -599,8 +598,8 @@
                                      TraverseLayersFunction traverseLayers,
                                      ANativeWindowBuffer* buffer, bool useIdentityTransform,
                                      bool forSystem, int* outSyncFd);
-    void traverseLayersInDisplay(const sp<const DisplayDevice>& display, int32_t minLayerZ,
-                                 int32_t maxLayerZ, const LayerVector::Visitor& visitor);
+    void traverseLayersInDisplay(const sp<const DisplayDevice>& display,
+                                 const LayerVector::Visitor& visitor);
 
     sp<StartPropertySetThread> mStartPropertySetThread = nullptr;
 
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index 0e9b04e..67dcd06 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -27,32 +27,36 @@
 namespace android {
 
 void SurfaceTracing::enable() {
+    ATRACE_CALL();
+    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
+
     if (mEnabled) {
         return;
     }
-    ATRACE_CALL();
     mEnabled = true;
-    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
 
-    mTrace.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
-                            LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
+    mTrace = std::make_unique<LayersTraceFileProto>();
+    mTrace->set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
+                             LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
 }
 
 status_t SurfaceTracing::disable() {
+    ATRACE_CALL();
+    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
+
     if (!mEnabled) {
         return NO_ERROR;
     }
-    ATRACE_CALL();
-    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
     mEnabled = false;
     status_t err(writeProtoFileLocked());
     ALOGE_IF(err == PERMISSION_DENIED, "Could not save the proto file! Permission denied");
     ALOGE_IF(err == NOT_ENOUGH_DATA, "Could not save the proto file! There are missing fields");
-    mTrace.Clear();
+    mTrace.reset();
     return err;
 }
 
-bool SurfaceTracing::isEnabled() {
+bool SurfaceTracing::isEnabled() const {
+    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
     return mEnabled;
 }
 
@@ -61,20 +65,29 @@
     if (!mEnabled) {
         return;
     }
-    LayersTraceProto* entry = mTrace.add_entry();
+    LayersTraceProto* entry = mTrace->add_entry();
     entry->set_elapsed_realtime_nanos(elapsedRealtimeNano());
     entry->set_where(where);
     entry->mutable_layers()->Swap(&layers);
+
+    constexpr int maxBufferedEntryCount = 3600;
+    if (mTrace->entry_size() >= maxBufferedEntryCount) {
+        // TODO: flush buffered entries without disabling tracing
+        ALOGE("too many buffered frames; force disable tracing");
+        mEnabled = false;
+        writeProtoFileLocked();
+        mTrace.reset();
+    }
 }
 
 status_t SurfaceTracing::writeProtoFileLocked() {
     ATRACE_CALL();
 
-    if (!mTrace.IsInitialized()) {
+    if (!mTrace->IsInitialized()) {
         return NOT_ENOUGH_DATA;
     }
     std::string output;
-    if (!mTrace.SerializeToString(&output)) {
+    if (!mTrace->SerializeToString(&output)) {
         return PERMISSION_DENIED;
     }
     if (!android::base::WriteStringToFile(output, mOutputFileName, true)) {
@@ -84,4 +97,11 @@
     return NO_ERROR;
 }
 
+void SurfaceTracing::dump(String8& result) const {
+    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
+
+    result.appendFormat("Tracing state: %s\n", mEnabled ? "enabled" : "disabled");
+    result.appendFormat("  number of entries: %d\n", mTrace ? mTrace->entry_size() : 0);
+}
+
 } // namespace android
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index 590ab96..fd8cb82 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -18,7 +18,9 @@
 
 #include <layerproto/LayerProtoHeader.h>
 #include <utils/Errors.h>
+#include <utils/String8.h>
 
+#include <memory>
 #include <mutex>
 
 using namespace android::surfaceflinger;
@@ -32,9 +34,10 @@
 public:
     void enable();
     status_t disable();
-    bool isEnabled();
+    bool isEnabled() const;
 
     void traceLayers(const char* where, LayersProto);
+    void dump(String8& result) const;
 
 private:
     static constexpr auto DEFAULT_FILENAME = "/data/misc/wmtrace/layers_trace.pb";
@@ -43,8 +46,8 @@
 
     bool mEnabled = false;
     std::string mOutputFileName = DEFAULT_FILENAME;
-    std::mutex mTraceMutex;
-    LayersTraceFileProto mTrace;
+    mutable std::mutex mTraceMutex;
+    std::unique_ptr<LayersTraceFileProto> mTrace;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
index a5bf9c1..1d7fb67 100644
--- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp
+++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
@@ -31,17 +31,12 @@
     int32_t lz = lhs->z;
     int32_t rz = rhs->z;
     if (lz != rz) {
-        return (lz > rz) ? 1 : -1;
+        return lz < rz;
     }
 
     return lhs->id < rhs->id;
 }
 
-bool sortLayerUniquePtrs(const std::unique_ptr<LayerProtoParser::Layer>& lhs,
-                   const std::unique_ptr<LayerProtoParser::Layer>& rhs) {
-    return sortLayers(lhs.get(), rhs.get());
-}
-
 const LayerProtoParser::LayerGlobal LayerProtoParser::generateLayerGlobalInfo(
         const LayersProto& layersProto) {
     LayerGlobal layerGlobal;
@@ -52,77 +47,80 @@
     return layerGlobal;
 }
 
-std::vector<std::unique_ptr<LayerProtoParser::Layer>> LayerProtoParser::generateLayerTree(
-        const LayersProto& layersProto) {
-    std::unordered_map<int32_t, LayerProtoParser::Layer*> layerMap = generateMap(layersProto);
-    std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers;
+LayerProtoParser::LayerTree LayerProtoParser::generateLayerTree(const LayersProto& layersProto) {
+    LayerTree layerTree;
+    layerTree.allLayers = generateLayerList(layersProto);
 
-    for (std::pair<int32_t, Layer*> kv : layerMap) {
-        if (kv.second->parent == nullptr) {
-            // Make unique_ptr for top level layers since they are not children. This ensures there
-            // will only be one unique_ptr made for each layer.
-            layers.push_back(std::unique_ptr<Layer>(kv.second));
+    // find and sort the top-level layers
+    for (Layer& layer : layerTree.allLayers) {
+        if (layer.parent == nullptr) {
+            layerTree.topLevelLayers.push_back(&layer);
         }
     }
+    std::sort(layerTree.topLevelLayers.begin(), layerTree.topLevelLayers.end(), sortLayers);
 
-    std::sort(layers.begin(), layers.end(), sortLayerUniquePtrs);
-    return layers;
+    return layerTree;
 }
 
-std::unordered_map<int32_t, LayerProtoParser::Layer*> LayerProtoParser::generateMap(
+std::vector<LayerProtoParser::Layer> LayerProtoParser::generateLayerList(
         const LayersProto& layersProto) {
+    std::vector<Layer> layerList;
     std::unordered_map<int32_t, Layer*> layerMap;
 
+    // build the layer list and the layer map
+    layerList.reserve(layersProto.layers_size());
+    layerMap.reserve(layersProto.layers_size());
     for (int i = 0; i < layersProto.layers_size(); i++) {
-        const LayerProto& layerProto = layersProto.layers(i);
-        layerMap[layerProto.id()] = generateLayer(layerProto);
+        layerList.emplace_back(generateLayer(layersProto.layers(i)));
+        // this works because layerList never changes capacity
+        layerMap[layerList.back().id] = &layerList.back();
     }
 
+    // fix up children and relatives
     for (int i = 0; i < layersProto.layers_size(); i++) {
-        const LayerProto& layerProto = layersProto.layers(i);
-        updateChildrenAndRelative(layerProto, layerMap);
+        updateChildrenAndRelative(layersProto.layers(i), layerMap);
     }
 
-    return layerMap;
+    return layerList;
 }
 
-LayerProtoParser::Layer* LayerProtoParser::generateLayer(const LayerProto& layerProto) {
-    Layer* layer = new Layer();
-    layer->id = layerProto.id();
-    layer->name = layerProto.name();
-    layer->type = layerProto.type();
-    layer->transparentRegion = generateRegion(layerProto.transparent_region());
-    layer->visibleRegion = generateRegion(layerProto.visible_region());
-    layer->damageRegion = generateRegion(layerProto.damage_region());
-    layer->layerStack = layerProto.layer_stack();
-    layer->z = layerProto.z();
-    layer->position = {layerProto.position().x(), layerProto.position().y()};
-    layer->requestedPosition = {layerProto.requested_position().x(),
+LayerProtoParser::Layer LayerProtoParser::generateLayer(const LayerProto& layerProto) {
+    Layer layer;
+    layer.id = layerProto.id();
+    layer.name = layerProto.name();
+    layer.type = layerProto.type();
+    layer.transparentRegion = generateRegion(layerProto.transparent_region());
+    layer.visibleRegion = generateRegion(layerProto.visible_region());
+    layer.damageRegion = generateRegion(layerProto.damage_region());
+    layer.layerStack = layerProto.layer_stack();
+    layer.z = layerProto.z();
+    layer.position = {layerProto.position().x(), layerProto.position().y()};
+    layer.requestedPosition = {layerProto.requested_position().x(),
                                 layerProto.requested_position().y()};
-    layer->size = {layerProto.size().w(), layerProto.size().h()};
-    layer->crop = generateRect(layerProto.crop());
-    layer->isOpaque = layerProto.is_opaque();
-    layer->invalidate = layerProto.invalidate();
-    layer->dataspace = layerProto.dataspace();
-    layer->pixelFormat = layerProto.pixel_format();
-    layer->color = {layerProto.color().r(), layerProto.color().g(), layerProto.color().b(),
+    layer.size = {layerProto.size().w(), layerProto.size().h()};
+    layer.crop = generateRect(layerProto.crop());
+    layer.isOpaque = layerProto.is_opaque();
+    layer.invalidate = layerProto.invalidate();
+    layer.dataspace = layerProto.dataspace();
+    layer.pixelFormat = layerProto.pixel_format();
+    layer.color = {layerProto.color().r(), layerProto.color().g(), layerProto.color().b(),
                     layerProto.color().a()};
-    layer->requestedColor = {layerProto.requested_color().r(), layerProto.requested_color().g(),
+    layer.requestedColor = {layerProto.requested_color().r(), layerProto.requested_color().g(),
                              layerProto.requested_color().b(), layerProto.requested_color().a()};
-    layer->flags = layerProto.flags();
-    layer->transform = generateTransform(layerProto.transform());
-    layer->requestedTransform = generateTransform(layerProto.requested_transform());
-    layer->activeBuffer = generateActiveBuffer(layerProto.active_buffer());
-    layer->bufferTransform = generateTransform(layerProto.buffer_transform());
-    layer->queuedFrames = layerProto.queued_frames();
-    layer->refreshPending = layerProto.refresh_pending();
-    layer->hwcFrame = generateRect(layerProto.hwc_frame());
-    layer->hwcCrop = generateFloatRect(layerProto.hwc_crop());
-    layer->hwcTransform = layerProto.hwc_transform();
-    layer->windowType = layerProto.window_type();
-    layer->appId = layerProto.app_id();
-    layer->hwcCompositionType = layerProto.hwc_composition_type();
-    layer->isProtected = layerProto.is_protected();
+    layer.flags = layerProto.flags();
+    layer.transform = generateTransform(layerProto.transform());
+    layer.requestedTransform = generateTransform(layerProto.requested_transform());
+    layer.activeBuffer = generateActiveBuffer(layerProto.active_buffer());
+    layer.bufferTransform = generateTransform(layerProto.buffer_transform());
+    layer.queuedFrames = layerProto.queued_frames();
+    layer.refreshPending = layerProto.refresh_pending();
+    layer.hwcFrame = generateRect(layerProto.hwc_frame());
+    layer.hwcCrop = generateFloatRect(layerProto.hwc_crop());
+    layer.hwcTransform = layerProto.hwc_transform();
+    layer.windowType = layerProto.window_type();
+    layer.appId = layerProto.app_id();
+    layer.hwcCompositionType = layerProto.hwc_composition_type();
+    layer.isProtected = layerProto.is_protected();
 
     return layer;
 }
@@ -186,9 +184,7 @@
 
     for (int i = 0; i < layerProto.children_size(); i++) {
         if (layerMap.count(layerProto.children(i)) > 0) {
-            // Only make unique_ptrs for children since they are guaranteed to be unique, only one
-            // parent per child. This ensures there will only be one unique_ptr made for each layer.
-            currLayer->children.push_back(std::unique_ptr<Layer>(layerMap[layerProto.children(i)]));
+            currLayer->children.push_back(layerMap[layerProto.children(i)]);
         }
     }
 
@@ -211,29 +207,28 @@
     }
 }
 
-std::string LayerProtoParser::layersToString(
-        std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers) {
+std::string LayerProtoParser::layerTreeToString(const LayerTree& layerTree) {
     std::string result;
-    for (std::unique_ptr<LayerProtoParser::Layer>& layer : layers) {
+    for (const LayerProtoParser::Layer* layer : layerTree.topLevelLayers) {
         if (layer->zOrderRelativeOf != nullptr) {
             continue;
         }
-        result.append(layerToString(layer.get()).c_str());
+        result.append(layerToString(layer));
     }
 
     return result;
 }
 
-std::string LayerProtoParser::layerToString(LayerProtoParser::Layer* layer) {
+std::string LayerProtoParser::layerToString(const LayerProtoParser::Layer* layer) {
     std::string result;
 
     std::vector<Layer*> traverse(layer->relatives);
-    for (std::unique_ptr<LayerProtoParser::Layer>& child : layer->children) {
+    for (LayerProtoParser::Layer* child : layer->children) {
         if (child->zOrderRelativeOf != nullptr) {
             continue;
         }
 
-        traverse.push_back(child.get());
+        traverse.push_back(child);
     }
 
     std::sort(traverse.begin(), traverse.end(), sortLayers);
@@ -244,13 +239,13 @@
         if (relative->z >= 0) {
             break;
         }
-        result.append(layerToString(relative).c_str());
+        result.append(layerToString(relative));
     }
-    result.append(layer->to_string().c_str());
+    result.append(layer->to_string());
     result.append("\n");
     for (; i < traverse.size(); i++) {
         auto& relative = traverse[i];
-        result.append(layerToString(relative).c_str());
+        result.append(layerToString(relative));
     }
 
     return result;
diff --git a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
index b1610cf..6b3b497 100644
--- a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
+++ b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
@@ -80,7 +80,7 @@
     public:
         int32_t id;
         std::string name;
-        std::vector<std::unique_ptr<Layer>> children;
+        std::vector<Layer*> children;
         std::vector<Layer*> relatives;
         std::string type;
         LayerProtoParser::Region transparentRegion;
@@ -126,13 +126,22 @@
         int32_t globalTransform;
     };
 
+    class LayerTree {
+    public:
+        // all layers in LayersProto and in the original order
+        std::vector<Layer> allLayers;
+
+        // pointers to top-level layers in allLayers
+        std::vector<Layer*> topLevelLayers;
+    };
+
     static const LayerGlobal generateLayerGlobalInfo(const LayersProto& layersProto);
-    static std::vector<std::unique_ptr<Layer>> generateLayerTree(const LayersProto& layersProto);
-    static std::string layersToString(std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers);
+    static LayerTree generateLayerTree(const LayersProto& layersProto);
+    static std::string layerTreeToString(const LayerTree& layerTree);
 
 private:
-    static std::unordered_map<int32_t, Layer*> generateMap(const LayersProto& layersProto);
-    static LayerProtoParser::Layer* generateLayer(const LayerProto& layerProto);
+    static std::vector<Layer> generateLayerList(const LayersProto& layersProto);
+    static LayerProtoParser::Layer generateLayer(const LayerProto& layerProto);
     static LayerProtoParser::Region generateRegion(const RegionProto& regionProto);
     static LayerProtoParser::Rect generateRect(const RectProto& rectProto);
     static LayerProtoParser::FloatRect generateFloatRect(const FloatRectProto& rectProto);
@@ -142,7 +151,7 @@
     static void updateChildrenAndRelative(const LayerProto& layerProto,
                                           std::unordered_map<int32_t, Layer*>& layerMap);
 
-    static std::string layerToString(LayerProtoParser::Layer* layer);
+    static std::string layerToString(const LayerProtoParser::Layer* layer);
 };
 
 } // namespace surfaceflinger
diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp
index 8e23eb8e..9e762f0 100644
--- a/services/surfaceflinger/tests/Credentials_test.cpp
+++ b/services/surfaceflinger/tests/Credentials_test.cpp
@@ -23,8 +23,6 @@
 namespace {
 const String8 DISPLAY_NAME("Credentials Display Test");
 const String8 SURFACE_NAME("Test Surface Name");
-const int32_t MIN_LAYER_Z = 0;
-const int32_t MAX_LAYER_Z = std::numeric_limits<int32_t>::max();
 const uint32_t ROTATION = 0;
 const float FRAME_SCALE = 1.0f;
 } // namespace
@@ -269,8 +267,8 @@
     sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
     std::function<status_t()> condition = [=]() {
         sp<GraphicBuffer> outBuffer;
-        return ScreenshotClient::capture(display, Rect(), 0 /*reqWidth*/, 0 /*reqHeight*/,
-                                         MIN_LAYER_Z, MAX_LAYER_Z, false, ROTATION, &outBuffer);
+        return ScreenshotClient::capture(display, Rect(), 0 /*reqWidth*/, 0 /*reqHeight*/, false,
+                                         ROTATION, &outBuffer);
     };
     ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
 }
diff --git a/services/surfaceflinger/tests/Stress_test.cpp b/services/surfaceflinger/tests/Stress_test.cpp
index 4577153..3e1be8e 100644
--- a/services/surfaceflinger/tests/Stress_test.cpp
+++ b/services/surfaceflinger/tests/Stress_test.cpp
@@ -101,10 +101,7 @@
     for (int i = 0; i < 100000; i++) {
         surfaceflinger::LayersProto layersProto = generateLayerProto();
         auto layerTree = surfaceflinger::LayerProtoParser::generateLayerTree(layersProto);
-        // Allow some layerTrees to just fall out of scope (instead of std::move)
-        if (i % 2) {
-            surfaceflinger::LayerProtoParser::layersToString(std::move(layerTree));
-        }
+        surfaceflinger::LayerProtoParser::layerTreeToString(layerTree);
     }
     system(cmd.c_str());
 }
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index ed1529b..3af98e5 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -186,17 +186,15 @@
 // individual pixel values for testing purposes.
 class ScreenCapture : public RefBase {
 public:
-    static void captureScreen(sp<ScreenCapture>* sc, int32_t minLayerZ = 0,
-                              int32_t maxLayerZ = std::numeric_limits<int32_t>::max()) {
+    static void captureScreen(std::unique_ptr<ScreenCapture>* sc) {
         sp<ISurfaceComposer> sf(ComposerService::getComposerService());
         sp<IBinder> display(sf->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
         SurfaceComposerClient::Transaction().apply(true);
 
         sp<GraphicBuffer> outBuffer;
         ASSERT_EQ(NO_ERROR,
-                  sf->captureScreen(display, &outBuffer, Rect(), 0, 0, minLayerZ, maxLayerZ,
-                                    false));
-        *sc = new ScreenCapture(outBuffer);
+                  sf->captureScreen(display, &outBuffer, Rect(), 0, 0, false));
+        *sc = std::make_unique<ScreenCapture>(outBuffer);
     }
 
     static void captureLayers(std::unique_ptr<ScreenCapture>* sc, sp<IBinder>& parentHandle,
@@ -318,6 +316,12 @@
         ASSERT_NO_FATAL_FAILURE(SetUpDisplay());
     }
 
+    virtual void TearDown() {
+        mBlackBgSurface = 0;
+        mClient->dispose();
+        mClient = 0;
+    }
+
     virtual sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height,
                                            uint32_t flags = 0) {
         auto layer =
@@ -445,9 +449,9 @@
         Transaction().setBuffer(layer, buffer).setSize(layer, bufferWidth, bufferHeight).apply();
     }
 
-    sp<ScreenCapture> screenshot() {
-        sp<ScreenCapture> screenshot;
-        ScreenCapture::captureScreen(&screenshot, mLayerZBase);
+    std::unique_ptr<ScreenCapture> screenshot() {
+        std::unique_ptr<ScreenCapture> screenshot;
+        ScreenCapture::captureScreen(&screenshot);
         return screenshot;
     }
 
@@ -465,6 +469,7 @@
     void setSizeBasicHelper(uint32_t layerType);
     void setMatrixWithResizeHelper(uint32_t layerType);
 
+    sp<SurfaceControl> mBlackBgSurface;
 private:
     void SetUpDisplay() {
         mDisplay = mClient->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain);
@@ -482,13 +487,26 @@
         mBufferPostDelay = int32_t(1e6 / info.fps) * 3;
 
         mDisplayLayerStack = 0;
+
+        mBlackBgSurface = mClient->createSurface(String8("BaseSurface"), mDisplayWidth,
+                                                 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
+                                                 ISurfaceComposerClient::eFXSurfaceColor);
+
         // set layer stack (b/68888219)
         Transaction t;
         t.setDisplayLayerStack(mDisplay, mDisplayLayerStack);
+        t.setLayerStack(mBlackBgSurface, mDisplayLayerStack);
+        t.setColor(mBlackBgSurface, half3{0, 0, 0});
+        t.setLayer(mBlackBgSurface, mLayerZBase);
         t.apply();
     }
 
-    void waitForLayerBuffers() { usleep(mBufferPostDelay); }
+    void waitForLayerBuffers() {
+        // Request an empty transaction to get applied synchronously to ensure the buffer is
+        // latched.
+        Transaction().apply(true);
+        usleep(mBufferPostDelay);
+    }
 
     int32_t mBufferPostDelay;
 };
@@ -793,6 +811,9 @@
 }
 
 TEST_P(LayerTypeTransactionTest, SetZNegative) {
+    sp<SurfaceControl> parent =
+            LayerTransactionTest::createLayer("Parent", mDisplayWidth, mDisplayHeight,
+                                              ISurfaceComposerClient::eFXSurfaceContainer);
     sp<SurfaceControl> layerR;
     sp<SurfaceControl> layerG;
     ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32));
@@ -800,20 +821,22 @@
     ASSERT_NO_FATAL_FAILURE(layerG = createLayer("test G", 32, 32));
     ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerG, Color::GREEN, 32, 32));
 
+    Transaction()
+            .reparent(layerR, parent->getHandle())
+            .reparent(layerG, parent->getHandle())
+            .apply();
     Transaction().setLayer(layerR, -1).setLayer(layerG, -2).apply();
     {
         SCOPED_TRACE("layerR");
-        sp<ScreenCapture> screenshot;
-        ScreenCapture::captureScreen(&screenshot, -2, -1);
-        screenshot->expectColor(Rect(0, 0, 32, 32), Color::RED);
+        auto shot = screenshot();
+        shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
     }
 
     Transaction().setLayer(layerR, -3).apply();
     {
         SCOPED_TRACE("layerG");
-        sp<ScreenCapture> screenshot;
-        ScreenCapture::captureScreen(&screenshot, -3, -1);
-        screenshot->expectColor(Rect(0, 0, 32, 32), Color::GREEN);
+        auto shot = screenshot();
+        shot->expectColor(Rect(0, 0, 32, 32), Color::GREEN);
     }
 }
 
@@ -846,6 +869,9 @@
 }
 
 TEST_P(LayerTypeTransactionTest, SetRelativeZNegative) {
+    sp<SurfaceControl> parent =
+            LayerTransactionTest::createLayer("Parent", mDisplayWidth, mDisplayHeight,
+                                              ISurfaceComposerClient::eFXSurfaceContainer);
     sp<SurfaceControl> layerR;
     sp<SurfaceControl> layerG;
     sp<SurfaceControl> layerB;
@@ -856,12 +882,17 @@
     ASSERT_NO_FATAL_FAILURE(layerB = createLayer("test B", 32, 32));
     ASSERT_NO_FATAL_FAILURE(fillLayerColor(layerB, Color::BLUE, 32, 32));
 
+    Transaction()
+            .reparent(layerB, parent->getHandle())
+            .apply();
+
     // layerR = mLayerZBase, layerG = layerR - 1, layerB = -2
     Transaction().setRelativeLayer(layerG, layerR->getHandle(), -1).setLayer(layerB, -2).apply();
 
-    sp<ScreenCapture> screenshot;
+    std::unique_ptr<ScreenCapture> screenshot;
     // only layerB is in this range
-    ScreenCapture::captureScreen(&screenshot, -2, -1);
+    sp<IBinder> parentHandle = parent->getHandle();
+    ScreenCapture::captureLayers(&screenshot, parentHandle);
     screenshot->expectColor(Rect(0, 0, 32, 32), Color::BLUE);
 }
 
@@ -1006,13 +1037,11 @@
             .setFlags(layer, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure)
             .apply(true);
     ASSERT_EQ(PERMISSION_DENIED,
-              composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, mLayerZBase, mLayerZBase,
-                                      false));
+              composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, false));
 
     Transaction().setFlags(layer, 0, layer_state_t::eLayerSecure).apply(true);
     ASSERT_EQ(NO_ERROR,
-              composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, mLayerZBase, mLayerZBase,
-                                      false));
+              composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, false));
 }
 
 TEST_F(LayerTransactionTest, SetTransparentRegionHintBasic_BufferQueue) {
@@ -2038,8 +2067,8 @@
 class LayerUpdateTest : public LayerTransactionTest {
 protected:
     virtual void SetUp() {
-        mComposerClient = new SurfaceComposerClient;
-        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
+        LayerTransactionTest::SetUp();
+        ASSERT_EQ(NO_ERROR, mClient->initCheck());
 
         sp<IBinder> display(
                 SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
@@ -2050,24 +2079,22 @@
         ssize_t displayHeight = info.h;
 
         // Background surface
-        mBGSurfaceControl =
-                mComposerClient->createSurface(String8("BG Test Surface"), displayWidth,
-                                               displayHeight, PIXEL_FORMAT_RGBA_8888, 0);
+        mBGSurfaceControl = createLayer(String8("BG Test Surface"), displayWidth,
+                                               displayHeight, 0);
         ASSERT_TRUE(mBGSurfaceControl != nullptr);
         ASSERT_TRUE(mBGSurfaceControl->isValid());
         fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
 
         // Foreground surface
-        mFGSurfaceControl = mComposerClient->createSurface(String8("FG Test Surface"), 64, 64,
-                                                           PIXEL_FORMAT_RGBA_8888, 0);
+        mFGSurfaceControl = createLayer(String8("FG Test Surface"), 64, 64, 0);
+
         ASSERT_TRUE(mFGSurfaceControl != nullptr);
         ASSERT_TRUE(mFGSurfaceControl->isValid());
 
         fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
 
         // Synchronization surface
-        mSyncSurfaceControl = mComposerClient->createSurface(String8("Sync Test Surface"), 1, 1,
-                                                             PIXEL_FORMAT_RGBA_8888, 0);
+        mSyncSurfaceControl = createLayer(String8("Sync Test Surface"), 1, 1, 0);
         ASSERT_TRUE(mSyncSurfaceControl != nullptr);
         ASSERT_TRUE(mSyncSurfaceControl->isValid());
 
@@ -2089,11 +2116,10 @@
     }
 
     virtual void TearDown() {
-        mComposerClient->dispose();
+        LayerTransactionTest::TearDown();
         mBGSurfaceControl = 0;
         mFGSurfaceControl = 0;
         mSyncSurfaceControl = 0;
-        mComposerClient = 0;
     }
 
     void waitForPostedBuffers() {
@@ -2112,7 +2138,6 @@
         t.apply(true);
     }
 
-    sp<SurfaceComposerClient> mComposerClient;
     sp<SurfaceControl> mBGSurfaceControl;
     sp<SurfaceControl> mFGSurfaceControl;
 
@@ -2122,10 +2147,10 @@
 };
 
 TEST_F(LayerUpdateTest, RelativesAreNotDetached) {
-    sp<ScreenCapture> sc;
 
-    sp<SurfaceControl> relative = mComposerClient->createSurface(String8("relativeTestSurface"), 10,
-                                                                 10, PIXEL_FORMAT_RGBA_8888, 0);
+    std::unique_ptr<ScreenCapture> sc;
+
+    sp<SurfaceControl> relative = createLayer(String8("relativeTestSurface"), 10, 10, 0);
     fillSurfaceRGBA8(relative, 10, 10, 10);
     waitForPostedBuffers();
 
@@ -2188,7 +2213,7 @@
 
         EXPECT_INITIAL_STATE("After restoring initial state");
     }
-    sp<ScreenCapture> sc;
+    std::unique_ptr<ScreenCapture> sc;
 };
 
 class CropLatchingTest : public GeometryLatchingTest {
@@ -2213,7 +2238,7 @@
 };
 
 TEST_F(LayerUpdateTest, DeferredTransactionTest) {
-    sp<ScreenCapture> sc;
+    std::unique_ptr<ScreenCapture> sc;
     {
         SCOPED_TRACE("before anything");
         ScreenCapture::captureScreen(&sc);
@@ -2268,13 +2293,13 @@
 }
 
 TEST_F(LayerUpdateTest, LayerWithNoBuffersResizesImmediately) {
-    sp<ScreenCapture> sc;
+    std::unique_ptr<ScreenCapture> sc;
 
     sp<SurfaceControl> childNoBuffer =
-            mComposerClient->createSurface(String8("Bufferless child"), 10, 10,
+            mClient->createSurface(String8("Bufferless child"), 10, 10,
                                            PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
     sp<SurfaceControl> childBuffer =
-            mComposerClient->createSurface(String8("Buffered child"), 20, 20,
+            mClient->createSurface(String8("Buffered child"), 20, 20,
                                            PIXEL_FORMAT_RGBA_8888, 0, childNoBuffer.get());
     fillSurfaceRGBA8(childBuffer, 200, 200, 200);
 
@@ -2296,7 +2321,7 @@
 }
 
 TEST_F(LayerUpdateTest, MergingTransactions) {
-    sp<ScreenCapture> sc;
+    std::unique_ptr<ScreenCapture> sc;
     {
         SCOPED_TRACE("before move");
         ScreenCapture::captureScreen(&sc);
@@ -2323,13 +2348,13 @@
 protected:
     void SetUp() override {
         LayerUpdateTest::SetUp();
-        mChild = mComposerClient->createSurface(String8("Child surface"), 10, 10,
+        mChild = mClient->createSurface(String8("Child surface"), 10, 10,
                                                 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
         fillSurfaceRGBA8(mChild, 200, 200, 200);
 
         {
             SCOPED_TRACE("before anything");
-            ScreenCapture::captureScreen(&mCapture);
+            mCapture = screenshot();
             mCapture->expectChildColor(64, 64);
         }
     }
@@ -2339,7 +2364,7 @@
     }
 
     sp<SurfaceControl> mChild;
-    sp<ScreenCapture> mCapture;
+    std::unique_ptr<ScreenCapture> mCapture;
 };
 
 TEST_F(ChildLayerTest, ChildLayerPositioning) {
@@ -2350,7 +2375,7 @@
     });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // Top left of foreground must now be visible
         mCapture->expectFGColor(64, 64);
         // But 10 pixels in we should see the child surface
@@ -2362,7 +2387,7 @@
     asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // Top left of foreground should now be at 0, 0
         mCapture->expectFGColor(0, 0);
         // But 10 pixels in we should see the child surface
@@ -2381,7 +2406,7 @@
     });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         mCapture->expectChildColor(0, 0);
         mCapture->expectChildColor(4, 4);
         mCapture->expectBGColor(5, 5);
@@ -2396,7 +2421,7 @@
     });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         mCapture->expectFGColor(0, 0);
         // Last pixel in foreground should now be the child.
         mCapture->expectChildColor(63, 63);
@@ -2411,7 +2436,7 @@
 
     // Find the boundary between the parent and child
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         mCapture->expectChildColor(9, 9);
         mCapture->expectFGColor(10, 10);
     }
@@ -2421,7 +2446,7 @@
     // The boundary should be twice as far from the origin now.
     // The pixels from the last test should all be child now
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         mCapture->expectChildColor(9, 9);
         mCapture->expectChildColor(10, 10);
         mCapture->expectChildColor(19, 19);
@@ -2442,7 +2467,7 @@
     });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // Unblended child color
         mCapture->checkPixel(0, 0, 0, 254, 0);
     }
@@ -2450,7 +2475,7 @@
     asTransaction([&](Transaction& t) { t.setAlpha(mChild, 0.5); });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // Child and BG blended.
         mCapture->checkPixel(0, 0, 127, 127, 0);
     }
@@ -2458,7 +2483,7 @@
     asTransaction([&](Transaction& t) { t.setAlpha(mFGSurfaceControl, 0.5); });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // Child and BG blended.
         mCapture->checkPixel(0, 0, 95, 64, 95);
     }
@@ -2472,7 +2497,7 @@
     });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // Top left of foreground must now be visible
         mCapture->expectFGColor(64, 64);
         // But 10 pixels in we should see the child surface
@@ -2486,7 +2511,7 @@
     });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         mCapture->expectFGColor(64, 64);
         // In reparenting we should have exposed the entire foreground surface.
         mCapture->expectFGColor(74, 74);
@@ -2505,7 +2530,7 @@
     });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // Top left of foreground must now be visible
         mCapture->expectFGColor(64, 64);
         // But 10 pixels in we should see the child surface
@@ -2514,6 +2539,7 @@
         mCapture->expectFGColor(84, 84);
     }
 
+
     asTransaction([&](Transaction& t) { t.detachChildren(mFGSurfaceControl); });
 
     asTransaction([&](Transaction& t) { t.hide(mChild); });
@@ -2521,7 +2547,7 @@
     // Since the child has the same client as the parent, it will not get
     // detached and will be hidden.
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         mCapture->expectFGColor(64, 64);
         mCapture->expectFGColor(74, 74);
         mCapture->expectFGColor(84, 84);
@@ -2547,7 +2573,7 @@
     });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // Top left of foreground must now be visible
         mCapture->expectFGColor(64, 64);
         // But 10 pixels in we should see the child surface
@@ -2562,7 +2588,7 @@
 
     // Nothing should have changed.
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         mCapture->expectFGColor(64, 64);
         mCapture->expectChildColor(74, 74);
         mCapture->expectFGColor(84, 84);
@@ -2577,7 +2603,7 @@
     });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // We've positioned the child in the top left.
         mCapture->expectChildColor(0, 0);
         // But it's only 10x10.
@@ -2591,7 +2617,7 @@
     });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // We've positioned the child in the top left.
         mCapture->expectChildColor(0, 0);
         mCapture->expectChildColor(10, 10);
@@ -2610,7 +2636,7 @@
     });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // We've positioned the child in the top left.
         mCapture->expectChildColor(0, 0);
         // But it's only 10x10.
@@ -2629,7 +2655,7 @@
     {
         // The child should still be in the same place and not have any strange scaling as in
         // b/37673612.
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         mCapture->expectChildColor(0, 0);
         mCapture->expectFGColor(10, 10);
     }
@@ -2640,7 +2666,7 @@
     mChild.clear();
 
     // Now recreate it as hidden
-    mChild = mComposerClient->createSurface(String8("Child surface"), 10, 10,
+    mChild = mClient->createSurface(String8("Child surface"), 10, 10,
                                             PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eHidden,
                                             mFGSurfaceControl.get());
 
@@ -2674,7 +2700,7 @@
     });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // Top left of foreground must now be visible
         mCapture->expectFGColor(64, 64);
         // But 10 pixels in we should see the child surface
@@ -2686,7 +2712,7 @@
     asTransaction([&](Transaction& t) { t.reparent(mChild, mBGSurfaceControl->getHandle()); });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         mCapture->expectFGColor(64, 64);
         // In reparenting we should have exposed the entire foreground surface.
         mCapture->expectFGColor(74, 74);
@@ -2705,7 +2731,7 @@
     });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // Top left of foreground must now be visible
         mCapture->expectFGColor(64, 64);
         // But 10 pixels in we should see the child surface
@@ -2715,7 +2741,7 @@
     }
     asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // Nothing should have changed.
         mCapture->expectFGColor(64, 64);
         mCapture->expectChildColor(74, 74);
@@ -2724,8 +2750,7 @@
 }
 
 TEST_F(ChildLayerTest, ReparentFromNoParent) {
-    sp<SurfaceControl> newSurface = mComposerClient->createSurface(String8("New Surface"), 10, 10,
-                                                                   PIXEL_FORMAT_RGBA_8888, 0);
+    sp<SurfaceControl> newSurface = createLayer(String8("New Surface"), 10, 10, 0);
     ASSERT_TRUE(newSurface != nullptr);
     ASSERT_TRUE(newSurface->isValid());
 
@@ -2739,7 +2764,7 @@
     });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // Top left of foreground must now be visible
         mCapture->expectFGColor(64, 64);
         // At 10, 10 we should see the new surface
@@ -2749,7 +2774,7 @@
     asTransaction([&](Transaction& t) { t.reparent(newSurface, mFGSurfaceControl->getHandle()); });
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // newSurface will now be a child of mFGSurface so it will be 10, 10 offset from
         // mFGSurface, putting it at 74, 74.
         mCapture->expectFGColor(64, 64);
@@ -2760,12 +2785,12 @@
 
 TEST_F(ChildLayerTest, NestedChildren) {
     sp<SurfaceControl> grandchild =
-            mComposerClient->createSurface(String8("Grandchild surface"), 10, 10,
+            mClient->createSurface(String8("Grandchild surface"), 10, 10,
                                            PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
     fillSurfaceRGBA8(grandchild, 50, 50, 50);
 
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         // Expect the grandchild to begin at 64, 64 because it's a child of mChild layer
         // which begins at 64, 64
         mCapture->checkPixel(64, 64, 50, 50, 50);
@@ -2773,8 +2798,7 @@
 }
 
 TEST_F(ChildLayerTest, ChildLayerRelativeLayer) {
-    sp<SurfaceControl> relative = mComposerClient->createSurface(String8("Relative surface"), 128,
-                                                                 128, PIXEL_FORMAT_RGBA_8888, 0);
+    sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 128, 128, 0);
     fillSurfaceRGBA8(relative, 255, 255, 255);
 
     Transaction t;
@@ -2786,7 +2810,7 @@
     // We expect that the child should have been elevated above our
     // INT_MAX layer even though it's not a child of it.
     {
-        ScreenCapture::captureScreen(&mCapture);
+        mCapture = screenshot();
         mCapture->expectChildColor(0, 0);
         mCapture->expectChildColor(9, 9);
         mCapture->checkPixel(10, 10, 255, 255, 255);
@@ -2810,7 +2834,7 @@
     auto fgHandle = mFGSurfaceControl->getHandle();
 
     sp<SurfaceControl> child =
-            mComposerClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
+            mClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
                                            0, mFGSurfaceControl.get());
     fillSurfaceRGBA8(child, 200, 200, 200);
 
@@ -2826,7 +2850,7 @@
     auto fgHandle = mFGSurfaceControl->getHandle();
 
     sp<SurfaceControl> child =
-            mComposerClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
+            mClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
                                            0, mFGSurfaceControl.get());
     fillSurfaceRGBA8(child, 200, 200, 200);
 
@@ -2840,7 +2864,7 @@
 
 TEST_F(ScreenCaptureTest, CaptureTransparent) {
     sp<SurfaceControl> child =
-            mComposerClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
+            mClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
                                            0, mFGSurfaceControl.get());
 
     fillSurfaceRGBA8(child, 200, 200, 200);
@@ -2860,10 +2884,9 @@
     auto fgHandle = mFGSurfaceControl->getHandle();
 
     sp<SurfaceControl> child =
-            mComposerClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
+            mClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
                                            0, mFGSurfaceControl.get());
-    sp<SurfaceControl> relative = mComposerClient->createSurface(String8("Relative surface"), 10,
-                                                                 10, PIXEL_FORMAT_RGBA_8888, 0);
+    sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 10, 10, 0);
     fillSurfaceRGBA8(child, 200, 200, 200);
     fillSurfaceRGBA8(relative, 100, 100, 100);
 
@@ -2884,10 +2907,10 @@
     auto fgHandle = mFGSurfaceControl->getHandle();
 
     sp<SurfaceControl> child =
-            mComposerClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
+            mClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
                                            0, mFGSurfaceControl.get());
     sp<SurfaceControl> relative =
-            mComposerClient->createSurface(String8("Relative surface"), 10, 10,
+            mClient->createSurface(String8("Relative surface"), 10, 10,
                                            PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
     fillSurfaceRGBA8(child, 200, 200, 200);
     fillSurfaceRGBA8(relative, 100, 100, 100);
@@ -2918,7 +2941,7 @@
         LayerUpdateTest::SetUp();
 
         mChild =
-            mComposerClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
+            mClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
                     0, mFGSurfaceControl.get());
         fillSurfaceRGBA8(mChild, 200, 200, 200);
 
@@ -2976,12 +2999,12 @@
     auto fgHandle = mFGSurfaceControl->getHandle();
 
     sp<SurfaceControl> child =
-            mComposerClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
+            mClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
                                            0, mFGSurfaceControl.get());
     fillSurfaceRGBA8(child, 200, 200, 200);
 
     sp<SurfaceControl> grandchild =
-            mComposerClient->createSurface(String8("Grandchild surface"), 5, 5,
+            mClient->createSurface(String8("Grandchild surface"), 5, 5,
                                            PIXEL_FORMAT_RGBA_8888, 0, child.get());
 
     fillSurfaceRGBA8(grandchild, 50, 50, 50);
@@ -3000,7 +3023,7 @@
 
 TEST_F(ScreenCaptureTest, CaptureChildOnly) {
     sp<SurfaceControl> child =
-            mComposerClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
+            mClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
                                            0, mFGSurfaceControl.get());
     fillSurfaceRGBA8(child, 200, 200, 200);
     auto childHandle = child->getHandle();
@@ -3015,13 +3038,13 @@
 
 TEST_F(ScreenCaptureTest, CaptureGrandchildOnly) {
     sp<SurfaceControl> child =
-            mComposerClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
+            mClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
                                            0, mFGSurfaceControl.get());
     fillSurfaceRGBA8(child, 200, 200, 200);
     auto childHandle = child->getHandle();
 
     sp<SurfaceControl> grandchild =
-            mComposerClient->createSurface(String8("Grandchild surface"), 5, 5,
+            mClient->createSurface(String8("Grandchild surface"), 5, 5,
                                            PIXEL_FORMAT_RGBA_8888, 0, child.get());
     fillSurfaceRGBA8(grandchild, 50, 50, 50);
 
@@ -3040,10 +3063,9 @@
 }
 
 TEST_F(ScreenCaptureTest, CaptureCrop) {
-    sp<SurfaceControl> redLayer = mComposerClient->createSurface(String8("Red surface"), 60, 60,
-                                                                 PIXEL_FORMAT_RGBA_8888, 0);
+    sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
     sp<SurfaceControl> blueLayer =
-            mComposerClient->createSurface(String8("Blue surface"), 30, 30, PIXEL_FORMAT_RGBA_8888,
+            mClient->createSurface(String8("Blue surface"), 30, 30, PIXEL_FORMAT_RGBA_8888,
                                            0, redLayer.get());
 
     ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
@@ -3074,10 +3096,9 @@
 }
 
 TEST_F(ScreenCaptureTest, CaptureSize) {
-    sp<SurfaceControl> redLayer = mComposerClient->createSurface(String8("Red surface"), 60, 60,
-                                                                 PIXEL_FORMAT_RGBA_8888, 0);
+    sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
     sp<SurfaceControl> blueLayer =
-            mComposerClient->createSurface(String8("Blue surface"), 30, 30, PIXEL_FORMAT_RGBA_8888,
+            mClient->createSurface(String8("Blue surface"), 30, 30, PIXEL_FORMAT_RGBA_8888,
                                            0, redLayer.get());
 
     ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
@@ -3110,13 +3131,12 @@
 }
 
 TEST_F(ScreenCaptureTest, CaptureInvalidLayer) {
-    sp<SurfaceControl> redLayer = mComposerClient->createSurface(String8("Red surface"), 60, 60,
-                                                                 PIXEL_FORMAT_RGBA_8888, 0);
+    sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
 
     ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
 
     auto redLayerHandle = redLayer->getHandle();
-    mComposerClient->destroySurface(redLayerHandle);
+    mClient->destroySurface(redLayerHandle);
     SurfaceComposerClient::Transaction().apply(true);
 
     sp<GraphicBuffer> outBuffer;
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 5aa6e27..d52f0d8 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -185,8 +185,6 @@
     LayerCase::setupForScreenCapture(this);
 
     const Rect sourceCrop(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
-    constexpr int32_t minLayerZ = -1;
-    constexpr int32_t maxLayerZ = 1000;
     constexpr bool useIdentityTransform = true;
     constexpr bool forSystem = true;
 
@@ -194,7 +192,7 @@
                                  DEFAULT_DISPLAY_HEIGHT, ui::Transform::ROT_0);
 
     auto traverseLayers = [this](const LayerVector::Visitor& visitor) {
-        return mFlinger.traverseLayersInDisplay(mDisplay, minLayerZ, maxLayerZ, visitor);
+        return mFlinger.traverseLayersInDisplay(mDisplay, visitor);
     };
 
     // TODO: Eliminate expensive/real allocation if possible.
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 341734c..f367275 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -121,10 +121,9 @@
                                                  useIdentityTransform, forSystem, outSyncFd);
     }
 
-    auto traverseLayersInDisplay(const sp<const DisplayDevice>& display, int32_t minLayerZ,
-                                 int32_t maxLayerZ, const LayerVector::Visitor& visitor) {
-        return mFlinger->SurfaceFlinger::traverseLayersInDisplay(display, minLayerZ, maxLayerZ,
-                                                                 visitor);
+    auto traverseLayersInDisplay(const sp<const DisplayDevice>& display,
+                                 const LayerVector::Visitor& visitor) {
+        return mFlinger->SurfaceFlinger::traverseLayersInDisplay(display, visitor);
     }
 
     /* ------------------------------------------------------------------------
diff --git a/services/vr/bufferhubd/Android.bp b/services/vr/bufferhubd/Android.bp
index 499a8f6..04b9511 100644
--- a/services/vr/bufferhubd/Android.bp
+++ b/services/vr/bufferhubd/Android.bp
@@ -12,46 +12,65 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-sourceFiles = [
-    "buffer_channel.cpp",
-    "buffer_hub.cpp",
-    "buffer_node.cpp",
-    "bufferhubd.cpp",
-    "consumer_channel.cpp",
-    "producer_channel.cpp",
-    "consumer_queue_channel.cpp",
-    "producer_queue_channel.cpp",
-]
-
-headerLibraries = ["libdvr_headers"]
-
-staticLibraries = [
-    "libperformance",
-    "libbufferhub",
-]
-
 sharedLibraries = [
     "libbase",
     "libbinder",
     "libcutils",
-    "liblog",
-    "libsync",
-    "libutils",
     "libgui",
-    "libui",
+    "liblog",
     "libpdx_default_transport",
+    "libsync",
+    "libui",
+    "libutils",
 ]
 
+cc_library_static {
+    name: "libbufferhubd",
+    srcs: [
+        "binder/android/dvr/IBufferHub.aidl",
+        "buffer_channel.cpp",
+        "buffer_hub.cpp",
+        "buffer_hub_binder.cpp",
+        "buffer_node.cpp",
+        "consumer_channel.cpp",
+        "consumer_queue_channel.cpp",
+        "producer_channel.cpp",
+        "producer_queue_channel.cpp",
+    ],
+    cflags: [
+        "-DLOG_TAG=\"libbufferhubd\"",
+        "-DTRACE=0",
+        "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
+    ],
+    export_include_dirs: ["include"],
+    header_libs: ["libdvr_headers"],
+    shared_libs: sharedLibraries,
+    static_libs: [
+        "libbufferhub",
+    ],
+    aidl: {
+        local_include_dirs: ["binder"],
+        include_dirs: ["frameworks/native/aidl/binder"],
+        export_aidl_headers: true,
+    },
+}
+
 cc_binary {
-    srcs: sourceFiles,
+    srcs: ["bufferhubd.cpp"],
     cflags: [
         "-DLOG_TAG=\"bufferhubd\"",
         "-DTRACE=0",
         "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
     ],
-    header_libs: headerLibraries,
-    static_libs: staticLibraries,
+    header_libs: ["libdvr_headers"],
     shared_libs: sharedLibraries,
+    static_libs: [
+        "libbufferhub",
+        "libbufferhubd",
+        "libperformance",
+    ],
     name: "bufferhubd",
     init_rc: ["bufferhubd.rc"],
 }
+
+subdirs = ["tests"]
\ No newline at end of file
diff --git a/services/vr/bufferhubd/binder/android/dvr/IBufferHub.aidl b/services/vr/bufferhubd/binder/android/dvr/IBufferHub.aidl
new file mode 100644
index 0000000..6a86adc
--- /dev/null
+++ b/services/vr/bufferhubd/binder/android/dvr/IBufferHub.aidl
@@ -0,0 +1,5 @@
+package android.dvr;
+
+/** {@hide} */
+interface IBufferHub {
+}
\ No newline at end of file
diff --git a/services/vr/bufferhubd/buffer_channel.cpp b/services/vr/bufferhubd/buffer_channel.cpp
index 2150d62..6d22dee 100644
--- a/services/vr/bufferhubd/buffer_channel.cpp
+++ b/services/vr/bufferhubd/buffer_channel.cpp
@@ -1,5 +1,5 @@
-#include "buffer_channel.h"
-#include "producer_channel.h"
+#include <private/dvr/buffer_channel.h>
+#include <private/dvr/producer_channel.h>
 
 using android::pdx::BorrowedHandle;
 using android::pdx::ErrorStatus;
diff --git a/services/vr/bufferhubd/buffer_hub.cpp b/services/vr/bufferhubd/buffer_hub.cpp
index c0ee31b..15391da 100644
--- a/services/vr/bufferhubd/buffer_hub.cpp
+++ b/services/vr/bufferhubd/buffer_hub.cpp
@@ -1,9 +1,5 @@
-#include "buffer_hub.h"
-
 #include <inttypes.h>
-#include <log/log.h>
 #include <poll.h>
-#include <utils/Trace.h>
 
 #include <iomanip>
 #include <memory>
@@ -11,12 +7,15 @@
 #include <string>
 #include <thread>
 
+#include <log/log.h>
 #include <pdx/default_transport/service_endpoint.h>
 #include <private/dvr/bufferhub_rpc.h>
-#include "buffer_channel.h"
-#include "consumer_channel.h"
-#include "producer_channel.h"
-#include "producer_queue_channel.h"
+#include <private/dvr/buffer_channel.h>
+#include <private/dvr/buffer_hub.h>
+#include <private/dvr/consumer_channel.h>
+#include <private/dvr/producer_channel.h>
+#include <private/dvr/producer_queue_channel.h>
+#include <utils/Trace.h>
 
 using android::pdx::Channel;
 using android::pdx::ErrorStatus;
diff --git a/services/vr/bufferhubd/buffer_hub_binder.cpp b/services/vr/bufferhubd/buffer_hub_binder.cpp
new file mode 100644
index 0000000..def15f1
--- /dev/null
+++ b/services/vr/bufferhubd/buffer_hub_binder.cpp
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+#include <log/log.h>
+#include <private/dvr/buffer_hub_binder.h>
+
+namespace android {
+namespace dvr {
+
+status_t BufferHubBinderService::start() {
+  ProcessState::self()->startThreadPool();
+  IPCThreadState::self()->disableBackgroundScheduling(true);
+  status_t result = BinderService<BufferHubBinderService>::publish();
+  if (result != OK) {
+    ALOGE("Publishing bufferhubd failed with error %d", result);
+    return result;
+  }
+
+  return result;
+}
+
+status_t BufferHubBinderService::dump(int fd, const Vector<String16> & /* args */) {
+  // TODO(b/115435506): not implemented yet
+  FILE *out = fdopen(dup(fd), "w");
+
+  fprintf(out, "BufferHubBinderService::dump(): Not Implemented.\n");
+
+  fclose(out);
+  return NO_ERROR;
+}
+
+
+}  // namespace dvr
+}  // namespace android
\ No newline at end of file
diff --git a/services/vr/bufferhubd/buffer_node.cpp b/services/vr/bufferhubd/buffer_node.cpp
index de22bba..5a04d0c 100644
--- a/services/vr/bufferhubd/buffer_node.cpp
+++ b/services/vr/bufferhubd/buffer_node.cpp
@@ -1,6 +1,5 @@
-#include "buffer_node.h"
-
 #include <private/dvr/buffer_hub_defs.h>
+#include <private/dvr/buffer_node.h>
 
 namespace android {
 namespace dvr {
diff --git a/services/vr/bufferhubd/bufferhubd.cpp b/services/vr/bufferhubd/bufferhubd.cpp
index b27f218..0ca7edc 100644
--- a/services/vr/bufferhubd/bufferhubd.cpp
+++ b/services/vr/bufferhubd/bufferhubd.cpp
@@ -1,13 +1,12 @@
 #include <sched.h>
+#include <sys/resource.h>
 #include <unistd.h>
 
-#include <log/log.h>
-#include <sys/resource.h>
-
 #include <dvr/performance_client_api.h>
+#include <log/log.h>
 #include <pdx/service_dispatcher.h>
-
-#include "buffer_hub.h"
+#include <private/dvr/buffer_hub.h>
+#include <private/dvr/buffer_hub_binder.h>
 
 int main(int, char**) {
   int ret = -1;
@@ -34,11 +33,14 @@
   else
     ALOGI("New nofile limit is %llu/%llu.", rlim.rlim_cur, rlim.rlim_max);
 
+  CHECK_ERROR(android::dvr::BufferHubBinderService::start() != android::OK,
+              error, "Failed to create bufferhub binder service\n");
+
   dispatcher = android::pdx::ServiceDispatcher::Create();
   CHECK_ERROR(!dispatcher, error, "Failed to create service dispatcher\n");
 
   service = android::dvr::BufferHubService::Create();
-  CHECK_ERROR(!service, error, "Failed to create buffer hub service\n");
+  CHECK_ERROR(!service, error, "Failed to create bufferhubd service\n");
   dispatcher->AddService(service);
 
   ret = dvrSetSchedulerClass(0, "graphics");
diff --git a/services/vr/bufferhubd/consumer_channel.cpp b/services/vr/bufferhubd/consumer_channel.cpp
index a6d2dbb..623c9d6 100644
--- a/services/vr/bufferhubd/consumer_channel.cpp
+++ b/services/vr/bufferhubd/consumer_channel.cpp
@@ -1,12 +1,10 @@
-#include "consumer_channel.h"
-
-#include <log/log.h>
-#include <utils/Trace.h>
-
 #include <thread>
 
+#include <log/log.h>
 #include <private/dvr/bufferhub_rpc.h>
-#include "producer_channel.h"
+#include <private/dvr/consumer_channel.h>
+#include <private/dvr/producer_channel.h>
+#include <utils/Trace.h>
 
 using android::pdx::BorrowedHandle;
 using android::pdx::Channel;
diff --git a/services/vr/bufferhubd/consumer_queue_channel.cpp b/services/vr/bufferhubd/consumer_queue_channel.cpp
index 4d43001..74b549d 100644
--- a/services/vr/bufferhubd/consumer_queue_channel.cpp
+++ b/services/vr/bufferhubd/consumer_queue_channel.cpp
@@ -1,8 +1,6 @@
-#include "consumer_queue_channel.h"
-
 #include <pdx/channel_handle.h>
-
-#include "producer_channel.h"
+#include <private/dvr/consumer_queue_channel.h>
+#include <private/dvr/producer_channel.h>
 
 using android::pdx::ErrorStatus;
 using android::pdx::RemoteChannelHandle;
diff --git a/services/vr/bufferhubd/buffer_channel.h b/services/vr/bufferhubd/include/private/dvr/buffer_channel.h
similarity index 96%
rename from services/vr/bufferhubd/buffer_channel.h
rename to services/vr/bufferhubd/include/private/dvr/buffer_channel.h
index ac99a73..bcc93a1 100644
--- a/services/vr/bufferhubd/buffer_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/buffer_channel.h
@@ -1,11 +1,10 @@
 #ifndef ANDROID_DVR_BUFFERHUBD_BUFFER_CHANNEL_H_
 #define ANDROID_DVR_BUFFERHUBD_BUFFER_CHANNEL_H_
 
-#include "buffer_hub.h"
-#include "buffer_node.h"
-
 #include <pdx/channel_handle.h>
 #include <pdx/file_handle.h>
+#include <private/dvr/buffer_hub.h>
+#include <private/dvr/buffer_node.h>
 
 namespace android {
 namespace dvr {
diff --git a/services/vr/bufferhubd/buffer_hub.h b/services/vr/bufferhubd/include/private/dvr/buffer_hub.h
similarity index 100%
rename from services/vr/bufferhubd/buffer_hub.h
rename to services/vr/bufferhubd/include/private/dvr/buffer_hub.h
diff --git a/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h b/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h
new file mode 100644
index 0000000..c0281fd
--- /dev/null
+++ b/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h
@@ -0,0 +1,23 @@
+#ifndef ANDROID_DVR_BUFFER_HUB_BINDER_H
+#define ANDROID_DVR_BUFFER_HUB_BINDER_H
+
+#include <binder/BinderService.h>
+
+#include "android/dvr/BnBufferHub.h"
+
+namespace android {
+namespace dvr {
+
+class BufferHubBinderService : public BinderService<BufferHubBinderService>, public BnBufferHub {
+ public:
+  static status_t start();
+  static const char* getServiceName() { return "bufferhubd"; }
+  // Dump bufferhub related information to given fd (usually stdout)
+  // usage: adb shell dumpsys bufferhubd
+  virtual status_t dump(int fd, const Vector<String16> &args) override;
+};
+
+}  // namespace dvr
+}  // namespace android
+
+#endif // ANDROID_DVR_BUFFER_HUB_BINDER_H
\ No newline at end of file
diff --git a/services/vr/bufferhubd/buffer_node.h b/services/vr/bufferhubd/include/private/dvr/buffer_node.h
similarity index 100%
rename from services/vr/bufferhubd/buffer_node.h
rename to services/vr/bufferhubd/include/private/dvr/buffer_node.h
diff --git a/services/vr/bufferhubd/consumer_channel.h b/services/vr/bufferhubd/include/private/dvr/consumer_channel.h
similarity index 97%
rename from services/vr/bufferhubd/consumer_channel.h
rename to services/vr/bufferhubd/include/private/dvr/consumer_channel.h
index 55cf969..0d70409 100644
--- a/services/vr/bufferhubd/consumer_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/consumer_channel.h
@@ -1,10 +1,9 @@
 #ifndef ANDROID_DVR_BUFFERHUBD_CONSUMER_CHANNEL_H_
 #define ANDROID_DVR_BUFFERHUBD_CONSUMER_CHANNEL_H_
 
-#include "buffer_hub.h"
-
 #include <pdx/rpc/buffer_wrapper.h>
 #include <private/dvr/bufferhub_rpc.h>
+#include <private/dvr/buffer_hub.h>
 
 namespace android {
 namespace dvr {
diff --git a/services/vr/bufferhubd/consumer_queue_channel.h b/services/vr/bufferhubd/include/private/dvr/consumer_queue_channel.h
similarity index 93%
rename from services/vr/bufferhubd/consumer_queue_channel.h
rename to services/vr/bufferhubd/include/private/dvr/consumer_queue_channel.h
index 8437c4c..d98dbbc 100644
--- a/services/vr/bufferhubd/consumer_queue_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/consumer_queue_channel.h
@@ -1,14 +1,12 @@
 #ifndef ANDROID_DVR_BUFFERHUBD_CONSUMER_QUEUE_CHANNEL_H_
 #define ANDROID_DVR_BUFFERHUBD_CONSUMER_QUEUE_CHANNEL_H_
 
-#include "buffer_hub.h"
-
-#include <private/dvr/bufferhub_rpc.h>
-
 #include <queue>
 
-#include "consumer_channel.h"
-#include "producer_queue_channel.h"
+#include <private/dvr/bufferhub_rpc.h>
+#include <private/dvr/buffer_hub.h>
+#include <private/dvr/consumer_channel.h>
+#include <private/dvr/producer_queue_channel.h>
 
 namespace android {
 namespace dvr {
diff --git a/services/vr/bufferhubd/producer_channel.h b/services/vr/bufferhubd/include/private/dvr/producer_channel.h
similarity index 98%
rename from services/vr/bufferhubd/producer_channel.h
rename to services/vr/bufferhubd/include/private/dvr/producer_channel.h
index 10a4ce7..242198f 100644
--- a/services/vr/bufferhubd/producer_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/producer_channel.h
@@ -1,8 +1,6 @@
 #ifndef ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_
 #define ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_
 
-#include "buffer_hub.h"
-
 #include <functional>
 #include <memory>
 #include <vector>
@@ -11,6 +9,7 @@
 #include <pdx/file_handle.h>
 #include <pdx/rpc/buffer_wrapper.h>
 #include <private/dvr/bufferhub_rpc.h>
+#include <private/dvr/buffer_hub.h>
 #include <private/dvr/ion_buffer.h>
 
 namespace android {
diff --git a/services/vr/bufferhubd/producer_queue_channel.h b/services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h
similarity index 98%
rename from services/vr/bufferhubd/producer_queue_channel.h
rename to services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h
index e4fa243..c4003da 100644
--- a/services/vr/bufferhubd/producer_queue_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h
@@ -1,10 +1,9 @@
 #ifndef ANDROID_DVR_BUFFERHUBD_PRODUCER_QUEUE_CHANNEL_H_
 #define ANDROID_DVR_BUFFERHUBD_PRODUCER_QUEUE_CHANNEL_H_
 
-#include "buffer_hub.h"
-
 #include <pdx/status.h>
 #include <private/dvr/bufferhub_rpc.h>
+#include <private/dvr/buffer_hub.h>
 
 namespace android {
 namespace dvr {
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
index 19d48f2..057d4f4 100644
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ b/services/vr/bufferhubd/producer_channel.cpp
@@ -1,19 +1,18 @@
-#include "producer_channel.h"
-
-#include <log/log.h>
-#include <sync/sync.h>
 #include <sys/epoll.h>
 #include <sys/eventfd.h>
 #include <sys/poll.h>
-#include <utils/Trace.h>
 
 #include <algorithm>
 #include <atomic>
 #include <thread>
 
+#include <log/log.h>
 #include <private/dvr/bufferhub_rpc.h>
-#include "buffer_channel.h"
-#include "consumer_channel.h"
+#include <private/dvr/buffer_channel.h>
+#include <private/dvr/consumer_channel.h>
+#include <private/dvr/producer_channel.h>
+#include <sync/sync.h>
+#include <utils/Trace.h>
 
 using android::pdx::BorrowedHandle;
 using android::pdx::ErrorStatus;
diff --git a/services/vr/bufferhubd/producer_queue_channel.cpp b/services/vr/bufferhubd/producer_queue_channel.cpp
index 88f5508..6b5027c 100644
--- a/services/vr/bufferhubd/producer_queue_channel.cpp
+++ b/services/vr/bufferhubd/producer_queue_channel.cpp
@@ -1,9 +1,8 @@
-#include "producer_queue_channel.h"
-
 #include <inttypes.h>
 
-#include "consumer_queue_channel.h"
-#include "producer_channel.h"
+#include <private/dvr/consumer_queue_channel.h>
+#include <private/dvr/producer_channel.h>
+#include <private/dvr/producer_queue_channel.h>
 
 using android::pdx::ErrorStatus;
 using android::pdx::Message;
diff --git a/services/vr/bufferhubd/tests/Android.bp b/services/vr/bufferhubd/tests/Android.bp
new file mode 100644
index 0000000..4d1d43f
--- /dev/null
+++ b/services/vr/bufferhubd/tests/Android.bp
@@ -0,0 +1,16 @@
+cc_test {
+    name: "buffer_hub_binder_service-test",
+    srcs: ["buffer_hub_binder_service-test.cpp"],
+    cflags: [
+        "-DLOG_TAG=\"buffer_hub_binder_service-test\"",
+        "-DTRACE=0",
+        "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
+    ],
+    static_libs: ["libbufferhubd"],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "liblog",
+        "libutils",
+    ],
+}
\ No newline at end of file
diff --git a/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp b/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp
new file mode 100644
index 0000000..e3f2825
--- /dev/null
+++ b/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp
@@ -0,0 +1,22 @@
+#include <private/dvr/buffer_hub_binder.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+namespace dvr {
+
+namespace {
+
+class BufferHubBinderServiceTest : public ::testing::Test {
+  // Add setup and teardown if necessary
+};
+
+TEST_F(BufferHubBinderServiceTest, TestInitialize) {
+  // Test if start binder server returns OK
+  EXPECT_EQ(BufferHubBinderService::start(), OK);
+}
+
+}  // namespace
+
+}  // namespace dvr
+}  // namespace android
\ No newline at end of file
diff --git a/services/vr/performanced/task.cpp b/services/vr/performanced/task.cpp
index c2f078e..bda1682 100644
--- a/services/vr/performanced/task.cpp
+++ b/services/vr/performanced/task.cpp
@@ -115,7 +115,7 @@
     std::istream file_stream(&filebuf);
 
     for (std::string line; std::getline(file_stream, line);) {
-      auto offset = line.find(":");
+      auto offset = line.find(':');
       if (offset == std::string::npos) {
         ALOGW("ReadStatusFields: Failed to find delimiter \":\" in line=\"%s\"",
               line.c_str());
diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api
index 8817e8d..fa63fbd 100644
--- a/vulkan/api/vulkan.api
+++ b/vulkan/api/vulkan.api
@@ -28,7 +28,7 @@
 // API version (major.minor.patch)
 define VERSION_MAJOR 1
 define VERSION_MINOR 1
-define VERSION_PATCH 84
+define VERSION_PATCH 85
 
 // API limits
 define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256
@@ -173,6 +173,10 @@
 @extension("VK_AMD_shader_image_load_store_lod") define VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_SPEC_VERSION 1
 @extension("VK_AMD_shader_image_load_store_lod") define VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_EXTENSION_NAME "VK_AMD_shader_image_load_store_lod"
 
+// 51
+@extension("VK_NV_corner_sampled_image") define VK_NV_CORNER_SAMPLED_IMAGE_SPEC_VERSION 2
+@extension("VK_NV_corner_sampled_image") define VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME "VK_NV_corner_sampled_image"
+
 // 54
 @extension("VK_KHR_multiview") define VK_KHR_MULTIVIEW_SPEC_VERSION 1
 @extension("VK_KHR_multiview") define VK_KHR_MULTIVIEW_EXTENSION_NAME "VK_KHR_multiview"
@@ -501,10 +505,22 @@
 @extension("VK_EXT_descriptor_indexing") define VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION 2
 @extension("VK_EXT_descriptor_indexing") define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME "VK_EXT_descriptor_indexing"
 
-// 165
+// 163
 @extension("VK_EXT_shader_viewport_index_layer") define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_SPEC_VERSION 1
 @extension("VK_EXT_shader_viewport_index_layer") define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME "VK_EXT_shader_viewport_index_layer"
 
+// 165
+@extension("VK_NV_shading_rate_image") define VK_NV_SHADING_RATE_IMAGE_SPEC_VERSION 3
+@extension("VK_NV_shading_rate_image") define VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME "VK_NV_shading_rate_image"
+
+// 166
+@extension("VK_NVX_raytracing") define VK_NVX_RAYTRACING_SPEC_VERSION 1
+@extension("VK_NVX_raytracing") define VK_NVX_RAYTRACING_EXTENSION_NAME "VK_NVX_raytracing"
+
+// 167
+@extension("VK_NV_representative_fragment_test") define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION 1
+@extension("VK_NV_representative_fragment_test") define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME "VK_NV_representative_fragment_test"
+
 // 169
 @extension("VK_KHR_maintenance3") define VK_KHR_MAINTENANCE3_SPEC_VERSION 1
 @extension("VK_KHR_maintenance3") define VK_KHR_MAINTENANCE3_EXTENSION_NAME "VK_KHR_maintenance3"
@@ -541,6 +557,26 @@
 @extension("VK_NV_shader_subgroup_partitioned") define VK_NV_SHADER_SUBGROUP_PARTITIONED_SPEC_VERSION 1
 @extension("VK_NV_shader_subgroup_partitioned") define VK_NV_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME "VK_NV_shader_subgroup_partitioned"
 
+// 202
+@extension("VK_NV_compute_shader_derivatives") define VK_NV_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION 1
+@extension("VK_NV_compute_shader_derivatives") define VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME "VK_NV_compute_shader_derivatives"
+
+// 203
+@extension("VK_NV_mesh_shader") define VK_NV_MESH_SHADER_SPEC_VERSION 1
+@extension("VK_NV_mesh_shader") define VK_NV_MESH_SHADER_EXTENSION_NAME "VK_NV_mesh_shader"
+
+// 204
+@extension("VK_NV_fragment_shader_barycentric") define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION 1
+@extension("VK_NV_fragment_shader_barycentric") define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME "VK_NV_fragment_shader_barycentric"
+
+// 205
+@extension("VK_NV_shader_image_footprint") define VK_NV_SHADER_IMAGE_FOOTPRINT_SPEC_VERSION 1
+@extension("VK_NV_shader_image_footprint") define VK_NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME "VK_NV_shader_image_footprint"
+
+// 206
+@extension("VK_NV_scissor_exclusive") define VK_NV_SCISSOR_EXCLUSIVE_SPEC_VERSION 1
+@extension("VK_NV_scissor_exclusive") define VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME "VK_NV_scissor_exclusive"
+
 // 207
 @extension("VK_NV_device_diagnostic_checkpoints") define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_SPEC_VERSION 2
 @extension("VK_NV_device_diagnostic_checkpoints") define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME "VK_NV_device_diagnostic_checkpoints"
@@ -620,6 +656,9 @@
 // 161
 @extension("VK_EXT_validation_cache") @nonDispatchHandle type u64 VkValidationCacheEXT
 
+// 166
+@extension("VK_NVX_raytracing") @nonDispatchHandle type u64 VkAccelerationStructureNVX
+
 /////////////
 //  Enums  //
 /////////////
@@ -648,6 +687,9 @@
     //@extension("VK_KHR_maintenance2") // 118
     VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR  = 1000117000,
     VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR  = 1000117001,
+
+    //@extension("VK_NV_shading_rate_image") // 165
+    VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV                 = 1000164003,
 }
 
 enum VkAttachmentLoadOp {
@@ -712,12 +754,18 @@
 
     //@extension("VK_EXT_inline_uniform_block") // 139
     VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT             = 1000138000,
+
+    //@extension("VK_NVX_raytracing") // 166
+    VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NVX           = 1000165000,
 }
 
 enum VkQueryType {
     VK_QUERY_TYPE_OCCLUSION                                 = 0x00000000,
     VK_QUERY_TYPE_PIPELINE_STATISTICS                       = 0x00000001, /// Optional
     VK_QUERY_TYPE_TIMESTAMP                                 = 0x00000002,
+
+    //@extension("VK_NVX_raytracing") // 166
+    VK_QUERY_TYPE_COMPACTED_SIZE_NVX                        = 1000165000,
 }
 
 enum VkBorderColor {
@@ -732,6 +780,9 @@
 enum VkPipelineBindPoint {
     VK_PIPELINE_BIND_POINT_GRAPHICS                         = 0x00000000,
     VK_PIPELINE_BIND_POINT_COMPUTE                          = 0x00000001,
+
+    //@extension("VK_NVX_raytracing") // 166
+    VK_PIPELINE_BIND_POINT_RAYTRACING_NVX                   = 1000165000,
 }
 
 enum VkPrimitiveTopology {
@@ -1387,6 +1438,9 @@
     //@extension("VK_AMD_texture_gather_bias_lod") // 42
     VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD  = 1000041000,
 
+    //@extension("VK_NV_corner_sampled_image") // 51
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV  = 1000050000,
+
     //@extension("VK_KHR_multiview") // 54
     VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR     = 1000053000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR    = 1000053001,
@@ -1671,6 +1725,29 @@
     VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT    = 1000161003,
     VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT   = 1000161004,
 
+    //@extension("VK_NV_shading_rate_image") // 165
+    VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002,
+    VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005,
+
+    //@extension("VK_NVX_raytracing") // 166
+    VK_STRUCTURE_TYPE_RAYTRACING_PIPELINE_CREATE_INFO_NVX = 1000165000,
+    VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NVX = 1000165001,
+    VK_STRUCTURE_TYPE_GEOMETRY_INSTANCE_NVX = 1000165002,
+    VK_STRUCTURE_TYPE_GEOMETRY_NVX = 1000165003,
+    VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NVX = 1000165004,
+    VK_STRUCTURE_TYPE_GEOMETRY_AABB_NVX = 1000165005,
+    VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NVX = 1000165006,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_ACCELERATION_STRUCTURE_INFO_NVX = 1000165007,
+    VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NVX = 1000165008,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAYTRACING_PROPERTIES_NVX = 1000165009,
+    VK_STRUCTURE_TYPE_HIT_SHADER_MODULE_CREATE_INFO_NVX = 1000165010,
+
+    //@extension("VK_NV_representative_fragment_test") // 167
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV = 1000166000,
+    VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001,
+
     //@extension("VK_KHR_maintenance3") // 169
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR      = 1000168000,
     VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR                 = 1000168001,
@@ -1791,6 +1868,13 @@
 
     //@extension("VK_EXT_sample_locations") // 144
     VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT                   = 1000143000,
+
+    //@extension("VK_NV_shading_rate_image") // 165
+    VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV       = 1000164004,
+    VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV        = 1000164006,
+
+    //@extension("VK_NV_scissor_exclusive") // 206
+    VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV                   = 1000205001,
 }
 
 enum VkObjectType {
@@ -1853,6 +1937,9 @@
 
     //@extension("VK_EXT_validation_cache") // 161
     VK_OBJECT_TYPE_VALIDATION_CACHE_EXT                     = 1000160000,
+
+    //@extension("VK_NVX_raytracing") // 166
+    VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NVX               = 1000165000,
 }
 
 
@@ -1974,6 +2061,9 @@
 
     //@extension("VK_KHR_sampler_ycbcr_conversion") // 157
     VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT = 1000156000,
+
+    //@extension("VK_NVX_raytracing") // 166
+    VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NVX_EXT  = 1000165000,
 }
 
 @extension("VK_AMD_rasterization_order") // 19
@@ -2124,6 +2214,48 @@
     VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT              = 1,
 }
 
+@extension("VK_NV_shading_rate_image") // 165
+enum VkShadingRatePaletteEntryNV {
+    VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV                 = 0,
+    VK_SHADING_RATE_PALETTE_ENTRY_16_INVOCATIONS_PER_PIXEL_NV       = 1,
+    VK_SHADING_RATE_PALETTE_ENTRY_8_INVOCATIONS_PER_PIXEL_NV        = 2,
+    VK_SHADING_RATE_PALETTE_ENTRY_4_INVOCATIONS_PER_PIXEL_NV        = 3,
+    VK_SHADING_RATE_PALETTE_ENTRY_2_INVOCATIONS_PER_PIXEL_NV        = 4,
+    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV         = 5,
+    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X1_PIXELS_NV    = 6,
+    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV    = 7,
+    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X2_PIXELS_NV    = 8,
+    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV    = 9,
+    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV    = 10,
+    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV    = 11,
+}
+
+@extension("VK_NV_shading_rate_image") // 165
+enum VkCoarseSampleOrderTypeNV {
+    VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV                  = 0,
+    VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV                   = 1,
+    VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV              = 2,
+    VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV             = 3,
+}
+
+@extension("VK_NVX_raytracing") // 166
+enum VkGeometryTypeNVX {
+    VK_GEOMETRY_TYPE_TRIANGLES_NVX                          = 0,
+    VK_GEOMETRY_TYPE_AABBS_NVX                              = 1,
+}
+
+@extension("VK_NVX_raytracing") // 166
+enum VkAccelerationStructureTypeNVX {
+    VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NVX            = 0,
+    VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NVX         = 1,
+}
+
+@extension("VK_NVX_raytracing") // 166
+enum VkCopyAccelerationStructureModeNVX {
+    VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NVX           = 0,
+    VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NVX         = 1,
+}
+
 @extension("VK_EXT_global_priority") // 175
 enum VkQueueGlobalPriorityEXT {
     VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT                        = 128,
@@ -2203,6 +2335,13 @@
 
     //@extension("VK_EXT_conditional_rendering") // 82
     VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT            = 0x00100000,
+
+    //@extension("VK_NV_shading_rate_image") // 165
+    VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV                = 0x00800000,
+
+    //@extension("VK_NVX_raytracing") // 166
+    VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NVX           = 0x00200000,
+    VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NVX          = 0x00400000,
 }
 
 /// Buffer usage flags
@@ -2220,6 +2359,9 @@
 
     //@extension("VK_EXT_conditional_rendering") // 82
     VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT           = 0x00000200,
+
+    //@extension("VK_NVX_raytracing") // 166
+    VK_BUFFER_USAGE_RAYTRACING_BIT_NVX                      = 0x00000400,
 }
 
 /// Buffer creation flags
@@ -2245,6 +2387,18 @@
     VK_SHADER_STAGE_ALL_GRAPHICS                            = 0x0000001F,
 
     VK_SHADER_STAGE_ALL                                     = 0x7FFFFFFF,
+
+    //@extension("VK_NVX_raytracing") // 166
+    VK_SHADER_STAGE_RAYGEN_BIT_NVX                          = 0x00000100,
+    VK_SHADER_STAGE_ANY_HIT_BIT_NVX                         = 0x00000200,
+    VK_SHADER_STAGE_CLOSEST_HIT_BIT_NVX                     = 0x00000400,
+    VK_SHADER_STAGE_MISS_BIT_NVX                            = 0x00000800,
+    VK_SHADER_STAGE_INTERSECTION_BIT_NVX                    = 0x00001000,
+    VK_SHADER_STAGE_CALLABLE_BIT_NVX                        = 0x00002000,
+
+    //@extension("VK_NV_mesh_shader") // 203
+    VK_SHADER_STAGE_TASK_BIT_NV                             = 0x00000040,
+    VK_SHADER_STAGE_MESH_BIT_NV                             = 0x00000080,
 }
 
 /// Descriptor pool create flags
@@ -2272,6 +2426,9 @@
     VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT             = 0x00000020,    /// Can be used as framebuffer depth/stencil attachment
     VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT                 = 0x00000040,    /// Image data not needed outside of rendering
     VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT                     = 0x00000080,    /// Can be used as framebuffer input attachment
+
+    //@extension("VK_NV_shading_rate_image") // 165
+    VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV                = 0x00000100,
 }
 
 /// Image creation flags
@@ -2310,6 +2467,9 @@
 
     //@extension("VK_EXT_sample_locations") // 144
     VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000,
+
+    //@extension("VK_NV_corner_sampled_image") // 51
+    VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV                   = 0x00002000,
 }
 
 /// Image view creation flags
@@ -2331,6 +2491,9 @@
     //@extension("VK_KHR_device_group") // 61
     VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = 0x00000008,
     VK_PIPELINE_CREATE_DISPATCH_BASE_KHR                    = 0x00000010,
+
+    //@extension("VK_NVX_raytracing") // 166
+    VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NVX                = 0x00000020,
 }
 
 /// Color component flags
@@ -2515,6 +2678,16 @@
 
     //@extension("VK_EXT_conditional_rendering") // 82
     VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT         = 0x00040000,
+
+    //@extension("VK_NV_shading_rate_image") // 165
+    VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV             = 0x00400000,
+
+    //@extension("VK_NVX_raytracing") // 166
+    VK_PIPELINE_STAGE_RAYTRACING_BIT_NVX                    = 0x00200000,
+
+    //@extension("VK_NV_mesh_shader") // 203
+    VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV                    = 0x00080000,
+    VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV                    = 0x00100000,
 }
 
 /// Render pass attachment description flags
@@ -3193,6 +3366,35 @@
     VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT     = 0x00000008,
 }
 
+@extension("VK_NVX_raytracing") // 166
+type VkFlags VkGeometryFlagsNVX
+@extension("VK_NVX_raytracing") // 166
+bitfield VkGeometryFlagBitsNVX {
+    VK_GEOMETRY_OPAQUE_BIT_NVX                          = 0x00000001,
+    VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_NVX = 0x00000002,
+}
+
+@extension("VK_NVX_raytracing") // 166
+type VkFlags VkGeometryInstanceFlagsNVX
+@extension("VK_NVX_raytracing") // 166
+bitfield VkGeometryInstanceFlagBitsNVX {
+    VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NVX      = 0x00000001,
+    VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_FLIP_WINDING_BIT_NVX = 0x00000002,
+    VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NVX               = 0x00000004,
+    VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NVX            = 0x00000008,
+}
+
+@extension("VK_NVX_raytracing") // 166
+type VkFlags VkBuildAccelerationStructureFlagsNVX
+@extension("VK_NVX_raytracing") // 166
+bitfield VkBuildAccelerationStructureFlagBitsNVX {
+    VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NVX        = 0x00000001,
+    VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NVX    = 0x00000002,
+    VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NVX   = 0x00000004,
+    VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NVX   = 0x00000008,
+    VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_NVX          = 0x00000010,
+}
+
 //////////////////
 //  Structures  //
 //////////////////
@@ -5154,6 +5356,13 @@
     u32[3]                                      computeWorkGroupSize
 }
 
+@extension("VK_NV_corner_sampled_image") // 51
+class VkPhysicalDeviceCornerSampledImageFeaturesNV {
+    VkStructureType                             sType
+    void*                                       pNext
+    VkBool32                                    cornerSampledImage
+}
+
 @extension("VK_KHR_multiview") // 54
 class VkRenderPassMultiviewCreateInfoKHR {
     VkStructureType                             sType
@@ -6779,6 +6988,179 @@
     u32                                             maxVariableDescriptorCount
 }
 
+@extension("VK_NV_shading_rate_image") // 165
+class VkShadingRatePaletteNV {
+    u32                                             shadingRatePaletteEntryCount
+    const VkShadingRatePaletteEntryNV*              pShadingRatePaletteEntries
+}
+
+@extension("VK_NV_shading_rate_image") // 165
+class VkPipelineViewportShadingRateImageStateCreateInfoNV {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkBool32                                        shadingRateImageEnable
+    u32                                             viewportCount
+    const VkShadingRatePaletteNV*                   pShadingRatePalettes
+}
+
+@extension("VK_NV_shading_rate_image") // 165
+class VkPhysicalDeviceShadingRateImageFeaturesNV {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkBool32                                        shadingRateImage
+    VkBool32                                        shadingRateCoarseSampleOrder
+}
+
+@extension("VK_NV_shading_rate_image") // 165
+class VkPhysicalDeviceShadingRateImagePropertiesNV {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkExtent2D                                      shadingRateTexelSize
+    u32                                             shadingRatePaletteSize
+    u32                                             shadingRateMaxCoarseSamples
+}
+
+@extension("VK_NV_shading_rate_image") // 165
+class VkCoarseSampleLocationNV {
+    u32                                             pixelX
+    u32                                             pixelY
+    u32                                             sample
+}
+
+@extension("VK_NV_shading_rate_image") // 165
+class VkCoarseSampleOrderCustomNV {
+    VkShadingRatePaletteEntryNV                     shadingRate
+    u32                                             sampleCount
+    u32                                             sampleLocationCount
+    const VkCoarseSampleLocationNV*                 pSampleLocations
+}
+
+@extension("VK_NV_shading_rate_image") // 165
+class VkPipelineViewportCoarseSampleOrderStateCreateInfoNV {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkCoarseSampleOrderTypeNV                       sampleOrderType
+    u32                                             customSampleOrderCount
+    const VkCoarseSampleOrderCustomNV*              pCustomSampleOrders
+}
+
+@extension("VK_NVX_raytracing") // 166
+class VkRaytracingPipelineCreateInfoNVX {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkPipelineCreateFlags                           flags
+    u32                                             stageCount
+    const VkPipelineShaderStageCreateInfo*          pStages
+    const u32*                                      pGroupNumbers
+    u32                                             maxRecursionDepth
+    VkPipelineLayout                                layout
+    VkPipeline                                      basePipelineHandle
+    s32                                             basePipelineIndex
+}
+
+@extension("VK_NVX_raytracing") // 166
+class VkGeometryTrianglesNVX {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkBuffer                                        vertexData
+    VkDeviceSize                                    vertexOffset
+    u32                                             vertexCount
+    VkDeviceSize                                    vertexStride
+    VkFormat                                        vertexFormat
+    VkBuffer                                        indexData
+    VkDeviceSize                                    indexOffset
+    u32                                             indexCount
+    VkIndexType                                     indexType
+    VkBuffer                                        transformData
+    VkDeviceSize                                    transformOffset
+}
+
+@extension("VK_NVX_raytracing") // 166
+class VkGeometryAABBNVX {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkBuffer                                        aabbData
+    u32                                             numAABBs
+    u32                                             stride
+    VkDeviceSize                                    offset
+}
+
+@extension("VK_NVX_raytracing") // 166
+class VkGeometryDataNVX {
+    VkGeometryTrianglesNVX                          triangles
+    VkGeometryAABBNVX                               aabbs
+}
+
+@extension("VK_NVX_raytracing") // 166
+class VkGeometryNVX {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkGeometryTypeNVX                               geometryType
+    VkGeometryDataNVX                               geometry
+    VkGeometryFlagsNVX                              flags
+}
+
+@extension("VK_NVX_raytracing") // 166
+class VkAccelerationStructureCreateInfoNVX {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkAccelerationStructureTypeNVX                  type
+    VkBuildAccelerationStructureFlagsNVX            flags
+    VkDeviceSize                                    compactedSize
+    u32                                             instanceCount
+    u32                                             geometryCount
+    const VkGeometryNVX*                            pGeometries
+}
+
+@extension("VK_NVX_raytracing") // 166
+class VkBindAccelerationStructureMemoryInfoNVX {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkAccelerationStructureNVX                      accelerationStructure
+    VkDeviceMemory                                  memory
+    VkDeviceSize                                    memoryOffset
+    u32                                             deviceIndexCount
+    const u32*                                      pDeviceIndices
+}
+
+@extension("VK_NVX_raytracing") // 166
+class VkDescriptorAccelerationStructureInfoNVX {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    u32                                             accelerationStructureCount
+    const VkAccelerationStructureNVX*               pAccelerationStructures
+}
+
+@extension("VK_NVX_raytracing") // 166
+class VkAccelerationStructureMemoryRequirementsInfoNVX {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkAccelerationStructureNVX                      accelerationStructure
+}
+
+@extension("VK_NVX_raytracing") // 166
+class VkPhysicalDeviceRaytracingPropertiesNVX {
+    VkStructureType                                 sType
+    void*                                           pNext
+    u32                                             shaderHeaderSize
+    u32                                             maxRecursionDepth
+    u32                                             maxGeometryCount
+}
+
+@extension("VK_NV_representative_fragment_test") // 167
+class VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkBool32                                        representativeFragmentTest
+}
+
+@extension("VK_NV_representative_fragment_test") // 167
+class VkPipelineRepresentativeFragmentTestStateCreateInfoNV {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkBool32                                        representativeFragmentTestEnable
+}
+
 @extension("VK_KHR_maintenance3") // 169
 class VkPhysicalDeviceMaintenance3PropertiesKHR {
     VkStructureType                                 sType
@@ -6881,6 +7263,76 @@
     VkBool32                                        vertexAttributeInstanceRateZeroDivisor
 }
 
+@extension("VK_NV_compute_shader_derivatives") // 202
+class VkPhysicalDeviceComputeShaderDerivativesFeaturesNV {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkBool32                                        computeDerivativeGroupQuads
+    VkBool32                                        computeDerivativeGroupLinear
+}
+
+@extension("VK_NV_mesh_shader") // 203
+class VkPhysicalDeviceMeshShaderFeaturesNV {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkBool32                                        taskShader
+    VkBool32                                        meshShader
+}
+
+@extension("VK_NV_mesh_shader") // 203
+class VkPhysicalDeviceMeshShaderPropertiesNV {
+    VkStructureType                                 sType
+    void*                                           pNext
+    u32                                             maxDrawMeshTasksCount
+    u32                                             maxTaskWorkGroupInvocations
+    u32[3]                                          maxTaskWorkGroupSize
+    u32                                             maxTaskTotalMemorySize
+    u32                                             maxTaskOutputCount
+    u32                                             maxMeshWorkGroupInvocations
+    u32[3]                                          maxMeshWorkGroupSize
+    u32                                             maxMeshTotalMemorySize
+    u32                                             maxMeshOutputVertices
+    u32                                             maxMeshOutputPrimitives
+    u32                                             maxMeshMultiviewViewCount
+    u32                                             meshOutputPerVertexGranularity
+    u32                                             meshOutputPerPrimitiveGranularity
+}
+
+@extension("VK_NV_mesh_shader") // 203
+class VkDrawMeshTasksIndirectCommandNV {
+    u32                                             taskCount
+    u32                                             firstTask
+}
+
+@extension("VK_NV_fragment_shader_barycentric") // 204
+class VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkBool32                                        fragmentShaderBarycentric
+}
+
+@extension("VK_NV_shader_image_footprint") // 205
+class VkPhysicalDeviceShaderImageFootprintFeaturesNV {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkBool32                                        imageFootprint
+}
+
+@extension("VK_NV_scissor_exclusive") // 206
+class VkPipelineViewportExclusiveScissorStateCreateInfoNV {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    u32                                             exclusiveScissorCount
+    const VkRect2D*                                 pExclusiveScissors
+}
+
+@extension("VK_NV_scissor_exclusive") // 206
+class VkPhysicalDeviceExclusiveScissorFeaturesNV {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkBool32                                        exclusiveScissor
+}
+
 @extension("VK_NV_device_diagnostic_checkpoints") // 207
 class VkQueueFamilyCheckpointPropertiesNV {
     VkStructureType                                 sType
@@ -10653,6 +11105,155 @@
     return ?
 }
 
+@extension("VK_NV_shading_rate_image") // 165
+cmd void vkCmdBindShadingRateImageNV(
+        VkCommandBuffer                             commandBuffer,
+        VkImageView                                 imageView,
+        VkImageLayout                               imageLayout) {
+}
+
+@extension("VK_NV_shading_rate_image") // 165
+cmd void vkCmdSetViewportShadingRatePaletteNV(
+        VkCommandBuffer                             commandBuffer,
+        u32                                         firstViewport,
+        u32                                         viewportCount,
+        const VkShadingRatePaletteNV*               pShadingRatePalettes) {
+}
+
+@extension("VK_NV_shading_rate_image") // 165
+cmd void vkCmdSetCoarseSampleOrderNV(
+        VkCommandBuffer                             commandBuffer,
+        VkCoarseSampleOrderTypeNV                   sampleOrderType,
+        u32                                         customSampleOrderCount,
+        const VkCoarseSampleOrderCustomNV*          pCustomSampleOrders) {
+}
+
+@extension("VK_NVX_raytracing") // 166
+cmd VkResult vkCreateAccelerationStructureNVX(
+        VkDevice                                    device,
+        const VkAccelerationStructureCreateInfoNVX* pCreateInfo,
+        const VkAllocationCallbacks*                pAllocator,
+        VkAccelerationStructureNVX*                 pAccelerationStructure) {
+    return ?
+}
+
+@extension("VK_NVX_raytracing") // 166
+cmd void vkDestroyAccelerationStructureNVX(
+        VkDevice                                    device,
+        VkAccelerationStructureNVX                  accelerationStructure,
+        const VkAllocationCallbacks*                pAllocator) {
+}
+
+@extension("VK_NVX_raytracing") // 166
+cmd void vkGetAccelerationStructureMemoryRequirementsNVX(
+        VkDevice                                                device,
+        const VkAccelerationStructureMemoryRequirementsInfoNVX* pInfo,
+        VkMemoryRequirements2KHR*                               pMemoryRequirements) {
+}
+
+@extension("VK_NVX_raytracing") // 166
+cmd void vkGetAccelerationStructureScratchMemoryRequirementsNVX(
+        VkDevice                                                device,
+        const VkAccelerationStructureMemoryRequirementsInfoNVX* pInfo,
+        VkMemoryRequirements2KHR*                               pMemoryRequirements) {
+}
+
+@extension("VK_NVX_raytracing") // 166
+cmd VkResult vkBindAccelerationStructureMemoryNVX(
+        VkDevice                                        device,
+        u32                                             bindInfoCount,
+        const VkBindAccelerationStructureMemoryInfoNVX* pBindInfos) {
+    return ?
+}
+
+@extension("VK_NVX_raytracing") // 166
+cmd void vkCmdBuildAccelerationStructureNVX(
+        VkCommandBuffer                         cmdBuf,
+        VkAccelerationStructureTypeNVX          type,
+        u32                                     instanceCount,
+        VkBuffer                                instanceData,
+        VkDeviceSize                            instanceOffset,
+        u32                                     geometryCount,
+        const VkGeometryNVX*                    pGeometries,
+        VkBuildAccelerationStructureFlagsNVX    flags,
+        VkBool32                                update,
+        VkAccelerationStructureNVX              dst,
+        VkAccelerationStructureNVX              src,
+        VkBuffer                                scratch,
+        VkDeviceSize                            scratchOffset) {
+}
+
+@extension("VK_NVX_raytracing") // 166
+cmd void vkCmdCopyAccelerationStructureNVX(
+        VkCommandBuffer                         cmdBuf,
+        VkAccelerationStructureNVX              dst,
+        VkAccelerationStructureNVX              src,
+        VkCopyAccelerationStructureModeNVX      mode) {
+}
+
+@extension("VK_NVX_raytracing") // 166
+cmd void vkCmdTraceRaysNVX(
+        VkCommandBuffer                         cmdBuf,
+        VkBuffer                                raygenShaderBindingTableBuffer,
+        VkDeviceSize                            raygenShaderBindingOffset,
+        VkBuffer                                missShaderBindingTableBuffer,
+        VkDeviceSize                            missShaderBindingOffset,
+        VkDeviceSize                            missShaderBindingStride,
+        VkBuffer                                hitShaderBindingTableBuffer,
+        VkDeviceSize                            hitShaderBindingOffset,
+        VkDeviceSize                            hitShaderBindingStride,
+        u32                                     width,
+        u32                                     height) {
+}
+
+@extension("VK_NVX_raytracing") // 166
+cmd VkResult vkCreateRaytracingPipelinesNVX(
+        VkDevice                                    device,
+        VkPipelineCache                             pipelineCache,
+        u32                                         createInfoCount,
+        const VkRaytracingPipelineCreateInfoNVX*    pCreateInfos,
+        const VkAllocationCallbacks*                pAllocator,
+        VkPipeline*                                 pPipelines) {
+    return ?
+}
+
+@extension("VK_NVX_raytracing") // 166
+cmd VkResult vkGetRaytracingShaderHandlesNVX(
+        VkDevice                                device,
+        VkPipeline                              pipeline,
+        u32                                     firstGroup,
+        u32                                     groupCount,
+        platform.size_t                         dataSize,
+        void*                                   pData) {
+    return ?
+}
+
+@extension("VK_NVX_raytracing") // 166
+cmd VkResult vkGetAccelerationStructureHandleNVX(
+        VkDevice                                device,
+        VkAccelerationStructureNVX              accelerationStructure,
+        platform.size_t                         dataSize,
+        void*                                   pData) {
+    return ?
+}
+
+@extension("VK_NVX_raytracing") // 166
+cmd void vkCmdWriteAccelerationStructurePropertiesNVX(
+        VkCommandBuffer                         cmdBuf,
+        VkAccelerationStructureNVX              accelerationStructure,
+        VkQueryType                             queryType,
+        VkQueryPool                             queryPool,
+        u32                                     query) {
+}
+
+@extension("VK_NVX_raytracing") // 166
+cmd VkResult vkCompileDeferredNVX(
+        VkDevice                                device,
+        VkPipeline                              pipeline,
+        u32                                     shader) {
+    return ?
+}
+
 @extension("VK_KHR_maintenance3") // 169
 cmd void vkGetDescriptorSetLayoutSupportKHR(
         VkDevice                                    device,
@@ -10700,6 +11301,41 @@
         u32                                         marker) {
 }
 
+@extension("VK_NV_mesh_shader") // 203
+cmd void vkCmdDrawMeshTasksNV(
+        VkCommandBuffer                             commandBuffer,
+        u32                                         taskCount,
+        u32                                         firstTask) {
+}
+
+@extension("VK_NV_mesh_shader") // 203
+cmd void vkCmdDrawMeshTasksIndirectNV(
+        VkCommandBuffer                             commandBuffer,
+        VkBuffer                                    buffer,
+        VkDeviceSize                                offset,
+        u32                                         drawCount,
+        u32                                         stride) {
+}
+
+@extension("VK_NV_mesh_shader") // 203
+cmd void vkCmdDrawMeshTasksIndirectCountNV(
+        VkCommandBuffer                             commandBuffer,
+        VkBuffer                                    buffer,
+        VkDeviceSize                                offset,
+        VkBuffer                                    countBuffer,
+        VkDeviceSize                                countBufferOffset,
+        u32                                         maxDrawCount,
+        u32                                         stride) {
+}
+
+@extension("VK_NV_scissor_exclusive") // 206
+cmd void vkCmdSetExclusiveScissorNV(
+        VkCommandBuffer                             commandBuffer,
+        u32                                         firstExclusiveScissor,
+        u32                                         exclusiveScissorCount,
+        const VkRect2D*                             pExclusiveScissors) {
+}
+
 @extension("VK_NV_device_diagnostic_checkpoints") // 207
 cmd void vkCmdSetCheckpointNV(
         VkCommandBuffer                             commandBuffer,
diff --git a/vulkan/include/vulkan/vulkan_core.h b/vulkan/include/vulkan/vulkan_core.h
index fe45014..2d1b3f5 100644
--- a/vulkan/include/vulkan/vulkan_core.h
+++ b/vulkan/include/vulkan/vulkan_core.h
@@ -43,7 +43,7 @@
 #define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
 #define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
 // Version of this file
-#define VK_HEADER_VERSION 84
+#define VK_HEADER_VERSION 85
 
 
 #define VK_NULL_HANDLE 0
@@ -298,6 +298,7 @@
     VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001,
     VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002,
     VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000,
     VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000,
     VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001,
     VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000,
@@ -404,6 +405,23 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = 1000161002,
     VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = 1000161003,
     VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = 1000161004,
+    VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002,
+    VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005,
+    VK_STRUCTURE_TYPE_RAYTRACING_PIPELINE_CREATE_INFO_NVX = 1000165000,
+    VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NVX = 1000165001,
+    VK_STRUCTURE_TYPE_GEOMETRY_INSTANCE_NVX = 1000165002,
+    VK_STRUCTURE_TYPE_GEOMETRY_NVX = 1000165003,
+    VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NVX = 1000165004,
+    VK_STRUCTURE_TYPE_GEOMETRY_AABB_NVX = 1000165005,
+    VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NVX = 1000165006,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_ACCELERATION_STRUCTURE_INFO_NVX = 1000165007,
+    VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NVX = 1000165008,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAYTRACING_PROPERTIES_NVX = 1000165009,
+    VK_STRUCTURE_TYPE_HIT_SHADER_MODULE_CREATE_INFO_NVX = 1000165010,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV = 1000166000,
+    VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001,
     VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = 1000177000,
     VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000,
@@ -413,6 +431,13 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000,
     VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = 1000203000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV = 1000204000,
+    VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV = 1000205000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002,
     VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000,
     VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = 1000211000,
@@ -806,6 +831,7 @@
     VK_QUERY_TYPE_OCCLUSION = 0,
     VK_QUERY_TYPE_PIPELINE_STATISTICS = 1,
     VK_QUERY_TYPE_TIMESTAMP = 2,
+    VK_QUERY_TYPE_COMPACTED_SIZE_NVX = 1000165000,
     VK_QUERY_TYPE_BEGIN_RANGE = VK_QUERY_TYPE_OCCLUSION,
     VK_QUERY_TYPE_END_RANGE = VK_QUERY_TYPE_TIMESTAMP,
     VK_QUERY_TYPE_RANGE_SIZE = (VK_QUERY_TYPE_TIMESTAMP - VK_QUERY_TYPE_OCCLUSION + 1),
@@ -835,6 +861,7 @@
     VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001,
     VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002,
     VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000,
+    VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = 1000164003,
     VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
     VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
     VK_IMAGE_LAYOUT_BEGIN_RANGE = VK_IMAGE_LAYOUT_UNDEFINED,
@@ -1068,6 +1095,9 @@
     VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000,
     VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000,
     VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1000143000,
+    VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV = 1000164004,
+    VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV = 1000164006,
+    VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1000205001,
     VK_DYNAMIC_STATE_BEGIN_RANGE = VK_DYNAMIC_STATE_VIEWPORT,
     VK_DYNAMIC_STATE_END_RANGE = VK_DYNAMIC_STATE_STENCIL_REFERENCE,
     VK_DYNAMIC_STATE_RANGE_SIZE = (VK_DYNAMIC_STATE_STENCIL_REFERENCE - VK_DYNAMIC_STATE_VIEWPORT + 1),
@@ -1131,6 +1161,7 @@
     VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9,
     VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10,
     VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = 1000138000,
+    VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NVX = 1000165000,
     VK_DESCRIPTOR_TYPE_BEGIN_RANGE = VK_DESCRIPTOR_TYPE_SAMPLER,
     VK_DESCRIPTOR_TYPE_END_RANGE = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
     VK_DESCRIPTOR_TYPE_RANGE_SIZE = (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT - VK_DESCRIPTOR_TYPE_SAMPLER + 1),
@@ -1159,6 +1190,7 @@
 typedef enum VkPipelineBindPoint {
     VK_PIPELINE_BIND_POINT_GRAPHICS = 0,
     VK_PIPELINE_BIND_POINT_COMPUTE = 1,
+    VK_PIPELINE_BIND_POINT_RAYTRACING_NVX = 1000165000,
     VK_PIPELINE_BIND_POINT_BEGIN_RANGE = VK_PIPELINE_BIND_POINT_GRAPHICS,
     VK_PIPELINE_BIND_POINT_END_RANGE = VK_PIPELINE_BIND_POINT_COMPUTE,
     VK_PIPELINE_BIND_POINT_RANGE_SIZE = (VK_PIPELINE_BIND_POINT_COMPUTE - VK_PIPELINE_BIND_POINT_GRAPHICS + 1),
@@ -1230,6 +1262,7 @@
     VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX = 1000086001,
     VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000128000,
     VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000,
+    VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NVX = 1000165000,
     VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE,
     VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION,
     VK_OBJECT_TYPE_BEGIN_RANGE = VK_OBJECT_TYPE_UNKNOWN,
@@ -1297,6 +1330,7 @@
     VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020,
     VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040,
     VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080,
+    VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00000100,
     VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkImageUsageFlagBits;
 typedef VkFlags VkImageUsageFlags;
@@ -1314,6 +1348,7 @@
     VK_IMAGE_CREATE_EXTENDED_USAGE_BIT = 0x00000100,
     VK_IMAGE_CREATE_PROTECTED_BIT = 0x00000800,
     VK_IMAGE_CREATE_DISJOINT_BIT = 0x00000200,
+    VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV = 0x00002000,
     VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000,
     VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT,
     VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT,
@@ -1393,6 +1428,10 @@
     VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000,
     VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000,
     VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX = 0x00020000,
+    VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00400000,
+    VK_PIPELINE_STAGE_RAYTRACING_BIT_NVX = 0x00200000,
+    VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV = 0x00080000,
+    VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV = 0x00100000,
     VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkPipelineStageFlagBits;
 typedef VkFlags VkPipelineStageFlags;
@@ -1481,6 +1520,7 @@
     VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080,
     VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100,
     VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00000200,
+    VK_BUFFER_USAGE_RAYTRACING_BIT_NVX = 0x00000400,
     VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkBufferUsageFlagBits;
 typedef VkFlags VkBufferUsageFlags;
@@ -1495,6 +1535,7 @@
     VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004,
     VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008,
     VK_PIPELINE_CREATE_DISPATCH_BASE = 0x00000010,
+    VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NVX = 0x00000020,
     VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT,
     VK_PIPELINE_CREATE_DISPATCH_BASE_KHR = VK_PIPELINE_CREATE_DISPATCH_BASE,
     VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
@@ -1511,6 +1552,14 @@
     VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020,
     VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F,
     VK_SHADER_STAGE_ALL = 0x7FFFFFFF,
+    VK_SHADER_STAGE_RAYGEN_BIT_NVX = 0x00000100,
+    VK_SHADER_STAGE_ANY_HIT_BIT_NVX = 0x00000200,
+    VK_SHADER_STAGE_CLOSEST_HIT_BIT_NVX = 0x00000400,
+    VK_SHADER_STAGE_MISS_BIT_NVX = 0x00000800,
+    VK_SHADER_STAGE_INTERSECTION_BIT_NVX = 0x00001000,
+    VK_SHADER_STAGE_CALLABLE_BIT_NVX = 0x00002000,
+    VK_SHADER_STAGE_TASK_BIT_NV = 0x00000040,
+    VK_SHADER_STAGE_MESH_BIT_NV = 0x00000080,
     VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkShaderStageFlagBits;
 typedef VkFlags VkPipelineVertexInputStateCreateFlags;
@@ -1596,6 +1645,9 @@
     VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX = 0x00020000,
     VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX = 0x00040000,
     VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000,
+    VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000,
+    VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NVX = 0x00200000,
+    VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NVX = 0x00400000,
     VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkAccessFlagBits;
 typedef VkFlags VkAccessFlags;
@@ -4062,6 +4114,8 @@
     VkMemoryRequirements    memoryRequirements;
 } VkMemoryRequirements2;
 
+typedef VkMemoryRequirements2 VkMemoryRequirements2KHR;
+
 typedef struct VkSparseImageMemoryRequirements2 {
     VkStructureType                    sType;
     void*                              pNext;
@@ -5826,8 +5880,6 @@
 
 typedef VkImageSparseMemoryRequirementsInfo2 VkImageSparseMemoryRequirementsInfo2KHR;
 
-typedef VkMemoryRequirements2 VkMemoryRequirements2KHR;
-
 typedef VkSparseImageMemoryRequirements2 VkSparseImageMemoryRequirements2KHR;
 
 
@@ -6049,6 +6101,7 @@
     VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT = 33,
     VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT = 1000156000,
     VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT = 1000085000,
+    VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NVX_EXT = 1000165000,
     VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT,
     VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT,
     VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT,
@@ -6355,6 +6408,18 @@
 #define VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_EXTENSION_NAME "VK_AMD_shader_image_load_store_lod"
 
 
+#define VK_NV_corner_sampled_image 1
+#define VK_NV_CORNER_SAMPLED_IMAGE_SPEC_VERSION 2
+#define VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME "VK_NV_corner_sampled_image"
+
+typedef struct VkPhysicalDeviceCornerSampledImageFeaturesNV {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           cornerSampledImage;
+} VkPhysicalDeviceCornerSampledImageFeaturesNV;
+
+
+
 #define VK_IMG_format_pvrtc 1
 #define VK_IMG_FORMAT_PVRTC_SPEC_VERSION  1
 #define VK_IMG_FORMAT_PVRTC_EXTENSION_NAME "VK_IMG_format_pvrtc"
@@ -7711,6 +7776,397 @@
 #define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME "VK_EXT_shader_viewport_index_layer"
 
 
+#define VK_NV_shading_rate_image 1
+#define VK_NV_SHADING_RATE_IMAGE_SPEC_VERSION 3
+#define VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME "VK_NV_shading_rate_image"
+
+
+typedef enum VkShadingRatePaletteEntryNV {
+    VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV = 0,
+    VK_SHADING_RATE_PALETTE_ENTRY_16_INVOCATIONS_PER_PIXEL_NV = 1,
+    VK_SHADING_RATE_PALETTE_ENTRY_8_INVOCATIONS_PER_PIXEL_NV = 2,
+    VK_SHADING_RATE_PALETTE_ENTRY_4_INVOCATIONS_PER_PIXEL_NV = 3,
+    VK_SHADING_RATE_PALETTE_ENTRY_2_INVOCATIONS_PER_PIXEL_NV = 4,
+    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV = 5,
+    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X1_PIXELS_NV = 6,
+    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV = 7,
+    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X2_PIXELS_NV = 8,
+    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV = 9,
+    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV = 10,
+    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV = 11,
+    VK_SHADING_RATE_PALETTE_ENTRY_BEGIN_RANGE_NV = VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV,
+    VK_SHADING_RATE_PALETTE_ENTRY_END_RANGE_NV = VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV,
+    VK_SHADING_RATE_PALETTE_ENTRY_RANGE_SIZE_NV = (VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV - VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV + 1),
+    VK_SHADING_RATE_PALETTE_ENTRY_MAX_ENUM_NV = 0x7FFFFFFF
+} VkShadingRatePaletteEntryNV;
+
+typedef enum VkCoarseSampleOrderTypeNV {
+    VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV = 0,
+    VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV = 1,
+    VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV = 2,
+    VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV = 3,
+    VK_COARSE_SAMPLE_ORDER_TYPE_BEGIN_RANGE_NV = VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV,
+    VK_COARSE_SAMPLE_ORDER_TYPE_END_RANGE_NV = VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV,
+    VK_COARSE_SAMPLE_ORDER_TYPE_RANGE_SIZE_NV = (VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV - VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV + 1),
+    VK_COARSE_SAMPLE_ORDER_TYPE_MAX_ENUM_NV = 0x7FFFFFFF
+} VkCoarseSampleOrderTypeNV;
+
+typedef struct VkShadingRatePaletteNV {
+    uint32_t                              shadingRatePaletteEntryCount;
+    const VkShadingRatePaletteEntryNV*    pShadingRatePaletteEntries;
+} VkShadingRatePaletteNV;
+
+typedef struct VkPipelineViewportShadingRateImageStateCreateInfoNV {
+    VkStructureType                  sType;
+    const void*                      pNext;
+    VkBool32                         shadingRateImageEnable;
+    uint32_t                         viewportCount;
+    const VkShadingRatePaletteNV*    pShadingRatePalettes;
+} VkPipelineViewportShadingRateImageStateCreateInfoNV;
+
+typedef struct VkPhysicalDeviceShadingRateImageFeaturesNV {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           shadingRateImage;
+    VkBool32           shadingRateCoarseSampleOrder;
+} VkPhysicalDeviceShadingRateImageFeaturesNV;
+
+typedef struct VkPhysicalDeviceShadingRateImagePropertiesNV {
+    VkStructureType    sType;
+    void*              pNext;
+    VkExtent2D         shadingRateTexelSize;
+    uint32_t           shadingRatePaletteSize;
+    uint32_t           shadingRateMaxCoarseSamples;
+} VkPhysicalDeviceShadingRateImagePropertiesNV;
+
+typedef struct VkCoarseSampleLocationNV {
+    uint32_t    pixelX;
+    uint32_t    pixelY;
+    uint32_t    sample;
+} VkCoarseSampleLocationNV;
+
+typedef struct VkCoarseSampleOrderCustomNV {
+    VkShadingRatePaletteEntryNV        shadingRate;
+    uint32_t                           sampleCount;
+    uint32_t                           sampleLocationCount;
+    const VkCoarseSampleLocationNV*    pSampleLocations;
+} VkCoarseSampleOrderCustomNV;
+
+typedef struct VkPipelineViewportCoarseSampleOrderStateCreateInfoNV {
+    VkStructureType                       sType;
+    const void*                           pNext;
+    VkCoarseSampleOrderTypeNV             sampleOrderType;
+    uint32_t                              customSampleOrderCount;
+    const VkCoarseSampleOrderCustomNV*    pCustomSampleOrders;
+} VkPipelineViewportCoarseSampleOrderStateCreateInfoNV;
+
+
+typedef void (VKAPI_PTR *PFN_vkCmdBindShadingRateImageNV)(VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout);
+typedef void (VKAPI_PTR *PFN_vkCmdSetViewportShadingRatePaletteNV)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkShadingRatePaletteNV* pShadingRatePalettes);
+typedef void (VKAPI_PTR *PFN_vkCmdSetCoarseSampleOrderNV)(VkCommandBuffer commandBuffer, VkCoarseSampleOrderTypeNV sampleOrderType, uint32_t customSampleOrderCount, const VkCoarseSampleOrderCustomNV* pCustomSampleOrders);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdBindShadingRateImageNV(
+    VkCommandBuffer                             commandBuffer,
+    VkImageView                                 imageView,
+    VkImageLayout                               imageLayout);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportShadingRatePaletteNV(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    firstViewport,
+    uint32_t                                    viewportCount,
+    const VkShadingRatePaletteNV*               pShadingRatePalettes);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetCoarseSampleOrderNV(
+    VkCommandBuffer                             commandBuffer,
+    VkCoarseSampleOrderTypeNV                   sampleOrderType,
+    uint32_t                                    customSampleOrderCount,
+    const VkCoarseSampleOrderCustomNV*          pCustomSampleOrders);
+#endif
+
+#define VK_NVX_raytracing 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureNVX)
+
+#define VK_NVX_RAYTRACING_SPEC_VERSION    1
+#define VK_NVX_RAYTRACING_EXTENSION_NAME  "VK_NVX_raytracing"
+
+
+typedef enum VkGeometryTypeNVX {
+    VK_GEOMETRY_TYPE_TRIANGLES_NVX = 0,
+    VK_GEOMETRY_TYPE_AABBS_NVX = 1,
+    VK_GEOMETRY_TYPE_BEGIN_RANGE_NVX = VK_GEOMETRY_TYPE_TRIANGLES_NVX,
+    VK_GEOMETRY_TYPE_END_RANGE_NVX = VK_GEOMETRY_TYPE_AABBS_NVX,
+    VK_GEOMETRY_TYPE_RANGE_SIZE_NVX = (VK_GEOMETRY_TYPE_AABBS_NVX - VK_GEOMETRY_TYPE_TRIANGLES_NVX + 1),
+    VK_GEOMETRY_TYPE_MAX_ENUM_NVX = 0x7FFFFFFF
+} VkGeometryTypeNVX;
+
+typedef enum VkAccelerationStructureTypeNVX {
+    VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NVX = 0,
+    VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NVX = 1,
+    VK_ACCELERATION_STRUCTURE_TYPE_BEGIN_RANGE_NVX = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NVX,
+    VK_ACCELERATION_STRUCTURE_TYPE_END_RANGE_NVX = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NVX,
+    VK_ACCELERATION_STRUCTURE_TYPE_RANGE_SIZE_NVX = (VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NVX - VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NVX + 1),
+    VK_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_NVX = 0x7FFFFFFF
+} VkAccelerationStructureTypeNVX;
+
+typedef enum VkCopyAccelerationStructureModeNVX {
+    VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NVX = 0,
+    VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NVX = 1,
+    VK_COPY_ACCELERATION_STRUCTURE_MODE_BEGIN_RANGE_NVX = VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NVX,
+    VK_COPY_ACCELERATION_STRUCTURE_MODE_END_RANGE_NVX = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NVX,
+    VK_COPY_ACCELERATION_STRUCTURE_MODE_RANGE_SIZE_NVX = (VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NVX - VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NVX + 1),
+    VK_COPY_ACCELERATION_STRUCTURE_MODE_MAX_ENUM_NVX = 0x7FFFFFFF
+} VkCopyAccelerationStructureModeNVX;
+
+
+typedef enum VkGeometryFlagBitsNVX {
+    VK_GEOMETRY_OPAQUE_BIT_NVX = 0x00000001,
+    VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_NVX = 0x00000002,
+    VK_GEOMETRY_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF
+} VkGeometryFlagBitsNVX;
+typedef VkFlags VkGeometryFlagsNVX;
+
+typedef enum VkGeometryInstanceFlagBitsNVX {
+    VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NVX = 0x00000001,
+    VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_FLIP_WINDING_BIT_NVX = 0x00000002,
+    VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NVX = 0x00000004,
+    VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NVX = 0x00000008,
+    VK_GEOMETRY_INSTANCE_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF
+} VkGeometryInstanceFlagBitsNVX;
+typedef VkFlags VkGeometryInstanceFlagsNVX;
+
+typedef enum VkBuildAccelerationStructureFlagBitsNVX {
+    VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NVX = 0x00000001,
+    VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NVX = 0x00000002,
+    VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NVX = 0x00000004,
+    VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NVX = 0x00000008,
+    VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_NVX = 0x00000010,
+    VK_BUILD_ACCELERATION_STRUCTURE_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF
+} VkBuildAccelerationStructureFlagBitsNVX;
+typedef VkFlags VkBuildAccelerationStructureFlagsNVX;
+
+typedef struct VkRaytracingPipelineCreateInfoNVX {
+    VkStructureType                           sType;
+    const void*                               pNext;
+    VkPipelineCreateFlags                     flags;
+    uint32_t                                  stageCount;
+    const VkPipelineShaderStageCreateInfo*    pStages;
+    const uint32_t*                           pGroupNumbers;
+    uint32_t                                  maxRecursionDepth;
+    VkPipelineLayout                          layout;
+    VkPipeline                                basePipelineHandle;
+    int32_t                                   basePipelineIndex;
+} VkRaytracingPipelineCreateInfoNVX;
+
+typedef struct VkGeometryTrianglesNVX {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkBuffer           vertexData;
+    VkDeviceSize       vertexOffset;
+    uint32_t           vertexCount;
+    VkDeviceSize       vertexStride;
+    VkFormat           vertexFormat;
+    VkBuffer           indexData;
+    VkDeviceSize       indexOffset;
+    uint32_t           indexCount;
+    VkIndexType        indexType;
+    VkBuffer           transformData;
+    VkDeviceSize       transformOffset;
+} VkGeometryTrianglesNVX;
+
+typedef struct VkGeometryAABBNVX {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkBuffer           aabbData;
+    uint32_t           numAABBs;
+    uint32_t           stride;
+    VkDeviceSize       offset;
+} VkGeometryAABBNVX;
+
+typedef struct VkGeometryDataNVX {
+    VkGeometryTrianglesNVX    triangles;
+    VkGeometryAABBNVX         aabbs;
+} VkGeometryDataNVX;
+
+typedef struct VkGeometryNVX {
+    VkStructureType       sType;
+    const void*           pNext;
+    VkGeometryTypeNVX     geometryType;
+    VkGeometryDataNVX     geometry;
+    VkGeometryFlagsNVX    flags;
+} VkGeometryNVX;
+
+typedef struct VkAccelerationStructureCreateInfoNVX {
+    VkStructureType                         sType;
+    const void*                             pNext;
+    VkAccelerationStructureTypeNVX          type;
+    VkBuildAccelerationStructureFlagsNVX    flags;
+    VkDeviceSize                            compactedSize;
+    uint32_t                                instanceCount;
+    uint32_t                                geometryCount;
+    const VkGeometryNVX*                    pGeometries;
+} VkAccelerationStructureCreateInfoNVX;
+
+typedef struct VkBindAccelerationStructureMemoryInfoNVX {
+    VkStructureType               sType;
+    const void*                   pNext;
+    VkAccelerationStructureNVX    accelerationStructure;
+    VkDeviceMemory                memory;
+    VkDeviceSize                  memoryOffset;
+    uint32_t                      deviceIndexCount;
+    const uint32_t*               pDeviceIndices;
+} VkBindAccelerationStructureMemoryInfoNVX;
+
+typedef struct VkDescriptorAccelerationStructureInfoNVX {
+    VkStructureType                      sType;
+    const void*                          pNext;
+    uint32_t                             accelerationStructureCount;
+    const VkAccelerationStructureNVX*    pAccelerationStructures;
+} VkDescriptorAccelerationStructureInfoNVX;
+
+typedef struct VkAccelerationStructureMemoryRequirementsInfoNVX {
+    VkStructureType               sType;
+    const void*                   pNext;
+    VkAccelerationStructureNVX    accelerationStructure;
+} VkAccelerationStructureMemoryRequirementsInfoNVX;
+
+typedef struct VkPhysicalDeviceRaytracingPropertiesNVX {
+    VkStructureType    sType;
+    void*              pNext;
+    uint32_t           shaderHeaderSize;
+    uint32_t           maxRecursionDepth;
+    uint32_t           maxGeometryCount;
+} VkPhysicalDeviceRaytracingPropertiesNVX;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructureNVX)(VkDevice device, const VkAccelerationStructureCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureNVX* pAccelerationStructure);
+typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureNVX)(VkDevice device, VkAccelerationStructureNVX accelerationStructure, const VkAllocationCallbacks* pAllocator);
+typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureMemoryRequirementsNVX)(VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNVX* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureScratchMemoryRequirementsNVX)(VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNVX* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements);
+typedef VkResult (VKAPI_PTR *PFN_vkBindAccelerationStructureMemoryNVX)(VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoNVX* pBindInfos);
+typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructureNVX)(VkCommandBuffer cmdBuf, VkAccelerationStructureTypeNVX type, uint32_t instanceCount, VkBuffer instanceData, VkDeviceSize instanceOffset, uint32_t geometryCount, const VkGeometryNVX* pGeometries, VkBuildAccelerationStructureFlagsNVX flags, VkBool32 update, VkAccelerationStructureNVX dst, VkAccelerationStructureNVX src, VkBuffer scratch, VkDeviceSize scratchOffset);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureNVX)(VkCommandBuffer cmdBuf, VkAccelerationStructureNVX dst, VkAccelerationStructureNVX src, VkCopyAccelerationStructureModeNVX mode);
+typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysNVX)(VkCommandBuffer cmdBuf, VkBuffer raygenShaderBindingTableBuffer, VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer, VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride, VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset, VkDeviceSize hitShaderBindingStride, uint32_t width, uint32_t height);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateRaytracingPipelinesNVX)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRaytracingPipelineCreateInfoNVX* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines);
+typedef VkResult (VKAPI_PTR *PFN_vkGetRaytracingShaderHandlesNVX)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData);
+typedef VkResult (VKAPI_PTR *PFN_vkGetAccelerationStructureHandleNVX)(VkDevice device, VkAccelerationStructureNVX accelerationStructure, size_t dataSize, void* pData);
+typedef void (VKAPI_PTR *PFN_vkCmdWriteAccelerationStructurePropertiesNVX)(VkCommandBuffer cmdBuf, VkAccelerationStructureNVX accelerationStructure, VkQueryType queryType, VkQueryPool queryPool, uint32_t query);
+typedef VkResult (VKAPI_PTR *PFN_vkCompileDeferredNVX)(VkDevice device, VkPipeline pipeline, uint32_t shader);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateAccelerationStructureNVX(
+    VkDevice                                    device,
+    const VkAccelerationStructureCreateInfoNVX* pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkAccelerationStructureNVX*                 pAccelerationStructure);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyAccelerationStructureNVX(
+    VkDevice                                    device,
+    VkAccelerationStructureNVX                  accelerationStructure,
+    const VkAllocationCallbacks*                pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureMemoryRequirementsNVX(
+    VkDevice                                    device,
+    const VkAccelerationStructureMemoryRequirementsInfoNVX* pInfo,
+    VkMemoryRequirements2KHR*                   pMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureScratchMemoryRequirementsNVX(
+    VkDevice                                    device,
+    const VkAccelerationStructureMemoryRequirementsInfoNVX* pInfo,
+    VkMemoryRequirements2KHR*                   pMemoryRequirements);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBindAccelerationStructureMemoryNVX(
+    VkDevice                                    device,
+    uint32_t                                    bindInfoCount,
+    const VkBindAccelerationStructureMemoryInfoNVX* pBindInfos);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructureNVX(
+    VkCommandBuffer                             cmdBuf,
+    VkAccelerationStructureTypeNVX              type,
+    uint32_t                                    instanceCount,
+    VkBuffer                                    instanceData,
+    VkDeviceSize                                instanceOffset,
+    uint32_t                                    geometryCount,
+    const VkGeometryNVX*                        pGeometries,
+    VkBuildAccelerationStructureFlagsNVX        flags,
+    VkBool32                                    update,
+    VkAccelerationStructureNVX                  dst,
+    VkAccelerationStructureNVX                  src,
+    VkBuffer                                    scratch,
+    VkDeviceSize                                scratchOffset);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureNVX(
+    VkCommandBuffer                             cmdBuf,
+    VkAccelerationStructureNVX                  dst,
+    VkAccelerationStructureNVX                  src,
+    VkCopyAccelerationStructureModeNVX          mode);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysNVX(
+    VkCommandBuffer                             cmdBuf,
+    VkBuffer                                    raygenShaderBindingTableBuffer,
+    VkDeviceSize                                raygenShaderBindingOffset,
+    VkBuffer                                    missShaderBindingTableBuffer,
+    VkDeviceSize                                missShaderBindingOffset,
+    VkDeviceSize                                missShaderBindingStride,
+    VkBuffer                                    hitShaderBindingTableBuffer,
+    VkDeviceSize                                hitShaderBindingOffset,
+    VkDeviceSize                                hitShaderBindingStride,
+    uint32_t                                    width,
+    uint32_t                                    height);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateRaytracingPipelinesNVX(
+    VkDevice                                    device,
+    VkPipelineCache                             pipelineCache,
+    uint32_t                                    createInfoCount,
+    const VkRaytracingPipelineCreateInfoNVX*    pCreateInfos,
+    const VkAllocationCallbacks*                pAllocator,
+    VkPipeline*                                 pPipelines);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetRaytracingShaderHandlesNVX(
+    VkDevice                                    device,
+    VkPipeline                                  pipeline,
+    uint32_t                                    firstGroup,
+    uint32_t                                    groupCount,
+    size_t                                      dataSize,
+    void*                                       pData);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetAccelerationStructureHandleNVX(
+    VkDevice                                    device,
+    VkAccelerationStructureNVX                  accelerationStructure,
+    size_t                                      dataSize,
+    void*                                       pData);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdWriteAccelerationStructurePropertiesNVX(
+    VkCommandBuffer                             cmdBuf,
+    VkAccelerationStructureNVX                  accelerationStructure,
+    VkQueryType                                 queryType,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    query);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCompileDeferredNVX(
+    VkDevice                                    device,
+    VkPipeline                                  pipeline,
+    uint32_t                                    shader);
+#endif
+
+#define VK_NV_representative_fragment_test 1
+#define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION 1
+#define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME "VK_NV_representative_fragment_test"
+
+typedef struct VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           representativeFragmentTest;
+} VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV;
+
+typedef struct VkPipelineRepresentativeFragmentTestStateCreateInfoNV {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkBool32           representativeFragmentTestEnable;
+} VkPipelineRepresentativeFragmentTestStateCreateInfoNV;
+
+
+
 #define VK_EXT_global_priority 1
 #define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 2
 #define VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME "VK_EXT_global_priority"
@@ -7845,6 +8301,133 @@
 #define VK_NV_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME "VK_NV_shader_subgroup_partitioned"
 
 
+#define VK_NV_compute_shader_derivatives 1
+#define VK_NV_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION 1
+#define VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME "VK_NV_compute_shader_derivatives"
+
+typedef struct VkPhysicalDeviceComputeShaderDerivativesFeaturesNV {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           computeDerivativeGroupQuads;
+    VkBool32           computeDerivativeGroupLinear;
+} VkPhysicalDeviceComputeShaderDerivativesFeaturesNV;
+
+
+
+#define VK_NV_mesh_shader 1
+#define VK_NV_MESH_SHADER_SPEC_VERSION    1
+#define VK_NV_MESH_SHADER_EXTENSION_NAME  "VK_NV_mesh_shader"
+
+typedef struct VkPhysicalDeviceMeshShaderFeaturesNV {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           taskShader;
+    VkBool32           meshShader;
+} VkPhysicalDeviceMeshShaderFeaturesNV;
+
+typedef struct VkPhysicalDeviceMeshShaderPropertiesNV {
+    VkStructureType    sType;
+    void*              pNext;
+    uint32_t           maxDrawMeshTasksCount;
+    uint32_t           maxTaskWorkGroupInvocations;
+    uint32_t           maxTaskWorkGroupSize[3];
+    uint32_t           maxTaskTotalMemorySize;
+    uint32_t           maxTaskOutputCount;
+    uint32_t           maxMeshWorkGroupInvocations;
+    uint32_t           maxMeshWorkGroupSize[3];
+    uint32_t           maxMeshTotalMemorySize;
+    uint32_t           maxMeshOutputVertices;
+    uint32_t           maxMeshOutputPrimitives;
+    uint32_t           maxMeshMultiviewViewCount;
+    uint32_t           meshOutputPerVertexGranularity;
+    uint32_t           meshOutputPerPrimitiveGranularity;
+} VkPhysicalDeviceMeshShaderPropertiesNV;
+
+typedef struct VkDrawMeshTasksIndirectCommandNV {
+    uint32_t    taskCount;
+    uint32_t    firstTask;
+} VkDrawMeshTasksIndirectCommandNV;
+
+
+typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksNV)(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectNV)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectCountNV)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksNV(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    taskCount,
+    uint32_t                                    firstTask);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectNV(
+    VkCommandBuffer                             commandBuffer,
+    VkBuffer                                    buffer,
+    VkDeviceSize                                offset,
+    uint32_t                                    drawCount,
+    uint32_t                                    stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectCountNV(
+    VkCommandBuffer                             commandBuffer,
+    VkBuffer                                    buffer,
+    VkDeviceSize                                offset,
+    VkBuffer                                    countBuffer,
+    VkDeviceSize                                countBufferOffset,
+    uint32_t                                    maxDrawCount,
+    uint32_t                                    stride);
+#endif
+
+#define VK_NV_fragment_shader_barycentric 1
+#define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION 1
+#define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME "VK_NV_fragment_shader_barycentric"
+
+typedef struct VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           fragmentShaderBarycentric;
+} VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV;
+
+
+
+#define VK_NV_shader_image_footprint 1
+#define VK_NV_SHADER_IMAGE_FOOTPRINT_SPEC_VERSION 1
+#define VK_NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME "VK_NV_shader_image_footprint"
+
+typedef struct VkPhysicalDeviceShaderImageFootprintFeaturesNV {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           imageFootprint;
+} VkPhysicalDeviceShaderImageFootprintFeaturesNV;
+
+
+
+#define VK_NV_scissor_exclusive 1
+#define VK_NV_SCISSOR_EXCLUSIVE_SPEC_VERSION 1
+#define VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME "VK_NV_scissor_exclusive"
+
+typedef struct VkPipelineViewportExclusiveScissorStateCreateInfoNV {
+    VkStructureType    sType;
+    const void*        pNext;
+    uint32_t           exclusiveScissorCount;
+    const VkRect2D*    pExclusiveScissors;
+} VkPipelineViewportExclusiveScissorStateCreateInfoNV;
+
+typedef struct VkPhysicalDeviceExclusiveScissorFeaturesNV {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           exclusiveScissor;
+} VkPhysicalDeviceExclusiveScissorFeaturesNV;
+
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetExclusiveScissorNV)(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor, uint32_t exclusiveScissorCount, const VkRect2D* pExclusiveScissors);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetExclusiveScissorNV(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    firstExclusiveScissor,
+    uint32_t                                    exclusiveScissorCount,
+    const VkRect2D*                             pExclusiveScissors);
+#endif
+
 #define VK_NV_device_diagnostic_checkpoints 1
 #define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_SPEC_VERSION 2
 #define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME "VK_NV_device_diagnostic_checkpoints"
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 4c2d223..a607a5d 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -1165,27 +1165,28 @@
         result = EnumeratePhysicalDevices(instance, &device_count, nullptr);
         if (result < 0)
             return result;
+
         if (!pPhysicalDeviceGroupProperties) {
             *pPhysicalDeviceGroupCount = device_count;
             return result;
         }
 
-        device_count = std::min(device_count, *pPhysicalDeviceGroupCount);
         if (!device_count) {
             *pPhysicalDeviceGroupCount = 0;
             return result;
         }
+        device_count = std::min(device_count, *pPhysicalDeviceGroupCount);
+        if (!device_count)
+            return VK_INCOMPLETE;
 
         android::Vector<VkPhysicalDevice> devices;
         devices.resize(device_count);
-
+        *pPhysicalDeviceGroupCount = device_count;
         result = EnumeratePhysicalDevices(instance, &device_count,
                                           devices.editArray());
         if (result < 0)
             return result;
 
-        devices.resize(device_count);
-        *pPhysicalDeviceGroupCount = device_count;
         for (uint32_t i = 0; i < device_count; ++i) {
             pPhysicalDeviceGroupProperties[i].physicalDeviceCount = 1;
             pPhysicalDeviceGroupProperties[i].physicalDevices[0] = devices[i];