Merge "Fix sanitizer in ISensorService list functions."
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 07a6adb..1b90579 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -152,6 +152,8 @@
     { "freq",       "CPU Frequency",    0, {
         { REQ,      "events/power/cpu_frequency/enable" },
         { OPT,      "events/power/clock_set_rate/enable" },
+        { OPT,      "events/power/clock_disable/enable" },
+        { OPT,      "events/power/clock_enable/enable" },
         { OPT,      "events/power/cpu_frequency_limits/enable" },
     } },
     { "membus",     "Memory Bus Utilization", 0, {
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 380921d..b94d3d5 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -690,6 +690,7 @@
     printf("Kernel: ");
     DumpFileToFd(STDOUT_FILENO, "", "/proc/version");
     printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
+    ds.RunCommand("UPTIME", {"uptime"}, CommandOptions::DEFAULT);
     printf("Bugreport format version: %s\n", version_.c_str());
     printf("Dumpstate info: id=%d pid=%d dry_run=%d args=%s extra_options=%s\n", id_, pid_,
            PropertiesHelper::IsDryRun(), args_.c_str(), extra_options_.c_str());
@@ -1092,6 +1093,7 @@
     DurationReporter duration_reporter("DUMPSTATE");
 
     dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version");
+    /* TODO: Remove duplicate uptime call when tools use it from header */
     RunCommand("UPTIME", {"uptime"});
     DumpBlockStatFiles();
     dump_emmc_ecsd("/d/mmc0/mmc0:0001/ext_csd");
diff --git a/cmds/flatland/Android.mk b/cmds/flatland/Android.mk
index c295167..7aa111c 100644
--- a/cmds/flatland/Android.mk
+++ b/cmds/flatland/Android.mk
@@ -8,6 +8,8 @@
     Renderers.cpp   \
     Main.cpp        \
 
+LOCAL_CFLAGS := -Wall -Werror
+
 LOCAL_MODULE:= flatland
 
 LOCAL_MODULE_TAGS := tests
diff --git a/cmds/flatland/Main.cpp b/cmds/flatland/Main.cpp
index ec1e543..3d7cac0 100644
--- a/cmds/flatland/Main.cpp
+++ b/cmds/flatland/Main.cpp
@@ -284,7 +284,6 @@
 public:
 
     Layer() :
-        mFirstFrame(true),
         mGLHelper(NULL),
         mSurface(EGL_NO_SURFACE) {
     }
@@ -358,8 +357,6 @@
     }
 
 private:
-    bool mFirstFrame;
-
     LayerDesc mDesc;
 
     GLHelper* mGLHelper;
@@ -389,7 +386,6 @@
         ATRACE_CALL();
 
         bool result;
-        EGLint resulte;
 
         float scaleFactor = float(mDesc.runHeights[mInstance]) /
             float(mDesc.height);
@@ -465,7 +461,6 @@
         ATRACE_CALL();
 
         bool result;
-        status_t err;
 
         resetColorGenerator();
 
diff --git a/cmds/ip-up-vpn/Android.mk b/cmds/ip-up-vpn/Android.mk
index 36bbdf5..e1e2204 100644
--- a/cmds/ip-up-vpn/Android.mk
+++ b/cmds/ip-up-vpn/Android.mk
@@ -18,6 +18,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := ip-up-vpn.c
+LOCAL_CFLAGS := -Wall -Werror
 LOCAL_SHARED_LIBRARIES := libcutils liblog
 LOCAL_MODULE := ip-up-vpn
 LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/ppp
diff --git a/cmds/rawbu/Android.mk b/cmds/rawbu/Android.mk
index b580390..9322151 100644
--- a/cmds/rawbu/Android.mk
+++ b/cmds/rawbu/Android.mk
@@ -5,6 +5,8 @@
 
 LOCAL_SRC_FILES:= backup.cpp
 
+LOCAL_CFLAGS := -Wall -Werror
+
 LOCAL_SHARED_LIBRARIES := libcutils libc
 
 LOCAL_MODULE:= rawbu
diff --git a/cmds/rawbu/backup.cpp b/cmds/rawbu/backup.cpp
index ff6719f..0072281 100644
--- a/cmds/rawbu/backup.cpp
+++ b/cmds/rawbu/backup.cpp
@@ -129,7 +129,6 @@
         }
 
         if(S_ISDIR(statBuffer.st_mode)) {
-            int i;
             char *newpath;
 
             newpath = strdup(nameBuffer);
diff --git a/cmds/surfacereplayer/proto/Android.bp b/cmds/surfacereplayer/proto/Android.bp
index dda80bb..71a5e23 100644
--- a/cmds/surfacereplayer/proto/Android.bp
+++ b/cmds/surfacereplayer/proto/Android.bp
@@ -3,6 +3,10 @@
     srcs: [
         "src/trace.proto",
     ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
     proto: {
         type: "lite",
         export_proto_headers: true,
diff --git a/libs/hwc2onfbadapter/Android.bp b/libs/hwc2onfbadapter/Android.bp
new file mode 100644
index 0000000..73a41f7
--- /dev/null
+++ b/libs/hwc2onfbadapter/Android.bp
@@ -0,0 +1,33 @@
+// Copyright 2010 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+    name: "libhwc2onfbadapter",
+    vendor: true,
+
+    clang: true,
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
+
+    srcs: [
+        "HWC2OnFbAdapter.cpp",
+    ],
+
+    header_libs: ["libhardware_headers"],
+    shared_libs: ["liblog", "libsync"],
+    export_include_dirs: ["include"],
+}
diff --git a/libs/hwc2onfbadapter/HWC2OnFbAdapter.cpp b/libs/hwc2onfbadapter/HWC2OnFbAdapter.cpp
new file mode 100644
index 0000000..7c9e651
--- /dev/null
+++ b/libs/hwc2onfbadapter/HWC2OnFbAdapter.cpp
@@ -0,0 +1,887 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "HWC2OnFbAdapter"
+
+//#define LOG_NDEBUG 0
+
+#include "hwc2onfbadapter/HWC2OnFbAdapter.h"
+
+#include <algorithm>
+#include <type_traits>
+
+#include <inttypes.h>
+#include <time.h>
+#include <sys/prctl.h>
+#include <unistd.h> // for close
+
+#include <hardware/fb.h>
+#include <log/log.h>
+#include <sync/sync.h>
+
+namespace android {
+
+namespace {
+
+void dumpHook(hwc2_device_t* device, uint32_t* outSize, char* outBuffer) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (outBuffer) {
+        *outSize = adapter.getDebugString().copy(outBuffer, *outSize);
+    } else {
+        adapter.updateDebugString();
+        *outSize = adapter.getDebugString().size();
+    }
+}
+
+int32_t registerCallbackHook(hwc2_device_t* device, int32_t descriptor,
+                             hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    switch (descriptor) {
+        case HWC2_CALLBACK_HOTPLUG:
+            if (pointer) {
+                reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer)(callbackData, adapter.getDisplayId(),
+                                                            HWC2_CONNECTION_CONNECTED);
+            }
+            break;
+        case HWC2_CALLBACK_REFRESH:
+            break;
+        case HWC2_CALLBACK_VSYNC:
+            adapter.setVsyncCallback(reinterpret_cast<HWC2_PFN_VSYNC>(pointer), callbackData);
+            break;
+        default:
+            return HWC2_ERROR_BAD_PARAMETER;
+    }
+
+    return HWC2_ERROR_NONE;
+}
+
+uint32_t getMaxVirtualDisplayCountHook(hwc2_device_t* /*device*/) {
+    return 0;
+}
+
+int32_t createVirtualDisplayHook(hwc2_device_t* /*device*/, uint32_t /*width*/, uint32_t /*height*/,
+                                 int32_t* /*format*/, hwc2_display_t* /*outDisplay*/) {
+    return HWC2_ERROR_NO_RESOURCES;
+}
+
+int32_t destroyVirtualDisplayHook(hwc2_device_t* /*device*/, hwc2_display_t /*display*/) {
+    return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t setOutputBufferHook(hwc2_device_t* /*device*/, hwc2_display_t /*display*/,
+                            buffer_handle_t /*buffer*/, int32_t /*releaseFence*/) {
+    return HWC2_ERROR_BAD_DISPLAY;
+}
+
+int32_t getDisplayNameHook(hwc2_device_t* device, hwc2_display_t display, uint32_t* outSize,
+                           char* outName) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    const auto& info = adapter.getInfo();
+    if (outName) {
+        *outSize = info.name.copy(outName, *outSize);
+    } else {
+        *outSize = info.name.size();
+    }
+
+    return HWC2_ERROR_NONE;
+}
+
+int32_t getDisplayTypeHook(hwc2_device_t* device, hwc2_display_t display, int32_t* outType) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    *outType = HWC2_DISPLAY_TYPE_PHYSICAL;
+    return HWC2_ERROR_NONE;
+}
+
+int32_t getDozeSupportHook(hwc2_device_t* device, hwc2_display_t display, int32_t* outSupport) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    *outSupport = 0;
+    return HWC2_ERROR_NONE;
+}
+
+int32_t getHdrCapabilitiesHook(hwc2_device_t* device, hwc2_display_t display, uint32_t* outNumTypes,
+                               int32_t* /*outTypes*/, float* /*outMaxLuminance*/,
+                               float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    *outNumTypes = 0;
+    return HWC2_ERROR_NONE;
+}
+
+int32_t setPowerModeHook(hwc2_device_t* device, hwc2_display_t display, int32_t /*mode*/) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    // pretend that it works
+    return HWC2_ERROR_NONE;
+}
+
+int32_t setVsyncEnabledHook(hwc2_device_t* device, hwc2_display_t display, int32_t enabled) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    adapter.enableVsync(enabled == HWC2_VSYNC_ENABLE);
+    return HWC2_ERROR_NONE;
+}
+
+int32_t getColorModesHook(hwc2_device_t* device, hwc2_display_t display, uint32_t* outNumModes,
+                          int32_t* outModes) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    if (outModes) {
+        if (*outNumModes > 0) {
+            outModes[0] = HAL_COLOR_MODE_NATIVE;
+            *outNumModes = 1;
+        }
+    } else {
+        *outNumModes = 1;
+    }
+
+    return HWC2_ERROR_NONE;
+}
+
+int32_t setColorModeHook(hwc2_device_t* device, hwc2_display_t display, int32_t mode) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+    if (mode != HAL_COLOR_MODE_NATIVE) {
+        return HWC2_ERROR_BAD_PARAMETER;
+    }
+
+    return HWC2_ERROR_NONE;
+}
+
+int32_t setColorTransformHook(hwc2_device_t* device, hwc2_display_t display,
+                              const float* /*matrix*/, int32_t /*hint*/) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    // we always force client composition
+    adapter.setState(HWC2OnFbAdapter::State::MODIFIED);
+    return HWC2_ERROR_NONE;
+}
+
+int32_t getClientTargetSupportHook(hwc2_device_t* device, hwc2_display_t display, uint32_t width,
+                                   uint32_t height, int32_t format, int32_t dataspace) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+    if (dataspace != HAL_DATASPACE_UNKNOWN) {
+        return HWC2_ERROR_UNSUPPORTED;
+    }
+
+    const auto& info = adapter.getInfo();
+    return (info.width == width && info.height == height && info.format == format)
+            ? HWC2_ERROR_NONE
+            : HWC2_ERROR_UNSUPPORTED;
+}
+
+int32_t setClientTargetHook(hwc2_device_t* device, hwc2_display_t display, buffer_handle_t target,
+                            int32_t acquireFence, int32_t dataspace, hwc_region_t /*damage*/) {
+    if (acquireFence >= 0) {
+        sync_wait(acquireFence, -1);
+        close(acquireFence);
+    }
+
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+    if (dataspace != HAL_DATASPACE_UNKNOWN) {
+        return HWC2_ERROR_BAD_PARAMETER;
+    }
+
+    // no state change
+    adapter.setBuffer(target);
+    return HWC2_ERROR_NONE;
+}
+
+int32_t getDisplayConfigsHook(hwc2_device_t* device, hwc2_display_t display,
+                              uint32_t* outNumConfigs, hwc2_config_t* outConfigs) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    if (outConfigs) {
+        if (*outNumConfigs > 0) {
+            outConfigs[0] = adapter.getConfigId();
+            *outNumConfigs = 1;
+        }
+    } else {
+        *outNumConfigs = 1;
+    }
+
+    return HWC2_ERROR_NONE;
+}
+
+int32_t getDisplayAttributeHook(hwc2_device_t* device, hwc2_display_t display, hwc2_config_t config,
+                                int32_t attribute, int32_t* outValue) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+    if (adapter.getConfigId() != config) {
+        return HWC2_ERROR_BAD_CONFIG;
+    }
+
+    const auto& info = adapter.getInfo();
+    switch (attribute) {
+        case HWC2_ATTRIBUTE_WIDTH:
+            *outValue = int32_t(info.width);
+            break;
+        case HWC2_ATTRIBUTE_HEIGHT:
+            *outValue = int32_t(info.height);
+            break;
+        case HWC2_ATTRIBUTE_VSYNC_PERIOD:
+            *outValue = int32_t(info.vsync_period_ns);
+            break;
+        case HWC2_ATTRIBUTE_DPI_X:
+            *outValue = int32_t(info.xdpi_scaled);
+            break;
+        case HWC2_ATTRIBUTE_DPI_Y:
+            *outValue = int32_t(info.ydpi_scaled);
+            break;
+        default:
+            return HWC2_ERROR_BAD_PARAMETER;
+    }
+
+    return HWC2_ERROR_NONE;
+}
+
+int32_t getActiveConfigHook(hwc2_device_t* device, hwc2_display_t display,
+                            hwc2_config_t* outConfig) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    *outConfig = adapter.getConfigId();
+    return HWC2_ERROR_NONE;
+}
+
+int32_t setActiveConfigHook(hwc2_device_t* device, hwc2_display_t display, hwc2_config_t config) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+    if (adapter.getConfigId() != config) {
+        return HWC2_ERROR_BAD_CONFIG;
+    }
+
+    return HWC2_ERROR_NONE;
+}
+
+int32_t validateDisplayHook(hwc2_device_t* device, hwc2_display_t display, uint32_t* outNumTypes,
+                            uint32_t* outNumRequests) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    const auto& dirtyLayers = adapter.getDirtyLayers();
+    *outNumTypes = dirtyLayers.size();
+    *outNumRequests = 0;
+
+    if (*outNumTypes > 0) {
+        adapter.setState(HWC2OnFbAdapter::State::VALIDATED_WITH_CHANGES);
+        return HWC2_ERROR_HAS_CHANGES;
+    } else {
+        adapter.setState(HWC2OnFbAdapter::State::VALIDATED);
+        return HWC2_ERROR_NONE;
+    }
+}
+
+int32_t getChangedCompositionTypesHook(hwc2_device_t* device, hwc2_display_t display,
+                                       uint32_t* outNumElements, hwc2_layer_t* outLayers,
+                                       int32_t* outTypes) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+    if (adapter.getState() == HWC2OnFbAdapter::State::MODIFIED) {
+        return HWC2_ERROR_NOT_VALIDATED;
+    }
+
+    // request client composition for all layers
+    const auto& dirtyLayers = adapter.getDirtyLayers();
+    if (outLayers && outTypes) {
+        *outNumElements = std::min(*outNumElements, uint32_t(dirtyLayers.size()));
+        auto iter = dirtyLayers.cbegin();
+        for (uint32_t i = 0; i < *outNumElements; i++) {
+            outLayers[i] = *iter++;
+            outTypes[i] = HWC2_COMPOSITION_CLIENT;
+        }
+    } else {
+        *outNumElements = dirtyLayers.size();
+    }
+
+    return HWC2_ERROR_NONE;
+}
+
+int32_t getDisplayRequestsHook(hwc2_device_t* device, hwc2_display_t display,
+                               int32_t* outDisplayRequests, uint32_t* outNumElements,
+                               hwc2_layer_t* /*outLayers*/, int32_t* /*outLayerRequests*/) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+    if (adapter.getState() == HWC2OnFbAdapter::State::MODIFIED) {
+        return HWC2_ERROR_NOT_VALIDATED;
+    }
+
+    *outDisplayRequests = 0;
+    *outNumElements = 0;
+    return HWC2_ERROR_NONE;
+}
+
+int32_t acceptDisplayChangesHook(hwc2_device_t* device, hwc2_display_t display) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+    if (adapter.getState() == HWC2OnFbAdapter::State::MODIFIED) {
+        return HWC2_ERROR_NOT_VALIDATED;
+    }
+
+    adapter.clearDirtyLayers();
+    adapter.setState(HWC2OnFbAdapter::State::VALIDATED);
+    return HWC2_ERROR_NONE;
+}
+
+int32_t presentDisplayHook(hwc2_device_t* device, hwc2_display_t display,
+                           int32_t* outPresentFence) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+    if (adapter.getState() != HWC2OnFbAdapter::State::VALIDATED) {
+        return HWC2_ERROR_NOT_VALIDATED;
+    }
+
+    adapter.postBuffer();
+    *outPresentFence = -1;
+
+    return HWC2_ERROR_NONE;
+}
+
+int32_t getReleaseFencesHook(hwc2_device_t* device, hwc2_display_t display,
+                             uint32_t* outNumElements, hwc2_layer_t* /*outLayers*/,
+                             int32_t* /*outFences*/) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    *outNumElements = 0;
+    return HWC2_ERROR_NONE;
+}
+
+int32_t createLayerHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t* outLayer) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    *outLayer = adapter.addLayer();
+    adapter.setState(HWC2OnFbAdapter::State::MODIFIED);
+    return HWC2_ERROR_NONE;
+}
+
+int32_t destroyLayerHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    if (adapter.removeLayer(layer)) {
+        adapter.setState(HWC2OnFbAdapter::State::MODIFIED);
+        return HWC2_ERROR_NONE;
+    } else {
+        return HWC2_ERROR_BAD_LAYER;
+    }
+}
+
+int32_t setCursorPositionHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t /*layer*/,
+                              int32_t /*x*/, int32_t /*y*/) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    // always an error
+    return HWC2_ERROR_BAD_LAYER;
+}
+
+int32_t setLayerBufferHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer,
+                           buffer_handle_t /*buffer*/, int32_t acquireFence) {
+    if (acquireFence >= 0) {
+        sync_wait(acquireFence, -1);
+        close(acquireFence);
+    }
+
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+    if (!adapter.hasLayer(layer)) {
+        return HWC2_ERROR_BAD_LAYER;
+    }
+
+    // no state change
+    return HWC2_ERROR_NONE;
+}
+
+int32_t setLayerSurfaceDamageHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer,
+                                  hwc_region_t /*damage*/) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+    if (!adapter.hasLayer(layer)) {
+        return HWC2_ERROR_BAD_LAYER;
+    }
+
+    // no state change
+    return HWC2_ERROR_NONE;
+}
+
+int32_t setLayerCompositionTypeHook(hwc2_device_t* device, hwc2_display_t display,
+                                    hwc2_layer_t layer, int32_t type) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+    if (!adapter.markLayerDirty(layer, type != HWC2_COMPOSITION_CLIENT)) {
+        return HWC2_ERROR_BAD_LAYER;
+    }
+
+    adapter.setState(HWC2OnFbAdapter::State::MODIFIED);
+    return HWC2_ERROR_NONE;
+}
+
+template <typename... Args>
+int32_t setLayerStateHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer,
+                          Args... /*args*/) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    if (adapter.getDisplayId() != display) {
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+    if (!adapter.hasLayer(layer)) {
+        return HWC2_ERROR_BAD_LAYER;
+    }
+
+    adapter.setState(HWC2OnFbAdapter::State::MODIFIED);
+    return HWC2_ERROR_NONE;
+}
+
+template <typename PFN, typename T>
+static hwc2_function_pointer_t asFP(T function) {
+    static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
+    return reinterpret_cast<hwc2_function_pointer_t>(function);
+}
+
+hwc2_function_pointer_t getFunctionHook(hwc2_device_t* /*device*/, int32_t descriptor) {
+    switch (descriptor) {
+        // global functions
+        case HWC2_FUNCTION_DUMP:
+            return asFP<HWC2_PFN_DUMP>(dumpHook);
+        case HWC2_FUNCTION_REGISTER_CALLBACK:
+            return asFP<HWC2_PFN_REGISTER_CALLBACK>(registerCallbackHook);
+
+        // virtual display functions
+        case HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT:
+            return asFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(getMaxVirtualDisplayCountHook);
+        case HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY:
+            return asFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(createVirtualDisplayHook);
+        case HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY:
+            return asFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(destroyVirtualDisplayHook);
+        case HWC2_FUNCTION_SET_OUTPUT_BUFFER:
+            return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>(setOutputBufferHook);
+
+        // display functions
+        case HWC2_FUNCTION_GET_DISPLAY_NAME:
+            return asFP<HWC2_PFN_GET_DISPLAY_NAME>(getDisplayNameHook);
+        case HWC2_FUNCTION_GET_DISPLAY_TYPE:
+            return asFP<HWC2_PFN_GET_DISPLAY_TYPE>(getDisplayTypeHook);
+        case HWC2_FUNCTION_GET_DOZE_SUPPORT:
+            return asFP<HWC2_PFN_GET_DOZE_SUPPORT>(getDozeSupportHook);
+        case HWC2_FUNCTION_GET_HDR_CAPABILITIES:
+            return asFP<HWC2_PFN_GET_HDR_CAPABILITIES>(getHdrCapabilitiesHook);
+        case HWC2_FUNCTION_SET_POWER_MODE:
+            return asFP<HWC2_PFN_SET_POWER_MODE>(setPowerModeHook);
+        case HWC2_FUNCTION_SET_VSYNC_ENABLED:
+            return asFP<HWC2_PFN_SET_VSYNC_ENABLED>(setVsyncEnabledHook);
+        case HWC2_FUNCTION_GET_COLOR_MODES:
+            return asFP<HWC2_PFN_GET_COLOR_MODES>(getColorModesHook);
+        case HWC2_FUNCTION_SET_COLOR_MODE:
+            return asFP<HWC2_PFN_SET_COLOR_MODE>(setColorModeHook);
+        case HWC2_FUNCTION_SET_COLOR_TRANSFORM:
+            return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(setColorTransformHook);
+        case HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT:
+            return asFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(getClientTargetSupportHook);
+        case HWC2_FUNCTION_SET_CLIENT_TARGET:
+            return asFP<HWC2_PFN_SET_CLIENT_TARGET>(setClientTargetHook);
+
+        // config functions
+        case HWC2_FUNCTION_GET_DISPLAY_CONFIGS:
+            return asFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(getDisplayConfigsHook);
+        case HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE:
+            return asFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(getDisplayAttributeHook);
+        case HWC2_FUNCTION_GET_ACTIVE_CONFIG:
+            return asFP<HWC2_PFN_GET_ACTIVE_CONFIG>(getActiveConfigHook);
+        case HWC2_FUNCTION_SET_ACTIVE_CONFIG:
+            return asFP<HWC2_PFN_SET_ACTIVE_CONFIG>(setActiveConfigHook);
+
+        // validate/present functions
+        case HWC2_FUNCTION_VALIDATE_DISPLAY:
+            return asFP<HWC2_PFN_VALIDATE_DISPLAY>(validateDisplayHook);
+        case HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES:
+            return asFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(getChangedCompositionTypesHook);
+        case HWC2_FUNCTION_GET_DISPLAY_REQUESTS:
+            return asFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(getDisplayRequestsHook);
+        case HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES:
+            return asFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(acceptDisplayChangesHook);
+        case HWC2_FUNCTION_PRESENT_DISPLAY:
+            return asFP<HWC2_PFN_PRESENT_DISPLAY>(presentDisplayHook);
+        case HWC2_FUNCTION_GET_RELEASE_FENCES:
+            return asFP<HWC2_PFN_GET_RELEASE_FENCES>(getReleaseFencesHook);
+
+        // layer create/destroy
+        case HWC2_FUNCTION_CREATE_LAYER:
+            return asFP<HWC2_PFN_CREATE_LAYER>(createLayerHook);
+        case HWC2_FUNCTION_DESTROY_LAYER:
+            return asFP<HWC2_PFN_DESTROY_LAYER>(destroyLayerHook);
+
+        // layer functions; validateDisplay not required
+        case HWC2_FUNCTION_SET_CURSOR_POSITION:
+            return asFP<HWC2_PFN_SET_CURSOR_POSITION>(setCursorPositionHook);
+        case HWC2_FUNCTION_SET_LAYER_BUFFER:
+            return asFP<HWC2_PFN_SET_LAYER_BUFFER>(setLayerBufferHook);
+        case HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE:
+            return asFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(setLayerSurfaceDamageHook);
+
+        // layer state functions; validateDisplay required
+        case HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE:
+            return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(setLayerCompositionTypeHook);
+        case HWC2_FUNCTION_SET_LAYER_BLEND_MODE:
+            return asFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(setLayerStateHook<int32_t>);
+        case HWC2_FUNCTION_SET_LAYER_COLOR:
+            return asFP<HWC2_PFN_SET_LAYER_COLOR>(setLayerStateHook<hwc_color_t>);
+        case HWC2_FUNCTION_SET_LAYER_DATASPACE:
+            return asFP<HWC2_PFN_SET_LAYER_DATASPACE>(setLayerStateHook<int32_t>);
+        case HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME:
+            return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(setLayerStateHook<hwc_rect_t>);
+        case HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA:
+            return asFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(setLayerStateHook<float>);
+        case HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM:
+            return asFP<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(setLayerStateHook<buffer_handle_t>);
+        case HWC2_FUNCTION_SET_LAYER_SOURCE_CROP:
+            return asFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(setLayerStateHook<hwc_frect_t>);
+        case HWC2_FUNCTION_SET_LAYER_TRANSFORM:
+            return asFP<HWC2_PFN_SET_LAYER_TRANSFORM>(setLayerStateHook<int32_t>);
+        case HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION:
+            return asFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(setLayerStateHook<hwc_region_t>);
+        case HWC2_FUNCTION_SET_LAYER_Z_ORDER:
+            return asFP<HWC2_PFN_SET_LAYER_Z_ORDER>(setLayerStateHook<uint32_t>);
+
+        default:
+            ALOGE("unknown function descriptor %d", descriptor);
+            return nullptr;
+    }
+}
+
+void getCapabilitiesHook(hwc2_device_t* /*device*/, uint32_t* outCount,
+                         int32_t* /*outCapabilities*/) {
+    *outCount = 0;
+}
+
+int closeHook(hw_device_t* device) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    adapter.close();
+    return 0;
+}
+
+} // anonymous namespace
+
+HWC2OnFbAdapter::HWC2OnFbAdapter(framebuffer_device_t* fbDevice)
+      : hwc2_device_t(), mFbDevice(fbDevice) {
+    common.close = closeHook;
+    hwc2_device::getCapabilities = getCapabilitiesHook;
+    hwc2_device::getFunction = getFunctionHook;
+
+    mFbInfo.name = "fbdev";
+    mFbInfo.width = mFbDevice->width;
+    mFbInfo.height = mFbDevice->height;
+    mFbInfo.format = mFbDevice->format;
+    mFbInfo.vsync_period_ns = int(1e9 / mFbDevice->fps);
+    mFbInfo.xdpi_scaled = int(mFbDevice->xdpi * 1000.0f);
+    mFbInfo.ydpi_scaled = int(mFbDevice->ydpi * 1000.0f);
+
+    mVsyncThread.start(0, mFbInfo.vsync_period_ns);
+}
+
+HWC2OnFbAdapter& HWC2OnFbAdapter::cast(hw_device_t* device) {
+    return *reinterpret_cast<HWC2OnFbAdapter*>(device);
+}
+
+HWC2OnFbAdapter& HWC2OnFbAdapter::cast(hwc2_device_t* device) {
+    return *reinterpret_cast<HWC2OnFbAdapter*>(device);
+}
+
+hwc2_display_t HWC2OnFbAdapter::getDisplayId() {
+    return 0;
+}
+
+hwc2_config_t HWC2OnFbAdapter::getConfigId() {
+    return 0;
+}
+
+void HWC2OnFbAdapter::close() {
+    mVsyncThread.stop();
+    framebuffer_close(mFbDevice);
+}
+
+const HWC2OnFbAdapter::Info& HWC2OnFbAdapter::getInfo() const {
+    return mFbInfo;
+}
+
+void HWC2OnFbAdapter::updateDebugString() {
+    if (mFbDevice->common.version >= 1 && mFbDevice->dump) {
+        char buffer[4096];
+        mFbDevice->dump(mFbDevice, buffer, sizeof(buffer));
+        buffer[sizeof(buffer) - 1] = '\0';
+
+        mDebugString = buffer;
+    }
+}
+
+const std::string& HWC2OnFbAdapter::getDebugString() const {
+    return mDebugString;
+}
+
+void HWC2OnFbAdapter::setState(State state) {
+    mState = state;
+}
+
+HWC2OnFbAdapter::State HWC2OnFbAdapter::getState() const {
+    return mState;
+}
+
+hwc2_layer_t HWC2OnFbAdapter::addLayer() {
+    hwc2_layer_t id = ++mNextLayerId;
+
+    mLayers.insert(id);
+    mDirtyLayers.insert(id);
+
+    return id;
+}
+
+bool HWC2OnFbAdapter::removeLayer(hwc2_layer_t layer) {
+    mDirtyLayers.erase(layer);
+    return mLayers.erase(layer);
+}
+
+bool HWC2OnFbAdapter::hasLayer(hwc2_layer_t layer) const {
+    return mLayers.count(layer) > 0;
+}
+
+bool HWC2OnFbAdapter::markLayerDirty(hwc2_layer_t layer, bool dirty) {
+    if (mLayers.count(layer) == 0) {
+        return false;
+    }
+
+    if (dirty) {
+        mDirtyLayers.insert(layer);
+    } else {
+        mDirtyLayers.erase(layer);
+    }
+
+    return true;
+}
+
+const std::unordered_set<hwc2_layer_t>& HWC2OnFbAdapter::getDirtyLayers() const {
+    return mDirtyLayers;
+}
+
+void HWC2OnFbAdapter::clearDirtyLayers() {
+    mDirtyLayers.clear();
+}
+
+/*
+ * For each frame, SurfaceFlinger
+ *
+ *  - peforms GLES composition
+ *  - calls eglSwapBuffers
+ *  - calls setClientTarget, which maps to setBuffer below
+ *  - calls presentDisplay, which maps to postBuffer below
+ *
+ * setBuffer should be a good place to call compositionComplete.
+ *
+ * As for post, it
+ *
+ *  - schedules the buffer for presentation on the next vsync
+ *  - locks the buffer and blocks all other users trying to lock it
+ *
+ * It does not give us a way to return a present fence, and we need to live
+ * with that.  The implication is that, when we are double-buffered,
+ * SurfaceFlinger assumes the front buffer is available for rendering again
+ * immediately after the back buffer is posted.  The locking semantics
+ * hopefully are strong enough that the rendering will be blocked.
+ */
+void HWC2OnFbAdapter::setBuffer(buffer_handle_t buffer) {
+    if (mFbDevice->compositionComplete) {
+        mFbDevice->compositionComplete(mFbDevice);
+    }
+    mBuffer = buffer;
+}
+
+bool HWC2OnFbAdapter::postBuffer() {
+    int error = 0;
+    if (mBuffer) {
+        error = mFbDevice->post(mFbDevice, mBuffer);
+    }
+
+    return error == 0;
+}
+
+void HWC2OnFbAdapter::setVsyncCallback(HWC2_PFN_VSYNC callback, hwc2_callback_data_t data) {
+    mVsyncThread.setCallback(callback, data);
+}
+
+void HWC2OnFbAdapter::enableVsync(bool enable) {
+    mVsyncThread.enableCallback(enable);
+}
+
+int64_t HWC2OnFbAdapter::VsyncThread::now() {
+    struct timespec ts;
+    clock_gettime(CLOCK_MONOTONIC, &ts);
+
+    return int64_t(ts.tv_sec) * 1'000'000'000 + ts.tv_nsec;
+}
+
+bool HWC2OnFbAdapter::VsyncThread::sleepUntil(int64_t t) {
+    struct timespec ts;
+    ts.tv_sec = t / 1'000'000'000;
+    ts.tv_nsec = t % 1'000'000'000;
+
+    while (true) {
+        int error = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, nullptr);
+        if (error) {
+            if (error == EINTR) {
+                continue;
+            }
+            return false;
+        } else {
+            return true;
+        }
+    }
+}
+
+void HWC2OnFbAdapter::VsyncThread::start(int64_t firstVsync, int64_t period) {
+    mNextVsync = firstVsync;
+    mPeriod = period;
+    mStarted = true;
+    mThread = std::thread(&VsyncThread::vsyncLoop, this);
+}
+
+void HWC2OnFbAdapter::VsyncThread::stop() {
+    {
+        std::lock_guard<std::mutex> lock(mMutex);
+        mStarted = false;
+    }
+    mCondition.notify_all();
+    mThread.join();
+}
+
+void HWC2OnFbAdapter::VsyncThread::setCallback(HWC2_PFN_VSYNC callback, hwc2_callback_data_t data) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    mCallback = callback;
+    mCallbackData = data;
+}
+
+void HWC2OnFbAdapter::VsyncThread::enableCallback(bool enable) {
+    {
+        std::lock_guard<std::mutex> lock(mMutex);
+        mCallbackEnabled = enable;
+    }
+    mCondition.notify_all();
+}
+
+void HWC2OnFbAdapter::VsyncThread::vsyncLoop() {
+    prctl(PR_SET_NAME, "VsyncThread", 0, 0, 0);
+
+    std::unique_lock<std::mutex> lock(mMutex);
+    if (!mStarted) {
+        return;
+    }
+
+    while (true) {
+        if (!mCallbackEnabled) {
+            mCondition.wait(lock, [this] { return mCallbackEnabled || !mStarted; });
+            if (!mStarted) {
+                break;
+            }
+        }
+
+        lock.unlock();
+
+        // adjust mNextVsync if necessary
+        int64_t t = now();
+        if (mNextVsync < t) {
+            int64_t n = (t - mNextVsync + mPeriod - 1) / mPeriod;
+            mNextVsync += mPeriod * n;
+        }
+        bool fire = sleepUntil(mNextVsync);
+
+        lock.lock();
+
+        if (fire) {
+            ALOGV("VsyncThread(%" PRId64 ")", mNextVsync);
+            if (mCallback) {
+                mCallback(mCallbackData, getDisplayId(), mNextVsync);
+            }
+            mNextVsync += mPeriod;
+        }
+    }
+}
+
+} // namespace android
diff --git a/libs/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h b/libs/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h
new file mode 100644
index 0000000..d6272fd
--- /dev/null
+++ b/libs/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SF_HWC2_ON_FB_ADAPTER_H
+#define ANDROID_SF_HWC2_ON_FB_ADAPTER_H
+
+#include <condition_variable>
+#include <mutex>
+#include <string>
+#include <thread>
+#include <unordered_set>
+
+#include <hardware/hwcomposer2.h>
+
+struct framebuffer_device_t;
+
+namespace android {
+
+class HWC2OnFbAdapter : public hwc2_device_t {
+public:
+    HWC2OnFbAdapter(framebuffer_device_t* fbDevice);
+
+    static HWC2OnFbAdapter& cast(hw_device_t* device);
+    static HWC2OnFbAdapter& cast(hwc2_device_t* device);
+
+    static hwc2_display_t getDisplayId();
+    static hwc2_config_t getConfigId();
+
+    void close();
+
+    struct Info {
+        std::string name;
+        uint32_t width;
+        uint32_t height;
+        int format;
+        int vsync_period_ns;
+        int xdpi_scaled;
+        int ydpi_scaled;
+    };
+    const Info& getInfo() const;
+
+    void updateDebugString();
+    const std::string& getDebugString() const;
+
+    enum class State {
+        MODIFIED,
+        VALIDATED_WITH_CHANGES,
+        VALIDATED,
+    };
+    void setState(State state);
+    State getState() const;
+
+    hwc2_layer_t addLayer();
+    bool removeLayer(hwc2_layer_t layer);
+    bool hasLayer(hwc2_layer_t layer) const;
+    bool markLayerDirty(hwc2_layer_t layer, bool dirty);
+    const std::unordered_set<hwc2_layer_t>& getDirtyLayers() const;
+    void clearDirtyLayers();
+
+    void setBuffer(buffer_handle_t buffer);
+    bool postBuffer();
+
+    void setVsyncCallback(HWC2_PFN_VSYNC callback, hwc2_callback_data_t data);
+    void enableVsync(bool enable);
+
+private:
+    framebuffer_device_t* mFbDevice{nullptr};
+    Info mFbInfo{};
+
+    std::string mDebugString;
+
+    State mState{State::MODIFIED};
+
+    uint64_t mNextLayerId{0};
+    std::unordered_set<hwc2_layer_t> mLayers;
+    std::unordered_set<hwc2_layer_t> mDirtyLayers;
+
+    buffer_handle_t mBuffer{nullptr};
+
+    class VsyncThread {
+    public:
+        static int64_t now();
+        static bool sleepUntil(int64_t t);
+
+        void start(int64_t first, int64_t period);
+        void stop();
+        void setCallback(HWC2_PFN_VSYNC callback, hwc2_callback_data_t data);
+        void enableCallback(bool enable);
+
+    private:
+        void vsyncLoop();
+        bool waitUntilNextVsync();
+
+        std::thread mThread;
+        int64_t mNextVsync{0};
+        int64_t mPeriod{0};
+
+        std::mutex mMutex;
+        std::condition_variable mCondition;
+        bool mStarted{false};
+        HWC2_PFN_VSYNC mCallback{nullptr};
+        hwc2_callback_data_t mCallbackData{nullptr};
+        bool mCallbackEnabled{false};
+    };
+    VsyncThread mVsyncThread;
+};
+
+} // namespace android
+
+#endif // ANDROID_SF_HWC2_ON_FB_ADAPTER_H
diff --git a/libs/input/VelocityTracker.cpp b/libs/input/VelocityTracker.cpp
index 57eee12..e54f147 100644
--- a/libs/input/VelocityTracker.cpp
+++ b/libs/input/VelocityTracker.cpp
@@ -107,7 +107,7 @@
 // this is the strategy that applications will actually use.  Be very careful
 // when adjusting the default strategy because it can dramatically affect
 // (often in a bad way) the user experience.
