Merge "Game Driver: make GpuService the GpuStats holder"
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index 609ddaf..670abea 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -80,8 +80,6 @@
     // system/apex/apexd/apexd_main.cpp.
     //
     // Only scan the APEX directory under /system (within the chroot dir).
-    // Note that this leaves around the loop devices created and used by
-    // libapexd's code, but this is fine, as we expect to reboot soon after.
     apex::scanPackagesDirAndActivate(apex::kApexPackageSystemDir);
     return apex::getActivePackages();
 }
diff --git a/include/android/surface_control.h b/include/android/surface_control.h
index 0573187..0e79239 100644
--- a/include/android/surface_control.h
+++ b/include/android/surface_control.h
@@ -28,6 +28,7 @@
 
 #include <sys/cdefs.h>
 
+#include <android/data_space.h>
 #include <android/hardware_buffer.h>
 #include <android/hdr_metadata.h>
 #include <android/native_window.h>
@@ -316,6 +317,15 @@
                                         ASurfaceControl* surface_control, float alpha)
                                         __INTRODUCED_IN(29);
 
+/**
+ * Sets the data space of the surface_control's buffers.
+ *
+ * If no data space is set, the surface control defaults to ADATASPACE_SRGB.
+ */
+void ASurfaceTransaction_setBufferDataSpace(ASurfaceTransaction* transaction,
+                                            ASurfaceControl* surface_control, ADataSpace data_space)
+                                            __INTRODUCED_IN(29);
+
 /*
  * SMPTE ST 2086 "Mastering Display Color Volume" static metadata
  *
diff --git a/include/input/InputDevice.h b/include/input/InputDevice.h
index 34d164c..ce8db91 100644
--- a/include/input/InputDevice.h
+++ b/include/input/InputDevice.h
@@ -165,6 +165,13 @@
 extern std::string getInputDeviceConfigurationFilePathByName(
         const std::string& name, InputDeviceConfigurationFileType type);
 
+enum ReservedInputDeviceId : int32_t {
+    // Device id of a special "virtual" keyboard that is always present.
+    VIRTUAL_KEYBOARD_ID = -1,
+    // Device id of the "built-in" keyboard if there is one.
+    BUILT_IN_KEYBOARD_ID = 0,
+};
+
 } // namespace android
 
 #endif // _LIBINPUT_INPUT_DEVICE_H
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index 96ee295..cb0e08d 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -218,7 +218,7 @@
         if (!e) return; // out of memory
     }
 
-    e->mRequestingSid = true;
+    e->mRequestingSid = requestingSid;
 }
 
 BBinder::~BBinder()
diff --git a/libs/binder/include/binder/IInterface.h b/libs/binder/include/binder/IInterface.h
index f6381f7..0d30560 100644
--- a/libs/binder/include/binder/IInterface.h
+++ b/libs/binder/include/binder/IInterface.h
@@ -54,6 +54,7 @@
     virtual const String16&     getInterfaceDescriptor() const;
 
 protected:
+    typedef INTERFACE           BaseInterface;
     virtual IBinder*            onAsBinder();
 };
 
@@ -66,6 +67,7 @@
     explicit                    BpInterface(const sp<IBinder>& remote);
 
 protected:
+    typedef INTERFACE           BaseInterface;
     virtual IBinder*            onAsBinder();
 };
 
diff --git a/libs/binder/include/binder/SafeInterface.h b/libs/binder/include/binder/SafeInterface.h
index 3bfd462..5fa2ff6 100644
--- a/libs/binder/include/binder/SafeInterface.h
+++ b/libs/binder/include/binder/SafeInterface.h
@@ -152,6 +152,12 @@
         return callParcel("writeParcelableVector",
                           [&]() { return parcel->writeParcelableVector(v); });
     }
+    status_t read(const Parcel& parcel, float* f) const {
+        return callParcel("readFloat", [&]() { return parcel.readFloat(f); });
+    }
+    status_t write(Parcel* parcel, float f) const {
+        return callParcel("writeFloat", [&]() { return parcel->writeFloat(f); });
+    }
 
     // Templates to handle integral types. We use a struct template to require that the called
     // function exactly matches the signedness and size of the argument (e.g., the argument isn't
diff --git a/libs/binder/tests/binderSafeInterfaceTest.cpp b/libs/binder/tests/binderSafeInterfaceTest.cpp
index 6a16e24..3b1db27 100644
--- a/libs/binder/tests/binderSafeInterfaceTest.cpp
+++ b/libs/binder/tests/binderSafeInterfaceTest.cpp
@@ -229,6 +229,7 @@
         IncrementUint32,
         IncrementInt64,
         IncrementUint64,
+        IncrementFloat,
         IncrementTwo,
         Last,
     };
@@ -259,6 +260,7 @@
     virtual status_t increment(uint32_t a, uint32_t* aPlusOne) const = 0;
     virtual status_t increment(int64_t a, int64_t* aPlusOne) const = 0;
     virtual status_t increment(uint64_t a, uint64_t* aPlusOne) const = 0;
+    virtual status_t increment(float a, float* aPlusOne) const = 0;
 
     // This tests that input/output parameter interleaving works correctly
     virtual status_t increment(int32_t a, int32_t* aPlusOne, int32_t b,
@@ -353,6 +355,11 @@
         using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
         return callRemote<Signature>(Tag::IncrementUint64, a, aPlusOne);
     }
+    status_t increment(float a, float* aPlusOne) const override {
+        ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
+        using Signature = status_t (ISafeInterfaceTest::*)(float, float*) const;
+        return callRemote<Signature>(Tag::IncrementFloat, a, aPlusOne);
+    }
     status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
         using Signature =
@@ -474,6 +481,11 @@
         *aPlusOne = a + 1;
         return NO_ERROR;
     }
+    status_t increment(float a, float* aPlusOne) const override {
+        ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
+        *aPlusOne = a + 1.0f;
+        return NO_ERROR;
+    }
     status_t increment(int32_t a, int32_t* aPlusOne, int32_t b, int32_t* bPlusOne) const override {
         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
         *aPlusOne = a + 1;
@@ -555,6 +567,10 @@
                 using Signature = status_t (ISafeInterfaceTest::*)(uint64_t, uint64_t*) const;
                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
             }
+            case ISafeInterfaceTest::Tag::IncrementFloat: {
+                using Signature = status_t (ISafeInterfaceTest::*)(float, float*) const;
+                return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
+            }
             case ISafeInterfaceTest::Tag::IncrementTwo: {
                 using Signature = status_t (ISafeInterfaceTest::*)(int32_t, int32_t*, int32_t,
                                                                    int32_t*) const;
@@ -804,6 +820,14 @@
     ASSERT_EQ(a + 1, aPlusOne);
 }
 
+TEST_F(SafeInterfaceTest, TestIncrementFloat) {
+    const float a = 1.0f;
+    float aPlusOne = 0.0f;
+    status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
+    ASSERT_EQ(NO_ERROR, result);
+    ASSERT_EQ(a + 1.0f, aPlusOne);
+}
+
 TEST_F(SafeInterfaceTest, TestIncrementTwo) {
     const int32_t a = 1;
     int32_t aPlusOne = 0;
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 008f520..55488da 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -63,23 +63,25 @@
 
 SurfaceControl::~SurfaceControl()
 {
+    // Avoid reparenting the server-side surface to null if we are not the owner of it,
+    // meaning that we retrieved it from another process.
     if (mClient != nullptr && mHandle != nullptr && mOwned) {
         SurfaceComposerClient::doDropReferenceTransaction(mHandle, mClient->getClient());
     }
-    mClient.clear();
-    mHandle.clear();
-    mGraphicBufferProducer.clear();
-    IPCThreadState::self()->flushCommands();
+    release();
 }
 
 void SurfaceControl::destroy()
 {
-    // Avoid destroying the server-side surface if we are not the owner of it, meaning that we
-    // retrieved it from another process.
-    if (isValid() && mOwned) {
+    if (isValid()) {
         SurfaceComposerClient::Transaction().reparent(this, nullptr).apply();
     }
-    // clear all references and trigger an IPC now, to make sure things
+    release();
+}
+
+void SurfaceControl::release()
+{
+    // Trigger an IPC now, to make sure things
     // happen without delay, since these resources are quite heavy.
     mClient.clear();
     mHandle.clear();
@@ -87,17 +89,6 @@
     IPCThreadState::self()->flushCommands();
 }
 
-void SurfaceControl::clear()
-{
-    // here, the window manager tells us explicitly that we should destroy
-    // the surface's resource. Soon after this call, it will also release
-    // its last reference (which will call the dtor); however, it is possible
-    // that a client living in the same process still holds references which
-    // would delay the call to the dtor -- that is why we need this explicit
-    // "clear()" call.
-    destroy();
-}
-
 void SurfaceControl::disconnect() {
     if (mGraphicBufferProducer != nullptr) {
         mGraphicBufferProducer->disconnect(
diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
index b584f36..55efcbf 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -58,8 +58,12 @@
     static bool isSameSurface(
             const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs);
 
-    // release surface data from java
-    void        clear();
+    // Release the handles assosciated with the SurfaceControl, without reparenting
+    // them off-screen. At the moment if this isn't executed before ~SurfaceControl
+    // is called then the destructor will reparent the layer off-screen for you.
+    void        release();
+    // Reparent off-screen and release. This is invoked by the destructor.
+    void destroy();
 
     // disconnect any api that's connected
     void        disconnect();
@@ -98,7 +102,6 @@
 
     sp<Surface> generateSurfaceLocked() const;
     status_t validate() const;
-    void destroy();
 
     sp<SurfaceComposerClient>   mClient;
     sp<IBinder>                 mHandle;
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index 6ea1270..8ef4896 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -263,8 +263,17 @@
     if (!desc) return 0;
     if (!AHardwareBuffer_isValidDescription(desc, /*log=*/false)) return 0;
 
-    // Make a trial allocation.
-    // TODO(b/115660272): add implementation that uses a HAL query.
+    bool supported = false;
+    GraphicBuffer* gBuffer = new GraphicBuffer();
+    status_t err = gBuffer->isSupported(desc->width, desc->height, desc->format, desc->layers,
+                                        desc->usage, &supported);
+
+    if (err == NO_ERROR) {
+        return supported;
+    }
+
+    // function isSupported is not implemented on device or an error occurred during HAL
+    // query.  Make a trial allocation.
     AHardwareBuffer_Desc trialDesc = *desc;
     trialDesc.width = 4;
     trialDesc.height = desc->format == AHARDWAREBUFFER_FORMAT_BLOB ? 1 : 4;
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index c5a9942..8f9071e 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -424,6 +424,7 @@
         mTraceGpuCompletion = true;
         mFlushTracer = std::make_unique<FlushTracer>(this);
     }
+    mDrawingBuffer = createFramebuffer();
 }
 
 GLESRenderEngine::~GLESRenderEngine() {
@@ -439,6 +440,10 @@
     return std::make_unique<GLImage>(*this);
 }
 
+Framebuffer* GLESRenderEngine::getFramebufferForDrawing() {
+    return mDrawingBuffer.get();
+}
+
 void GLESRenderEngine::primeCache() const {
     ProgramCache::getInstance().primeCache(mInProtectedContext ? mProtectedEGLContext : mEGLContext,
                                            mFeatureFlags & USE_COLOR_MANAGEMENT);
@@ -449,6 +454,7 @@
 }
 
 base::unique_fd GLESRenderEngine::flush() {
+    ATRACE_CALL();
     if (!GLExtensions::getInstance().hasNativeFenceSync()) {
         return base::unique_fd();
     }
@@ -479,6 +485,7 @@
 }
 
 bool GLESRenderEngine::finish() {
+    ATRACE_CALL();
     if (!GLExtensions::getInstance().hasFenceSync()) {
         ALOGW("no synchronization support");
         return false;
@@ -544,6 +551,8 @@
 }
 
 void GLESRenderEngine::clearWithColor(float red, float green, float blue, float alpha) {
+    ATRACE_CALL();
+    glDisable(GL_BLEND);
     glClearColor(red, green, blue, alpha);
     glClear(GL_COLOR_BUFFER_BIT);
 }
@@ -594,6 +603,7 @@
 }
 
 void GLESRenderEngine::bindExternalTextureImage(uint32_t texName, const Image& image) {
+    ATRACE_CALL();
     const GLImage& glImage = static_cast<const GLImage&>(image);
     const GLenum target = GL_TEXTURE_EXTERNAL_OES;
 
@@ -608,8 +618,15 @@
 }
 
 status_t GLESRenderEngine::bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer,
+                                                     sp<Fence> bufferFence, bool readCache) {
+    return bindExternalTextureBuffer(texName, buffer, bufferFence, readCache,
+                                     /*persistCache=*/false);
+}
+
+status_t GLESRenderEngine::bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer,
                                                      sp<Fence> bufferFence, bool readCache,
                                                      bool persistCache) {
+    ATRACE_CALL();
     if (readCache) {
         auto cachedImage = mImageCache.find(buffer->getId());
 
@@ -655,7 +672,7 @@
     }
 
     // We don't always want to persist to the cache, e.g. on older devices we
-    // might bind for synchronization purpoeses, but that might leak if we never
+    // might bind for synchronization purposes, but that might leak if we never
     // call drawLayers again, so it's just better to recreate the image again
     // if needed when we draw.
     if (persistCache) {
@@ -666,6 +683,7 @@
 }
 
 void GLESRenderEngine::evictImages(const std::vector<LayerSettings>& layers) {
+    ATRACE_CALL();
     // destroy old image references that we're not going to draw with.
     std::unordered_set<uint64_t> bufIds;
     for (auto layer : layers) {
@@ -703,6 +721,7 @@
 }
 
 status_t GLESRenderEngine::bindFrameBuffer(Framebuffer* framebuffer) {
+    ATRACE_CALL();
     GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(framebuffer);
     EGLImageKHR eglImage = glFramebuffer->getEGLImage();
     uint32_t textureName = glFramebuffer->getTextureName();
@@ -731,6 +750,7 @@
 }
 
 void GLESRenderEngine::unbindFrameBuffer(Framebuffer* /* framebuffer */) {
+    ATRACE_CALL();
     mFboHeight = 0;
 
     // back to main framebuffer
@@ -770,6 +790,7 @@
                                       const std::vector<LayerSettings>& layers,
                                       ANativeWindowBuffer* const buffer,
                                       base::unique_fd* drawFence) {
+    ATRACE_CALL();
     if (layers.empty()) {
         ALOGV("Drawing empty layer stack");
         return NO_ERROR;
@@ -786,6 +807,13 @@
 
     evictImages(layers);
 
+    // clear the entire buffer, sometimes when we reuse buffers we'd persist
+    // ghost images otherwise.
+    // we also require a full transparent framebuffer for overlays. This is
+    // probably not quite efficient on all GPUs, since we could filter out
+    // opaque layers.
+    clearWithColor(0.0, 0.0, 0.0, 0.0);
+
     setViewportAndProjection(display.physicalDisplay, display.clip);
 
     setOutputDataSpace(display.outputDataspace);
@@ -794,6 +822,7 @@
     mat4 projectionMatrix = mState.projectionMatrix * display.globalTransform;
     mState.projectionMatrix = projectionMatrix;
     if (!display.clearRegion.isEmpty()) {
+        glDisable(GL_BLEND);
         fillRegionWithColor(display.clearRegion, 0.0, 0.0, 0.0, 1.0);
     }
 
@@ -813,9 +842,11 @@
 
         bool usePremultipliedAlpha = true;
         bool disableTexture = true;
+        bool isOpaque = false;
 
         if (layer.source.buffer.buffer != nullptr) {
             disableTexture = false;
+            isOpaque = layer.source.buffer.isOpaque;
 
             sp<GraphicBuffer> gBuf = layer.source.buffer.buffer;
 
@@ -825,17 +856,19 @@
 
             usePremultipliedAlpha = layer.source.buffer.usePremultipliedAlpha;
             Texture texture(Texture::TEXTURE_EXTERNAL, layer.source.buffer.textureName);
-            texture.setMatrix(layer.source.buffer.textureTransform.asArray());
+            mat4 texMatrix = layer.source.buffer.textureTransform;
+
+            texture.setMatrix(texMatrix.asArray());
             texture.setFiltering(layer.source.buffer.useTextureFiltering);
 
             texture.setDimensions(gBuf->getWidth(), gBuf->getHeight());
             setSourceY410BT2020(layer.source.buffer.isY410BT2020);
 
             renderengine::Mesh::VertexArray<vec2> texCoords(mesh.getTexCoordArray<vec2>());
-            texCoords[0] = vec2(0.0, 1.0);
-            texCoords[1] = vec2(0.0, 0.0);
-            texCoords[2] = vec2(1.0, 0.0);
-            texCoords[3] = vec2(1.0, 1.0);
+            texCoords[0] = vec2(0.0, 0.0);
+            texCoords[1] = vec2(0.0, 1.0);
+            texCoords[2] = vec2(1.0, 1.0);
+            texCoords[3] = vec2(1.0, 0.0);
             setupLayerTexturing(texture);
         }
 
@@ -843,8 +876,11 @@
         const half4 color = half4(solidColor.r, solidColor.g, solidColor.b, layer.alpha);
         // Buffer sources will have a black solid color ignored in the shader,
         // so in that scenario the solid color passed here is arbitrary.
-        setupLayerBlending(usePremultipliedAlpha, layer.source.buffer.isOpaque, disableTexture,
-                           color, layer.geometry.roundedCornersRadius);
+        setupLayerBlending(usePremultipliedAlpha, isOpaque, disableTexture, color,
+                           layer.geometry.roundedCornersRadius);
+        if (layer.disableBlending) {
+            glDisable(GL_BLEND);
+        }
         setSourceDataSpace(layer.sourceDataspace);
 
         drawMesh(mesh);
@@ -903,6 +939,7 @@
 }
 
 void GLESRenderEngine::setViewportAndProjection(Rect viewport, Rect clip) {
+    ATRACE_CALL();
     mVpWidth = viewport.getWidth();
     mVpHeight = viewport.getHeight();
 
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index e094860..7b72666 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -71,6 +71,8 @@
     void genTextures(size_t count, uint32_t* names) override;
     void deleteTextures(size_t count, uint32_t const* names) override;
     void bindExternalTextureImage(uint32_t texName, const Image& image) override;
+    status_t bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer, sp<Fence> fence,
+                                       bool readCache);
     status_t bindFrameBuffer(Framebuffer* framebuffer) override;
     void unbindFrameBuffer(Framebuffer* framebuffer) override;
     void checkErrors() const override;
@@ -86,6 +88,7 @@
     EGLConfig getEGLConfig() const { return mEGLConfig; }
 
 protected:
+    Framebuffer* getFramebufferForDrawing() override;
     void dump(std::string& result) override;
     void setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop,
                                   ui::Transform::orientation_flags rotation) override;
@@ -184,8 +187,13 @@
     const bool mUseColorManagement = false;
 
     // Cache of GL images that we'll store per GraphicBuffer ID
+    // TODO: Layer should call back on destruction instead to clean this up,
+    // as it has better system utilization at the potential expense of a
+    // more complicated interface.
     std::unordered_map<uint64_t, std::unique_ptr<Image>> mImageCache;
 
+    std::unique_ptr<Framebuffer> mDrawingBuffer;
+
     class FlushTracer {
     public:
         FlushTracer(GLESRenderEngine* engine);
diff --git a/libs/renderengine/gl/GLFramebuffer.cpp b/libs/renderengine/gl/GLFramebuffer.cpp
index 4a519bb..0e3b405 100644
--- a/libs/renderengine/gl/GLFramebuffer.cpp
+++ b/libs/renderengine/gl/GLFramebuffer.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
 #include "GLFramebuffer.h"
 
 #include <GLES/gl.h>
@@ -21,6 +23,7 @@
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 #include <nativebase/nativebase.h>
+#include <utils/Trace.h>
 #include "GLESRenderEngine.h"
 
 namespace android {
@@ -40,6 +43,7 @@
 }
 
 bool GLFramebuffer::setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer, bool isProtected) {
+    ATRACE_CALL();
     if (mEGLImage != EGL_NO_IMAGE_KHR) {
         eglDestroyImageKHR(mEGLDisplay, mEGLImage);
         mEGLImage = EGL_NO_IMAGE_KHR;
diff --git a/libs/renderengine/gl/GLImage.cpp b/libs/renderengine/gl/GLImage.cpp
index 587cb31..77e648e 100644
--- a/libs/renderengine/gl/GLImage.cpp
+++ b/libs/renderengine/gl/GLImage.cpp
@@ -14,11 +14,14 @@
  * limitations under the License.
  */
 
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
 #include "GLImage.h"
 
 #include <vector>
 
 #include <log/log.h>
+#include <utils/Trace.h>
 #include "GLESRenderEngine.h"
 #include "GLExtensions.h"
 
@@ -50,6 +53,7 @@
 }
 
 bool GLImage::setNativeWindowBuffer(ANativeWindowBuffer* buffer, bool isProtected) {
+    ATRACE_CALL();
     if (mEGLImage != EGL_NO_IMAGE_KHR) {
         if (!eglDestroyImageKHR(mEGLDisplay, mEGLImage)) {
             ALOGE("failed to destroy image: %#x", eglGetError());
diff --git a/libs/renderengine/include/renderengine/LayerSettings.h b/libs/renderengine/include/renderengine/LayerSettings.h
index 56ac714..aa45ed8 100644
--- a/libs/renderengine/include/renderengine/LayerSettings.h
+++ b/libs/renderengine/include/renderengine/LayerSettings.h
@@ -126,6 +126,9 @@
     // Additional layer-specific color transform to be applied before the global
     // transform.
     mat4 colorTransform = mat4();
+
+    // True if blending will be forced to be disabled.
+    bool disableBlending = false;
 };
 
 } // namespace renderengine
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index 20dd996..b51ed22 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -108,6 +108,8 @@
     virtual void genTextures(size_t count, uint32_t* names) = 0;
     virtual void deleteTextures(size_t count, uint32_t const* names) = 0;
     virtual void bindExternalTextureImage(uint32_t texName, const Image& image) = 0;
+    virtual status_t bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer,
+                                               sp<Fence> fence, bool cleanCache) = 0;
     // When binding a native buffer, it must be done before setViewportAndProjection
     // Returns NO_ERROR when binds successfully, NO_MEMORY when there's no memory for allocation.
     virtual status_t bindFrameBuffer(Framebuffer* framebuffer) = 0;
@@ -172,37 +174,37 @@
     // fence.
     // @return An error code indicating whether drawing was successful. For
     // now, this always returns NO_ERROR.
-    // TODO(alecmouri): Consider making this a multi-display API, so that the
-    // caller deoes not need to handle multiple fences.
     virtual status_t drawLayers(const DisplaySettings& display,
                                 const std::vector<LayerSettings>& layers,
                                 ANativeWindowBuffer* buffer, base::unique_fd* drawFence) = 0;
 
-    // TODO(alecmouri): Expose something like bindTexImage() so that devices
-    // that don't support native sync fences can get rid of code duplicated
-    // between BufferStateLayer and BufferQueueLayer for binding an external
-    // texture.
-
-    // TODO(alecmouri): Add API to help with managing a texture pool.
+protected:
+    // Gets a framebuffer to render to. This framebuffer may or may not be
+    // cached depending on the implementation.
+    //
+    // Note that this method does not transfer ownership, so the caller most not
+    // live longer than RenderEngine.
+    virtual Framebuffer* getFramebufferForDrawing() = 0;
+    friend class BindNativeBufferAsFramebuffer;
 };
 
 class BindNativeBufferAsFramebuffer {
 public:
     BindNativeBufferAsFramebuffer(RenderEngine& engine, ANativeWindowBuffer* buffer)
-          : mEngine(engine), mFramebuffer(mEngine.createFramebuffer()), mStatus(NO_ERROR) {
+          : mEngine(engine), mFramebuffer(mEngine.getFramebufferForDrawing()), mStatus(NO_ERROR) {
         mStatus = mFramebuffer->setNativeWindowBuffer(buffer, mEngine.isProtected())
-                ? mEngine.bindFrameBuffer(mFramebuffer.get())
+                ? mEngine.bindFrameBuffer(mFramebuffer)
                 : NO_MEMORY;
     }
     ~BindNativeBufferAsFramebuffer() {
         mFramebuffer->setNativeWindowBuffer(nullptr, false);
-        mEngine.unbindFrameBuffer(mFramebuffer.get());
+        mEngine.unbindFrameBuffer(mFramebuffer);
     }
     status_t getStatus() const { return mStatus; }
 
 private:
     RenderEngine& mEngine;
-    std::unique_ptr<Framebuffer> mFramebuffer;
+    Framebuffer* mFramebuffer;
     status_t mStatus;
 };
 
diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h
index b4c7c96..800eac3 100644
--- a/libs/renderengine/include/renderengine/mock/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h
@@ -36,6 +36,7 @@
 
     MOCK_METHOD0(createFramebuffer, std::unique_ptr<renderengine::Framebuffer>());
     MOCK_METHOD0(createImage, std::unique_ptr<renderengine::Image>());
+    MOCK_METHOD0(getFramebufferForDrawing, Framebuffer*());
     MOCK_CONST_METHOD0(primeCache, void());
     MOCK_METHOD1(dump, void(std::string&));
     MOCK_CONST_METHOD0(useNativeFenceSync, bool());
@@ -52,6 +53,7 @@
     MOCK_METHOD2(genTextures, void(size_t, uint32_t*));
     MOCK_METHOD2(deleteTextures, void(size_t, uint32_t const*));
     MOCK_METHOD2(bindExternalTextureImage, void(uint32_t, const renderengine::Image&));
+    MOCK_METHOD4(bindExternalTextureBuffer, status_t(uint32_t, sp<GraphicBuffer>, sp<Fence>, bool));
     MOCK_CONST_METHOD0(checkErrors, void());
     MOCK_METHOD4(setViewportAndProjection,
                  void(size_t, size_t, Rect, ui::Transform::orientation_flags));
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index bef25a8..f82beeb 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -178,6 +178,9 @@
     template <typename SourceVariant>
     void fillBufferWithRoundedCorners();
 
+    template <typename SourceVariant>
+    void overlayCorners();
+
     void fillRedBufferTextureTransform();
 
     void fillBufferTextureTransform();
@@ -194,7 +197,7 @@
 
     void clearLeftRegion();
 
-    void fillBufferThenClearRegion();
+    void clearRegion();
 
     // Dumb hack to get aroud the fact that tear-down for renderengine isn't
     // well defined right now, so we can't create multiple instances
@@ -543,6 +546,44 @@
                       255);
 }
 
+template <typename SourceVariant>
+void RenderEngineTest::overlayCorners() {
+    renderengine::DisplaySettings settings;
+    settings.physicalDisplay = fullscreenRect();
+    settings.clip = fullscreenRect();
+
+    std::vector<renderengine::LayerSettings> layersFirst;
+
+    renderengine::LayerSettings layerOne;
+    layerOne.geometry.boundaries =
+            FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
+    SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
+    layerOne.alpha = 0.2;
+
+    layersFirst.push_back(layerOne);
+    invokeDraw(settings, layersFirst, mBuffer);
+    expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
+    expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
+                           DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
+                      0, 0, 0, 0);
+
+    std::vector<renderengine::LayerSettings> layersSecond;
+    renderengine::LayerSettings layerTwo;
+    layerTwo.geometry.boundaries =
+            FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
+                      DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
+    SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
+    layerTwo.alpha = 1.0f;
+
+    layersSecond.push_back(layerTwo);
+    invokeDraw(settings, layersSecond, mBuffer);
+
+    expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
+    expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
+                           DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
+                      0, 255, 0, 255);
+}
+
 void RenderEngineTest::fillRedBufferTextureTransform() {
     renderengine::DisplaySettings settings;
     settings.physicalDisplay = fullscreenRect();
@@ -685,14 +726,13 @@
     invokeDraw(settings, layers, mBuffer);
 }
 
-void RenderEngineTest::fillBufferThenClearRegion() {
-    fillGreenBuffer<ColorSourceVariant>();
+void RenderEngineTest::clearRegion() {
     // Reuse mBuffer
     clearLeftRegion();
     expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 255);
     expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
                            DEFAULT_DISPLAY_HEIGHT),
-                      0, 255, 0, 255);
+                      0, 0, 0, 0);
 }
 
 TEST_F(RenderEngineTest, drawLayers_noLayersToDraw) {
@@ -747,6 +787,10 @@
     fillBufferWithRoundedCorners<ColorSourceVariant>();
 }
 
+TEST_F(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
+    overlayCorners<ColorSourceVariant>();
+}
+
 TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
     fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
 }
@@ -795,6 +839,10 @@
     fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
 }
 
+TEST_F(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
+    overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
 TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
     fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
 }
@@ -843,6 +891,10 @@
     fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
 }
 
+TEST_F(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
+    overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
 TEST_F(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
     fillBufferTextureTransform();
 }
@@ -855,8 +907,8 @@
     fillBufferWithoutPremultiplyAlpha();
 }
 
-TEST_F(RenderEngineTest, drawLayers_fillBufferThenClearRegion) {
-    fillBufferThenClearRegion();
+TEST_F(RenderEngineTest, drawLayers_clearRegion) {
+    clearRegion();
 }
 
 } // namespace android
diff --git a/libs/ui/BufferHubBuffer.cpp b/libs/ui/BufferHubBuffer.cpp
index 4b20772..7693fcb 100644
--- a/libs/ui/BufferHubBuffer.cpp
+++ b/libs/ui/BufferHubBuffer.cpp
@@ -24,12 +24,12 @@
 #include <utils/Trace.h>
 
 using ::android::base::unique_fd;
-using ::android::BufferHubDefs::AnyClientAcquired;
-using ::android::BufferHubDefs::AnyClientGained;
-using ::android::BufferHubDefs::IsClientAcquired;
-using ::android::BufferHubDefs::IsClientGained;
-using ::android::BufferHubDefs::IsClientPosted;
-using ::android::BufferHubDefs::IsClientReleased;
+using ::android::BufferHubDefs::isAnyClientAcquired;
+using ::android::BufferHubDefs::isAnyClientGained;
+using ::android::BufferHubDefs::isClientAcquired;
+using ::android::BufferHubDefs::isClientGained;
+using ::android::BufferHubDefs::isClientPosted;
+using ::android::BufferHubDefs::isClientReleased;
 using ::android::frameworks::bufferhub::V1_0::BufferHubStatus;
 using ::android::frameworks::bufferhub::V1_0::BufferTraits;
 using ::android::frameworks::bufferhub::V1_0::IBufferClient;