-const char* VelocityTracker::DEFAULT_STRATEGY = "impulse";
+const char* VelocityTracker::DEFAULT_STRATEGY = "lsq2";
 
 VelocityTracker::VelocityTracker(const char* strategy) :
         mLastEventTime(0), mCurrentPointerIdBits(0), mActivePointerId(-1) {
diff --git a/libs/vr/libbufferhub/buffer_hub-test.cpp b/libs/vr/libbufferhub/buffer_hub-test.cpp
index 3c99f99..a5cf9ae 100644
--- a/libs/vr/libbufferhub/buffer_hub-test.cpp
+++ b/libs/vr/libbufferhub/buffer_hub-test.cpp
@@ -33,6 +33,7 @@
 const int kUsage = 0;
 const uint64_t kContext = 42;
 const size_t kMaxConsumerCount = 63;
+const int kPollTimeoutMs = 100;
 
 using LibBufferHubTest = ::testing::Test;
 
@@ -51,51 +52,51 @@
   // Producer state mask is unique, i.e. 1.
   EXPECT_EQ(p->buffer_state_bit(), kProducerStateBit);
   // Consumer state mask cannot have producer bit on.
-  EXPECT_EQ(c->buffer_state_bit() & kProducerStateBit, 0);
+  EXPECT_EQ(c->buffer_state_bit() & kProducerStateBit, 0U);
   // Consumer state mask must be a single, i.e. power of 2.
-  EXPECT_NE(c->buffer_state_bit(), 0);
-  EXPECT_EQ(c->buffer_state_bit() & (c->buffer_state_bit() - 1), 0);
+  EXPECT_NE(c->buffer_state_bit(), 0U);
+  EXPECT_EQ(c->buffer_state_bit() & (c->buffer_state_bit() - 1), 0U);
   // Consumer state mask cannot have producer bit on.
-  EXPECT_EQ(c2->buffer_state_bit() & kProducerStateBit, 0);
+  EXPECT_EQ(c2->buffer_state_bit() & kProducerStateBit, 0U);
   // Consumer state mask must be a single, i.e. power of 2.
-  EXPECT_NE(c2->buffer_state_bit(), 0);
-  EXPECT_EQ(c2->buffer_state_bit() & (c2->buffer_state_bit() - 1), 0);
+  EXPECT_NE(c2->buffer_state_bit(), 0U);
+  EXPECT_EQ(c2->buffer_state_bit() & (c2->buffer_state_bit() - 1), 0U);
   // Each consumer should have unique bit.
-  EXPECT_EQ(c->buffer_state_bit() & c2->buffer_state_bit(), 0);
+  EXPECT_EQ(c->buffer_state_bit() & c2->buffer_state_bit(), 0U);
 
   // Initial state: producer not available, consumers not available.
-  EXPECT_EQ(0, RETRY_EINTR(p->Poll(100)));
-  EXPECT_EQ(0, RETRY_EINTR(c->Poll(100)));
-  EXPECT_EQ(0, RETRY_EINTR(c2->Poll(100)));
+  EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
+  EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
+  EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
 
   EXPECT_EQ(0, p->Post(LocalHandle(), kContext));
 
   // New state: producer not available, consumers available.
-  EXPECT_EQ(0, RETRY_EINTR(p->Poll(100)));
-  EXPECT_EQ(1, RETRY_EINTR(c->Poll(100)));
-  EXPECT_EQ(1, RETRY_EINTR(c2->Poll(100)));
+  EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
+  EXPECT_EQ(1, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
+  EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
 
   uint64_t context;
   LocalHandle fence;
   EXPECT_EQ(0, c->Acquire(&fence, &context));
   EXPECT_EQ(kContext, context);
-  EXPECT_EQ(0, RETRY_EINTR(c->Poll(100)));
-  EXPECT_EQ(1, RETRY_EINTR(c2->Poll(100)));
+  EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
+  EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
 
   EXPECT_EQ(0, c2->Acquire(&fence, &context));
   EXPECT_EQ(kContext, context);
-  EXPECT_EQ(0, RETRY_EINTR(c2->Poll(100)));
-  EXPECT_EQ(0, RETRY_EINTR(c->Poll(100)));
+  EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
+  EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
 
   EXPECT_EQ(0, c->Release(LocalHandle()));
-  EXPECT_EQ(0, RETRY_EINTR(p->Poll(100)));
+  EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
   EXPECT_EQ(0, c2->Discard());
 
-  EXPECT_EQ(1, RETRY_EINTR(p->Poll(100)));
+  EXPECT_EQ(1, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
   EXPECT_EQ(0, p->Gain(&fence));
-  EXPECT_EQ(0, RETRY_EINTR(p->Poll(100)));
-  EXPECT_EQ(0, RETRY_EINTR(c->Poll(100)));
-  EXPECT_EQ(0, RETRY_EINTR(c2->Poll(100)));
+  EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
+  EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
+  EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
 }
 
 TEST_F(LibBufferHubTest, TestEpoll) {
@@ -137,7 +138,8 @@
 
   // Post the producer and check for consumer signal.
   EXPECT_EQ(0, p->Post({}, kContext));
-  ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
+  ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
+                          kPollTimeoutMs));
   ASSERT_TRUE(events[0].events & EPOLLIN);
   ASSERT_EQ(c->event_fd(), events[0].data.fd);
 
@@ -145,10 +147,14 @@
   event = events[0];
 
   // Check for events again. Edge-triggered mode should prevent any.
-  EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
-  EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
-  EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
-  EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
+  EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
+                          kPollTimeoutMs));
+  EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
+                          kPollTimeoutMs));
+  EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
+                          kPollTimeoutMs));
+  EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
+                          kPollTimeoutMs));
 
   // Translate the events.
   auto event_status = c->GetEventMask(event.events);
@@ -156,7 +162,8 @@
   ASSERT_TRUE(event_status.get() & EPOLLIN);
 
   // Check for events again. Edge-triggered mode should prevent any.
-  EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
+  EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
+                          kPollTimeoutMs));
 }
 
 TEST_F(LibBufferHubTest, TestStateMask) {
@@ -171,7 +178,7 @@
     cs[i] = BufferConsumer::Import(p->CreateConsumer());
     ASSERT_TRUE(cs[i].get() != nullptr);
     // Expect all buffers have unique state mask.
-    EXPECT_EQ(buffer_state_bits & cs[i]->buffer_state_bit(), 0);
+    EXPECT_EQ(buffer_state_bits & cs[i]->buffer_state_bit(), 0U);
     buffer_state_bits |= cs[i]->buffer_state_bit();
   }
   EXPECT_EQ(buffer_state_bits, kProducerStateBit | kConsumerStateMask);
@@ -187,7 +194,7 @@
     cs[i] = BufferConsumer::Import(p->CreateConsumer());
     ASSERT_TRUE(cs[i].get() != nullptr);
     // The released state mask will be reused.
-    EXPECT_EQ(buffer_state_bits & cs[i]->buffer_state_bit(), 0);
+    EXPECT_EQ(buffer_state_bits & cs[i]->buffer_state_bit(), 0U);
     buffer_state_bits |= cs[i]->buffer_state_bit();
     EXPECT_EQ(buffer_state_bits, kProducerStateBit | kConsumerStateMask);
   }
@@ -229,7 +236,7 @@
 
   // Release in acquired state should succeed.
   EXPECT_EQ(0, c->Release(LocalHandle()));
-  EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
+  EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
 
   // Release, acquire, and post in released state should fail.
   EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
@@ -277,7 +284,7 @@
   EXPECT_FALSE(invalid_fence.IsValid());
 
   // Acquire in posted state should succeed.
-  EXPECT_LT(0, RETRY_EINTR(c->Poll(10)));
+  EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
   EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
   EXPECT_FALSE(invalid_fence.IsValid());
   EXPECT_EQ(p->buffer_state(), c->buffer_state());
@@ -292,7 +299,7 @@
 
   // Release in acquired state should succeed.
   EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
-  EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
+  EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
   EXPECT_EQ(p->buffer_state(), c->buffer_state());
   EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
 
@@ -330,7 +337,7 @@
   EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
 
   // The buffer should stay in posted stay until a consumer picks it up.
-  EXPECT_GE(0, RETRY_EINTR(p->Poll(100)));
+  EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
 
   // A new consumer should still be able to acquire the buffer immediately.
   std::unique_ptr<BufferConsumer> c =
@@ -361,7 +368,7 @@
   for (size_t i = 0; i < kMaxConsumerCount; i++) {
     EXPECT_TRUE(IsBufferPosted(cs[i]->buffer_state(),
                                cs[i]->buffer_state_bit()));
-    EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(10)));
+    EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(kPollTimeoutMs)));
     EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
     EXPECT_TRUE(IsBufferAcquired(p->buffer_state()));
   }
@@ -373,7 +380,7 @@
     EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
   }
 
-  EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
+  EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
   EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
 
   // Buffer state cross all clients must be consistent.
@@ -399,7 +406,7 @@
   // Post the gained buffer should signal already created consumer.
   EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
   EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
-  EXPECT_LT(0, RETRY_EINTR(c->Poll(10)));
+  EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
   EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
   EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
 }
@@ -440,7 +447,7 @@
 
   // Post, acquire, and release the buffer..
   EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
-  EXPECT_LT(0, RETRY_EINTR(c1->Poll(10)));
+  EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
   EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
   EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
 
@@ -450,7 +457,7 @@
       BufferConsumer::Import(p->CreateConsumer());
   ASSERT_TRUE(c2.get() != nullptr);
 
-  EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
+  EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
   EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
   EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
   EXPECT_TRUE(IsBufferGained(p->buffer_state()));
@@ -470,7 +477,7 @@
 
   Metadata m = {1, 3};
   EXPECT_EQ(0, p->Post(LocalHandle(), m));
-  EXPECT_LE(0, RETRY_EINTR(c->Poll(10)));
+  EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
 
   LocalHandle fence;
   Metadata m2 = {};
@@ -503,7 +510,7 @@
   // buffer allocation.
   OverSizedMetadata evil_meta = {};
   EXPECT_NE(0, p->Post(LocalHandle(), evil_meta));
-  EXPECT_GE(0, RETRY_EINTR(c->Poll(10)));
+  EXPECT_GE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
 
   // It is ok to post metadata smaller than originally requested during
   // buffer allocation.
@@ -638,7 +645,7 @@
   EXPECT_EQ(0, p->Post<void>(LocalHandle()));
   EXPECT_EQ(0, c->Acquire(&fence));
   EXPECT_EQ(0, c->Release(LocalHandle()));
-  EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
+  EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
 
   // Test that removing persistence and closing the producer orphans the
   // consumer.
@@ -679,7 +686,7 @@
 
   // Should acquire a valid fence.
   LocalHandle f2;
-  EXPECT_LT(0, RETRY_EINTR(c->Poll(10)));
+  EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
   EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
   EXPECT_TRUE(f2.IsValid());
   // The original fence and acquired fence should have different fd number.
@@ -689,14 +696,14 @@
   // Signal the original fence will trigger the new fence.
   eventfd_write(f1.Get(), 1);
   // Now the original FD has been signaled.
-  EXPECT_LT(0, PollFd(f2.Get(), 10));
+  EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
 
   // Release the consumer with an invalid fence.
   EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
 
   // Should gain an invalid fence.
   LocalHandle f3;
-  EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
+  EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
   EXPECT_EQ(0, p->GainAsync(&meta, &f3));
   EXPECT_FALSE(f3.IsValid());
 
@@ -705,10 +712,10 @@
 
   // Should acquire a valid fence and it's already signalled.
   LocalHandle f4;
-  EXPECT_LT(0, RETRY_EINTR(c->Poll(10)));
+  EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
   EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
   EXPECT_TRUE(f4.IsValid());
-  EXPECT_LT(0, PollFd(f4.Get(), 10));
+  EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
 
   // Release with an unsignalled fence and signal it immediately after release
   // without producer gainning.
@@ -718,10 +725,10 @@
 
   // Should gain a valid fence, which is already signaled.
   LocalHandle f6;
-  EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
+  EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
   EXPECT_EQ(0, p->GainAsync(&meta, &f6));
   EXPECT_TRUE(f6.IsValid());
-  EXPECT_LT(0, PollFd(f6.Get(), 10));
+  EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
 }
 
 TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
@@ -737,12 +744,12 @@
   EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
 
   LocalHandle fence;
-  EXPECT_LT(0, RETRY_EINTR(c1->Poll(10)));
+  EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
   EXPECT_LE(0, c1->AcquireAsync(&meta, &fence));
   // Destroy the consumer now will make it orphaned and the buffer is still
   // acquired.
   c1 = nullptr;
-  EXPECT_GE(0, RETRY_EINTR(p->Poll(10)));
+  EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
 
   std::unique_ptr<BufferConsumer> c2 =
       BufferConsumer::Import(p->CreateConsumer());
@@ -751,13 +758,13 @@
   EXPECT_NE(consumer_state_bit1, consumer_state_bit2);
 
   // The new consumer is available for acquire.
-  EXPECT_LT(0, RETRY_EINTR(c2->Poll(10)));
+  EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
   EXPECT_LE(0, c2->AcquireAsync(&meta, &fence));
   // Releasing the consumer makes the buffer gainable.
   EXPECT_EQ(0, c2->ReleaseAsync(&meta, LocalHandle()));
 
   // The buffer is now available for the producer to gain.
-  EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
+  EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
 
   // But if another consumer is created in released state.
   std::unique_ptr<BufferConsumer> c3 =
@@ -766,7 +773,7 @@
   const uint64_t consumer_state_bit3 = c3->buffer_state_bit();
   EXPECT_NE(consumer_state_bit2, consumer_state_bit3);
   // The consumer buffer is not acquirable.
-  EXPECT_GE(0, RETRY_EINTR(c3->Poll(10)));
+  EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
   EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &fence));
 
   // Producer should be able to gain no matter what.
diff --git a/libs/vr/libdvr/include/dvr/dvr_display_types.h b/libs/vr/libdvr/include/dvr/dvr_display_types.h
index 25364d8..fd69843 100644
--- a/libs/vr/libdvr/include/dvr/dvr_display_types.h
+++ b/libs/vr/libdvr/include/dvr/dvr_display_types.h
@@ -13,7 +13,7 @@
 #ifndef __FLOAT32X4T_86
 #define __FLOAT32X4T_86
 typedef float float32x4_t __attribute__((__vector_size__(16)));
-typedef struct float32x4x4_t { float32x4_t val[4]; };
+typedef struct float32x4x4_t { float32x4_t val[4]; } float32x4x4_t;
 #endif
 #endif
 
diff --git a/libs/vr/libpdx_uds/private/uds/channel_event_set.h b/libs/vr/libpdx_uds/private/uds/channel_event_set.h
index 99e7502..e960740 100644
--- a/libs/vr/libpdx_uds/private/uds/channel_event_set.h
+++ b/libs/vr/libpdx_uds/private/uds/channel_event_set.h
@@ -54,6 +54,14 @@
   BorrowedHandle pollhup_event_fd() const { return pollhup_event_fd_.Borrow(); }
   BorrowedHandle data_fd() const { return data_fd_.Borrow(); }
 
+  // Moves file descriptors out of ChannelEventReceiver. Note these operations
+  // immediately invalidates the receiver.
+  std::tuple<LocalHandle, LocalHandle, LocalHandle> TakeFds() {
+    epoll_fd_.Close();
+    return {std::move(data_fd_), std::move(pollin_event_fd_),
+            std::move(pollhup_event_fd_)};
+  }
+
   Status<int> GetPendingEvents() const;
   Status<int> PollPendingEvents(int timeout_ms) const;
 
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index 32c2d7e..d43c164 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -122,6 +122,16 @@
     },
 }
 
+cc_library_static {
+    name: "libEGL_blobCache",
+    defaults: ["egl_libs_defaults"],
+    srcs: [
+        "EGL/BlobCache.cpp",
+        "EGL/FileBlobCache.cpp",
+    ],
+    export_include_dirs: ["EGL"],
+}
+
 cc_library_shared {
     name: "libEGL",
     defaults: ["egl_libs_defaults"],
@@ -133,7 +143,6 @@
         "EGL/egl.cpp",
         "EGL/eglApi.cpp",
         "EGL/Loader.cpp",
-        "EGL/BlobCache.cpp",
     ],
     shared_libs: [
         "libvndksupport",
@@ -143,7 +152,10 @@
         "libhidltransport",
         "libutils",
     ],
-    static_libs: ["libEGL_getProcAddress"],
+    static_libs: [
+        "libEGL_getProcAddress",
+        "libEGL_blobCache",
+    ],
     ldflags: ["-Wl,--exclude-libs=ALL"],
     export_include_dirs: ["EGL/include"],
 }
diff --git a/opengl/libs/EGL/BlobCache.cpp b/opengl/libs/EGL/BlobCache.cpp
index 0624b60..b3752f5 100644
--- a/opengl/libs/EGL/BlobCache.cpp
+++ b/opengl/libs/EGL/BlobCache.cpp
@@ -37,9 +37,9 @@
 static const uint32_t blobCacheDeviceVersion = 1;
 
 BlobCache::BlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize):
+        mMaxTotalSize(maxTotalSize),
         mMaxKeySize(maxKeySize),
         mMaxValueSize(maxValueSize),
-        mMaxTotalSize(maxTotalSize),
         mTotalSize(0) {
     int64_t now = std::chrono::steady_clock::now().time_since_epoch().count();
 #ifdef _WIN32
diff --git a/opengl/libs/EGL/BlobCache.h b/opengl/libs/EGL/BlobCache.h
index a0a270a..1f5d535 100644
--- a/opengl/libs/EGL/BlobCache.h
+++ b/opengl/libs/EGL/BlobCache.h
@@ -97,6 +97,14 @@
     //
     int unflatten(void const* buffer, size_t size);
 
+protected:
+    // mMaxTotalSize is the maximum size that all cache entries can occupy. This
+    // includes space for both keys and values. When a call to BlobCache::set
+    // would otherwise cause this limit to be exceeded, either the key/value
+    // pair passed to BlobCache::set will not be cached or other cache entries
+    // will be evicted from the cache to make room for the new entry.
+    const size_t mMaxTotalSize;
+
 private:
     // Copying is disallowed.
     BlobCache(const BlobCache&);
@@ -220,13 +228,6 @@
     // simply not add the key/value pair to the cache.
     const size_t mMaxValueSize;
 
-    // mMaxTotalSize is the maximum size that all cache entries can occupy. This
-    // includes space for both keys and values. When a call to BlobCache::set
-    // would otherwise cause this limit to be exceeded, either the key/value
-    // pair passed to BlobCache::set will not be cached or other cache entries
-    // will be evicted from the cache to make room for the new entry.
-    const size_t mMaxTotalSize;
-
     // mTotalSize is the total combined size of all keys and values currently in
     // the cache.
     size_t mTotalSize;
diff --git a/opengl/libs/EGL/FileBlobCache.cpp b/opengl/libs/EGL/FileBlobCache.cpp
new file mode 100644
index 0000000..ff608a3
--- /dev/null
+++ b/opengl/libs/EGL/FileBlobCache.cpp
@@ -0,0 +1,185 @@
+/*
+ ** Copyright 2017, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#include "FileBlobCache.h"
+
+#include <inttypes.h>
+#include <log/log.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+
+// Cache file header
+static const char* cacheFileMagic = "EGL$";
+static const size_t cacheFileHeaderSize = 8;
+
+namespace android {
+
+static uint32_t crc32c(const uint8_t* buf, size_t len) {
+    const uint32_t polyBits = 0x82F63B78;
+    uint32_t r = 0;
+    for (size_t i = 0; i < len; i++) {
+        r ^= buf[i];
+        for (int j = 0; j < 8; j++) {
+            if (r & 1) {
+                r = (r >> 1) ^ polyBits;
+            } else {
+                r >>= 1;
+            }
+        }
+    }
+    return r;
+}
+
+FileBlobCache::FileBlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize,
+        const std::string& filename)
+        : BlobCache(maxKeySize, maxValueSize, maxTotalSize)
+        , mFilename(filename) {
+    if (mFilename.length() > 0) {
+        size_t headerSize = cacheFileHeaderSize;
+
+        int fd = open(mFilename.c_str(), O_RDONLY, 0);
+        if (fd == -1) {
+            if (errno != ENOENT) {
+                ALOGE("error opening cache file %s: %s (%d)", mFilename.c_str(),
+                        strerror(errno), errno);
+            }
+            return;
+        }
+
+        struct stat statBuf;
+        if (fstat(fd, &statBuf) == -1) {
+            ALOGE("error stat'ing cache file: %s (%d)", strerror(errno), errno);
+            close(fd);
+            return;
+        }
+
+        // Sanity check the size before trying to mmap it.
+        size_t fileSize = statBuf.st_size;
+        if (fileSize > mMaxTotalSize * 2) {
+            ALOGE("cache file is too large: %#" PRIx64,
+                  static_cast<off64_t>(statBuf.st_size));
+            close(fd);
+            return;
+        }
+
+        uint8_t* buf = reinterpret_cast<uint8_t*>(mmap(NULL, fileSize,
+                PROT_READ, MAP_PRIVATE, fd, 0));
+        if (buf == MAP_FAILED) {
+            ALOGE("error mmaping cache file: %s (%d)", strerror(errno),
+                    errno);
+            close(fd);
+            return;
+        }
+
+        // Check the file magic and CRC
+        size_t cacheSize = fileSize - headerSize;
+        if (memcmp(buf, cacheFileMagic, 4) != 0) {
+            ALOGE("cache file has bad mojo");
+            close(fd);
+            return;
+        }
+        uint32_t* crc = reinterpret_cast<uint32_t*>(buf + 4);
+        if (crc32c(buf + headerSize, cacheSize) != *crc) {
+            ALOGE("cache file failed CRC check");
+            close(fd);
+            return;
+        }
+
+        int err = unflatten(buf + headerSize, cacheSize);
+        if (err < 0) {
+            ALOGE("error reading cache contents: %s (%d)", strerror(-err),
+                    -err);
+            munmap(buf, fileSize);
+            close(fd);
+            return;
+        }
+
+        munmap(buf, fileSize);
+        close(fd);
+    }
+}
+
+void FileBlobCache::writeToFile() {
+    if (mFilename.length() > 0) {
+        size_t cacheSize = getFlattenedSize();
+        size_t headerSize = cacheFileHeaderSize;
+        const char* fname = mFilename.c_str();
+
+        // Try to create the file with no permissions so we can write it
+        // without anyone trying to read it.
+        int fd = open(fname, O_CREAT | O_EXCL | O_RDWR, 0);
+        if (fd == -1) {
+            if (errno == EEXIST) {
+                // The file exists, delete it and try again.
+                if (unlink(fname) == -1) {
+                    // No point in retrying if the unlink failed.
+                    ALOGE("error unlinking cache file %s: %s (%d)", fname,
+                            strerror(errno), errno);
+                    return;
+                }
+                // Retry now that we've unlinked the file.
+                fd = open(fname, O_CREAT | O_EXCL | O_RDWR, 0);
+            }
+            if (fd == -1) {
+                ALOGE("error creating cache file %s: %s (%d)", fname,
+                        strerror(errno), errno);
+                return;
+            }
+        }
+
+        size_t fileSize = headerSize + cacheSize;
+
+        uint8_t* buf = new uint8_t [fileSize];
+        if (!buf) {
+            ALOGE("error allocating buffer for cache contents: %s (%d)",
+                    strerror(errno), errno);
+            close(fd);
+            unlink(fname);
+            return;
+        }
+
+        int err = flatten(buf + headerSize, cacheSize);
+        if (err < 0) {
+            ALOGE("error writing cache contents: %s (%d)", strerror(-err),
+                    -err);
+            delete [] buf;
+            close(fd);
+            unlink(fname);
+            return;
+        }
+
+        // Write the file magic and CRC
+        memcpy(buf, cacheFileMagic, 4);
+        uint32_t* crc = reinterpret_cast<uint32_t*>(buf + 4);
+        *crc = crc32c(buf + headerSize, cacheSize);
+
+        if (write(fd, buf, fileSize) == -1) {
+            ALOGE("error writing cache file: %s (%d)", strerror(errno),
+                    errno);
+            delete [] buf;
+            close(fd);
+            unlink(fname);
+            return;
+        }
+
+        delete [] buf;
+        fchmod(fd, S_IRUSR);
+        close(fd);
+    }
+}
+
+}
\ No newline at end of file
diff --git a/opengl/libs/EGL/FileBlobCache.h b/opengl/libs/EGL/FileBlobCache.h
new file mode 100644
index 0000000..393703f
--- /dev/null
+++ b/opengl/libs/EGL/FileBlobCache.h
@@ -0,0 +1,43 @@
+/*
+ ** Copyright 2017, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#ifndef ANDROID_FILE_BLOB_CACHE_H
+#define ANDROID_FILE_BLOB_CACHE_H
+
+#include "BlobCache.h"
+#include <string>
+
+namespace android {
+
+class FileBlobCache : public BlobCache {
+public:
+    // FileBlobCache attempts to load the saved cache contents from disk into
+    // BlobCache.
+    FileBlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize,
+            const std::string& filename);
+
+    // writeToFile attempts to save the current contents of BlobCache to
+    // disk.
+    void writeToFile();
+
+private:
+    // mFilename is the name of the file for storing cache contents.
+    std::string mFilename;
+};
+
+} // namespace android
+
+#endif // ANDROID_BLOB_CACHE_H
diff --git a/opengl/libs/EGL/egl_cache.cpp b/opengl/libs/EGL/egl_cache.cpp
index 579e422..ec548f3 100644
--- a/opengl/libs/EGL/egl_cache.cpp
+++ b/opengl/libs/EGL/egl_cache.cpp
@@ -20,12 +20,8 @@
 
 #include "egl_display.h"
 
-
 #include <private/EGL/cache.h>
 
-#include <inttypes.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
 #include <unistd.h>
 
 #include <thread>
@@ -37,10 +33,6 @@
 static const size_t maxValueSize = 64 * 1024;
 static const size_t maxTotalSize = 2 * 1024 * 1024;
 
-// Cache file header
-static const char* cacheFileMagic = "EGL$";
-static const size_t cacheFileHeaderSize = 8;
-
 // The time in seconds to wait before saving newly inserted cache entries.
 static const unsigned int deferredSaveDelay = 4;
 
@@ -124,7 +116,9 @@
 
 void egl_cache_t::terminate() {
     std::lock_guard<std::mutex> lock(mMutex);
-    saveBlobCacheLocked();
+    if (mBlobCache) {
+        mBlobCache->writeToFile();
+    }
     mBlobCache = NULL;
 }
 
@@ -146,8 +140,8 @@
             std::thread deferredSaveThread([this]() {
                 sleep(deferredSaveDelay);
                 std::lock_guard<std::mutex> lock(mMutex);
-                if (mInitialized) {
-                    saveBlobCacheLocked();
+                if (mInitialized && mBlobCache) {
+                    mBlobCache->writeToFile();
                 }
                 mSavePending = false;
             });
@@ -179,163 +173,11 @@
 
 BlobCache* egl_cache_t::getBlobCacheLocked() {
     if (mBlobCache == nullptr) {
-        mBlobCache.reset(new BlobCache(maxKeySize, maxValueSize, maxTotalSize));
-        loadBlobCacheLocked();
+        mBlobCache.reset(new FileBlobCache(maxKeySize, maxValueSize, maxTotalSize, mFilename));
     }
     return mBlobCache.get();
 }
 
-static uint32_t crc32c(const uint8_t* buf, size_t len) {
-    const uint32_t polyBits = 0x82F63B78;
-    uint32_t r = 0;
-    for (size_t i = 0; i < len; i++) {
-        r ^= buf[i];
-        for (int j = 0; j < 8; j++) {
-            if (r & 1) {
-                r = (r >> 1) ^ polyBits;
-            } else {
-                r >>= 1;
-            }
-        }
-    }
-    return r;
-}
-
-void egl_cache_t::saveBlobCacheLocked() {
-    if (mFilename.length() > 0 && mBlobCache != NULL) {
-        size_t cacheSize = mBlobCache->getFlattenedSize();
-        size_t headerSize = cacheFileHeaderSize;
-        const char* fname = mFilename.c_str();
-
-        // Try to create the file with no permissions so we can write it
-        // without anyone trying to read it.
-        int fd = open(fname, O_CREAT | O_EXCL | O_RDWR, 0);
-        if (fd == -1) {
-            if (errno == EEXIST) {
-                // The file exists, delete it and try again.
-                if (unlink(fname) == -1) {
-                    // No point in retrying if the unlink failed.
-                    ALOGE("error unlinking cache file %s: %s (%d)", fname,
-                            strerror(errno), errno);
-                    return;
-                }
-                // Retry now that we've unlinked the file.
-                fd = open(fname, O_CREAT | O_EXCL | O_RDWR, 0);
-            }
-            if (fd == -1) {
-                ALOGE("error creating cache file %s: %s (%d)", fname,
-                        strerror(errno), errno);
-                return;
-            }
-        }
-
-        size_t fileSize = headerSize + cacheSize;
-
-        uint8_t* buf = new uint8_t [fileSize];
-        if (!buf) {
-            ALOGE("error allocating buffer for cache contents: %s (%d)",
-                    strerror(errno), errno);
-            close(fd);
-            unlink(fname);
-            return;
-        }
-
-        int err = mBlobCache->flatten(buf + headerSize, cacheSize);
-        if (err < 0) {
-            ALOGE("error writing cache contents: %s (%d)", strerror(-err),
-                    -err);
-            delete [] buf;
-            close(fd);
-            unlink(fname);
-            return;
-        }
-
-        // Write the file magic and CRC
-        memcpy(buf, cacheFileMagic, 4);
-        uint32_t* crc = reinterpret_cast<uint32_t*>(buf + 4);
-        *crc = crc32c(buf + headerSize, cacheSize);
-
-        if (write(fd, buf, fileSize) == -1) {
-            ALOGE("error writing cache file: %s (%d)", strerror(errno),
-                    errno);
-            delete [] buf;
-            close(fd);
-            unlink(fname);
-            return;
-        }
-
-        delete [] buf;
-        fchmod(fd, S_IRUSR);
-        close(fd);
-    }
-}
-
-void egl_cache_t::loadBlobCacheLocked() {
-    if (mFilename.length() > 0) {
-        size_t headerSize = cacheFileHeaderSize;
-
-        int fd = open(mFilename.c_str(), O_RDONLY, 0);
-        if (fd == -1) {
-            if (errno != ENOENT) {
-                ALOGE("error opening cache file %s: %s (%d)", mFilename.c_str(),
-                        strerror(errno), errno);
-            }
-            return;
-        }
-
-        struct stat statBuf;
-        if (fstat(fd, &statBuf) == -1) {
-            ALOGE("error stat'ing cache file: %s (%d)", strerror(errno), errno);
-            close(fd);
-            return;
-        }
-
-        // Sanity check the size before trying to mmap it.
-        size_t fileSize = statBuf.st_size;
-        if (fileSize > maxTotalSize * 2) {
-            ALOGE("cache file is too large: %#" PRIx64,
-                  static_cast<off64_t>(statBuf.st_size));
-            close(fd);
-            return;
-        }
-
-        uint8_t* buf = reinterpret_cast<uint8_t*>(mmap(NULL, fileSize,
-                PROT_READ, MAP_PRIVATE, fd, 0));
-        if (buf == MAP_FAILED) {
-            ALOGE("error mmaping cache file: %s (%d)", strerror(errno),
-                    errno);
-            close(fd);
-            return;
-        }
-
-        // Check the file magic and CRC
-        size_t cacheSize = fileSize - headerSize;
-        if (memcmp(buf, cacheFileMagic, 4) != 0) {
-            ALOGE("cache file has bad mojo");
-            close(fd);
-            return;
-        }
-        uint32_t* crc = reinterpret_cast<uint32_t*>(buf + 4);
-        if (crc32c(buf + headerSize, cacheSize) != *crc) {
-            ALOGE("cache file failed CRC check");
-            close(fd);
-            return;
-        }
-
-        int err = mBlobCache->unflatten(buf + headerSize, cacheSize);
-        if (err < 0) {
-            ALOGE("error reading cache contents: %s (%d)", strerror(-err),
-                    -err);
-            munmap(buf, fileSize);
-            close(fd);
-            return;
-        }
-
-        munmap(buf, fileSize);
-        close(fd);
-    }
-}
-
 // ----------------------------------------------------------------------------
 }; // namespace android
 // ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_cache.h b/opengl/libs/EGL/egl_cache.h
index 56360f0..7382b91 100644
--- a/opengl/libs/EGL/egl_cache.h
+++ b/opengl/libs/EGL/egl_cache.h
@@ -20,7 +20,7 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
-#include "BlobCache.h"
+#include "FileBlobCache.h"
 
 #include <memory>
 #include <mutex>
@@ -82,14 +82,6 @@
     // possible.
     BlobCache* getBlobCacheLocked();
 
-    // saveBlobCache attempts to save the current contents of mBlobCache to
-    // disk.
-    void saveBlobCacheLocked();
-
-    // loadBlobCache attempts to load the saved cache contents from disk into
-    // mBlobCache.
-    void loadBlobCacheLocked();
-
     // mInitialized indicates whether the egl_cache_t is in the initialized
     // state.  It is initialized to false at construction time, and gets set to
     // true when initialize is called.  It is set back to false when terminate
@@ -101,7 +93,7 @@
     // mBlobCache is the cache in which the key/value blob pairs are stored.  It
     // is initially NULL, and will be initialized by getBlobCacheLocked the
     // first time it's needed.
-    std::unique_ptr<BlobCache> mBlobCache;
+    std::unique_ptr<FileBlobCache> mBlobCache;
 
     // mFilename is the name of the file for storing cache contents in between
     // program invocations.  It is initialized to an empty string at
diff --git a/services/sensorservice/BatteryService.cpp b/services/sensorservice/BatteryService.cpp
index 452c8c6..330861d 100644
--- a/services/sensorservice/BatteryService.cpp
+++ b/services/sensorservice/BatteryService.cpp
@@ -78,12 +78,13 @@
     if (checkService()) {
         Mutex::Autolock _l(mActivationsLock);
         int64_t identity = IPCThreadState::self()->clearCallingIdentity();
-        for (size_t i=0 ; i<mActivations.size() ; i++) {
+        for (size_t i=0 ; i<mActivations.size() ; ) {
             const Info& info(mActivations[i]);
             if (info.uid == uid) {
                 mBatteryStatService->noteStopSensor(info.uid, info.handle);
                 mActivations.removeAt(i);
-                i--;
+            } else {
+              i++;
             }
         }
         IPCThreadState::self()->restoreCallingIdentity(identity);
@@ -105,4 +106,3 @@
 
 // ---------------------------------------------------------------------------
 }; // namespace android
-
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 3f8ab3f..7115ad6 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -14,6 +14,7 @@
     FrameTracker.cpp \
     GpuService.cpp \
     Layer.cpp \
+    BufferLayer.cpp \
     ColorLayer.cpp \
     LayerRejecter.cpp \
     LayerVector.cpp \
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
new file mode 100644
index 0000000..45093be
--- /dev/null
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -0,0 +1,1002 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#undef LOG_TAG
+#define LOG_TAG "BufferLayer"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include "BufferLayer.h"
+#include "Colorizer.h"
+#include "DisplayDevice.h"
+#include "LayerRejecter.h"
+#include "clz.h"
+
+#include "RenderEngine/RenderEngine.h"
+
+#include <gui/BufferItem.h>
+#include <gui/BufferQueue.h>
+#include <gui/LayerDebugInfo.h>
+#include <gui/Surface.h>
+
+#include <ui/DebugUtils.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/NativeHandle.h>
+#include <utils/StopWatch.h>
+#include <utils/Trace.h>
+
+#include <cutils/compiler.h>
+#include <cutils/native_handle.h>
+#include <cutils/properties.h>
+
+#include <math.h>
+#include <stdlib.h>
+#include <mutex>
+
+namespace android {
+
+BufferLayer::BufferLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name,
+                         uint32_t w, uint32_t h, uint32_t flags)
+      : Layer(flinger, client, name, w, h, flags),
+        mSurfaceFlingerConsumer(nullptr),
+        mTextureName(-1U),
+        mFormat(PIXEL_FORMAT_NONE),
+        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
+        mBufferLatched(false),
+        mPreviousFrameNumber(0),
+        mUpdateTexImageFailed(false),
+        mRefreshPending(false) {
+#ifdef USE_HWC2
+    ALOGV("Creating Layer %s", name.string());
+#endif
+
+    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
+    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
+
+    if (flags & ISurfaceComposerClient::eNonPremultiplied) mPremultipliedAlpha = false;
+
+    mCurrentState.requested = mCurrentState.active;
+
+    // drawing state & current state are identical
+    mDrawingState = mCurrentState;
+}
+
+BufferLayer::~BufferLayer() {
+    sp<Client> c(mClientRef.promote());
+    if (c != 0) {
+        c->detachLayer(this);
+    }
+
+    for (auto& point : mRemoteSyncPoints) {
+        point->setTransactionApplied();
+    }
+    for (auto& point : mLocalSyncPoints) {
+        point->setFrameAvailable();
+    }
+    mFlinger->deleteTextureAsync(mTextureName);
+
+#ifdef USE_HWC2
+    if (!mHwcLayers.empty()) {
+        ALOGE("Found stale hardware composer layers when destroying "
+              "surface flinger layer %s",
+              mName.string());
+        destroyAllHwcLayers();
+    }
+#endif
+}
+
+void BufferLayer::useSurfaceDamage() {
+    if (mFlinger->mForceFullDamage) {
+        surfaceDamageRegion = Region::INVALID_REGION;
+    } else {
+        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
+    }
+}
+
+void BufferLayer::useEmptyDamage() {
+    surfaceDamageRegion.clear();
+}
+
+bool BufferLayer::isProtected() const {
+    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
+    return (activeBuffer != 0) && (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
+}
+
+bool BufferLayer::isVisible() const {
+    return !(isHiddenByPolicy()) && getAlpha() > 0.0f &&
+            (mActiveBuffer != NULL || mSidebandStream != NULL);
+}
+
+bool BufferLayer::isFixedSize() const {
+    return getEffectiveScalingMode() != NATIVE_WINDOW_SCALING_MODE_FREEZE;
+}
+
+status_t BufferLayer::setBuffers(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) {
+    uint32_t const maxSurfaceDims =
+            min(mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
+
+    // never allow a surface larger than what our underlying GL implementation
+    // can handle.
+    if ((uint32_t(w) > maxSurfaceDims) || (uint32_t(h) > maxSurfaceDims)) {
+        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
+        return BAD_VALUE;
+    }
+
+    mFormat = format;
+
+    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
+    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
+    mCurrentOpacity = getOpacityForFormat(format);
+
+    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
+    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
+    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
+
+    return NO_ERROR;
+}
+
+static constexpr mat4 inverseOrientation(uint32_t transform) {
+    const mat4 flipH(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1);
+    const mat4 flipV(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1);
+    const mat4 rot90(0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1);
+    mat4 tr;
+
+    if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+        tr = tr * rot90;
+    }
+    if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
+        tr = tr * flipH;
+    }
+    if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
+        tr = tr * flipV;
+    }
+    return inverse(tr);
+}
+
+/*
+ * onDraw will draw the current layer onto the presentable buffer
+ */
+void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip,
+                         bool useIdentityTransform) const {
+    ATRACE_CALL();
+
+    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
+        // SurfaceView because the WindowManager can't know when the client
+        // has drawn the first time.
+
+        // If there is nothing under us, we paint the screen in black, otherwise
+        // we just skip this update.
+
+        // figure out if there is something below us
+        Region under;
+        bool finished = false;
+        mFlinger->mDrawingState.traverseInZOrder([&](Layer* layer) {
+            if (finished || layer == static_cast<BufferLayer const*>(this)) {
+                finished = true;
+                return;
+            }
+            under.orSelf(renderArea.getTransform().transform(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);
+        }
+        return;
+    }
+
+    // Bind the current buffer to the GL texture, and wait for it to be
+    // ready for us to draw into.
+    status_t err = mSurfaceFlingerConsumer->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());
+
+    RenderEngine& engine(mFlinger->getRenderEngine());
+
+    if (!blackOutLayer) {
+        // TODO: we could be more subtle with isFixedSize()
+        const bool useFiltering = getFiltering() || needsFiltering(renderArea) || isFixedSize();
+
+        // Query the texture matrix given our current filtering mode.
+        float textureMatrix[16];
+        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
+        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
+
+        if (getTransformToDisplayInverse()) {
+            /*
+             * the code below applies the primary display's inverse transform to
+             * the texture transform
+             */
+            uint32_t transform = DisplayDevice::getPrimaryDisplayOrientationTransform();
+            mat4 tr = inverseOrientation(transform);
+
+            /**
+             * TODO(b/36727915): This is basically a hack.
+             *
+             * Ensure that regardless of the parent transformation,
+             * this buffer is always transformed from native display
+             * orientation to display orientation. For example, in the case
+             * of a camera where the buffer remains in native orientation,
+             * we want the pixels to always be upright.
+             */
+            sp<Layer> p = mDrawingParent.promote();
+            if (p != nullptr) {
+                const auto parentTransform = p->getTransform();
+                tr = tr * inverseOrientation(parentTransform.getOrientation());
+            }
+
+            // and finally apply it to the original texture matrix
+            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
+            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
+        }
+
+        // Set things up for texturing.
+        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
+        mTexture.setFiltering(useFiltering);
+        mTexture.setMatrix(textureMatrix);
+
+        engine.setupLayerTexturing(mTexture);
+    } else {
+        engine.setupLayerBlackedOut();
+    }
+    drawWithOpenGL(renderArea, useIdentityTransform);
+    engine.disableTexturing();
+}
+
+#ifdef USE_HWC2
+void BufferLayer::onLayerDisplayed(const sp<Fence>& releaseFence) {
+    if (mHwcLayers.empty()) {
+        return;
+    }
+    mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
+}
+#else
+void BufferLayer::onLayerDisplayed(const sp<const DisplayDevice>& /*hw*/,
+                                   HWComposer::HWCLayerInterface* layer) {
+    if (layer) {
+        layer->onDisplayed();
+        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
+    }
+}
+#endif
+
+void BufferLayer::abandon() {
+    mSurfaceFlingerConsumer->abandon();
+}
+
+bool BufferLayer::shouldPresentNow(const DispSync& dispSync) const {
+    if (mSidebandStreamChanged || mAutoRefresh) {
+        return true;
+    }
+
+    Mutex::Autolock lock(mQueueItemLock);
+    if (mQueueItems.empty()) {
+        return false;
+    }
+    auto timestamp = mQueueItems[0].mTimestamp;
+    nsecs_t expectedPresent = mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
+
+    // Ignore timestamps more than a second in the future
+    bool isPlausible = timestamp < (expectedPresent + s2ns(1));
+    ALOGW_IF(!isPlausible,
+             "[%s] Timestamp %" PRId64 " seems implausible "
+             "relative to expectedPresent %" PRId64,
+             mName.string(), timestamp, expectedPresent);
+
+    bool isDue = timestamp < expectedPresent;
+    return isDue || !isPlausible;
+}
+
+void BufferLayer::setTransformHint(uint32_t orientation) const {
+    mSurfaceFlingerConsumer->setTransformHint(orientation);
+}
+
+bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) {
+    if (mBufferLatched) {
+        Mutex::Autolock lock(mFrameEventHistoryMutex);
+        mFrameEventHistory.addPreComposition(mCurrentFrameNumber, refreshStartTime);
+    }
+    mRefreshPending = false;
+    return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
+}
+bool BufferLayer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
+                                    const std::shared_ptr<FenceTime>& presentFence,
+                                    const CompositorTiming& compositorTiming) {
+    // mFrameLatencyNeeded is true when a new frame was latched for the
+    // composition.
+    if (!mFrameLatencyNeeded) return false;
+
+    // Update mFrameEventHistory.
+    {
+        Mutex::Autolock lock(mFrameEventHistoryMutex);
+        mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence, presentFence,
+                                              compositorTiming);
+    }
+
+    // Update mFrameTracker.
+    nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
+    mFrameTracker.setDesiredPresentTime(desiredPresentTime);
+
+    std::shared_ptr<FenceTime> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFenceTime();
+    if (frameReadyFence->isValid()) {
+        mFrameTracker.setFrameReadyFence(std::move(frameReadyFence));
+    } else {
+        // There was no fence for this frame, so assume that it was ready
+        // to be presented at the desired present time.
+        mFrameTracker.setFrameReadyTime(desiredPresentTime);
+    }
+
+    if (presentFence->isValid()) {
+        mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
+    } else {
+        // The HWC doesn't support present fences, so use the refresh
+        // timestamp instead.
+        mFrameTracker.setActualPresentTime(
+                mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY));
+    }
+
+    mFrameTracker.advanceFrame();
+    mFrameLatencyNeeded = false;
+    return true;
+}
+
+std::vector<OccupancyTracker::Segment> BufferLayer::getOccupancyHistory(bool forceFlush) {
+    std::vector<OccupancyTracker::Segment> history;
+    status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush, &history);
+    if (result != NO_ERROR) {
+        ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(), result);
+        return {};
+    }
+    return history;
+}
+
+bool BufferLayer::getTransformToDisplayInverse() const {
+    return mSurfaceFlingerConsumer->getTransformToDisplayInverse();
+}
+
+#ifdef USE_HWC2
+void BufferLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
+    if (!mSurfaceFlingerConsumer->releasePendingBuffer()) {
+        return;
+    }
+
+    auto releaseFenceTime =
+            std::make_shared<FenceTime>(mSurfaceFlingerConsumer->getPrevFinalReleaseFence());
+    mReleaseTimeline.updateSignalTimes();
+    mReleaseTimeline.push(releaseFenceTime);
+
+    Mutex::Autolock lock(mFrameEventHistoryMutex);
+    if (mPreviousFrameNumber != 0) {
+        mFrameEventHistory.addRelease(mPreviousFrameNumber, dequeueReadyTime,
+                                      std::move(releaseFenceTime));
+    }
+}
+#endif
+
+Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) {
+    ATRACE_CALL();
+
+    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
+        // mSidebandStreamChanged was true
+        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
+        if (mSidebandStream != NULL) {
+            setTransactionFlags(eTransactionNeeded);
+            mFlinger->setTransactionFlags(eTraversalNeeded);
+        }
+        recomputeVisibleRegions = true;
+
+        const State& s(getDrawingState());
+        return getTransform().transform(Region(Rect(s.active.w, s.active.h)));
+    }
+
+    Region outDirtyRegion;
+    if (mQueuedFrames <= 0 && !mAutoRefresh) {
+        return outDirtyRegion;
+    }
+
+    // if we've already called updateTexImage() without going through
+    // a composition step, we have to skip this layer at this point
+    // because we cannot call updateTeximage() without a corresponding
+    // compositionComplete() call.
+    // we'll trigger an update in onPreComposition().
+    if (mRefreshPending) {
+        return outDirtyRegion;
+    }
+
+    // If the head buffer's acquire fence hasn't signaled yet, return and
+    // try again later
+    if (!headFenceHasSignaled()) {
+        mFlinger->signalLayerUpdate();
+        return outDirtyRegion;
+    }
+
+    // Capture the old state of the layer for comparisons later
+    const State& s(getDrawingState());
+    const bool oldOpacity = isOpaque(s);
+    sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
+
+    if (!allTransactionsSignaled()) {
+        mFlinger->signalLayerUpdate();
+        return outDirtyRegion;
+    }
+
+    // This boolean is used to make sure that SurfaceFlinger's shadow copy
+    // of the buffer queue isn't modified when the buffer queue is returning
+    // BufferItem's that weren't actually queued. This can happen in shared
+    // buffer mode.
+    bool queuedBuffer = false;
+    LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
+                    getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode,
+                    mFreezeGeometryUpdates);
+    status_t updateResult =
+            mSurfaceFlingerConsumer->updateTexImage(&r, mFlinger->mPrimaryDispSync, &mAutoRefresh,
+                                                    &queuedBuffer, mLastFrameNumberReceived);
+    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.
+        mFlinger->signalLayerUpdate();
+        return outDirtyRegion;
+    } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
+        // If the buffer has been rejected, remove it from the shadow queue
+        // and return early
+        if (queuedBuffer) {
+            Mutex::Autolock lock(mQueueItemLock);
+            mQueueItems.removeAt(0);
+            android_atomic_dec(&mQueuedFrames);
+        }
+        return outDirtyRegion;
+    } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
+        // This can occur if something goes wrong when trying to create the
+        // EGLImage for this buffer. If this happens, the buffer has already
+        // been released, so we need to clean up the queue and bug out
+        // early.
+        if (queuedBuffer) {
+            Mutex::Autolock lock(mQueueItemLock);
+            mQueueItems.clear();
+            android_atomic_and(0, &mQueuedFrames);
+        }
+
+        // Once we have hit this state, the shadow queue may no longer
+        // correctly reflect the incoming BufferQueue's contents, so even if
+        // updateTexImage starts working, the only safe course of action is
+        // to continue to ignore updates.
+        mUpdateTexImageFailed = true;
+
+        return outDirtyRegion;
+    }
+
+    if (queuedBuffer) {
+        // Autolock scope
+        auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
+
+        Mutex::Autolock lock(mQueueItemLock);
+
+        // Remove any stale buffers that have been dropped during
+        // updateTexImage
+        while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
+            mQueueItems.removeAt(0);
+            android_atomic_dec(&mQueuedFrames);
+        }
+
+        mQueueItems.removeAt(0);
+    }
+
+    // Decrement the queued-frames count.  Signal another event if we
+    // have more frames pending.
+    if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1) || mAutoRefresh) {
+        mFlinger->signalLayerUpdate();
+    }
+
+    // update the active buffer
+    mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer(&mActiveBufferSlot);
+    if (mActiveBuffer == NULL) {
+        // this can only happen if the very first buffer was rejected.
+        return outDirtyRegion;
+    }
+
+    mBufferLatched = true;
+    mPreviousFrameNumber = mCurrentFrameNumber;
+    mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
+
+    {
+        Mutex::Autolock lock(mFrameEventHistoryMutex);
+        mFrameEventHistory.addLatch(mCurrentFrameNumber, latchTime);
+#ifndef USE_HWC2
+        auto releaseFenceTime =
+                std::make_shared<FenceTime>(mSurfaceFlingerConsumer->getPrevFinalReleaseFence());
+        mReleaseTimeline.updateSignalTimes();
+        mReleaseTimeline.push(releaseFenceTime);
+        if (mPreviousFrameNumber != 0) {
+            mFrameEventHistory.addRelease(mPreviousFrameNumber, latchTime,
+                                          std::move(releaseFenceTime));
+        }
+#endif
+    }
+
+    mRefreshPending = true;
+    mFrameLatencyNeeded = true;
+    if (oldActiveBuffer == NULL) {
+        // the first time we receive a buffer, we need to trigger a
+        // geometry invalidation.
+        recomputeVisibleRegions = true;
+    }
+
+    setDataSpace(mSurfaceFlingerConsumer->getCurrentDataSpace());
+
+    Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
+    const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
+    const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
+    if ((crop != mCurrentCrop) || (transform != mCurrentTransform) ||
+        (scalingMode != mCurrentScalingMode)) {
+        mCurrentCrop = crop;
+        mCurrentTransform = transform;
+        mCurrentScalingMode = scalingMode;
+        recomputeVisibleRegions = true;
+    }
+
+    if (oldActiveBuffer != NULL) {
+        uint32_t bufWidth = mActiveBuffer->getWidth();
+        uint32_t bufHeight = mActiveBuffer->getHeight();
+        if (bufWidth != uint32_t(oldActiveBuffer->width) ||
+            bufHeight != uint32_t(oldActiveBuffer->height)) {
+            recomputeVisibleRegions = true;
+        }
+    }
+
+    mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
+    if (oldOpacity != isOpaque(s)) {
+        recomputeVisibleRegions = true;
+    }
+
+    // Remove any sync points corresponding to the buffer which was just
+    // latched
+    {
+        Mutex::Autolock lock(mLocalSyncPointMutex);
+        auto point = mLocalSyncPoints.begin();
+        while (point != mLocalSyncPoints.end()) {
+            if (!(*point)->frameIsAvailable() || !(*point)->transactionIsApplied()) {
+                // This sync point must have been added since we started
+                // latching. Don't drop it yet.
+                ++point;
+                continue;
+            }
+
+            if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
+                point = mLocalSyncPoints.erase(point);
+            } else {
+                ++point;
+            }
+        }
+    }
+
+    // FIXME: postedRegion should be dirty & bounds
+    Region dirtyRegion(Rect(s.active.w, s.active.h));
+
+    // transform the dirty region to window-manager space
+    outDirtyRegion = (getTransform().transform(dirtyRegion));
+
+    return outDirtyRegion;
+}
+
+void BufferLayer::setDefaultBufferSize(uint32_t w, uint32_t h) {
+    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
+}
+
+#ifdef USE_HWC2
+void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
+    // Apply this display's projection's viewport to the visible region
+    // before giving it to the HWC HAL.
+    const Transform& tr = displayDevice->getTransform();
+    const auto& viewport = displayDevice->getViewport();
+    Region visible = tr.transform(visibleRegion.intersect(viewport));
+    auto hwcId = displayDevice->getHwcDisplayId();
+    auto& hwcInfo = mHwcLayers[hwcId];
+    auto& hwcLayer = hwcInfo.layer;
+    auto error = hwcLayer->setVisibleRegion(visible);
+    if (error != HWC2::Error::None) {
+        ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
+              to_string(error).c_str(), static_cast<int32_t>(error));
+        visible.dump(LOG_TAG);
+    }
+
+    error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
+    if (error != HWC2::Error::None) {
+        ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
+              to_string(error).c_str(), static_cast<int32_t>(error));
+        surfaceDamageRegion.dump(LOG_TAG);
+    }
+
+    // Sideband layers
+    if (mSidebandStream.get()) {
+        setCompositionType(hwcId, HWC2::Composition::Sideband);
+        ALOGV("[%s] Requesting Sideband composition", mName.string());
+        error = hwcLayer->setSidebandStream(mSidebandStream->handle());
+        if (error != HWC2::Error::None) {
+            ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(),
+                  mSidebandStream->handle(), to_string(error).c_str(), static_cast<int32_t>(error));
+        }
+        return;
+    }
+
+    // Client layers
+    if (hwcInfo.forceClientComposition ||
+        (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) {
+        ALOGV("[%s] Requesting Client composition", mName.string());
+        setCompositionType(hwcId, HWC2::Composition::Client);
+        return;
+    }
+
+    // Device or Cursor layers
+    if (mPotentialCursor) {
+        ALOGV("[%s] Requesting Cursor composition", mName.string());
+        setCompositionType(hwcId, HWC2::Composition::Cursor);
+    } else {
+        ALOGV("[%s] Requesting Device composition", mName.string());
+        setCompositionType(hwcId, HWC2::Composition::Device);
+    }
+
+    ALOGV("setPerFrameData: dataspace = %d", mCurrentState.dataSpace);
+    error = hwcLayer->setDataspace(mCurrentState.dataSpace);
+    if (error != HWC2::Error::None) {
+        ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentState.dataSpace,
+              to_string(error).c_str(), static_cast<int32_t>(error));
+    }
+
+    uint32_t hwcSlot = 0;
+    sp<GraphicBuffer> hwcBuffer;
+    hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot, &hwcBuffer);
+
+    auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
+    error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
+    if (error != HWC2::Error::None) {
+        ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), mActiveBuffer->handle,
+              to_string(error).c_str(), static_cast<int32_t>(error));
+    }
+}
+
+#else
+void BufferLayer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
+                                  HWComposer::HWCLayerInterface& layer) {
+    int fenceFd = -1;
+
+    // TODO: there is a possible optimization here: we only need to set the
+    // acquire fence the first time a new buffer is acquired on EACH display.
+
+    if (layer.getCompositionType() == HWC_OVERLAY ||
+        layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
+        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
+        if (fence->isValid()) {
+            fenceFd = fence->dup();
+            if (fenceFd == -1) {
+                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
+            }
+        }
+    }
+    layer.setAcquireFenceFd(fenceFd);
+}
+#endif
+
+bool BufferLayer::isOpaque(const Layer::State& s) const {
+    // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the
+    // layer's opaque flag.
+    if ((mSidebandStream == nullptr) && (mActiveBuffer == nullptr)) {
+        return false;
+    }
+
+    // if the layer has the opaque flag, then we're always opaque,
+    // otherwise we use the current buffer's format.
+    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
+}
+
+void BufferLayer::onFirstRef() {
+    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
+    sp<IGraphicBufferProducer> producer;
+    sp<IGraphicBufferConsumer> consumer;
+    BufferQueue::createBufferQueue(&producer, &consumer, true);
+    mProducer = new MonitoredProducer(producer, mFlinger, this);
+    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName, this);
+    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
+    mSurfaceFlingerConsumer->setContentsChangedListener(this);
+    mSurfaceFlingerConsumer->setName(mName);
+
+    if (mFlinger->isLayerTripleBufferingDisabled()) {
+        mProducer->setMaxDequeuedBufferCount(2);
+    }
+
+    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
+    updateTransformHint(hw);
+}
+
+// ---------------------------------------------------------------------------
+// Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener
+// ---------------------------------------------------------------------------
+
+void BufferLayer::onFrameAvailable(const BufferItem& item) {
+    // Add this buffer from our internal queue tracker
+    { // Autolock scope
+        Mutex::Autolock lock(mQueueItemLock);
+        mFlinger->mInterceptor.saveBufferUpdate(this, item.mGraphicBuffer->getWidth(),
+                                                item.mGraphicBuffer->getHeight(),
+                                                item.mFrameNumber);
+        // Reset the frame number tracker when we receive the first buffer after
+        // a frame number reset
+        if (item.mFrameNumber == 1) {
+            mLastFrameNumberReceived = 0;
+        }
+
+        // Ensure that callbacks are handled in order
+        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
+            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, ms2ns(500));
+            if (result != NO_ERROR) {
+                ALOGE("[%s] Timed out waiting on callback", mName.string());
+            }
+        }
+
+        mQueueItems.push_back(item);
+        android_atomic_inc(&mQueuedFrames);
+
+        // Wake up any pending callbacks
+        mLastFrameNumberReceived = item.mFrameNumber;
+        mQueueItemCondition.broadcast();
+    }
+
+    mFlinger->signalLayerUpdate();
+}
+
+void BufferLayer::onFrameReplaced(const BufferItem& item) {
+    { // Autolock scope
+        Mutex::Autolock lock(mQueueItemLock);
+
+        // Ensure that callbacks are handled in order
+        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
+            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, ms2ns(500));
+            if (result != NO_ERROR) {
+                ALOGE("[%s] Timed out waiting on callback", mName.string());
+            }
+        }
+
+        if (mQueueItems.empty()) {
+            ALOGE("Can't replace a frame on an empty queue");
+            return;
+        }
+        mQueueItems.editItemAt(mQueueItems.size() - 1) = item;
+
+        // Wake up any pending callbacks
+        mLastFrameNumberReceived = item.mFrameNumber;
+        mQueueItemCondition.broadcast();
+    }
+}
+
+void BufferLayer::onSidebandStreamChanged() {
+    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
+        // mSidebandStreamChanged was false
+        mFlinger->signalLayerUpdate();
+    }
+}
+
+bool BufferLayer::needsFiltering(const RenderArea& renderArea) const {
+    return mNeedsFiltering || renderArea.needsFiltering();
+}
+
+// As documented in libhardware header, formats in the range
+// 0x100 - 0x1FF are specific to the HAL implementation, and
+// are known to have no alpha channel
+// TODO: move definition for device-specific range into
+// hardware.h, instead of using hard-coded values here.
+#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
+
+bool BufferLayer::getOpacityForFormat(uint32_t format) {
+    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
+        return true;
+    }
+    switch (format) {
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+        case HAL_PIXEL_FORMAT_RGBA_FP16:
+        case HAL_PIXEL_FORMAT_RGBA_1010102:
+            return false;
+    }
+    // in all other case, we have no blending (also for unknown formats)
+    return true;
+}
+
+void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const {
+    const State& s(getDrawingState());
+
+    computeGeometry(renderArea, mMesh, useIdentityTransform);
+
+    /*
+     * NOTE: the way we compute the texture coordinates here produces
+     * different results than when we take the HWC path -- in the later case
+     * the "source crop" is rounded to texel boundaries.
+     * This can produce significantly different results when the texture
+     * is scaled by a large amount.
+     *
+     * The GL code below is more logical (imho), and the difference with
+     * HWC is due to a limitation of the HWC API to integers -- a question
+     * is suspend is whether we should ignore this problem or revert to
+     * GL composition when a buffer scaling is applied (maybe with some
+     * minimal value)? Or, we could make GL behave like HWC -- but this feel
+     * like more of a hack.
+     */
+    Rect win(computeBounds());
+
+    Transform t = getTransform();
+    if (!s.finalCrop.isEmpty()) {
+        win = t.transform(win);
+        if (!win.intersect(s.finalCrop, &win)) {
+            win.clear();
+        }
+        win = t.inverse().transform(win);
+        if (!win.intersect(computeBounds(), &win)) {
+            win.clear();
+        }
+    }
+
+    float left = float(win.left) / float(s.active.w);
+    float top = float(win.top) / float(s.active.h);
+    float right = float(win.right) / float(s.active.w);
+    float bottom = float(win.bottom) / float(s.active.h);
+
+    // TODO: we probably want to generate the texture coords with the mesh
+    // here we assume that we only have 4 vertices
+    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
+    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);
+
+    RenderEngine& engine(mFlinger->getRenderEngine());
+    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), false /* disableTexture */,
+                              getColor());
+#ifdef USE_HWC2
+    engine.setSourceDataSpace(mCurrentState.dataSpace);
+#endif
+    engine.drawMesh(mMesh);
+    engine.disableBlending();
+}
+
+uint32_t BufferLayer::getProducerStickyTransform() const {
+    int producerStickyTransform = 0;
+    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
+    if (ret != OK) {
+        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
+              strerror(-ret), ret);
+        return 0;
+    }
+    return static_cast<uint32_t>(producerStickyTransform);
+}
+
+bool BufferLayer::latchUnsignaledBuffers() {
+    static bool propertyLoaded = false;
+    static bool latch = false;
+    static std::mutex mutex;
+    std::lock_guard<std::mutex> lock(mutex);
+    if (!propertyLoaded) {
+        char value[PROPERTY_VALUE_MAX] = {};
+        property_get("debug.sf.latch_unsignaled", value, "0");
+        latch = atoi(value);
+        propertyLoaded = true;
+    }
+    return latch;
+}
+
+uint64_t BufferLayer::getHeadFrameNumber() const {
+    Mutex::Autolock lock(mQueueItemLock);
+    if (!mQueueItems.empty()) {
+        return mQueueItems[0].mFrameNumber;
+    } else {
+        return mCurrentFrameNumber;
+    }
+}
+
+bool BufferLayer::headFenceHasSignaled() const {
+#ifdef USE_HWC2
+    if (latchUnsignaledBuffers()) {
+        return true;
+    }
+
+    Mutex::Autolock lock(mQueueItemLock);
+    if (mQueueItems.empty()) {
+        return true;
+    }
+    if (mQueueItems[0].mIsDroppable) {
+        // Even though this buffer's fence may not have signaled yet, it could
+        // be replaced by another buffer before it has a chance to, which means
+        // that it's possible to get into a situation where a buffer is never
+        // able to be latched. To avoid this, grab this buffer anyway.
+        return true;
+    }
+    return mQueueItems[0].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
+#else
+    return true;
+#endif
+}
+
+uint32_t BufferLayer::getEffectiveScalingMode() const {
+    if (mOverrideScalingMode >= 0) {
+        return mOverrideScalingMode;
+    }
+    return mCurrentScalingMode;
+}
+
+// ----------------------------------------------------------------------------
+// transaction
+// ----------------------------------------------------------------------------
+
+void BufferLayer::notifyAvailableFrames() {
+    auto headFrameNumber = getHeadFrameNumber();
+    bool headFenceSignaled = headFenceHasSignaled();
+    Mutex::Autolock lock(mLocalSyncPointMutex);
+    for (auto& point : mLocalSyncPoints) {
+        if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled) {
+            point->setFrameAvailable();
+        }
+    }
+}
+
+sp<IGraphicBufferProducer> BufferLayer::getProducer() const {
+    return mProducer;
+}
+
+// ---------------------------------------------------------------------------
+// h/w composer set-up
+// ---------------------------------------------------------------------------
+
+bool BufferLayer::allTransactionsSignaled() {
+    auto headFrameNumber = getHeadFrameNumber();
+    bool matchingFramesFound = false;
+    bool allTransactionsApplied = true;
+    Mutex::Autolock lock(mLocalSyncPointMutex);
+
+    for (auto& point : mLocalSyncPoints) {
+        if (point->getFrameNumber() > headFrameNumber) {
+            break;
+        }
+        matchingFramesFound = true;
+
+        if (!point->frameIsAvailable()) {
+            // We haven't notified the remote layer that the frame for
+            // this point is available yet. Notify it now, and then
+            // abort this attempt to latch.
+            point->setFrameAvailable();
+            allTransactionsApplied = false;
+            break;
+        }
+
+        allTransactionsApplied = allTransactionsApplied && point->transactionIsApplied();
+    }
+    return !matchingFramesFound || allTransactionsApplied;
+}
+
+} // namespace android
+
+#if defined(__gl_h_)
+#error "don't include gl/gl.h in this file"
+#endif
+
+#if defined(__gl2_h_)
+#error "don't include gl2/gl2.h in this file"
+#endif
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
new file mode 100644
index 0000000..418f032
--- /dev/null
+++ b/services/surfaceflinger/BufferLayer.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Client.h"
+#include "Layer.h"
+#include "DisplayHardware/HWComposer.h"
+#include "DisplayHardware/HWComposerBufferCache.h"
+#include "FrameTracker.h"
+#include "LayerVector.h"
+#include "MonitoredProducer.h"
+#include "RenderEngine/Mesh.h"
+#include "RenderEngine/Texture.h"
+#include "SurfaceFlinger.h"
+#include "SurfaceFlingerConsumer.h"
+#include "Transform.h"
+
+#include <gui/ISurfaceComposerClient.h>
+#include <gui/LayerState.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <ui/FrameStats.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
+#include <ui/Region.h>
+
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <utils/Timers.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <list>
+
+namespace android {
+
+/*
+ * A new BufferQueue and a new SurfaceFlingerConsumer are created when the
+ * BufferLayer is first referenced.
+ *
+ * This also implements onFrameAvailable(), which notifies SurfaceFlinger
+ * that new data has arrived.
+ */
+class BufferLayer : public Layer, public SurfaceFlingerConsumer::ContentsChangedListener {
+public:
+    BufferLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w,
+                uint32_t h, uint32_t flags);
+
+    ~BufferLayer() override;
+
+    // If we have received a new buffer this frame, we will pass its surface
+    // damage down to hardware composer. Otherwise, we must send a region with
+    // one empty rect.
+    void useSurfaceDamage();
+    void useEmptyDamage();
+
+    // -----------------------------------------------------------------------
+    // Overriden from Layer
+    // -----------------------------------------------------------------------
+
+    /*
+     * getTypeId - Provide unique string for each class type in the Layer
+     * hierarchy
+     */
+    const char* getTypeId() const override { return "BufferLayer"; }
+
+    /*
+     * isProtected - true if the layer may contain protected content in the
+     * GRALLOC_USAGE_PROTECTED sense.
+     */
+    bool isProtected() const;
+
+    /*
+     * isVisible - true if this layer is visible, false otherwise
+     */
+    bool isVisible() const override;
+
+    /*
+     * isFixedSize - true if content has a fixed size
+     */
+    bool isFixedSize() const override;
+
+    // the this layer's size and format
+    status_t setBuffers(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
+
+    /*
+     * onDraw - draws the surface.
+     */
+    void onDraw(const RenderArea& renderArea, const Region& clip,
+                bool useIdentityTransform) const override;
+
+#ifdef USE_HWC2
+    void onLayerDisplayed(const sp<Fence>& releaseFence) override;
+#else
+    void onLayerDisplayed(const sp<const DisplayDevice>& hw,
+                          HWComposer::HWCLayerInterface* layer) override;
+#endif
+
+    void abandon() override;
+    bool shouldPresentNow(const DispSync& dispSync) const override;
+    void setTransformHint(uint32_t orientation) const override;
+    bool onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
+                           const std::shared_ptr<FenceTime>& presentFence,
+                           const CompositorTiming& compositorTiming) override;
+    std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush) override;
+    bool getTransformToDisplayInverse() const override;
+
+public:
+    bool onPreComposition(nsecs_t refreshStartTime) override;
+
+#ifdef USE_HWC2
+    // If a buffer was replaced this frame, release the former buffer
+    void releasePendingBuffer(nsecs_t dequeueReadyTime);
+#endif
+
+    /*
+     * latchBuffer - called each time the screen is redrawn and returns whether
+     * the visible regions need to be recomputed (this is a fairly heavy
+     * 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.
+     */
+    Region latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) override;
+    bool isBufferLatched() const override { return mRefreshPending; }
+    void setDefaultBufferSize(uint32_t w, uint32_t h) override;
+
+#ifdef USE_HWC2
+    void setPerFrameData(const sp<const DisplayDevice>& displayDevice) override;
+#else
+    void setAcquireFence(const sp<const DisplayDevice>& hw,
+                         HWComposer::HWCLayerInterface& layer) override;
+#endif
+
+    bool isOpaque(const Layer::State& s) const override;
+
+private:
+    void onFirstRef() override;
+
+    // Interface implementation for
+    // SurfaceFlingerConsumer::ContentsChangedListener
+    void onFrameAvailable(const BufferItem& item) override;
+    void onFrameReplaced(const BufferItem& item) override;
+    void onSidebandStreamChanged() override;
+
+    // needsLinearFiltering - true if this surface's state requires filtering
+    bool needsFiltering(const RenderArea& renderArea) const;
+
+    static bool getOpacityForFormat(uint32_t format);
+
+    // drawing
+    void drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const;
+
+    // Temporary - Used only for LEGACY camera mode.
+    uint32_t getProducerStickyTransform() const;
+
+    // Loads the corresponding system property once per process
+    static bool latchUnsignaledBuffers();
+
+    uint64_t getHeadFrameNumber() const;
+    bool headFenceHasSignaled() const;
+
+    // Returns the current scaling mode, unless mOverrideScalingMode
+    // is set, in which case, it returns mOverrideScalingMode
+    uint32_t getEffectiveScalingMode() const override;
+
+public:
+    void notifyAvailableFrames() override;
+
+    PixelFormat getPixelFormat() const override { return mFormat; }
+    sp<IGraphicBufferProducer> getProducer() const;
+
+private:
+    sp<SurfaceFlingerConsumer> mSurfaceFlingerConsumer;
+
+    // Check all of the local sync points to ensure that all transactions
+    // which need to have been applied prior to the frame which is about to
+    // be latched have signaled
+    bool allTransactionsSignaled();
+    sp<IGraphicBufferProducer> mProducer;
+
+    // constants
+    uint32_t mTextureName; // from GLES
+    PixelFormat mFormat;
+
+    // main thread
+    uint32_t mCurrentScalingMode;
+    bool mBufferLatched = false;   // TODO: Use mActiveBuffer?
+    uint64_t mPreviousFrameNumber; // Only accessed on the main thread.
+    // The texture used to draw the layer in GLES composition mode
+    mutable Texture mTexture;
+
+    bool mUpdateTexImageFailed; // This is only accessed on the main thread.
+    bool mRefreshPending;
+};
+
+} // namespace android
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index 32526dd..8a17f88 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -18,8 +18,8 @@
 #undef LOG_TAG
 #define LOG_TAG "ColorLayer"
 