@@ -39,22 +39,22 @@
 
 namespace android {
 
-std::unique_ptr<BufferHubBuffer> BufferHubBuffer::Create(uint32_t width, uint32_t height,
+std::unique_ptr<BufferHubBuffer> BufferHubBuffer::create(uint32_t width, uint32_t height,
                                                          uint32_t layerCount, uint32_t format,
                                                          uint64_t usage, size_t userMetadataSize) {
     auto buffer = std::unique_ptr<BufferHubBuffer>(
             new BufferHubBuffer(width, height, layerCount, format, usage, userMetadataSize));
-    return buffer->IsValid() ? std::move(buffer) : nullptr;
+    return buffer->isValid() ? std::move(buffer) : nullptr;
 }
 
-std::unique_ptr<BufferHubBuffer> BufferHubBuffer::Import(const native_handle_t* token) {
+std::unique_ptr<BufferHubBuffer> BufferHubBuffer::import(const native_handle_t* token) {
     if (token == nullptr) {
         ALOGE("%s: token cannot be nullptr!", __FUNCTION__);
         return nullptr;
     }
 
     auto buffer = std::unique_ptr<BufferHubBuffer>(new BufferHubBuffer(token));
-    return buffer->IsValid() ? std::move(buffer) : nullptr;
+    return buffer->isValid() ? std::move(buffer) : nullptr;
 }
 
 BufferHubBuffer::BufferHubBuffer(uint32_t width, uint32_t height, uint32_t layerCount,
@@ -169,8 +169,8 @@
 
     // Import fds. Dup fds because hidl_handle owns the fds.
     unique_fd ashmemFd(fcntl(bufferTraits.bufferInfo->data[0], F_DUPFD_CLOEXEC, 0));
-    mMetadata = BufferHubMetadata::Import(std::move(ashmemFd));
-    if (!mMetadata.IsValid()) {
+    mMetadata = BufferHubMetadata::import(std::move(ashmemFd));
+    if (!mMetadata.isValid()) {
         ALOGE("%s: Received an invalid metadata.", __FUNCTION__);
         return -EINVAL;
     }
@@ -196,29 +196,29 @@
 
     uint32_t userMetadataSize;
     memcpy(&userMetadataSize, &bufferTraits.bufferInfo->data[4], sizeof(userMetadataSize));
-    if (mMetadata.user_metadata_size() != userMetadataSize) {
+    if (mMetadata.userMetadataSize() != userMetadataSize) {
         ALOGE("%s: user metadata size not match: expected %u, actual %zu.", __FUNCTION__,
-              userMetadataSize, mMetadata.user_metadata_size());
+              userMetadataSize, mMetadata.userMetadataSize());
         return -EINVAL;
     }
 
-    size_t metadataSize = static_cast<size_t>(mMetadata.metadata_size());
+    size_t metadataSize = static_cast<size_t>(mMetadata.metadataSize());
     if (metadataSize < BufferHubDefs::kMetadataHeaderSize) {
         ALOGE("%s: metadata too small: %zu", __FUNCTION__, metadataSize);
         return -EINVAL;
     }
 
     // Populate shortcuts to the atomics in metadata.
-    auto metadata_header = mMetadata.metadata_header();
-    buffer_state_ = &metadata_header->buffer_state;
-    fence_state_ = &metadata_header->fence_state;
-    active_clients_bit_mask_ = &metadata_header->active_clients_bit_mask;
+    auto metadata_header = mMetadata.metadataHeader();
+    mBufferState = &metadata_header->buffer_state;
+    mFenceState = &metadata_header->fence_state;
+    mActiveClientsBitMask = &metadata_header->active_clients_bit_mask;
     // The C++ standard recommends (but does not require) that lock-free atomic operations are
     // also address-free, that is, suitable for communication between processes using shared
     // memory.
-    LOG_ALWAYS_FATAL_IF(!std::atomic_is_lock_free(buffer_state_) ||
-                                !std::atomic_is_lock_free(fence_state_) ||
-                                !std::atomic_is_lock_free(active_clients_bit_mask_),
+    LOG_ALWAYS_FATAL_IF(!std::atomic_is_lock_free(mBufferState) ||
+                                !std::atomic_is_lock_free(mFenceState) ||
+                                !std::atomic_is_lock_free(mActiveClientsBitMask),
                         "Atomic variables in ashmen are not lock free.");
 
     // Import the buffer: We only need to hold on the native_handle_t here so that
@@ -231,104 +231,104 @@
 
     // TODO(b/112012161) Set up shared fences.
     ALOGD("%s: id=%d, buffer_state=%" PRIx32 ".", __FUNCTION__, mId,
-          buffer_state_->load(std::memory_order_acquire));
+          mBufferState->load(std::memory_order_acquire));
     return 0;
 }
 
-int BufferHubBuffer::Gain() {
-    uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
-    if (IsClientGained(current_buffer_state, mClientStateMask)) {
+int BufferHubBuffer::gain() {
+    uint32_t currentBufferState = mBufferState->load(std::memory_order_acquire);
+    if (isClientGained(currentBufferState, mClientStateMask)) {
         ALOGV("%s: Buffer is already gained by this client %" PRIx32 ".", __FUNCTION__,
               mClientStateMask);
         return 0;
     }
     do {
-        if (AnyClientGained(current_buffer_state & (~mClientStateMask)) ||
-            AnyClientAcquired(current_buffer_state)) {
+        if (isAnyClientGained(currentBufferState & (~mClientStateMask)) ||
+            isAnyClientAcquired(currentBufferState)) {
             ALOGE("%s: Buffer is in use, id=%d mClientStateMask=%" PRIx32 " state=%" PRIx32 ".",
-                  __FUNCTION__, mId, mClientStateMask, current_buffer_state);
+                  __FUNCTION__, mId, mClientStateMask, currentBufferState);
             return -EBUSY;
         }
         // Change the buffer state to gained state, whose value happens to be the same as
         // mClientStateMask.
-    } while (!buffer_state_->compare_exchange_weak(current_buffer_state, mClientStateMask,
-                                                   std::memory_order_acq_rel,
-                                                   std::memory_order_acquire));
+    } while (!mBufferState->compare_exchange_weak(currentBufferState, mClientStateMask,
+                                                  std::memory_order_acq_rel,
+                                                  std::memory_order_acquire));
     // TODO(b/119837586): Update fence state and return GPU fence.
     return 0;
 }
 
-int BufferHubBuffer::Post() {
-    uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
-    uint32_t updated_buffer_state = (~mClientStateMask) & BufferHubDefs::kHighBitsMask;
+int BufferHubBuffer::post() {
+    uint32_t currentBufferState = mBufferState->load(std::memory_order_acquire);
+    uint32_t updatedBufferState = (~mClientStateMask) & BufferHubDefs::kHighBitsMask;
     do {
-        if (!IsClientGained(current_buffer_state, mClientStateMask)) {
+        if (!isClientGained(currentBufferState, mClientStateMask)) {
             ALOGE("%s: Cannot post a buffer that is not gained by this client. buffer_id=%d "
                   "mClientStateMask=%" PRIx32 " state=%" PRIx32 ".",
-                  __FUNCTION__, mId, mClientStateMask, current_buffer_state);
+                  __FUNCTION__, mId, mClientStateMask, currentBufferState);
             return -EBUSY;
         }
         // Set the producer client buffer state to released, other clients' buffer state to posted.
         // Post to all existing and non-existing clients.
-    } while (!buffer_state_->compare_exchange_weak(current_buffer_state, updated_buffer_state,
-                                                   std::memory_order_acq_rel,
-                                                   std::memory_order_acquire));
+    } while (!mBufferState->compare_exchange_weak(currentBufferState, updatedBufferState,
+                                                  std::memory_order_acq_rel,
+                                                  std::memory_order_acquire));
     // TODO(b/119837586): Update fence state and return GPU fence if needed.
     return 0;
 }
 
-int BufferHubBuffer::Acquire() {
-    uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
-    if (IsClientAcquired(current_buffer_state, mClientStateMask)) {
+int BufferHubBuffer::acquire() {
+    uint32_t currentBufferState = mBufferState->load(std::memory_order_acquire);
+    if (isClientAcquired(currentBufferState, mClientStateMask)) {
         ALOGV("%s: Buffer is already acquired by this client %" PRIx32 ".", __FUNCTION__,
               mClientStateMask);
         return 0;
     }
-    uint32_t updated_buffer_state = 0U;
+    uint32_t updatedBufferState = 0U;
     do {
-        if (!IsClientPosted(current_buffer_state, mClientStateMask)) {
+        if (!isClientPosted(currentBufferState, mClientStateMask)) {
             ALOGE("%s: Cannot acquire a buffer that is not in posted state. buffer_id=%d "
                   "mClientStateMask=%" PRIx32 " state=%" PRIx32 ".",
-                  __FUNCTION__, mId, mClientStateMask, current_buffer_state);
+                  __FUNCTION__, mId, mClientStateMask, currentBufferState);
             return -EBUSY;
         }
         // Change the buffer state for this consumer from posted to acquired.
-        updated_buffer_state = current_buffer_state ^ mClientStateMask;
-    } while (!buffer_state_->compare_exchange_weak(current_buffer_state, updated_buffer_state,
-                                                   std::memory_order_acq_rel,
-                                                   std::memory_order_acquire));
+        updatedBufferState = currentBufferState ^ mClientStateMask;
+    } while (!mBufferState->compare_exchange_weak(currentBufferState, updatedBufferState,
+                                                  std::memory_order_acq_rel,
+                                                  std::memory_order_acquire));
     // TODO(b/119837586): Update fence state and return GPU fence.
     return 0;
 }
 
-int BufferHubBuffer::Release() {
-    uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
-    if (IsClientReleased(current_buffer_state, mClientStateMask)) {
+int BufferHubBuffer::release() {
+    uint32_t currentBufferState = mBufferState->load(std::memory_order_acquire);
+    if (isClientReleased(currentBufferState, mClientStateMask)) {
         ALOGV("%s: Buffer is already released by this client %" PRIx32 ".", __FUNCTION__,
               mClientStateMask);
         return 0;
     }
-    uint32_t updated_buffer_state = 0U;
+    uint32_t updatedBufferState = 0U;
     do {
-        updated_buffer_state = current_buffer_state & (~mClientStateMask);
-    } while (!buffer_state_->compare_exchange_weak(current_buffer_state, updated_buffer_state,
-                                                   std::memory_order_acq_rel,
-                                                   std::memory_order_acquire));
+        updatedBufferState = currentBufferState & (~mClientStateMask);
+    } while (!mBufferState->compare_exchange_weak(currentBufferState, updatedBufferState,
+                                                  std::memory_order_acq_rel,
+                                                  std::memory_order_acquire));
     // TODO(b/119837586): Update fence state and return GPU fence if needed.
     return 0;
 }
 
-bool BufferHubBuffer::IsReleased() const {
-    return (buffer_state_->load(std::memory_order_acquire) &
-            active_clients_bit_mask_->load(std::memory_order_acquire)) == 0;
+bool BufferHubBuffer::isReleased() const {
+    return (mBufferState->load(std::memory_order_acquire) &
+            mActiveClientsBitMask->load(std::memory_order_acquire)) == 0;
 }
 
-bool BufferHubBuffer::IsValid() const {
+bool BufferHubBuffer::isValid() const {
     return mBufferHandle.getNativeHandle() != nullptr && mId >= 0 && mClientStateMask != 0U &&
-            mEventFd.get() >= 0 && mMetadata.IsValid() && mBufferClient != nullptr;
+            mEventFd.get() >= 0 && mMetadata.isValid() && mBufferClient != nullptr;
 }
 
-native_handle_t* BufferHubBuffer::Duplicate() {
+native_handle_t* BufferHubBuffer::duplicate() {
     if (mBufferClient == nullptr) {
         ALOGE("%s: missing BufferClient!", __FUNCTION__);
         return nullptr;
diff --git a/libs/ui/BufferHubMetadata.cpp b/libs/ui/BufferHubMetadata.cpp
index 816707d..05bc7dd 100644
--- a/libs/ui/BufferHubMetadata.cpp
+++ b/libs/ui/BufferHubMetadata.cpp
@@ -34,7 +34,7 @@
 using BufferHubDefs::MetadataHeader;
 
 /* static */
-BufferHubMetadata BufferHubMetadata::Create(size_t userMetadataSize) {
+BufferHubMetadata BufferHubMetadata::create(size_t userMetadataSize) {
     // The size the of metadata buffer is used as the "width" parameter during allocation. Thus it
     // cannot overflow uint32_t.
     if (userMetadataSize >= (std::numeric_limits<uint32_t>::max() - kMetadataHeaderSize)) {
@@ -59,11 +59,11 @@
         return {};
     }
 
-    return BufferHubMetadata::Import(std::move(ashmemFd));
+    return BufferHubMetadata::import(std::move(ashmemFd));
 }
 
 /* static */
-BufferHubMetadata BufferHubMetadata::Import(unique_fd ashmemFd) {
+BufferHubMetadata BufferHubMetadata::import(unique_fd ashmemFd) {
     if (!ashmem_valid(ashmemFd.get())) {
         ALOGE("BufferHubMetadata::Import: invalid ashmem fd.");
         return {};
@@ -94,7 +94,7 @@
 
 BufferHubMetadata::~BufferHubMetadata() {
     if (mMetadataHeader != nullptr) {
-        int ret = munmap(mMetadataHeader, metadata_size());
+        int ret = munmap(mMetadataHeader, metadataSize());
         ALOGE_IF(ret != 0,
                  "BufferHubMetadata::~BufferHubMetadata: failed to unmap ashmem, error=%d.", errno);
         mMetadataHeader = nullptr;
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index e678c58..f487dfa 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -100,7 +100,7 @@
         return;
     }
 
-    mInitCheck = initWithHandle(buffer->DuplicateHandle(), /*method=*/TAKE_UNREGISTERED_HANDLE,
+    mInitCheck = initWithHandle(buffer->duplicateHandle(), /*method=*/TAKE_UNREGISTERED_HANDLE,
                                 buffer->desc().width, buffer->desc().height,
                                 static_cast<PixelFormat>(buffer->desc().format),
                                 buffer->desc().layers, buffer->desc().usage, buffer->desc().stride);
@@ -286,22 +286,22 @@
     return res;
 }
 
-status_t GraphicBuffer::lockAsync(uint32_t inUsage, void** vaddr, int fenceFd)
-{
+status_t GraphicBuffer::lockAsync(uint32_t inUsage, void** vaddr, int fenceFd,
+                                  int32_t* outBytesPerPixel, int32_t* outBytesPerStride) {
     const Rect lockBounds(width, height);
-    status_t res = lockAsync(inUsage, lockBounds, vaddr, fenceFd);
+    status_t res =
+            lockAsync(inUsage, lockBounds, vaddr, fenceFd, outBytesPerPixel, outBytesPerStride);
     return res;
 }
 
-status_t GraphicBuffer::lockAsync(uint32_t inUsage, const Rect& rect,
-        void** vaddr, int fenceFd)
-{
-    return lockAsync(inUsage, inUsage, rect, vaddr, fenceFd);
+status_t GraphicBuffer::lockAsync(uint32_t inUsage, const Rect& rect, void** vaddr, int fenceFd,
+                                  int32_t* outBytesPerPixel, int32_t* outBytesPerStride) {
+    return lockAsync(inUsage, inUsage, rect, vaddr, fenceFd, outBytesPerPixel, outBytesPerStride);
 }
 
-status_t GraphicBuffer::lockAsync(uint64_t inProducerUsage,
-        uint64_t inConsumerUsage, const Rect& rect, void** vaddr, int fenceFd)
-{
+status_t GraphicBuffer::lockAsync(uint64_t inProducerUsage, uint64_t inConsumerUsage,
+                                  const Rect& rect, void** vaddr, int fenceFd,
+                                  int32_t* outBytesPerPixel, int32_t* outBytesPerStride) {
     if (rect.left < 0 || rect.right  > width ||
         rect.top  < 0 || rect.bottom > height) {
         ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)",
@@ -310,9 +310,9 @@
         return BAD_VALUE;
     }
 
-    int32_t bytesPerPixel, bytesPerStride;
     status_t res = getBufferMapper().lockAsync(handle, inProducerUsage, inConsumerUsage, rect,
-                                               vaddr, fenceFd, &bytesPerPixel, &bytesPerStride);
+                                               vaddr, fenceFd, outBytesPerPixel, outBytesPerStride);
+
     return res;
 }
 
diff --git a/libs/ui/include/ui/BufferHubBuffer.h b/libs/ui/include/ui/BufferHubBuffer.h
index 0b6d75a..eac8c84 100644
--- a/libs/ui/include/ui/BufferHubBuffer.h
+++ b/libs/ui/include/ui/BufferHubBuffer.h
@@ -29,14 +29,14 @@
 class BufferHubBuffer {
 public:
     // Allocates a standalone BufferHubBuffer.
-    static std::unique_ptr<BufferHubBuffer> Create(uint32_t width, uint32_t height,
+    static std::unique_ptr<BufferHubBuffer> create(uint32_t width, uint32_t height,
                                                    uint32_t layerCount, uint32_t format,
                                                    uint64_t usage, size_t userMetadataSize);
 
     // Imports the given token to a BufferHubBuffer. Not taking ownership of the token. Caller
     // should close and destroy the token after calling this function regardless of output.
     // TODO(b/122543147): use a movable wrapper for token
-    static std::unique_ptr<BufferHubBuffer> Import(const native_handle_t* token);
+    static std::unique_ptr<BufferHubBuffer> import(const native_handle_t* token);
 
     BufferHubBuffer(const BufferHubBuffer&) = delete;
     void operator=(const BufferHubBuffer&) = delete;
@@ -52,51 +52,51 @@
 
     // Duplicate the underlying Gralloc buffer handle. Caller is responsible to free the handle
     // after use.
-    native_handle_t* DuplicateHandle() {
+    native_handle_t* duplicateHandle() {
         return native_handle_clone(mBufferHandle.getNativeHandle());
     }
 
     const BufferHubEventFd& eventFd() const { return mEventFd; }
 
     // Returns the current value of MetadataHeader::buffer_state.
-    uint32_t buffer_state() const { return buffer_state_->load(std::memory_order_acquire); }
+    uint32_t bufferState() const { return mBufferState->load(std::memory_order_acquire); }
 
     // A state mask which is unique to a buffer hub client among all its siblings sharing the same
     // concrete graphic buffer.
-    uint32_t client_state_mask() const { return mClientStateMask; }
+    uint32_t clientStateMask() const { return mClientStateMask; }
 
-    size_t user_metadata_size() const { return mMetadata.user_metadata_size(); }
+    size_t userMetadataSize() const { return mMetadata.userMetadataSize(); }
 
     // Returns true if the BufferClient is still alive.
-    bool IsConnected() const { return mBufferClient->ping().isOk(); }
+    bool isConnected() const { return mBufferClient->ping().isOk(); }
 
     // Returns true if the buffer is valid: non-null buffer handle, valid id, valid client bit mask,
     // valid metadata and valid buffer client
-    bool IsValid() const;
+    bool isValid() const;
 
     // Gains the buffer for exclusive write permission. Read permission is implied once a buffer is
     // gained.
     // The buffer can be gained as long as there is no other client in acquired or gained state.
-    int Gain();
+    int gain();
 
     // Posts the gained buffer for other buffer clients to use the buffer.
     // The buffer can be posted iff the buffer state for this client is gained.
     // After posting the buffer, this client is put to released state and does not have access to
     // the buffer for this cycle of the usage of the buffer.
-    int Post();
+    int post();
 
     // Acquires the buffer for shared read permission.
     // The buffer can be acquired iff the buffer state for this client is posted.
-    int Acquire();
+    int acquire();
 
     // Releases the buffer.
     // The buffer can be released from any buffer state.
     // After releasing the buffer, this client no longer have any permissions to the buffer for the
     // current cycle of the usage of the buffer.
-    int Release();
+    int release();
 
     // Returns whether the buffer is released by all active clients or not.
-    bool IsReleased() const;
+    bool isReleased() const;
 
     // Creates a token that stands for this BufferHubBuffer client and could be used for Import to
     // create another BufferHubBuffer. The new BufferHubBuffer will share the same underlying
@@ -104,7 +104,7 @@
     // should free it after use.
     // Returns a valid token on success, nullptr on failure.
     // TODO(b/122543147): use a movable wrapper for token
-    native_handle_t* Duplicate();
+    native_handle_t* duplicate();
 
 private:
     BufferHubBuffer(uint32_t width, uint32_t height, uint32_t layerCount, uint32_t format,
@@ -134,9 +134,9 @@
     // bufferhubd daemon and all buffer clients.
     BufferHubMetadata mMetadata;
     // Shortcuts to the atomics inside the header of mMetadata.
-    std::atomic<uint32_t>* buffer_state_ = nullptr;
-    std::atomic<uint32_t>* fence_state_ = nullptr;
-    std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;
+    std::atomic<uint32_t>* mBufferState = nullptr;
+    std::atomic<uint32_t>* mFenceState = nullptr;
+    std::atomic<uint32_t>* mActiveClientsBitMask = nullptr;
 
     // HwBinder backend
     sp<frameworks::bufferhub::V1_0::IBufferClient> mBufferClient;
diff --git a/libs/ui/include/ui/BufferHubDefs.h b/libs/ui/include/ui/BufferHubDefs.h
index ff970cb..722a060 100644
--- a/libs/ui/include/ui/BufferHubDefs.h
+++ b/libs/ui/include/ui/BufferHubDefs.h
@@ -63,19 +63,19 @@
 static constexpr uint32_t kFirstClientBitMask = (1U << kMaxNumberOfClients) + 1U;
 
 // Returns true if any of the client is in gained state.
-static inline bool AnyClientGained(uint32_t state) {
+static inline bool isAnyClientGained(uint32_t state) {
     uint32_t high_bits = state >> kMaxNumberOfClients;
     uint32_t low_bits = state & kLowbitsMask;
     return high_bits == low_bits && low_bits != 0U;
 }
 
 // Returns true if the input client is in gained state.
-static inline bool IsClientGained(uint32_t state, uint32_t client_bit_mask) {
+static inline bool isClientGained(uint32_t state, uint32_t client_bit_mask) {
     return state == client_bit_mask;
 }
 
 // Returns true if any of the client is in posted state.
-static inline bool AnyClientPosted(uint32_t state) {
+static inline bool isAnyClientPosted(uint32_t state) {
     uint32_t high_bits = state >> kMaxNumberOfClients;
     uint32_t low_bits = state & kLowbitsMask;
     uint32_t posted_or_acquired = high_bits ^ low_bits;
@@ -83,7 +83,7 @@
 }
 
 // Returns true if the input client is in posted state.
-static inline bool IsClientPosted(uint32_t state, uint32_t client_bit_mask) {
+static inline bool isClientPosted(uint32_t state, uint32_t client_bit_mask) {
     uint32_t client_bits = state & client_bit_mask;
     if (client_bits == 0U) return false;
     uint32_t low_bits = client_bits & kLowbitsMask;
@@ -91,7 +91,7 @@
 }
 
 // Return true if any of the client is in acquired state.
-static inline bool AnyClientAcquired(uint32_t state) {
+static inline bool isAnyClientAcquired(uint32_t state) {
     uint32_t high_bits = state >> kMaxNumberOfClients;
     uint32_t low_bits = state & kLowbitsMask;
     uint32_t posted_or_acquired = high_bits ^ low_bits;
@@ -99,7 +99,7 @@
 }
 
 // Return true if the input client is in acquired state.
-static inline bool IsClientAcquired(uint32_t state, uint32_t client_bit_mask) {
+static inline bool isClientAcquired(uint32_t state, uint32_t client_bit_mask) {
     uint32_t client_bits = state & client_bit_mask;
     if (client_bits == 0U) return false;
     uint32_t high_bits = client_bits & kHighBitsMask;
@@ -107,13 +107,13 @@
 }
 
 // Returns true if the input client is in released state.
-static inline bool IsClientReleased(uint32_t state, uint32_t client_bit_mask) {
+static inline bool isClientReleased(uint32_t state, uint32_t client_bit_mask) {
     return (state & client_bit_mask) == 0U;
 }
 
 // Returns the next available buffer client's client_state_masks.
 // @params union_bits. Union of all existing clients' client_state_masks.
-static inline uint32_t FindNextAvailableClientStateMask(uint32_t union_bits) {
+static inline uint32_t findNextAvailableClientStateMask(uint32_t union_bits) {
     uint32_t low_union = union_bits & kLowbitsMask;
     if (low_union == kLowbitsMask) return 0U;
     uint32_t incremented = low_union + 1U;
diff --git a/libs/ui/include/ui/BufferHubMetadata.h b/libs/ui/include/ui/BufferHubMetadata.h
index 2121894..3482507 100644
--- a/libs/ui/include/ui/BufferHubMetadata.h
+++ b/libs/ui/include/ui/BufferHubMetadata.h
@@ -33,12 +33,12 @@
     // @param userMetadataSize Size in bytes of the user defined metadata. The entire metadata
     //        shared memory region to be allocated is the size of canonical
     //        BufferHubDefs::MetadataHeader plus userMetadataSize.
-    static BufferHubMetadata Create(size_t userMetadataSize);
+    static BufferHubMetadata create(size_t userMetadataSize);
 
     // Imports an existing BufferHubMetadata from an ashmem FD.
     //
     // @param ashmemFd Ashmem file descriptor representing an ashmem region.
-    static BufferHubMetadata Import(unique_fd ashmemFd);
+    static BufferHubMetadata import(unique_fd ashmemFd);
 
     BufferHubMetadata() = default;
 
@@ -63,13 +63,13 @@
 
     // Returns true if the metadata is valid, i.e. the metadata has a valid ashmem fd and the ashmem
     // has been mapped into virtual address space.
-    bool IsValid() const { return mAshmemFd.get() != -1 && mMetadataHeader != nullptr; }
+    bool isValid() const { return mAshmemFd.get() != -1 && mMetadataHeader != nullptr; }
 
-    size_t user_metadata_size() const { return mUserMetadataSize; }
-    size_t metadata_size() const { return mUserMetadataSize + BufferHubDefs::kMetadataHeaderSize; }
+    size_t userMetadataSize() const { return mUserMetadataSize; }
+    size_t metadataSize() const { return mUserMetadataSize + BufferHubDefs::kMetadataHeaderSize; }
 
-    const unique_fd& ashmem_fd() const { return mAshmemFd; }
-    BufferHubDefs::MetadataHeader* metadata_header() { return mMetadataHeader; }
+    const unique_fd& ashmemFd() const { return mAshmemFd; }
+    BufferHubDefs::MetadataHeader* metadataHeader() { return mMetadataHeader; }
 
 private:
     BufferHubMetadata(size_t userMetadataSize, unique_fd ashmemFd,
diff --git a/libs/ui/include/ui/GraphicBuffer.h b/libs/ui/include/ui/GraphicBuffer.h
index 7d88c58..4d4ee68 100644
--- a/libs/ui/include/ui/GraphicBuffer.h
+++ b/libs/ui/include/ui/GraphicBuffer.h
@@ -180,11 +180,15 @@
     status_t lockYCbCr(uint32_t inUsage, const Rect& rect,
             android_ycbcr *ycbcr);
     status_t unlock();
-    status_t lockAsync(uint32_t inUsage, void** vaddr, int fenceFd);
-    status_t lockAsync(uint32_t inUsage, const Rect& rect, void** vaddr,
-            int fenceFd);
-    status_t lockAsync(uint64_t inProducerUsage, uint64_t inConsumerUsage,
-            const Rect& rect, void** vaddr, int fenceFd);
+    // For the following three lockAsync functions, if bytesPerStride or bytesPerPixel
+    // are unknown or variable, -1 will be returned
+    status_t lockAsync(uint32_t inUsage, void** vaddr, int fenceFd,
+                       int32_t* outBytesPerPixel = nullptr, int32_t* outBytesPerStride = nullptr);
+    status_t lockAsync(uint32_t inUsage, const Rect& rect, void** vaddr, int fenceFd,
+                       int32_t* outBytesPerPixel = nullptr, int32_t* outBytesPerStride = nullptr);
+    status_t lockAsync(uint64_t inProducerUsage, uint64_t inConsumerUsage, const Rect& rect,
+                       void** vaddr, int fenceFd, int32_t* outBytesPerPixel = nullptr,
+                       int32_t* outBytesPerStride = nullptr);
     status_t lockAsyncYCbCr(uint32_t inUsage, android_ycbcr *ycbcr,
             int fenceFd);
     status_t lockAsyncYCbCr(uint32_t inUsage, const Rect& rect,
diff --git a/libs/ui/tests/BufferHubBuffer_test.cpp b/libs/ui/tests/BufferHubBuffer_test.cpp
index 3bcd935..3087a90 100644
--- a/libs/ui/tests/BufferHubBuffer_test.cpp
+++ b/libs/ui/tests/BufferHubBuffer_test.cpp
@@ -32,13 +32,13 @@
 
 namespace {
 
-using ::android::BufferHubDefs::AnyClientAcquired;
-using ::android::BufferHubDefs::AnyClientGained;
-using ::android::BufferHubDefs::AnyClientPosted;
-using ::android::BufferHubDefs::IsClientAcquired;
-using ::android::BufferHubDefs::IsClientGained;
-using ::android::BufferHubDefs::IsClientPosted;
-using ::android::BufferHubDefs::IsClientReleased;
+using ::android::BufferHubDefs::isAnyClientAcquired;
+using ::android::BufferHubDefs::isAnyClientGained;
+using ::android::BufferHubDefs::isAnyClientPosted;
+using ::android::BufferHubDefs::isClientAcquired;
+using ::android::BufferHubDefs::isClientGained;
+using ::android::BufferHubDefs::isClientPosted;
+using ::android::BufferHubDefs::isClientReleased;
 using ::android::BufferHubDefs::kMetadataHeaderSize;
 using ::testing::IsNull;
 using ::testing::NotNull;
@@ -81,88 +81,88 @@
 };
 
 void BufferHubBufferStateTransitionTest::CreateTwoClientsOfABuffer() {
-    b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage, kUserMetadataSize);
+    b1 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage, kUserMetadataSize);
     ASSERT_THAT(b1, NotNull());
-    b1ClientMask = b1->client_state_mask();
+    b1ClientMask = b1->clientStateMask();
     ASSERT_NE(b1ClientMask, 0U);
 
-    native_handle_t* token = b1->Duplicate();
+    native_handle_t* token = b1->duplicate();
     ASSERT_THAT(token, NotNull());
 
     // TODO(b/122543147): use a movalbe wrapper for token
-    b2 = BufferHubBuffer::Import(token);
+    b2 = BufferHubBuffer::import(token);
     native_handle_close(token);
     native_handle_delete(token);
     ASSERT_THAT(b2, NotNull());
 
-    b2ClientMask = b2->client_state_mask();
+    b2ClientMask = b2->clientStateMask();
     ASSERT_NE(b2ClientMask, 0U);
     ASSERT_NE(b2ClientMask, b1ClientMask);
 }
 
 TEST_F(BufferHubBufferTest, CreateBufferFails) {
     // Buffer Creation will fail: BLOB format requires height to be 1.
-    auto b1 = BufferHubBuffer::Create(kWidth, /*height=*/2, kLayerCount,
+    auto b1 = BufferHubBuffer::create(kWidth, /*height=*/2, kLayerCount,
                                       /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage, kUserMetadataSize);
 
     EXPECT_THAT(b1, IsNull());
 
     // Buffer Creation will fail: user metadata size too large.
-    auto b2 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
+    auto b2 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
                                       /*userMetadataSize=*/std::numeric_limits<size_t>::max());
 
     EXPECT_THAT(b2, IsNull());
 
     // Buffer Creation will fail: user metadata size too large.
     const size_t userMetadataSize = std::numeric_limits<size_t>::max() - kMetadataHeaderSize;
-    auto b3 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
+    auto b3 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
                                       userMetadataSize);
 
     EXPECT_THAT(b3, IsNull());
 }
 
 TEST_F(BufferHubBufferTest, CreateBuffer) {
-    auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
+    auto b1 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
                                       kUserMetadataSize);
     ASSERT_THAT(b1, NotNull());
-    EXPECT_TRUE(b1->IsConnected());
-    EXPECT_TRUE(b1->IsValid());
+    EXPECT_TRUE(b1->isConnected());
+    EXPECT_TRUE(b1->isValid());
     EXPECT_TRUE(cmpAHardwareBufferDesc(b1->desc(), kDesc));
-    EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
+    EXPECT_EQ(b1->userMetadataSize(), kUserMetadataSize);
 }
 
 TEST_F(BufferHubBufferTest, DuplicateAndImportBuffer) {
-    auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
+    auto b1 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
                                       kUserMetadataSize);
     ASSERT_THAT(b1, NotNull());
-    EXPECT_TRUE(b1->IsValid());
+    EXPECT_TRUE(b1->isValid());
 
-    native_handle_t* token = b1->Duplicate();
+    native_handle_t* token = b1->duplicate();
     EXPECT_TRUE(token);
 
     // The detached buffer should still be valid.
-    EXPECT_TRUE(b1->IsConnected());
-    EXPECT_TRUE(b1->IsValid());
+    EXPECT_TRUE(b1->isConnected());
+    EXPECT_TRUE(b1->isValid());
 
-    std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(token);
+    std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::import(token);
     native_handle_close(token);
     native_handle_delete(token);
 
     ASSERT_THAT(b2, NotNull());
-    EXPECT_TRUE(b2->IsValid());
+    EXPECT_TRUE(b2->isValid());
 
     EXPECT_TRUE(cmpAHardwareBufferDesc(b1->desc(), b2->desc()));
-    EXPECT_EQ(b1->user_metadata_size(), b2->user_metadata_size());
+    EXPECT_EQ(b1->userMetadataSize(), b2->userMetadataSize());
 
     // These two buffer instances are based on the same physical buffer under the
     // hood, so they should share the same id.
     EXPECT_EQ(b1->id(), b2->id());
-    // We use client_state_mask() to tell those two instances apart.
-    EXPECT_NE(b1->client_state_mask(), b2->client_state_mask());
+    // We use clientStateMask() to tell those two instances apart.
+    EXPECT_NE(b1->clientStateMask(), b2->clientStateMask());
 
     // Both buffer instances should be in released state currently.
-    EXPECT_TRUE(b1->IsReleased());
-    EXPECT_TRUE(b2->IsReleased());
+    EXPECT_TRUE(b1->isReleased());
+    EXPECT_TRUE(b2->isReleased());
 
     // The event fd should behave like duped event fds.
     const BufferHubEventFd& eventFd1 = b1->eventFd();
@@ -192,19 +192,19 @@
 }
 
 TEST_F(BufferHubBufferTest, ImportFreedBuffer) {
-    auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
+    auto b1 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
                                       kUserMetadataSize);
     ASSERT_THAT(b1, NotNull());
-    EXPECT_TRUE(b1->IsValid());
+    EXPECT_TRUE(b1->isValid());
 
-    native_handle_t* token = b1->Duplicate();
+    native_handle_t* token = b1->duplicate();
     EXPECT_TRUE(token);
 
     // Explicitly destroy b1. Backend buffer should be freed and token becomes invalid
     b1.reset();
 
     // TODO(b/122543147): use a movalbe wrapper for token
-    std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(token);
+    std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::import(token);
     native_handle_close(token);
     native_handle_delete(token);
 
@@ -214,7 +214,7 @@
 
 // nullptr must not crash the service
 TEST_F(BufferHubBufferTest, ImportNullToken) {
-    auto b1 = BufferHubBuffer::Import(nullptr);
+    auto b1 = BufferHubBuffer::import(nullptr);
     EXPECT_THAT(b1, IsNull());
 }
 
@@ -222,185 +222,185 @@
     native_handle_t* token = native_handle_create(/*numFds=*/0, /*numInts=*/1);
     token->data[0] = 0;
 
-    auto b1 = BufferHubBuffer::Import(token);
+    auto b1 = BufferHubBuffer::import(token);
     native_handle_delete(token);
 
     EXPECT_THAT(b1, IsNull());
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromReleasedState) {
-    ASSERT_TRUE(b1->IsReleased());
+    ASSERT_TRUE(b1->isReleased());
 
     // Successful gaining the buffer should change the buffer state bit of b1 to
     // gained state, other client state bits to released state.
-    EXPECT_EQ(b1->Gain(), 0);
-    EXPECT_TRUE(IsClientGained(b1->buffer_state(), b1ClientMask));
+    EXPECT_EQ(b1->gain(), 0);
+    EXPECT_TRUE(isClientGained(b1->bufferState(), b1ClientMask));
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromGainedState) {
-    ASSERT_EQ(b1->Gain(), 0);
-    auto current_buffer_state = b1->buffer_state();
-    ASSERT_TRUE(IsClientGained(current_buffer_state, b1ClientMask));
+    ASSERT_EQ(b1->gain(), 0);
+    auto currentBufferState = b1->bufferState();
+    ASSERT_TRUE(isClientGained(currentBufferState, b1ClientMask));
 
     // Gaining from gained state by the same client should not return error.
-    EXPECT_EQ(b1->Gain(), 0);
+    EXPECT_EQ(b1->gain(), 0);
 
     // Gaining from gained state by another client should return error.
-    EXPECT_EQ(b2->Gain(), -EBUSY);
+    EXPECT_EQ(b2->gain(), -EBUSY);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromAcquiredState) {
-    ASSERT_EQ(b1->Gain(), 0);
-    ASSERT_EQ(b1->Post(), 0);
-    ASSERT_EQ(b2->Acquire(), 0);
-    ASSERT_TRUE(AnyClientAcquired(b1->buffer_state()));
+    ASSERT_EQ(b1->gain(), 0);
+    ASSERT_EQ(b1->post(), 0);
+    ASSERT_EQ(b2->acquire(), 0);
+    ASSERT_TRUE(isAnyClientAcquired(b1->bufferState()));
 
     // Gaining from acquired state should fail.
-    EXPECT_EQ(b1->Gain(), -EBUSY);
-    EXPECT_EQ(b2->Gain(), -EBUSY);
+    EXPECT_EQ(b1->gain(), -EBUSY);
+    EXPECT_EQ(b2->gain(), -EBUSY);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromOtherClientInPostedState) {
-    ASSERT_EQ(b1->Gain(), 0);
-    ASSERT_EQ(b1->Post(), 0);
-    ASSERT_TRUE(AnyClientPosted(b1->buffer_state()));
+    ASSERT_EQ(b1->gain(), 0);
+    ASSERT_EQ(b1->post(), 0);
+    ASSERT_TRUE(isAnyClientPosted(b1->bufferState()));
 
     // Gaining a buffer who has other posted client should succeed.
-    EXPECT_EQ(b1->Gain(), 0);
+    EXPECT_EQ(b1->gain(), 0);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromSelfInPostedState) {
-    ASSERT_EQ(b1->Gain(), 0);
-    ASSERT_EQ(b1->Post(), 0);
-    ASSERT_TRUE(AnyClientPosted(b1->buffer_state()));
+    ASSERT_EQ(b1->gain(), 0);
+    ASSERT_EQ(b1->post(), 0);
+    ASSERT_TRUE(isAnyClientPosted(b1->bufferState()));
 
     // A posted client should be able to gain the buffer when there is no other clients in
     // acquired state.
-    EXPECT_EQ(b2->Gain(), 0);
+    EXPECT_EQ(b2->gain(), 0);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromOtherInGainedState) {
-    ASSERT_EQ(b1->Gain(), 0);
-    ASSERT_TRUE(IsClientGained(b1->buffer_state(), b1ClientMask));
+    ASSERT_EQ(b1->gain(), 0);
+    ASSERT_TRUE(isClientGained(b1->bufferState(), b1ClientMask));
 
-    EXPECT_EQ(b2->Post(), -EBUSY);
+    EXPECT_EQ(b2->post(), -EBUSY);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromSelfInGainedState) {
-    ASSERT_EQ(b1->Gain(), 0);
-    ASSERT_TRUE(IsClientGained(b1->buffer_state(), b1ClientMask));
+    ASSERT_EQ(b1->gain(), 0);
+    ASSERT_TRUE(isClientGained(b1->bufferState(), b1ClientMask));
 
-    EXPECT_EQ(b1->Post(), 0);
-    auto current_buffer_state = b1->buffer_state();
-    EXPECT_TRUE(IsClientReleased(current_buffer_state, b1ClientMask));
-    EXPECT_TRUE(IsClientPosted(current_buffer_state, b2ClientMask));
+    EXPECT_EQ(b1->post(), 0);
+    auto currentBufferState = b1->bufferState();
+    EXPECT_TRUE(isClientReleased(currentBufferState, b1ClientMask));
+    EXPECT_TRUE(isClientPosted(currentBufferState, b2ClientMask));
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromPostedState) {
-    ASSERT_EQ(b1->Gain(), 0);
-    ASSERT_EQ(b1->Post(), 0);
-    ASSERT_TRUE(AnyClientPosted(b1->buffer_state()));
+    ASSERT_EQ(b1->gain(), 0);
+    ASSERT_EQ(b1->post(), 0);
+    ASSERT_TRUE(isAnyClientPosted(b1->bufferState()));
 
     // Post from posted state should fail.
-    EXPECT_EQ(b1->Post(), -EBUSY);
-    EXPECT_EQ(b2->Post(), -EBUSY);
+    EXPECT_EQ(b1->post(), -EBUSY);
+    EXPECT_EQ(b2->post(), -EBUSY);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromAcquiredState) {
-    ASSERT_EQ(b1->Gain(), 0);
-    ASSERT_EQ(b1->Post(), 0);
-    ASSERT_EQ(b2->Acquire(), 0);
-    ASSERT_TRUE(AnyClientAcquired(b1->buffer_state()));
+    ASSERT_EQ(b1->gain(), 0);
+    ASSERT_EQ(b1->post(), 0);
+    ASSERT_EQ(b2->acquire(), 0);
+    ASSERT_TRUE(isAnyClientAcquired(b1->bufferState()));
 
     // Posting from acquired state should fail.
-    EXPECT_EQ(b1->Post(), -EBUSY);
-    EXPECT_EQ(b2->Post(), -EBUSY);
+    EXPECT_EQ(b1->post(), -EBUSY);
+    EXPECT_EQ(b2->post(), -EBUSY);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromReleasedState) {
-    ASSERT_TRUE(b1->IsReleased());
+    ASSERT_TRUE(b1->isReleased());
 
     // Posting from released state should fail.
-    EXPECT_EQ(b1->Post(), -EBUSY);
-    EXPECT_EQ(b2->Post(), -EBUSY);
+    EXPECT_EQ(b1->post(), -EBUSY);
+    EXPECT_EQ(b2->post(), -EBUSY);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromSelfInPostedState) {
-    ASSERT_EQ(b1->Gain(), 0);
-    ASSERT_EQ(b1->Post(), 0);
-    ASSERT_TRUE(IsClientPosted(b1->buffer_state(), b2ClientMask));
+    ASSERT_EQ(b1->gain(), 0);
+    ASSERT_EQ(b1->post(), 0);
+    ASSERT_TRUE(isClientPosted(b1->bufferState(), b2ClientMask));
 
     // Acquire from posted state should pass.
-    EXPECT_EQ(b2->Acquire(), 0);
+    EXPECT_EQ(b2->acquire(), 0);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromOtherInPostedState) {
-    ASSERT_EQ(b1->Gain(), 0);
-    ASSERT_EQ(b1->Post(), 0);
-    ASSERT_TRUE(IsClientPosted(b1->buffer_state(), b2ClientMask));
+    ASSERT_EQ(b1->gain(), 0);
+    ASSERT_EQ(b1->post(), 0);
+    ASSERT_TRUE(isClientPosted(b1->bufferState(), b2ClientMask));
 
     // Acquire from released state should fail, although there are other clients
     // in posted state.
-    EXPECT_EQ(b1->Acquire(), -EBUSY);
+    EXPECT_EQ(b1->acquire(), -EBUSY);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromSelfInAcquiredState) {
-    ASSERT_EQ(b1->Gain(), 0);
-    ASSERT_EQ(b1->Post(), 0);
-    ASSERT_EQ(b2->Acquire(), 0);
-    auto current_buffer_state = b1->buffer_state();
-    ASSERT_TRUE(IsClientAcquired(current_buffer_state, b2ClientMask));
+    ASSERT_EQ(b1->gain(), 0);
+    ASSERT_EQ(b1->post(), 0);
+    ASSERT_EQ(b2->acquire(), 0);
+    auto currentBufferState = b1->bufferState();
+    ASSERT_TRUE(isClientAcquired(currentBufferState, b2ClientMask));
 
     // Acquiring from acquired state by the same client should not error out.
-    EXPECT_EQ(b2->Acquire(), 0);
+    EXPECT_EQ(b2->acquire(), 0);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromReleasedState) {
-    ASSERT_TRUE(b1->IsReleased());
+    ASSERT_TRUE(b1->isReleased());
 
     // Acquiring form released state should fail.
-    EXPECT_EQ(b1->Acquire(), -EBUSY);
-    EXPECT_EQ(b2->Acquire(), -EBUSY);
+    EXPECT_EQ(b1->acquire(), -EBUSY);
+    EXPECT_EQ(b2->acquire(), -EBUSY);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromGainedState) {
-    ASSERT_EQ(b1->Gain(), 0);
-    ASSERT_TRUE(AnyClientGained(b1->buffer_state()));
+    ASSERT_EQ(b1->gain(), 0);
+    ASSERT_TRUE(isAnyClientGained(b1->bufferState()));
 
     // Acquiring from gained state should fail.
-    EXPECT_EQ(b1->Acquire(), -EBUSY);
-    EXPECT_EQ(b2->Acquire(), -EBUSY);
+    EXPECT_EQ(b1->acquire(), -EBUSY);
+    EXPECT_EQ(b2->acquire(), -EBUSY);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, ReleaseBuffer_fromSelfInReleasedState) {
-    ASSERT_TRUE(b1->IsReleased());
+    ASSERT_TRUE(b1->isReleased());
 
-    EXPECT_EQ(b1->Release(), 0);
+    EXPECT_EQ(b1->release(), 0);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, ReleaseBuffer_fromSelfInGainedState) {
-    ASSERT_TRUE(b1->IsReleased());
-    ASSERT_EQ(b1->Gain(), 0);
-    ASSERT_TRUE(AnyClientGained(b1->buffer_state()));
+    ASSERT_TRUE(b1->isReleased());
+    ASSERT_EQ(b1->gain(), 0);
+    ASSERT_TRUE(isAnyClientGained(b1->bufferState()));
 
-    EXPECT_EQ(b1->Release(), 0);
+    EXPECT_EQ(b1->release(), 0);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, ReleaseBuffer_fromSelfInPostedState) {
-    ASSERT_EQ(b1->Gain(), 0);
-    ASSERT_EQ(b1->Post(), 0);
-    ASSERT_TRUE(AnyClientPosted(b1->buffer_state()));
+    ASSERT_EQ(b1->gain(), 0);
+    ASSERT_EQ(b1->post(), 0);
+    ASSERT_TRUE(isAnyClientPosted(b1->bufferState()));
 
-    EXPECT_EQ(b2->Release(), 0);
+    EXPECT_EQ(b2->release(), 0);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, ReleaseBuffer_fromSelfInAcquiredState) {
-    ASSERT_EQ(b1->Gain(), 0);
-    ASSERT_EQ(b1->Post(), 0);
-    ASSERT_EQ(b2->Acquire(), 0);
-    ASSERT_TRUE(AnyClientAcquired(b1->buffer_state()));
+    ASSERT_EQ(b1->gain(), 0);
+    ASSERT_EQ(b1->post(), 0);
+    ASSERT_EQ(b2->acquire(), 0);
+    ASSERT_TRUE(isAnyClientAcquired(b1->bufferState()));
 
-    EXPECT_EQ(b2->Release(), 0);
+    EXPECT_EQ(b2->release(), 0);
 }
 
 TEST_F(BufferHubBufferStateTransitionTest, BasicUsage) {
@@ -408,60 +408,60 @@
     // Test if this set of basic operation succeed:
     // Producer post three times to the consumer, and released by consumer.
     for (int i = 0; i < 3; ++i) {
-        ASSERT_EQ(b1->Gain(), 0);
-        ASSERT_EQ(b1->Post(), 0);
-        ASSERT_EQ(b2->Acquire(), 0);
-        ASSERT_EQ(b2->Release(), 0);
+        ASSERT_EQ(b1->gain(), 0);
+        ASSERT_EQ(b1->post(), 0);
+        ASSERT_EQ(b2->acquire(), 0);
+        ASSERT_EQ(b2->release(), 0);
     }
 }
 
 TEST_F(BufferHubBufferTest, createNewConsumerAfterGain) {
     // Create a poducer buffer and gain.
     std::unique_ptr<BufferHubBuffer> b1 =
-            BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
+            BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
                                     kUserMetadataSize);
     ASSERT_THAT(b1, NotNull());
-    ASSERT_EQ(b1->Gain(), 0);
+    ASSERT_EQ(b1->gain(), 0);
 
     // Create a consumer of the buffer and test if the consumer can acquire the
     // buffer if producer posts.
     // TODO(b/122543147): use a movalbe wrapper for token
-    native_handle_t* token = b1->Duplicate();
+    native_handle_t* token = b1->duplicate();
     ASSERT_TRUE(token);
 
-    std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(token);
+    std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::import(token);
     native_handle_close(token);
     native_handle_delete(token);
 
     ASSERT_THAT(b2, NotNull());
-    ASSERT_NE(b1->client_state_mask(), b2->client_state_mask());
+    ASSERT_NE(b1->clientStateMask(), b2->clientStateMask());
 
-    ASSERT_EQ(b1->Post(), 0);
-    EXPECT_EQ(b2->Acquire(), 0);
+    ASSERT_EQ(b1->post(), 0);
+    EXPECT_EQ(b2->acquire(), 0);
 }
 
 TEST_F(BufferHubBufferTest, createNewConsumerAfterPost) {
     // Create a poducer buffer and post.
     std::unique_ptr<BufferHubBuffer> b1 =
-            BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
+            BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
                                     kUserMetadataSize);
-    ASSERT_EQ(b1->Gain(), 0);
-    ASSERT_EQ(b1->Post(), 0);
+    ASSERT_EQ(b1->gain(), 0);
+    ASSERT_EQ(b1->post(), 0);
 
     // Create a consumer of the buffer and test if the consumer can acquire the
     // buffer if producer posts.
     // TODO(b/122543147): use a movalbe wrapper for token
-    native_handle_t* token = b1->Duplicate();
+    native_handle_t* token = b1->duplicate();
     ASSERT_TRUE(token);
 
-    std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(token);
+    std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::import(token);
     native_handle_close(token);
     native_handle_delete(token);
 
     ASSERT_THAT(b2, NotNull());
-    ASSERT_NE(b1->client_state_mask(), b2->client_state_mask());
+    ASSERT_NE(b1->clientStateMask(), b2->clientStateMask());
 
-    EXPECT_EQ(b2->Acquire(), 0);
+    EXPECT_EQ(b2->acquire(), 0);
 }
 
 } // namespace
diff --git a/libs/ui/tests/BufferHubMetadata_test.cpp b/libs/ui/tests/BufferHubMetadata_test.cpp
index b7f0b4b..f02c4fc 100644
--- a/libs/ui/tests/BufferHubMetadata_test.cpp
+++ b/libs/ui/tests/BufferHubMetadata_test.cpp
@@ -25,74 +25,73 @@
 class BufferHubMetadataTest : public ::testing::Test {};
 
 TEST_F(BufferHubMetadataTest, Create_UserMetdataSizeTooBig) {
-  BufferHubMetadata m1 =
-      BufferHubMetadata::Create(std::numeric_limits<uint32_t>::max());
-  EXPECT_FALSE(m1.IsValid());
+    BufferHubMetadata m1 = BufferHubMetadata::create(std::numeric_limits<uint32_t>::max());
+    EXPECT_FALSE(m1.isValid());
 }
 
 TEST_F(BufferHubMetadataTest, Create_Success) {
-  BufferHubMetadata m1 = BufferHubMetadata::Create(kEmptyUserMetadataSize);
-  EXPECT_TRUE(m1.IsValid());
-  EXPECT_NE(m1.metadata_header(), nullptr);
+    BufferHubMetadata m1 = BufferHubMetadata::create(kEmptyUserMetadataSize);
+    EXPECT_TRUE(m1.isValid());
+    EXPECT_NE(m1.metadataHeader(), nullptr);
 }
 
 TEST_F(BufferHubMetadataTest, Import_Success) {
-  BufferHubMetadata m1 = BufferHubMetadata::Create(kEmptyUserMetadataSize);
-  EXPECT_TRUE(m1.IsValid());
-  EXPECT_NE(m1.metadata_header(), nullptr);
+    BufferHubMetadata m1 = BufferHubMetadata::create(kEmptyUserMetadataSize);
+    EXPECT_TRUE(m1.isValid());
+    EXPECT_NE(m1.metadataHeader(), nullptr);
 
-  unique_fd h2 = unique_fd(dup(m1.ashmem_fd().get()));
-  EXPECT_NE(h2.get(), -1);
+    unique_fd h2 = unique_fd(dup(m1.ashmemFd().get()));
+    EXPECT_NE(h2.get(), -1);
 
-  BufferHubMetadata m2 = BufferHubMetadata::Import(std::move(h2));
-  EXPECT_EQ(h2.get(), -1);
-  EXPECT_TRUE(m1.IsValid());
-  BufferHubDefs::MetadataHeader* mh1 = m1.metadata_header();
-  EXPECT_NE(mh1, nullptr);
+    BufferHubMetadata m2 = BufferHubMetadata::import(std::move(h2));
+    EXPECT_EQ(h2.get(), -1);
+    EXPECT_TRUE(m1.isValid());
+    BufferHubDefs::MetadataHeader* mh1 = m1.metadataHeader();
+    EXPECT_NE(mh1, nullptr);
 
-  // Check if the newly allocated buffer is initialized in released state (i.e.
-  // state equals to 0U).
-  EXPECT_TRUE(mh1->buffer_state.load() == 0U);
+    // Check if the newly allocated buffer is initialized in released state (i.e.
+    // state equals to 0U).
+    EXPECT_TRUE(mh1->buffer_state.load() == 0U);
 
-  EXPECT_TRUE(m2.IsValid());
-  BufferHubDefs::MetadataHeader* mh2 = m2.metadata_header();
-  EXPECT_NE(mh2, nullptr);
+    EXPECT_TRUE(m2.isValid());
+    BufferHubDefs::MetadataHeader* mh2 = m2.metadataHeader();
+    EXPECT_NE(mh2, nullptr);
 
-  // Check if the newly allocated buffer is initialized in released state (i.e.
-  // state equals to 0U).
-  EXPECT_TRUE(mh2->buffer_state.load() == 0U);
+    // Check if the newly allocated buffer is initialized in released state (i.e.
+    // state equals to 0U).
+    EXPECT_TRUE(mh2->buffer_state.load() == 0U);
 }
 
 TEST_F(BufferHubMetadataTest, MoveMetadataInvalidatesOldOne) {
-  BufferHubMetadata m1 = BufferHubMetadata::Create(sizeof(int));
-  EXPECT_TRUE(m1.IsValid());
-  EXPECT_NE(m1.metadata_header(), nullptr);
-  EXPECT_NE(m1.ashmem_fd().get(), -1);
-  EXPECT_EQ(m1.user_metadata_size(), sizeof(int));
+    BufferHubMetadata m1 = BufferHubMetadata::create(sizeof(int));
+    EXPECT_TRUE(m1.isValid());
+    EXPECT_NE(m1.metadataHeader(), nullptr);
+    EXPECT_NE(m1.ashmemFd().get(), -1);
+    EXPECT_EQ(m1.userMetadataSize(), sizeof(int));
 
-  BufferHubMetadata m2 = std::move(m1);
+    BufferHubMetadata m2 = std::move(m1);
 
-  // After the move, the metadata header (a raw pointer) should be reset in the older buffer.
-  EXPECT_EQ(m1.metadata_header(), nullptr);
-  EXPECT_NE(m2.metadata_header(), nullptr);
+    // After the move, the metadata header (a raw pointer) should be reset in the older buffer.
+    EXPECT_EQ(m1.metadataHeader(), nullptr);
+    EXPECT_NE(m2.metadataHeader(), nullptr);
 
-  EXPECT_EQ(m1.ashmem_fd().get(), -1);
-  EXPECT_NE(m2.ashmem_fd().get(), -1);
+    EXPECT_EQ(m1.ashmemFd().get(), -1);
+    EXPECT_NE(m2.ashmemFd().get(), -1);
 
-  EXPECT_EQ(m1.user_metadata_size(), 0U);
-  EXPECT_EQ(m2.user_metadata_size(), sizeof(int));
+    EXPECT_EQ(m1.userMetadataSize(), 0U);
+    EXPECT_EQ(m2.userMetadataSize(), sizeof(int));
 
-  BufferHubMetadata m3{std::move(m2)};
+    BufferHubMetadata m3{std::move(m2)};
 
-  // After the move, the metadata header (a raw pointer) should be reset in the older buffer.
-  EXPECT_EQ(m2.metadata_header(), nullptr);
-  EXPECT_NE(m3.metadata_header(), nullptr);
+    // After the move, the metadata header (a raw pointer) should be reset in the older buffer.
+    EXPECT_EQ(m2.metadataHeader(), nullptr);
+    EXPECT_NE(m3.metadataHeader(), nullptr);
 
-  EXPECT_EQ(m2.ashmem_fd().get(), -1);
-  EXPECT_NE(m3.ashmem_fd().get(), -1);
+    EXPECT_EQ(m2.ashmemFd().get(), -1);
+    EXPECT_NE(m3.ashmemFd().get(), -1);
 
-  EXPECT_EQ(m2.user_metadata_size(), 0U);
-  EXPECT_EQ(m3.user_metadata_size(), sizeof(int));
+    EXPECT_EQ(m2.userMetadataSize(), 0U);
+    EXPECT_EQ(m3.userMetadataSize(), sizeof(int));
 }
 
 }  // namespace dvr
diff --git a/libs/ui/tests/GraphicBuffer_test.cpp b/libs/ui/tests/GraphicBuffer_test.cpp
index 5b46454..c767ce0 100644
--- a/libs/ui/tests/GraphicBuffer_test.cpp
+++ b/libs/ui/tests/GraphicBuffer_test.cpp
@@ -37,10 +37,10 @@
 
 TEST_F(GraphicBufferTest, CreateFromBufferHubBuffer) {
     std::unique_ptr<BufferHubBuffer> b1 =
-            BufferHubBuffer::Create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat,
+            BufferHubBuffer::create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat,
                                     kTestUsage, /*userMetadataSize=*/0);
     ASSERT_NE(b1, nullptr);
-    EXPECT_TRUE(b1->IsValid());
+    EXPECT_TRUE(b1->isValid());
 
     sp<GraphicBuffer> gb(new GraphicBuffer(std::move(b1)));
     EXPECT_TRUE(gb->isBufferHubBuffer());
@@ -61,10 +61,10 @@
 
 TEST_F(GraphicBufferTest, BufferIdMatchesBufferHubBufferId) {
     std::unique_ptr<BufferHubBuffer> b1 =
-            BufferHubBuffer::Create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat,
+            BufferHubBuffer::create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat,
                                     kTestUsage, /*userMetadataSize=*/0);
     EXPECT_NE(b1, nullptr);
-    EXPECT_TRUE(b1->IsValid());
+    EXPECT_TRUE(b1->isValid());
 
     int b1_id = b1->id();
     EXPECT_GE(b1_id, 0);
diff --git a/libs/vr/libbufferhub/buffer_hub-test.cpp b/libs/vr/libbufferhub/buffer_hub-test.cpp
index 527a27d..27ab024 100644
--- a/libs/vr/libbufferhub/buffer_hub-test.cpp
+++ b/libs/vr/libbufferhub/buffer_hub-test.cpp
@@ -20,12 +20,12 @@
     return result;                            \
   })()
 
-using android::BufferHubDefs::AnyClientAcquired;
-using android::BufferHubDefs::AnyClientGained;
-using android::BufferHubDefs::AnyClientPosted;
-using android::BufferHubDefs::IsClientAcquired;
-using android::BufferHubDefs::IsClientPosted;
-using android::BufferHubDefs::IsClientReleased;
+using android::BufferHubDefs::isAnyClientAcquired;
+using android::BufferHubDefs::isAnyClientGained;
+using android::BufferHubDefs::isAnyClientPosted;
+using android::BufferHubDefs::isClientAcquired;
+using android::BufferHubDefs::isClientPosted;
+using android::BufferHubDefs::isClientReleased;
 using android::BufferHubDefs::kFirstClientBitMask;
 using android::dvr::ConsumerBuffer;
 using android::dvr::ProducerBuffer;
@@ -268,7 +268,7 @@
   // Post in gained state should succeed.
   EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
   EXPECT_EQ(p->buffer_state(), c->buffer_state());
-  EXPECT_TRUE(AnyClientPosted(p->buffer_state()));
+  EXPECT_TRUE(isAnyClientPosted(p->buffer_state()));
 
   // Post and gain in posted state should fail.
   EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
@@ -280,7 +280,7 @@
   EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
   EXPECT_FALSE(invalid_fence.IsValid());
   EXPECT_EQ(p->buffer_state(), c->buffer_state());
-  EXPECT_TRUE(AnyClientAcquired(p->buffer_state()));
+  EXPECT_TRUE(isAnyClientAcquired(p->buffer_state()));
 
   // Acquire, post, and gain in acquired state should fail.
   EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
@@ -304,7 +304,7 @@
   EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
   EXPECT_FALSE(invalid_fence.IsValid());
   EXPECT_EQ(p->buffer_state(), c->buffer_state());
-  EXPECT_TRUE(AnyClientGained(p->buffer_state()));
+  EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
 
   // Acquire and gain in gained state should fail.
   EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
@@ -329,7 +329,7 @@
   ASSERT_TRUE(c.get() != nullptr);
   ASSERT_EQ(0, p->GainAsync());
   ASSERT_EQ(0, p->Post(LocalHandle()));
-  ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
+  ASSERT_TRUE(isAnyClientPosted(p->buffer_state()));
 
   // Gain in posted state should only succeed with gain_posted_buffer = true.
   LocalHandle invalid_fence;
@@ -346,7 +346,7 @@
   ASSERT_TRUE(c.get() != nullptr);
   ASSERT_EQ(0, p->GainAsync());
   ASSERT_EQ(0, p->Post(LocalHandle()));
-  ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
+  ASSERT_TRUE(isAnyClientPosted(p->buffer_state()));
 
   // GainAsync in posted state should only succeed with gain_posted_buffer
   // equals true.
@@ -364,9 +364,9 @@
   ASSERT_EQ(0, p->Post(LocalHandle()));
   // Producer state bit is in released state after post, other clients shall be
   // in posted state although there is no consumer of this buffer yet.
-  ASSERT_TRUE(IsClientReleased(p->buffer_state(), p->client_state_mask()));
+  ASSERT_TRUE(isClientReleased(p->buffer_state(), p->client_state_mask()));
   ASSERT_TRUE(p->is_released());
-  ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
+  ASSERT_TRUE(isAnyClientPosted(p->buffer_state()));
 
   // Gain in released state should succeed.
   LocalHandle invalid_fence;
@@ -393,14 +393,14 @@
 
   // Post the producer should trigger all consumers to be available.
   EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
-  EXPECT_TRUE(IsClientReleased(p->buffer_state(), p->client_state_mask()));
+  EXPECT_TRUE(isClientReleased(p->buffer_state(), p->client_state_mask()));
   for (size_t i = 0; i < kMaxConsumerCount; ++i) {
     EXPECT_TRUE(
-        IsClientPosted(cs[i]->buffer_state(), cs[i]->client_state_mask()));
+        isClientPosted(cs[i]->buffer_state(), cs[i]->client_state_mask()));
     EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(cs[i])));
     EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
     EXPECT_TRUE(
-        IsClientAcquired(p->buffer_state(), cs[i]->client_state_mask()));
+        isClientAcquired(p->buffer_state(), cs[i]->client_state_mask()));
   }
 
   // All consumers have to release before the buffer is considered to be
@@ -424,22 +424,22 @@
       kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
   ASSERT_TRUE(p.get() != nullptr);
   EXPECT_EQ(0, p->GainAsync());
-  EXPECT_TRUE(AnyClientGained(p->buffer_state()));
+  EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
 
   std::unique_ptr<ConsumerBuffer> c =
       ConsumerBuffer::Import(p->CreateConsumer());
   ASSERT_TRUE(c.get() != nullptr);
-  EXPECT_TRUE(AnyClientGained(c->buffer_state()));
+  EXPECT_TRUE(isAnyClientGained(c->buffer_state()));
 
   DvrNativeBufferMetadata metadata;
   LocalHandle invalid_fence;
 
   // Post the gained buffer should signal already created consumer.
   EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
-  EXPECT_TRUE(AnyClientPosted(p->buffer_state()));
+  EXPECT_TRUE(isAnyClientPosted(p->buffer_state()));
   EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
   EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
-  EXPECT_TRUE(AnyClientAcquired(c->buffer_state()));
+  EXPECT_TRUE(isAnyClientAcquired(c->buffer_state()));
 }
 
 TEST_F(LibBufferHubTest, TestCreateTheFirstConsumerAfterPostingBuffer) {
@@ -447,7 +447,7 @@
       kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
   ASSERT_TRUE(p.get() != nullptr);
   EXPECT_EQ(0, p->GainAsync());
-  EXPECT_TRUE(AnyClientGained(p->buffer_state()));
+  EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
 
   DvrNativeBufferMetadata metadata;
   LocalHandle invalid_fence;
@@ -462,7 +462,7 @@
   std::unique_ptr<ConsumerBuffer> c =
       ConsumerBuffer::Import(p->CreateConsumer());
   ASSERT_TRUE(c.get() != nullptr);
-  EXPECT_TRUE(IsClientPosted(c->buffer_state(), c->client_state_mask()));
+  EXPECT_TRUE(isClientPosted(c->buffer_state(), c->client_state_mask()));
   EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
 }
 
@@ -500,7 +500,7 @@
 
   EXPECT_TRUE(p->is_released());
   EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
-  EXPECT_TRUE(AnyClientGained(p->buffer_state()));
+  EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
 }
 
 TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
diff --git a/libs/vr/libbufferhub/consumer_buffer.cpp b/libs/vr/libbufferhub/consumer_buffer.cpp
index b6ca64e..115e866 100644
--- a/libs/vr/libbufferhub/consumer_buffer.cpp
+++ b/libs/vr/libbufferhub/consumer_buffer.cpp
@@ -38,7 +38,7 @@
   // The buffer can be acquired iff the buffer state for this client is posted.
   uint32_t current_buffer_state =
       buffer_state_->load(std::memory_order_acquire);
-  if (!BufferHubDefs::IsClientPosted(current_buffer_state,
+  if (!BufferHubDefs::isClientPosted(current_buffer_state,
                                      client_state_mask())) {
     ALOGE(
         "%s: Failed to acquire the buffer. The buffer is not posted, id=%d "
@@ -58,7 +58,7 @@
         " when trying to acquire the buffer and modify the buffer state to "
         "%" PRIx32 ". About to try again if the buffer is still posted.",
         __FUNCTION__, current_buffer_state, updated_buffer_state);
-    if (!BufferHubDefs::IsClientPosted(current_buffer_state,
+    if (!BufferHubDefs::isClientPosted(current_buffer_state,
                                        client_state_mask())) {
       ALOGE(
           "%s: Failed to acquire the buffer. The buffer is no longer posted, "
@@ -144,7 +144,7 @@
   // released state.
   uint32_t current_buffer_state =
       buffer_state_->load(std::memory_order_acquire);
-  if (BufferHubDefs::IsClientReleased(current_buffer_state,
+  if (BufferHubDefs::isClientReleased(current_buffer_state,
                                       client_state_mask())) {
     return 0;
   }
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h
index bab7367..e610e18 100644
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h
+++ b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h
@@ -27,38 +27,38 @@
 static constexpr uint32_t kFirstClientBitMask =
     android::BufferHubDefs::kFirstClientBitMask;
 
-static inline bool AnyClientGained(uint32_t state) {
-  return android::BufferHubDefs::AnyClientGained(state);
+static inline bool isAnyClientGained(uint32_t state) {
+  return android::BufferHubDefs::isAnyClientGained(state);
 }
 
-static inline bool IsClientGained(uint32_t state, uint32_t client_bit_mask) {
-  return android::BufferHubDefs::IsClientGained(state, client_bit_mask);
+static inline bool isClientGained(uint32_t state, uint32_t client_bit_mask) {
+  return android::BufferHubDefs::isClientGained(state, client_bit_mask);
 }
 
-static inline bool AnyClientPosted(uint32_t state) {
-  return android::BufferHubDefs::AnyClientPosted(state);
+static inline bool isAnyClientPosted(uint32_t state) {
+  return android::BufferHubDefs::isAnyClientPosted(state);
 }
 
-static inline bool IsClientPosted(uint32_t state, uint32_t client_bit_mask) {
-  return android::BufferHubDefs::IsClientPosted(state, client_bit_mask);
+static inline bool isClientPosted(uint32_t state, uint32_t client_bit_mask) {
+  return android::BufferHubDefs::isClientPosted(state, client_bit_mask);
 }
 
-static inline bool AnyClientAcquired(uint32_t state) {
-  return android::BufferHubDefs::AnyClientAcquired(state);
+static inline bool isAnyClientAcquired(uint32_t state) {
+  return android::BufferHubDefs::isAnyClientAcquired(state);
 }
 
-static inline bool IsClientAcquired(uint32_t state, uint32_t client_bit_mask) {
-  return android::BufferHubDefs::IsClientAcquired(state, client_bit_mask);
+static inline bool isClientAcquired(uint32_t state, uint32_t client_bit_mask) {
+  return android::BufferHubDefs::isClientAcquired(state, client_bit_mask);
 }
 
-static inline bool IsClientReleased(uint32_t state, uint32_t client_bit_mask) {
-  return android::BufferHubDefs::IsClientReleased(state, client_bit_mask);
+static inline bool isClientReleased(uint32_t state, uint32_t client_bit_mask) {
+  return android::BufferHubDefs::isClientReleased(state, client_bit_mask);
 }
 
 // Returns the next available buffer client's client_state_masks.
 // @params union_bits. Union of all existing clients' client_state_masks.
-static inline uint32_t FindNextAvailableClientStateMask(uint32_t union_bits) {
-  return android::BufferHubDefs::FindNextAvailableClientStateMask(union_bits);
+static inline uint32_t findNextAvailableClientStateMask(uint32_t union_bits) {
+  return android::BufferHubDefs::findNextAvailableClientStateMask(union_bits);
 }
 
 using MetadataHeader = android::BufferHubDefs::MetadataHeader;
diff --git a/libs/vr/libbufferhub/producer_buffer.cpp b/libs/vr/libbufferhub/producer_buffer.cpp
index edfdddf..3d88ba5 100644
--- a/libs/vr/libbufferhub/producer_buffer.cpp
+++ b/libs/vr/libbufferhub/producer_buffer.cpp
@@ -82,7 +82,7 @@
   // The buffer can be posted iff the buffer state for this client is gained.
   uint32_t current_buffer_state =
       buffer_state_->load(std::memory_order_acquire);
-  if (!BufferHubDefs::IsClientGained(current_buffer_state,
+  if (!BufferHubDefs::isClientGained(current_buffer_state,
                                      client_state_mask())) {
     ALOGE("%s: not gained, id=%d state=%" PRIx32 ".", __FUNCTION__, id(),
           current_buffer_state);
@@ -103,7 +103,7 @@
         "%" PRIx32
         ". About to try again if the buffer is still gained by this client.",
         __FUNCTION__, current_buffer_state, updated_buffer_state);
-    if (!BufferHubDefs::IsClientGained(current_buffer_state,
+    if (!BufferHubDefs::isClientGained(current_buffer_state,
                                        client_state_mask())) {
       ALOGE(
           "%s: Failed to post the buffer. The buffer is no longer gained, "
@@ -166,14 +166,14 @@
   ALOGD_IF(TRACE, "%s: buffer=%d, state=%" PRIx32 ".", __FUNCTION__, id(),
            current_buffer_state);
 
-  if (BufferHubDefs::IsClientGained(current_buffer_state,
+  if (BufferHubDefs::isClientGained(current_buffer_state,
                                     client_state_mask())) {
     ALOGV("%s: already gained id=%d.", __FUNCTION__, id());
     return 0;
   }
-  if (BufferHubDefs::AnyClientAcquired(current_buffer_state) ||
-      BufferHubDefs::AnyClientGained(current_buffer_state) ||
-      (BufferHubDefs::AnyClientPosted(
+  if (BufferHubDefs::isAnyClientAcquired(current_buffer_state) ||
+      BufferHubDefs::isAnyClientGained(current_buffer_state) ||
+      (BufferHubDefs::isAnyClientPosted(
            current_buffer_state &
            active_clients_bit_mask_->load(std::memory_order_acquire)) &&
        !gain_posted_buffer)) {
@@ -195,9 +195,9 @@
         "clients.",
         __FUNCTION__, current_buffer_state, updated_buffer_state);
 
-    if (BufferHubDefs::AnyClientAcquired(current_buffer_state) ||
-        BufferHubDefs::AnyClientGained(current_buffer_state) ||
-        (BufferHubDefs::AnyClientPosted(
+    if (BufferHubDefs::isAnyClientAcquired(current_buffer_state) ||
+        BufferHubDefs::isAnyClientGained(current_buffer_state) ||
+        (BufferHubDefs::isAnyClientPosted(
              current_buffer_state &
              active_clients_bit_mask_->load(std::memory_order_acquire)) &&
          !gain_posted_buffer)) {
@@ -291,7 +291,7 @@
   // TODO(b/112338294) Keep here for reference. Remove it after new logic is
   // written.
   /* uint32_t buffer_state = buffer_state_->load(std::memory_order_acquire);
-  if (!BufferHubDefs::IsClientGained(
+  if (!BufferHubDefs::isClientGained(
       buffer_state, BufferHubDefs::kFirstClientStateMask)) {
     // Can only detach a ProducerBuffer when it's in gained state.
     ALOGW("ProducerBuffer::Detach: The buffer (id=%d, state=0x%" PRIx32
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
index d7833f3..2d3fa4a 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
@@ -532,7 +532,7 @@
 Status<size_t> ProducerQueue::InsertBuffer(
     const std::shared_ptr<ProducerBuffer>& buffer) {
   if (buffer == nullptr ||
-      !BufferHubDefs::IsClientGained(buffer->buffer_state(),
+      !BufferHubDefs::isClientGained(buffer->buffer_state(),
                                      buffer->client_state_mask())) {
     ALOGE(
         "ProducerQueue::InsertBuffer: Can only insert a buffer when it's in "
@@ -638,7 +638,7 @@
             static_cast<int>(*slot));
       return ErrorStatus(EIO);
     }
-    if (!BufferHubDefs::AnyClientAcquired(buffer->buffer_state())) {
+    if (!BufferHubDefs::isAnyClientAcquired(buffer->buffer_state())) {
       *slot = *iter;
       unavailable_buffers_slot_.erase(iter);
       unavailable_buffers_slot_.push_back(*slot);
diff --git a/opengl/libagl/Android.bp b/opengl/libagl/Android.bp
new file mode 100644
index 0000000..6ec24b3
--- /dev/null
+++ b/opengl/libagl/Android.bp
@@ -0,0 +1,99 @@
+//
+// Build the software OpenGL ES library
+//
+
+cc_defaults {
+    name: "libGLES_android_defaults",
+
+    cflags: [
+        "-DLOG_TAG=\"libagl\"",
+        "-DGL_GLEXT_PROTOTYPES",
+        "-DEGL_EGLEXT_PROTOTYPES",
+        "-fvisibility=hidden",
+        "-Wall",
+        "-Werror",
+    ],
+
+    shared_libs: [
+        "libcutils",
+        "libhardware",
+        "libutils",
+        "liblog",
+        "libpixelflinger",
+        "libETC1",
+        "libui",
+        "libnativewindow",
+    ],
+
+    // we need to access the private Bionic header <bionic_tls.h>
+    include_dirs: ["bionic/libc/private"],
+
+    arch: {
+        arm: {
+            cflags: ["-fstrict-aliasing"],
+        },
+
+        mips: {
+            cflags: [
+                "-fstrict-aliasing",
+                // The graphics code can generate division by zero
+                "-mno-check-zero-division",
+            ],
+        },
+    },
+}
+
+cc_library_shared {
+    name: "libGLES_android",
+    defaults: ["libGLES_android_defaults"],
+
+    whole_static_libs: ["libGLES_android_arm"],
+
+    srcs: [
+        "egl.cpp",
+        "state.cpp",
+        "texture.cpp",
+        "Tokenizer.cpp",
+        "TokenManager.cpp",
+        "TextureObjectManager.cpp",
+        "BufferObjectManager.cpp",
+    ],
+
+    arch: {
+        arm: {
+            srcs: [
+                "fixed_asm.S",
+                "iterators.S",
+            ],
+        },
+
+        mips: {
+            rev6: {
+                srcs: ["arch-mips/fixed_asm.S"],
+            },
+        },
+    },
+
+    relative_install_path: "egl",
+}
+
+cc_library_static {
+    name: "libGLES_android_arm",
+    defaults: ["libGLES_android_defaults"],
+
+    srcs: [
+        "array.cpp",
+        "fp.cpp",
+        "light.cpp",
+        "matrix.cpp",
+        "mipmap.cpp",
+        "primitives.cpp",
+        "vertex.cpp",
+    ],
+
+    arch: {
+        arm: {
+            instruction_set: "arm",
+        },
+    },
+}
diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk
deleted file mode 100644
index 15a12e4..0000000
--- a/opengl/libagl/Android.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-#
-# Build the software OpenGL ES library
-#
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-	egl.cpp                     \
-	state.cpp		            \
-	texture.cpp		            \
-    Tokenizer.cpp               \
-    TokenManager.cpp            \
-    TextureObjectManager.cpp    \
-    BufferObjectManager.cpp     \
-	array.cpp.arm		        \
-	fp.cpp.arm		            \
-	light.cpp.arm		        \
-	matrix.cpp.arm		        \
-	mipmap.cpp.arm		        \
-	primitives.cpp.arm	        \
-	vertex.cpp.arm
-
-LOCAL_CFLAGS += -DLOG_TAG=\"libagl\"
-LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
-LOCAL_CFLAGS += -fvisibility=hidden
-
-LOCAL_SHARED_LIBRARIES := libcutils libhardware libutils liblog libpixelflinger libETC1 libui libnativewindow
-
-LOCAL_SRC_FILES_arm += fixed_asm.S iterators.S
-LOCAL_CFLAGS_arm += -fstrict-aliasing
-
-ifndef ARCH_MIPS_REV6
-LOCAL_SRC_FILES_mips += arch-mips/fixed_asm.S
-endif
-LOCAL_CFLAGS_mips += -fstrict-aliasing
-# The graphics code can generate division by zero
-LOCAL_CFLAGS_mips += -mno-check-zero-division
-
-LOCAL_CFLAGS += -Wall -Werror
-
-# we need to access the private Bionic header <bionic_tls.h>
-LOCAL_C_INCLUDES += bionic/libc/private
-
-LOCAL_MODULE_RELATIVE_PATH := egl
-LOCAL_MODULE:= libGLES_android
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/services/bufferhub/BufferHubService.cpp b/services/bufferhub/BufferHubService.cpp
index 6b802fb..90ac1c2 100644
--- a/services/bufferhub/BufferHubService.cpp
+++ b/services/bufferhub/BufferHubService.cpp
@@ -53,7 +53,7 @@
             std::make_shared<BufferNode>(desc.width, desc.height, desc.layers, desc.format,
                                          desc.usage, userMetadataSize,
                                          BufferHubIdGenerator::getInstance().getId());
-    if (node == nullptr || !node->IsValid()) {
+    if (node == nullptr || !node->isValid()) {
         ALOGE("%s: creating BufferNode failed.", __FUNCTION__);
         _hidl_cb(/*status=*/BufferHubStatus::ALLOCATION_FAILED, /*bufferClient=*/nullptr,
                  /*bufferTraits=*/{});
@@ -70,11 +70,11 @@
     NATIVE_HANDLE_DECLARE_STORAGE(bufferInfoStorage, BufferHubDefs::kBufferInfoNumFds,
                                   BufferHubDefs::kBufferInfoNumInts);
     hidl_handle bufferInfo =
-            buildBufferInfo(bufferInfoStorage, node->id(), node->AddNewActiveClientsBitToMask(),
-                            node->user_metadata_size(), node->metadata().ashmem_fd(),
+            buildBufferInfo(bufferInfoStorage, node->id(), node->addNewActiveClientsBitToMask(),
+                            node->userMetadataSize(), node->metadata().ashmemFd(),
                             node->eventFd().get());
     BufferTraits bufferTraits = {/*bufferDesc=*/description,
-                                 /*bufferHandle=*/hidl_handle(node->buffer_handle()),
+                                 /*bufferHandle=*/hidl_handle(node->bufferHandle()),
                                  /*bufferInfo=*/std::move(bufferInfo)};
 
     _hidl_cb(/*status=*/BufferHubStatus::NO_ERROR, /*bufferClient=*/client,
@@ -141,7 +141,7 @@
     }
 
     sp<BufferClient> client = new BufferClient(*originClient);
-    uint32_t clientStateMask = client->getBufferNode()->AddNewActiveClientsBitToMask();
+    uint32_t clientStateMask = client->getBufferNode()->addNewActiveClientsBitToMask();
     if (clientStateMask == 0U) {
         // Reach max client count
         ALOGE("%s: import failed, BufferNode#%u reached maximum clients.", __FUNCTION__,
@@ -157,17 +157,17 @@
     std::shared_ptr<BufferNode> node = client->getBufferNode();
 
     HardwareBufferDescription bufferDesc;
-    memcpy(&bufferDesc, &node->buffer_desc(), sizeof(HardwareBufferDescription));
+    memcpy(&bufferDesc, &node->bufferDesc(), sizeof(HardwareBufferDescription));
 
     // Allocate memory for bufferInfo of type hidl_handle on the stack. See
     // http://aosp/286282 for the usage of NATIVE_HANDLE_DECLARE_STORAGE.
     NATIVE_HANDLE_DECLARE_STORAGE(bufferInfoStorage, BufferHubDefs::kBufferInfoNumFds,
                                   BufferHubDefs::kBufferInfoNumInts);
     hidl_handle bufferInfo = buildBufferInfo(bufferInfoStorage, node->id(), clientStateMask,
-                                             node->user_metadata_size(),
-                                             node->metadata().ashmem_fd(), node->eventFd().get());
+                                             node->userMetadataSize(), node->metadata().ashmemFd(),
+                                             node->eventFd().get());
     BufferTraits bufferTraits = {/*bufferDesc=*/bufferDesc,
-                                 /*bufferHandle=*/hidl_handle(node->buffer_handle()),
+                                 /*bufferHandle=*/hidl_handle(node->bufferHandle()),
                                  /*bufferInfo=*/std::move(bufferInfo)};
 
     _hidl_cb(/*status=*/BufferHubStatus::NO_ERROR, /*bufferClient=*/client,
@@ -231,10 +231,10 @@
     for (auto iter = clientCount.begin(); iter != clientCount.end(); ++iter) {
         const std::shared_ptr<BufferNode> node = std::move(iter->second.first);
         const uint32_t clientCount = iter->second.second;
-        AHardwareBuffer_Desc desc = node->buffer_desc();
+        AHardwareBuffer_Desc desc = node->bufferDesc();
 
         MetadataHeader* metadataHeader =
-                const_cast<BufferHubMetadata*>(&node->metadata())->metadata_header();
+                const_cast<BufferHubMetadata*>(&node->metadata())->metadataHeader();
         const uint32_t state = metadataHeader->buffer_state.load(std::memory_order_acquire);
         const uint64_t index = metadataHeader->queue_index;
 
diff --git a/services/bufferhub/BufferNode.cpp b/services/bufferhub/BufferNode.cpp
index 5106390..4f877b2 100644
--- a/services/bufferhub/BufferNode.cpp
+++ b/services/bufferhub/BufferNode.cpp
@@ -11,20 +11,19 @@
 namespace V1_0 {
 namespace implementation {
 
-void BufferNode::InitializeMetadata() {
+void BufferNode::initializeMetadata() {
     // Using placement new here to reuse shared memory instead of new allocation
     // Initialize the atomic variables to zero.
-    BufferHubDefs::MetadataHeader* metadata_header = metadata_.metadata_header();
-    buffer_state_ = new (&metadata_header->buffer_state) std::atomic<uint32_t>(0);
-    fence_state_ = new (&metadata_header->fence_state) std::atomic<uint32_t>(0);
-    active_clients_bit_mask_ =
-            new (&metadata_header->active_clients_bit_mask) std::atomic<uint32_t>(0);
+    BufferHubDefs::MetadataHeader* metadataHeader = mMetadata.metadataHeader();
+    mBufferState = new (&metadataHeader->buffer_state) std::atomic<uint32_t>(0);
+    mFenceState = new (&metadataHeader->fence_state) std::atomic<uint32_t>(0);
+    mActiveClientsBitMask = new (&metadataHeader->active_clients_bit_mask) std::atomic<uint32_t>(0);
     // The C++ standard recommends (but does not require) that lock-free atomic operations are
     // also address-free, that is, suitable for communication between processes using shared
     // memory.
-    LOG_ALWAYS_FATAL_IF(!std::atomic_is_lock_free(buffer_state_) ||
-                                !std::atomic_is_lock_free(fence_state_) ||
-                                !std::atomic_is_lock_free(active_clients_bit_mask_),
+    LOG_ALWAYS_FATAL_IF(!std::atomic_is_lock_free(mBufferState) ||
+                                !std::atomic_is_lock_free(mFenceState) ||
+                                !std::atomic_is_lock_free(mActiveClientsBitMask),
                         "Atomic variables in ashmen are not lock free.");
 }
 
@@ -38,35 +37,35 @@
     // hardcoded service name "bufferhub".
     int ret = GraphicBufferAllocator::get().allocate(width, height, format, layer_count, usage,
                                                      const_cast<const native_handle_t**>(
-                                                             &buffer_handle_),
+                                                             &mBufferHandle),
                                                      &out_stride,
                                                      /*graphicBufferId=*/0,
                                                      /*requestor=*/"bufferhub");
 
-    if (ret != OK || buffer_handle_ == nullptr) {
+    if (ret != OK || mBufferHandle == nullptr) {
         ALOGE("%s: Failed to allocate buffer: %s", __FUNCTION__, strerror(-ret));
         return;
     }
 
-    buffer_desc_.width = width;
-    buffer_desc_.height = height;
-    buffer_desc_.layers = layer_count;
-    buffer_desc_.format = format;
-    buffer_desc_.usage = usage;
-    buffer_desc_.stride = out_stride;
+    mBufferDesc.width = width;
+    mBufferDesc.height = height;
+    mBufferDesc.layers = layer_count;
+    mBufferDesc.format = format;
+    mBufferDesc.usage = usage;
+    mBufferDesc.stride = out_stride;
 
-    metadata_ = BufferHubMetadata::Create(user_metadata_size);
-    if (!metadata_.IsValid()) {
+    mMetadata = BufferHubMetadata::create(user_metadata_size);
+    if (!mMetadata.isValid()) {
         ALOGE("%s: Failed to allocate metadata.", __FUNCTION__);
         return;
     }
-    InitializeMetadata();
+    initializeMetadata();
 }
 
 BufferNode::~BufferNode() {
     // Free the handle
-    if (buffer_handle_ != nullptr) {
-        status_t ret = GraphicBufferAllocator::get().free(buffer_handle_);
+    if (mBufferHandle != nullptr) {
+        status_t ret = GraphicBufferAllocator::get().free(mBufferHandle);
         if (ret != OK) {
             ALOGE("%s: Failed to free handle; Got error: %d", __FUNCTION__, ret);
         }
@@ -78,33 +77,33 @@
     }
 }
 
-uint32_t BufferNode::GetActiveClientsBitMask() const {
-    return active_clients_bit_mask_->load(std::memory_order_acquire);
+uint32_t BufferNode::getActiveClientsBitMask() const {
+    return mActiveClientsBitMask->load(std::memory_order_acquire);
 }
 
-uint32_t BufferNode::AddNewActiveClientsBitToMask() {
-    uint32_t current_active_clients_bit_mask = GetActiveClientsBitMask();
+uint32_t BufferNode::addNewActiveClientsBitToMask() {
+    uint32_t currentActiveClientsBitMask = getActiveClientsBitMask();
     uint32_t client_state_mask = 0U;
-    uint32_t updated_active_clients_bit_mask = 0U;
+    uint32_t updatedActiveClientsBitMask = 0U;
     do {
         client_state_mask =
-                BufferHubDefs::FindNextAvailableClientStateMask(current_active_clients_bit_mask);
+                BufferHubDefs::findNextAvailableClientStateMask(currentActiveClientsBitMask);
         if (client_state_mask == 0U) {
             ALOGE("%s: reached the maximum number of channels per buffer node: %d.", __FUNCTION__,
                   BufferHubDefs::kMaxNumberOfClients);
             errno = E2BIG;
             return 0U;
         }
-        updated_active_clients_bit_mask = current_active_clients_bit_mask | client_state_mask;
-    } while (!(active_clients_bit_mask_->compare_exchange_weak(current_active_clients_bit_mask,
-                                                               updated_active_clients_bit_mask,
-                                                               std::memory_order_acq_rel,
-                                                               std::memory_order_acquire)));
+        updatedActiveClientsBitMask = currentActiveClientsBitMask | client_state_mask;
+    } while (!(mActiveClientsBitMask->compare_exchange_weak(currentActiveClientsBitMask,
+                                                            updatedActiveClientsBitMask,
+                                                            std::memory_order_acq_rel,
+                                                            std::memory_order_acquire)));
     return client_state_mask;
 }
 
-void BufferNode::RemoveClientsBitFromMask(const uint32_t& value) {
-    active_clients_bit_mask_->fetch_and(~value);
+void BufferNode::removeClientsBitFromMask(const uint32_t& value) {
+    mActiveClientsBitMask->fetch_and(~value);
 }
 
 } // namespace implementation
diff --git a/services/bufferhub/include/bufferhub/BufferNode.h b/services/bufferhub/include/bufferhub/BufferNode.h
index 4729e1c..04970fd 100644
--- a/services/bufferhub/include/bufferhub/BufferNode.h
+++ b/services/bufferhub/include/bufferhub/BufferNode.h
@@ -22,73 +22,73 @@
     ~BufferNode();
 
     // Returns whether the object holds a valid metadata.
-    bool IsValid() const { return metadata_.IsValid(); }
+    bool isValid() const { return mMetadata.isValid(); }
 
     int id() const { return mId; }
 
-    size_t user_metadata_size() const { return metadata_.user_metadata_size(); }
+    size_t userMetadataSize() const { return mMetadata.userMetadataSize(); }
 
     // Accessors of the buffer description and handle
-    const native_handle_t* buffer_handle() const { return buffer_handle_; }
-    const AHardwareBuffer_Desc& buffer_desc() const { return buffer_desc_; }
+    const native_handle_t* bufferHandle() const { return mBufferHandle; }
+    const AHardwareBuffer_Desc& bufferDesc() const { return mBufferDesc; }
 
     // Accessor of event fd.
     const BufferHubEventFd& eventFd() const { return mEventFd; }
 
-    // Accessors of metadata.
-    const BufferHubMetadata& metadata() const { return metadata_; }
+    // Accessors of mMetadata.
+    const BufferHubMetadata& metadata() const { return mMetadata; }
 
-    // Gets the current value of active_clients_bit_mask in metadata_ with
+    // Gets the current value of mActiveClientsBitMask in mMetadata with
     // std::memory_order_acquire, so that all previous releases of
-    // active_clients_bit_mask from all threads will be returned here.
-    uint32_t GetActiveClientsBitMask() const;
+    // mActiveClientsBitMask from all threads will be returned here.
+    uint32_t getActiveClientsBitMask() const;
 
-    // Find and add a new client_state_mask to active_clients_bit_mask in
-    // metadata_.
-    // Return the new client_state_mask that is added to active_clients_bit_mask.
+    // Find and add a new client state mask to mActiveClientsBitMask in
+    // mMetadata.
+    // Return the new client state mask that is added to mActiveClientsBitMask.
     // Return 0U if there are already 16 clients of the buffer.
-    uint32_t AddNewActiveClientsBitToMask();
+    uint32_t addNewActiveClientsBitToMask();
 
-    // Removes the value from active_clients_bit_mask in metadata_ with
+    // Removes the value from active_clients_bit_mask in mMetadata with
     // std::memory_order_release, so that the change will be visible to any
-    // acquire of active_clients_bit_mask_ in any threads after the succeed of
+    // acquire of mActiveClientsBitMask in any threads after the succeed of
     // this operation.
-    void RemoveClientsBitFromMask(const uint32_t& value);
+    void removeClientsBitFromMask(const uint32_t& value);
 
 private:
     // Helper method for constructors to initialize atomic metadata header
     // variables in shared memory.
-    void InitializeMetadata();
+    void initializeMetadata();
 
     // Gralloc buffer handles.
-    native_handle_t* buffer_handle_;
-    AHardwareBuffer_Desc buffer_desc_;
+    native_handle_t* mBufferHandle;
+    AHardwareBuffer_Desc mBufferDesc;
 
     // Eventfd used for signalling buffer events among the clients of the buffer.
     BufferHubEventFd mEventFd;
 
     // Metadata in shared memory.
-    BufferHubMetadata metadata_;
+    BufferHubMetadata mMetadata;
 
     // A system-unique id generated by bufferhub from 0 to std::numeric_limits<int>::max().
     // BufferNodes not created by bufferhub will have id < 0, meaning "not specified".
     // TODO(b/118891412): remove default id = -1 and update comments after pdx is no longer in use
     const int mId = -1;
 
-    // The following variables are atomic variables in metadata_ that are visible
+    // The following variables are atomic variables in mMetadata that are visible
     // to Bn object and Bp objects. Please find more info in
     // BufferHubDefs::MetadataHeader.
 
-    // buffer_state_ tracks the state of the buffer. Buffer can be in one of these
+    // mBufferState tracks the state of the buffer. Buffer can be in one of these
     // four states: gained, posted, acquired, released.
-    std::atomic<uint32_t>* buffer_state_ = nullptr;
+    std::atomic<uint32_t>* mBufferState = nullptr;
 
-    // TODO(b/112012161): add comments to fence_state_.
-    std::atomic<uint32_t>* fence_state_ = nullptr;
+    // TODO(b/112012161): add comments to mFenceState.
+    std::atomic<uint32_t>* mFenceState = nullptr;
 
-    // active_clients_bit_mask_ tracks all the bp clients of the buffer. It is the
+    // mActiveClientsBitMask tracks all the bp clients of the buffer. It is the
     // union of all client_state_mask of all bp clients.
-    std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;
+    std::atomic<uint32_t>* mActiveClientsBitMask = nullptr;
 };
 
 } // namespace implementation
diff --git a/services/bufferhub/tests/BufferNode_test.cpp b/services/bufferhub/tests/BufferNode_test.cpp
index ccb1197..b9f1c81 100644
--- a/services/bufferhub/tests/BufferNode_test.cpp
+++ b/services/bufferhub/tests/BufferNode_test.cpp
@@ -28,7 +28,7 @@
     void SetUp() override {
         buffer_node =
                 new BufferNode(kWidth, kHeight, kLayerCount, kFormat, kUsage, kUserMetadataSize);
-        ASSERT_TRUE(buffer_node->IsValid());
+        ASSERT_TRUE(buffer_node->isValid());
     }
 
     void TearDown() override {
@@ -41,65 +41,64 @@
 };
 
 TEST_F(BufferNodeTest, TestCreateBufferNode) {
-    EXPECT_EQ(buffer_node->user_metadata_size(), kUserMetadataSize);
+    EXPECT_EQ(buffer_node->userMetadataSize(), kUserMetadataSize);
     // Test the handle just allocated is good (i.e. able to be imported)
     GraphicBufferMapper& mapper = GraphicBufferMapper::get();
     const native_handle_t* outHandle;
     status_t ret =
-            mapper.importBuffer(buffer_node->buffer_handle(), buffer_node->buffer_desc().width,
-                                buffer_node->buffer_desc().height,
-                                buffer_node->buffer_desc().layers,
-                                buffer_node->buffer_desc().format, buffer_node->buffer_desc().usage,
-                                buffer_node->buffer_desc().stride, &outHandle);
+            mapper.importBuffer(buffer_node->bufferHandle(), buffer_node->bufferDesc().width,
+                                buffer_node->bufferDesc().height, buffer_node->bufferDesc().layers,
+                                buffer_node->bufferDesc().format, buffer_node->bufferDesc().usage,
+                                buffer_node->bufferDesc().stride, &outHandle);
     EXPECT_EQ(ret, OK);
     EXPECT_THAT(outHandle, NotNull());
 }
 
-TEST_F(BufferNodeTest, TestAddNewActiveClientsBitToMask_twoNewClients) {
-    uint32_t new_client_state_mask_1 = buffer_node->AddNewActiveClientsBitToMask();
-    EXPECT_EQ(buffer_node->GetActiveClientsBitMask(), new_client_state_mask_1);
+TEST_F(BufferNodeTest, TestaddNewActiveClientsBitToMask_twoNewClients) {
+    uint32_t new_client_state_mask_1 = buffer_node->addNewActiveClientsBitToMask();
+    EXPECT_EQ(buffer_node->getActiveClientsBitMask(), new_client_state_mask_1);
 
     // Request and add a new client_state_mask again.
     // Active clients bit mask should be the union of the two new
     // client_state_masks.
-    uint32_t new_client_state_mask_2 = buffer_node->AddNewActiveClientsBitToMask();
-    EXPECT_EQ(buffer_node->GetActiveClientsBitMask(),
+    uint32_t new_client_state_mask_2 = buffer_node->addNewActiveClientsBitToMask();
+    EXPECT_EQ(buffer_node->getActiveClientsBitMask(),
               new_client_state_mask_1 | new_client_state_mask_2);
 }
 
-TEST_F(BufferNodeTest, TestAddNewActiveClientsBitToMask_32NewClients) {
+TEST_F(BufferNodeTest, TestaddNewActiveClientsBitToMask_32NewClients) {
     uint32_t new_client_state_mask = 0U;
     uint32_t current_mask = 0U;
     uint32_t expected_mask = 0U;
 
     for (int i = 0; i < BufferHubDefs::kMaxNumberOfClients; ++i) {
-        new_client_state_mask = buffer_node->AddNewActiveClientsBitToMask();
+        new_client_state_mask = buffer_node->addNewActiveClientsBitToMask();
         EXPECT_NE(new_client_state_mask, 0U);
         EXPECT_FALSE(new_client_state_mask & current_mask);
         expected_mask = current_mask | new_client_state_mask;
-        current_mask = buffer_node->GetActiveClientsBitMask();
+        current_mask = buffer_node->getActiveClientsBitMask();
         EXPECT_EQ(current_mask, expected_mask);
     }
 
     // Method should fail upon requesting for more than maximum allowable clients.
-    new_client_state_mask = buffer_node->AddNewActiveClientsBitToMask();
+    new_client_state_mask = buffer_node->addNewActiveClientsBitToMask();
     EXPECT_EQ(new_client_state_mask, 0U);
     EXPECT_EQ(errno, E2BIG);
 }
 
 TEST_F(BufferNodeTest, TestRemoveActiveClientsBitFromMask) {
-    buffer_node->AddNewActiveClientsBitToMask();
-    uint32_t current_mask = buffer_node->GetActiveClientsBitMask();
-    uint32_t new_client_state_mask = buffer_node->AddNewActiveClientsBitToMask();
-    EXPECT_NE(buffer_node->GetActiveClientsBitMask(), current_mask);
+    buffer_node->addNewActiveClientsBitToMask();
+    uint32_t current_mask = buffer_node->getActiveClientsBitMask();
+    uint32_t new_client_state_mask = buffer_node->addNewActiveClientsBitToMask();
+    EXPECT_NE(buffer_node->getActiveClientsBitMask(), current_mask);
 
-    buffer_node->RemoveClientsBitFromMask(new_client_state_mask);
-    EXPECT_EQ(buffer_node->GetActiveClientsBitMask(), current_mask);
+    buffer_node->removeClientsBitFromMask(new_client_state_mask);
+    EXPECT_EQ(buffer_node->getActiveClientsBitMask(), current_mask);
 
     // Remove the test_mask again to the active client bit mask should not modify
     // the value of active clients bit mask.
-    buffer_node->RemoveClientsBitFromMask(new_client_state_mask);
-    EXPECT_EQ(buffer_node->GetActiveClientsBitMask(), current_mask);
+    buffer_node->removeClientsBitFromMask(new_client_state_mask);
+    EXPECT_EQ(buffer_node->getActiveClientsBitMask(), current_mask);
 }
 
 } // namespace
diff --git a/services/inputflinger/BlockingQueue.h b/services/inputflinger/BlockingQueue.h
index b892120..c9eb683 100644
--- a/services/inputflinger/BlockingQueue.h
+++ b/services/inputflinger/BlockingQueue.h
@@ -80,6 +80,16 @@
         mQueue.clear();
     };
 
+    /**
+     * How many elements are currently stored in the queue.
+     * Primary used for debugging.
+     * Does not block.
+     */
+    size_t size() {
+        std::scoped_lock lock(mLock);
+        return mQueue.size();
+    }
+
 private:
     size_t mCapacity;
     /**
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index cf9d3c7..c13bac6 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -763,7 +763,7 @@
 }
 
 EventHub::Device* EventHub::getDeviceLocked(int32_t deviceId) const {
-    if (deviceId == BUILT_IN_KEYBOARD_ID) {
+    if (deviceId == ReservedInputDeviceId::BUILT_IN_KEYBOARD_ID) {
         deviceId = mBuiltInKeyboardId;
     }
     ssize_t index = mDevices.indexOfKey(deviceId);
@@ -835,7 +835,8 @@
                  device->id, device->path.c_str());
             mClosingDevices = device->next;
             event->when = now;
-            event->deviceId = device->id == mBuiltInKeyboardId ? BUILT_IN_KEYBOARD_ID : device->id;
+            event->deviceId = (device->id == mBuiltInKeyboardId) ?
+                    ReservedInputDeviceId::BUILT_IN_KEYBOARD_ID : device->id;
             event->type = DEVICE_REMOVED;
             event += 1;
             delete device;
@@ -1081,7 +1082,7 @@
             ALOGE("scan video dir failed for %s", VIDEO_DEVICE_PATH);
         }
     }
-    if (mDevices.indexOfKey(VIRTUAL_KEYBOARD_ID) < 0) {
+    if (mDevices.indexOfKey(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID) < 0) {
         createVirtualKeyboardLocked();
     }
 }
@@ -1580,7 +1581,8 @@
     identifier.uniqueId = "<virtual>";
     assignDescriptorLocked(identifier);
 
-    Device* device = new Device(-1, VIRTUAL_KEYBOARD_ID, "<virtual>", identifier);
+    Device* device = new Device(-1, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, "<virtual>",
+            identifier);
     device->classes = INPUT_DEVICE_CLASS_KEYBOARD
             | INPUT_DEVICE_CLASS_ALPHAKEY
             | INPUT_DEVICE_CLASS_DPAD
diff --git a/services/inputflinger/include/EventHub.h b/services/inputflinger/EventHub.h
similarity index 98%
rename from services/inputflinger/include/EventHub.h
rename to services/inputflinger/EventHub.h
index 295aca8..d176648 100644
--- a/services/inputflinger/include/EventHub.h
+++ b/services/inputflinger/EventHub.h
@@ -46,13 +46,6 @@
 
 namespace android {
 
-enum {
-    // Device id of a special "virtual" keyboard that is always present.
-    VIRTUAL_KEYBOARD_ID = -1,
-    // Device id of the "built-in" keyboard if there is one.
-    BUILT_IN_KEYBOARD_ID = 0,
-};
-
 /*
  * A raw event as retrieved from the EventHub.
  */
diff --git a/services/inputflinger/InputClassifier.cpp b/services/inputflinger/InputClassifier.cpp
index 7ade0d4..09a004c 100644
--- a/services/inputflinger/InputClassifier.cpp
+++ b/services/inputflinger/InputClassifier.cpp
@@ -19,6 +19,7 @@
 #include "InputClassifier.h"
 
 #include <algorithm>
+#include <android-base/stringprintf.h>
 #include <cmath>
 #include <inttypes.h>
 #include <log/log.h>
@@ -26,9 +27,17 @@
     #include <pthread.h>
 #endif
 #include <server_configurable_flags/get_flags.h>
+#include <unordered_set>
 
 #include <android/hardware/input/classifier/1.0/IInputClassifier.h>
 
+#define INDENT1 "  "
+#define INDENT2 "    "
+#define INDENT3 "      "
+#define INDENT4 "        "
+#define INDENT5 "          "
+
+using android::base::StringPrintf;
 using android::hardware::hidl_bitfield;
 using android::hardware::hidl_vec;
 using namespace android::hardware::input;
@@ -646,6 +655,30 @@
     mEvents.push(std::make_unique<NotifyDeviceResetArgs>(args));
 }
 
+void MotionClassifier::dump(std::string& dump) {
+    std::scoped_lock lock(mLock);
+    std::string serviceStatus = mService->ping().isOk() ? "running" : " not responding";
+    dump += StringPrintf(INDENT2 "mService status: %s\n", serviceStatus.c_str());
+    dump += StringPrintf(INDENT2 "mEvents: %zu element(s) (max=%zu)\n",
+            mEvents.size(), MAX_EVENTS);
+    dump += INDENT2 "mClassifications, mLastDownTimes:\n";
+    dump += INDENT3 "Device Id\tClassification\tLast down time";
+    // Combine mClassifications and mLastDownTimes into a single table.
+    // Create a superset of device ids.
+    std::unordered_set<int32_t> deviceIds;
+    std::for_each(mClassifications.begin(), mClassifications.end(),
+            [&deviceIds](auto pair){ deviceIds.insert(pair.first); });
+    std::for_each(mLastDownTimes.begin(), mLastDownTimes.end(),
+            [&deviceIds](auto pair){ deviceIds.insert(pair.first); });
+    for(int32_t deviceId : deviceIds) {
+        const MotionClassification classification =
+                getValueForKey(mClassifications, deviceId, MotionClassification::NONE);
+        const nsecs_t downTime = getValueForKey(mLastDownTimes, deviceId, static_cast<nsecs_t>(0));
+        dump += StringPrintf("\n" INDENT4 "%" PRId32 "\t%s\t%" PRId64,
+                deviceId, motionClassificationToString(classification), downTime);
+    }
+}
+
 // --- InputClassifier ---
 
 InputClassifier::InputClassifier(const sp<InputListenerInterface>& listener) :
@@ -694,4 +727,16 @@
     mListener->notifyDeviceReset(args);
 }
 
+void InputClassifier::dump(std::string& dump) {
+    dump += "Input Classifier State:\n";
+
+    dump += INDENT1 "Motion Classifier:\n";
+    if (mMotionClassifier) {
+        mMotionClassifier->dump(dump);
+    } else {
+        dump += INDENT2 "<nullptr>";
+    }
+    dump += "\n";
+}
+
 } // namespace android
\ No newline at end of file
diff --git a/services/inputflinger/InputClassifier.h b/services/inputflinger/InputClassifier.h
index cb46494..4b9dae2 100644
--- a/services/inputflinger/InputClassifier.h
+++ b/services/inputflinger/InputClassifier.h
@@ -70,6 +70,11 @@
     virtual MotionClassification classify(const NotifyMotionArgs& args) = 0;
     virtual void reset() = 0;
     virtual void reset(const NotifyDeviceResetArgs& args) = 0;
+
+    /**
+     * Dump the state of the motion classifier
+     */
+    virtual void dump(std::string& dump) = 0;
 };
 
 /**
@@ -77,6 +82,12 @@
  * Provides classification to events.
  */
 class InputClassifierInterface : public virtual RefBase, public InputListenerInterface {
+public:
+    /**
+     * Dump the state of the input classifier.
+     * This method may be called on any thread (usually by the input manager).
+     */
+    virtual void dump(std::string& dump) = 0;
 protected:
     InputClassifierInterface() { }
     virtual ~InputClassifierInterface() { }
@@ -110,6 +121,8 @@
     virtual void reset() override;
     virtual void reset(const NotifyDeviceResetArgs& args) override;
 
+    virtual void dump(std::string& dump) override;
+
 private:
     // The events that need to be sent to the HAL.
     BlockingQueue<ClassifierEvent> mEvents;
@@ -186,6 +199,8 @@
     virtual void notifySwitch(const NotifySwitchArgs* args) override;
     virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) override;
 
+    virtual void dump(std::string& dump) override;
+
 private:
     std::unique_ptr<MotionClassifierInterface> mMotionClassifier = nullptr;
     // The next stage to pass input events to
diff --git a/services/inputflinger/InputListener.cpp b/services/inputflinger/InputListener.cpp
index e537e09..a403f31 100644
--- a/services/inputflinger/InputListener.cpp
+++ b/services/inputflinger/InputListener.cpp
@@ -28,12 +28,12 @@
 
 NotifyConfigurationChangedArgs::NotifyConfigurationChangedArgs(
         uint32_t sequenceNum, nsecs_t eventTime) :
-        NotifyArgs(sequenceNum), eventTime(eventTime) {
+        NotifyArgs(sequenceNum, eventTime) {
 }
 
 NotifyConfigurationChangedArgs::NotifyConfigurationChangedArgs(
         const NotifyConfigurationChangedArgs& other) :
-        NotifyArgs(other.sequenceNum), eventTime(other.eventTime) {
+        NotifyArgs(other.sequenceNum, other.eventTime) {
 }
 
 bool NotifyConfigurationChangedArgs::operator==(const NotifyConfigurationChangedArgs& rhs) const {
@@ -51,14 +51,14 @@
         uint32_t source, int32_t displayId, uint32_t policyFlags,
         int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
         int32_t metaState, nsecs_t downTime) :
-        NotifyArgs(sequenceNum), eventTime(eventTime), deviceId(deviceId), source(source),
+        NotifyArgs(sequenceNum, eventTime), deviceId(deviceId), source(source),
         displayId(displayId), policyFlags(policyFlags),
         action(action), flags(flags), keyCode(keyCode), scanCode(scanCode),
         metaState(metaState), downTime(downTime) {
 }
 
 NotifyKeyArgs::NotifyKeyArgs(const NotifyKeyArgs& other) :
-        NotifyArgs(other.sequenceNum), eventTime(other.eventTime), deviceId(other.deviceId),
+        NotifyArgs(other.sequenceNum, other.eventTime), deviceId(other.deviceId),
         source(other.source), displayId(other.displayId), policyFlags(other.policyFlags),
         action(other.action), flags(other.flags),
         keyCode(other.keyCode), scanCode(other.scanCode),
@@ -95,7 +95,7 @@
         const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
         float xPrecision, float yPrecision, nsecs_t downTime,
         const std::vector<TouchVideoFrame>& videoFrames) :
-        NotifyArgs(sequenceNum), eventTime(eventTime), deviceId(deviceId), source(source),
+        NotifyArgs(sequenceNum, eventTime), deviceId(deviceId), source(source),
         displayId(displayId), policyFlags(policyFlags),
         action(action), actionButton(actionButton),
         flags(flags), metaState(metaState), buttonState(buttonState),
@@ -110,7 +110,7 @@
 }
 
 NotifyMotionArgs::NotifyMotionArgs(const NotifyMotionArgs& other) :
-        NotifyArgs(other.sequenceNum), eventTime(other.eventTime), deviceId(other.deviceId),
+        NotifyArgs(other.sequenceNum, other.eventTime), deviceId(other.deviceId),
         source(other.source), displayId(other.displayId), policyFlags(other.policyFlags),
         action(other.action), actionButton(other.actionButton), flags(other.flags),
         metaState(other.metaState), buttonState(other.buttonState),
@@ -170,12 +170,12 @@
 
 NotifySwitchArgs::NotifySwitchArgs(uint32_t sequenceNum, nsecs_t eventTime, uint32_t policyFlags,
         uint32_t switchValues, uint32_t switchMask) :
-        NotifyArgs(sequenceNum), eventTime(eventTime), policyFlags(policyFlags),
+        NotifyArgs(sequenceNum, eventTime), policyFlags(policyFlags),
         switchValues(switchValues), switchMask(switchMask) {
 }
 
 NotifySwitchArgs::NotifySwitchArgs(const NotifySwitchArgs& other) :
-        NotifyArgs(other.sequenceNum), eventTime(other.eventTime), policyFlags(other.policyFlags),
+        NotifyArgs(other.sequenceNum, other.eventTime), policyFlags(other.policyFlags),
         switchValues(other.switchValues), switchMask(other.switchMask) {
 }
 
@@ -196,11 +196,11 @@
 
 NotifyDeviceResetArgs::NotifyDeviceResetArgs(
         uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId) :
-        NotifyArgs(sequenceNum), eventTime(eventTime), deviceId(deviceId) {
+        NotifyArgs(sequenceNum, eventTime), deviceId(deviceId) {
 }
 
 NotifyDeviceResetArgs::NotifyDeviceResetArgs(const NotifyDeviceResetArgs& other) :
-        NotifyArgs(other.sequenceNum), eventTime(other.eventTime), deviceId(other.deviceId) {
+        NotifyArgs(other.sequenceNum, other.eventTime), deviceId(other.deviceId) {
 }
 
 bool NotifyDeviceResetArgs::operator==(const NotifyDeviceResetArgs& rhs) const {
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index b3b9e3e..a7fd9ba 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -84,6 +84,10 @@
     return mReader;
 }
 
+sp<InputClassifierInterface> InputManager::getClassifier() {
+    return mClassifier;
+}
+
 sp<InputDispatcherInterface> InputManager::getDispatcher() {
     return mDispatcher;
 }
diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h
index 142ec0c..e632da3 100644
--- a/services/inputflinger/InputManager.h
+++ b/services/inputflinger/InputManager.h
@@ -90,6 +90,7 @@
     virtual status_t stop();
 
     virtual sp<InputReaderInterface> getReader();
+    virtual sp<InputClassifierInterface> getClassifier();
     virtual sp<InputDispatcherInterface> getDispatcher();
 
     virtual void setInputWindows(const Vector<InputWindowInfo>& handles);
diff --git a/services/inputflinger/include/TouchVideoDevice.h b/services/inputflinger/TouchVideoDevice.h
similarity index 96%
rename from services/inputflinger/include/TouchVideoDevice.h
rename to services/inputflinger/TouchVideoDevice.h
index 7ff2653..3d5c8c6 100644
--- a/services/inputflinger/include/TouchVideoDevice.h
+++ b/services/inputflinger/TouchVideoDevice.h
@@ -73,6 +73,8 @@
     size_t readAndQueueFrames();
     /**
      * Return all of the queued frames, and erase them from the local buffer.
+     * The returned frames are in the order that they were received from the
+     * v4l2 device, with the oldest frame at the index 0.
      */
     std::vector<TouchVideoFrame> consumeFrames();
     /**
diff --git a/services/inputflinger/include/InputListener.h b/services/inputflinger/include/InputListener.h
index 13ae7dd..cd8caf7 100644
--- a/services/inputflinger/include/InputListener.h
+++ b/services/inputflinger/include/InputListener.h
@@ -32,10 +32,12 @@
 /* Superclass of all input event argument objects */
 struct NotifyArgs {
     uint32_t sequenceNum;
+    nsecs_t eventTime;
 
-    inline NotifyArgs() : sequenceNum(0) { }
+    inline NotifyArgs() : sequenceNum(0), eventTime(0) { }
 
-    inline explicit NotifyArgs(uint32_t sequenceNum) : sequenceNum(sequenceNum) { }
+    inline explicit NotifyArgs(uint32_t sequenceNum, nsecs_t eventTime) :
+            sequenceNum(sequenceNum), eventTime(eventTime) { }
 
     virtual ~NotifyArgs() { }
 
@@ -45,7 +47,6 @@
 
 /* Describes a configuration change event. */
 struct NotifyConfigurationChangedArgs : public NotifyArgs {
-    nsecs_t eventTime;
 
     inline NotifyConfigurationChangedArgs() { }
 
@@ -63,7 +64,6 @@
 
 /* Describes a key event. */
 struct NotifyKeyArgs : public NotifyArgs {
-    nsecs_t eventTime;
     int32_t deviceId;
     uint32_t source;
     int32_t displayId;
@@ -93,7 +93,6 @@
 
 /* Describes a motion event. */
 struct NotifyMotionArgs : public NotifyArgs {
-    nsecs_t eventTime;
     int32_t deviceId;
     uint32_t source;
     int32_t displayId;
@@ -146,7 +145,6 @@
 
 /* Describes a switch event. */
 struct NotifySwitchArgs : public NotifyArgs {
-    nsecs_t eventTime;
     uint32_t policyFlags;
     uint32_t switchValues;
     uint32_t switchMask;
@@ -169,7 +167,6 @@
 /* Describes a device reset event, such as when a device is added,
  * reconfigured, or removed. */
 struct NotifyDeviceResetArgs : public NotifyArgs {
-    nsecs_t eventTime;
     int32_t deviceId;
 
     inline NotifyDeviceResetArgs() { }
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 65308a6..63748bf 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -57,8 +57,6 @@
                 compositionengine::LayerCreationArgs{this})} {
     ALOGV("Creating Layer %s", args.name.string());
 
-    mTexture.init(renderengine::Texture::TEXTURE_EXTERNAL, mTextureName);
-
     mPremultipliedAlpha = !(args.flags & ISurfaceComposerClient::eNonPremultiplied);
 
     mPotentialCursor = args.flags & ISurfaceComposerClient::eCursorWindow;
@@ -129,13 +127,11 @@
     return inverse(tr);
 }
 
-/*
- * onDraw will draw the current layer onto the presentable buffer
- */
-void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip,
-                         bool useIdentityTransform) {
+bool BufferLayer::prepareClientLayer(const RenderArea& renderArea, const Region& clip,
+                                     bool useIdentityTransform, Region& clearRegion,
+                                     renderengine::LayerSettings& layer) {
     ATRACE_CALL();
-
+    Layer::prepareClientLayer(renderArea, clip, useIdentityTransform, clearRegion, layer);
     if (CC_UNLIKELY(mActiveBuffer == 0)) {
         // the texture has not been created yet, this Layer has
         // in fact never been drawn into. This happens frequently with
@@ -153,30 +149,27 @@
                 finished = true;
                 return;
             }
-            under.orSelf(renderArea.getTransform().transform(layer->visibleRegion));
+            under.orSelf(layer->visibleRegion);
         });
         // if not everything below us is covered, we plug the holes!
         Region holes(clip.subtract(under));
         if (!holes.isEmpty()) {
-            clearWithOpenGL(renderArea, 0, 0, 0, 1);
+            clearRegion.orSelf(holes);
         }
-        return;
+        return false;
     }
-
-    // Bind the current buffer to the GL texture, and wait for it to be
-    // ready for us to draw into.
-    status_t err = bindTextureImage();
-    if (err != NO_ERROR) {
-        ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
-        // Go ahead and draw the buffer anyway; no matter what we do the screen
-        // is probably going to have something visibly wrong.
-    }
-
     bool blackOutLayer = isProtected() || (isSecure() && !renderArea.isSecure());
-
-    auto& engine(mFlinger->getRenderEngine());
-
+    const State& s(getDrawingState());
     if (!blackOutLayer) {
+        layer.source.buffer.buffer = mActiveBuffer;
+        layer.source.buffer.isOpaque = isOpaque(s);
+        layer.source.buffer.fence = mActiveBufferFence;
+        layer.source.buffer.cacheHint = useCachedBufferForClientComposition()
+                ? renderengine::Buffer::CachingHint::USE_CACHE
+                : renderengine::Buffer::CachingHint::NO_CACHE;
+        layer.source.buffer.textureName = mTextureName;
+        layer.source.buffer.usePremultipliedAlpha = getPremultipledAlpha();
+        layer.source.buffer.isY410BT2020 = isHdrY410();
         // TODO: we could be more subtle with isFixedSize()
         const bool useFiltering = needsFiltering() || renderArea.needsFiltering() || isFixedSize();
 
@@ -213,17 +206,31 @@
             memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
         }
 
-        // Set things up for texturing.
-        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
-        mTexture.setFiltering(useFiltering);
-        mTexture.setMatrix(textureMatrix);
+        const Rect win{computeBounds()};
+        const float bufferWidth = getBufferSize(s).getWidth();
+        const float bufferHeight = getBufferSize(s).getHeight();
 
-        engine.setupLayerTexturing(mTexture);
+        const float scaleHeight = (float(win.bottom) - float(win.top)) / bufferHeight;
+        const float scaleWidth = (float(win.right) - float(win.left)) / bufferWidth;
+        const float translateY = float(win.top) / bufferHeight;
+        const float translateX = float(win.left) / bufferWidth;
+
+        // Flip y-coordinates because GLConsumer expects OpenGL convention.
+        mat4 tr = mat4::translate(vec4(.5, .5, 0, 1)) * mat4::scale(vec4(1, -1, 1, 1)) *
+                mat4::translate(vec4(-.5, -.5, 0, 1)) *
+                mat4::translate(vec4(translateX, translateY, 0, 1)) *
+                mat4::scale(vec4(scaleWidth, scaleHeight, 1.0, 1.0));
+
+        layer.source.buffer.useTextureFiltering = useFiltering;
+        layer.source.buffer.textureTransform = mat4(static_cast<const float*>(textureMatrix)) * tr;
     } else {
-        engine.setupLayerBlackedOut();
+        // If layer is blacked out, force alpha to 1 so that we draw a black color
+        // layer.
+        layer.source.buffer.buffer = nullptr;
+        layer.alpha = 1.0;
     }
-    drawWithOpenGL(renderArea, useIdentityTransform);
-    engine.disableTexturing();
+
+    return true;
 }
 
 bool BufferLayer::isHdrY410() const {
@@ -365,20 +372,18 @@
     return true;
 }
 
-Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                                const sp<Fence>& releaseFence) {
+bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
+                              const sp<Fence>& releaseFence) {
     ATRACE_CALL();
 
-    std::optional<Region> sidebandStreamDirtyRegion = latchSidebandStream(recomputeVisibleRegions);
+    bool refreshRequired = latchSidebandStream(recomputeVisibleRegions);
 
-    if (sidebandStreamDirtyRegion) {
-        return *sidebandStreamDirtyRegion;
+    if (refreshRequired) {
+        return refreshRequired;
     }
 
-    Region dirtyRegion;
-
     if (!hasReadyFrame()) {
-        return dirtyRegion;
+        return false;
     }
 
     // if we've already called updateTexImage() without going through
@@ -387,14 +392,14 @@
     // compositionComplete() call.
     // we'll trigger an update in onPreComposition().
     if (mRefreshPending) {
-        return dirtyRegion;
+        return false;
     }
 
     // If the head buffer's acquire fence hasn't signaled yet, return and
     // try again later
     if (!fenceHasSignaled()) {
         mFlinger->signalLayerUpdate();
-        return dirtyRegion;
+        return false;
     }
 
     // Capture the old state of the layer for comparisons later
@@ -404,24 +409,24 @@
 
     if (!allTransactionsSignaled()) {
         mFlinger->signalLayerUpdate();
-        return dirtyRegion;
+        return false;
     }
 
     status_t err = updateTexImage(recomputeVisibleRegions, latchTime, releaseFence);
     if (err != NO_ERROR) {
-        return dirtyRegion;
+        return false;
     }
 
     err = updateActiveBuffer();
     if (err != NO_ERROR) {
-        return dirtyRegion;
+        return false;
     }
 
     mBufferLatched = true;
 
     err = updateFrameNumber(latchTime);
     if (err != NO_ERROR) {
-        return dirtyRegion;
+        return false;
     }
 
     mRefreshPending = true;
@@ -461,11 +466,14 @@
     Rect crop(getDrawingCrop());
     const uint32_t transform(getDrawingTransform());
     const uint32_t scalingMode(getDrawingScalingMode());
+    const bool transformToDisplayInverse(getTransformToDisplayInverse());
     if ((crop != mCurrentCrop) || (transform != mCurrentTransform) ||
-        (scalingMode != mCurrentScalingMode)) {
+        (scalingMode != mCurrentScalingMode) ||
+        (transformToDisplayInverse != mTransformToDisplayInverse)) {
         mCurrentCrop = crop;
         mCurrentTransform = transform;
         mCurrentScalingMode = scalingMode;
+        mTransformToDisplayInverse = transformToDisplayInverse;
         recomputeVisibleRegions = true;
     }
 
@@ -502,9 +510,7 @@
         }
     }
 
-    // FIXME: postedRegion should be dirty & bounds
-    // transform the dirty region to window-manager space
-    return getTransform().transform(Region(getBufferSize(s)));
+    return true;
 }
 
 // transaction
@@ -606,67 +612,6 @@
             sourceCrop.getWidth() != displayFrame.getWidth();
 }
 
-void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const {
-    ATRACE_CALL();
-    const State& s(getDrawingState());
-
-    computeGeometry(renderArea, getBE().mMesh, useIdentityTransform);
-
-    /*
-     * NOTE: the way we compute the texture coordinates here produces
-     * different results than when we take the HWC path -- in the later case
-     * the "source crop" is rounded to texel boundaries.
-     * This can produce significantly different results when the texture
-     * is scaled by a large amount.
-     *
-     * The GL code below is more logical (imho), and the difference with
-     * HWC is due to a limitation of the HWC API to integers -- a question
-     * is suspend is whether we should ignore this problem or revert to
-     * GL composition when a buffer scaling is applied (maybe with some
-     * minimal value)? Or, we could make GL behave like HWC -- but this feel
-     * like more of a hack.
-     */
-    const Rect bounds{computeBounds()}; // Rounds from FloatRect
-
-    Rect win = bounds;
-    const int bufferWidth = getBufferSize(s).getWidth();
-    const int bufferHeight = getBufferSize(s).getHeight();
-
-    const float left = float(win.left) / float(bufferWidth);
-    const float top = float(win.top) / float(bufferHeight);
-    const float right = float(win.right) / float(bufferWidth);
-    const float bottom = float(win.bottom) / float(bufferHeight);
-
-    // TODO: we probably want to generate the texture coords with the mesh
-    // here we assume that we only have 4 vertices
-    renderengine::Mesh::VertexArray<vec2> texCoords(getBE().mMesh.getTexCoordArray<vec2>());
-    // flip texcoords vertically because BufferLayerConsumer expects them to be in GL convention
-    texCoords[0] = vec2(left, 1.0f - top);
-    texCoords[1] = vec2(left, 1.0f - bottom);
-    texCoords[2] = vec2(right, 1.0f - bottom);
-    texCoords[3] = vec2(right, 1.0f - top);
-
-    const auto roundedCornerState = getRoundedCornerState();
-    const auto cropRect = roundedCornerState.cropRect;
-    setupRoundedCornersCropCoordinates(win, cropRect);
-
-    auto& engine(mFlinger->getRenderEngine());
-    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), false /* disableTexture */,
-                              getColor(), roundedCornerState.radius);
-    engine.setSourceDataSpace(mCurrentDataSpace);
-
-    if (isHdrY410()) {
-        engine.setSourceY410BT2020(true);
-    }
-
-    engine.setupCornerRadiusCropSize(cropRect.getWidth(), cropRect.getHeight());
-
-    engine.drawMesh(getBE().mMesh);
-    engine.disableBlending();
-
-    engine.setSourceY410BT2020(false);
-}
-
 uint64_t BufferLayer::getHeadFrameNumber() const {
     if (hasFrameUpdate()) {
         return getFrameNumber();
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 8158d6c..c118b78 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -22,6 +22,7 @@
 
 #include <gui/ISurfaceComposerClient.h>
 #include <gui/LayerState.h>
+#include <renderengine/Image.h>
 #include <renderengine/Mesh.h>
 #include <renderengine/Texture.h>
 #include <system/window.h> // For NATIVE_WINDOW_SCALING_MODE_FREEZE
@@ -77,10 +78,6 @@
     // isFixedSize - true if content has a fixed size
     bool isFixedSize() const override;
 
-    // onDraw - draws the surface.
-    void onDraw(const RenderArea& renderArea, const Region& clip,
-                bool useIdentityTransform) override;
-
     bool isHdrY410() const override;
 
     void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport,
@@ -99,8 +96,8 @@
     // If there was a GL composition step rendering the previous frame, then
     // releaseFence will be populated with a native fence that fires when
     // composition has completed.
-    Region latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                       const sp<Fence>& releaseFence) override;
+    bool latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
+                     const sp<Fence>& releaseFence) override;
 
     bool isBufferLatched() const override { return mRefreshPending; }
 
@@ -137,7 +134,8 @@
     virtual bool getAutoRefresh() const = 0;
     virtual bool getSidebandStreamChanged() const = 0;
 
-    virtual std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) = 0;
+    // Latch sideband stream and returns true if the dirty region should be updated.
+    virtual bool latchSidebandStream(bool& recomputeVisibleRegions) = 0;
 
     virtual bool hasFrameUpdate() const = 0;
 
@@ -168,23 +166,28 @@
 
     bool mRefreshPending{false};
 
+    // Returns true if, when drawing the active buffer during gpu compositon, we
+    // should use a cached buffer or not.
+    virtual bool useCachedBufferForClientComposition() const = 0;
+
+    // prepareClientLayer - constructs a RenderEngine layer for GPU composition.
+    bool prepareClientLayer(const RenderArea& renderArea, const Region& clip,
+                            bool useIdentityTransform, Region& clearRegion,
+                            renderengine::LayerSettings& layer);
+
 private:
     // Returns true if this layer requires filtering
     bool needsFiltering() const;
 
-    // drawing
-    void drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const;
-
     uint64_t getHeadFrameNumber() const;
 
     uint32_t mCurrentScalingMode{NATIVE_WINDOW_SCALING_MODE_FREEZE};
 
+    bool mTransformToDisplayInverse{false};
+
     // main thread.
     bool mBufferLatched{false}; // TODO: Use mActiveBuffer?
 
-    // The texture used to draw the layer in GLES composition mode
-    mutable renderengine::Texture mTexture;
-
     Rect getBufferSize(const State& s) const override;
 
     std::shared_ptr<compositionengine::Layer> mCompositionLayer;
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp
index 6826050..7ed8184 100644
--- a/services/surfaceflinger/BufferLayerConsumer.cpp
+++ b/services/surfaceflinger/BufferLayerConsumer.cpp
@@ -272,6 +272,7 @@
     // Update the BufferLayerConsumer state.
     mCurrentTexture = slot;
     mCurrentTextureBuffer = nextTextureBuffer;
+    mCurrentTextureBufferStaleForGpu = false;
     mCurrentTextureImageFreed = nullptr;
     mCurrentCrop = item.mCrop;
     mCurrentTransform = item.mTransform;
@@ -294,48 +295,7 @@
 status_t BufferLayerConsumer::bindTextureImageLocked() {
     ATRACE_CALL();
 
-    mRE.checkErrors();
-
-    // It is possible for the current slot's buffer to be freed before a new one
-    // is bound. In that scenario we still want to bind the image.
-    if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureBuffer == nullptr) {
-        BLC_LOGE("bindTextureImage: no currently-bound texture");
-        mRE.bindExternalTextureImage(mTexName, *mRE.createImage());
-        return NO_INIT;
-    }
-
-    renderengine::Image* imageToRender;
-
-    // mCurrentTextureImageFreed is non-null iff mCurrentTexture ==
-    // BufferQueue::INVALID_BUFFER_SLOT, so we can omit that check.
-    if (mCurrentTextureImageFreed) {
-        imageToRender = mCurrentTextureImageFreed.get();
-    } else if (mImages[mCurrentTexture]) {
-        imageToRender = mImages[mCurrentTexture].get();
-    } else {
-        std::unique_ptr<renderengine::Image> image = mRE.createImage();
-        bool success = image->setNativeWindowBuffer(mCurrentTextureBuffer->getNativeBuffer(),
-                                                    mCurrentTextureBuffer->getUsage() &
-                                                            GRALLOC_USAGE_PROTECTED);
-        if (!success) {
-            BLC_LOGE("bindTextureImage: Failed to create image. size=%ux%u st=%u usage=%#" PRIx64
-                     " fmt=%d",
-                     mCurrentTextureBuffer->getWidth(), mCurrentTextureBuffer->getHeight(),
-                     mCurrentTextureBuffer->getStride(), mCurrentTextureBuffer->getUsage(),
-                     mCurrentTextureBuffer->getPixelFormat());
-            BLC_LOGW("bindTextureImage: can't create image on slot=%d", mCurrentTexture);
-            mRE.bindExternalTextureImage(mTexName, *image);
-            return UNKNOWN_ERROR;
-        }
-        imageToRender = image.get();
-        // Cache the image here so that we can reuse it.
-        mImages[mCurrentTexture] = std::move(image);
-    }
-
-    mRE.bindExternalTextureImage(mTexName, *imageToRender);
-
-    // Wait for the new buffer to be ready.
-    return doFenceWaitLocked();
+    return mRE.bindExternalTextureBuffer(mTexName, mCurrentTextureBuffer, mCurrentFence, false);
 }
 
 status_t BufferLayerConsumer::syncForReleaseLocked(const sp<Fence>& releaseFence) {
@@ -433,16 +393,29 @@
     return mCurrentApi;
 }
 
-sp<GraphicBuffer> BufferLayerConsumer::getCurrentBuffer(int* outSlot) const {
+sp<GraphicBuffer> BufferLayerConsumer::getCurrentBuffer(int* outSlot, sp<Fence>* outFence) const {
     Mutex::Autolock lock(mMutex);
 
     if (outSlot != nullptr) {
         *outSlot = mCurrentTexture;
     }
 
+    if (outFence != nullptr) {
+        *outFence = mCurrentFence;
+    }
+
     return mCurrentTextureBuffer;
 }
 
+bool BufferLayerConsumer::getAndSetCurrentBufferCacheHint() {
+    Mutex::Autolock lock(mMutex);
+    bool useCache = mCurrentTextureBufferStaleForGpu;
+    // Set the staleness bit here, as this function is only called during a
+    // client composition path.
+    mCurrentTextureBufferStaleForGpu = true;
+    return useCache;
+}
+
 Rect BufferLayerConsumer::getCurrentCrop() const {
     Mutex::Autolock lock(mMutex);
     return (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP)
diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h
index ea46245..e2ef399 100644
--- a/services/surfaceflinger/BufferLayerConsumer.h
+++ b/services/surfaceflinger/BufferLayerConsumer.h
@@ -150,10 +150,16 @@
     // for use with bilinear filtering.
     void setFilteringEnabled(bool enabled);
 
+    // Sets mCurrentTextureBufferStaleForGpu to true to indicate that the
+    // buffer is now "stale" for GPU composition, and returns the old staleness
+    // bit as a caching hint.
+    bool getAndSetCurrentBufferCacheHint();
+
     // getCurrentBuffer returns the buffer associated with the current image.
     // When outSlot is not nullptr, the current buffer slot index is also
-    // returned.
-    sp<GraphicBuffer> getCurrentBuffer(int* outSlot = nullptr) const;
+    // returned. Simiarly, when outFence is not nullptr, the current output
+    // fence is returned.
+    sp<GraphicBuffer> getCurrentBuffer(int* outSlot = nullptr, sp<Fence>* outFence = nullptr) const;
 
     // getCurrentCrop returns the cropping rectangle of the current buffer.
     Rect getCurrentCrop() const;
@@ -255,6 +261,10 @@
     // must track it separately in order to support the getCurrentBuffer method.
     sp<GraphicBuffer> mCurrentTextureBuffer;
 
+    // True if the buffer was used for the previous client composition frame,
+    // and false otherwise.
+    bool mCurrentTextureBufferStaleForGpu;
+
     // mCurrentCrop is the crop rectangle that applies to the current texture.
     // It gets set each time updateTexImage is called.
     Rect mCurrentCrop;
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 42021d1..3915757 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -190,7 +190,7 @@
     return mSidebandStreamChanged;
 }
 
-std::optional<Region> BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
+bool BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
     bool sidebandStreamChanged = true;
     if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false)) {
         // mSidebandStreamChanged was changed to false
@@ -202,10 +202,9 @@
         }
         recomputeVisibleRegions = true;
 
-        const State& s(getDrawingState());
-        return getTransform().transform(Region(Rect(s.active_legacy.w, s.active_legacy.h)));
+        return true;
     }
-    return {};
+    return false;
 }
 
 bool BufferQueueLayer::hasFrameUpdate() const {
@@ -235,9 +234,28 @@
     const nsecs_t expectedPresentTime = mFlinger->mUseScheduler
             ? mFlinger->mScheduler->mPrimaryDispSync->expectedPresentTime()
             : mFlinger->mPrimaryDispSync->expectedPresentTime();
+
+    // updateTexImage() below might drop the some buffers at the head of the queue if there is a
+    // buffer behind them which is timely to be presented. However this buffer may not be signaled
+    // yet. The code below makes sure that this wouldn't happen by setting maxFrameNumber to the
+    // last buffer that was signaled.
+    uint64_t lastSignaledFrameNumber = mLastFrameNumberReceived;
+    {
+        Mutex::Autolock lock(mQueueItemLock);
+        for (int i = 0; i < mQueueItems.size(); i++) {
+            bool fenceSignaled =
+                    mQueueItems[i].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
+            if (!fenceSignaled) {
+                break;
+            }
+            lastSignaledFrameNumber = mQueueItems[i].mFrameNumber;
+        }
+    }
+    const uint64_t maxFrameNumberToAcquire =
+            std::min(mLastFrameNumberReceived.load(), lastSignaledFrameNumber);
     status_t updateResult =
             mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh, &queuedBuffer,
-                                      mLastFrameNumberReceived, releaseFence);
+                                      maxFrameNumberToAcquire, releaseFence);
     if (updateResult == BufferQueue::PRESENT_LATER) {
         // Producer doesn't want buffer to be displayed yet.  Signal a
         // layer update so we check again at the next opportunity.
@@ -306,7 +324,7 @@
 
 status_t BufferQueueLayer::updateActiveBuffer() {
     // update the active buffer
-    mActiveBuffer = mConsumer->getCurrentBuffer(&mActiveBufferSlot);
+    mActiveBuffer = mConsumer->getCurrentBuffer(&mActiveBufferSlot, &mActiveBufferFence);
     getBE().compositionInfo.mBuffer = mActiveBuffer;
     getBE().compositionInfo.mBufferSlot = mActiveBufferSlot;
 
@@ -317,6 +335,10 @@
     return NO_ERROR;
 }
 
+bool BufferQueueLayer::useCachedBufferForClientComposition() const {
+    return mConsumer->getAndSetCurrentBufferCacheHint();
+}
+
 status_t BufferQueueLayer::updateFrameNumber(nsecs_t latchTime) {
     mPreviousFrameNumber = mCurrentFrameNumber;
     mCurrentFrameNumber = mConsumer->getFrameNumber();
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index d7c3f6a..d392a69 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -62,6 +62,9 @@
 public:
     bool fenceHasSignaled() const override;
 
+protected:
+    bool useCachedBufferForClientComposition() const override;
+
 private:
     nsecs_t getDesiredPresentTime() override;
     std::shared_ptr<FenceTime> getCurrentFenceTime() const override;
@@ -81,7 +84,7 @@
     bool getAutoRefresh() const override;
     bool getSidebandStreamChanged() const override;
 
-    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override;
+    bool latchSidebandStream(bool& recomputeVisibleRegions) override;
 
     bool hasFrameUpdate() const override;
 
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 044662c..b0506fe 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -42,6 +42,7 @@
 
 BufferStateLayer::BufferStateLayer(const LayerCreationArgs& args) : BufferLayer(args) {
     mOverrideScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
+    mCurrentState.dataspace = ui::Dataspace::V0_SRGB;
 }
 BufferStateLayer::~BufferStateLayer() = default;
 
@@ -96,7 +97,8 @@
 bool BufferStateLayer::willPresentCurrentTransaction() const {
     // Returns true if the most recent Transaction applied to CurrentState will be presented.
     return getSidebandStreamChanged() || getAutoRefresh() ||
-            (mCurrentState.modified && mCurrentState.buffer != nullptr);
+            (mCurrentState.modified &&
+             (mCurrentState.buffer != nullptr || mCurrentState.bgColorLayer != nullptr));
 }
 
 bool BufferStateLayer::getTransformToDisplayInverse() const {
@@ -420,7 +422,7 @@
     return mSidebandStreamChanged.load();
 }
 
-std::optional<Region> BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
+bool BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
     if (mSidebandStreamChanged.exchange(false)) {
         const State& s(getDrawingState());
         // mSidebandStreamChanged was true
@@ -432,13 +434,14 @@
         }
         recomputeVisibleRegions = true;
 
-        return getTransform().transform(Region(Rect(s.active.w, s.active.h)));
+        return true;
     }
-    return {};
+    return false;
 }
 
 bool BufferStateLayer::hasFrameUpdate() const {
-    return mCurrentStateModified && getCurrentState().buffer != nullptr;
+    const State& c(getCurrentState());
+    return mCurrentStateModified && (c.buffer != nullptr || c.bgColorLayer != nullptr);
 }
 
 void BufferStateLayer::setFilteringEnabled(bool enabled) {
@@ -450,46 +453,7 @@
     const State& s(getDrawingState());
     auto& engine(mFlinger->getRenderEngine());
 
-    engine.checkErrors();
-
-    // TODO(marissaw): once buffers are cached, don't create a new image everytime
-    mTextureImage = engine.createImage();
-
-    bool created =
-            mTextureImage->setNativeWindowBuffer(s.buffer->getNativeBuffer(),
-                                                 s.buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
-    if (!created) {
-        ALOGE("Failed to create image. size=%ux%u st=%u usage=%#" PRIx64 " fmt=%d",
-              s.buffer->getWidth(), s.buffer->getHeight(), s.buffer->getStride(),
-              s.buffer->getUsage(), s.buffer->getPixelFormat());
-        engine.bindExternalTextureImage(mTextureName, *engine.createImage());
-        return NO_INIT;
-    }
-
-    engine.bindExternalTextureImage(mTextureName, *mTextureImage);
-
-    // Wait for the new buffer to be ready.
-    if (s.acquireFence->isValid()) {
-        if (SyncFeatures::getInstance().useWaitSync()) {
-            base::unique_fd fenceFd(s.acquireFence->dup());
-            if (fenceFd == -1) {
-                ALOGE("error dup'ing fence fd: %d", errno);
-                return -errno;
-            }
-            if (!engine.waitFence(std::move(fenceFd))) {
-                ALOGE("failed to wait on fence fd");
-                return UNKNOWN_ERROR;
-            }
-        } else {
-            status_t err = s.acquireFence->waitForever("BufferStateLayer::bindTextureImage");
-            if (err != NO_ERROR) {
-                ALOGE("error waiting for fence: %d", err);
-                return err;
-            }
-        }
-    }
-
-    return NO_ERROR;
+    return engine.bindExternalTextureBuffer(mTextureName, s.buffer, s.acquireFence, false);
 }
 
 status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime,
@@ -497,6 +461,11 @@
     const State& s(getDrawingState());
 
     if (!s.buffer) {
+        if (s.bgColorLayer) {
+            for (auto& handle : mDrawingState.callbackHandles) {
+                handle->latchTime = latchTime;
+            }
+        }
         return NO_ERROR;
     }
 
@@ -612,12 +581,18 @@
     }
 
     mActiveBuffer = s.buffer;
+    mActiveBufferFence = s.acquireFence;
     getBE().compositionInfo.mBuffer = mActiveBuffer;
     getBE().compositionInfo.mBufferSlot = 0;
 
     return NO_ERROR;
 }
 
+bool BufferStateLayer::useCachedBufferForClientComposition() const {
+    // TODO: Store a proper staleness bit to support EGLImage caching.
+    return false;
+}
+
 status_t BufferStateLayer::updateFrameNumber(nsecs_t /*latchTime*/) {
     // TODO(marissaw): support frame history events
     mCurrentFrameNumber = mFrameNumber;
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 3f891d3..ef287b9 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -95,6 +95,9 @@
     // -----------------------------------------------------------------------
     bool fenceHasSignaled() const override;
 
+protected:
+    bool useCachedBufferForClientComposition() const override;
+
 private:
     nsecs_t getDesiredPresentTime() override;
     std::shared_ptr<FenceTime> getCurrentFenceTime() const override;
@@ -114,7 +117,7 @@
     bool getAutoRefresh() const override;
     bool getSidebandStreamChanged() const override;
 
-    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override;
+    bool latchSidebandStream(bool& recomputeVisibleRegions) override;
 
     bool hasFrameUpdate() const override;
 
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index b4e9d17..d82ff0e 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -44,28 +44,14 @@
 
 ColorLayer::~ColorLayer() = default;
 
-void ColorLayer::onDraw(const RenderArea& renderArea, const Region& /* clip */,
-                        bool useIdentityTransform) {
-    half4 color = getColor();
-    if (color.a > 0) {
-        renderengine::Mesh mesh(renderengine::Mesh::TRIANGLE_FAN, 4, 2);
-        computeGeometry(renderArea, mesh, useIdentityTransform);
-        auto& engine(mFlinger->getRenderEngine());
-
-        Rect win{computeBounds()};
-
-        const auto roundedCornerState = getRoundedCornerState();
-        const auto cropRect = roundedCornerState.cropRect;
-        setupRoundedCornersCropCoordinates(win, cropRect);
-
-        engine.setupLayerBlending(getPremultipledAlpha(), false /* opaque */,
-                                  true /* disableTexture */, color, roundedCornerState.radius);
-
-        engine.setSourceDataSpace(mCurrentDataSpace);
-        engine.setupCornerRadiusCropSize(cropRect.getWidth(), cropRect.getHeight());
-        engine.drawMesh(mesh);
-        engine.disableBlending();
-    }
+bool ColorLayer::prepareClientLayer(const RenderArea& renderArea, const Region& clip,
+                                    bool useIdentityTransform, Region& clearRegion,
+                                    renderengine::LayerSettings& layer) {
+    Layer::prepareClientLayer(renderArea, clip, useIdentityTransform, clearRegion, layer);
+    half4 color(getColor());
+    half3 solidColor(color.r, color.g, color.b);
+    layer.source.solidColor = solidColor;
+    return true;
 }
 
 bool ColorLayer::isVisible() const {
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index 3b98e8c..ed4c2d8 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -31,8 +31,6 @@
     std::shared_ptr<compositionengine::Layer> getCompositionLayer() const override;
 
     virtual const char* getTypeId() const { return "ColorLayer"; }
-    virtual void onDraw(const RenderArea& renderArea, const Region& clip,
-                        bool useIdentityTransform);
     bool isVisible() const override;
 
     bool setColor(const half3& color) override;
@@ -44,6 +42,9 @@
 
 protected:
     FloatRect computeCrop(const sp<const DisplayDevice>& /*display*/) const override { return {}; }
+    virtual bool prepareClientLayer(const RenderArea& renderArea, const Region& clip,
+                                    bool useIdentityTransform, Region& clearRegion,
+                                    renderengine::LayerSettings& layer);
 
 private:
     std::shared_ptr<compositionengine::Layer> mCompositionLayer;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
index a7ab472..84b2423 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
@@ -97,10 +97,9 @@
     // TODO(lpique): Make this protected once it is only internally called.
     virtual OutputCompositionState& editState() = 0;
 
-    // Gets the physical space dirty region. If repaintEverything is true, this
-    // will be the full display bounds. Internally the dirty region is stored in
-    // logical (aka layer stack) space.
-    virtual Region getPhysicalSpaceDirtyRegion(bool repaintEverything) const = 0;
+    // Gets the dirty region in layer stack space.
+    // If repaintEverything is true, this will be the full display bounds.
+    virtual Region getDirtyRegion(bool repaintEverything) const = 0;
 
     // Tests whether a given layerStackId belongs in this output.
     // A layer belongs to the output if its layerStackId matches the of the output layerStackId,
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
index dd01b05..ddeb730 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
@@ -75,16 +75,13 @@
     // Allocates a buffer as scratch space for GPU composition
     virtual sp<GraphicBuffer> dequeueBuffer() = 0;
 
-    // Queues the drawn buffer for consumption by HWC
-    virtual void queueBuffer() = 0;
+    // Queues the drawn buffer for consumption by HWC. readyFence is the fence
+    // which will fire when the buffer is ready for consumption.
+    virtual void queueBuffer(base::unique_fd&& readyFence) = 0;
 
     // Called after the HWC calls are made to present the display
     virtual void onPresentDisplayCompleted() = 0;
 
-    // Marks the current buffer has finished, so that it can be presented and
-    // swapped out
-    virtual void finishBuffer() = 0;
-
     // Called to set the viewport and projection state for rendering into this
     // surface
     virtual void setViewportAndProjection() = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index d876c03..3fd057c 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -61,7 +61,7 @@
     const OutputCompositionState& getState() const override;
     OutputCompositionState& editState() override;
 
-    Region getPhysicalSpaceDirtyRegion(bool repaintEverything) const override;
+    Region getDirtyRegion(bool repaintEverything) const override;
     bool belongsInOutput(uint32_t, bool) const override;
 
     compositionengine::OutputLayer* getOutputLayerForLayer(
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
index 0489310..2f0fceb 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
@@ -53,9 +53,8 @@
     status_t beginFrame(bool mustRecompose) override;
     status_t prepareFrame(std::vector<CompositionInfo>& compositionData) override;
     sp<GraphicBuffer> dequeueBuffer() override;
-    void queueBuffer() override;
+    void queueBuffer(base::unique_fd&& readyFence) override;
     void onPresentDisplayCompleted() override;
-    void finishBuffer() override;
     void setViewportAndProjection() override;
     void flip() override;
 
@@ -77,9 +76,6 @@
     const sp<ANativeWindow> mNativeWindow;
     // Current buffer being rendered into
     sp<GraphicBuffer> mGraphicBuffer;
-    // File descriptor indicating that mGraphicBuffer is ready for display, i.e.
-    // that drawing to the buffer is now complete.
-    base::unique_fd mBufferReady;
     const sp<DisplaySurface> mDisplaySurface;
     ui::Size mSize;
     std::uint32_t mPageFlipCount{0};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
index e79a44c..2972ad7 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
@@ -56,7 +56,7 @@
     MOCK_CONST_METHOD0(getState, const OutputCompositionState&());
     MOCK_METHOD0(editState, OutputCompositionState&());
 
-    MOCK_CONST_METHOD1(getPhysicalSpaceDirtyRegion, Region(bool));
+    MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
     MOCK_CONST_METHOD2(belongsInOutput, bool(uint32_t, bool));
 
     MOCK_CONST_METHOD1(getOutputLayerForLayer,
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
index 2269e57..e9ff330 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
@@ -39,9 +39,8 @@
     MOCK_METHOD1(beginFrame, status_t(bool mustRecompose));
     MOCK_METHOD1(prepareFrame, status_t(std::vector<CompositionInfo>& compositionData));
     MOCK_METHOD0(dequeueBuffer, sp<GraphicBuffer>());
-    MOCK_METHOD0(queueBuffer, void());
+    MOCK_METHOD1(queueBuffer, void(base::unique_fd&&));
     MOCK_METHOD0(onPresentDisplayCompleted, void());
-    MOCK_METHOD0(finishBuffer, void());
     MOCK_METHOD0(setViewportAndProjection, void());
     MOCK_METHOD0(flip, void());
     MOCK_CONST_METHOD1(dump, void(std::string& result));
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 6d5147d..e103ebe 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -90,13 +90,25 @@
 
 void Output::setColorTransform(const mat4& transform) {
     const bool isIdentity = (transform == mat4());
-
-    mState.colorTransform =
+    const auto newColorTransform =
             isIdentity ? HAL_COLOR_TRANSFORM_IDENTITY : HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX;
+
+    if (mState.colorTransform == newColorTransform) {
+        return;
+    }
+
+    mState.colorTransform = newColorTransform;
+
+    dirtyEntireOutput();
 }
 
 void Output::setColorMode(ui::ColorMode mode, ui::Dataspace dataspace,
                           ui::RenderIntent renderIntent) {
+    if (mState.colorMode == mode && mState.dataspace == dataspace &&
+        mState.renderIntent == renderIntent) {
+        return;
+    }
+
     mState.colorMode = mode;
     mState.dataspace = dataspace;
     mState.renderIntent = renderIntent;
@@ -106,6 +118,8 @@
     ALOGV("Set active color mode: %s (%d), active render intent: %s (%d)",
           decodeColorMode(mode).c_str(), mode, decodeRenderIntent(renderIntent).c_str(),
           renderIntent);
+
+    dirtyEntireOutput();
 }
 
 void Output::dump(std::string& out) const {
@@ -170,13 +184,10 @@
     return mState;
 }
 
-Region Output::getPhysicalSpaceDirtyRegion(bool repaintEverything) const {
-    Region dirty;
-    if (repaintEverything) {
-        dirty.set(mState.bounds);
-    } else {
-        dirty = mState.transform.transform(mState.dirtyRegion);
-        dirty.andSelf(mState.bounds);
+Region Output::getDirtyRegion(bool repaintEverything) const {
+    Region dirty(mState.viewport);
+    if (!repaintEverything) {
+        dirty.andSelf(mState.dirtyRegion);
     }
     return dirty;
 }
diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
index d546fc8..3f841d2 100644
--- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
@@ -156,7 +156,7 @@
     return mGraphicBuffer;
 }
 
-void RenderSurface::queueBuffer() {
+void RenderSurface::queueBuffer(base::unique_fd&& readyFence) {
     auto& hwc = mCompositionEngine.getHwComposer();
     const auto id = mDisplay.getId();
 
@@ -178,9 +178,9 @@
         if (mGraphicBuffer == nullptr) {
             ALOGE("No buffer is ready for display [%s]", mDisplay.getName().c_str());
         } else {
-            status_t result = mNativeWindow->queueBuffer(mNativeWindow.get(),
-                                                         mGraphicBuffer->getNativeBuffer(),
-                                                         dup(mBufferReady));
+            status_t result =
+                    mNativeWindow->queueBuffer(mNativeWindow.get(),
+                                               mGraphicBuffer->getNativeBuffer(), dup(readyFence));
             if (result != NO_ERROR) {
                 ALOGE("Error when queueing buffer for display [%s]: %d", mDisplay.getName().c_str(),
                       result);
@@ -190,12 +190,10 @@
                     LOG_ALWAYS_FATAL("ANativeWindow::queueBuffer failed with error: %d", result);
                 } else {
                     mNativeWindow->cancelBuffer(mNativeWindow.get(),
-                                                mGraphicBuffer->getNativeBuffer(),
-                                                dup(mBufferReady));
+                                                mGraphicBuffer->getNativeBuffer(), dup(readyFence));
                 }
             }
 
-            mBufferReady.reset();
             mGraphicBuffer = nullptr;
         }
     }
@@ -217,14 +215,6 @@
                                           ui::Transform::ROT_0);
 }
 
-void RenderSurface::finishBuffer() {
-    auto& renderEngine = mCompositionEngine.getRenderEngine();
-    mBufferReady = renderEngine.flush();
-    if (mBufferReady.get() < 0) {
-        renderEngine.finish();
-    }
-}
-
 void RenderSurface::flip() {
     mPageFlipCount++;
 }
@@ -263,9 +253,5 @@
     return mGraphicBuffer;
 }
 
-base::unique_fd& RenderSurface::mutableBufferReadyForTest() {
-    return mBufferReady;
-}
-
 } // namespace impl
 } // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 8cb6936..cd2d454 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -156,17 +156,17 @@
     EXPECT_EQ(ui::RenderIntent::COLORIMETRIC, mDisplay.getState().renderIntent);
 
     // Otherwise if the values are different, updates happen
-    EXPECT_CALL(*renderSurface, setBufferDataspace(ui::Dataspace::SRGB)).Times(1);
+    EXPECT_CALL(*renderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
     EXPECT_CALL(mHwComposer,
-                setActiveColorMode(DEFAULT_DISPLAY_ID, ui::ColorMode::BT2100_PQ,
+                setActiveColorMode(DEFAULT_DISPLAY_ID, ui::ColorMode::DISPLAY_P3,
                                    ui::RenderIntent::TONE_MAP_COLORIMETRIC))
             .Times(1);
 
-    mDisplay.setColorMode(ui::ColorMode::BT2100_PQ, ui::Dataspace::SRGB,
+    mDisplay.setColorMode(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
                           ui::RenderIntent::TONE_MAP_COLORIMETRIC);
 
-    EXPECT_EQ(ui::ColorMode::BT2100_PQ, mDisplay.getState().colorMode);
-    EXPECT_EQ(ui::Dataspace::SRGB, mDisplay.getState().dataspace);
+    EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mDisplay.getState().colorMode);
+    EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mDisplay.getState().dataspace);
     EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mDisplay.getState().renderIntent);
 }
 
@@ -174,7 +174,7 @@
     impl::Display virtualDisplay{mCompositionEngine,
                                  DisplayCreationArgs{false, true, DEFAULT_DISPLAY_ID}};
 
-    virtualDisplay.setColorMode(ui::ColorMode::BT2100_PQ, ui::Dataspace::SRGB,
+    virtualDisplay.setColorMode(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
                                 ui::RenderIntent::TONE_MAP_COLORIMETRIC);
 
     EXPECT_EQ(ui::ColorMode::NATIVE, virtualDisplay.getState().colorMode);
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index cc1211b..cb71821 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -43,15 +43,21 @@
         mOutput.setDisplayColorProfileForTest(
                 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
         mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
+
+        mOutput.editState().bounds = kDefaultDisplaySize;
     }
     ~OutputTest() override = default;
 
+    static const Rect kDefaultDisplaySize;
+
     StrictMock<mock::CompositionEngine> mCompositionEngine;
     mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
     mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
     impl::Output mOutput{mCompositionEngine};
 };
 
+const Rect OutputTest::kDefaultDisplaySize{100, 200};
+
 /* ------------------------------------------------------------------------
  * Basic construction
  */
@@ -76,8 +82,6 @@
  */
 
 TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
-    const Rect displaySize{100, 200};
-    mOutput.editState().bounds = displaySize;
     mOutput.editState().isEnabled = true;
 
     mOutput.setCompositionEnabled(true);
@@ -87,25 +91,21 @@
 }
 
 TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
-    const Rect displaySize{100, 200};
-    mOutput.editState().bounds = displaySize;
     mOutput.editState().isEnabled = false;
 
     mOutput.setCompositionEnabled(true);
 
     EXPECT_TRUE(mOutput.getState().isEnabled);
-    EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(displaySize)));
+    EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
 }
 
 TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
-    const Rect displaySize{100, 200};
-    mOutput.editState().bounds = displaySize;
     mOutput.editState().isEnabled = true;
 
     mOutput.setCompositionEnabled(false);
 
     EXPECT_FALSE(mOutput.getState().isEnabled);
-    EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(displaySize)));
+    EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
 }
 
 /* ------------------------------------------------------------------------
@@ -135,7 +135,7 @@
  */
 
 TEST_F(OutputTest, setBoundsSetsSizeAndDirtiesEntireOutput) {
-    const ui::Size displaySize{100, 200};
+    const ui::Size displaySize{200, 400};
 
     EXPECT_CALL(*mRenderSurface, setDisplaySize(displaySize)).Times(1);
     EXPECT_CALL(*mRenderSurface, getSize()).WillOnce(ReturnRef(displaySize));
@@ -152,16 +152,13 @@
  */
 
 TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
-    const Rect displaySize{100, 200};
-    mOutput.editState().bounds = displaySize;
-
     const uint32_t layerStack = 123u;
     mOutput.setLayerStackFilter(layerStack, true);
 
     EXPECT_TRUE(mOutput.getState().layerStackInternal);
     EXPECT_EQ(layerStack, mOutput.getState().layerStackId);
 
-    EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(displaySize)));
+    EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
 }
 
 /* ------------------------------------------------------------------------
@@ -176,27 +173,45 @@
 
     EXPECT_EQ(HAL_COLOR_TRANSFORM_IDENTITY, mOutput.getState().colorTransform);
 
+    // Since identity is the default, the dirty region should be unchanged (empty)
+    EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region()));
+
     // Non-identity matrix sets a non-identity state value
     const mat4 nonIdentity = mat4() * 2;
 
     mOutput.setColorTransform(nonIdentity);
 
     EXPECT_EQ(HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX, mOutput.getState().colorTransform);
+
+    // Since this is a state change, the entire output should now be dirty.
+    EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
 }
 
 /* ------------------------------------------------------------------------
  * Output::setColorMode
  */
 
-TEST_F(OutputTest, setColorModeSetsModeUnlessNoChange) {
-    EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::SRGB)).Times(1);
+TEST_F(OutputTest, setColorModeSetsStateAndDirtiesOutputIfChanged) {
+    EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
 
-    mOutput.setColorMode(ui::ColorMode::BT2100_PQ, ui::Dataspace::SRGB,
+    mOutput.setColorMode(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
                          ui::RenderIntent::TONE_MAP_COLORIMETRIC);
 
-    EXPECT_EQ(ui::ColorMode::BT2100_PQ, mOutput.getState().colorMode);
-    EXPECT_EQ(ui::Dataspace::SRGB, mOutput.getState().dataspace);
+    EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput.getState().colorMode);
+    EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput.getState().dataspace);
     EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput.getState().renderIntent);
+    EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
+}
+
+TEST_F(OutputTest, setColorModeDoesNothingIfNoChange) {
+    mOutput.editState().colorMode = ui::ColorMode::DISPLAY_P3;
+    mOutput.editState().dataspace = ui::Dataspace::DISPLAY_P3;
+    mOutput.editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
+
+    mOutput.setColorMode(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
+                         ui::RenderIntent::TONE_MAP_COLORIMETRIC);
+
+    EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region()));
 }
 
 /* ------------------------------------------------------------------------
@@ -215,52 +230,32 @@
 }
 
 /* ------------------------------------------------------------------------
- * Output::getPhysicalSpaceDirtyRegion()
+ * Output::getDirtyRegion()
  */
 
-TEST_F(OutputTest, getPhysicalSpaceDirtyRegionWithRepaintEverythingTrue) {
-    const Rect displaySize{100, 200};
-    mOutput.editState().bounds = displaySize;
+TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
+    const Rect viewport{100, 200};
+    mOutput.editState().viewport = viewport;
     mOutput.editState().dirtyRegion.set(50, 300);
 
     {
-        Region result = mOutput.getPhysicalSpaceDirtyRegion(true);
+        Region result = mOutput.getDirtyRegion(true);
 
-        EXPECT_THAT(result, RegionEq(Region(displaySize)));
-    }
-
-    // For repaint everything == true, the returned value does not depend on the display
-    // rotation.
-    mOutput.editState().transform.set(ui::Transform::ROT_90, 0, 0);
-
-    {
-        Region result = mOutput.getPhysicalSpaceDirtyRegion(true);
-
-        EXPECT_THAT(result, RegionEq(Region(displaySize)));
+        EXPECT_THAT(result, RegionEq(Region(viewport)));
     }
 }
 
-TEST_F(OutputTest, getPhysicalSpaceDirtyRegionWithRepaintEverythingFalse) {
-    const Rect displaySize{100, 200};
-    mOutput.editState().bounds = displaySize;
+TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
+    const Rect viewport{100, 200};
+    mOutput.editState().viewport = viewport;
     mOutput.editState().dirtyRegion.set(50, 300);
 
     {
-        Region result = mOutput.getPhysicalSpaceDirtyRegion(false);
+        Region result = mOutput.getDirtyRegion(false);
 
         // The dirtyRegion should be clipped to the display bounds.
         EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
     }
-
-    mOutput.editState().transform.set(ui::Transform::ROT_90, displaySize.getWidth(),
-                                      displaySize.getHeight());
-
-    {
-        Region result = mOutput.getPhysicalSpaceDirtyRegion(false);
-
-        // The dirtyRegion should be rotated and clipped to the display bounds.
-        EXPECT_THAT(result, RegionEq(Region(Rect(100, 50))));
-    }
 }
 
 /* ------------------------------------------------------------------------
diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
index 13cc663..c56d92a 100644
--- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
@@ -373,7 +373,7 @@
             .WillOnce(Return(false));
     EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
 
-    mSurface.queueBuffer();
+    mSurface.queueBuffer(base::unique_fd());
 
     EXPECT_EQ(buffer.get(), mSurface.mutableGraphicBufferForTest().get());
 }
@@ -387,7 +387,7 @@
             .WillOnce(Return(NO_ERROR));
     EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
 
-    mSurface.queueBuffer();
+    mSurface.queueBuffer(base::unique_fd());
 
     EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
 }
@@ -402,7 +402,7 @@
             .WillOnce(Return(NO_ERROR));
     EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
 
-    mSurface.queueBuffer();
+    mSurface.queueBuffer(base::unique_fd());
 
     EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
 }
@@ -419,7 +419,7 @@
             .WillOnce(Return(NO_ERROR));
     EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
 
-    mSurface.queueBuffer();
+    mSurface.queueBuffer(base::unique_fd());
 
     EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
 }
@@ -436,7 +436,7 @@
             .WillOnce(Return(NO_ERROR));
     EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
 
-    mSurface.queueBuffer();
+    mSurface.queueBuffer(base::unique_fd());
 
     EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
 }
@@ -452,29 +452,6 @@
 }
 
 /* ------------------------------------------------------------------------
- * RenderSurface::finishBuffer()
- */
-
-TEST_F(RenderSurfaceTest, finishBufferJustFlushesRenderEngine) {
-    int fd = dup(1);
-
-    EXPECT_CALL(mRenderEngine, flush()).WillOnce(Return(ByMove(base::unique_fd(fd))));
-
-    mSurface.finishBuffer();
-
-    EXPECT_EQ(fd, mSurface.mutableBufferReadyForTest().release());
-}
-
-TEST_F(RenderSurfaceTest, finishBufferFlushesAndFinishesRenderEngine) {
-    EXPECT_CALL(mRenderEngine, flush()).WillOnce(Return(ByMove(base::unique_fd(-2))));
-    EXPECT_CALL(mRenderEngine, finish()).Times(1);
-
-    mSurface.finishBuffer();
-
-    EXPECT_EQ(-2, mSurface.mutableBufferReadyForTest().release());
-}
-
-/* ------------------------------------------------------------------------
  * RenderSurface::setViewportAndProjection()
  */
 
diff --git a/services/surfaceflinger/ContainerLayer.cpp b/services/surfaceflinger/ContainerLayer.cpp
index ca49f6c..941b4ad 100644
--- a/services/surfaceflinger/ContainerLayer.cpp
+++ b/services/surfaceflinger/ContainerLayer.cpp
@@ -26,9 +26,16 @@
 
 ContainerLayer::~ContainerLayer() = default;
 
-void ContainerLayer::onDraw(const RenderArea&, const Region& /* clip */, bool) {}
+bool ContainerLayer::prepareClientLayer(const RenderArea&, const Region&, bool, Region&,
+                                        renderengine::LayerSettings&) {
+    return false;
+}
 
 bool ContainerLayer::isVisible() const {
+    return false;
+}
+
+bool ContainerLayer::canReceiveInput() const {
     return !isHiddenByPolicy();
 }
 
diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h
index 413844b..fec82d7 100644
--- a/services/surfaceflinger/ContainerLayer.h
+++ b/services/surfaceflinger/ContainerLayer.h
@@ -29,16 +29,21 @@
     ~ContainerLayer() override;
 
     const char* getTypeId() const override { return "ContainerLayer"; }
-    void onDraw(const RenderArea& renderArea, const Region& clip,
-                bool useIdentityTransform) override;
     bool isVisible() const override;
 
+    bool canReceiveInput() const override;
+
     void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport,
                          int32_t supportedPerFrameMetadata) override;
 
     bool isCreatedFromMainThread() const override { return true; }
 
     bool onPreComposition(nsecs_t /*refreshStartTime*/) override { return false; }
+
+protected:
+    bool prepareClientLayer(const RenderArea& renderArea, const Region& clip,
+                            bool useIdentityTransform, Region& clearRegion,
+                            renderengine::LayerSettings& layer);
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2de169d..46e587d 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -639,7 +639,7 @@
          * Here we cancel out the orientation component of the WM transform.
          * The scaling and translate components are already included in our bounds
          * computation so it's enough to just omit it in the composition.
-         * See comment in onDraw with ref to b/36727915 for why.
+         * See comment in BufferLayer::prepareClientLayer with ref to b/36727915 for why.
          */
         transform = ui::Transform(invTransform) * tr * bufferOrientation;
     }
@@ -681,7 +681,7 @@
     }
 
     // This gives us only the "orientation" component of the transform
-    const State& s(getCurrentState());
+    const State& s(getDrawingState());
 
     // Apply the layer's transform, followed by the display's global transform
     // Here we're guaranteed that the layer's transform preserves rects
@@ -707,12 +707,51 @@
 // drawing...
 // ---------------------------------------------------------------------------
 
-void Layer::draw(const RenderArea& renderArea, const Region& clip) {
-    onDraw(renderArea, clip, false);
+bool Layer::prepareClientLayer(const RenderArea& renderArea, const Region& clip,
+                               Region& clearRegion, renderengine::LayerSettings& layer) {
+    return prepareClientLayer(renderArea, clip, false, clearRegion, layer);
 }
 
-void Layer::draw(const RenderArea& renderArea, bool useIdentityTransform) {
-    onDraw(renderArea, Region(renderArea.getBounds()), useIdentityTransform);
+bool Layer::prepareClientLayer(const RenderArea& renderArea, bool useIdentityTransform,
+                               Region& clearRegion, renderengine::LayerSettings& layer) {
+    return prepareClientLayer(renderArea, Region(renderArea.getBounds()), useIdentityTransform,
+                              clearRegion, layer);
+}
+
+bool Layer::prepareClientLayer(const RenderArea& /*renderArea*/, const Region& /*clip*/,
+                               bool useIdentityTransform, Region& /*clearRegion*/,
+                               renderengine::LayerSettings& layer) {
+    FloatRect bounds = computeBounds();
+    half alpha = getAlpha();
+    layer.geometry.boundaries = bounds;
+    if (useIdentityTransform) {
+        layer.geometry.positionTransform = mat4();
+    } else {
+        const ui::Transform transform = getTransform();
+        mat4 m;
+        m[0][0] = transform[0][0];
+        m[0][1] = transform[0][1];
+        m[0][3] = transform[0][2];
+        m[1][0] = transform[1][0];
+        m[1][1] = transform[1][1];
+        m[1][3] = transform[1][2];
+        m[3][0] = transform[2][0];
+        m[3][1] = transform[2][1];
+        m[3][3] = transform[2][2];
+        layer.geometry.positionTransform = m;
+    }
+
+    if (hasColorTransform()) {
+        layer.colorTransform = getColorTransform();
+    }
+
+    const auto roundedCornerState = getRoundedCornerState();
+    layer.geometry.roundedCornersRadius = roundedCornerState.radius;
+    layer.geometry.roundedCornersCrop = roundedCornerState.cropRect;
+
+    layer.alpha = alpha;
+    layer.sourceDataspace = mCurrentDataSpace;
+    return true;
 }
 
 void Layer::clearWithOpenGL(const RenderArea& renderArea, float red, float green, float blue,
@@ -1039,13 +1078,18 @@
     ATRACE_CALL();
 
     if (mLayerDetached) {
-        return 0;
+        return flags;
+    }
+
+    if (mChildrenChanged) {
+        flags |= eVisibleRegion;
+        mChildrenChanged = false;
     }
 
     pushPendingState();
     State c = getCurrentState();
     if (!applyPendingStates(&c)) {
-        return 0;
+        return flags;
     }
 
     flags = doTransactionResize(flags, &c);
@@ -1067,11 +1111,6 @@
         mNeedsFiltering = (!getActiveTransform(c).preserveRects() || type >= ui::Transform::SCALE);
     }
 
-    if (mChildrenChanged) {
-        flags |= eVisibleRegion;
-        mChildrenChanged = false;
-    }
-
     // If the layer is hidden, signal and clear out all local sync points so
     // that transactions for layers depending on this layer's frames becoming
     // visible are not blocked
@@ -1241,7 +1280,12 @@
 bool Layer::setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace) {
     if (!mCurrentState.bgColorLayer && alpha == 0) {
         return false;
-    } else if (!mCurrentState.bgColorLayer && alpha != 0) {
+    }
+    mCurrentState.sequence++;
+    mCurrentState.modified = true;
+    setTransactionFlags(eTransactionNeeded);
+
+    if (!mCurrentState.bgColorLayer && alpha != 0) {
         // create background color layer if one does not yet exist
         uint32_t flags = ISurfaceComposerClient::eFXSurfaceColor;
         const String8& name = mName + "BackgroundColorLayer";
@@ -1595,6 +1639,7 @@
 
 void Layer::addChild(const sp<Layer>& layer) {
     mChildrenChanged = true;
+    setTransactionFlags(eTransactionNeeded);
 
     mCurrentChildren.add(layer);
     layer->setParent(this);
@@ -1602,6 +1647,7 @@
 
 ssize_t Layer::removeChild(const sp<Layer>& layer) {
     mChildrenChanged = true;
+    setTransactionFlags(eTransactionNeeded);
 
     layer->setParent(nullptr);
     return mCurrentChildren.remove(layer);
@@ -2206,7 +2252,7 @@
     // Position the touchable region relative to frame screen location and restrict it to frame
     // bounds.
     info.touchableRegion = info.touchableRegion.translate(info.frameLeft, info.frameTop);
-    info.visible = isVisible();
+    info.visible = canReceiveInput();
     return info;
 }
 
@@ -2218,6 +2264,10 @@
     return nullptr;
 }
 
+bool Layer::canReceiveInput() const {
+    return isVisible();
+}
+
 // ---------------------------------------------------------------------------
 
 }; // namespace android
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index f099df6..8b6d4c7 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -387,6 +387,11 @@
     bool isHiddenByPolicy() const;
 
     /*
+     * Returns whether this layer can receive input.
+     */
+    virtual bool canReceiveInput() const;
+
+    /*
      * isProtected - true if the layer may contain protected content in the
      * GRALLOC_USAGE_PROTECTED sense.
      */
@@ -421,11 +426,9 @@
     virtual Rect getCrop(const Layer::State& s) const { return s.crop_legacy; }
 
 protected:
-    /*
-     * onDraw - draws the surface.
-     */
-    virtual void onDraw(const RenderArea& renderArea, const Region& clip,
-                        bool useIdentityTransform) = 0;
+    virtual bool prepareClientLayer(const RenderArea& renderArea, const Region& clip,
+                                    bool useIdentityTransform, Region& clearRegion,
+                                    renderengine::LayerSettings& layer) = 0;
 
 public:
     virtual void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) {}
@@ -475,11 +478,14 @@
     virtual void releasePendingBuffer(nsecs_t /*dequeueReadyTime*/) { }
 
     /*
-     * draw - performs some global clipping optimizations
-     * and calls onDraw().
+     * prepareClientLayer - populates a renderengine::LayerSettings to passed to
+     * RenderEngine::drawLayers. Returns true if the layer can be used, and
+     * false otherwise.
      */
-    void draw(const RenderArea& renderArea, const Region& clip);
-    void draw(const RenderArea& renderArea, bool useIdentityTransform);
+    bool prepareClientLayer(const RenderArea& renderArea, const Region& clip, Region& clearRegion,
+                            renderengine::LayerSettings& layer);
+    bool prepareClientLayer(const RenderArea& renderArea, bool useIdentityTransform,
+                            Region& clearRegion, renderengine::LayerSettings& layer);
 
     /*
      * doTransaction - process the transaction. This is a good place to figure
@@ -517,8 +523,8 @@
      * operation, so this should be set only if needed). Typically this is used
      * to figure out if the content or size of a surface has changed.
      */
-    virtual Region latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/,
-                               const sp<Fence>& /*releaseFence*/) {
+    virtual bool latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/,
+                             const sp<Fence>& /*releaseFence*/) {
         return {};
     }
 
@@ -810,7 +816,13 @@
     FenceTimeline mReleaseTimeline;
 
     // main thread
+    // Active buffer fields
     sp<GraphicBuffer> mActiveBuffer;
+    sp<Fence> mActiveBufferFence;
+    // False if the buffer and its contents have been previously used for GPU
+    // composition, true otherwise.
+    bool mIsActiveBufferUpdatedForGpu = true;
+
     ui::Dataspace mCurrentDataSpace = ui::Dataspace::UNKNOWN;
     Rect mCurrentCrop;
     uint32_t mCurrentTransform{0};
@@ -866,7 +878,6 @@
                                        const LayerVector::Visitor& visitor);
     LayerVector makeChildrenTraversalList(LayerVector::StateSet stateSet,
                                           const std::vector<Layer*>& layersInTree);
-
     /**
      * Retuns the child bounds in layer space cropped to its bounds as well all its parent bounds.
      * The cropped bounds must be transformed back from parent layer space to child layer space by
diff --git a/services/surfaceflinger/OWNERS b/services/surfaceflinger/OWNERS
index dc2b300..ce0611c 100644
--- a/services/surfaceflinger/OWNERS
+++ b/services/surfaceflinger/OWNERS
@@ -1,3 +1,4 @@
+akrulec@google.com
 chaviw@google.com
 lpy@google.com
 marissaw@google.com
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 91ae087..5d9cfde 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -100,8 +100,10 @@
 } // namespace
 
 EventThreadConnection::EventThreadConnection(EventThread* eventThread,
-                                             ResyncCallback resyncCallback)
+                                             ResyncCallback resyncCallback,
+                                             ResetIdleTimerCallback resetIdleTimerCallback)
       : resyncCallback(std::move(resyncCallback)),
+        resetIdleTimerCallback(std::move(resetIdleTimerCallback)),
         mEventThread(eventThread),
         mChannel(gui::BitTube::DefaultSize) {}
 
@@ -147,22 +149,18 @@
 namespace impl {
 
 EventThread::EventThread(std::unique_ptr<VSyncSource> src,
-                         const InterceptVSyncsCallback& interceptVSyncsCallback,
-                         const ResetIdleTimerCallback& resetIdleTimerCallback,
-                         const char* threadName)
-      : EventThread(nullptr, std::move(src), interceptVSyncsCallback, threadName) {
-    mResetIdleTimer = resetIdleTimerCallback;
-}
+                         InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
+      : EventThread(nullptr, std::move(src), std::move(interceptVSyncsCallback), threadName) {}
 
 EventThread::EventThread(VSyncSource* src, InterceptVSyncsCallback interceptVSyncsCallback,
                          const char* threadName)
-      : EventThread(src, nullptr, interceptVSyncsCallback, threadName) {}
+      : EventThread(src, nullptr, std::move(interceptVSyncsCallback), threadName) {}
 
 EventThread::EventThread(VSyncSource* src, std::unique_ptr<VSyncSource> uniqueSrc,
                          InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
       : mVSyncSource(src),
         mVSyncSourceUnique(std::move(uniqueSrc)),
-        mInterceptVSyncsCallback(interceptVSyncsCallback),
+        mInterceptVSyncsCallback(std::move(interceptVSyncsCallback)),
         mThreadName(threadName) {
     if (src == nullptr) {
         mVSyncSource = mVSyncSourceUnique.get();
@@ -205,8 +203,10 @@
     mVSyncSource->setPhaseOffset(phaseOffset);
 }
 
-sp<EventThreadConnection> EventThread::createEventConnection(ResyncCallback resyncCallback) const {
-    return new EventThreadConnection(const_cast<EventThread*>(this), std::move(resyncCallback));
+sp<EventThreadConnection> EventThread::createEventConnection(
+        ResyncCallback resyncCallback, ResetIdleTimerCallback resetIdleTimerCallback) const {
+    return new EventThreadConnection(const_cast<EventThread*>(this), std::move(resyncCallback),
+                                     std::move(resetIdleTimerCallback));
 }
 
 status_t EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection) {
@@ -249,9 +249,9 @@
 }
 
 void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection, bool reset) {
-    if (mResetIdleTimer && reset) {
+    if (connection->resetIdleTimerCallback && reset) {
         ATRACE_NAME("resetIdleTimer");
-        mResetIdleTimer();
+        connection->resetIdleTimerCallback();
     }
 
     if (connection->resyncCallback) {
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index 62b6a8b..b275183 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -45,6 +45,7 @@
 // ---------------------------------------------------------------------------
 
 using ResyncCallback = std::function<void()>;
+using ResetIdleTimerCallback = std::function<void()>;
 
 enum class VSyncRequest {
     None = -1,
@@ -69,7 +70,7 @@
 
 class EventThreadConnection : public BnDisplayEventConnection {
 public:
-    EventThreadConnection(EventThread* eventThread, ResyncCallback resyncCallback);
+    EventThreadConnection(EventThread*, ResyncCallback, ResetIdleTimerCallback);
     virtual ~EventThreadConnection();
 
     virtual status_t postEvent(const DisplayEventReceiver::Event& event);
@@ -83,6 +84,7 @@
 
     // Called in response to requestNextVsync.
     const ResyncCallback resyncCallback;
+    const ResetIdleTimerCallback resetIdleTimerCallback;
 
     VSyncRequest vsyncRequest = VSyncRequest::None;
 
@@ -96,8 +98,8 @@
 public:
     virtual ~EventThread();
 
-    virtual sp<EventThreadConnection> createEventConnection(
-            ResyncCallback resyncCallback) const = 0;
+    virtual sp<EventThreadConnection> createEventConnection(ResyncCallback,
+                                                            ResetIdleTimerCallback) const = 0;
 
     // called before the screen is turned off from main thread
     virtual void onScreenReleased() = 0;
@@ -124,17 +126,14 @@
 class EventThread : public android::EventThread, private VSyncSource::Callback {
 public:
     using InterceptVSyncsCallback = std::function<void(nsecs_t)>;
-    using ResetIdleTimerCallback = std::function<void()>;
 
     // TODO(b/113612090): Once the Scheduler is complete this constructor will become obsolete.
-    EventThread(VSyncSource* src, InterceptVSyncsCallback interceptVSyncsCallback,
-                const char* threadName);
-    EventThread(std::unique_ptr<VSyncSource> src,
-                const InterceptVSyncsCallback& interceptVSyncsCallback,
-                const ResetIdleTimerCallback& resetIdleTimerCallback, const char* threadName);
+    EventThread(VSyncSource*, InterceptVSyncsCallback, const char* threadName);
+    EventThread(std::unique_ptr<VSyncSource>, InterceptVSyncsCallback, const char* threadName);
     ~EventThread();
 
-    sp<EventThreadConnection> createEventConnection(ResyncCallback resyncCallback) const override;
+    sp<EventThreadConnection> createEventConnection(ResyncCallback,
+                                                    ResetIdleTimerCallback) const override;
 
     status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
     void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) override;
@@ -220,9 +219,6 @@
     State mState GUARDED_BY(mMutex) = State::Idle;
 
     static const char* toCString(State);
-
-    // Callback that resets the idle timer when the next vsync is received.
-    ResetIdleTimerCallback mResetIdleTimer;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index 75a410b..1f18ead 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -96,7 +96,8 @@
     }
 
     mEventThread = eventThread;
-    mEvents = eventThread->createEventConnection(std::move(resyncCallback));
+    mEvents =
+            eventThread->createEventConnection(std::move(resyncCallback), ResetIdleTimerCallback());
     mEvents->stealReceiveChannel(&mEventTube);
     mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
                    this);
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 3060f1d..2f581d2 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -87,6 +87,7 @@
 
 sp<Scheduler::ConnectionHandle> Scheduler::createConnection(
         const char* connectionName, int64_t phaseOffsetNs, ResyncCallback resyncCallback,
+        ResetIdleTimerCallback resetIdleTimerCallback,
         impl::EventThread::InterceptVSyncsCallback interceptCallback) {
     const int64_t id = sNextId++;
     ALOGV("Creating a connection handle with ID: %" PRId64 "\n", id);
@@ -94,12 +95,14 @@
     std::unique_ptr<EventThread> eventThread =
             makeEventThread(connectionName, mPrimaryDispSync.get(), phaseOffsetNs,
                             std::move(interceptCallback));
-    auto connection = std::make_unique<Connection>(new ConnectionHandle(id),
-                                                   eventThread->createEventConnection(
-                                                           std::move(resyncCallback)),
-                                                   std::move(eventThread));
 
-    mConnections.insert(std::make_pair(id, std::move(connection)));
+    auto eventThreadConnection =
+            createConnectionInternal(eventThread.get(), std::move(resyncCallback),
+                                     std::move(resetIdleTimerCallback));
+    mConnections.emplace(id,
+                         std::make_unique<Connection>(new ConnectionHandle(id),
+                                                      eventThreadConnection,
+                                                      std::move(eventThread)));
     return mConnections[id]->handle;
 }
 
@@ -109,14 +112,29 @@
     std::unique_ptr<VSyncSource> eventThreadSource =
             std::make_unique<DispSyncSource>(dispSync, phaseOffsetNs, true, connectionName);
     return std::make_unique<impl::EventThread>(std::move(eventThreadSource),
-                                               std::move(interceptCallback),
-                                               [this] { resetIdleTimer(); }, connectionName);
+                                               std::move(interceptCallback), connectionName);
+}
+
+sp<EventThreadConnection> Scheduler::createConnectionInternal(
+        EventThread* eventThread, ResyncCallback&& resyncCallback,
+        ResetIdleTimerCallback&& resetIdleTimerCallback) {
+    return eventThread->createEventConnection(std::move(resyncCallback),
+                                              [this,
+                                               resetIdleTimerCallback =
+                                                       std::move(resetIdleTimerCallback)] {
+                                                  resetIdleTimer();
+                                                  if (resetIdleTimerCallback) {
+                                                      resetIdleTimerCallback();
+                                                  }
+                                              });
 }
 
 sp<IDisplayEventConnection> Scheduler::createDisplayEventConnection(
-        const sp<Scheduler::ConnectionHandle>& handle, ResyncCallback resyncCallback) {
+        const sp<Scheduler::ConnectionHandle>& handle, ResyncCallback resyncCallback,
+        ResetIdleTimerCallback resetIdleTimerCallback) {
     RETURN_VALUE_IF_INVALID(nullptr);
-    return mConnections[handle->id]->thread->createEventConnection(std::move(resyncCallback));
+    return createConnectionInternal(mConnections[handle->id]->thread.get(),
+                                    std::move(resyncCallback), std::move(resetIdleTimerCallback));
 }
 
 EventThread* Scheduler::getEventThread(const sp<Scheduler::ConnectionHandle>& handle) {
@@ -241,11 +259,6 @@
     mExpiredTimerCallback = expiredTimerCallback;
 }
 
-void Scheduler::setResetIdleTimerCallback(const ResetIdleTimerCallback& resetTimerCallback) {
-    std::lock_guard<std::mutex> lock(mCallbackLock);
-    mResetTimerCallback = resetTimerCallback;
-}
-
 void Scheduler::updateFrameSkipping(const int64_t skipCount) {
     ATRACE_INT("FrameSkipCount", skipCount);
     if (mSkipCount != skipCount) {
@@ -336,11 +349,6 @@
         mIdleTimer->reset();
         ATRACE_INT("ExpiredIdleTimer", 0);
     }
-
-    std::lock_guard<std::mutex> lock(mCallbackLock);
-    if (mResetTimerCallback) {
-        mResetTimerCallback();
-    }
 }
 
 void Scheduler::expiredTimerCallback() {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index e77dc06..4abf027 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -37,7 +37,6 @@
 class Scheduler {
 public:
     using ExpiredIdleTimerCallback = std::function<void()>;
-    using ResetIdleTimerCallback = std::function<void()>;
 
     // Enum to indicate whether to start the transaction early, or at vsync time.
     enum class TransactionStart { EARLY, NORMAL };
@@ -72,12 +71,13 @@
     virtual ~Scheduler();
 
     /** Creates an EventThread connection. */
-    sp<ConnectionHandle> createConnection(
-            const char* connectionName, int64_t phaseOffsetNs, ResyncCallback resyncCallback,
-            impl::EventThread::InterceptVSyncsCallback interceptCallback);
+    sp<ConnectionHandle> createConnection(const char* connectionName, int64_t phaseOffsetNs,
+                                          ResyncCallback, ResetIdleTimerCallback,
+                                          impl::EventThread::InterceptVSyncsCallback);
 
     sp<IDisplayEventConnection> createDisplayEventConnection(const sp<ConnectionHandle>& handle,
-                                                             ResyncCallback resyncCallback);
+                                                             ResyncCallback,
+                                                             ResetIdleTimerCallback);
 
     // Getter methods.
     EventThread* getEventThread(const sp<ConnectionHandle>& handle);
@@ -116,8 +116,6 @@
     void incrementFrameCounter();
     // Callback that gets invoked once the idle timer expires.
     void setExpiredIdleTimerCallback(const ExpiredIdleTimerCallback& expiredTimerCallback);
-    // Callback that gets invoked once the idle timer is reset.
-    void setResetIdleTimerCallback(const ResetIdleTimerCallback& resetTimerCallback);
     // Returns relevant information about Scheduler for dumpsys purposes.
     std::string doDump();
 
@@ -127,6 +125,10 @@
             impl::EventThread::InterceptVSyncsCallback interceptCallback);
 
 private:
+    // Creates a connection on the given EventThread and forwards the given callbacks.
+    sp<EventThreadConnection> createConnectionInternal(EventThread*, ResyncCallback&&,
+                                                       ResetIdleTimerCallback&&);
+
     nsecs_t calculateAverage() const;
     void updateFrameSkipping(const int64_t skipCount);
     // Collects the statistical mean (average) and median between timestamp
@@ -184,7 +186,6 @@
 
     std::mutex mCallbackLock;
     ExpiredIdleTimerCallback mExpiredTimerCallback GUARDED_BY(mCallbackLock);
-    ResetIdleTimerCallback mResetTimerCallback GUARDED_BY(mCallbackLock);
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1a64f69..5f8de83 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-// #define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
 #include <sys/types.h>
@@ -120,6 +120,7 @@
 using namespace android::hardware::configstore;
 using namespace android::hardware::configstore::V1_0;
 using namespace android::sysprop;
+
 using base::StringAppendF;
 using ui::ColorMode;
 using ui::Dataspace;
@@ -127,6 +128,8 @@
 using ui::Hdr;
 using ui::RenderIntent;
 
+using RefreshRateType = scheduler::RefreshRateConfigs::RefreshRateType;
+
 namespace {
 
 #pragma clang diagnostic push
@@ -211,6 +214,9 @@
 constexpr float kSrgbWhiteY = 1.0000f;
 constexpr float kSrgbWhiteZ = 1.0891f;
 
+constexpr float kDefaultRefreshRate = 60.f;
+constexpr float kPerformanceRefreshRate = 90.f;
+
 // ---------------------------------------------------------------------------
 int64_t SurfaceFlinger::dispSyncPresentTimeOffset;
 bool SurfaceFlinger::useHwcForRgbToYuv;
@@ -627,13 +633,17 @@
         mPhaseOffsets->setRefreshRateType(
                 scheduler::RefreshRateConfigs::RefreshRateType::PERFORMANCE);
 
+        auto resetIdleTimerCallback =
+                std::bind(&SurfaceFlinger::setRefreshRateTo, this, RefreshRateType::PERFORMANCE);
+
         mAppConnectionHandle =
                 mScheduler->createConnection("appConnection", mPhaseOffsets->getCurrentAppOffset(),
-                                             resyncCallback,
+                                             resyncCallback, resetIdleTimerCallback,
                                              impl::EventThread::InterceptVSyncsCallback());
         mSfConnectionHandle =
                 mScheduler->createConnection("sfConnection", mPhaseOffsets->getCurrentSfOffset(),
-                                             resyncCallback, [this](nsecs_t timestamp) {
+                                             resyncCallback, resetIdleTimerCallback,
+                                             [this](nsecs_t timestamp) {
                                                  mInterceptor->saveVSyncEvent(timestamp);
                                              });
 
@@ -731,20 +741,11 @@
     }
 
     if (mUseScheduler) {
-        mScheduler->setExpiredIdleTimerCallback([this]() {
-            mPhaseOffsets->setRefreshRateType(
-                    scheduler::RefreshRateConfigs::RefreshRateType::DEFAULT);
-            const auto [early, gl, late] = mPhaseOffsets->getCurrentOffsets();
-            mVsyncModulator.setPhaseOffsets(early, gl, late);
-            setRefreshRateTo(60.f /* fps */);
+        mScheduler->setExpiredIdleTimerCallback([this] {
+            Mutex::Autolock lock(mStateLock);
+            setRefreshRateTo(RefreshRateType::DEFAULT);
         });
-        mScheduler->setResetIdleTimerCallback([this]() {
-            mPhaseOffsets->setRefreshRateType(
-                    scheduler::RefreshRateConfigs::RefreshRateType::PERFORMANCE);
-            const auto [early, gl, late] = mPhaseOffsets->getCurrentOffsets();
-            mVsyncModulator.setPhaseOffsets(early, gl, late);
-            setRefreshRateTo(90.f /* fps */);
-        });
+
         mRefreshRateStats =
                 std::make_unique<scheduler::RefreshRateStats>(getHwComposer().getConfigs(
                                                                       *display->getId()),
@@ -956,13 +957,6 @@
     return display->getActiveConfig();
 }
 
-status_t SurfaceFlinger::setActiveConfigAsync(const sp<IBinder>& displayToken, int mode) {
-    ATRACE_NAME("setActiveConfigAsync");
-    postMessageAsync(new LambdaMessage(
-            [=]() NO_THREAD_SAFETY_ANALYSIS { setActiveConfigInternal(displayToken, mode); }));
-    return NO_ERROR;
-}
-
 status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& displayToken, int mode) {
     ATRACE_NAME("setActiveConfigSync");
     postMessageSync(new LambdaMessage(
@@ -1269,16 +1263,21 @@
     });
 
     if (mUseScheduler) {
-        if (vsyncSource == eVsyncSourceSurfaceFlinger) {
-            return mScheduler->createDisplayEventConnection(mSfConnectionHandle, resyncCallback);
-        } else {
-            return mScheduler->createDisplayEventConnection(mAppConnectionHandle, resyncCallback);
-        }
+        auto resetIdleTimerCallback = [this] {
+            Mutex::Autolock lock(mStateLock);
+            setRefreshRateTo(RefreshRateType::PERFORMANCE);
+        };
+
+        const auto& handle = vsyncSource == eVsyncSourceSurfaceFlinger ? mSfConnectionHandle
+                                                                       : mAppConnectionHandle;
+
+        return mScheduler->createDisplayEventConnection(handle, std::move(resyncCallback),
+                                                        std::move(resetIdleTimerCallback));
     } else {
         if (vsyncSource == eVsyncSourceSurfaceFlinger) {
-            return mSFEventThread->createEventConnection(resyncCallback);
+            return mSFEventThread->createEventConnection(resyncCallback, ResetIdleTimerCallback());
         } else {
-            return mEventThread->createEventConnection(resyncCallback);
+            return mEventThread->createEventConnection(resyncCallback, ResetIdleTimerCallback());
         }
     }
 }
@@ -1440,12 +1439,16 @@
     *compositorTiming = getBE().mCompositorTiming;
 }
 
-// TODO(b/123715322): Fix thread safety.
-void SurfaceFlinger::setRefreshRateTo(float newFps) NO_THREAD_SAFETY_ANALYSIS {
-    const auto display = getDefaultDisplayDeviceLocked();
-    if (!display || mBootStage != BootStage::FINISHED) {
+void SurfaceFlinger::setRefreshRateTo(RefreshRateType refreshRate) {
+    mPhaseOffsets->setRefreshRateType(refreshRate);
+
+    const auto [early, gl, late] = mPhaseOffsets->getCurrentOffsets();
+    mVsyncModulator.setPhaseOffsets(early, gl, late);
+
+    if (mBootStage != BootStage::FINISHED) {
         return;
     }
+
     // TODO(b/113612090): There should be a message queue flush here. Because this esentially
     // runs on a mainthread, we cannot call postMessageSync. This can be resolved in a better
     // manner, once the setActiveConfig is synchronous, and is executed at a known time in a
@@ -1456,14 +1459,20 @@
     if (currentVsyncPeriod == 0) {
         return;
     }
+
     // TODO(b/113612090): Consider having an enum value for correct refresh rates, rather than
     // floating numbers.
     const float currentFps = 1e9 / currentVsyncPeriod;
+    const float newFps = refreshRate == RefreshRateType::PERFORMANCE ? kPerformanceRefreshRate
+                                                                     : kDefaultRefreshRate;
     if (std::abs(currentFps - newFps) <= 1) {
         return;
     }
 
-    auto configs = getHwComposer().getConfigs(*display->getId());
+    const auto displayId = getInternalDisplayIdLocked();
+    LOG_ALWAYS_FATAL_IF(!displayId);
+
+    auto configs = getHwComposer().getConfigs(*displayId);
     for (int i = 0; i < configs.size(); i++) {
         const nsecs_t vsyncPeriod = configs.at(i)->getVsyncPeriod();
         if (vsyncPeriod == 0) {
@@ -1473,12 +1482,7 @@
         // TODO(b/113612090): There should be a better way at determining which config
         // has the right refresh rate.
         if (std::abs(fps - newFps) <= 1) {
-            const sp<IBinder> token = display->getDisplayToken().promote();
-            LOG_ALWAYS_FATAL_IF(token == nullptr);
-
-            // This is posted in async function to avoid deadlock when getDisplayDevice
-            // requires mStateLock.
-            setActiveConfigAsync(token, i);
+            setActiveConfigInternal(getInternalDisplayTokenLocked(), i);
             ATRACE_INT("FPS", newFps);
         }
     }
@@ -1648,6 +1652,10 @@
 
             bool refreshNeeded = handleMessageTransaction();
             refreshNeeded |= handleMessageInvalidate();
+
+            updateCursorAsync();
+            updateInputFlinger();
+
             refreshNeeded |= mRepaintEverything;
             if (refreshNeeded && CC_LIKELY(mBootStage != BootStage::BOOTLOADER)) {
                 // Signal a refresh if a transaction modified the window state,
@@ -1742,7 +1750,15 @@
 
 bool SurfaceFlinger::handleMessageInvalidate() {
     ATRACE_CALL();
-    return handlePageFlip();
+    bool refreshNeeded = handlePageFlip();
+
+    for (auto& layer : mLayersPendingRefresh) {
+        Region visibleReg;
+        visibleReg.set(layer->computeScreenBounds());
+        invalidateLayerStack(layer, visibleReg);
+    }
+    mLayersPendingRefresh.clear();
+    return refreshNeeded;
 }
 
 void SurfaceFlinger::calculateWorkingSet() {
@@ -1863,16 +1879,13 @@
 
     if (displayState.isEnabled) {
         // transform the dirty region into this screen's coordinate space
-        const Region dirtyRegion = display->getPhysicalSpaceDirtyRegion(repaintEverything);
+        const Region dirtyRegion = display->getDirtyRegion(repaintEverything);
         if (!dirtyRegion.isEmpty()) {
+            base::unique_fd readyFence;
             // redraw the whole screen
-            doComposeSurfaces(displayDevice);
+            doComposeSurfaces(displayDevice, dirtyRegion, &readyFence);
 
-            // and draw the dirty region
-            auto& engine(getRenderEngine());
-            engine.fillRegionWithColor(dirtyRegion, 1, 0, 1, 1);
-
-            display->getRenderSurface()->queueBuffer();
+            display->getRenderSurface()->queueBuffer(std::move(readyFence));
         }
     }
 
@@ -2409,7 +2422,7 @@
     auto display = displayDevice->getCompositionDisplay();
     const auto& displayState = display->getState();
 
-    bool dirty = !display->getPhysicalSpaceDirtyRegion(false).isEmpty();
+    bool dirty = !display->getDirtyRegion(false).isEmpty();
     bool empty = displayDevice->getVisibleLayersSortedByZ().size() == 0;
     bool wasEmpty = !displayState.lastCompositionHadVisibleLayers;
 
@@ -2460,7 +2473,7 @@
 
     if (displayState.isEnabled) {
         // transform the dirty region into this screen's coordinate space
-        const Region dirtyRegion = display->getPhysicalSpaceDirtyRegion(repaintEverything);
+        const Region dirtyRegion = display->getDirtyRegion(repaintEverything);
 
         // repaint the framebuffer (if needed)
         doDisplayComposition(displayDevice, dirtyRegion);
@@ -2849,7 +2862,6 @@
      * (perform the transaction for each of them if needed)
      */
 
-    bool inputChanged = false;
     if (transactionFlags & eTraversalNeeded) {
         mCurrentState.traverseInZOrder([&](Layer* layer) {
             uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
@@ -2860,7 +2872,7 @@
                 mVisibleRegionsDirty = true;
 
             if (flags & Layer::eInputInfoChanged) {
-                inputChanged = true;
+                mInputInfoChanged = true;
             }
         });
     }
@@ -2972,22 +2984,23 @@
     }
 
     commitTransaction();
-
-    if (inputChanged || mVisibleRegionsDirty) {
-        updateInputWindows();
-    }
-    executeInputWindowCommands();
-
-    updateCursorAsync();
 }
 
-void SurfaceFlinger::updateInputWindows() {
+void SurfaceFlinger::updateInputFlinger() {
     ATRACE_CALL();
-
-    if (mInputFlinger == nullptr) {
+    if (!mInputFlinger) {
         return;
     }
 
+    if (mVisibleRegionsDirty || mInputInfoChanged) {
+        mInputInfoChanged = false;
+        updateInputWindowInfo();
+    }
+
+    executeInputWindowCommands();
+}
+
+void SurfaceFlinger::updateInputWindowInfo() {
     Vector<InputWindowInfo> inputHandles;
 
     mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
@@ -3001,10 +3014,6 @@
 }
 
 void SurfaceFlinger::executeInputWindowCommands() {
-    if (!mInputFlinger) {
-        return;
-    }
-
     for (const auto& transferTouchFocusCommand : mInputWindowCommands.transferTouchFocusCommands) {
         if (transferTouchFocusCommand.fromToken != nullptr &&
             transferTouchFocusCommand.toToken != nullptr &&
@@ -3281,9 +3290,10 @@
         Mutex::Autolock lock(mStateLock);
 
         for (auto& layer : mLayersWithQueuedFrames) {
-            const Region dirty(layer->latchBuffer(visibleRegions, latchTime, getBE().flushFence));
+            if (layer->latchBuffer(visibleRegions, latchTime, getBE().flushFence)) {
+                mLayersPendingRefresh.push_back(layer);
+            }
             layer->useSurfaceDamage();
-            invalidateLayerStack(layer, dirty);
             if (layer->isBufferLatched()) {
                 newDataLatched = true;
             }
@@ -3297,11 +3307,6 @@
 
     mVisibleRegionsDirty |= visibleRegions;
 
-    if (visibleRegions) {
-        // Update input window info if the layer receives its first buffer.
-        updateInputWindows();
-    }
-
     // If we will need to wake up at some time in the future to deal with a
     // queued frame that shouldn't be displayed during this vsync period, wake
     // up during the next vsync period to check again.
@@ -3327,7 +3332,6 @@
 void SurfaceFlinger::doDisplayComposition(const sp<DisplayDevice>& displayDevice,
                                           const Region& inDirtyRegion) {
     auto display = displayDevice->getCompositionDisplay();
-
     // We only need to actually compose the display if:
     // 1) It is being handled by hardware composer, which may need this to
     //    keep its virtual display state machine in sync, or
@@ -3338,13 +3342,16 @@
     }
 
     ALOGV("doDisplayComposition");
-    if (!doComposeSurfaces(displayDevice)) return;
+    base::unique_fd readyFence;
+    if (!doComposeSurfaces(displayDevice, Region::INVALID_REGION, &readyFence)) return;
 
     // swap buffers (presentation)
-    display->getRenderSurface()->queueBuffer();
+    display->getRenderSurface()->queueBuffer(std::move(readyFence));
 }
 
-bool SurfaceFlinger::doComposeSurfaces(const sp<DisplayDevice>& displayDevice) {
+bool SurfaceFlinger::doComposeSurfaces(const sp<DisplayDevice>& displayDevice,
+                                       const Region& debugRegion, base::unique_fd* readyFence) {
+    ATRACE_CALL();
     ALOGV("doComposeSurfaces");
 
     auto display = displayDevice->getCompositionDisplay();
@@ -3359,13 +3366,14 @@
     mat4 colorMatrix;
     bool applyColorMatrix = false;
 
-    // Framebuffer will live in this scope for GPU composition.
-    std::unique_ptr<renderengine::BindNativeBufferAsFramebuffer> fbo;
+    renderengine::DisplaySettings clientCompositionDisplay;
+    std::vector<renderengine::LayerSettings> clientCompositionLayers;
+    sp<GraphicBuffer> buf;
 
     if (hasClientComposition) {
         ALOGV("hasClientComposition");
 
-        sp<GraphicBuffer> buf = display->getRenderSurface()->dequeueBuffer();
+        buf = display->getRenderSurface()->dequeueBuffer();
 
         if (buf == nullptr) {
             ALOGW("Dequeuing buffer for display [%s] failed, bailing out of "
@@ -3374,24 +3382,30 @@
             return false;
         }
 
-        // Bind the framebuffer in this scope.
-        fbo = std::make_unique<renderengine::BindNativeBufferAsFramebuffer>(getRenderEngine(),
-                                                                            buf->getNativeBuffer());
+        clientCompositionDisplay.physicalDisplay = displayState.scissor;
+        clientCompositionDisplay.clip = displayState.scissor;
+        const ui::Transform& displayTransform = displayState.transform;
+        mat4 m;
+        m[0][0] = displayTransform[0][0];
+        m[0][1] = displayTransform[0][1];
+        m[0][3] = displayTransform[0][2];
+        m[1][0] = displayTransform[1][0];
+        m[1][1] = displayTransform[1][1];
+        m[1][3] = displayTransform[1][2];
+        m[3][0] = displayTransform[2][0];
+        m[3][1] = displayTransform[2][1];
+        m[3][3] = displayTransform[2][2];
 
-        if (fbo->getStatus() != NO_ERROR) {
-            ALOGW("Binding buffer for display [%s] failed with status: %d",
-                  displayDevice->getDisplayName().c_str(), fbo->getStatus());
-            return false;
-        }
+        clientCompositionDisplay.globalTransform = m;
 
         const auto* profile = display->getDisplayColorProfile();
         Dataspace outputDataspace = Dataspace::UNKNOWN;
         if (profile->hasWideColorGamut()) {
             outputDataspace = displayState.dataspace;
         }
-        getRenderEngine().setOutputDataSpace(outputDataspace);
-        getRenderEngine().setDisplayMaxLuminance(
-                profile->getHdrCapabilities().getDesiredMaxLuminance());
+        clientCompositionDisplay.outputDataspace = outputDataspace;
+        clientCompositionDisplay.maxLuminance =
+                profile->getHdrCapabilities().getDesiredMaxLuminance();
 
         const bool hasDeviceComposition = getHwComposer().hasDeviceComposition(displayId);
         const bool skipClientColorTransform =
@@ -3402,44 +3416,7 @@
         // Compute the global color transform matrix.
         applyColorMatrix = !hasDeviceComposition && !skipClientColorTransform;
         if (applyColorMatrix) {
-            colorMatrix = mDrawingState.colorMatrix;
-        }
-
-        display->getRenderSurface()->setViewportAndProjection();
-
-        // Never touch the framebuffer if we don't have any framebuffer layers
-        if (hasDeviceComposition) {
-            // when using overlays, we assume a fully transparent framebuffer
-            // NOTE: we could reduce how much we need to clear, for instance
-            // remove where there are opaque FB layers. however, on some
-            // GPUs doing a "clean slate" clear might be more efficient.
-            // We'll revisit later if needed.
-            getRenderEngine().clearWithColor(0, 0, 0, 0);
-        } else {
-            // we start with the whole screen area and remove the scissor part
-            // we're left with the letterbox region
-            // (common case is that letterbox ends-up being empty)
-            const Region letterbox = bounds.subtract(displayState.scissor);
-
-            // compute the area to clear
-            const Region region = displayState.undefinedRegion.merge(letterbox);
-
-            // screen is already cleared here
-            if (!region.isEmpty()) {
-                // can happen with SurfaceView
-                drawWormhole(region);
-            }
-        }
-
-        const Rect& bounds = displayState.bounds;
-        const Rect& scissor = displayState.scissor;
-        if (scissor != bounds) {
-            // scissor doesn't match the screen's dimensions, so we
-            // need to clear everything outside of it and enable
-            // the GL scissor so we don't draw anything where we shouldn't
-
-            // enable scissor for this frame
-            getRenderEngine().setScissor(scissor);
+            clientCompositionDisplay.colorTransform = colorMatrix;
         }
     }
 
@@ -3448,10 +3425,11 @@
      */
 
     ALOGV("Rendering client layers");
-    const ui::Transform& displayTransform = displayState.transform;
     bool firstLayer = true;
+    Region clearRegion = Region::INVALID_REGION;
     for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
-        const Region clip(bounds.intersect(displayTransform.transform(layer->visibleRegion)));
+        const Region viewportRegion(displayState.viewport);
+        const Region clip(viewportRegion.intersect(layer->visibleRegion));
         ALOGV("Layer: %s", layer->getName().string());
         ALOGV("  Composition type: %s", to_string(layer->getCompositionType(displayId)).c_str());
         if (!clip.isEmpty()) {
@@ -3467,22 +3445,28 @@
                         layer->getRoundedCornerState().radius == 0.0f && hasClientComposition) {
                         // never clear the very first layer since we're
                         // guaranteed the FB is already cleared
-                        layer->clearWithOpenGL(renderArea);
+                        renderengine::LayerSettings layerSettings;
+                        Region dummyRegion;
+                        bool prepared = layer->prepareClientLayer(renderArea, clip, dummyRegion,
+                                                                  layerSettings);
+
+                        if (prepared) {
+                            layerSettings.source.buffer.buffer = nullptr;
+                            layerSettings.source.solidColor = half3(0.0, 0.0, 0.0);
+                            layerSettings.alpha = half(0.0);
+                            layerSettings.disableBlending = true;
+                            clientCompositionLayers.push_back(layerSettings);
+                        }
                     }
                     break;
                 }
                 case HWC2::Composition::Client: {
-                    if (layer->hasColorTransform()) {
-                        mat4 tmpMatrix;
-                        if (applyColorMatrix) {
-                            tmpMatrix = mDrawingState.colorMatrix;
-                        }
-                        tmpMatrix *= layer->getColorTransform();
-                        getRenderEngine().setColorTransform(tmpMatrix);
-                    } else {
-                        getRenderEngine().setColorTransform(colorMatrix);
+                    renderengine::LayerSettings layerSettings;
+                    bool prepared =
+                            layer->prepareClientLayer(renderArea, clip, clearRegion, layerSettings);
+                    if (prepared) {
+                        clientCompositionLayers.push_back(layerSettings);
                     }
-                    layer->draw(renderArea, clip);
                     break;
                 }
                 default:
@@ -3496,12 +3480,22 @@
 
     // Perform some cleanup steps if we used client composition.
     if (hasClientComposition) {
-        getRenderEngine().setColorTransform(mat4());
-        getRenderEngine().disableScissor();
-        display->getRenderSurface()->finishBuffer();
-        // Clear out error flags here so that we don't wait until next
-        // composition to log.
-        getRenderEngine().checkErrors();
+        clientCompositionDisplay.clearRegion = clearRegion;
+        if (!debugRegion.isEmpty()) {
+            Region::const_iterator it = debugRegion.begin();
+            Region::const_iterator end = debugRegion.end();
+            while (it != end) {
+                const Rect& rect = *it++;
+                renderengine::LayerSettings layerSettings;
+                layerSettings.source.buffer.buffer = nullptr;
+                layerSettings.source.solidColor = half3(1.0, 0.0, 1.0);
+                layerSettings.geometry.boundaries = rect.toFloatRect();
+                layerSettings.alpha = half(1.0);
+                clientCompositionLayers.push_back(layerSettings);
+            }
+        }
+        getRenderEngine().drawLayers(clientCompositionDisplay, clientCompositionLayers,
+                                     buf->getNativeBuffer(), readyFence);
     }
     return true;
 }
@@ -5396,8 +5390,8 @@
     DisplayRenderArea renderArea(display, sourceCrop, reqWidth, reqHeight, reqDataspace,
                                  renderAreaRotation);
 
-    auto traverseLayers = std::bind(std::mem_fn(&SurfaceFlinger::traverseLayersInDisplay), this,
-                                    display, std::placeholders::_1);
+    auto traverseLayers = std::bind(&SurfaceFlinger::traverseLayersInDisplay, this, display,
+                                    std::placeholders::_1);
     return captureScreenCommon(renderArea, traverseLayers, outBuffer, reqPixelFormat,
                                useIdentityTransform);
 }
@@ -5616,35 +5610,109 @@
 
 void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
                                             TraverseLayersFunction traverseLayers,
-                                            bool useIdentityTransform) {
+                                            ANativeWindowBuffer* buffer, bool useIdentityTransform,
+                                            int* outSyncFd) {
     ATRACE_CALL();
 
-    auto& engine(getRenderEngine());
-
     const auto reqWidth = renderArea.getReqWidth();
     const auto reqHeight = renderArea.getReqHeight();
     const auto sourceCrop = renderArea.getSourceCrop();
     const auto rotation = renderArea.getRotationFlags();
 
-    engine.setOutputDataSpace(renderArea.getReqDataSpace());
-    engine.setDisplayMaxLuminance(DisplayDevice::sDefaultMaxLumiance);
+    renderengine::DisplaySettings clientCompositionDisplay;
+    std::vector<renderengine::LayerSettings> clientCompositionLayers;
 
-    // make sure to clear all GL error flags
-    engine.checkErrors();
+    // assume that bounds are never offset, and that they are the same as the
+    // buffer bounds.
+    clientCompositionDisplay.physicalDisplay = Rect(reqWidth, reqHeight);
+    ui::Transform transform = renderArea.getTransform();
+    mat4 m;
+    m[0][0] = transform[0][0];
+    m[0][1] = transform[0][1];
+    m[0][3] = transform[0][2];
+    m[1][0] = transform[1][0];
+    m[1][1] = transform[1][1];
+    m[1][3] = transform[1][2];
+    m[3][0] = transform[2][0];
+    m[3][1] = transform[2][1];
+    m[3][3] = transform[2][2];
 
-    // set-up our viewport
-    engine.setViewportAndProjection(reqWidth, reqHeight, sourceCrop, rotation);
-    engine.disableTexturing();
+    clientCompositionDisplay.globalTransform = m;
+    mat4 rotMatrix;
+    // Displacement for repositioning the clipping rectangle after rotating it
+    // with the rotation hint.
+    int displacementX = 0;
+    int displacementY = 0;
+    float rot90InRadians = 2.0f * static_cast<float>(M_PI) / 4.0f;
+    switch (rotation) {
+        case ui::Transform::ROT_90:
+            rotMatrix = mat4::rotate(rot90InRadians, vec3(0, 0, 1));
+            displacementX = reqWidth;
+            break;
+        case ui::Transform::ROT_180:
+            rotMatrix = mat4::rotate(rot90InRadians * 2.0f, vec3(0, 0, 1));
+            displacementX = reqWidth;
+            displacementY = reqHeight;
+            break;
+        case ui::Transform::ROT_270:
+            rotMatrix = mat4::rotate(rot90InRadians * 3.0f, vec3(0, 0, 1));
+            displacementY = reqHeight;
+            break;
+        default:
+            break;
+    }
+    // We need to transform the clipping window into the right spot.
+    // First, rotate the clipping rectangle by the rotation hint to get the
+    // right orientation
+    const vec4 clipTL = vec4(sourceCrop.left, sourceCrop.top, 0, 1);
+    const vec4 clipBR = vec4(sourceCrop.right, sourceCrop.bottom, 0, 1);
+    const vec4 rotClipTL = rotMatrix * clipTL;
+    const vec4 rotClipBR = rotMatrix * clipBR;
+    const int newClipLeft = std::min(rotClipTL[0], rotClipBR[0]);
+    const int newClipTop = std::min(rotClipTL[1], rotClipBR[1]);
+    const int newClipRight = std::max(rotClipTL[0], rotClipBR[0]);
+    const int newClipBottom = std::max(rotClipTL[1], rotClipBR[1]);
+
+    // Now reposition the clipping rectangle with the displacement vector
+    // computed above.
+    const mat4 displacementMat = mat4::translate(vec4(displacementX, displacementY, 0, 1));
+
+    clientCompositionDisplay.clip =
+            Rect(newClipLeft + displacementX, newClipTop + displacementY,
+                 newClipRight + displacementX, newClipBottom + displacementY);
+
+    // We need to perform the same transformation in layer space, so propagate
+    // it to the global transform.
+    mat4 clipTransform = displacementMat * rotMatrix;
+    clientCompositionDisplay.globalTransform *= clipTransform;
+    clientCompositionDisplay.outputDataspace = renderArea.getReqDataSpace();
+    clientCompositionDisplay.maxLuminance = DisplayDevice::sDefaultMaxLumiance;
 
     const float alpha = RenderArea::getCaptureFillValue(renderArea.getCaptureFill());
-    // redraw the screen entirely...
-    engine.clearWithColor(0, 0, 0, alpha);
 
+    renderengine::LayerSettings fillLayer;
+    fillLayer.source.buffer.buffer = nullptr;
+    fillLayer.source.solidColor = half3(0.0, 0.0, 0.0);
+    fillLayer.geometry.boundaries = FloatRect(0.0, 0.0, 1.0, 1.0);
+    fillLayer.alpha = half(alpha);
+    clientCompositionLayers.push_back(fillLayer);
+
+    Region clearRegion = Region::INVALID_REGION;
     traverseLayers([&](Layer* layer) {
-        engine.setColorTransform(layer->getColorTransform());
-        layer->draw(renderArea, useIdentityTransform);
-        engine.setColorTransform(mat4());
+        renderengine::LayerSettings layerSettings;
+        bool prepared = layer->prepareClientLayer(renderArea, useIdentityTransform, clearRegion,
+                                                  layerSettings);
+        if (prepared) {
+            clientCompositionLayers.push_back(layerSettings);
+        }
     });
+
+    clientCompositionDisplay.clearRegion = clearRegion;
+    base::unique_fd drawFence;
+    getRenderEngine().drawLayers(clientCompositionDisplay, clientCompositionLayers, buffer,
+                                 &drawFence);
+
+    *outSyncFd = drawFence.release();
 }
 
 status_t SurfaceFlinger::captureScreenImplLocked(const RenderArea& renderArea,
@@ -5668,28 +5736,7 @@
         ALOGW("FB is protected: PERMISSION_DENIED");
         return PERMISSION_DENIED;
     }
-    auto& engine(getRenderEngine());
-
-    // this binds the given EGLImage as a framebuffer for the
-    // duration of this scope.
-    renderengine::BindNativeBufferAsFramebuffer bufferBond(engine, buffer);
-    if (bufferBond.getStatus() != NO_ERROR) {
-        ALOGE("got ANWB binding error while taking screenshot");
-        return INVALID_OPERATION;
-    }
-
-    // this will in fact render into our dequeued buffer
-    // via an FBO, which means we didn't have to create
-    // an EGLSurface and therefore we're not
-    // dependent on the context's EGLConfig.
-    renderScreenImplLocked(renderArea, traverseLayers, useIdentityTransform);
-
-    base::unique_fd syncFd = engine.flush();
-    if (syncFd < 0) {
-        engine.finish();
-    }
-    *outSyncFd = syncFd.release();
-
+    renderScreenImplLocked(renderArea, traverseLayers, buffer, useIdentityTransform, outSyncFd);
     return NO_ERROR;
 }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index c878a08..6546973 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -60,6 +60,7 @@
 #include "Scheduler/EventThread.h"
 #include "Scheduler/MessageQueue.h"
 #include "Scheduler/PhaseOffsets.h"
+#include "Scheduler/RefreshRateConfigs.h"
 #include "Scheduler/RefreshRateStats.h"
 #include "Scheduler/Scheduler.h"
 #include "Scheduler/VSyncModulator.h"
@@ -502,8 +503,6 @@
 
     // called on the main thread in response to initializeDisplays()
     void onInitializeDisplays() REQUIRES(mStateLock);
-    // setActiveConfigInternal() posted on a main thread for async execution
-    status_t setActiveConfigAsync(const sp<IBinder>& displayToken, int mode);
     // called on the main thread in response to setActiveConfig()
     void setActiveConfigInternal(const sp<IBinder>& displayToken, int mode) REQUIRES(mStateLock);
     // called on the main thread in response to setPowerMode()
@@ -520,7 +519,8 @@
     void handleTransaction(uint32_t transactionFlags);
     void handleTransactionLocked(uint32_t transactionFlags);
 
-    void updateInputWindows();
+    void updateInputFlinger();
+    void updateInputWindowInfo();
     void executeInputWindowCommands();
     void updateCursorAsync();
 
@@ -598,7 +598,8 @@
     void startBootAnim();
 
     void renderScreenImplLocked(const RenderArea& renderArea, TraverseLayersFunction traverseLayers,
-                                bool useIdentityTransform);
+                                ANativeWindowBuffer* buffer, bool useIdentityTransform,
+                                int* outSyncFd);
     status_t captureScreenCommon(RenderArea& renderArea, TraverseLayersFunction traverseLayers,
                                  sp<GraphicBuffer>* outBuffer, const ui::PixelFormat reqPixelFormat,
                                  bool useIdentityTransform);
@@ -737,8 +738,11 @@
     void logLayerStats();
     void doDisplayComposition(const sp<DisplayDevice>& display, const Region& dirtyRegion);
 
-    // This fails if using GL and the surface has been destroyed.
-    bool doComposeSurfaces(const sp<DisplayDevice>& display);
+    // This fails if using GL and the surface has been destroyed. readyFence
+    // will be populated if using GL and native fence sync is supported, to
+    // signal when drawing has completed.
+    bool doComposeSurfaces(const sp<DisplayDevice>& display, const Region& debugRegionm,
+                           base::unique_fd* readyFence);
 
     void postFramebuffer(const sp<DisplayDevice>& display);
     void postFrame();
@@ -765,9 +769,9 @@
     void resyncToHardwareVsync(bool makeAvailable, nsecs_t period);
     void disableHardwareVsync(bool makeUnavailable);
 
-    // Sets the refresh rate to newFps by switching active configs, if they are available for
+    // Sets the refresh rate by switching active configs, if they are available for
     // the desired refresh rate.
-    void setRefreshRateTo(float newFps);
+    void setRefreshRateTo(scheduler::RefreshRateConfigs::RefreshRateType) REQUIRES(mStateLock);
 
     using GetVsyncPeriod = std::function<nsecs_t()>;
 
@@ -947,9 +951,13 @@
     // don't need synchronization
     State mDrawingState{LayerVector::StateSet::Drawing};
     bool mVisibleRegionsDirty;
+    // Set during transaction commit stage to track if the input info for a layer has changed.
+    bool mInputInfoChanged{false};
     bool mGeometryInvalid;
     bool mAnimCompositionPending;
     std::vector<sp<Layer>> mLayersWithQueuedFrames;
+    // Tracks layers that need to update a display's dirty region.
+    std::vector<sp<Layer>> mLayersPendingRefresh;
     sp<Fence> mPreviousPresentFence = Fence::NO_FENCE;
     bool mHadClientComposition = false;
 
diff --git a/services/surfaceflinger/TimeStats/OWNERS b/services/surfaceflinger/TimeStats/OWNERS
new file mode 100644
index 0000000..ac02d12
--- /dev/null
+++ b/services/surfaceflinger/TimeStats/OWNERS
@@ -0,0 +1 @@
+zzyiwei@google.com
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/Stress_test.cpp b/services/surfaceflinger/tests/Stress_test.cpp
index 89c26f4..ee857b0 100644
--- a/services/surfaceflinger/tests/Stress_test.cpp
+++ b/services/surfaceflinger/tests/Stress_test.cpp
@@ -34,7 +34,7 @@
             auto surf = client->createSurface(String8("t"), 100, 100,
                     PIXEL_FORMAT_RGBA_8888, 0);
             ASSERT_TRUE(surf != nullptr);
-            surf->clear();
+            surf.clear();
         }
     };
 
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index 3770317..7b21dbc 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -1134,7 +1134,7 @@
             .setRelativeLayer(layerG, layerR->getHandle(), 1)
             .apply();
 
-    layerG->clear();
+    layerG.clear();
     // layerG should have been removed
     getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED);
 }
@@ -1537,7 +1537,6 @@
         SCOPED_TRACE("default before setting background color layer");
         screenshot()->expectColor(Rect(0, 0, width, height), expectedColor);
     }
-
     Transaction()
             .setBackgroundColor(layer, half3(0, 1.0f, 0), alpha, ui::Dataspace::UNKNOWN)
             .apply();
@@ -3126,16 +3125,25 @@
     }
 
     static int fillTransaction(Transaction& transaction, CallbackHelper* callbackHelper,
-                               const sp<SurfaceControl>& layer = nullptr) {
+                               const sp<SurfaceControl>& layer = nullptr, bool setBuffer = true,
+                               bool setBackgroundColor = false) {
         if (layer) {
             sp<GraphicBuffer> buffer;
             sp<Fence> fence;
-            int err = getBuffer(&buffer, &fence);
-            if (err != NO_ERROR) {
-                return err;
+            if (setBuffer) {
+                int err = getBuffer(&buffer, &fence);
+                if (err != NO_ERROR) {
+                    return err;
+                }
+
+                transaction.setBuffer(layer, buffer);
+                transaction.setAcquireFence(layer, fence);
             }
 
-            transaction.setBuffer(layer, buffer).setAcquireFence(layer, fence);
+            if (setBackgroundColor) {
+                transaction.setBackgroundColor(layer, /*color*/ half3(1.0f, 0, 0), /*alpha*/ 1.0f,
+                                               ui::Dataspace::UNKNOWN);
+            }
         }
 
         transaction.addTransactionCompletedCallback(callbackHelper->function,
@@ -3166,13 +3174,13 @@
     }
 };
 
-TEST_F(LayerCallbackTest, Basic) {
+TEST_F(LayerCallbackTest, BufferColor) {
     sp<SurfaceControl> layer;
     ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
 
     Transaction transaction;
     CallbackHelper callback;
-    int err = fillTransaction(transaction, &callback, layer);
+    int err = fillTransaction(transaction, &callback, layer, true, true);
     if (err) {
         GTEST_SUCCEED() << "test not supported";
         return;
@@ -3185,13 +3193,13 @@
     EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
 }
 
-TEST_F(LayerCallbackTest, NoBuffer) {
+TEST_F(LayerCallbackTest, NoBufferNoColor) {
     sp<SurfaceControl> layer;
     ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
 
     Transaction transaction;
     CallbackHelper callback;
-    int err = fillTransaction(transaction, &callback);
+    int err = fillTransaction(transaction, &callback, layer, false, false);
     if (err) {
         GTEST_SUCCEED() << "test not supported";
         return;
@@ -3205,6 +3213,45 @@
     EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
 }
 
+TEST_F(LayerCallbackTest, BufferNoColor) {
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+
+    Transaction transaction;
+    CallbackHelper callback;
+    int err = fillTransaction(transaction, &callback, layer, true, false);
+    if (err) {
+        GTEST_SUCCEED() << "test not supported";
+        return;
+    }
+
+    transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply();
+
+    ExpectedResult expected;
+    expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer);
+    EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
+}
+
+TEST_F(LayerCallbackTest, NoBufferColor) {
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+
+    Transaction transaction;
+    CallbackHelper callback;
+    int err = fillTransaction(transaction, &callback, layer, false, true);
+    if (err) {
+        GTEST_SUCCEED() << "test not supported";
+        return;
+    }
+
+    transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply();
+
+    ExpectedResult expected;
+    expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
+                        ExpectedResult::Buffer::NOT_ACQUIRED);
+    EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
+}
+
 TEST_F(LayerCallbackTest, NoStateChange) {
     Transaction transaction;
     CallbackHelper callback;
@@ -3239,7 +3286,7 @@
     EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
 }
 
-TEST_F(LayerCallbackTest, Merge) {
+TEST_F(LayerCallbackTest, MergeBufferNoColor) {
     sp<SurfaceControl> layer1, layer2;
     ASSERT_NO_FATAL_FAILURE(layer1 = createBufferStateLayer());
     ASSERT_NO_FATAL_FAILURE(layer2 = createBufferStateLayer());
@@ -3266,6 +3313,62 @@
     EXPECT_NO_FATAL_FAILURE(waitForCallback(callback2, expected, true));
 }
 
+TEST_F(LayerCallbackTest, MergeNoBufferColor) {
+    sp<SurfaceControl> layer1, layer2;
+    ASSERT_NO_FATAL_FAILURE(layer1 = createBufferStateLayer());
+    ASSERT_NO_FATAL_FAILURE(layer2 = createBufferStateLayer());
+
+    Transaction transaction1, transaction2;
+    CallbackHelper callback1, callback2;
+    int err = fillTransaction(transaction1, &callback1, layer1, false, true);
+    if (err) {
+        GTEST_SUCCEED() << "test not supported";
+        return;
+    }
+    err = fillTransaction(transaction2, &callback2, layer2, false, true);
+    if (err) {
+        GTEST_SUCCEED() << "test not supported";
+        return;
+    }
+
+    transaction1.setFrame(layer1, Rect(0, 0, 32, 32));
+    transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply();
+
+    ExpectedResult expected;
+    expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2},
+                         ExpectedResult::Buffer::NOT_ACQUIRED);
+    EXPECT_NO_FATAL_FAILURE(waitForCallback(callback1, expected, true));
+    EXPECT_NO_FATAL_FAILURE(waitForCallback(callback2, expected, true));
+}
+
+TEST_F(LayerCallbackTest, MergeOneBufferOneColor) {
+    sp<SurfaceControl> layer1, layer2;
+    ASSERT_NO_FATAL_FAILURE(layer1 = createBufferStateLayer());
+    ASSERT_NO_FATAL_FAILURE(layer2 = createBufferStateLayer());
+
+    Transaction transaction1, transaction2;
+    CallbackHelper callback1, callback2;
+    int err = fillTransaction(transaction1, &callback1, layer1);
+    if (err) {
+        GTEST_SUCCEED() << "test not supported";
+        return;
+    }
+    err = fillTransaction(transaction2, &callback2, layer2, false, true);
+    if (err) {
+        GTEST_SUCCEED() << "test not supported";
+        return;
+    }
+
+    transaction1.setFrame(layer1, Rect(0, 0, 32, 32));
+    transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply();
+
+    ExpectedResult expected;
+    expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer1);
+    expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer2,
+                        ExpectedResult::Buffer::NOT_ACQUIRED);
+    EXPECT_NO_FATAL_FAILURE(waitForCallback(callback1, expected, true));
+    EXPECT_NO_FATAL_FAILURE(waitForCallback(callback2, expected, true));
+}
 TEST_F(LayerCallbackTest, Merge_SameCallback) {
     sp<SurfaceControl> layer1, layer2;
     ASSERT_NO_FATAL_FAILURE(layer1 = createBufferStateLayer());
@@ -4332,7 +4435,7 @@
         mCapture->checkPixel(64, 64, 111, 111, 111);
     }
 
-    mChild->clear();
+    mChild.clear();
 
     {
         SCOPED_TRACE("After destroying child");
@@ -5204,7 +5307,7 @@
     ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
 
     auto redLayerHandle = redLayer->getHandle();
-    redLayer->clear();
+    redLayer.clear();
     SurfaceComposerClient::Transaction().apply(true);
 
     sp<GraphicBuffer> outBuffer;
diff --git a/services/surfaceflinger/tests/unittests/AsyncCallRecorder.h b/services/surfaceflinger/tests/unittests/AsyncCallRecorder.h
index 2245ee1..8bed766 100644
--- a/services/surfaceflinger/tests/unittests/AsyncCallRecorder.h
+++ b/services/surfaceflinger/tests/unittests/AsyncCallRecorder.h
@@ -75,14 +75,16 @@
 template <typename... Args>
 class AsyncCallRecorder<void (*)(Args...)> {
 public:
-    // For the tests, we expect the wait for an expected change to be signaled
-    // to be much shorter than this.
-    static constexpr std::chrono::milliseconds DEFAULT_CALL_EXPECTED_TIMEOUT{10};
+    // This wait value needs to be large enough to avoid flakes caused by delays
+    // scheduling threads, but small enough that tests don't take forever if
+    // something really is wrong. Based on some empirical evidence, 100ms should
+    // be enough to avoid the former.
+    static constexpr std::chrono::milliseconds DEFAULT_CALL_EXPECTED_TIMEOUT{100};
 
-    // The wait here is tricky. We don't expect a change, but we don't want to
-    // wait forever (or for longer than the typical test function runtime). As
-    // even the simplest Google Test can take 1ms (1000us) to run, we wait for
-    // half that time.
+    // The wait here is tricky. It's for when We don't expect to record a call,
+    // but we don't want to wait forever (or for longer than the typical test
+    // function runtime). As even the simplest Google Test can take 1ms (1000us)
+    // to run, we wait for half that time.
     static constexpr std::chrono::microseconds UNEXPECTED_CALL_TIMEOUT{500};
 
     using ArgTuple = std::tuple<std::remove_cv_t<std::remove_reference_t<Args>>...>;
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index e092aed..ee79c18 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -45,8 +45,10 @@
 
 using testing::_;
 using testing::AtLeast;
+using testing::Between;
 using testing::ByMove;
 using testing::DoAll;
+using testing::Field;
 using testing::Invoke;
 using testing::IsNull;
 using testing::Mock;
@@ -159,7 +161,6 @@
     renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
     mock::MessageQueue* mMessageQueue = new mock::MessageQueue();
     mock::DispSync* mPrimaryDispSync = new mock::DispSync();
-    renderengine::mock::Image* mReImage = new renderengine::mock::Image();
     renderengine::mock::Framebuffer* mReFrameBuffer = new renderengine::mock::Framebuffer();
 
     sp<Fence> mClientTargetAcquireFence = Fence::NO_FENCE;
@@ -279,11 +280,10 @@
         EXPECT_CALL(*test->mComposer, getReleaseFences(HWC_DISPLAY, _, _)).Times(1);
 
         EXPECT_CALL(*test->mRenderEngine, useNativeFenceSync()).WillRepeatedly(Return(true));
-        EXPECT_CALL(*test->mRenderEngine, checkErrors()).WillRepeatedly(Return());
-        EXPECT_CALL(*test->mRenderEngine, isCurrent()).WillRepeatedly(Return(true));
-
+        // TODO: remove once we verify that we can just grab the fence from the
+        // FramebufferSurface.
         EXPECT_CALL(*test->mRenderEngine, flush()).WillRepeatedly(Invoke([]() {
-            return base::unique_fd(0);
+            return base::unique_fd();
         }));
 
         EXPECT_CALL(*test->mDisplaySurface, onFrameCommitted()).Times(1);
@@ -295,36 +295,18 @@
 
     template <typename Case>
     static void setupCommonScreensCaptureCallExpectations(CompositionTest* test) {
-        // Called once with a non-null value to set a framebuffer, and then
-        // again with nullptr to clear it.
-        EXPECT_CALL(*test->mReFrameBuffer, setNativeWindowBuffer(NotNull(), false))
-                .WillOnce(Return(true));
-        EXPECT_CALL(*test->mReFrameBuffer, setNativeWindowBuffer(IsNull(), false))
-                .WillOnce(Return(true));
-
-        EXPECT_CALL(*test->mRenderEngine, checkErrors()).WillRepeatedly(Return());
-        EXPECT_CALL(*test->mRenderEngine, createFramebuffer())
-                .WillOnce(Return(
-                        ByMove(std::unique_ptr<renderengine::Framebuffer>(test->mReFrameBuffer))));
-        EXPECT_CALL(*test->mRenderEngine, bindFrameBuffer(test->mReFrameBuffer)).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, unbindFrameBuffer(test->mReFrameBuffer)).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, clearWithColor(0, 0, 0, 1)).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, flush()).WillOnce(Return(ByMove(base::unique_fd())));
-        EXPECT_CALL(*test->mRenderEngine, finish()).WillOnce(Return(true));
-
-        EXPECT_CALL(*test->mRenderEngine, setOutputDataSpace(_)).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, setDisplayMaxLuminance(DEFAULT_DISPLAY_MAX_LUMINANCE))
-                .Times(1);
-        // This expectation retires on saturation as setViewportAndProjection is
-        // called an extra time for the code path this setup is for.
-        // TODO: Investigate this extra call
-        EXPECT_CALL(*test->mRenderEngine,
-                    setViewportAndProjection(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
-                                             Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
-                                             ui::Transform::ROT_0))
-                .Times(1)
-                .RetiresOnSaturation();
-        EXPECT_CALL(*test->mRenderEngine, disableTexturing()).Times(1);
+        EXPECT_CALL(*test->mRenderEngine, drawLayers)
+                .WillRepeatedly(
+                        [](const renderengine::DisplaySettings& displaySettings,
+                           const std::vector<renderengine::LayerSettings>& /*layerSettings*/,
+                           ANativeWindowBuffer*, base::unique_fd*) -> status_t {
+                            EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
+                            EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
+                                      displaySettings.physicalDisplay);
+                            EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
+                                      displaySettings.clip);
+                            return NO_ERROR;
+                        });
     }
 
     static void setupNonEmptyFrameCompositionCallExpectations(CompositionTest* test) {
@@ -348,31 +330,23 @@
         EXPECT_CALL(*test->mDisplaySurface, getClientTargetAcquireFence())
                 .WillRepeatedly(ReturnRef(test->mClientTargetAcquireFence));
 
-        EXPECT_CALL(*test->mRenderEngine, setOutputDataSpace(ui::Dataspace::UNKNOWN)).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, setDisplayMaxLuminance(DEFAULT_DISPLAY_MAX_LUMINANCE))
-                .Times(1);
-        EXPECT_CALL(*test->mRenderEngine, setColorTransform(_)).Times(2);
-        // These expectations retire on saturation as the code path these
-        // expectations are for appears to make an extra call to them.
-        // TODO: Investigate this extra call
-        EXPECT_CALL(*test->mRenderEngine,
-                    setViewportAndProjection(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
-                                             Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
-                                             ui::Transform::ROT_0))
-                .Times(1);
-        EXPECT_CALL(*test->mReFrameBuffer, setNativeWindowBuffer(NotNull(), false))
-                .WillOnce(Return(true));
-        EXPECT_CALL(*test->mReFrameBuffer, setNativeWindowBuffer(IsNull(), false))
-                .WillOnce(Return(true));
-        EXPECT_CALL(*test->mRenderEngine, createFramebuffer())
-                .WillOnce(Return(
-                        ByMove(std::unique_ptr<renderengine::Framebuffer>(test->mReFrameBuffer))));
-        EXPECT_CALL(*test->mRenderEngine, bindFrameBuffer(test->mReFrameBuffer)).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, unbindFrameBuffer(test->mReFrameBuffer)).Times(1);
         EXPECT_CALL(*test->mNativeWindow, queueBuffer(_, _)).WillOnce(Return(0));
         EXPECT_CALL(*test->mNativeWindow, dequeueBuffer(_, _))
                 .WillOnce(DoAll(SetArgPointee<0>(test->mNativeWindowBuffer), SetArgPointee<1>(-1),
                                 Return(0)));
+        EXPECT_CALL(*test->mRenderEngine, drawLayers)
+                .WillRepeatedly(
+                        [](const renderengine::DisplaySettings& displaySettings,
+                           const std::vector<renderengine::LayerSettings>& /*layerSettings*/,
+                           ANativeWindowBuffer*, base::unique_fd*) -> status_t {
+                            EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
+                            EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
+                                      displaySettings.physicalDisplay);
+                            EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
+                                      displaySettings.clip);
+                            EXPECT_EQ(ui::Dataspace::UNKNOWN, displaySettings.outputDataspace);
+                            return NO_ERROR;
+                        });
     }
 
     template <typename Case>
@@ -383,8 +357,6 @@
     template <typename Case>
     static void setupRELayerScreenshotCompositionCallExpectations(CompositionTest* test) {
         Case::Layer::setupREScreenshotCompositionCallExpectations(test);
-
-        EXPECT_CALL(*test->mRenderEngine, isCurrent()).WillRepeatedly(Return(true));
     }
 };
 
@@ -396,16 +368,11 @@
     template <typename Case>
     static void setupRELayerCompositionCallExpectations(CompositionTest* test) {
         Case::Layer::setupInsecureRECompositionCallExpectations(test);
-
-        // TODO: Investigate this extra call
-        EXPECT_CALL(*test->mRenderEngine, disableScissor()).Times(1);
     }
 
     template <typename Case>
     static void setupRELayerScreenshotCompositionCallExpectations(CompositionTest* test) {
         Case::Layer::setupInsecureREScreenshotCompositionCallExpectations(test);
-
-        EXPECT_CALL(*test->mRenderEngine, isCurrent()).WillRepeatedly(Return(true));
     }
 };
 
@@ -516,7 +483,6 @@
         bool ignoredRecomputeVisibleRegions;
         layer->latchBuffer(ignoredRecomputeVisibleRegions, 0, Fence::NO_FENCE);
         Mock::VerifyAndClear(test->mRenderEngine);
-        Mock::VerifyAndClear(test->mReImage);
     }
 
     static void setupLayerState(CompositionTest* test, sp<BufferQueueLayer> layer) {
@@ -598,33 +564,35 @@
     }
 
     static void setupREBufferCompositionCommonCallExpectations(CompositionTest* test) {
-        EXPECT_CALL(*test->mRenderEngine,
-                    setupLayerBlending(true, false, false,
-                                       half4(LayerProperties::COLOR[0], LayerProperties::COLOR[1],
-                                             LayerProperties::COLOR[2], LayerProperties::COLOR[3]),
-                                       0.0f))
-                .Times(1);
-
-        EXPECT_CALL(*test->mRenderEngine, createImage())
-                .WillOnce(Return(ByMove(std::unique_ptr<renderengine::Image>(test->mReImage))));
-        EXPECT_CALL(*test->mReImage, setNativeWindowBuffer(_, _)).WillOnce(Return(true));
-        EXPECT_CALL(*test->mRenderEngine, bindExternalTextureImage(DEFAULT_TEXTURE_ID, _)).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, setupLayerTexturing(_)).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, setSourceDataSpace(ui::Dataspace::UNKNOWN)).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, drawMesh(_)).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, disableBlending()).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, setSourceY410BT2020(false)).Times(1);
-        // This call retires on saturation as the code that renders a texture disables the state,
-        // along with a top-level disable to ensure it is disabled for non-buffer layers.
-        EXPECT_CALL(*test->mRenderEngine, disableTexturing()).Times(1).RetiresOnSaturation();
+        EXPECT_CALL(*test->mRenderEngine, drawLayers)
+                .WillOnce([](const renderengine::DisplaySettings& displaySettings,
+                             const std::vector<renderengine::LayerSettings>& layerSettings,
+                             ANativeWindowBuffer*, base::unique_fd*) -> status_t {
+                    EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
+                    EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
+                              displaySettings.physicalDisplay);
+                    EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
+                              displaySettings.clip);
+                    // screen capture adds an additional color layer as an alpha
+                    // prefill, so gtet the back layer.
+                    renderengine::LayerSettings layer = layerSettings.back();
+                    EXPECT_THAT(layer.source.buffer.buffer, Not(IsNull()));
+                    EXPECT_THAT(layer.source.buffer.fence, Not(IsNull()));
+                    EXPECT_EQ(renderengine::Buffer::CachingHint::NO_CACHE,
+                              layer.source.buffer.cacheHint);
+                    EXPECT_EQ(DEFAULT_TEXTURE_ID, layer.source.buffer.textureName);
+                    EXPECT_EQ(false, layer.source.buffer.isY410BT2020);
+                    EXPECT_EQ(true, layer.source.buffer.usePremultipliedAlpha);
+                    EXPECT_EQ(false, layer.source.buffer.isOpaque);
+                    EXPECT_EQ(0.0, layer.geometry.roundedCornersRadius);
+                    EXPECT_EQ(ui::Dataspace::UNKNOWN, layer.sourceDataspace);
+                    EXPECT_EQ(LayerProperties::COLOR[3], layer.alpha);
+                    return NO_ERROR;
+                });
     }
 
     static void setupREBufferCompositionCallExpectations(CompositionTest* test) {
         LayerProperties::setupREBufferCompositionCommonCallExpectations(test);
-
-        // TODO - Investigate and eliminate these differences between display
-        // composition and screenshot composition.
-        EXPECT_CALL(*test->mRenderEngine, disableScissor()).Times(1);
     }
 
     static void setupInsecureREBufferCompositionCallExpectations(CompositionTest* test) {
@@ -639,20 +607,28 @@
         LayerProperties::setupREBufferCompositionCommonCallExpectations(test);
     }
 
-    static void setupREColorCompositionCommonCallExpectations(CompositionTest* test) {
-        EXPECT_CALL(*test->mRenderEngine, disableScissor()).Times(1);
-    }
-
     static void setupREColorCompositionCallExpectations(CompositionTest* test) {
-        EXPECT_CALL(*test->mRenderEngine, setSourceDataSpace(ui::Dataspace::UNKNOWN)).Times(1);
-        EXPECT_CALL(*test->mRenderEngine,
-                    setupLayerBlending(true, false, true,
-                                       half4(LayerProperties::COLOR[0], LayerProperties::COLOR[1],
-                                             LayerProperties::COLOR[2], LayerProperties::COLOR[3]),
-                                       0.0f))
-                .Times(1);
-        EXPECT_CALL(*test->mRenderEngine, drawMesh(_)).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, disableBlending()).Times(1);
+        EXPECT_CALL(*test->mRenderEngine, drawLayers)
+                .WillOnce([](const renderengine::DisplaySettings& displaySettings,
+                             const std::vector<renderengine::LayerSettings>& layerSettings,
+                             ANativeWindowBuffer*, base::unique_fd*) -> status_t {
+                    EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
+                    EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
+                              displaySettings.physicalDisplay);
+                    EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
+                              displaySettings.clip);
+                    // screen capture adds an additional color layer as an alpha
+                    // prefill, so get the back layer.
+                    renderengine::LayerSettings layer = layerSettings.back();
+                    EXPECT_THAT(layer.source.buffer.buffer, IsNull());
+                    EXPECT_EQ(half3(LayerProperties::COLOR[0], LayerProperties::COLOR[1],
+                                    LayerProperties::COLOR[2]),
+                              layer.source.solidColor);
+                    EXPECT_EQ(0.0, layer.geometry.roundedCornersRadius);
+                    EXPECT_EQ(ui::Dataspace::UNKNOWN, layer.sourceDataspace);
+                    EXPECT_EQ(LayerProperties::COLOR[3], layer.alpha);
+                    return NO_ERROR;
+                });
     }
 
     static void setupREColorScreenshotCompositionCallExpectations(CompositionTest* test) {
@@ -692,10 +668,7 @@
         EXPECT_CALL(*test->mComposer, setLayerSurfaceDamage(HWC_DISPLAY, HWC_LAYER, _)).Times(1);
     }
 
-    static void setupREBufferCompositionCommonCallExpectations(CompositionTest* test) {
-        EXPECT_CALL(*test->mRenderEngine, setupFillWithColor(0, 0, 0, 1)).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, drawMesh(_)).Times(1);
-    }
+    static void setupREBufferCompositionCommonCallExpectations(CompositionTest* /*test*/) {}
 };
 
 struct SecureLayerProperties : public BaseLayerProperties<SecureLayerProperties> {
@@ -704,25 +677,25 @@
     static constexpr uint32_t LAYER_FLAGS = ISurfaceComposerClient::eSecure;
 
     static void setupInsecureREBufferCompositionCommonCallExpectations(CompositionTest* test) {
-        EXPECT_CALL(*test->mRenderEngine, createImage())
-                .WillOnce(Return(ByMove(std::unique_ptr<renderengine::Image>(test->mReImage))));
-        EXPECT_CALL(*test->mReImage, setNativeWindowBuffer(_, _)).WillOnce(Return(true));
-        EXPECT_CALL(*test->mRenderEngine, bindExternalTextureImage(DEFAULT_TEXTURE_ID, _)).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, setupLayerBlackedOut()).Times(1);
-
-        EXPECT_CALL(*test->mRenderEngine,
-                    setupLayerBlending(true, false, false,
-                                       half4(Base::COLOR[0], Base::COLOR[1], Base::COLOR[2],
-                                             Base::COLOR[3]),
-                                       0.0f))
-                .Times(1);
-        EXPECT_CALL(*test->mRenderEngine, setSourceDataSpace(ui::Dataspace::UNKNOWN)).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, drawMesh(_)).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, disableBlending()).Times(1);
-        EXPECT_CALL(*test->mRenderEngine, setSourceY410BT2020(false)).Times(1);
-        // This call retires on saturation as the code that renders a texture disables the state,
-        // along with a top-level disable to ensure it is disabled for non-buffer layers.
-        EXPECT_CALL(*test->mRenderEngine, disableTexturing()).Times(1).RetiresOnSaturation();
+        EXPECT_CALL(*test->mRenderEngine, drawLayers)
+                .WillOnce([](const renderengine::DisplaySettings& displaySettings,
+                             const std::vector<renderengine::LayerSettings>& layerSettings,
+                             ANativeWindowBuffer*, base::unique_fd*) -> status_t {
+                    EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
+                    EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
+                              displaySettings.physicalDisplay);
+                    EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
+                              displaySettings.clip);
+                    // screen capture adds an additional color layer as an alpha
+                    // prefill, so get the back layer.
+                    renderengine::LayerSettings layer = layerSettings.back();
+                    EXPECT_THAT(layer.source.buffer.buffer, IsNull());
+                    EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), layer.source.solidColor);
+                    EXPECT_EQ(0.0, layer.geometry.roundedCornersRadius);
+                    EXPECT_EQ(ui::Dataspace::UNKNOWN, layer.sourceDataspace);
+                    EXPECT_EQ(1.0f, layer.alpha);
+                    return NO_ERROR;
+                });
     }
 
     static void setupInsecureREBufferCompositionCallExpectations(CompositionTest* test) {
@@ -826,7 +799,6 @@
     }
 
     static void setupRECompositionCallExpectations(CompositionTest* test) {
-        LayerProperties::setupREColorCompositionCommonCallExpectations(test);
         LayerProperties::setupREColorCompositionCallExpectations(test);
     }
 
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index ad7dcb4..3a7cfba 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -53,8 +53,10 @@
     class MockEventThreadConnection : public EventThreadConnection {
     public:
         MockEventThreadConnection(android::impl::EventThread* eventThread,
-                                  ResyncCallback&& resyncCallback)
-              : EventThreadConnection(eventThread, std::move(resyncCallback)) {}
+                                  ResyncCallback&& resyncCallback,
+                                  ResetIdleTimerCallback&& resetIdleTimerCallback)
+              : EventThreadConnection(eventThread, std::move(resyncCallback),
+                                      std::move(resetIdleTimerCallback)) {}
         MOCK_METHOD1(postEvent, status_t(const DisplayEventReceiver::Event& event));
     };
 