-#include <stdlib.h>
 #include <stdint.h>
+#include <stdlib.h>
 #include <sys/types.h>
 
 #include <utils/Errors.h>
@@ -28,27 +28,29 @@
 #include <ui/GraphicBuffer.h>
 
 #include "ColorLayer.h"
-#include "SurfaceFlinger.h"
 #include "DisplayDevice.h"
 #include "RenderEngine/RenderEngine.h"
+#include "SurfaceFlinger.h"
 
 namespace android {
 // ---------------------------------------------------------------------------
 
-ColorLayer::ColorLayer(SurfaceFlinger* flinger, const sp<Client>& client,
-        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
-    : Layer(flinger, client, name, w, h, flags) {
+ColorLayer::ColorLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name,
+                       uint32_t w, uint32_t h, uint32_t flags)
+      : Layer(flinger, client, name, w, h, flags) {
+    // drawing state & current state are identical
+    mDrawingState = mCurrentState;
 }
 
 void ColorLayer::onDraw(const RenderArea& renderArea, const Region& /* clip */,
                         bool useIdentityTransform) const {
     const State& s(getDrawingState());
-    if (s.color.a>0) {
+    if (s.color.a > 0) {
         Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2);
         computeGeometry(renderArea, mesh, useIdentityTransform);
         RenderEngine& engine(mFlinger->getRenderEngine());
         engine.setupLayerBlending(getPremultipledAlpha(), false /* opaque */,
-              true /* disableTexture */, s.color);
+                                  true /* disableTexture */, s.color);
         engine.drawMesh(mesh);
         engine.disableBlending();
     }
@@ -59,6 +61,35 @@
     return !isHiddenByPolicy() && s.color.a;
 }
 
+#ifdef USE_HWC2
+void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
+    const Transform& tr = displayDevice->getTransform();
+    const auto& viewport = displayDevice->getViewport();
+    Region visible = tr.transform(visibleRegion.intersect(viewport));
+    auto hwcId = displayDevice->getHwcDisplayId();
+    auto& hwcInfo = mHwcLayers[hwcId];
+    auto& hwcLayer = hwcInfo.layer;
+    auto error = hwcLayer->setVisibleRegion(visible);
+
+    setCompositionType(hwcId, HWC2::Composition::SolidColor);
+
+    half4 color = getColor();
+    error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
+                                static_cast<uint8_t>(std::round(255.0f * color.g)),
+                                static_cast<uint8_t>(std::round(255.0f * color.b)), 255});
+    if (error != HWC2::Error::None) {
+        ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(),
+              static_cast<int32_t>(error));
+    }
+
+    // Clear out the transform, because it doesn't make sense absent a source buffer
+    error = hwcLayer->setTransform(HWC2::Transform::None);
+    if (error != HWC2::Error::None) {
+        ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), to_string(error).c_str(),
+              static_cast<int32_t>(error));
+    }
+}
+#endif
 
 // ---------------------------------------------------------------------------
 
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index cdf3eca..debd3c3 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -26,20 +26,49 @@
 
 namespace android {
 
-class ColorLayer : public Layer
-{
+class ColorLayer : public Layer {
 public:
-    ColorLayer(SurfaceFlinger* flinger, const sp<Client>& client,
-                        const String8& name, uint32_t w, uint32_t h, uint32_t flags);
+    ColorLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w,
+               uint32_t h, uint32_t flags);
     virtual ~ColorLayer() = default;
 
     virtual const char* getTypeId() const { return "ColorLayer"; }
     virtual void onDraw(const RenderArea& renderArea, const Region& clip,
-            bool useIdentityTransform) const;
+                        bool useIdentityTransform) const;
+    bool isVisible() const override;
     virtual bool isOpaque(const Layer::State&) const { return false; }
-    virtual bool isSecure() const         { return false; }
-    virtual bool isFixedSize() const      { return true; }
-    virtual bool isVisible() const;
+    virtual bool isFixedSize() const { return true; }
+
+    void notifyAvailableFrames() override {}
+    PixelFormat getPixelFormat() const override { return PIXEL_FORMAT_NONE; }
+    uint32_t getEffectiveScalingMode() const override { return 0; }
+#ifdef USE_HWC2
+    void releasePendingBuffer(nsecs_t) override {}
+#endif
+    Region latchBuffer(bool&, nsecs_t) override { return Region(); }
+    void useSurfaceDamage() override {}
+    void useEmptyDamage() override {}
+    bool isBufferLatched() const override { return false; }
+    bool onPreComposition(nsecs_t) override { return true; }
+    void abandon() override {}
+#ifdef USE_HWC2
+    void setPerFrameData(const sp<const DisplayDevice>& displayDevice) override;
+#else
+    void setAcquireFence(const sp<const DisplayDevice>& /*hw*/,
+                         HWComposer::HWCLayerInterface& /*layer*/) override {}
+#endif
+    void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) override {}
+    bool shouldPresentNow(const DispSync& /*dispSync*/) const override { return false; }
+    bool onPostComposition(const std::shared_ptr<FenceTime>& /*glDoneFence*/,
+                           const std::shared_ptr<FenceTime>& /*presentFence*/,
+                           const CompositorTiming& /*compositorTiming*/) override {
+        return false;
+    }
+    void setTransformHint(uint32_t /*orientation*/) const override {}
+    std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool /*forceFlush*/) override {
+        return {};
+    }
+    bool getTransformToDisplayInverse() const override { return false; }
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
old mode 100755
new mode 100644
index 0525607..80987a4
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -19,10 +19,10 @@
 #define LOG_TAG "Layer"
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
 #include <math.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/types.h>
 
 #include <cutils/compiler.h>
 #include <cutils/native_handle.h>