@@ -82,6 +84,7 @@
     AsyncCallRecorder<void (*)(VSyncSource::Callback*)> mVSyncSetCallbackCallRecorder;
     AsyncCallRecorder<void (*)(nsecs_t)> mVSyncSetPhaseOffsetCallRecorder;
     AsyncCallRecorder<void (*)()> mResyncCallRecorder;
+    AsyncCallRecorder<void (*)()> mResetIdleTimerCallRecorder;
     AsyncCallRecorder<void (*)(nsecs_t)> mInterceptVSyncCallRecorder;
     ConnectionEventRecorder mConnectionEventCallRecorder{0};
 
@@ -119,7 +122,7 @@
     ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
 
     // EventThread should unregister itself as VSyncSource callback.
-    EXPECT_FALSE(expectVSyncSetCallbackCallReceived());
+    EXPECT_TRUE(!mVSyncSetCallbackCallRecorder.waitForUnexpectedCall().has_value());
 }
 
 void EventThreadTest::createThread() {
@@ -136,7 +139,8 @@
 sp<EventThreadTest::MockEventThreadConnection> EventThreadTest::createConnection(
         ConnectionEventRecorder& recorder) {
     sp<MockEventThreadConnection> connection =
-            new MockEventThreadConnection(mThread.get(), mResyncCallRecorder.getInvocable());
+            new MockEventThreadConnection(mThread.get(), mResyncCallRecorder.getInvocable(),
+                                          mResetIdleTimerCallRecorder.getInvocable());
     EXPECT_CALL(*connection, postEvent(_)).WillRepeatedly(Invoke(recorder.getInvocable()));
     return connection;
 }
@@ -207,6 +211,7 @@
     EXPECT_FALSE(mVSyncSetCallbackCallRecorder.waitForCall(0us).has_value());
     EXPECT_FALSE(mVSyncSetPhaseOffsetCallRecorder.waitForCall(0us).has_value());
     EXPECT_FALSE(mResyncCallRecorder.waitForCall(0us).has_value());
+    EXPECT_FALSE(mResetIdleTimerCallRecorder.waitForCall(0us).has_value());
     EXPECT_FALSE(mInterceptVSyncCallRecorder.waitForCall(0us).has_value());
     EXPECT_FALSE(mConnectionEventCallRecorder.waitForCall(0us).has_value());
 }