@@ -43,13 +43,13 @@
 #include <gui/LayerDebugInfo.h>
 #include <gui/Surface.h>
 
-#include "clz.h"
 #include "Colorizer.h"
 #include "DisplayDevice.h"
 #include "Layer.h"
 #include "LayerRejecter.h"
 #include "MonitoredProducer.h"
 #include "SurfaceFlinger.h"
+#include "clz.h"
 
 #include "DisplayHardware/HWComposer.h"
 
@@ -58,23 +58,19 @@
 #include <mutex>
 #include "LayerProtoHelper.h"
 
-#define DEBUG_RESIZE    0
+#define DEBUG_RESIZE 0
 
 namespace android {
 
-// ---------------------------------------------------------------------------
-
 int32_t Layer::sSequence = 1;
 
-Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
-        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
-    :   contentDirty(false),
+Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w,
+             uint32_t h, uint32_t flags)
+      : contentDirty(false),
         sequence(uint32_t(android_atomic_inc(&sSequence))),
         mFlinger(flinger),
-        mTextureName(UINT32_MAX),
         mPremultipliedAlpha(true),
-        mName("unnamed"),
-        mFormat(PIXEL_FORMAT_NONE),
+        mName(name),
         mTransactionFlags(0),
         mPendingStateMutex(),
         mPendingStates(),
@@ -82,13 +78,9 @@
         mSidebandStreamChanged(false),
         mActiveBufferSlot(BufferQueue::INVALID_BUFFER_SLOT),
         mCurrentTransform(0),
-        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
         mOverrideScalingMode(-1),
         mCurrentOpacity(true),
-        mBufferLatched(false),
         mCurrentFrameNumber(0),
-        mPreviousFrameNumber(0),
-        mRefreshPending(false),
         mFrameLatencyNeeded(false),
         mFiltering(false),
         mNeedsFiltering(false),
@@ -97,41 +89,28 @@
         mIsGlesComposition(false),
 #endif
         mProtectedByApp(false),
-        mHasSurface(false),
         mClientRef(client),
         mPotentialCursor(false),
         mQueueItemLock(),
         mQueueItemCondition(),
         mQueueItems(),
         mLastFrameNumberReceived(0),
-        mUpdateTexImageFailed(false),
         mAutoRefresh(false),
-        mFreezeGeometryUpdates(false)
-{
-#ifdef USE_HWC2
-    ALOGV("Creating Layer %s", name.string());
-#endif
+        mFreezeGeometryUpdates(false) {
 
     mCurrentCrop.makeInvalid();
-    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
-    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
 
     uint32_t layerFlags = 0;
-    if (flags & ISurfaceComposerClient::eHidden)
-        layerFlags |= layer_state_t::eLayerHidden;
-    if (flags & ISurfaceComposerClient::eOpaque)
-        layerFlags |= layer_state_t::eLayerOpaque;
-    if (flags & ISurfaceComposerClient::eSecure)
-        layerFlags |= layer_state_t::eLayerSecure;
-
-    if (flags & ISurfaceComposerClient::eNonPremultiplied)
-        mPremultipliedAlpha = false;
+    if (flags & ISurfaceComposerClient::eHidden) layerFlags |= layer_state_t::eLayerHidden;
+    if (flags & ISurfaceComposerClient::eOpaque) layerFlags |= layer_state_t::eLayerOpaque;
+    if (flags & ISurfaceComposerClient::eSecure) layerFlags |= layer_state_t::eLayerSecure;
 
     mName = name;
     mTransactionName = String8("TX - ") + mName;
 
     mCurrentState.active.w = w;
     mCurrentState.active.h = h;
+    mCurrentState.flags = layerFlags;
     mCurrentState.active.transform.set(0, 0);
     mCurrentState.crop.makeInvalid();
     mCurrentState.finalCrop.makeInvalid();
@@ -140,7 +119,6 @@
     mCurrentState.z = 0;
     mCurrentState.color.a = 1.0f;
     mCurrentState.layerStack = 0;
-    mCurrentState.flags = layerFlags;
     mCurrentState.sequence = 0;
     mCurrentState.requested = mCurrentState.active;
     mCurrentState.dataSpace = HAL_DATASPACE_UNKNOWN;
@@ -155,8 +133,7 @@
     const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY);
     nsecs_t displayPeriod = activeConfig->getVsyncPeriod();
 #else
-    nsecs_t displayPeriod =
-            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
+    nsecs_t displayPeriod = flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
 #endif
     mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
 
@@ -165,137 +142,33 @@
     mFrameEventHistory.initializeCompositorTiming(compositorTiming);
 }
 
-void Layer::onFirstRef() {
-    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
-    sp<IGraphicBufferProducer> producer;
-    sp<IGraphicBufferConsumer> consumer;
-    BufferQueue::createBufferQueue(&producer, &consumer, true);
-    mProducer = new MonitoredProducer(producer, mFlinger, this);
-    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName, this);
-    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
-    mSurfaceFlingerConsumer->setContentsChangedListener(this);
-    mSurfaceFlingerConsumer->setName(mName);
-
-    if (mFlinger->isLayerTripleBufferingDisabled()) {
-        mProducer->setMaxDequeuedBufferCount(2);
-    }
-
-    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
-    updateTransformHint(hw);
-}
+void Layer::onFirstRef() {}
 
 Layer::~Layer() {
-  sp<Client> c(mClientRef.promote());
-    if (c != 0) {
-        c->detachLayer(this);
-    }
-
-    for (auto& point : mRemoteSyncPoints) {
-        point->setTransactionApplied();
-    }
-    for (auto& point : mLocalSyncPoints) {
-        point->setFrameAvailable();
-    }
-    mFlinger->deleteTextureAsync(mTextureName);
     mFrameTracker.logAndResetStats(mName);
-
-#ifdef USE_HWC2
-    if (!mHwcLayers.empty()) {
-        ALOGE("Found stale hardware composer layers when destroying "
-                "surface flinger layer %s", mName.string());
-        destroyAllHwcLayers();
-    }
-#endif
 }
 
 // ---------------------------------------------------------------------------
 // callbacks
 // ---------------------------------------------------------------------------
 
+/*
+ * onLayerDisplayed is only meaningful for BufferLayer, but, is called through
+ * Layer.  So, the implementation is done in BufferLayer.  When called on a
+ * ColorLayer object, it's essentially a NOP.
+ */
 #ifdef USE_HWC2
-void Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
-    if (mHwcLayers.empty()) {
-        return;
-    }
-    mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
-}
+void Layer::onLayerDisplayed(const sp<Fence>& /*releaseFence*/) {}
 #else
 void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
-        HWComposer::HWCLayerInterface* layer) {
-    if (layer) {
-        layer->onDisplayed();
-        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
-    }
-}
+                             HWComposer::HWCLayerInterface* /*layer*/) {}
 #endif
 
-void Layer::onFrameAvailable(const BufferItem& item) {
-    // Add this buffer from our internal queue tracker
-    { // Autolock scope
-        Mutex::Autolock lock(mQueueItemLock);
-        mFlinger->mInterceptor.saveBufferUpdate(this, item.mGraphicBuffer->getWidth(),
-                item.mGraphicBuffer->getHeight(), item.mFrameNumber);
-        // Reset the frame number tracker when we receive the first buffer after
-        // a frame number reset
-        if (item.mFrameNumber == 1) {
-            mLastFrameNumberReceived = 0;
-        }
-
-        // Ensure that callbacks are handled in order
-        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
-            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
-                    ms2ns(500));
-            if (result != NO_ERROR) {
-                ALOGE("[%s] Timed out waiting on callback", mName.string());
-            }
-        }
-
-        mQueueItems.push_back(item);
-        android_atomic_inc(&mQueuedFrames);
-
-        // Wake up any pending callbacks
-        mLastFrameNumberReceived = item.mFrameNumber;
-        mQueueItemCondition.broadcast();
-    }
-
-    mFlinger->signalLayerUpdate();
-}
-
-void Layer::onFrameReplaced(const BufferItem& item) {
-    { // Autolock scope
-        Mutex::Autolock lock(mQueueItemLock);
-
-        // Ensure that callbacks are handled in order
-        while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
-            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
-                    ms2ns(500));
-            if (result != NO_ERROR) {
-                ALOGE("[%s] Timed out waiting on callback", mName.string());
-            }
-        }
-
-        if (mQueueItems.empty()) {
-            ALOGE("Can't replace a frame on an empty queue");
-            return;
-        }
-        mQueueItems.editItemAt(mQueueItems.size() - 1) = item;
-
-        // Wake up any pending callbacks
-        mLastFrameNumberReceived = item.mFrameNumber;
-        mQueueItemCondition.broadcast();
-    }
-}
-
-void Layer::onSidebandStreamChanged() {
-    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
-        // mSidebandStreamChanged was false
-        mFlinger->signalLayerUpdate();
-    }
-}
-
 void Layer::onRemovedFromCurrentState() {
     // the layer is removed from SF mCurrentState to mLayersPendingRemoval
 
+    mPendingRemoval = true;
+
     if (mCurrentState.zOrderRelativeOf != nullptr) {
         sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
         if (strongRelative != nullptr) {
@@ -312,8 +185,8 @@
 
 void Layer::onRemoved() {
     // the layer is removed from SF mLayersPendingRemoval
+    abandon();
 
-    mSurfaceFlingerConsumer->abandon();
 #ifdef USE_HWC2
     destroyAllHwcLayers();
 #endif
@@ -335,55 +208,18 @@
     return mPremultipliedAlpha;
 }
 
-status_t Layer::setBuffers( uint32_t w, uint32_t h,
-                            PixelFormat format, uint32_t flags)
-{
-    uint32_t const maxSurfaceDims = min(
-            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
-
-    // never allow a surface larger than what our underlying GL implementation
-    // can handle.
-    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
-        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
-        return BAD_VALUE;
-    }
-
-    mFormat = format;
-
-    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
-    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
-    mCurrentOpacity = getOpacityForFormat(format);
-
-    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
-    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
-    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
-
-    return NO_ERROR;
-}
-
 sp<IBinder> Layer::getHandle() {
     Mutex::Autolock _l(mLock);
-
-    LOG_ALWAYS_FATAL_IF(mHasSurface,
-            "Layer::getHandle() has already been called");
-
-    mHasSurface = true;
-
     return new Handle(mFlinger, this);
 }
 
-sp<IGraphicBufferProducer> Layer::getProducer() const {
-    return mProducer;
-}
-
 // ---------------------------------------------------------------------------
 // h/w composer set-up
 // ---------------------------------------------------------------------------
 
 #ifdef USE_HWC2
 bool Layer::createHwcLayer(HWComposer* hwc, int32_t hwcId) {
-    LOG_ALWAYS_FATAL_IF(mHwcLayers.count(hwcId) != 0,
-                "Already have a layer for hwcId %d", hwcId);
+    LOG_ALWAYS_FATAL_IF(mHwcLayers.count(hwcId) != 0, "Already have a layer for hwcId %d", hwcId);
     HWC2::Layer* layer = hwc->createLayer(hwcId);
     if (!layer) {
         return false;
@@ -392,7 +228,7 @@
     hwcInfo.hwc = hwc;
     hwcInfo.layer = layer;
     layer->setLayerDestroyedListener(
-            [this, hwcId] (HWC2::Layer* /*layer*/){mHwcLayers.erase(hwcId);});
+            [this, hwcId](HWC2::Layer* /*layer*/) { mHwcLayers.erase(hwcId); });
     return true;
 }
 
@@ -401,14 +237,12 @@
         return;
     }
     auto& hwcInfo = mHwcLayers[hwcId];
-    LOG_ALWAYS_FATAL_IF(hwcInfo.layer == nullptr,
-            "Attempt to destroy null layer");
+    LOG_ALWAYS_FATAL_IF(hwcInfo.layer == nullptr, "Attempt to destroy null layer");
     LOG_ALWAYS_FATAL_IF(hwcInfo.hwc == nullptr, "Missing HWComposer");
     hwcInfo.hwc->destroyLayer(hwcId, hwcInfo.layer);
     // The layer destroyed listener should have cleared the entry from
     // mHwcLayers. Verify that.
-    LOG_ALWAYS_FATAL_IF(mHwcLayers.count(hwcId) != 0,
-            "Stale layer entry in mHwcLayers");
+    LOG_ALWAYS_FATAL_IF(mHwcLayers.count(hwcId) != 0, "Stale layer entry in mHwcLayers");
 }
 
 void Layer::destroyAllHwcLayers() {
@@ -418,7 +252,7 @@
         destroyHwcLayer(mHwcLayers.begin()->first);
     }
     LOG_ALWAYS_FATAL_IF(!mHwcLayers.empty(),
-            "All hardware composer layers should have been destroyed");
+                        "All hardware composer layers should have been destroyed");
 }
 #endif
 
@@ -542,7 +376,7 @@
         activeCrop.clear();
     }
     if (!s.finalCrop.isEmpty()) {
-        if(!activeCrop.intersect(s.finalCrop, &activeCrop)) {
+        if (!activeCrop.intersect(s.finalCrop, &activeCrop)) {
             activeCrop.clear();
         }
     }
@@ -592,16 +426,13 @@
          * the code below applies the primary display's inverse transform to the
          * buffer
          */
-        uint32_t invTransformOrient =
-                DisplayDevice::getPrimaryDisplayOrientationTransform();
+        uint32_t invTransformOrient = DisplayDevice::getPrimaryDisplayOrientationTransform();
         // calculate the inverse transform
         if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) {
-            invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
-                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
+            invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | NATIVE_WINDOW_TRANSFORM_FLIP_H;
         }
         // and apply to the current transform
-        invTransform = (Transform(invTransformOrient) * Transform(invTransform))
-                .getOrientation();
+        invTransform = (Transform(invTransformOrient) * Transform(invTransform)).getOrientation();
     }
 
     int winWidth = s.active.w;
@@ -615,27 +446,25 @@
         bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0;
         bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0;
         if (is_h_flipped == is_v_flipped) {
-            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
-                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
+            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | NATIVE_WINDOW_TRANSFORM_FLIP_H;
         }
         winWidth = s.active.h;
         winHeight = s.active.w;
     }
-    const Rect winCrop = activeCrop.transform(
-            invTransform, s.active.w, s.active.h);
+    const Rect winCrop = activeCrop.transform(invTransform, s.active.w, s.active.h);
 
     // below, crop is intersected with winCrop expressed in crop's coordinate space
-    float xScale = crop.getWidth()  / float(winWidth);
+    float xScale = crop.getWidth() / float(winWidth);
     float yScale = crop.getHeight() / float(winHeight);
 
-    float insetL = winCrop.left                 * xScale;
-    float insetT = winCrop.top                  * yScale;
-    float insetR = (winWidth - winCrop.right )  * xScale;
+    float insetL = winCrop.left * xScale;
+    float insetT = winCrop.top * yScale;
+    float insetR = (winWidth - winCrop.right) * xScale;
     float insetB = (winHeight - winCrop.bottom) * yScale;
 
-    crop.left   += insetL;
-    crop.top    += insetT;
-    crop.right  -= insetR;
+    crop.left += insetL;
+    crop.top += insetT;
+    crop.right -= insetR;
     crop.bottom -= insetB;
 
     return crop;
@@ -644,9 +473,7 @@
 #ifdef USE_HWC2
 void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice, uint32_t z)
 #else
-void Layer::setGeometry(
-    const sp<const DisplayDevice>& hw,
-        HWComposer::HWCLayerInterface& layer)
+void Layer::setGeometry(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer)
 #endif
 {
 #ifdef USE_HWC2
@@ -678,18 +505,18 @@
 #ifdef USE_HWC2
     auto blendMode = HWC2::BlendMode::None;
     if (!isOpaque(s) || getAlpha() != 1.0f) {
-        blendMode = mPremultipliedAlpha ?
-                HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
+        blendMode =
+                mPremultipliedAlpha ? HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
     }
     auto error = hwcLayer->setBlendMode(blendMode);
-    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set blend mode %s:"
-             " %s (%d)", mName.string(), to_string(blendMode).c_str(),
-             to_string(error).c_str(), static_cast<int32_t>(error));
+    ALOGE_IF(error != HWC2::Error::None,
+             "[%s] Failed to set blend mode %s:"
+             " %s (%d)",
+             mName.string(), to_string(blendMode).c_str(), to_string(error).c_str(),
+             static_cast<int32_t>(error));
 #else
     if (!isOpaque(s) || getAlpha() != 1.0f) {
-        layer.setBlending(mPremultipliedAlpha ?
-                HWC_BLENDING_PREMULT :
-                HWC_BLENDING_COVERAGE);
+        layer.setBlending(mPremultipliedAlpha ? HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE);
     }
 #endif
 
@@ -701,9 +528,9 @@
         Rect activeCrop(s.crop);
         activeCrop = t.transform(activeCrop);
 #ifdef USE_HWC2
-        if(!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) {
+        if (!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) {
 #else
-        if(!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
+        if (!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
 #endif
             activeCrop.clear();
         }
@@ -714,22 +541,20 @@
         // transform.inverse().transform(transform.transform(Rect)) != Rect
         // in which case we need to make sure the final rect is clipped to the
         // display bounds.
-        if(!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
+        if (!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) {
             activeCrop.clear();
         }
         // mark regions outside the crop as transparent
         activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
-        activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
-                s.active.w, s.active.h));
-        activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
-                activeCrop.left, activeCrop.bottom));
-        activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
-                s.active.w, activeCrop.bottom));
+        activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom, s.active.w, s.active.h));
+        activeTransparentRegion.orSelf(Rect(0, activeCrop.top, activeCrop.left, activeCrop.bottom));
+        activeTransparentRegion.orSelf(
+                Rect(activeCrop.right, activeCrop.top, s.active.w, activeCrop.bottom));
     }
 
     Rect frame(t.transform(computeBounds(activeTransparentRegion)));
     if (!s.finalCrop.isEmpty()) {
-        if(!frame.intersect(s.finalCrop, &frame)) {
+        if (!frame.intersect(s.finalCrop, &frame)) {
             frame.clear();
         }
     }
@@ -741,10 +566,9 @@
     Rect transformedFrame = tr.transform(frame);
     error = hwcLayer->setDisplayFrame(transformedFrame);
     if (error != HWC2::Error::None) {
-        ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)",
-                mName.string(), transformedFrame.left, transformedFrame.top,
-                transformedFrame.right, transformedFrame.bottom,
-                to_string(error).c_str(), static_cast<int32_t>(error));
+        ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)", mName.string(),
+              transformedFrame.left, transformedFrame.top, transformedFrame.right,
+              transformedFrame.bottom, to_string(error).c_str(), static_cast<int32_t>(error));
     } else {
         hwcInfo.displayFrame = transformedFrame;
     }
@@ -753,23 +577,23 @@
     error = hwcLayer->setSourceCrop(sourceCrop);
     if (error != HWC2::Error::None) {
         ALOGE("[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: "
-                "%s (%d)", mName.string(), sourceCrop.left, sourceCrop.top,
-                sourceCrop.right, sourceCrop.bottom, to_string(error).c_str(),
-                static_cast<int32_t>(error));
+              "%s (%d)",
+              mName.string(), sourceCrop.left, sourceCrop.top, sourceCrop.right, sourceCrop.bottom,
+              to_string(error).c_str(), static_cast<int32_t>(error));
     } else {
         hwcInfo.sourceCrop = sourceCrop;
     }
 
     float alpha = static_cast<float>(getAlpha());
     error = hwcLayer->setPlaneAlpha(alpha);
-    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
-            "%s (%d)", mName.string(), alpha, to_string(error).c_str(),
-            static_cast<int32_t>(error));
+    ALOGE_IF(error != HWC2::Error::None,
+             "[%s] Failed to set plane alpha %.3f: "
+             "%s (%d)",
+             mName.string(), alpha, to_string(error).c_str(), static_cast<int32_t>(error));
 
     error = hwcLayer->setZOrder(z);
-    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)",
-            mName.string(), z, to_string(error).c_str(),
-            static_cast<int32_t>(error));
+    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)", mName.string(), z,
+             to_string(error).c_str(), static_cast<int32_t>(error));
 
     int type = s.type;
     int appId = s.appId;
@@ -781,8 +605,8 @@
     }
 
     error = hwcLayer->setInfo(type, appId);
-    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set info (%d)",
-             mName.string(), static_cast<int32_t>(error));
+    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set info (%d)", mName.string(),
+             static_cast<int32_t>(error));
 #else
     if (!frame.intersect(hw->getViewport(), &frame)) {
         frame.clear();
@@ -790,7 +614,7 @@
     const Transform& tr(hw->getTransform());
     layer.setFrame(tr.transform(frame));
     layer.setCrop(computeCrop(hw));
-    layer.setPlaneAlpha(static_cast<uint8_t>(std::round(255.0f*getAlpha())));
+    layer.setPlaneAlpha(static_cast<uint8_t>(std::round(255.0f * getAlpha())));
 #endif
 
     /*
@@ -809,12 +633,10 @@
          * the code below applies the primary display's inverse transform to the
          * buffer
          */
-        uint32_t invTransform =
-                DisplayDevice::getPrimaryDisplayOrientationTransform();
+        uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform();
         // calculate the inverse transform
         if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
-            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
-                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
+            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | NATIVE_WINDOW_TRANSFORM_FLIP_H;
         }
 
         /*
@@ -835,9 +657,11 @@
     } else {
         auto transform = static_cast<HWC2::Transform>(orientation);
         auto error = hwcLayer->setTransform(transform);
-        ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: "
-                "%s (%d)", mName.string(), to_string(transform).c_str(),
-                to_string(error).c_str(), static_cast<int32_t>(error));
+        ALOGE_IF(error != HWC2::Error::None,
+                 "[%s] Failed to set transform %s: "
+                 "%s (%d)",
+                 mName.string(), to_string(transform).c_str(), to_string(error).c_str(),
+                 static_cast<int32_t>(error));
     }
 #else
     if (orientation & Transform::ROT_INVALID) {
@@ -858,110 +682,9 @@
 
     mHwcLayers[hwcId].forceClientComposition = true;
 }
-
-void Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
-    // Apply this display's projection's viewport to the visible region
-    // before giving it to the HWC HAL.
-    const Transform& tr = displayDevice->getTransform();
-    const auto& viewport = displayDevice->getViewport();
-    Region visible = tr.transform(visibleRegion.intersect(viewport));
-    auto hwcId = displayDevice->getHwcDisplayId();
-    auto& hwcInfo = mHwcLayers[hwcId];
-    auto& hwcLayer = hwcInfo.layer;
-    auto error = hwcLayer->setVisibleRegion(visible);
-    if (error != HWC2::Error::None) {
-        ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
-                to_string(error).c_str(), static_cast<int32_t>(error));
-        visible.dump(LOG_TAG);
-    }
-
-    error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
-    if (error != HWC2::Error::None) {
-        ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
-                to_string(error).c_str(), static_cast<int32_t>(error));
-        surfaceDamageRegion.dump(LOG_TAG);
-    }
-
-    // Sideband layers
-    if (mSidebandStream.get()) {
-        setCompositionType(hwcId, HWC2::Composition::Sideband);
-        ALOGV("[%s] Requesting Sideband composition", mName.string());
-        error = hwcLayer->setSidebandStream(mSidebandStream->handle());
-        if (error != HWC2::Error::None) {
-            ALOGE("[%s] Failed to set sideband stream %p: %s (%d)",
-                    mName.string(), mSidebandStream->handle(),
-                    to_string(error).c_str(), static_cast<int32_t>(error));
-        }
-        return;
-    }
-
-    // Client layers
-    if (hwcInfo.forceClientComposition ||
-            (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) {
-        ALOGV("[%s] Requesting Client composition", mName.string());
-        setCompositionType(hwcId, HWC2::Composition::Client);
-        return;
-    }
-
-    // SolidColor layers
-    if (mActiveBuffer == nullptr) {
-        setCompositionType(hwcId, HWC2::Composition::SolidColor);
-
-        half4 color = getColor();
-        error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f*color.r)),
-                    static_cast<uint8_t>(std::round(255.0f * color.g)),
-                    static_cast<uint8_t>(std::round(255.0f * color.b)),
-                    255});
-        if (error != HWC2::Error::None) {
-            ALOGE("[%s] Failed to set color: %s (%d)", mName.string(),
-                    to_string(error).c_str(), static_cast<int32_t>(error));
-        }
-
-        // Clear out the transform, because it doesn't make sense absent a
-        // source buffer
-        error = hwcLayer->setTransform(HWC2::Transform::None);
-        if (error != HWC2::Error::None) {
-            ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(),
-                    to_string(error).c_str(), static_cast<int32_t>(error));
-        }
-
-        return;
-    }
-
-    // Device or Cursor layers
-    if (mPotentialCursor) {
-        ALOGV("[%s] Requesting Cursor composition", mName.string());
-        setCompositionType(hwcId, HWC2::Composition::Cursor);
-    } else {
-        ALOGV("[%s] Requesting Device composition", mName.string());
-        setCompositionType(hwcId, HWC2::Composition::Device);
-    }
-
-    ALOGV("setPerFrameData: dataspace = %d", mCurrentState.dataSpace);
-    error = hwcLayer->setDataspace(mCurrentState.dataSpace);
-    if (error != HWC2::Error::None) {
-        ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(),
-              mCurrentState.dataSpace, to_string(error).c_str(),
-              static_cast<int32_t>(error));
-    }
-
-    uint32_t hwcSlot = 0;
-    sp<GraphicBuffer> hwcBuffer;
-    hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer,
-            &hwcSlot, &hwcBuffer);
-
-    auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
-    error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
-    if (error != HWC2::Error::None) {
-        ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
-                mActiveBuffer->handle, to_string(error).c_str(),
-                static_cast<int32_t>(error));
-    }
-}
-
 #else
 void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
-        HWComposer::HWCLayerInterface& layer) {
+                                  HWComposer::HWCLayerInterface& layer) {
     // we have to set the visible region on every frame because
     // we currently free it during onLayerDisplayed(), which is called
     // after HWComposer::commit() -- every frame.
@@ -983,11 +706,11 @@
 }
 #endif
 
+
 #ifdef USE_HWC2
 void Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
     auto hwcId = displayDevice->getHwcDisplayId();
-    if (mHwcLayers.count(hwcId) == 0 ||
-            getCompositionType(hwcId) != HWC2::Composition::Cursor) {
+    if (mHwcLayers.count(hwcId) == 0 || getCompositionType(hwcId) != HWC2::Composition::Cursor) {
         return;
     }
 
@@ -1010,36 +733,15 @@
     auto& displayTransform(displayDevice->getTransform());
     auto position = displayTransform.transform(frame);
 
-    auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left,
-            position.top);
-    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position "
-            "to (%d, %d): %s (%d)", mName.string(), position.left,
-            position.top, to_string(error).c_str(),
-            static_cast<int32_t>(error));
+    auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left, position.top);
+    ALOGE_IF(error != HWC2::Error::None,
+             "[%s] Failed to set cursor position "
+             "to (%d, %d): %s (%d)",
+             mName.string(), position.left, position.top, to_string(error).c_str(),
+             static_cast<int32_t>(error));
 }
 #else
-void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
-        HWComposer::HWCLayerInterface& layer) {
-    int fenceFd = -1;
-
-    // TODO: there is a possible optimization here: we only need to set the
-    // acquire fence the first time a new buffer is acquired on EACH display.
-
-    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
-        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
-        if (fence->isValid()) {
-            fenceFd = fence->dup();
-            if (fenceFd == -1) {
-                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
-            }
-        }
-    }
-    layer.setAcquireFenceFd(fenceFd);
-}
-
-Rect Layer::getPosition(
-    const sp<const DisplayDevice>& hw)
-{
+Rect Layer::getPosition(const sp<const DisplayDevice>& hw) {
     // this gives us only the "orientation" component of the transform
     const State& s(getCurrentState());
 
@@ -1077,129 +779,8 @@
     onDraw(renderArea, Region(renderArea.getBounds()), false);
 }
 
-static constexpr mat4 inverseOrientation(uint32_t transform) {
-    const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
-    const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
-    const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
-    mat4 tr;
-
-    if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
-        tr = tr * rot90;
-    }
-    if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
-        tr = tr * flipH;
-    }
-    if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
-        tr = tr * flipV;
-    }
-    return inverse(tr);
-}
-
-/*
- * onDraw will draw the current layer onto the presentable buffer
- */
-void Layer::onDraw(const RenderArea& renderArea, const Region& clip,
-        bool useIdentityTransform) const
-{
-    ATRACE_CALL();
-
-    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
-        // SurfaceView because the WindowManager can't know when the client
-        // has drawn the first time.
-
-        // If there is nothing under us, we paint the screen in black, otherwise
-        // we just skip this update.
-
-        // figure out if there is something below us
-        Region under;
-        bool finished = false;
-        mFlinger->mDrawingState.traverseInZOrder([&](Layer* layer) {
-            if (finished || layer == static_cast<Layer const*>(this)) {
-                finished = true;
-                return;
-            }
-            under.orSelf(renderArea.getTransform().transform(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);
-        }
-        return;
-    }
-
-    // Bind the current buffer to the GL texture, and wait for it to be
-    // ready for us to draw into.
-    status_t err = mSurfaceFlingerConsumer->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());
-
-    RenderEngine& engine(mFlinger->getRenderEngine());
-
-    if (!blackOutLayer) {
-        // TODO: we could be more subtle with isFixedSize()
-        const bool useFiltering = getFiltering() || needsFiltering(renderArea) || isFixedSize();
-
-        // Query the texture matrix given our current filtering mode.
-        float textureMatrix[16];
-        mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
-        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
-
-        if (getTransformToDisplayInverse()) {
-
-            /*
-             * the code below applies the primary display's inverse transform to
-             * the texture transform
-             */
-            uint32_t transform =
-                    DisplayDevice::getPrimaryDisplayOrientationTransform();
-            mat4 tr = inverseOrientation(transform);
-
-            /**
-             * TODO(b/36727915): This is basically a hack.
-             *
-             * Ensure that regardless of the parent transformation,
-             * this buffer is always transformed from native display
-             * orientation to display orientation. For example, in the case
-             * of a camera where the buffer remains in native orientation,
-             * we want the pixels to always be upright.
-             */
-            sp<Layer> p = mDrawingParent.promote();
-            if (p != nullptr) {
-                const auto parentTransform = p->getTransform();
-                tr = tr * inverseOrientation(parentTransform.getOrientation());
-            }
-
-            // and finally apply it to the original texture matrix
-            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
-            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
-        }
-
-        // Set things up for texturing.
-        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
-        mTexture.setFiltering(useFiltering);
-        mTexture.setMatrix(textureMatrix);
-
-        engine.setupLayerTexturing(mTexture);
-    } else {
-        engine.setupLayerBlackedOut();
-    }
-    drawWithOpenGL(renderArea, useIdentityTransform);
-    engine.disableTexturing();
-}
-
-
-void Layer::clearWithOpenGL(const RenderArea& renderArea,
-        float red, float green, float blue,
-        float alpha) const
-{
+void Layer::clearWithOpenGL(const RenderArea& renderArea, float red, float green, float blue,
+                            float alpha) const {
     RenderEngine& engine(mFlinger->getRenderEngine());
     computeGeometry(renderArea, mMesh, false);
     engine.setupFillWithColor(red, green, blue, alpha);
@@ -1207,85 +788,29 @@
 }
 
 void Layer::clearWithOpenGL(const RenderArea& renderArea) const {
-    clearWithOpenGL(renderArea, 0,0,0,0);
-}
-
-void Layer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const {
-    const State& s(getDrawingState());
-
-    computeGeometry(renderArea, mMesh, useIdentityTransform);
-
-    /*
-     * NOTE: the way we compute the texture coordinates here produces
-     * different results than when we take the HWC path -- in the later case
-     * the "source crop" is rounded to texel boundaries.
-     * This can produce significantly different results when the texture
-     * is scaled by a large amount.
-     *
-     * The GL code below is more logical (imho), and the difference with
-     * HWC is due to a limitation of the HWC API to integers -- a question
-     * is suspend is whether we should ignore this problem or revert to
-     * GL composition when a buffer scaling is applied (maybe with some
-     * minimal value)? Or, we could make GL behave like HWC -- but this feel
-     * like more of a hack.
-     */
-    Rect win(computeBounds());
-
-    Transform t = getTransform();
-    if (!s.finalCrop.isEmpty()) {
-        win = t.transform(win);
-        if (!win.intersect(s.finalCrop, &win)) {
-            win.clear();
-        }
-        win = t.inverse().transform(win);
-        if (!win.intersect(computeBounds(), &win)) {
-            win.clear();
-        }
-    }
-
-    float left   = float(win.left)   / float(s.active.w);
-    float top    = float(win.top)    / float(s.active.h);
-    float right  = float(win.right)  / float(s.active.w);
-    float bottom = float(win.bottom) / float(s.active.h);
-
-    // TODO: we probably want to generate the texture coords with the mesh
-    // here we assume that we only have 4 vertices
-    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
-    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);
-
-    RenderEngine& engine(mFlinger->getRenderEngine());
-    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s),
-        false /* disableTexture */, getColor());
-#ifdef USE_HWC2
-    engine.setSourceDataSpace(mCurrentState.dataSpace);
-#endif
-    engine.drawMesh(mMesh);
-    engine.disableBlending();
+    clearWithOpenGL(renderArea, 0, 0, 0, 0);
 }
 
 #ifdef USE_HWC2
-void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type,
-        bool callIntoHwc) {
+void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type, bool callIntoHwc) {
     if (mHwcLayers.count(hwcId) == 0) {
         ALOGE("setCompositionType called without a valid HWC layer");
         return;
     }
     auto& hwcInfo = mHwcLayers[hwcId];
     auto& hwcLayer = hwcInfo.layer;
-    ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(),
-            to_string(type).c_str(), static_cast<int>(callIntoHwc));
+    ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(), to_string(type).c_str(),
+          static_cast<int>(callIntoHwc));
     if (hwcInfo.compositionType != type) {
         ALOGV("    actually setting");
         hwcInfo.compositionType = type;
         if (callIntoHwc) {
             auto error = hwcLayer->setCompositionType(type);
-            ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set "
-                    "composition type %s: %s (%d)", mName.string(),
-                    to_string(type).c_str(), to_string(error).c_str(),
-                    static_cast<int32_t>(error));
+            ALOGE_IF(error != HWC2::Error::None,
+                     "[%s] Failed to set "
+                     "composition type %s: %s (%d)",
+                     mName.string(), to_string(type).c_str(), to_string(error).c_str(),
+                     static_cast<int32_t>(error));
         }
     }
 }
@@ -1320,64 +845,6 @@
 }
 #endif
 
-uint32_t Layer::getProducerStickyTransform() const {
-    int producerStickyTransform = 0;
-    int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
-    if (ret != OK) {
-        ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
-                strerror(-ret), ret);
-        return 0;
-    }
-    return static_cast<uint32_t>(producerStickyTransform);
-}
-
-bool Layer::latchUnsignaledBuffers() {
-    static bool propertyLoaded = false;
-    static bool latch = false;
-    static std::mutex mutex;
-    std::lock_guard<std::mutex> lock(mutex);
-    if (!propertyLoaded) {
-        char value[PROPERTY_VALUE_MAX] = {};
-        property_get("debug.sf.latch_unsignaled", value, "0");
-        latch = atoi(value);
-        propertyLoaded = true;
-    }
-    return latch;
-}
-
-uint64_t Layer::getHeadFrameNumber() const {
-    Mutex::Autolock lock(mQueueItemLock);
-    if (!mQueueItems.empty()) {
-        return mQueueItems[0].mFrameNumber;
-    } else {
-        return mCurrentFrameNumber;
-    }
-}
-
-bool Layer::headFenceHasSignaled() const {
-#ifdef USE_HWC2
-    if (latchUnsignaledBuffers()) {
-        return true;
-    }
-
-    Mutex::Autolock lock(mQueueItemLock);
-    if (mQueueItems.empty()) {
-        return true;
-    }
-    if (mQueueItems[0].mIsDroppable) {
-        // Even though this buffer's fence may not have signaled yet, it could
-        // be replaced by another buffer before it has a chance to, which means
-        // that it's possible to get into a situation where a buffer is never
-        // able to be latched. To avoid this, grab this buffer anyway.
-        return true;
-    }
-    return mQueueItems[0].mFenceTime->getSignalTime() !=
-            Fence::SIGNAL_TIME_PENDING;
-#else
-    return true;
-#endif
-}
-
 bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
     if (point->getFrameNumber() <= mCurrentFrameNumber) {
         // Don't bother with a SyncPoint, since we've already latched the
@@ -1398,28 +865,6 @@
     return mFiltering;
 }
 
-// As documented in libhardware header, formats in the range
-// 0x100 - 0x1FF are specific to the HAL implementation, and
-// are known to have no alpha channel
-// TODO: move definition for device-specific range into
-// hardware.h, instead of using hard-coded values here.
-#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
-
-bool Layer::getOpacityForFormat(uint32_t format) {
-    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
-        return true;
-    }
-    switch (format) {
-        case HAL_PIXEL_FORMAT_RGBA_8888:
-        case HAL_PIXEL_FORMAT_BGRA_8888:
-        case HAL_PIXEL_FORMAT_RGBA_FP16:
-        case HAL_PIXEL_FORMAT_RGBA_1010102:
-            return false;
-    }
-    // in all other case, we have no blending (also for unknown formats)
-    return true;
-}
-
 // ----------------------------------------------------------------------------
 // local state
 // ----------------------------------------------------------------------------
@@ -1471,49 +916,16 @@
     position[1] = renderAreaTransform.transform(lb);
     position[2] = renderAreaTransform.transform(rb);
     position[3] = renderAreaTransform.transform(rt);
-    for (size_t i=0 ; i<4 ; i++) {
+    for (size_t i = 0; i < 4; i++) {
         position[i].y = height - position[i].y;
     }
 }
 
-bool Layer::isOpaque(const Layer::State& s) const
-{
-    // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the
-    // layer's opaque flag.
-    if ((mSidebandStream == nullptr) && (mActiveBuffer == nullptr)) {
-        return false;
-    }
-
-    // if the layer has the opaque flag, then we're always opaque,
-    // otherwise we use the current buffer's format.
-    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
-}
-
-bool Layer::isSecure() const
-{
+bool Layer::isSecure() const {
     const Layer::State& s(mDrawingState);
     return (s.flags & layer_state_t::eLayerSecure);
 }
 
-bool Layer::isProtected() const
-{
-    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
-    return (activeBuffer != 0) &&
-            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
-}
-
-bool Layer::isFixedSize() const {
-    return getEffectiveScalingMode() != NATIVE_WINDOW_SCALING_MODE_FREEZE;
-}
-
-bool Layer::isCropped() const {
-    return !mCurrentCrop.isEmpty();
-}
-
-bool Layer::needsFiltering(const RenderArea& renderArea) const {
-    return mNeedsFiltering || renderArea.needsFiltering();
-}
-
 void Layer::setVisibleRegion(const Region& visibleRegion) {
     // always called from main thread
     this->visibleRegion = visibleRegion;
@@ -1524,8 +936,7 @@
     this->coveredRegion = coveredRegion;
 }
 
-void Layer::setVisibleNonTransparentRegion(const Region&
-        setVisibleNonTransparentRegion) {
+void Layer::setVisibleNonTransparentRegion(const Region& setVisibleNonTransparentRegion) {
     // always called from main thread
     this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
 }
@@ -1550,8 +961,7 @@
             // to be applied as per normal (no synchronization).
             mCurrentState.barrierLayer = nullptr;
         } else {
-            auto syncPoint = std::make_shared<SyncPoint>(
-                    mCurrentState.frameNumber);
+            auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber);
             if (barrierLayer->addSyncPoint(syncPoint)) {
                 mRemoteSyncPoints.push_back(std::move(syncPoint));
             } else {
@@ -1572,8 +982,8 @@
 void Layer::popPendingState(State* stateToCommit) {
     auto oldFlags = stateToCommit->flags;
     *stateToCommit = mPendingStates[0];
-    stateToCommit->flags = (oldFlags & ~stateToCommit->mask) |
-            (stateToCommit->flags & stateToCommit->mask);
+    stateToCommit->flags =
+            (oldFlags & ~stateToCommit->mask) | (stateToCommit->flags & stateToCommit->mask);
 
     mPendingStates.removeAt(0);
     ATRACE_INT(mTransactionName.string(), mPendingStates.size());
@@ -1593,10 +1003,8 @@
                 continue;
             }
 
-            if (mRemoteSyncPoints.front()->getFrameNumber() !=
-                    mPendingStates[0].frameNumber) {
-                ALOGE("[%s] Unexpected sync point frame number found",
-                        mName.string());
+            if (mRemoteSyncPoints.front()->getFrameNumber() != mPendingStates[0].frameNumber) {
+                ALOGE("[%s] Unexpected sync point frame number found", mName.string());
 
                 // Signal our end of the sync point and then dispose of it
                 mRemoteSyncPoints.front()->setTransactionApplied();
@@ -1632,17 +1040,6 @@
     return stateUpdateAvailable;
 }
 
-void Layer::notifyAvailableFrames() {
-    auto headFrameNumber = getHeadFrameNumber();
-    bool headFenceSignaled = headFenceHasSignaled();
-    Mutex::Autolock lock(mLocalSyncPointMutex);
-    for (auto& point : mLocalSyncPoints) {
-        if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled) {
-            point->setFrameAvailable();
-        }
-    }
-}
-
 uint32_t Layer::doTransaction(uint32_t flags) {
     ATRACE_CALL();
 
@@ -1654,40 +1051,25 @@
 
     const Layer::State& s(getDrawingState());
 
-    const bool sizeChanged = (c.requested.w != s.requested.w) ||
-                             (c.requested.h != s.requested.h);
+    const bool sizeChanged = (c.requested.w != s.requested.w) || (c.requested.h != s.requested.h);
 
     if (sizeChanged) {
         // the size changed, we need to ask our client to request a new buffer
         ALOGD_IF(DEBUG_RESIZE,
-                "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
-                "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
-                "            requested={ wh={%4u,%4u} }}\n"
-                "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
-                "            requested={ wh={%4u,%4u} }}\n",
-                this, getName().string(), mCurrentTransform,
-                getEffectiveScalingMode(),
-                c.active.w, c.active.h,
-                c.crop.left,
-                c.crop.top,
-                c.crop.right,
-                c.crop.bottom,
-                c.crop.getWidth(),
-                c.crop.getHeight(),
-                c.requested.w, c.requested.h,
-                s.active.w, s.active.h,
-                s.crop.left,
-                s.crop.top,
-                s.crop.right,
-                s.crop.bottom,
-                s.crop.getWidth(),
-                s.crop.getHeight(),
-                s.requested.w, s.requested.h);
+                 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
+                 "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
+                 "            requested={ wh={%4u,%4u} }}\n"
+                 "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
+                 "            requested={ wh={%4u,%4u} }}\n",
+                 this, getName().string(), mCurrentTransform, getEffectiveScalingMode(), c.active.w,
+                 c.active.h, c.crop.left, c.crop.top, c.crop.right, c.crop.bottom,
+                 c.crop.getWidth(), c.crop.getHeight(), c.requested.w, c.requested.h, s.active.w,
+                 s.active.h, s.crop.left, s.crop.top, s.crop.right, s.crop.bottom,
+                 s.crop.getWidth(), s.crop.getHeight(), s.requested.w, s.requested.h);
 
         // record the new size, form this point on, when the client request
         // a buffer, it'll get the new size.
-        mSurfaceFlingerConsumer->setDefaultBufferSize(
-                c.requested.w, c.requested.h);
+        setDefaultBufferSize(c.requested.w, c.requested.h);
     }
 
     // Don't let Layer::doTransaction update the drawing state
@@ -1708,8 +1090,8 @@
     // resizePending state is to avoid applying the state of the new buffer
     // to the old buffer. However in the state where we don't have an old buffer
     // there is no such concern but we may still be being used as a parent layer.
-    const bool resizePending = ((c.requested.w != c.active.w) ||
-            (c.requested.h != c.active.h)) && (mActiveBuffer != nullptr);
+    const bool resizePending = ((c.requested.w != c.active.w) || (c.requested.h != c.active.h)) &&
+            (mActiveBuffer != nullptr);
     if (!isFixedSize()) {
         if (resizePending && mSidebandStream == NULL) {
             flags |= eDontUpdateGeometryState;
@@ -1758,8 +1140,7 @@
 
         // we may use linear filtering, if the matrix scales us
         const uint8_t type = c.active.transform.getType();
-        mNeedsFiltering = (!c.active.transform.preserveRects() ||
-                (type >= Transform::SCALE));
+        mNeedsFiltering = (!c.active.transform.preserveRects() || (type >= Transform::SCALE));
     }
 
     // If the layer is hidden, signal and clear out all local sync points so
@@ -1822,8 +1203,7 @@
 }
 
 bool Layer::setLayer(int32_t z) {
-    if (mCurrentState.z == z)
-        return false;
+    if (mCurrentState.z == z) return false;
     mCurrentState.sequence++;
     mCurrentState.z = z;
     mCurrentState.modified = true;
@@ -1881,8 +1261,7 @@
 }
 
 bool Layer::setSize(uint32_t w, uint32_t h) {
-    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
-        return false;
+    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h) return false;
     mCurrentState.requested.w = w;
     mCurrentState.requested.h = h;
     mCurrentState.modified = true;
@@ -1890,8 +1269,7 @@
     return true;
 }
 bool Layer::setAlpha(float alpha) {
-    if (mCurrentState.color.a == alpha)
-        return false;
+    if (mCurrentState.color.a == alpha) return false;
     mCurrentState.sequence++;
     mCurrentState.color.a = alpha;
     mCurrentState.modified = true;
@@ -1900,8 +1278,8 @@
 }
 
 bool Layer::setColor(const half3& color) {
-    if (color.r == mCurrentState.color.r && color.g == mCurrentState.color.g
-        && color.b == mCurrentState.color.b)
+    if (color.r == mCurrentState.color.r && color.g == mCurrentState.color.g &&
+        color.b == mCurrentState.color.b)
         return false;
 
     mCurrentState.sequence++;
@@ -1915,8 +1293,7 @@
 
 bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
     mCurrentState.sequence++;
-    mCurrentState.requested.transform.set(
-            matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
+    mCurrentState.requested.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
     mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
@@ -1929,8 +1306,7 @@
 }
 bool Layer::setFlags(uint8_t flags, uint8_t mask) {
     const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
-    if (mCurrentState.flags == newFlags)
-        return false;
+    if (mCurrentState.flags == newFlags) return false;
     mCurrentState.sequence++;
     mCurrentState.flags = newFlags;
     mCurrentState.mask = mask;
@@ -1940,8 +1316,7 @@
 }
 
 bool Layer::setCrop(const Rect& crop, bool immediate) {
-    if (mCurrentState.requestedCrop == crop)
-        return false;
+    if (mCurrentState.requestedCrop == crop) return false;
     mCurrentState.sequence++;
     mCurrentState.requestedCrop = crop;
     if (immediate && !mFreezeGeometryUpdates) {
@@ -1955,8 +1330,7 @@
 }
 
 bool Layer::setFinalCrop(const Rect& crop, bool immediate) {
-    if (mCurrentState.requestedFinalCrop == crop)
-        return false;
+    if (mCurrentState.requestedFinalCrop == crop) return false;
     mCurrentState.sequence++;
     mCurrentState.requestedFinalCrop = crop;
     if (immediate && !mFreezeGeometryUpdates) {
@@ -1970,30 +1344,21 @@
 }
 
 bool Layer::setOverrideScalingMode(int32_t scalingMode) {
-    if (scalingMode == mOverrideScalingMode)
-        return false;
+    if (scalingMode == mOverrideScalingMode) return false;
     mOverrideScalingMode = scalingMode;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 void Layer::setInfo(uint32_t type, uint32_t appId) {
-  mCurrentState.appId = appId;
-  mCurrentState.type = type;
-  mCurrentState.modified = true;
-  setTransactionFlags(eTransactionNeeded);
-}
-
-uint32_t Layer::getEffectiveScalingMode() const {
-    if (mOverrideScalingMode >= 0) {
-      return mOverrideScalingMode;
-    }
-    return mCurrentScalingMode;
+    mCurrentState.appId = appId;
+    mCurrentState.type = type;
+    mCurrentState.modified = true;
+    setTransactionFlags(eTransactionNeeded);
 }
 
 bool Layer::setLayerStack(uint32_t layerStack) {
-    if (mCurrentState.layerStack == layerStack)
-        return false;
+    if (mCurrentState.layerStack == layerStack) return false;
     mCurrentState.sequence++;
     mCurrentState.layerStack = layerStack;
     mCurrentState.modified = true;
@@ -2002,8 +1367,7 @@
 }
 
 bool Layer::setDataSpace(android_dataspace dataSpace) {
-    if (mCurrentState.dataSpace == dataSpace)
-        return false;
+    if (mCurrentState.dataSpace == dataSpace) return false;
     mCurrentState.sequence++;
     mCurrentState.dataSpace = dataSpace;
     mCurrentState.modified = true;
@@ -2023,8 +1387,7 @@
     return p->getLayerStack();
 }
 
-void Layer::deferTransactionUntil(const sp<Layer>& barrierLayer,
-        uint64_t frameNumber) {
+void Layer::deferTransactionUntil(const sp<Layer>& barrierLayer, uint64_t frameNumber) {
     mCurrentState.barrierLayer = barrierLayer;
     mCurrentState.frameNumber = frameNumber;
     // We don't set eTransactionNeeded, because just receiving a deferral
@@ -2036,124 +1399,16 @@
     mCurrentState.modified = false;
 }
 
-void Layer::deferTransactionUntil(const sp<IBinder>& barrierHandle,
-        uint64_t frameNumber) {
+void Layer::deferTransactionUntil(const sp<IBinder>& barrierHandle, uint64_t frameNumber) {
     sp<Handle> handle = static_cast<Handle*>(barrierHandle.get());
     deferTransactionUntil(handle->owner.promote(), frameNumber);
 }
 
-void Layer::useSurfaceDamage() {
-    if (mFlinger->mForceFullDamage) {
-        surfaceDamageRegion = Region::INVALID_REGION;
-    } else {
-        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
-    }
-}
-
-void Layer::useEmptyDamage() {
-    surfaceDamageRegion.clear();
-}
 
 // ----------------------------------------------------------------------------
 // pageflip handling...
 // ----------------------------------------------------------------------------
 
-bool Layer::shouldPresentNow(const DispSync& dispSync) const {
-    if (mSidebandStreamChanged || mAutoRefresh) {
-        return true;
-    }
-
-    Mutex::Autolock lock(mQueueItemLock);
-    if (mQueueItems.empty()) {
-        return false;
-    }
-    auto timestamp = mQueueItems[0].mTimestamp;
-    nsecs_t expectedPresent =
-            mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
-
-    // Ignore timestamps more than a second in the future
-    bool isPlausible = timestamp < (expectedPresent + s2ns(1));
-    ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
-            "relative to expectedPresent %" PRId64, mName.string(), timestamp,
-            expectedPresent);
-
-    bool isDue = timestamp < expectedPresent;
-    return isDue || !isPlausible;
-}
-
-bool Layer::onPreComposition(nsecs_t refreshStartTime) {
-    if (mBufferLatched) {
-        Mutex::Autolock lock(mFrameEventHistoryMutex);
-        mFrameEventHistory.addPreComposition(mCurrentFrameNumber, refreshStartTime);
-    }
-    mRefreshPending = false;
-    return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
-}
-
-bool Layer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
-        const std::shared_ptr<FenceTime>& presentFence,
-        const CompositorTiming& compositorTiming) {
-    // mFrameLatencyNeeded is true when a new frame was latched for the
-    // composition.
-    if (!mFrameLatencyNeeded)
-        return false;
-
-    // Update mFrameEventHistory.
-    {
-        Mutex::Autolock lock(mFrameEventHistoryMutex);
-        mFrameEventHistory.addPostComposition(mCurrentFrameNumber,
-                glDoneFence, presentFence, compositorTiming);
-    }
-
-    // Update mFrameTracker.
-    nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
-    mFrameTracker.setDesiredPresentTime(desiredPresentTime);
-
-    std::shared_ptr<FenceTime> frameReadyFence =
-            mSurfaceFlingerConsumer->getCurrentFenceTime();
-    if (frameReadyFence->isValid()) {
-        mFrameTracker.setFrameReadyFence(std::move(frameReadyFence));
-    } else {
-        // There was no fence for this frame, so assume that it was ready
-        // to be presented at the desired present time.
-        mFrameTracker.setFrameReadyTime(desiredPresentTime);
-    }
-
-    if (presentFence->isValid()) {
-        mFrameTracker.setActualPresentFence(
-                std::shared_ptr<FenceTime>(presentFence));
-    } else {
-        // The HWC doesn't support present fences, so use the refresh
-        // timestamp instead.
-        mFrameTracker.setActualPresentTime(
-            mFlinger->getHwComposer().getRefreshTimestamp(
-                HWC_DISPLAY_PRIMARY));
-    }
-
-    mFrameTracker.advanceFrame();
-    mFrameLatencyNeeded = false;
-    return true;
-}
-
-#ifdef USE_HWC2
-void Layer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
-    if (!mSurfaceFlingerConsumer->releasePendingBuffer()) {
-        return;
-    }
-
-    auto releaseFenceTime = std::make_shared<FenceTime>(
-            mSurfaceFlingerConsumer->getPrevFinalReleaseFence());
-    mReleaseTimeline.updateSignalTimes();
-    mReleaseTimeline.push(releaseFenceTime);
-
-    Mutex::Autolock lock(mFrameEventHistoryMutex);
-    if (mPreviousFrameNumber != 0) {
-        mFrameEventHistory.addRelease(mPreviousFrameNumber,
-                dequeueReadyTime, std::move(releaseFenceTime));
-    }
-}
-#endif
-
 bool Layer::isHiddenByPolicy() const {
     const Layer::State& s(mDrawingState);
     const auto& parent = mDrawingParent.promote();
@@ -2163,251 +1418,7 @@
     return s.flags & layer_state_t::eLayerHidden;
 }
 
-bool Layer::isVisible() const {
-    return !(isHiddenByPolicy()) && getAlpha() > 0.0f
-            && (mActiveBuffer != NULL || mSidebandStream != NULL);
-}
-
-bool Layer::allTransactionsSignaled() {
-    auto headFrameNumber = getHeadFrameNumber();
-    bool matchingFramesFound = false;
-    bool allTransactionsApplied = true;
-    Mutex::Autolock lock(mLocalSyncPointMutex);
-
-    for (auto& point : mLocalSyncPoints) {
-        if (point->getFrameNumber() > headFrameNumber) {
-            break;
-        }
-        matchingFramesFound = true;
-
-        if (!point->frameIsAvailable()) {
-           // We haven't notified the remote layer that the frame for
-           // this point is available yet. Notify it now, and then
-           // abort this attempt to latch.
-           point->setFrameAvailable();
-           allTransactionsApplied = false;
-           break;
-        }
-
-        allTransactionsApplied = allTransactionsApplied && point->transactionIsApplied();
-    }
-    return !matchingFramesFound || allTransactionsApplied;
-}
-
-Region Layer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime)
-{
-    ATRACE_CALL();
-
-    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
-        // mSidebandStreamChanged was true
-        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
-        if (mSidebandStream != NULL) {
-            setTransactionFlags(eTransactionNeeded);
-            mFlinger->setTransactionFlags(eTraversalNeeded);
-        }
-        recomputeVisibleRegions = true;
-
-        const State& s(getDrawingState());
-        return getTransform().transform(Region(Rect(s.active.w, s.active.h)));
-    }
-
-    Region outDirtyRegion;
-    if (mQueuedFrames <= 0 && !mAutoRefresh) {
-        return outDirtyRegion;
-    }
-
-    // if we've already called updateTexImage() without going through
-    // a composition step, we have to skip this layer at this point
-    // because we cannot call updateTeximage() without a corresponding
-    // compositionComplete() call.
-    // we'll trigger an update in onPreComposition().
-    if (mRefreshPending) {
-        return outDirtyRegion;
-    }
-
-    // If the head buffer's acquire fence hasn't signaled yet, return and
-    // try again later
-    if (!headFenceHasSignaled()) {
-        mFlinger->signalLayerUpdate();
-        return outDirtyRegion;
-    }
-
-    // Capture the old state of the layer for comparisons later
-    const State& s(getDrawingState());
-    const bool oldOpacity = isOpaque(s);
-    sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
-
-    if (!allTransactionsSignaled()) {
-        mFlinger->signalLayerUpdate();
-        return outDirtyRegion;
-    }
-
-    // This boolean is used to make sure that SurfaceFlinger's shadow copy
-    // of the buffer queue isn't modified when the buffer queue is returning
-    // BufferItem's that weren't actually queued. This can happen in shared
-    // buffer mode.
-    bool queuedBuffer = false;
-    LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
-                    getProducerStickyTransform() != 0, mName.string(),
-                    mOverrideScalingMode, mFreezeGeometryUpdates);
-    status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,
-            mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
-            mLastFrameNumberReceived);
-    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.
-        mFlinger->signalLayerUpdate();
-        return outDirtyRegion;
-    } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
-        // If the buffer has been rejected, remove it from the shadow queue
-        // and return early
-        if (queuedBuffer) {
-            Mutex::Autolock lock(mQueueItemLock);
-            mQueueItems.removeAt(0);
-            android_atomic_dec(&mQueuedFrames);
-        }
-        return outDirtyRegion;
-    } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
-        // This can occur if something goes wrong when trying to create the
-        // EGLImage for this buffer. If this happens, the buffer has already
-        // been released, so we need to clean up the queue and bug out
-        // early.
-        if (queuedBuffer) {
-            Mutex::Autolock lock(mQueueItemLock);
-            mQueueItems.clear();
-            android_atomic_and(0, &mQueuedFrames);
-        }
-
-        // Once we have hit this state, the shadow queue may no longer
-        // correctly reflect the incoming BufferQueue's contents, so even if
-        // updateTexImage starts working, the only safe course of action is
-        // to continue to ignore updates.
-        mUpdateTexImageFailed = true;
-
-        return outDirtyRegion;
-    }
-
-    if (queuedBuffer) {
-        // Autolock scope
-        auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
-
-        Mutex::Autolock lock(mQueueItemLock);
-
-        // Remove any stale buffers that have been dropped during
-        // updateTexImage
-        while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
-            mQueueItems.removeAt(0);
-            android_atomic_dec(&mQueuedFrames);
-        }
-
-        mQueueItems.removeAt(0);
-    }
-
-
-    // Decrement the queued-frames count.  Signal another event if we
-    // have more frames pending.
-    if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1)
-            || mAutoRefresh) {
-        mFlinger->signalLayerUpdate();
-    }
-
-    // update the active buffer
-    mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer(
-            &mActiveBufferSlot);
-    if (mActiveBuffer == NULL) {
-        // this can only happen if the very first buffer was rejected.
-        return outDirtyRegion;
-    }
-
-    mBufferLatched = true;
-    mPreviousFrameNumber = mCurrentFrameNumber;
-    mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
-
-    {
-        Mutex::Autolock lock(mFrameEventHistoryMutex);
-        mFrameEventHistory.addLatch(mCurrentFrameNumber, latchTime);
-#ifndef USE_HWC2
-        auto releaseFenceTime = std::make_shared<FenceTime>(
-                mSurfaceFlingerConsumer->getPrevFinalReleaseFence());
-        mReleaseTimeline.updateSignalTimes();
-        mReleaseTimeline.push(releaseFenceTime);
-        if (mPreviousFrameNumber != 0) {
-            mFrameEventHistory.addRelease(mPreviousFrameNumber,
-                    latchTime, std::move(releaseFenceTime));
-        }
-#endif
-    }
-
-    mRefreshPending = true;
-    mFrameLatencyNeeded = true;
-    if (oldActiveBuffer == NULL) {
-         // the first time we receive a buffer, we need to trigger a
-         // geometry invalidation.
-        recomputeVisibleRegions = true;
-     }
-
-    setDataSpace(mSurfaceFlingerConsumer->getCurrentDataSpace());
-
-    Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
-    const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
-    const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
-    if ((crop != mCurrentCrop) ||
-        (transform != mCurrentTransform) ||
-        (scalingMode != mCurrentScalingMode))
-    {
-        mCurrentCrop = crop;
-        mCurrentTransform = transform;
-        mCurrentScalingMode = scalingMode;
-        recomputeVisibleRegions = true;
-    }
-
-    if (oldActiveBuffer != NULL) {
-        uint32_t bufWidth  = mActiveBuffer->getWidth();
-        uint32_t bufHeight = mActiveBuffer->getHeight();
-        if (bufWidth != uint32_t(oldActiveBuffer->width) ||
-            bufHeight != uint32_t(oldActiveBuffer->height)) {
-            recomputeVisibleRegions = true;
-        }
-    }
-
-    mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
-    if (oldOpacity != isOpaque(s)) {
-        recomputeVisibleRegions = true;
-    }
-
-    // Remove any sync points corresponding to the buffer which was just
-    // latched
-    {
-        Mutex::Autolock lock(mLocalSyncPointMutex);
-        auto point = mLocalSyncPoints.begin();
-        while (point != mLocalSyncPoints.end()) {
-            if (!(*point)->frameIsAvailable() ||
-                    !(*point)->transactionIsApplied()) {
-                // This sync point must have been added since we started
-                // latching. Don't drop it yet.
-                ++point;
-                continue;
-            }
-
-            if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
-                point = mLocalSyncPoints.erase(point);
-            } else {
-                ++point;
-            }
-        }
-    }
-
-    // FIXME: postedRegion should be dirty & bounds
-    Region dirtyRegion(Rect(s.active.w, s.active.h));
-
-    // transform the dirty region to window-manager space
-    outDirtyRegion = (getTransform().transform(dirtyRegion));
-
-    return outDirtyRegion;
-}
-
-uint32_t Layer::getEffectiveUsage(uint32_t usage) const
-{
+uint32_t Layer::getEffectiveUsage(uint32_t usage) const {
     // TODO: should we do something special if mSecure is set?
     if (mProtectedByApp) {
         // need a hardware-protected path to external video sink
@@ -2432,7 +1443,7 @@
             orientation = 0;
         }
     }
-    mSurfaceFlingerConsumer->setTransformHint(orientation);
+    setTransformHint(orientation);
 }
 
 // ----------------------------------------------------------------------------