@@ -224,9 +229,10 @@
 
 TEST_F(EventThreadTest, requestNextVsyncPostsASingleVSyncEventToTheConnection) {
     // Signal that we want the next vsync event to be posted to the connection
-    mThread->requestNextVsync(mConnection, false);
+    mThread->requestNextVsync(mConnection, true);
 
-    // EventThread should immediately request a resync.
+    // EventThread should immediately reset the idle timer and request a resync.
+    EXPECT_TRUE(mResetIdleTimerCallRecorder.waitForCall().has_value());
     EXPECT_TRUE(mResyncCallRecorder.waitForCall().has_value());
 
     // EventThread should enable vsync callbacks.
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 0db96d9..26b6d0c 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -25,7 +25,7 @@
     class MockEventThreadConnection : public android::EventThreadConnection {
     public:
         explicit MockEventThreadConnection(EventThread* eventThread)
-              : EventThreadConnection(eventThread, ResyncCallback()) {}
+              : EventThreadConnection(eventThread, ResyncCallback(), ResetIdleTimerCallback()) {}
         ~MockEventThreadConnection() = default;
 
         MOCK_METHOD1(stealReceiveChannel, status_t(gui::BitTube* outChannel));
@@ -78,10 +78,11 @@
 
     // createConnection call to scheduler makes a createEventConnection call to EventThread. Make
     // sure that call gets executed and returns an EventThread::Connection object.
-    EXPECT_CALL(*mEventThread, createEventConnection(_))
+    EXPECT_CALL(*mEventThread, createEventConnection(_, _))
             .WillRepeatedly(Return(mEventThreadConnection));
 
     mConnectionHandle = mScheduler->createConnection("appConnection", 16, ResyncCallback(),
+                                                     ResetIdleTimerCallback(),
                                                      impl::EventThread::InterceptVSyncsCallback());
     EXPECT_TRUE(mConnectionHandle != nullptr);
 }
@@ -102,7 +103,8 @@
     // exceptions, just gracefully continues.
     sp<IDisplayEventConnection> returnedValue;
     ASSERT_NO_FATAL_FAILURE(
-            returnedValue = mScheduler->createDisplayEventConnection(nullptr, ResyncCallback()));
+            returnedValue = mScheduler->createDisplayEventConnection(nullptr, ResyncCallback(),
+                                                                     ResetIdleTimerCallback()));
     EXPECT_TRUE(returnedValue == nullptr);
     EXPECT_TRUE(mScheduler->getEventThread(nullptr) == nullptr);
     EXPECT_TRUE(mScheduler->getEventConnection(nullptr) == nullptr);