@@ -2519,14 +1530,11 @@
     const Layer::State& layerState(getDrawingState());
     const HWCInfo& hwcInfo = mHwcLayers.at(hwcId);
     result.appendFormat("  %10d | ", layerState.z);
-    result.appendFormat("%10s | ",
-            to_string(getCompositionType(hwcId)).c_str());
+    result.appendFormat("%10s | ", to_string(getCompositionType(hwcId)).c_str());
     const Rect& frame = hwcInfo.displayFrame;
-    result.appendFormat("%4d %4d %4d %4d | ", frame.left, frame.top,
-            frame.right, frame.bottom);
+    result.appendFormat("%4d %4d %4d %4d | ", frame.left, frame.top, frame.right, frame.bottom);
     const FloatRect& crop = hwcInfo.sourceCrop;
-    result.appendFormat("%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top,
-            crop.right, crop.bottom);
+    result.appendFormat("%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top, crop.right, crop.bottom);
 
     result.append("- - - - - - - - - - - - - - - - - - - - ");
     result.append("- - - - - - - - - - - - - - - - - - - -\n");
@@ -2550,8 +1558,7 @@
 }
 
 void Layer::dumpFrameEvents(String8& result) {
-    result.appendFormat("- Layer %s (%s, %p)\n",
-            getName().string(), getTypeId(), this);
+    result.appendFormat("- Layer %s (%s, %p)\n", getName().string(), getTypeId(), this);
     Mutex::Autolock lock(mFrameEventHistoryMutex);
     mFrameEventHistory.checkFencesForCompletion();
     mFrameEventHistory.dump(result);
@@ -2563,7 +1570,7 @@
 }
 
 void Layer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps,
-        FrameEventHistoryDelta *outDelta) {
+                                     FrameEventHistoryDelta* outDelta) {
     Mutex::Autolock lock(mFrameEventHistoryMutex);
     if (newTimestamps) {
         // If there are any unsignaled fences in the aquire timeline at this
@@ -2581,23 +1588,6 @@
     }
 }
 
-std::vector<OccupancyTracker::Segment> Layer::getOccupancyHistory(
-        bool forceFlush) {
-    std::vector<OccupancyTracker::Segment> history;
-    status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush,
-            &history);
-    if (result != NO_ERROR) {
-        ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(),
-                result);
-        return {};
-    }
-    return history;
-}
-
-bool Layer::getTransformToDisplayInverse() const {
-    return mSurfaceFlingerConsumer->getTransformToDisplayInverse();
-}
-
 size_t Layer::getChildrenCount() const {
     size_t count = 0;
     for (const sp<Layer>& child : mCurrentChildren) {
@@ -2706,8 +1696,8 @@
     return mDrawingState.z;
 }
 
-__attribute__((no_sanitize("unsigned-integer-overflow")))
-LayerVector Layer::makeTraversalList(LayerVector::StateSet stateSet) {
+__attribute__((no_sanitize("unsigned-integer-overflow"))) LayerVector Layer::makeTraversalList(
+        LayerVector::StateSet stateSet) {
     LOG_ALWAYS_FATAL_IF(stateSet == LayerVector::StateSet::Invalid,
                         "makeTraversalList received invalid stateSet");
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
@@ -2762,7 +1752,7 @@
     LayerVector list = makeTraversalList(stateSet);
 
     int32_t i = 0;
-    for (i = list.size()-1; i>=0; i--) {
+    for (i = int32_t(list.size()) - 1; i >= 0; i--) {
         const auto& relative = list[i];
         if (relative->getZ() < 0) {
             break;
@@ -2770,7 +1760,7 @@
         relative->traverseInReverseZOrder(stateSet, visitor);
     }
     visitor(this);
-    for (; i>=0; i--) {
+    for (; i >= 0; i--) {
         const auto& relative = list[i];
         relative->traverseInReverseZOrder(stateSet, visitor);
     }
@@ -2820,10 +1810,8 @@
                 bufferHeight = p->mActiveBuffer->getWidth();
                 bufferWidth = p->mActiveBuffer->getHeight();
             }
-            float sx = p->getDrawingState().active.w /
-                    static_cast<float>(bufferWidth);
-            float sy = p->getDrawingState().active.h /
-                    static_cast<float>(bufferHeight);
+            float sx = p->getDrawingState().active.w / static_cast<float>(bufferWidth);
+            float sy = p->getDrawingState().active.h / static_cast<float>(bufferHeight);
             Transform extraParentScaling;
             extraParentScaling.set(sx, 0, 0, sy);
             t = t * extraParentScaling;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index d75e175..0580b9f 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -37,20 +37,19 @@
 
 #include <list>
 
-#include "FrameTracker.h"
 #include "Client.h"
+#include "FrameTracker.h"
 #include "LayerVector.h"
 #include "MonitoredProducer.h"
 #include "SurfaceFlinger.h"
-#include "SurfaceFlingerConsumer.h"
 #include "Transform.h"
 
+#include <layerproto/LayerProtoHeader.h>
 #include "DisplayHardware/HWComposer.h"
 #include "DisplayHardware/HWComposerBufferCache.h"
+#include "RenderArea.h"
 #include "RenderEngine/Mesh.h"
 #include "RenderEngine/Texture.h"
-#include <layerproto/LayerProtoHeader.h>
-#include "RenderArea.h"
 
 #include <math/vec4.h>
 
@@ -69,14 +68,7 @@
 
 // ---------------------------------------------------------------------------
 
-/*
- * A new BufferQueue and a new SurfaceFlingerConsumer are created when the
- * Layer is first referenced.
- *
- * This also implements onFrameAvailable(), which notifies SurfaceFlinger
- * that new data has arrived.
- */
-class Layer : public SurfaceFlingerConsumer::ContentsChangedListener {
+class Layer : public virtual RefBase {
     static int32_t sSequence;
 
 public:
@@ -102,14 +94,11 @@
         uint32_t h;
         Transform transform;
 
-        inline bool operator ==(const Geometry& rhs) const {
-            return (w == rhs.w && h == rhs.h) &&
-                    (transform.tx() == rhs.transform.tx()) &&
+        inline bool operator==(const Geometry& rhs) const {
+            return (w == rhs.w && h == rhs.h) && (transform.tx() == rhs.transform.tx()) &&
                     (transform.ty() == rhs.transform.ty());
         }
-        inline bool operator !=(const Geometry& rhs) const {
-            return !operator ==(rhs);
-        }
+        inline bool operator!=(const Geometry& rhs) const { return !operator==(rhs); }
     };
 
     struct State {
@@ -162,18 +151,12 @@
         half4 color;
     };
 
-    // -----------------------------------------------------------------------
-
-    Layer(SurfaceFlinger* flinger, const sp<Client>& client,
-            const String8& name, uint32_t w, uint32_t h, uint32_t flags);
-
+    Layer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w,
+          uint32_t h, uint32_t flags);
     virtual ~Layer();
 
     void setPrimaryDisplayOnly() { mPrimaryDisplayOnly = true; }
 
-    // the this layer's size and format
-    status_t setBuffers(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
-
     // ------------------------------------------------------------------------
     // Geometry setting functions.
     //
@@ -246,8 +229,8 @@
     // If we have received a new buffer this frame, we will pass its surface
     // damage down to hardware composer. Otherwise, we must send a region with
     // one empty rect.
-    void useSurfaceDamage();
-    void useEmptyDamage();
+    virtual void useSurfaceDamage() = 0;
+    virtual void useEmptyDamage() = 0;
 
     uint32_t getTransactionFlags(uint32_t flags);
     uint32_t setTransactionFlags(uint32_t flags);
@@ -264,8 +247,7 @@
 
     // -----------------------------------------------------------------------
     // Virtuals
-
-    virtual const char* getTypeId() const { return "Layer"; }
+    virtual const char* getTypeId() const = 0;
 
     /*
      * isOpaque - true if this surface is opaque
@@ -274,24 +256,18 @@
      * pixel format includes an alpha channel) and the "opaque" flag set
      * on the layer.  It does not examine the current plane alpha value.
      */
-    virtual bool isOpaque(const Layer::State& s) const;
+    virtual bool isOpaque(const Layer::State& s) const = 0;
 
     /*
      * isSecure - true if this surface is secure, that is if it prevents
      * screenshots or VNC servers.
      */
-    virtual bool isSecure() const;
-
-    /*
-     * isProtected - true if the layer may contain protected content in the
-     * GRALLOC_USAGE_PROTECTED sense.
-     */
-    virtual bool isProtected() const;
+    bool isSecure() const;
 
     /*
      * isVisible - true if this layer is visible, false otherwise
      */
-    virtual bool isVisible() const;
+    virtual bool isVisible() const = 0;
 
     /*
      * isHiddenByPolicy - true if this layer has been forced invisible.
@@ -299,48 +275,45 @@
      * For example if this layer has no active buffer, it may not be hidden by
      * policy, but it still can not be visible.
      */
-    virtual bool isHiddenByPolicy() const;
+    bool isHiddenByPolicy() const;
 
     /*
      * isFixedSize - true if content has a fixed size
      */
-    virtual bool isFixedSize() const;
+    virtual bool isFixedSize() const = 0;
 
-    void writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing);
+    bool isPendingRemoval() const { return mPendingRemoval; }
+
+    void writeToProto(LayerProto* layerInfo,
+                      LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing);
 
 protected:
     /*
      * onDraw - draws the surface.
      */
     virtual void onDraw(const RenderArea& renderArea, const Region& clip,
-            bool useIdentityTransform) const;
+                        bool useIdentityTransform) const = 0;
 
 public:
-    // -----------------------------------------------------------------------
+    virtual void setDefaultBufferSize(uint32_t w, uint32_t h) = 0;
 
 #ifdef USE_HWC2
     void setGeometry(const sp<const DisplayDevice>& displayDevice, uint32_t z);
     void forceClientComposition(int32_t hwcId);
-    void setPerFrameData(const sp<const DisplayDevice>& displayDevice);
+    virtual void setPerFrameData(const sp<const DisplayDevice>& displayDevice) = 0;
 
     // callIntoHwc exists so we can update our local state and call
     // acceptDisplayChanges without unnecessarily updating the device's state
-    void setCompositionType(int32_t hwcId, HWC2::Composition type,
-            bool callIntoHwc = true);
+    void setCompositionType(int32_t hwcId, HWC2::Composition type, bool callIntoHwc = true);
     HWC2::Composition getCompositionType(int32_t hwcId) const;
-
     void setClearClientTarget(int32_t hwcId, bool clear);
     bool getClearClientTarget(int32_t hwcId) const;
-
     void updateCursorPosition(const sp<const DisplayDevice>& hw);
 #else
-    void setGeometry(const sp<const DisplayDevice>& hw,
-            HWComposer::HWCLayerInterface& layer);
-    void setPerFrameData(const sp<const DisplayDevice>& hw,
-            HWComposer::HWCLayerInterface& layer);
-    void setAcquireFence(const sp<const DisplayDevice>& hw,
-            HWComposer::HWCLayerInterface& layer);
-
+    void setGeometry(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer);
+    void setPerFrameData(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer);
+    virtual void setAcquireFence(const sp<const DisplayDevice>& hw,
+                                 HWComposer::HWCLayerInterface& layer) = 0;
     Rect getPosition(const sp<const DisplayDevice>& hw);
 #endif
 
@@ -348,31 +321,34 @@
      * called after page-flip
      */
 #ifdef USE_HWC2
-    void onLayerDisplayed(const sp<Fence>& releaseFence);
+    virtual void onLayerDisplayed(const sp<Fence>& releaseFence);
 #else
-    void onLayerDisplayed(const sp<const DisplayDevice>& hw,
-            HWComposer::HWCLayerInterface* layer);
+    virtual void onLayerDisplayed(const sp<const DisplayDevice>& hw,
+                                  HWComposer::HWCLayerInterface* layer);
 #endif
 
-    bool shouldPresentNow(const DispSync& dispSync) const;
+    virtual void abandon() = 0;
+
+    virtual bool shouldPresentNow(const DispSync& dispSync) const = 0;
+    virtual void setTransformHint(uint32_t orientation) const = 0;
 
     /*
      * called before composition.
      * returns true if the layer has pending updates.
      */
-    bool onPreComposition(nsecs_t refreshStartTime);
+    virtual bool onPreComposition(nsecs_t refreshStartTime) = 0;
 
     /*
      * called after composition.
      * returns true if the layer latched a new buffer this frame.
      */
-    bool onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
-            const std::shared_ptr<FenceTime>& presentFence,
-            const CompositorTiming& compositorTiming);
+    virtual bool onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
+                                   const std::shared_ptr<FenceTime>& presentFence,
+                                   const CompositorTiming& compositorTiming) = 0;
 
 #ifdef USE_HWC2
     // If a buffer was replaced this frame, release the former buffer
-    void releasePendingBuffer(nsecs_t dequeueReadyTime);
+    virtual void releasePendingBuffer(nsecs_t dequeueReadyTime) = 0;
 #endif
 
     /*
@@ -406,8 +382,7 @@
      * setVisibleNonTransparentRegion - called when the visible and
      * non-transparent region changes.
      */
-    void setVisibleNonTransparentRegion(const Region&
-            visibleNonTransparentRegion);
+    void setVisibleNonTransparentRegion(const Region& visibleNonTransparentRegion);
 
     /*
      * latchBuffer - called each time the screen is redrawn and returns whether
@@ -415,11 +390,10 @@
      * 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.
      */
-    Region latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime);
-    bool isBufferLatched() const { return mRefreshPending; }
+    virtual Region latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) = 0;
+    virtual bool isBufferLatched() const = 0;
 
-    bool isPotentialCursor() const { return mPotentialCursor;}
-
+    bool isPotentialCursor() const { return mPotentialCursor; }
     /*
      * called with the state lock from a binder thread when the layer is
      * removed from the current list to the pending removal list
@@ -432,7 +406,6 @@
      */
     void onRemoved();
 
-
     // Updates the transform hint in our SurfaceFlingerConsumer to match
     // the current orientation of the display device.
     void updateTransformHint(const sp<const DisplayDevice>& hw) const;
@@ -446,8 +419,9 @@
     /*
      * Returns if a frame is queued.
      */
-    bool hasQueuedFrame() const { return mQueuedFrames > 0 ||
-            mSidebandStreamChanged || mAutoRefresh; }
+    bool hasQueuedFrame() const {
+        return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
+    }
 
     int32_t getQueuedFrameCount() const { return mQueuedFrames; }
 
@@ -458,9 +432,7 @@
     void destroyHwcLayer(int32_t hwcId);
     void destroyAllHwcLayers();
 
-    bool hasHwcLayer(int32_t hwcId) {
-        return mHwcLayers.count(hwcId) > 0;
-    }
+    bool hasHwcLayer(int32_t hwcId) { return mHwcLayers.count(hwcId) > 0; }
 
     HWC2::Layer* getHwcLayer(int32_t hwcId) {
         if (mHwcLayers.count(hwcId) == 0) {
@@ -479,9 +451,9 @@
     // only for debugging
     inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
 
-    inline  const State&    getDrawingState() const { return mDrawingState; }
-    inline  const State&    getCurrentState() const { return mCurrentState; }
-    inline  State&          getCurrentState()       { return mCurrentState; }
+    inline const State& getDrawingState() const { return mDrawingState; }
+    inline const State& getCurrentState() const { return mCurrentState; }
+    inline State& getCurrentState() { return mCurrentState; }
 
     LayerDebugInfo getLayerDebugInfo() const;
 
@@ -496,13 +468,13 @@
     void logFrameStats();
     void getFrameStats(FrameStats* outStats) const;
 
-    std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush);
+    virtual std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush) = 0;
 
     void onDisconnect();
     void addAndGetFrameTimestamps(const NewFrameEventsEntry* newEntry,
-            FrameEventHistoryDelta* outDelta);
+                                  FrameEventHistoryDelta* outDelta);
 
-    bool getTransformToDisplayInverse() const;
+    virtual bool getTransformToDisplayInverse() const = 0;
 
     Transform getTransform() const;
 
@@ -526,15 +498,14 @@
     ssize_t removeChild(const sp<Layer>& layer);
     sp<Layer> getParent() const { return mCurrentParent.promote(); }
     bool hasParent() const { return getParent() != nullptr; }
-
     Rect computeScreenBounds(bool reduceTransparentRegion = true) const;
     bool setChildLayer(const sp<Layer>& childLayer, int32_t z);
 
     // Copy the current list of children to the drawing state. Called by
     // SurfaceFlinger to complete a transaction.
     void commitChildList();
-
     int32_t getZ() const;
+
 protected:
     // constant
     sp<SurfaceFlinger> mFlinger;
@@ -545,56 +516,36 @@
     class LayerCleaner {
         sp<SurfaceFlinger> mFlinger;
         wp<Layer> mLayer;
+
     protected:
         ~LayerCleaner() {
             // destroy client resources
             mFlinger->onLayerDestroyed(mLayer);
         }
-    public:
-        LayerCleaner(const sp<SurfaceFlinger>& flinger,
-                const sp<Layer>& layer)
-            : mFlinger(flinger), mLayer(layer) {
-        }
-    };
 
+    public:
+        LayerCleaner(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
+              : mFlinger(flinger), mLayer(layer) {}
+    };
 
     virtual void onFirstRef();
 
-
-
-private:
     friend class SurfaceInterceptor;
-    // Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener
-    virtual void onFrameAvailable(const BufferItem& item) override;
-    virtual void onFrameReplaced(const BufferItem& item) override;
-    virtual void onSidebandStreamChanged() override;
 
     void commitTransaction(const State& stateToCommit);
 
-    // needsLinearFiltering - true if this surface's state requires filtering
-    bool needsFiltering(const RenderArea& renderArea) const;
-
     uint32_t getEffectiveUsage(uint32_t usage) const;
 
     FloatRect computeCrop(const sp<const DisplayDevice>& hw) const;
-    // Compute the initial crop as specified by parent layers and the SurfaceControl
-    // for this layer. Does not include buffer crop from the IGraphicBufferProducer
-    // client, as that should not affect child clipping. Returns in screen space.
+    // Compute the initial crop as specified by parent layers and the
+    // SurfaceControl for this layer. Does not include buffer crop from the
+    // IGraphicBufferProducer client, as that should not affect child clipping.
+    // Returns in screen space.
     Rect computeInitialCrop(const sp<const DisplayDevice>& hw) const;
-    bool isCropped() const;
-    static bool getOpacityForFormat(uint32_t format);
 
     // drawing
-    void clearWithOpenGL(const RenderArea& renderArea,
-            float r, float g, float b, float alpha) const;
-    void drawWithOpenGL(const RenderArea& renderArea,
-            bool useIdentityTransform) const;
-
-    // Temporary - Used only for LEGACY camera mode.
-    uint32_t getProducerStickyTransform() const;
-
-    // Loads the corresponding system property once per process
-    static bool latchUnsignaledBuffers();
+    void clearWithOpenGL(const RenderArea& renderArea, float r, float g, float b,
+                         float alpha) const;
 
     void setParent(const sp<Layer>& layer);
 
@@ -602,33 +553,20 @@
     void addZOrderRelative(const wp<Layer>& relative);
     void removeZOrderRelative(const wp<Layer>& relative);
 