@@ -123,7 +125,8 @@
     sp<IDisplayEventConnection> returnedValue;
     ASSERT_NO_FATAL_FAILURE(
             returnedValue =
-                    mScheduler->createDisplayEventConnection(connectionHandle, ResyncCallback()));
+                    mScheduler->createDisplayEventConnection(connectionHandle, ResyncCallback(),
+                                                             ResetIdleTimerCallback()));
     EXPECT_TRUE(returnedValue == nullptr);
     EXPECT_TRUE(mScheduler->getEventThread(connectionHandle) == nullptr);
     EXPECT_TRUE(mScheduler->getEventConnection(connectionHandle) == nullptr);
@@ -152,7 +155,8 @@
     sp<IDisplayEventConnection> returnedValue;
     ASSERT_NO_FATAL_FAILURE(
             returnedValue =
-                    mScheduler->createDisplayEventConnection(mConnectionHandle, ResyncCallback()));
+                    mScheduler->createDisplayEventConnection(mConnectionHandle, ResyncCallback(),
+                                                             ResetIdleTimerCallback()));
     EXPECT_TRUE(returnedValue != nullptr);
     ASSERT_EQ(returnedValue, mEventThreadConnection);
 
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
index aaf67e9..589237d 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
@@ -28,7 +28,8 @@
     EventThread();
     ~EventThread() override;
 