-    // -----------------------------------------------------------------------
-
-    class SyncPoint
-    {
+    class SyncPoint {
     public:
-        explicit SyncPoint(uint64_t frameNumber) : mFrameNumber(frameNumber),
-                mFrameIsAvailable(false), mTransactionIsApplied(false) {}
+        explicit SyncPoint(uint64_t frameNumber)
+              : mFrameNumber(frameNumber), mFrameIsAvailable(false), mTransactionIsApplied(false) {}
 
-        uint64_t getFrameNumber() const {
-            return mFrameNumber;
-        }
+        uint64_t getFrameNumber() const { return mFrameNumber; }
 
-        bool frameIsAvailable() const {
-            return mFrameIsAvailable;
-        }
+        bool frameIsAvailable() const { return mFrameIsAvailable; }
 
-        void setFrameAvailable() {
-            mFrameIsAvailable = true;
-        }
+        void setFrameAvailable() { mFrameIsAvailable = true; }
 
-        bool transactionIsApplied() const {
-            return mTransactionIsApplied;
-        }
+        bool transactionIsApplied() const { return mTransactionIsApplied; }
 
-        void setTransactionApplied() {
-            mTransactionIsApplied = true;
-        }
+        void setTransactionApplied() { mTransactionIsApplied = true; }
 
     private:
         const uint64_t mFrameNumber;
@@ -646,9 +584,6 @@
     // is applied
     std::list<std::shared_ptr<SyncPoint>> mRemoteSyncPoints;
 
-    uint64_t getHeadFrameNumber() const;
-    bool headFenceHasSignaled() const;
-
     // Returns false if the relevant frame has already been latched
     bool addSyncPoint(const std::shared_ptr<SyncPoint>& point);
 
@@ -661,7 +596,8 @@
     // Returns mCurrentScaling mode (originating from the
     // Client) or mOverrideScalingMode mode (originating from
     // the Surface Controller) if set.
-    uint32_t getEffectiveScalingMode() const;
+    virtual uint32_t getEffectiveScalingMode() const = 0;
+
 public:
     /*
      * The layer handle is just a BBinder object passed to the client
@@ -672,36 +608,25 @@
      * this layer when the handle is destroyed.
      */
     class Handle : public BBinder, public LayerCleaner {
-        public:
-            Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
-                : LayerCleaner(flinger, layer), owner(layer) {}
+    public:
+        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
+              : LayerCleaner(flinger, layer), owner(layer) {}
 
-            wp<Layer> owner;
+        wp<Layer> owner;
     };
 
     sp<IBinder> getHandle();
-    sp<IGraphicBufferProducer> getProducer() const;
     const String8& getName() const;
-    void notifyAvailableFrames();
-    PixelFormat getPixelFormat() const { return mFormat; }
+    virtual void notifyAvailableFrames() = 0;
+    virtual PixelFormat getPixelFormat() const = 0;
     bool getPremultipledAlpha() const;
-private:
 
+protected:
     // -----------------------------------------------------------------------
 
-    // Check all of the local sync points to ensure that all transactions
-    // which need to have been applied prior to the frame which is about to
-    // be latched have signaled
-    bool allTransactionsSignaled();
-
-    // constants
-    sp<SurfaceFlingerConsumer> mSurfaceFlingerConsumer;
-    sp<IGraphicBufferProducer> mProducer;
-    uint32_t mTextureName;      // from GLES
     bool mPremultipliedAlpha;
     String8 mName;
     String8 mTransactionName; // A cached version of "TX - " + mName for systraces
-    PixelFormat mFormat;
 
     bool mPrimaryDisplayOnly = false;
 
@@ -734,14 +659,10 @@
     sp<NativeHandle> mSidebandStream;
     Rect mCurrentCrop;
     uint32_t mCurrentTransform;
-    uint32_t mCurrentScalingMode;
     // We encode unset as -1.
     int32_t mOverrideScalingMode;
     bool mCurrentOpacity;
-    bool mBufferLatched = false;  // TODO: Use mActiveBuffer?
     std::atomic<uint64_t> mCurrentFrameNumber;
-    uint64_t mPreviousFrameNumber; // Only accessed on the main thread.
-    bool mRefreshPending;
     bool mFrameLatencyNeeded;
     // Whether filtering is forced on or not
     bool mFiltering;
@@ -749,18 +670,18 @@
     bool mNeedsFiltering;
     // The mesh used to draw the layer in GLES composition mode
     mutable Mesh mMesh;
-    // The texture used to draw the layer in GLES composition mode
-    mutable Texture mTexture;
+
+    bool mPendingRemoval = false;
 
 #ifdef USE_HWC2
     // HWC items, accessed from the main thread
     struct HWCInfo {
         HWCInfo()
-          : hwc(nullptr),
-            layer(nullptr),
-            forceClientComposition(false),
-            compositionType(HWC2::Composition::Invalid),
-            clearClientTarget(false) {}
+              : hwc(nullptr),
+                layer(nullptr),
+                forceClientComposition(false),
+                compositionType(HWC2::Composition::Invalid),
+                clearClientTarget(false) {}
 
         HWComposer* hwc;
         HWC2::Layer* layer;
@@ -786,8 +707,7 @@
 
     // protected by mLock
     mutable Mutex mLock;
-    // Set to true once we've returned this surface's handle
-    mutable bool mHasSurface;
+
     const wp<Client> mClientRef;
 
     // This layer can be a cursor on some displays.
@@ -798,8 +718,6 @@
     Condition mQueueItemCondition;
     Vector<BufferItem> mQueueItems;
     std::atomic<uint64_t> mLastFrameNumberReceived;
-    bool mUpdateTexImageFailed; // This is only accessed on the main thread.
-
     bool mAutoRefresh;
     bool mFreezeGeometryUpdates;
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 77b9a29..4ca9acb 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -72,6 +72,7 @@
 #include "EventControlThread.h"
 #include "EventThread.h"
 #include "Layer.h"
+#include "BufferLayer.h"
 #include "LayerVector.h"
 #include "ColorLayer.h"
 #include "MonitoredProducer.h"
@@ -2856,6 +2857,10 @@
 status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer, bool topLevelOnly) {
     Mutex::Autolock _l(mStateLock);
 
+    if (layer->isPendingRemoval()) {
+        return NO_ERROR;
+    }
+
     const auto& p = layer->getParent();
     ssize_t index;
     if (p != nullptr) {
@@ -3059,131 +3064,139 @@
         const sp<Client>& client,
         const layer_state_t& s)
 {
-    uint32_t flags = 0;
     sp<Layer> layer(client->getLayerUser(s.surface));
-    if (layer != 0) {
-        const uint32_t what = s.what;
-        bool geometryAppliesWithResize =
-                what & layer_state_t::eGeometryAppliesWithResize;
-        if (what & layer_state_t::ePositionChanged) {
-            if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) {
-                flags |= eTraversalNeeded;
-            }
+    if (layer == nullptr) {
+        return 0;
+    }
+
+    if (layer->isPendingRemoval()) {
+        ALOGW("Attempting to set client state on removed layer: %s", layer->getName().string());
+        return 0;
+    }
+
+    uint32_t flags = 0;
+
+    const uint32_t what = s.what;
+    bool geometryAppliesWithResize =
+            what & layer_state_t::eGeometryAppliesWithResize;
+    if (what & layer_state_t::ePositionChanged) {
+        if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) {
+            flags |= eTraversalNeeded;
         }
-        if (what & layer_state_t::eLayerChanged) {
-            // NOTE: index needs to be calculated before we update the state
-            const auto& p = layer->getParent();
-            if (p == nullptr) {
-                ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
-                if (layer->setLayer(s.z) && idx >= 0) {
-                    mCurrentState.layersSortedByZ.removeAt(idx);
-                    mCurrentState.layersSortedByZ.add(layer);
-                    // we need traversal (state changed)
-                    // AND transaction (list changed)
-                    flags |= eTransactionNeeded|eTraversalNeeded;
-                }
-            } else {
-                if (p->setChildLayer(layer, s.z)) {
-                    flags |= eTransactionNeeded|eTraversalNeeded;
-                }
-            }
-        }
-        if (what & layer_state_t::eRelativeLayerChanged) {
+    }
+    if (what & layer_state_t::eLayerChanged) {
+        // NOTE: index needs to be calculated before we update the state
+        const auto& p = layer->getParent();
+        if (p == nullptr) {
             ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
-            if (layer->setRelativeLayer(s.relativeLayerHandle, s.z)) {
-                mCurrentState.layersSortedByZ.removeAt(idx);
-                mCurrentState.layersSortedByZ.add(layer);
-                flags |= eTransactionNeeded|eTraversalNeeded;
-            }
-        }
-        if (what & layer_state_t::eSizeChanged) {
-            if (layer->setSize(s.w, s.h)) {
-                flags |= eTraversalNeeded;
-            }
-        }
-        if (what & layer_state_t::eAlphaChanged) {
-            if (layer->setAlpha(s.alpha))
-                flags |= eTraversalNeeded;
-        }
-        if (what & layer_state_t::eColorChanged) {
-            if (layer->setColor(s.color))
-                flags |= eTraversalNeeded;
-        }
-        if (what & layer_state_t::eMatrixChanged) {
-            if (layer->setMatrix(s.matrix))
-                flags |= eTraversalNeeded;
-        }
-        if (what & layer_state_t::eTransparentRegionChanged) {
-            if (layer->setTransparentRegionHint(s.transparentRegion))
-                flags |= eTraversalNeeded;
-        }
-        if (what & layer_state_t::eFlagsChanged) {
-            if (layer->setFlags(s.flags, s.mask))
-                flags |= eTraversalNeeded;
-        }
-        if (what & layer_state_t::eCropChanged) {
-            if (layer->setCrop(s.crop, !geometryAppliesWithResize))
-                flags |= eTraversalNeeded;
-        }
-        if (what & layer_state_t::eFinalCropChanged) {
-            if (layer->setFinalCrop(s.finalCrop, !geometryAppliesWithResize))
-                flags |= eTraversalNeeded;
-        }
-        if (what & layer_state_t::eLayerStackChanged) {
-            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
-            // We only allow setting layer stacks for top level layers,
-            // everything else inherits layer stack from its parent.
-            if (layer->hasParent()) {
-                ALOGE("Attempt to set layer stack on layer with parent (%s) is invalid",
-                        layer->getName().string());
-            } else if (idx < 0) {
-                ALOGE("Attempt to set layer stack on layer without parent (%s) that "
-                        "that also does not appear in the top level layer list. Something"
-                        " has gone wrong.", layer->getName().string());
-            } else if (layer->setLayerStack(s.layerStack)) {
+            if (layer->setLayer(s.z) && idx >= 0) {
                 mCurrentState.layersSortedByZ.removeAt(idx);
                 mCurrentState.layersSortedByZ.add(layer);
                 // we need traversal (state changed)
                 // AND transaction (list changed)
                 flags |= eTransactionNeeded|eTraversalNeeded;
             }
-        }
-        if (what & layer_state_t::eDeferTransaction) {
-            if (s.barrierHandle != nullptr) {
-                layer->deferTransactionUntil(s.barrierHandle, s.frameNumber);
-            } else if (s.barrierGbp != nullptr) {
-                const sp<IGraphicBufferProducer>& gbp = s.barrierGbp;
-                if (authenticateSurfaceTextureLocked(gbp)) {
-                    const auto& otherLayer =
-                        (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
-                    layer->deferTransactionUntil(otherLayer, s.frameNumber);
-                } else {
-                    ALOGE("Attempt to defer transaction to to an"
-                            " unrecognized GraphicBufferProducer");
-                }
-            }
-            // We don't trigger a traversal here because if no other state is
-            // changed, we don't want this to cause any more work
-        }
-        if (what & layer_state_t::eReparent) {
-            if (layer->reparent(s.parentHandleForChild)) {
+        } else {
+            if (p->setChildLayer(layer, s.z)) {
                 flags |= eTransactionNeeded|eTraversalNeeded;
             }
         }
-        if (what & layer_state_t::eReparentChildren) {
-            if (layer->reparentChildren(s.reparentHandle)) {
-                flags |= eTransactionNeeded|eTraversalNeeded;
+    }
+    if (what & layer_state_t::eRelativeLayerChanged) {
+        ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
+        if (layer->setRelativeLayer(s.relativeLayerHandle, s.z)) {
+            mCurrentState.layersSortedByZ.removeAt(idx);
+            mCurrentState.layersSortedByZ.add(layer);
+            flags |= eTransactionNeeded|eTraversalNeeded;
+        }
+    }
+    if (what & layer_state_t::eSizeChanged) {
+        if (layer->setSize(s.w, s.h)) {
+            flags |= eTraversalNeeded;
+        }
+    }
+    if (what & layer_state_t::eAlphaChanged) {
+        if (layer->setAlpha(s.alpha))
+            flags |= eTraversalNeeded;
+    }
+    if (what & layer_state_t::eColorChanged) {
+        if (layer->setColor(s.color))
+            flags |= eTraversalNeeded;
+    }
+    if (what & layer_state_t::eMatrixChanged) {
+        if (layer->setMatrix(s.matrix))
+            flags |= eTraversalNeeded;
+    }
+    if (what & layer_state_t::eTransparentRegionChanged) {
+        if (layer->setTransparentRegionHint(s.transparentRegion))
+            flags |= eTraversalNeeded;
+    }
+    if (what & layer_state_t::eFlagsChanged) {
+        if (layer->setFlags(s.flags, s.mask))
+            flags |= eTraversalNeeded;
+    }
+    if (what & layer_state_t::eCropChanged) {
+        if (layer->setCrop(s.crop, !geometryAppliesWithResize))
+            flags |= eTraversalNeeded;
+    }
+    if (what & layer_state_t::eFinalCropChanged) {
+        if (layer->setFinalCrop(s.finalCrop, !geometryAppliesWithResize))
+            flags |= eTraversalNeeded;
+    }
+    if (what & layer_state_t::eLayerStackChanged) {
+        ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
+        // We only allow setting layer stacks for top level layers,
+        // everything else inherits layer stack from its parent.
+        if (layer->hasParent()) {
+            ALOGE("Attempt to set layer stack on layer with parent (%s) is invalid",
+                    layer->getName().string());
+        } else if (idx < 0) {
+            ALOGE("Attempt to set layer stack on layer without parent (%s) that "
+                    "that also does not appear in the top level layer list. Something"
+                    " has gone wrong.", layer->getName().string());
+        } else if (layer->setLayerStack(s.layerStack)) {
+            mCurrentState.layersSortedByZ.removeAt(idx);
+            mCurrentState.layersSortedByZ.add(layer);
+            // we need traversal (state changed)
+            // AND transaction (list changed)
+            flags |= eTransactionNeeded|eTraversalNeeded;
+        }
+    }
+    if (what & layer_state_t::eDeferTransaction) {
+        if (s.barrierHandle != nullptr) {
+            layer->deferTransactionUntil(s.barrierHandle, s.frameNumber);
+        } else if (s.barrierGbp != nullptr) {
+            const sp<IGraphicBufferProducer>& gbp = s.barrierGbp;
+            if (authenticateSurfaceTextureLocked(gbp)) {
+                const auto& otherLayer =
+                    (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
+                layer->deferTransactionUntil(otherLayer, s.frameNumber);
+            } else {
+                ALOGE("Attempt to defer transaction to to an"
+                        " unrecognized GraphicBufferProducer");
             }
         }
-        if (what & layer_state_t::eDetachChildren) {
-            layer->detachChildren();
+        // We don't trigger a traversal here because if no other state is
+        // changed, we don't want this to cause any more work
+    }
+    if (what & layer_state_t::eReparent) {
+        if (layer->reparent(s.parentHandleForChild)) {
+            flags |= eTransactionNeeded|eTraversalNeeded;
         }
-        if (what & layer_state_t::eOverrideScalingModeChanged) {
-            layer->setOverrideScalingMode(s.overrideScalingMode);
-            // We don't trigger a traversal here because if no other state is
-            // changed, we don't want this to cause any more work
+    }
+    if (what & layer_state_t::eReparentChildren) {
+        if (layer->reparentChildren(s.reparentHandle)) {
+            flags |= eTransactionNeeded|eTraversalNeeded;
         }
     }
+    if (what & layer_state_t::eDetachChildren) {
+        layer->detachChildren();
+    }
+    if (what & layer_state_t::eOverrideScalingModeChanged) {
+        layer->setOverrideScalingMode(s.overrideScalingMode);
+        // We don't trigger a traversal here because if no other state is
+        // changed, we don't want this to cause any more work
+    }
     return flags;
 }
 
@@ -3208,14 +3221,15 @@
 
     switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
         case ISurfaceComposerClient::eFXSurfaceNormal:
-            result = createNormalLayer(client,
+            result = createBufferLayer(client,
                     uniqueName, w, h, flags, format,
                     handle, gbp, &layer);
+
             break;
         case ISurfaceComposerClient::eFXSurfaceColor:
             result = createColorLayer(client,
                     uniqueName, w, h, flags,
-                    handle, gbp, &layer);
+                    handle, &layer);
             break;
         default:
             result = BAD_VALUE;
@@ -3269,7 +3283,7 @@
     return uniqueName;
 }
 
-status_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
+status_t SurfaceFlinger::createBufferLayer(const sp<Client>& client,
         const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
         sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
 {
@@ -3284,24 +3298,24 @@
         break;
     }
 
-    *outLayer = new Layer(this, client, name, w, h, flags);
-    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
+    sp<BufferLayer> layer = new BufferLayer(this, client, name, w, h, flags);
+    status_t err = layer->setBuffers(w, h, format, flags);
     if (err == NO_ERROR) {
-        *handle = (*outLayer)->getHandle();
-        *gbp = (*outLayer)->getProducer();
+        *handle = layer->getHandle();
+        *gbp = layer->getProducer();
+        *outLayer = layer;
     }
 
-    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
+    ALOGE_IF(err, "createBufferLayer() failed (%s)", strerror(-err));
     return err;
 }
 
 status_t SurfaceFlinger::createColorLayer(const sp<Client>& client,
         const String8& name, uint32_t w, uint32_t h, uint32_t flags,
-        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
+        sp<IBinder>* handle, sp<Layer>* outLayer)
 {
     *outLayer = new ColorLayer(this, client, name, w, h, flags);
     *handle = (*outLayer)->getHandle();
-    *gbp = (*outLayer)->getProducer();
     return NO_ERROR;
 }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index d0f4699..d10b41b 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -244,6 +244,7 @@
     friend class DisplayEventConnection;
     friend class EventThread;
     friend class Layer;
+    friend class BufferLayer;
     friend class MonitoredProducer;
 
     // This value is specified in number of frames.  Log frame stats at most
@@ -419,14 +420,14 @@
             uint32_t windowType, uint32_t ownerUid, sp<IBinder>* handle,
             sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent);
 
-    status_t createNormalLayer(const sp<Client>& client, const String8& name,
+    status_t createBufferLayer(const sp<Client>& client, const String8& name,
             uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
             sp<IBinder>* outHandle, sp<IGraphicBufferProducer>* outGbp,
             sp<Layer>* outLayer);
 
     status_t createColorLayer(const sp<Client>& client, const String8& name,
             uint32_t w, uint32_t h, uint32_t flags, sp<IBinder>* outHandle,
-            sp<IGraphicBufferProducer>* outGbp, sp<Layer>* outLayer);
+            sp<Layer>* outLayer);
 
     String8 getUniqueLayerName(const String8& name);
 
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 952023e..714c23d 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -70,6 +70,7 @@
 #include "EventControlThread.h"
 #include "EventThread.h"
 #include "Layer.h"
+#include "BufferLayer.h"
 #include "LayerVector.h"
 #include "ColorLayer.h"
 #include "MonitoredProducer.h"
@@ -2733,14 +2734,14 @@
 
     switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
         case ISurfaceComposerClient::eFXSurfaceNormal:
-            result = createNormalLayer(client,
+            result = createBufferLayer(client,
                     uniqueName, w, h, flags, format,
                     handle, gbp, &layer);
             break;
         case ISurfaceComposerClient::eFXSurfaceColor:
             result = createColorLayer(client,
                     uniqueName, w, h, flags,
-                    handle, gbp, &layer);
+                    handle, &layer);
             break;
         default:
             result = BAD_VALUE;
@@ -2787,7 +2788,7 @@
     return uniqueName;
 }
 
-status_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
+status_t SurfaceFlinger::createBufferLayer(const sp<Client>& client,
         const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
         sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
 {
@@ -2802,24 +2803,24 @@
         break;
     }
 
-    *outLayer = new Layer(this, client, name, w, h, flags);
-    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
+    sp<BufferLayer> layer = new BufferLayer(this, client, name, w, h, flags);
+    status_t err = layer->setBuffers(w, h, format, flags);
     if (err == NO_ERROR) {
-        *handle = (*outLayer)->getHandle();
-        *gbp = (*outLayer)->getProducer();
+        *handle = layer->getHandle();
+        *gbp = layer->getProducer();
+        *outLayer = layer;
     }
 
-    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
+    ALOGE_IF(err, "createBufferLayer() failed (%s)", strerror(-err));
     return err;
 }
 
 status_t SurfaceFlinger::createColorLayer(const sp<Client>& client,
         const String8& name, uint32_t w, uint32_t h, uint32_t flags,
-        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
+        sp<IBinder>* handle, sp<Layer>* outLayer)
 {
     *outLayer = new ColorLayer(this, client, name, w, h, flags);
     *handle = (*outLayer)->getHandle();
-    *gbp = (*outLayer)->getProducer();
     return NO_ERROR;
 }
 
diff --git a/services/vr/hardware_composer/Android.bp b/services/vr/hardware_composer/Android.bp
index 9201520..e92b8d8 100644
--- a/services/vr/hardware_composer/Android.bp
+++ b/services/vr/hardware_composer/Android.bp
@@ -44,6 +44,13 @@
 
   cflags: [
     "-DLOG_TAG=\"vr_hwc\"",
+    "-Wall",
+    "-Werror",
+    // mVrClient unused in vr_composer_client.cpp
+    "-Wno-error=unused-private-field",
+    // Warnings in vr_hwc.cpp to be fixed after sync of goog/master.
+    "-Wno-sign-compare",
+    "-Wno-unused-parameter",
   ],
 
 }
@@ -63,6 +70,11 @@
   },
   export_include_dirs: ["aidl"],
 
+  cflags: [
+    "-Wall",
+    "-Werror",
+  ],
+
   shared_libs: [
     "libbinder",
     "libui",
@@ -92,6 +104,8 @@
   ],
   cflags: [
     "-DLOG_TAG=\"vr_hwc\"",
+    "-Wall",
+    "-Werror",
   ],
 }
 
@@ -120,6 +134,8 @@
   ],
   cflags: [
     "-DLOG_TAG=\"vr_hwc\"",
+    "-Wall",
+    "-Werror",
   ],
   init_rc: [
     "vr_hwc.rc",
@@ -137,6 +153,13 @@
     // symbols in the *-binder library get optimized out.
     "libvr_hwc-binder",
   ],
+  cflags: [
+    "-Wall",
+    "-Werror",
+    // warnings in vr_composer_test.cpp to be fixed after merge of goog/master
+    "-Wno-sign-compare",
+    "-Wno-unused-parameter",
+  ],
   shared_libs: [
     "libbase",
     "libbinder",
diff --git a/services/vr/performanced/Android.mk b/services/vr/performanced/Android.mk
index dbc66f1..1470234 100644
--- a/services/vr/performanced/Android.mk
+++ b/services/vr/performanced/Android.mk
@@ -36,6 +36,7 @@
 LOCAL_SRC_FILES := $(sourceFiles)
 LOCAL_CFLAGS := -DLOG_TAG=\"performanced\"
 LOCAL_CFLAGS += -DTRACE=0
+LOCAL_CFLAGS += -Wall -Werror
 LOCAL_STATIC_LIBRARIES := $(staticLibraries)
 LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
 LOCAL_MODULE := performanced
diff --git a/services/vr/performanced/directory_reader.h b/services/vr/performanced/directory_reader.h
index 7d7ecc5..b9d27c3 100644
--- a/services/vr/performanced/directory_reader.h
+++ b/services/vr/performanced/directory_reader.h
@@ -19,7 +19,7 @@
     directory_ = fdopendir(directory_fd.get());
     error_ = errno;
     if (directory_ != nullptr)
-      directory_fd.release();
+      (void) directory_fd.release(); // ignore return result?
   }
 
   ~DirectoryReader() {
diff --git a/services/vr/virtual_touchpad/Android.bp b/services/vr/virtual_touchpad/Android.bp
index 6b11ce3..7196b2b 100644
--- a/services/vr/virtual_touchpad/Android.bp
+++ b/services/vr/virtual_touchpad/Android.bp
@@ -23,7 +23,11 @@
     shared_libs: shared_libs,
     header_libs: header_libraries,
     cppflags: ["-std=c++11"],
-    cflags: ["-DLOG_TAG=\"VrVirtualTouchpad\""],
+    cflags: [
+        "-DLOG_TAG=\"VrVirtualTouchpad\"",
+        "-Wall",
+        "-Werror",
+    ],
     name: "libvirtualtouchpad",
     tags: ["optional"],
 }
@@ -44,6 +48,10 @@
     srcs: test_src_files,
     static_libs: test_static_libs,
     header_libs: header_libraries,
+    cflags = [
+        "-Wall",
+        "-Werror",
+    ],
     cppflags = [
         "-std=c++11",
     ],
@@ -83,6 +91,8 @@
     cppflags: ["-std=c++11"],
     cflags: [
         "-DLOG_TAG=\"VrVirtualTouchpad\"",
+        "-Wall",
+        "-Werror",
     ],
     host_ldlibs: ["-llog"],
     name: "virtual_touchpad",
@@ -112,7 +122,11 @@
     shared_libs: client_shared_libs,
     header_libs: header_libraries,
     cppflags: ["-std=c++11"],
-    cflags: ["-DLOG_TAG=\"VirtualTouchpadClient\""],
+    cflags: [
+        "-DLOG_TAG=\"VirtualTouchpadClient\"",
+        "-Wall",
+        "-Werror",
+    ],
     host_ldlibs: ["-llog"],
     name: "libvirtualtouchpadclient",
     tags: ["optional"],
diff --git a/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp b/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
index b19b018..198ed06 100644
--- a/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
+++ b/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
@@ -110,17 +110,6 @@
   EvdevInjectorForTesting injector[kTouchpads];
 };
 
-void DumpDifference(const char* expect, const char* actual) {
-  printf("  common: ");
-  while (*expect && *expect == *actual) {
-    putchar(*expect);
-    ++expect;
-    ++actual;
-  }
-  printf("\n  expect: %s\n", expect);
-  printf("  actual: %s\n", actual);
-}
-
 }  // anonymous namespace
 
 class VirtualTouchpadTest : public testing::Test {};
@@ -153,7 +142,6 @@
   }
   const int32_t width = 1 + uidev->absmax[ABS_MT_POSITION_X];
   const int32_t height = 1 + uidev->absmax[ABS_MT_POSITION_Y];
-  const int32_t slots = uidev->absmax[ABS_MT_SLOT];
 
   for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
     SCOPED_TRACE(t);
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index dded1e3..ade0bde 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -94,7 +94,6 @@
     ~CreateInfoWrapper();
 
     VkResult Validate();
-    void DowngradeApiVersion();
 
     const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const;
     const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const;
@@ -132,8 +131,6 @@
         VkDeviceCreateInfo dev_info_;
     };
 
-    VkApplicationInfo application_info_;
-
     ExtensionFilter extension_filter_;
 
     std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions_;
@@ -540,15 +537,6 @@
     }
 }
 
-void CreateInfoWrapper::DowngradeApiVersion() {
-    // If pApplicationInfo is NULL, apiVersion is assumed to be 1.0:
-    if (instance_info_.pApplicationInfo) {
-        application_info_ = *instance_info_.pApplicationInfo;
-        instance_info_.pApplicationInfo = &application_info_;
-        application_info_.apiVersion = VK_API_VERSION_1_0;
-    }
-}
-
 VKAPI_ATTR void* DefaultAllocate(void*,
                                  size_t size,
                                  size_t alignment,
@@ -903,33 +891,6 @@
 
     data->hook_extensions |= wrapper.GetHookExtensions();
 
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wold-style-cast"
-    uint32_t api_version = ((pCreateInfo->pApplicationInfo)
-                                ? pCreateInfo->pApplicationInfo->apiVersion
-                                : VK_API_VERSION_1_0);
-    uint32_t api_major_version = VK_VERSION_MAJOR(api_version);
-    uint32_t api_minor_version = VK_VERSION_MINOR(api_version);
-    uint32_t icd_api_version;
-    PFN_vkEnumerateInstanceVersion pfn_enumerate_instance_version =
-        reinterpret_cast<PFN_vkEnumerateInstanceVersion>(
-            Hal::Device().GetInstanceProcAddr(NULL,
-                                              "vkEnumerateInstanceVersion"));
-    if (!pfn_enumerate_instance_version) {
-        icd_api_version = VK_API_VERSION_1_0;
-    } else {
-        result = (*pfn_enumerate_instance_version)(&icd_api_version);
-    }
-    uint32_t icd_api_major_version = VK_VERSION_MAJOR(icd_api_version);
-    uint32_t icd_api_minor_version = VK_VERSION_MINOR(icd_api_version);
-
-    if ((icd_api_major_version == 1) && (icd_api_minor_version == 0) &&
-        ((api_major_version > 1) || (api_minor_version > 0))) {
-        api_version = VK_API_VERSION_1_0;
-        wrapper.DowngradeApiVersion();
-    }
-#pragma clang diagnostic pop
-
     // call into the driver
     VkInstance instance;
     result = Hal::Device().CreateInstance(