-    MOCK_CONST_METHOD1(createEventConnection, sp<EventThreadConnection>(ResyncCallback));
+    MOCK_CONST_METHOD2(createEventConnection,
+                       sp<EventThreadConnection>(ResyncCallback, ResetIdleTimerCallback));
     MOCK_METHOD0(onScreenReleased, void());
     MOCK_METHOD0(onScreenAcquired, void());
     MOCK_METHOD2(onHotplugReceived, void(PhysicalDisplayId, bool));
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
index 164d9e6..f3e54a0 100644
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ b/services/vr/bufferhubd/producer_channel.cpp
@@ -253,7 +253,7 @@
   uint32_t current_active_clients_bit_mask =
       active_clients_bit_mask_->load(std::memory_order_acquire);
   uint32_t consumer_state_mask =
-      BufferHubDefs::FindNextAvailableClientStateMask(
+      BufferHubDefs::findNextAvailableClientStateMask(
           current_active_clients_bit_mask | orphaned_consumer_bit_mask_);
   if (consumer_state_mask == 0U) {
     ALOGE("%s: reached the maximum mumber of consumers per producer: 63.",
@@ -279,7 +279,7 @@
           "condition.",
           __FUNCTION__, updated_active_clients_bit_mask,
           current_active_clients_bit_mask);
-    consumer_state_mask = BufferHubDefs::FindNextAvailableClientStateMask(
+    consumer_state_mask = BufferHubDefs::findNextAvailableClientStateMask(
         current_active_clients_bit_mask | orphaned_consumer_bit_mask_);
     if (consumer_state_mask == 0U) {
       ALOGE("%s: reached the maximum mumber of consumers per producer: %d.",
@@ -337,13 +337,13 @@
   // consumer to a buffer that is available to producer (a.k.a a fully-released
   // buffer) or a gained buffer.
   if (current_buffer_state == 0U ||
-      BufferHubDefs::AnyClientGained(current_buffer_state)) {
+      BufferHubDefs::isAnyClientGained(current_buffer_state)) {
     return {status.take()};
   }
 
   // Signal the new consumer when adding it to a posted producer.
   bool update_buffer_state = true;
-  if (!BufferHubDefs::IsClientPosted(current_buffer_state,
+  if (!BufferHubDefs::isClientPosted(current_buffer_state,
                                      consumer_state_mask)) {
     uint32_t updated_buffer_state =
         current_buffer_state ^
@@ -360,7 +360,7 @@
           "released.",
           __FUNCTION__, current_buffer_state, updated_buffer_state);
       if (current_buffer_state == 0U ||
-          BufferHubDefs::AnyClientGained(current_buffer_state)) {
+          BufferHubDefs::isAnyClientGained(current_buffer_state)) {
         ALOGI("%s: buffer is gained or fully released, state=%" PRIx32 ".",
               __FUNCTION__, current_buffer_state);
         update_buffer_state = false;
@@ -371,7 +371,7 @@
           (consumer_state_mask & BufferHubDefs::kHighBitsMask);
     }
   }
-  if (update_buffer_state || BufferHubDefs::IsClientPosted(
+  if (update_buffer_state || BufferHubDefs::isClientPosted(
                                  buffer_state_->load(std::memory_order_acquire),
                                  consumer_state_mask)) {
     consumer->OnProducerPosted();
@@ -457,7 +457,7 @@
            buffer_id());
 
   uint32_t buffer_state = buffer_state_->load(std::memory_order_acquire);
-  if (!BufferHubDefs::IsClientGained(
+  if (!BufferHubDefs::isClientGained(
       buffer_state, BufferHubDefs::kFirstClientStateMask)) {
     // Can only detach a ProducerBuffer when it's in gained state.
     ALOGW(
@@ -616,9 +616,9 @@
 
   const uint32_t current_buffer_state =
       buffer_state_->load(std::memory_order_acquire);
-  if (BufferHubDefs::IsClientPosted(current_buffer_state,
+  if (BufferHubDefs::isClientPosted(current_buffer_state,
                                     consumer_state_mask) ||
-      BufferHubDefs::IsClientAcquired(current_buffer_state,
+      BufferHubDefs::isClientAcquired(current_buffer_state,
                                       consumer_state_mask)) {
     // The consumer client is being destoryed without releasing. This could
     // happen in corner cases when the consumer crashes. Here we mark it
@@ -627,9 +627,9 @@
     return;
   }
 
-  if (BufferHubDefs::IsClientReleased(current_buffer_state,
+  if (BufferHubDefs::isClientReleased(current_buffer_state,
                                       consumer_state_mask) ||
-      BufferHubDefs::AnyClientGained(current_buffer_state)) {
+      BufferHubDefs::isAnyClientGained(current_buffer_state)) {
     // The consumer is being close while it is suppose to signal a release
     // fence. Signal the dummy fence here.
     if (fence_state_->load(std::memory_order_acquire) & consumer_state_mask) {
diff --git a/services/vr/bufferhubd/producer_queue_channel.cpp b/services/vr/bufferhubd/producer_queue_channel.cpp
index 6b33f50..004dc7c 100644
--- a/services/vr/bufferhubd/producer_queue_channel.cpp
+++ b/services/vr/bufferhubd/producer_queue_channel.cpp
@@ -323,7 +323,7 @@
   // memory to indicate which client is the last producer of the buffer.
   // Currently, the first client is the only producer to the buffer.
   // Thus, it checks whether the first client gains the buffer below.
-  if (!BufferHubDefs::IsClientGained(buffer_state,
+  if (!BufferHubDefs::isClientGained(buffer_state,
                                      BufferHubDefs::kFirstClientBitMask)) {
     // Rejects the request if the requested buffer is not in Gained state.
     ALOGE(