diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 7115ad6..2a78aa5 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -20,6 +20,7 @@
     LayerVector.cpp \
     MessageQueue.cpp \
     MonitoredProducer.cpp \
+    SurfaceFlinger.cpp \
     SurfaceFlingerConsumer.cpp \
     SurfaceInterceptor.cpp \
     SurfaceTracing.cpp \
@@ -27,6 +28,7 @@
     DisplayHardware/ComposerHal.cpp \
     DisplayHardware/FramebufferSurface.cpp \
     DisplayHardware/HWC2.cpp \
+    DisplayHardware/HWComposer.cpp \
     DisplayHardware/HWComposerBufferCache.cpp \
     DisplayHardware/PowerHAL.cpp \
     DisplayHardware/VirtualDisplaySurface.cpp \
@@ -53,17 +55,6 @@
 LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\"
 LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
 
-ifeq ($(TARGET_USES_HWC2),true)
-    LOCAL_CFLAGS += -DUSE_HWC2
-    LOCAL_SRC_FILES += \
-        SurfaceFlinger.cpp \
-        DisplayHardware/HWComposer.cpp
-else
-    LOCAL_SRC_FILES += \
-        SurfaceFlinger_hwc1.cpp \
-        DisplayHardware/HWComposer_hwc1.cpp
-endif
-
 LOCAL_CFLAGS += -fvisibility=hidden -Werror=format
 
 LOCAL_STATIC_LIBRARIES := \
@@ -128,10 +119,6 @@
 
 LOCAL_INIT_RC := surfaceflinger.rc
 
-ifeq ($(TARGET_USES_HWC2),true)
-    LOCAL_CFLAGS += -DUSE_HWC2
-endif
-
 LOCAL_SRC_FILES := \
     main_surfaceflinger.cpp
 
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index fc0949d..0c1693b 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -61,9 +61,7 @@
         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);
@@ -90,14 +88,12 @@
     }
     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() {
@@ -265,22 +261,12 @@
     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();
@@ -376,7 +362,6 @@
     return mSurfaceFlingerConsumer->getTransformToDisplayInverse();
 }
 
-#ifdef USE_HWC2
 void BufferLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
     if (!mSurfaceFlingerConsumer->releasePendingBuffer()) {
         return;
@@ -393,7 +378,6 @@
                                       std::move(releaseFenceTime));
     }
 }
-#endif
 
 Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) {
     ATRACE_CALL();
@@ -523,16 +507,6 @@
     {
         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;
@@ -604,7 +578,6 @@
     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.
@@ -676,28 +649,6 @@
     }
 }
 
-#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.
@@ -871,9 +822,7 @@
     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();
 }
@@ -913,7 +862,6 @@
 }
 
 bool BufferLayer::headFenceHasSignaled() const {
-#ifdef USE_HWC2
     if (latchUnsignaledBuffers()) {
         return true;
     }
@@ -930,9 +878,6 @@
         return true;
     }
     return mQueueItems[0].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
-#else
-    return true;
-#endif
 }
 
 uint32_t BufferLayer::getEffectiveScalingMode() const {
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 418f032..078302b 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -105,12 +105,7 @@
     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;
@@ -124,10 +119,8 @@
 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
@@ -139,12 +132,7 @@
     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;
 
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index 8a17f88..292e1a7 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -61,7 +61,6 @@
     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();
@@ -89,7 +88,6 @@
               static_cast<int32_t>(error));
     }
 }
-#endif
 
 // ---------------------------------------------------------------------------
 
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index debd3c3..4022b31 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -42,21 +42,14 @@
     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*/,
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 0244c1b..ef7d482 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -38,9 +38,7 @@
 
 #include "DisplayHardware/DisplaySurface.h"
 #include "DisplayHardware/HWComposer.h"
-#ifdef USE_HWC2
 #include "DisplayHardware/HWC2.h"
-#endif
 #include "RenderEngine/RenderEngine.h"
 
 #include "clz.h"
@@ -86,9 +84,6 @@
         const sp<SurfaceFlinger>& flinger,
         DisplayType type,
         int32_t hwcId,
-#ifndef USE_HWC2
-        int format,
-#endif
         bool isSecure,
         const wp<IBinder>& displayToken,
         const sp<DisplaySurface>& displaySurface,
@@ -105,9 +100,6 @@
       mSurface(EGL_NO_SURFACE),
       mDisplayWidth(),
       mDisplayHeight(),
-#ifndef USE_HWC2
-      mFormat(),
-#endif
       mFlags(),
       mPageFlipCount(),
       mIsSecure(isSecure),
@@ -121,12 +113,8 @@
     mNativeWindow = surface = new Surface(producer, false);
     ANativeWindow* const window = mNativeWindow.get();
 
-#ifdef USE_HWC2
     mActiveColorMode = HAL_COLOR_MODE_NATIVE;
     mDisplayHasWideColor = supportWideColor;
-#else
-    (void) supportWideColor;
-#endif
     /*
      * Create our display's surface
      */
@@ -134,13 +122,8 @@
     EGLSurface eglSurface;
     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     if (config == EGL_NO_CONFIG) {
-#ifdef USE_HWC2
         config = RenderEngine::chooseEglConfig(display, PIXEL_FORMAT_RGBA_8888,
                                                /*logConfig*/ false);
-#else
-        config = RenderEngine::chooseEglConfig(display, format,
-                                               /*logConfig*/ false);
-#endif
     }
     eglSurface = eglCreateWindowSurface(display, config, window, NULL);
     eglQuerySurface(display, eglSurface, EGL_WIDTH,  &mDisplayWidth);
@@ -159,9 +142,6 @@
     mConfig = config;
     mDisplay = display;
     mSurface = eglSurface;
-#ifndef USE_HWC2
-    mFormat = format;
-#endif
     mPageFlipCount = 0;
     mViewport.makeInvalid();
     mFrame.makeInvalid();
@@ -202,10 +182,6 @@
 void DisplayDevice::disconnect(HWComposer& hwc) {
     if (mHwcDisplayId >= 0) {
         hwc.disconnectDisplay(mHwcDisplayId);
-#ifndef USE_HWC2
-        if (mHwcDisplayId >= DISPLAY_VIRTUAL)
-            hwc.freeDisplayId(mHwcDisplayId);
-#endif
         mHwcDisplayId = -1;
     }
 }
@@ -222,12 +198,6 @@
     return mDisplayHeight;
 }
 
-#ifndef USE_HWC2
-PixelFormat DisplayDevice::getFormat() const {
-    return mFormat;
-}
-#endif
-
 EGLSurface DisplayDevice::getEGLSurface() const {
     return mSurface;
 }
@@ -243,12 +213,6 @@
     return mPageFlipCount;
 }
 
-#ifndef USE_HWC2
-status_t DisplayDevice::compositionComplete() const {
-    return mDisplaySurface->compositionComplete();
-}
-#endif
-
 void DisplayDevice::flip(const Region& dirty) const
 {
     mFlinger->getRenderEngine().checkErrors();
@@ -269,7 +233,6 @@
     return mDisplaySurface->beginFrame(mustRecompose);
 }
 
-#ifdef USE_HWC2
 status_t DisplayDevice::prepareFrame(HWComposer& hwc) {
     status_t error = hwc.prepare(*this);
     if (error != NO_ERROR) {
@@ -293,41 +256,9 @@
     }
     return mDisplaySurface->prepareFrame(compositionType);
 }
-#else
-status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const {
-    DisplaySurface::CompositionType compositionType;
-    bool haveGles = hwc.hasGlesComposition(mHwcDisplayId);
-    bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId);
-    if (haveGles && haveHwc) {
-        compositionType = DisplaySurface::COMPOSITION_MIXED;
-    } else if (haveGles) {
-        compositionType = DisplaySurface::COMPOSITION_GLES;
-    } else if (haveHwc) {
-        compositionType = DisplaySurface::COMPOSITION_HWC;
-    } else {
-        // Nothing to do -- when turning the screen off we get a frame like
-        // this. Call it a HWC frame since we won't be doing any GLES work but
-        // will do a prepare/set cycle.
-        compositionType = DisplaySurface::COMPOSITION_HWC;
-    }
-    return mDisplaySurface->prepareFrame(compositionType);
-}
-#endif
 
 void DisplayDevice::swapBuffers(HWComposer& hwc) const {
-#ifdef USE_HWC2
     if (hwc.hasClientComposition(mHwcDisplayId)) {
-#else
-    // We need to call eglSwapBuffers() if:
-    //  (1) we don't have a hardware composer, or
-    //  (2) we did GLES composition this frame, and either
-    //    (a) we have framebuffer target support (not present on legacy
-    //        devices, where HWComposer::commit() handles things); or
-    //    (b) this is a virtual display
-    if (hwc.initCheck() != NO_ERROR ||
-            (hwc.hasGlesComposition(mHwcDisplayId) &&
-             (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) {
-#endif
         EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
         if (!success) {
             EGLint error = eglGetError();
@@ -349,17 +280,9 @@
     }
 }
 
-#ifdef USE_HWC2
 void DisplayDevice::onSwapBuffersCompleted() const {
     mDisplaySurface->onFrameCommitted();
 }
-#else
-void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
-    if (hwc.initCheck() == NO_ERROR) {
-        mDisplaySurface->onFrameCommitted();
-    }
-}
-#endif
 
 uint32_t DisplayDevice::getFlags() const
 {
@@ -437,7 +360,6 @@
 }
 
 // ----------------------------------------------------------------------------
-#ifdef USE_HWC2
 void DisplayDevice::setActiveColorMode(android_color_mode_t mode) {
     mActiveColorMode = mode;
 }
@@ -450,7 +372,6 @@
     ANativeWindow* const window = mNativeWindow.get();
     native_window_set_buffers_data_space(window, dataspace);
 }
-#endif
 
 // ----------------------------------------------------------------------------
 
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 49fef58..50e30b2 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -21,18 +21,13 @@
 
 #include <stdlib.h>
 
-#ifndef USE_HWC2
-#include <ui/PixelFormat.h>
-#endif
 #include <ui/Region.h>
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
-#ifdef USE_HWC2
 #include <binder/IBinder.h>
 #include <utils/RefBase.h>
-#endif
 #include <utils/Mutex.h>
 #include <utils/String8.h>
 #include <utils/Timers.h>
@@ -41,9 +36,7 @@
 #include <hardware/hwcomposer_defs.h>
 #include "RenderArea.h"
 
-#ifdef USE_HWC2
 #include <memory>
-#endif
 
 struct ANativeWindow;
 
@@ -90,9 +83,6 @@
             const sp<SurfaceFlinger>& flinger,
             DisplayType type,
             int32_t hwcId,
-#ifndef USE_HWC2
-            int format,
-#endif
             bool isSecure,
             const wp<IBinder>& displayToken,
             const sp<DisplaySurface>& displaySurface,
@@ -117,9 +107,6 @@
 
     int         getWidth() const;
     int         getHeight() const;
-#ifndef USE_HWC2
-    PixelFormat getFormat() const;
-#endif
     uint32_t    getFlags() const;
 
     EGLSurface  getEGLSurface() const;
@@ -150,24 +137,13 @@
     // We pass in mustRecompose so we can keep VirtualDisplaySurface's state
     // machine happy without actually queueing a buffer if nothing has changed
     status_t beginFrame(bool mustRecompose) const;
-#ifdef USE_HWC2
     status_t prepareFrame(HWComposer& hwc);
     bool getWideColorSupport() const { return mDisplayHasWideColor; }
-#else
-    status_t prepareFrame(const HWComposer& hwc) const;
-#endif
 
     void swapBuffers(HWComposer& hwc) const;
-#ifndef USE_HWC2
-    status_t compositionComplete() const;
-#endif
 
     // called after h/w composer has completed its set() call
-#ifdef USE_HWC2
     void onSwapBuffersCompleted() const;
-#else
-    void onSwapBuffersCompleted(HWComposer& hwc) const;
-#endif
 
     Rect getBounds() const {
         return Rect(mDisplayWidth, mDisplayHeight);
@@ -189,11 +165,9 @@
     void setPowerMode(int mode);
     bool isDisplayOn() const;
 
-#ifdef USE_HWC2
     android_color_mode_t getActiveColorMode() const;
     void setActiveColorMode(android_color_mode_t mode);
     void setCompositionDataSpace(android_dataspace dataspace);
-#endif
 
     /* ------------------------------------------------------------------------
      * Display active config management.
@@ -228,9 +202,6 @@
     EGLSurface      mSurface;
     int             mDisplayWidth;
     int             mDisplayHeight;
-#ifndef USE_HWC2
-    PixelFormat     mFormat;
-#endif
     uint32_t        mFlags;
     mutable uint32_t mPageFlipCount;
     String8         mDisplayName;
@@ -269,7 +240,6 @@
     int mPowerMode;
     // Current active config
     int mActiveConfig;
-#ifdef USE_HWC2
     // current active color mode
     android_color_mode_t mActiveColorMode;
 
@@ -277,7 +247,6 @@
     // Initialized by SurfaceFlinger when the DisplayDevice is created.
     // Fed to RenderEngine during composition.
     bool mDisplayHasWideColor;
-#endif
 };
 
 struct DisplayDeviceState {
@@ -319,12 +288,10 @@
     bool isSecure() const override { return mDevice->isSecure(); }
     bool needsFiltering() const override { return mDevice->needsFiltering(); }
     Rect getSourceCrop() const override { return mSourceCrop; }
-#ifdef USE_HWC2
     bool getWideColorSupport() const override { return mDevice->getWideColorSupport(); }
     android_color_mode_t getActiveColorMode() const override {
         return mDevice->getActiveColorMode();
     }
-#endif
 
 private:
     const sp<const DisplayDevice> mDevice;
diff --git a/services/surfaceflinger/DisplayHardware/DisplaySurface.h b/services/surfaceflinger/DisplayHardware/DisplaySurface.h
index cb08f08..f744f5c 100644
--- a/services/surfaceflinger/DisplayHardware/DisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/DisplaySurface.h
@@ -50,14 +50,6 @@
     };
     virtual status_t prepareFrame(CompositionType compositionType) = 0;
 
-#ifndef USE_HWC2
-    // Should be called when composition rendering is complete for a frame (but
-    // eglSwapBuffers hasn't necessarily been called). Required by certain
-    // older drivers for synchronization.
-    // TODO: Remove this when we drop support for HWC 1.0.
-    virtual status_t compositionComplete() = 0;
-#endif
-
     // Inform the surface that GLES composition is complete for this frame, and
     // the surface should make sure that HWComposer has the correct buffer for
     // this frame. Some implementations may only push a new buffer to
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 93c6d54..182629c 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -59,32 +59,21 @@
     mCurrentBufferSlot(-1),
     mCurrentBuffer(),
     mCurrentFence(Fence::NO_FENCE),
-#ifdef USE_HWC2
     mHwc(hwc),
     mHasPendingRelease(false),
     mPreviousBufferSlot(BufferQueue::INVALID_BUFFER_SLOT),
     mPreviousBuffer()
-#else
-    mHwc(hwc)
-#endif
 {
-#ifdef USE_HWC2
     ALOGV("Creating for display %d", disp);
-#endif
 
     mName = "FramebufferSurface";
     mConsumer->setConsumerName(mName);
     mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
                                        GRALLOC_USAGE_HW_RENDER |
                                        GRALLOC_USAGE_HW_COMPOSER);
-#ifdef USE_HWC2
     const auto& activeConfig = mHwc.getActiveConfig(disp);
     mConsumer->setDefaultBufferSize(activeConfig->getWidth(),
             activeConfig->getHeight());
-#else
-    mConsumer->setDefaultBufferFormat(mHwc.getFormat(disp));
-    mConsumer->setDefaultBufferSize(mHwc.getWidth(disp), mHwc.getHeight(disp));
-#endif
     mConsumer->setMaxAcquiredBufferCount(
             SurfaceFlinger::maxFrameBufferAcquiredBuffers - 1);
 }
@@ -98,7 +87,6 @@
 }
 
 status_t FramebufferSurface::advanceFrame() {
-#ifdef USE_HWC2
     uint32_t slot = 0;
     sp<GraphicBuffer> buf;
     sp<Fence> acquireFence(Fence::NO_FENCE);
@@ -110,32 +98,18 @@
                 strerror(-result), result);
     }
     return result;
-#else
-    // Once we remove FB HAL support, we can call nextBuffer() from here
-    // instead of using onFrameAvailable(). No real benefit, except it'll be
-    // more like VirtualDisplaySurface.
-    return NO_ERROR;
-#endif
 }
 
-#ifdef USE_HWC2
 status_t FramebufferSurface::nextBuffer(uint32_t& outSlot,
         sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence,
         android_dataspace_t& outDataspace) {
-#else
-status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) {
-#endif
     Mutex::Autolock lock(mMutex);
 
     BufferItem item;
     status_t err = acquireBufferLocked(&item, 0);
     if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
-#ifdef USE_HWC2
         mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer,
                 &outSlot, &outBuffer);
-#else
-        outBuffer = mCurrentBuffer;
-#endif
         return NO_ERROR;
     } else if (err != NO_ERROR) {
         ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err);
@@ -152,26 +126,15 @@
     // had released the old buffer first.
     if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT &&
         item.mSlot != mCurrentBufferSlot) {
-#ifdef USE_HWC2
         mHasPendingRelease = true;
         mPreviousBufferSlot = mCurrentBufferSlot;
         mPreviousBuffer = mCurrentBuffer;
-#else
-        // Release the previous buffer.
-        err = releaseBufferLocked(mCurrentBufferSlot, mCurrentBuffer,
-                EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
-        if (err < NO_ERROR) {
-            ALOGE("error releasing buffer: %s (%d)", strerror(-err), err);
-            return err;
-        }
-#endif
     }
     mCurrentBufferSlot = item.mSlot;
     mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer;
     mCurrentFence = item.mFence;
 
     outFence = item.mFence;
-#ifdef USE_HWC2
     mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer,
             &outSlot, &outBuffer);
     outDataspace = item.mDataSpace;
@@ -181,31 +144,10 @@
         ALOGE("error posting framebuffer: %d", result);
         return result;
     }
-#else
-    outBuffer = mCurrentBuffer;
-#endif
 
     return NO_ERROR;
 }
 
-#ifndef USE_HWC2
-// Overrides ConsumerBase::onFrameAvailable(), does not call base class impl.
-void FramebufferSurface::onFrameAvailable(const BufferItem& /* item */) {
-    sp<GraphicBuffer> buf;
-    sp<Fence> acquireFence;
-    status_t err = nextBuffer(buf, acquireFence);
-    if (err != NO_ERROR) {
-        ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)",
-                strerror(-err), err);
-        return;
-    }
-    err = mHwc.fbPost(mDisplayType, acquireFence, buf);
-    if (err != NO_ERROR) {
-        ALOGE("error posting framebuffer: %d", err);
-    }
-}
-#endif
-
 void FramebufferSurface::freeBufferLocked(int slotIndex) {
     ConsumerBase::freeBufferLocked(slotIndex);
     if (slotIndex == mCurrentBufferSlot) {
@@ -214,7 +156,6 @@
 }
 
 void FramebufferSurface::onFrameCommitted() {
-#ifdef USE_HWC2
     if (mHasPendingRelease) {
         sp<Fence> fence = mHwc.getPresentFence(mDisplayType);
         if (fence->isValid()) {
@@ -231,25 +172,8 @@
         mPreviousBuffer.clear();
         mHasPendingRelease = false;
     }
-#else
-    sp<Fence> fence = mHwc.getAndResetReleaseFence(mDisplayType);
-    if (fence->isValid() &&
-            mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) {
-        status_t err = addReleaseFence(mCurrentBufferSlot,
-                mCurrentBuffer, fence);
-        ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)",
-                strerror(-err), err);
-    }
-#endif
 }
 
-#ifndef USE_HWC2
-status_t FramebufferSurface::compositionComplete()
-{
-    return mHwc.fbCompositionComplete();
-}
-#endif
-
 void FramebufferSurface::dumpAsString(String8& result) const {
     Mutex::Autolock lock(mMutex);
     result.appendFormat("FramebufferSurface: dataspace: %s(%d)\n",
@@ -259,9 +183,6 @@
 
 void FramebufferSurface::dumpLocked(String8& result, const char* prefix) const
 {
-#ifndef USE_HWC2
-    mHwc.fbDump(result);
-#endif
     ConsumerBase::dumpLocked(result, prefix);
 }
 
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index a1756ca..4186b7a 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -42,9 +42,6 @@
 
     virtual status_t beginFrame(bool mustRecompose);
     virtual status_t prepareFrame(CompositionType compositionType);
-#ifndef USE_HWC2
-    virtual status_t compositionComplete();
-#endif
     virtual status_t advanceFrame();
     virtual void onFrameCommitted();
     virtual void dumpAsString(String8& result) const;
@@ -58,9 +55,6 @@
 private:
     virtual ~FramebufferSurface() { }; // this class cannot be overloaded
 
-#ifndef USE_HWC2
-    virtual void onFrameAvailable(const BufferItem& item);
-#endif
     virtual void freeBufferLocked(int slotIndex);
 
     virtual void dumpLocked(String8& result, const char* prefix) const;
@@ -68,12 +62,8 @@
     // nextBuffer waits for and then latches the next buffer from the
     // BufferQueue and releases the previously latched buffer to the
     // BufferQueue.  The new buffer is returned in the 'buffer' argument.
-#ifdef USE_HWC2
     status_t nextBuffer(uint32_t& outSlot, sp<GraphicBuffer>& outBuffer,
             sp<Fence>& outFence, android_dataspace_t& outDataspace);
-#else
-    status_t nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence);
-#endif
 
     // mDisplayType must match one of the HWC display types
     int mDisplayType;
@@ -100,14 +90,12 @@
     // Hardware composer, owned by SurfaceFlinger.
     HWComposer& mHwc;
 
-#ifdef USE_HWC2
     HWComposerBufferCache mHwcBufferCache;
 
     // Previous buffer to release after getting an updated retire fence
     bool mHasPendingRelease;
     int mPreviousBufferSlot;
     sp<GraphicBuffer> mPreviousBuffer;
-#endif
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 3640bb5..3b6d931 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -14,10 +14,6 @@
  * limitations under the License.
  */
 
-#ifndef USE_HWC2
-#include "HWComposer_hwc1.h"
-#else
-
 #ifndef ANDROID_SF_HWCOMPOSER_H
 #define ANDROID_SF_HWCOMPOSER_H
 
@@ -219,5 +215,3 @@
 }; // namespace android
 
 #endif // ANDROID_SF_HWCOMPOSER_H
-
-#endif // #ifdef USE_HWC2
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
deleted file mode 100644
index dcb2913..0000000
--- a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
+++ /dev/null
@@ -1,1346 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-
-#include <inttypes.h>
-#include <math.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/misc.h>
-#include <utils/NativeHandle.h>
-#include <utils/String8.h>
-#include <utils/Thread.h>
-#include <utils/Trace.h>
-#include <utils/Vector.h>
-
-#include <ui/GraphicBuffer.h>
-
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer.h>
-
-#include <android/configuration.h>
-
-#include <cutils/properties.h>
-#include <log/log.h>
-
-#include <system/graphics.h>
-
-#include "HWComposer.h"
-
-#include "../Layer.h"           // needed only for debugging
-#include "../SurfaceFlinger.h"
-
-namespace android {
-
-#define MIN_HWC_HEADER_VERSION HWC_HEADER_VERSION
-
-static uint32_t hwcApiVersion(const hwc_composer_device_1_t* hwc) {
-    uint32_t hwcVersion = hwc->common.version;
-    return hwcVersion & HARDWARE_API_VERSION_2_MAJ_MIN_MASK;
-}
-
-static uint32_t hwcHeaderVersion(const hwc_composer_device_1_t* hwc) {
-    uint32_t hwcVersion = hwc->common.version;
-    return hwcVersion & HARDWARE_API_VERSION_2_HEADER_MASK;
-}
-
-static bool hwcHasApiVersion(const hwc_composer_device_1_t* hwc,
-        uint32_t version) {
-    return hwcApiVersion(hwc) >= (version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK);
-}
-
-// ---------------------------------------------------------------------------
-
-struct HWComposer::cb_context {
-    struct callbacks : public hwc_procs_t {
-        // these are here to facilitate the transition when adding
-        // new callbacks (an implementation can check for NULL before
-        // calling a new callback).
-        void (*zero[4])(void);
-    };
-    callbacks procs;
-    HWComposer* hwc;
-};
-
-// ---------------------------------------------------------------------------
-
-HWComposer::HWComposer(
-        const sp<SurfaceFlinger>& flinger,
-        EventHandler& handler)
-    : mFlinger(flinger),
-      mFbDev(0), mHwc(0), mNumDisplays(1),
-      mCBContext(new cb_context),
-      mEventHandler(handler),
-      mDebugForceFakeVSync(false)
-{
-    for (size_t i =0 ; i<MAX_HWC_DISPLAYS ; i++) {
-        mLists[i] = 0;
-    }
-
-    for (size_t i=0 ; i<HWC_NUM_PHYSICAL_DISPLAY_TYPES ; i++) {
-        mLastHwVSync[i] = 0;
-        mVSyncCounts[i] = 0;
-    }
-
-    char value[PROPERTY_VALUE_MAX];
-    property_get("debug.sf.no_hw_vsync", value, "0");
-    mDebugForceFakeVSync = atoi(value);
-
-    bool needVSyncThread = true;
-
-    // Note: some devices may insist that the FB HAL be opened before HWC.
-    int fberr = loadFbHalModule();
-    loadHwcModule();
-
-    if (mFbDev && mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
-        // close FB HAL if we don't needed it.
-        // FIXME: this is temporary until we're not forced to open FB HAL
-        // before HWC.
-        framebuffer_close(mFbDev);
-        mFbDev = NULL;
-    }
-
-    // If we have no HWC, or a pre-1.1 HWC, an FB dev is mandatory.
-    if ((!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
-            && !mFbDev) {
-        ALOGE("ERROR: failed to open framebuffer (%s), aborting",
-                strerror(-fberr));
-        abort();
-    }
-
-    // these display IDs are always reserved
-    for (size_t i=0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {
-        mAllocatedDisplayIDs.markBit(i);
-    }
-
-    if (mHwc) {
-        ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER,
-              (hwcApiVersion(mHwc) >> 24) & 0xff,
-              (hwcApiVersion(mHwc) >> 16) & 0xff);
-        if (mHwc->registerProcs) {
-            mCBContext->hwc = this;
-            mCBContext->procs.invalidate = &hook_invalidate;
-            mCBContext->procs.vsync = &hook_vsync;
-            if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
-                mCBContext->procs.hotplug = &hook_hotplug;
-            else
-                mCBContext->procs.hotplug = NULL;
-            memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
-            mHwc->registerProcs(mHwc, &mCBContext->procs);
-        }
-
-        // don't need a vsync thread if we have a hardware composer
-        needVSyncThread = false;
-        // always turn vsync off when we start
-        eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
-
-        // the number of displays we actually have depends on the
-        // hw composer version
-        if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {
-            // 1.3 adds support for virtual displays
-            mNumDisplays = MAX_HWC_DISPLAYS;
-        } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
-            // 1.1 adds support for multiple displays
-            mNumDisplays = NUM_BUILTIN_DISPLAYS;
-        } else {
-            mNumDisplays = 1;
-        }
-    }
-
-    if (mFbDev) {
-        ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)),
-                "should only have fbdev if no hwc or hwc is 1.0");
-
-        DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]);
-        disp.connected = true;
-        disp.format = mFbDev->format;
-        DisplayConfig config = DisplayConfig();
-        config.width = mFbDev->width;
-        config.height = mFbDev->height;
-        config.xdpi = mFbDev->xdpi;
-        config.ydpi = mFbDev->ydpi;
-        config.refresh = nsecs_t(1e9 / mFbDev->fps);
-        disp.configs.push_back(config);
-        disp.currentConfig = 0;
-    } else if (mHwc) {
-        // here we're guaranteed to have at least HWC 1.1
-        for (size_t i =0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {
-            queryDisplayProperties(i);
-        }
-    }
-
-    if (needVSyncThread) {
-        // we don't have VSYNC support, we need to fake it
-        mVSyncThread = new VSyncThread(*this);
-    }
-}
-
-HWComposer::~HWComposer() {
-    if (mHwc) {
-        eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
-    }
-    if (mVSyncThread != NULL) {
-        mVSyncThread->requestExitAndWait();
-    }
-    if (mHwc) {
-        hwc_close_1(mHwc);
-    }
-    if (mFbDev) {
-        framebuffer_close(mFbDev);
-    }
-    delete mCBContext;
-}
-
-// Load and prepare the hardware composer module.  Sets mHwc.
-void HWComposer::loadHwcModule()
-{
-    hw_module_t const* module;
-
-    if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
-        ALOGE("%s module not found", HWC_HARDWARE_MODULE_ID);
-        return;
-    }
-
-    int err = hwc_open_1(module, &mHwc);
-    if (err) {
-        ALOGE("%s device failed to initialize (%s)",
-              HWC_HARDWARE_COMPOSER, strerror(-err));
-        return;
-    }
-
-    if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0) ||
-            hwcHeaderVersion(mHwc) < MIN_HWC_HEADER_VERSION ||
-            hwcHeaderVersion(mHwc) > HWC_HEADER_VERSION) {
-        ALOGE("%s device version %#x unsupported, will not be used",
-              HWC_HARDWARE_COMPOSER, mHwc->common.version);
-        hwc_close_1(mHwc);
-        mHwc = NULL;
-        return;
-    }
-}
-
-// Load and prepare the FB HAL, which uses the gralloc module.  Sets mFbDev.
-int HWComposer::loadFbHalModule()
-{
-    hw_module_t const* module;
-
-    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
-    if (err != 0) {
-        ALOGE("%s module not found", GRALLOC_HARDWARE_MODULE_ID);
-        return err;
-    }
-
-    return framebuffer_open(module, &mFbDev);
-}
-
-status_t HWComposer::initCheck() const {
-    return mHwc ? NO_ERROR : NO_INIT;
-}
-
-void HWComposer::hook_invalidate(const struct hwc_procs* procs) {
-    cb_context* ctx = reinterpret_cast<cb_context*>(
-            const_cast<hwc_procs_t*>(procs));
-    ctx->hwc->invalidate();
-}
-
-void HWComposer::hook_vsync(const struct hwc_procs* procs, int disp,
-        int64_t timestamp) {
-    cb_context* ctx = reinterpret_cast<cb_context*>(
-            const_cast<hwc_procs_t*>(procs));
-    ctx->hwc->vsync(disp, timestamp);
-}
-
-void HWComposer::hook_hotplug(const struct hwc_procs* procs, int disp,
-        int connected) {
-    cb_context* ctx = reinterpret_cast<cb_context*>(
-            const_cast<hwc_procs_t*>(procs));
-    ctx->hwc->hotplug(disp, connected);
-}
-
-void HWComposer::invalidate() {
-    mEventHandler.onInvalidateReceived(this);
-}
-
-void HWComposer::vsync(int disp, int64_t timestamp) {
-    if (uint32_t(disp) < HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
-        {
-            Mutex::Autolock _l(mLock);
-
-            // There have been reports of HWCs that signal several vsync events
-            // with the same timestamp when turning the display off and on. This
-            // is a bug in the HWC implementation, but filter the extra events
-            // out here so they don't cause havoc downstream.
-            if (timestamp == mLastHwVSync[disp]) {
-                ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",
-                        timestamp);
-                return;
-            }
-
-            mLastHwVSync[disp] = timestamp;
-        }
-
-        char tag[16];
-        snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
-        ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
-
-        mEventHandler.onVSyncReceived(this, disp, timestamp);
-    }
-}
-
-void HWComposer::hotplug(int disp, int connected) {
-    if (disp >= VIRTUAL_DISPLAY_ID_BASE) {
-        ALOGE("hotplug event received for invalid display: disp=%d connected=%d",
-                disp, connected);
-        return;
-    }
-    queryDisplayProperties(disp);
-    // Do not teardown or recreate the primary display
-    if (disp != HWC_DISPLAY_PRIMARY) {
-        mEventHandler.onHotplugReceived(this, disp, bool(connected));
-    }
-}
-
-static float getDefaultDensity(uint32_t width, uint32_t height) {
-    // Default density is based on TVs: 1080p displays get XHIGH density,
-    // lower-resolution displays get TV density. Maybe eventually we'll need
-    // to update it for 4K displays, though hopefully those just report
-    // accurate DPI information to begin with. This is also used for virtual
-    // displays and even primary displays with older hwcomposers, so be
-    // careful about orientation.
-
-    uint32_t h = width < height ? width : height;
-    if (h >= 1080) return ACONFIGURATION_DENSITY_XHIGH;
-    else           return ACONFIGURATION_DENSITY_TV;
-}
-
-static const uint32_t DISPLAY_ATTRIBUTES[] = {
-    HWC_DISPLAY_VSYNC_PERIOD,
-    HWC_DISPLAY_WIDTH,
-    HWC_DISPLAY_HEIGHT,
-    HWC_DISPLAY_DPI_X,
-    HWC_DISPLAY_DPI_Y,
-    HWC_DISPLAY_COLOR_TRANSFORM,
-    HWC_DISPLAY_NO_ATTRIBUTE,
-};
-#define NUM_DISPLAY_ATTRIBUTES (sizeof(DISPLAY_ATTRIBUTES) / sizeof(DISPLAY_ATTRIBUTES)[0])
-
-static const uint32_t PRE_HWC15_DISPLAY_ATTRIBUTES[] = {
-    HWC_DISPLAY_VSYNC_PERIOD,
-    HWC_DISPLAY_WIDTH,
-    HWC_DISPLAY_HEIGHT,
-    HWC_DISPLAY_DPI_X,
-    HWC_DISPLAY_DPI_Y,
-    HWC_DISPLAY_NO_ATTRIBUTE,
-};
-
-status_t HWComposer::queryDisplayProperties(int disp) {
-
-    LOG_ALWAYS_FATAL_IF(!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1));
-
-    // use zero as default value for unspecified attributes
-    int32_t values[NUM_DISPLAY_ATTRIBUTES - 1];
-    memset(values, 0, sizeof(values));
-
-    const size_t MAX_NUM_CONFIGS = 128;
-    uint32_t configs[MAX_NUM_CONFIGS] = {0};
-    size_t numConfigs = MAX_NUM_CONFIGS;
-    status_t err = mHwc->getDisplayConfigs(mHwc, disp, configs, &numConfigs);
-    if (err != NO_ERROR) {
-        // this can happen if an unpluggable display is not connected
-        mDisplayData[disp].connected = false;
-        return err;
-    }
-
-    mDisplayData[disp].currentConfig = 0;
-    for (size_t c = 0; c < numConfigs; ++c) {
-        err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],
-                DISPLAY_ATTRIBUTES, values);
-        // If this is a pre-1.5 HWC, it may not know about color transform, so
-        // try again with a smaller set of attributes
-        if (err != NO_ERROR) {
-            err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],
-                    PRE_HWC15_DISPLAY_ATTRIBUTES, values);
-        }
-        if (err != NO_ERROR) {
-            // we can't get this display's info. turn it off.
-            mDisplayData[disp].connected = false;
-            return err;
-        }
-
-        DisplayConfig config = DisplayConfig();
-        for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
-            switch (DISPLAY_ATTRIBUTES[i]) {
-                case HWC_DISPLAY_VSYNC_PERIOD:
-                    config.refresh = nsecs_t(values[i]);
-                    break;
-                case HWC_DISPLAY_WIDTH:
-                    config.width = values[i];
-                    break;
-                case HWC_DISPLAY_HEIGHT:
-                    config.height = values[i];
-                    break;
-                case HWC_DISPLAY_DPI_X:
-                    config.xdpi = values[i] / 1000.0f;
-                    break;
-                case HWC_DISPLAY_DPI_Y:
-                    config.ydpi = values[i] / 1000.0f;
-                    break;
-                case HWC_DISPLAY_COLOR_TRANSFORM:
-                    config.colorMode = static_cast<android_color_mode_t>(values[i]);
-                    break;
-                default:
-                    ALOG_ASSERT(false, "unknown display attribute[%zu] %#x",
-                            i, DISPLAY_ATTRIBUTES[i]);
-                    break;
-            }
-        }
-
-        if (config.xdpi == 0.0f || config.ydpi == 0.0f) {
-            float dpi = getDefaultDensity(config.width, config.height);
-            config.xdpi = dpi;
-            config.ydpi = dpi;
-        }
-
-        mDisplayData[disp].configs.push_back(config);
-    }
-
-    // FIXME: what should we set the format to?
-    mDisplayData[disp].format = HAL_PIXEL_FORMAT_RGBA_8888;
-    mDisplayData[disp].connected = true;
-    return NO_ERROR;
-}
-
-status_t HWComposer::setVirtualDisplayProperties(int32_t id,
-        uint32_t w, uint32_t h, uint32_t format) {
-    if (id < VIRTUAL_DISPLAY_ID_BASE || id >= int32_t(mNumDisplays) ||
-            !mAllocatedDisplayIDs.hasBit(id)) {
-        return BAD_INDEX;
-    }
-    size_t configId = mDisplayData[id].currentConfig;
-    mDisplayData[id].format = format;
-    DisplayConfig& config = mDisplayData[id].configs.editItemAt(configId);
-    config.width = w;
-    config.height = h;
-    config.xdpi = config.ydpi = getDefaultDensity(w, h);
-    return NO_ERROR;
-}
-
-int32_t HWComposer::allocateDisplayId() {
-    if (mAllocatedDisplayIDs.count() >= mNumDisplays) {
-        return NO_MEMORY;
-    }
-    int32_t id = mAllocatedDisplayIDs.firstUnmarkedBit();
-    mAllocatedDisplayIDs.markBit(id);
-    mDisplayData[id].connected = true;
-    mDisplayData[id].configs.resize(1);
-    mDisplayData[id].currentConfig = 0;
-    return id;
-}
-
-status_t HWComposer::freeDisplayId(int32_t id) {
-    if (id < NUM_BUILTIN_DISPLAYS) {
-        // cannot free the reserved IDs
-        return BAD_VALUE;
-    }
-    if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) {
-        return BAD_INDEX;
-    }
-    mAllocatedDisplayIDs.clearBit(id);
-    mDisplayData[id].connected = false;
-    return NO_ERROR;
-}
-
-nsecs_t HWComposer::getRefreshTimestamp(int disp) const {
-    // this returns the last refresh timestamp.
-    // if the last one is not available, we estimate it based on
-    // the refresh period and whatever closest timestamp we have.
-    Mutex::Autolock _l(mLock);
-    nsecs_t now = systemTime(CLOCK_MONOTONIC);
-    size_t configId = mDisplayData[disp].currentConfig;
-    return now - ((now - mLastHwVSync[disp]) %
-            mDisplayData[disp].configs[configId].refresh);
-}
-
-sp<Fence> HWComposer::getDisplayFence(int disp) const {
-    return mDisplayData[disp].lastDisplayFence;
-}
-
-uint32_t HWComposer::getFormat(int disp) const {
-    if (static_cast<uint32_t>(disp) >= MAX_HWC_DISPLAYS || !mAllocatedDisplayIDs.hasBit(disp)) {
-        return HAL_PIXEL_FORMAT_RGBA_8888;
-    } else {
-        return mDisplayData[disp].format;
-    }
-}
-
-bool HWComposer::isConnected(int disp) const {
-    return mDisplayData[disp].connected;
-}
-
-uint32_t HWComposer::getWidth(int disp) const {
-    size_t currentConfig = mDisplayData[disp].currentConfig;
-    return mDisplayData[disp].configs[currentConfig].width;
-}
-
-uint32_t HWComposer::getHeight(int disp) const {
-    size_t currentConfig = mDisplayData[disp].currentConfig;
-    return mDisplayData[disp].configs[currentConfig].height;
-}
-
-float HWComposer::getDpiX(int disp) const {
-    size_t currentConfig = mDisplayData[disp].currentConfig;
-    return mDisplayData[disp].configs[currentConfig].xdpi;
-}
-
-float HWComposer::getDpiY(int disp) const {
-    size_t currentConfig = mDisplayData[disp].currentConfig;
-    return mDisplayData[disp].configs[currentConfig].ydpi;
-}
-
-nsecs_t HWComposer::getRefreshPeriod(int disp) const {
-    size_t currentConfig = mDisplayData[disp].currentConfig;
-    return mDisplayData[disp].configs[currentConfig].refresh;
-}
-
-android_color_mode_t HWComposer::getColorMode(int disp) const {
-    size_t currentConfig = mDisplayData[disp].currentConfig;
-    return mDisplayData[disp].configs[currentConfig].colorMode;
-}
-
-const Vector<HWComposer::DisplayConfig>& HWComposer::getConfigs(int disp) const {
-    return mDisplayData[disp].configs;
-}
-
-size_t HWComposer::getCurrentConfig(int disp) const {
-    return mDisplayData[disp].currentConfig;
-}
-
-void HWComposer::eventControl(int disp, int event, int enabled) {
-    if (uint32_t(disp)>31 || !mAllocatedDisplayIDs.hasBit(disp)) {
-        ALOGD("eventControl ignoring event %d on unallocated disp %d (en=%d)",
-              event, disp, enabled);
-        return;
-    }
-    if (event != EVENT_VSYNC) {
-        ALOGW("eventControl got unexpected event %d (disp=%d en=%d)",
-              event, disp, enabled);
-        return;
-    }
-    status_t err = NO_ERROR;
-    if (mHwc && !mDebugForceFakeVSync) {
-        // NOTE: we use our own internal lock here because we have to call
-        // into the HWC with the lock held, and we want to make sure
-        // that even if HWC blocks (which it shouldn't), it won't
-        // affect other threads.
-        Mutex::Autolock _l(mEventControlLock);
-        const int32_t eventBit = 1UL << event;
-        const int32_t newValue = enabled ? eventBit : 0;
-        const int32_t oldValue = mDisplayData[disp].events & eventBit;
-        if (newValue != oldValue) {
-            ATRACE_CALL();
-            err = mHwc->eventControl(mHwc, disp, event, enabled);
-            if (!err) {
-                int32_t& events(mDisplayData[disp].events);
-                events = (events & ~eventBit) | newValue;
-
-                char tag[16];
-                snprintf(tag, sizeof(tag), "HW_VSYNC_ON_%1u", disp);
-                ATRACE_INT(tag, enabled);
-            }
-        }
-        // error here should not happen -- not sure what we should
-        // do if it does.
-        ALOGE_IF(err, "eventControl(%d, %d) failed %s",
-                event, enabled, strerror(-err));
-    }
-
-    if (err == NO_ERROR && mVSyncThread != NULL) {
-        mVSyncThread->setEnabled(enabled);
-    }
-}
-
-status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {
-    if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) {
-        return BAD_INDEX;
-    }
-
-    if (mHwc) {
-        DisplayData& disp(mDisplayData[id]);
-        if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
-            // we need space for the HWC_FRAMEBUFFER_TARGET
-            numLayers++;
-        }
-        if (disp.capacity < numLayers || disp.list == NULL) {
-            size_t size = sizeof(hwc_display_contents_1_t)
-                    + numLayers * sizeof(hwc_layer_1_t);
-            free(disp.list);
-            disp.list = (hwc_display_contents_1_t*)malloc(size);
-            disp.capacity = numLayers;
-        }
-        if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
-            disp.framebufferTarget = &disp.list->hwLayers[numLayers - 1];
-            memset(disp.framebufferTarget, 0, sizeof(hwc_layer_1_t));
-            const DisplayConfig& currentConfig =
-                    disp.configs[disp.currentConfig];
-            const hwc_rect_t r = { 0, 0,
-                    (int) currentConfig.width, (int) currentConfig.height };
-            disp.framebufferTarget->compositionType = HWC_FRAMEBUFFER_TARGET;
-            disp.framebufferTarget->hints = 0;
-            disp.framebufferTarget->flags = 0;
-            disp.framebufferTarget->handle = disp.fbTargetHandle;
-            disp.framebufferTarget->transform = 0;
-            disp.framebufferTarget->blending = HWC_BLENDING_PREMULT;
-            if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {
-                disp.framebufferTarget->sourceCropf.left = 0;
-                disp.framebufferTarget->sourceCropf.top = 0;
-                disp.framebufferTarget->sourceCropf.right =
-                        currentConfig.width;
-                disp.framebufferTarget->sourceCropf.bottom =
-                        currentConfig.height;
-            } else {
-                disp.framebufferTarget->sourceCrop = r;
-            }
-            disp.framebufferTarget->displayFrame = r;
-            disp.framebufferTarget->visibleRegionScreen.numRects = 1;
-            disp.framebufferTarget->visibleRegionScreen.rects =
-                &disp.framebufferTarget->displayFrame;
-            disp.framebufferTarget->acquireFenceFd = -1;
-            disp.framebufferTarget->releaseFenceFd = -1;
-            disp.framebufferTarget->planeAlpha = 0xFF;
-        }
-        disp.list->retireFenceFd = -1;
-        disp.list->flags = HWC_GEOMETRY_CHANGED;
-        disp.list->numHwLayers = numLayers;
-    }
-    return NO_ERROR;
-}
-
-status_t HWComposer::setFramebufferTarget(int32_t id,
-        const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buf) {
-    if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) {
-        return BAD_INDEX;
-    }
-    DisplayData& disp(mDisplayData[id]);
-    if (!disp.framebufferTarget) {
-        // this should never happen, but apparently eglCreateWindowSurface()
-        // triggers a Surface::queueBuffer()  on some
-        // devices (!?) -- log and ignore.
-        ALOGE("HWComposer: framebufferTarget is null");
-        return NO_ERROR;
-    }
-
-    int acquireFenceFd = -1;
-    if (acquireFence->isValid()) {
-        acquireFenceFd = acquireFence->dup();
-    }
-
-    // ALOGD("fbPost: handle=%p, fence=%d", buf->handle, acquireFenceFd);
-    disp.fbTargetHandle = buf->handle;
-    disp.framebufferTarget->handle = disp.fbTargetHandle;
-    disp.framebufferTarget->acquireFenceFd = acquireFenceFd;
-    return NO_ERROR;
-}
-
-status_t HWComposer::prepare() {
-    Mutex::Autolock _l(mDisplayLock);
-    for (size_t i=0 ; i<mNumDisplays ; i++) {
-        DisplayData& disp(mDisplayData[i]);
-        if (disp.framebufferTarget) {
-            // make sure to reset the type to HWC_FRAMEBUFFER_TARGET
-            // DO NOT reset the handle field to NULL, because it's possible
-            // that we have nothing to redraw (eg: eglSwapBuffers() not called)
-            // in which case, we should continue to use the same buffer.
-            LOG_FATAL_IF(disp.list == NULL);
-            disp.framebufferTarget->compositionType = HWC_FRAMEBUFFER_TARGET;
-        }
-        if (!disp.connected && disp.list != NULL) {
-            ALOGW("WARNING: disp %zu: connected, non-null list, layers=%zu",
-                  i, disp.list->numHwLayers);
-        }
-        mLists[i] = disp.list;
-        if (mLists[i]) {
-            if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {
-                mLists[i]->outbuf = disp.outbufHandle;
-                mLists[i]->outbufAcquireFenceFd = -1;
-            } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
-                // garbage data to catch improper use
-                mLists[i]->dpy = (hwc_display_t)0xDEADBEEF;
-                mLists[i]->sur = (hwc_surface_t)0xDEADBEEF;
-            } else {
-                mLists[i]->dpy = EGL_NO_DISPLAY;
-                mLists[i]->sur = EGL_NO_SURFACE;
-            }
-        }
-    }
-
-    int err = mHwc->prepare(mHwc, mNumDisplays, mLists);
-    ALOGE_IF(err, "HWComposer: prepare failed (%s)", strerror(-err));
-
-    if (err == NO_ERROR) {
-        // here we're just making sure that "skip" layers are set
-        // to HWC_FRAMEBUFFER and we're also counting how many layers
-        // we have of each type.
-        //
-        // If there are no window layers, we treat the display has having FB
-        // composition, because SurfaceFlinger will use GLES to draw the
-        // wormhole region.
-        for (size_t i=0 ; i<mNumDisplays ; i++) {
-            DisplayData& disp(mDisplayData[i]);
-            disp.hasFbComp = false;
-            disp.hasOvComp = false;
-            if (disp.list) {
-                for (size_t i=0 ; i<disp.list->numHwLayers ; i++) {
-                    hwc_layer_1_t& l = disp.list->hwLayers[i];
-
-                    //ALOGD("prepare: %d, type=%d, handle=%p",
-                    //        i, l.compositionType, l.handle);
-
-                    if (l.flags & HWC_SKIP_LAYER) {
-                        l.compositionType = HWC_FRAMEBUFFER;
-                    }
-                    if (l.compositionType == HWC_FRAMEBUFFER) {
-                        disp.hasFbComp = true;
-                    }
-                    if (l.compositionType == HWC_OVERLAY) {
-                        disp.hasOvComp = true;
-                    }
-                    if (l.compositionType == HWC_CURSOR_OVERLAY) {
-                        disp.hasOvComp = true;
-                    }
-                }
-                if (disp.list->numHwLayers == (disp.framebufferTarget ? 1 : 0)) {
-                    disp.hasFbComp = true;
-                }
-            } else {
-                disp.hasFbComp = true;
-            }
-        }
-    }
-    return (status_t)err;
-}
-
-bool HWComposer::hasHwcComposition(int32_t id) const {
-    if (!mHwc || uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id))
-        return false;
-    return mDisplayData[id].hasOvComp;
-}
-
-bool HWComposer::hasGlesComposition(int32_t id) const {
-    if (!mHwc || uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id))
-        return true;
-    return mDisplayData[id].hasFbComp;
-}
-
-sp<Fence> HWComposer::getAndResetReleaseFence(int32_t id) {
-    if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id))
-        return Fence::NO_FENCE;
-
-    int fd = INVALID_OPERATION;
-    if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
-        const DisplayData& disp(mDisplayData[id]);
-        if (disp.framebufferTarget) {
-            fd = disp.framebufferTarget->releaseFenceFd;
-            disp.framebufferTarget->acquireFenceFd = -1;
-            disp.framebufferTarget->releaseFenceFd = -1;
-        }
-    }
-    return fd >= 0 ? new Fence(fd) : Fence::NO_FENCE;
-}
-
-status_t HWComposer::commit() {
-    int err = NO_ERROR;
-    if (mHwc) {
-        if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
-            // On version 1.0, the OpenGL ES target surface is communicated
-            // by the (dpy, sur) fields and we are guaranteed to have only
-            // a single display.
-            mLists[0]->dpy = eglGetCurrentDisplay();
-            mLists[0]->sur = eglGetCurrentSurface(EGL_DRAW);
-        }
-
-        for (size_t i=VIRTUAL_DISPLAY_ID_BASE; i<mNumDisplays; i++) {
-            DisplayData& disp(mDisplayData[i]);
-            if (disp.outbufHandle) {
-                mLists[i]->outbuf = disp.outbufHandle;
-                mLists[i]->outbufAcquireFenceFd =
-                        disp.outbufAcquireFence->dup();
-            }
-        }
-
-        err = mHwc->set(mHwc, mNumDisplays, mLists);
-
-        for (size_t i=0 ; i<mNumDisplays ; i++) {
-            DisplayData& disp(mDisplayData[i]);
-            disp.lastDisplayFence = disp.lastRetireFence;
-            disp.lastRetireFence = Fence::NO_FENCE;
-            if (disp.list) {
-                if (disp.list->retireFenceFd != -1) {
-                    disp.lastRetireFence = new Fence(disp.list->retireFenceFd);
-                    disp.list->retireFenceFd = -1;
-                }
-                disp.list->flags &= ~HWC_GEOMETRY_CHANGED;
-            }
-        }
-    }
-    return (status_t)err;
-}
-
-status_t HWComposer::setPowerMode(int disp, int mode) {
-    LOG_FATAL_IF(disp >= VIRTUAL_DISPLAY_ID_BASE);
-    if (mHwc) {
-        if (mode == HWC_POWER_MODE_OFF) {
-            eventControl(disp, HWC_EVENT_VSYNC, 0);
-        }
-        if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_4)) {
-            return (status_t)mHwc->setPowerMode(mHwc, disp, mode);
-        } else {
-            return (status_t)mHwc->blank(mHwc, disp,
-                    mode == HWC_POWER_MODE_OFF ? 1 : 0);
-        }
-    }
-    return NO_ERROR;
-}
-
-status_t HWComposer::setActiveConfig(int disp, int mode) {
-    LOG_FATAL_IF(disp >= VIRTUAL_DISPLAY_ID_BASE);
-    DisplayData& dd(mDisplayData[disp]);
-    dd.currentConfig = mode;
-    if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_4)) {
-        return (status_t)mHwc->setActiveConfig(mHwc, disp, mode);
-    } else {
-        LOG_FATAL_IF(mode != 0);
-    }
-    return NO_ERROR;
-}
-
-void HWComposer::disconnectDisplay(int disp) {
-    LOG_ALWAYS_FATAL_IF(disp < 0 || disp == HWC_DISPLAY_PRIMARY);
-    DisplayData& dd(mDisplayData[disp]);
-    free(dd.list);
-    dd.list = NULL;
-    dd.framebufferTarget = NULL;    // points into dd.list
-    dd.fbTargetHandle = NULL;
-    dd.outbufHandle = NULL;
-    dd.lastRetireFence = Fence::NO_FENCE;
-    dd.lastDisplayFence = Fence::NO_FENCE;
-    dd.outbufAcquireFence = Fence::NO_FENCE;
-    // clear all the previous configs and repopulate when a new
-    // device is added
-    dd.configs.clear();
-}
-
-int HWComposer::getVisualID() const {
-    if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
-        // FIXME: temporary hack until HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
-        // is supported by the implementation. we can only be in this case
-        // if we have HWC 1.1
-        return HAL_PIXEL_FORMAT_RGBA_8888;
-        //return HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
-    } else {
-        return mFbDev->format;
-    }
-}
-
-bool HWComposer::supportsFramebufferTarget() const {
-    return (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1));
-}
-
-int HWComposer::fbPost(int32_t id,
-        const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) {
-    if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
-        return setFramebufferTarget(id, acquireFence, buffer);
-    } else {
-        acquireFence->waitForever("HWComposer::fbPost");
-        return mFbDev->post(mFbDev, buffer->handle);
-    }
-}
-
-int HWComposer::fbCompositionComplete() {
-    if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
-        return NO_ERROR;
-
-    if (mFbDev->compositionComplete) {
-        return mFbDev->compositionComplete(mFbDev);
-    } else {
-        return INVALID_OPERATION;
-    }
-}
-
-void HWComposer::fbDump(String8& result) {
-    if (mFbDev && mFbDev->common.version >= 1 && mFbDev->dump) {
-        const size_t SIZE = 4096;
-        char buffer[SIZE];
-        mFbDev->dump(mFbDev, buffer, SIZE);
-        result.append(buffer);
-    }
-}
-
-status_t HWComposer::setOutputBuffer(int32_t id, const sp<Fence>& acquireFence,
-        const sp<GraphicBuffer>& buf) {
-    if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id))
-        return BAD_INDEX;
-    if (id < VIRTUAL_DISPLAY_ID_BASE)
-        return INVALID_OPERATION;
-
-    DisplayData& disp(mDisplayData[id]);
-    disp.outbufHandle = buf->handle;
-    disp.outbufAcquireFence = acquireFence;
-    return NO_ERROR;
-}
-
-sp<Fence> HWComposer::getLastRetireFence(int32_t id) const {
-    if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id))
-        return Fence::NO_FENCE;
-    return mDisplayData[id].lastRetireFence;
-}
-
-status_t HWComposer::setCursorPositionAsync(int32_t id, const Rect& pos)
-{
-    if (mHwc->setCursorPositionAsync) {
-        return (status_t)mHwc->setCursorPositionAsync(mHwc, id, pos.left, pos.top);
-    }
-    else {
-        return NO_ERROR;
-    }
-}
-
-/*
- * Helper template to implement a concrete HWCLayer
- * This holds the pointer to the concrete hwc layer type
- * and implements the "iterable" side of HWCLayer.
- */
-template<typename CONCRETE, typename HWCTYPE>
-class Iterable : public HWComposer::HWCLayer {
-protected:
-    HWCTYPE* const mLayerList;
-    HWCTYPE* mCurrentLayer;
-    explicit Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer),
-            mIndex(0) { }
-    inline HWCTYPE const * getLayer() const { return mCurrentLayer; }
-    inline HWCTYPE* getLayer() { return mCurrentLayer; }
-    virtual ~Iterable() { }
-    size_t mIndex;
-private:
-    // returns a copy of ourselves
-    virtual HWComposer::HWCLayer* dup() {
-        return new CONCRETE( static_cast<const CONCRETE&>(*this) );
-    }
-    virtual status_t setLayer(size_t index) {
-        mIndex = index;
-        mCurrentLayer = &mLayerList[index];
-        return NO_ERROR;
-    }
-};
-
-/*
- * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_1_0.
- * This implements the HWCLayer side of HWCIterableLayer.
- */
-class HWCLayerVersion1 : public Iterable<HWCLayerVersion1, hwc_layer_1_t> {
-    struct hwc_composer_device_1* mHwc;
-public:
-    HWCLayerVersion1(struct hwc_composer_device_1* hwc, hwc_layer_1_t* layer,
-            Vector<Region>* visibleRegions,
-            Vector<Region>* surfaceDamageRegions)
-        : Iterable<HWCLayerVersion1, hwc_layer_1_t>(layer), mHwc(hwc),
-          mVisibleRegions(visibleRegions),
-          mSurfaceDamageRegions(surfaceDamageRegions) {}
-
-    virtual int32_t getCompositionType() const {
-        return getLayer()->compositionType;
-    }
-    virtual uint32_t getHints() const {
-        return getLayer()->hints;
-    }
-    virtual sp<Fence> getAndResetReleaseFence() {
-        int fd = getLayer()->releaseFenceFd;
-        getLayer()->releaseFenceFd = -1;
-        return fd >= 0 ? new Fence(fd) : Fence::NO_FENCE;
-    }
-    virtual void setAcquireFenceFd(int fenceFd) {
-        getLayer()->acquireFenceFd = fenceFd;
-    }
-    virtual void setPerFrameDefaultState() {
-        //getLayer()->compositionType = HWC_FRAMEBUFFER;
-    }
-    virtual void setPlaneAlpha(uint8_t alpha) {
-        if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_2)) {
-            getLayer()->planeAlpha = alpha;
-        } else {
-            if (alpha < 0xFF) {
-                getLayer()->flags |= HWC_SKIP_LAYER;
-            }
-        }
-    }
-    virtual void setDefaultState() {
-        hwc_layer_1_t* const l = getLayer();
-        l->compositionType = HWC_FRAMEBUFFER;
-        l->hints = 0;
-        l->flags = HWC_SKIP_LAYER;
-        l->handle = 0;
-        l->transform = 0;
-        l->blending = HWC_BLENDING_NONE;
-        l->visibleRegionScreen.numRects = 0;
-        l->visibleRegionScreen.rects = NULL;
-        l->acquireFenceFd = -1;
-        l->releaseFenceFd = -1;
-        l->planeAlpha = 0xFF;
-    }
-    virtual void setSkip(bool skip) {
-        if (skip) {
-            getLayer()->flags |= HWC_SKIP_LAYER;
-        } else {
-            getLayer()->flags &= ~HWC_SKIP_LAYER;
-        }
-    }
-    virtual void setIsCursorLayerHint(bool isCursor) {
-        if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_4)) {
-            if (isCursor) {
-                getLayer()->flags |= HWC_IS_CURSOR_LAYER;
-            }
-            else {
-                getLayer()->flags &= ~HWC_IS_CURSOR_LAYER;
-            }
-        }
-    }
-    virtual void setBlending(uint32_t blending) {
-        getLayer()->blending = blending;
-    }
-    virtual void setTransform(uint32_t transform) {
-        getLayer()->transform = transform;
-    }
-    virtual void setFrame(const Rect& frame) {
-        getLayer()->displayFrame = reinterpret_cast<hwc_rect_t const&>(frame);
-    }
-    virtual void setCrop(const FloatRect& crop) {
-        if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {
-            getLayer()->sourceCropf = reinterpret_cast<hwc_frect_t const&>(crop);
-        } else {
-            /*
-             * Since h/w composer didn't support a flot crop rect before version 1.3,
-             * using integer coordinates instead produces a different output from the GL code in
-             * Layer::drawWithOpenGL(). The difference can be large if the buffer crop to
-             * window size ratio is large and a window crop is defined
-             * (i.e.: if we scale the buffer a lot and we also crop it with a window crop).
-             */
-            hwc_rect_t& r = getLayer()->sourceCrop;
-            r.left  = int(ceilf(crop.left));
-            r.top   = int(ceilf(crop.top));
-            r.right = int(floorf(crop.right));
-            r.bottom= int(floorf(crop.bottom));
-        }
-    }
-    virtual void setVisibleRegionScreen(const Region& reg) {
-        hwc_region_t& visibleRegion = getLayer()->visibleRegionScreen;
-        mVisibleRegions->editItemAt(mIndex) = reg;
-        visibleRegion.rects = reinterpret_cast<hwc_rect_t const *>(
-                mVisibleRegions->itemAt(mIndex).getArray(
-                &visibleRegion.numRects));
-    }
-    virtual void setSurfaceDamage(const Region& reg) {
-        if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_5)) {
-            return;
-        }
-        hwc_region_t& surfaceDamage = getLayer()->surfaceDamage;
-        // We encode default full-screen damage as INVALID_RECT upstream, but as
-        // 0 rects for HWComposer
-        if (reg.isRect() && reg.getBounds() == Rect::INVALID_RECT) {
-            surfaceDamage.numRects = 0;
-            surfaceDamage.rects = NULL;
-            return;
-        }
-        mSurfaceDamageRegions->editItemAt(mIndex) = reg;
-        surfaceDamage.rects = reinterpret_cast<hwc_rect_t const *>(
-                mSurfaceDamageRegions->itemAt(mIndex).getArray(
-                &surfaceDamage.numRects));
-    }
-    virtual void setSidebandStream(const sp<NativeHandle>& stream) {
-        ALOG_ASSERT(stream->handle() != NULL);
-        getLayer()->compositionType = HWC_SIDEBAND;
-        getLayer()->sidebandStream = stream->handle();
-    }
-    virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
-        if (buffer == 0 || buffer->handle == 0) {
-            getLayer()->compositionType = HWC_FRAMEBUFFER;
-            getLayer()->flags |= HWC_SKIP_LAYER;
-            getLayer()->handle = 0;
-        } else {
-            if (getLayer()->compositionType == HWC_SIDEBAND) {
-                // If this was a sideband layer but the stream was removed, reset
-                // it to FRAMEBUFFER. The HWC can change it to OVERLAY in prepare.
-                getLayer()->compositionType = HWC_FRAMEBUFFER;
-            }
-            getLayer()->handle = buffer->handle;
-        }
-    }
-    virtual void onDisplayed() {
-        getLayer()->acquireFenceFd = -1;
-    }
-
-protected:
-    // Pointers to the vectors of Region backing-memory held in DisplayData.
-    // Only the Region at mIndex corresponds to this Layer.
-    Vector<Region>* mVisibleRegions;
-    Vector<Region>* mSurfaceDamageRegions;
-};
-
-/*
- * returns an iterator initialized at a given index in the layer list
- */
-HWComposer::LayerListIterator HWComposer::getLayerIterator(int32_t id, size_t index) {
-    if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) {
-        return LayerListIterator();
-    }
-    DisplayData& disp(mDisplayData[id]);
-    if (!mHwc || !disp.list || index > disp.list->numHwLayers) {
-        return LayerListIterator();
-    }
-    if (disp.visibleRegions.size() < disp.list->numHwLayers) {
-        disp.visibleRegions.resize(disp.list->numHwLayers);
-    }
-    if (disp.surfaceDamageRegions.size() < disp.list->numHwLayers) {
-        disp.surfaceDamageRegions.resize(disp.list->numHwLayers);
-    }
-    return LayerListIterator(new HWCLayerVersion1(mHwc, disp.list->hwLayers,
-            &disp.visibleRegions, &disp.surfaceDamageRegions), index);
-}
-
-/*
- * returns an iterator on the beginning of the layer list
- */
-HWComposer::LayerListIterator HWComposer::begin(int32_t id) {
-    return getLayerIterator(id, 0);
-}
-
-/*
- * returns an iterator on the end of the layer list
- */
-HWComposer::LayerListIterator HWComposer::end(int32_t id) {
-    size_t numLayers = 0;
-    if (uint32_t(id) <= 31 && mAllocatedDisplayIDs.hasBit(id)) {
-        const DisplayData& disp(mDisplayData[id]);
-        if (mHwc && disp.list) {
-            numLayers = disp.list->numHwLayers;
-            if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
-                // with HWC 1.1, the last layer is always the HWC_FRAMEBUFFER_TARGET,
-                // which we ignore when iterating through the layer list.
-                ALOGE_IF(!numLayers, "mDisplayData[%d].list->numHwLayers is 0", id);
-                if (numLayers) {
-                    numLayers--;
-                }
-            }
-        }
-    }
-    return getLayerIterator(id, numLayers);
-}
-
-// Converts a PixelFormat to a human-readable string.  Max 11 chars.
-// (Could use a table of prefab String8 objects.)
-static String8 getFormatStr(PixelFormat format) {
-    switch (format) {
-    case PIXEL_FORMAT_RGBA_8888:    return String8("RGBA_8888");
-    case PIXEL_FORMAT_RGBX_8888:    return String8("RGBx_8888");
-    case PIXEL_FORMAT_RGBA_FP16:    return String8("RGBA_FP16");
-    case PIXEL_FORMAT_RGBA_1010102: return String8("RGBA_1010102");
-    case PIXEL_FORMAT_RGB_888:      return String8("RGB_888");
-    case PIXEL_FORMAT_RGB_565:      return String8("RGB_565");
-    case PIXEL_FORMAT_BGRA_8888:    return String8("BGRA_8888");
-    case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
-                                    return String8("ImplDef");
-    default:
-        String8 result;
-        result.appendFormat("? %08x", format);
-        return result;
-    }
-}
-
-void HWComposer::dump(String8& result) const {
-    Mutex::Autolock _l(mDisplayLock);
-    if (mHwc) {
-        result.appendFormat("Hardware Composer state (version %08x):\n", hwcApiVersion(mHwc));
-        result.appendFormat("  mDebugForceFakeVSync=%d\n", mDebugForceFakeVSync);
-        for (size_t i=0 ; i<mNumDisplays ; i++) {
-            const DisplayData& disp(mDisplayData[i]);
-            if (!disp.connected)
-                continue;
-
-            const Vector< sp<Layer> >& visibleLayersSortedByZ =
-                    mFlinger->getLayerSortedByZForHwcDisplay(i);
-
-
-            result.appendFormat("  Display[%zd] configurations (* current):\n", i);
-            for (size_t c = 0; c < disp.configs.size(); ++c) {
-                const DisplayConfig& config(disp.configs[c]);
-                result.appendFormat("    %s%zd: %ux%u, xdpi=%f, ydpi=%f"
-                        ", refresh=%" PRId64 ", colorMode=%d\n",
-                        c == disp.currentConfig ? "* " : "", c,
-                        config.width, config.height, config.xdpi, config.ydpi,
-                        config.refresh, config.colorMode);
-            }
-
-            if (disp.list) {
-                result.appendFormat(
-                        "  numHwLayers=%zu, flags=%08x\n",
-                        disp.list->numHwLayers, disp.list->flags);
-
-                result.append(
-                        "    type   |  handle  | hint | flag | tr | blnd |   format    |     source crop (l,t,r,b)      |          frame         | name \n"
-                        "-----------+----------+------+------+----+------+-------------+--------------------------------+------------------------+------\n");
-                //      " _________ | ________ | ____ | ____ | __ | ____ | ___________ |_____._,_____._,_____._,_____._ |_____,_____,_____,_____ | ___...
-                for (size_t i=0 ; i<disp.list->numHwLayers ; i++) {
-                    const hwc_layer_1_t&l = disp.list->hwLayers[i];
-                    int32_t format = -1;
-                    String8 name("unknown");
-
-                    if (i < visibleLayersSortedByZ.size()) {
-                        const sp<Layer>& layer(visibleLayersSortedByZ[i]);
-                        const sp<GraphicBuffer>& buffer(
-                                layer->getActiveBuffer());
-                        if (buffer != NULL) {
-                            format = buffer->getPixelFormat();
-                        }
-                        name = layer->getName();
-                    }
-
-                    int type = l.compositionType;
-                    if (type == HWC_FRAMEBUFFER_TARGET) {
-                        name = "HWC_FRAMEBUFFER_TARGET";
-                        format = disp.format;
-                    }
-
-                    static char const* compositionTypeName[] = {
-                            "GLES",
-                            "HWC",
-                            "BKGND",
-                            "FB TARGET",
-                            "SIDEBAND",
-                            "HWC_CURSOR",
-                            "UNKNOWN"};
-                    if (type >= NELEM(compositionTypeName))
-                        type = NELEM(compositionTypeName) - 1;
-
-                    String8 formatStr = getFormatStr(format);
-                    if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {
-                        result.appendFormat(
-                                " %9s | %08" PRIxPTR " | %04x | %04x | %02x | %04x | %-11s |%7.1f,%7.1f,%7.1f,%7.1f |%5d,%5d,%5d,%5d | %s\n",
-                                        compositionTypeName[type],
-                                        intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, formatStr.string(),
-                                        l.sourceCropf.left, l.sourceCropf.top, l.sourceCropf.right, l.sourceCropf.bottom,
-                                        l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
-                                        name.string());
-                    } else {
-                        result.appendFormat(
-                                " %9s | %08" PRIxPTR " | %04x | %04x | %02x | %04x | %-11s |%7d,%7d,%7d,%7d |%5d,%5d,%5d,%5d | %s\n",
-                                        compositionTypeName[type],
-                                        intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, formatStr.string(),
-                                        l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
-                                        l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
-                                        name.string());
-                    }
-                }
-            }
-        }
-    }
-
-    if (mHwc && mHwc->dump) {
-        const size_t SIZE = 4096;
-        char buffer[SIZE];
-        mHwc->dump(mHwc, buffer, SIZE);
-        result.append(buffer);
-    }
-}
-
-// ---------------------------------------------------------------------------
-
-HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
-    : mHwc(hwc), mEnabled(false),
-      mNextFakeVSync(0),
-      mRefreshPeriod(hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY))
-{
-}
-
-void HWComposer::VSyncThread::setEnabled(bool enabled) {
-    Mutex::Autolock _l(mLock);
-    if (mEnabled != enabled) {
-        mEnabled = enabled;
-        mCondition.signal();
-    }
-}
-
-void HWComposer::VSyncThread::onFirstRef() {
-    run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
-}
-
-bool HWComposer::VSyncThread::threadLoop() {
-    { // scope for lock
-        Mutex::Autolock _l(mLock);
-        while (!mEnabled) {
-            mCondition.wait(mLock);
-        }
-    }
-
-    const nsecs_t period = mRefreshPeriod;
-    const nsecs_t now = systemTime(CLOCK_MONOTONIC);
-    nsecs_t next_vsync = mNextFakeVSync;
-    nsecs_t sleep = next_vsync - now;
-    if (sleep < 0) {
-        // we missed, find where the next vsync should be
-        sleep = (period - ((now - next_vsync) % period));
-        next_vsync = now + sleep;
-    }
-    mNextFakeVSync = next_vsync + period;
-
-    struct timespec spec;
-    spec.tv_sec  = next_vsync / 1000000000;
-    spec.tv_nsec = next_vsync % 1000000000;
-
-    int err;
-    do {
-        err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
-    } while (err<0 && errno == EINTR);
-
-    if (err == 0) {
-        mHwc.mEventHandler.onVSyncReceived(&mHwc, 0, next_vsync);
-    }
-
-    return true;
-}
-
-HWComposer::DisplayData::DisplayData()
-:   configs(),
-    currentConfig(0),
-    format(HAL_PIXEL_FORMAT_RGBA_8888),
-    connected(false),
-    hasFbComp(false), hasOvComp(false),
-    capacity(0), list(NULL),
-    framebufferTarget(NULL), fbTargetHandle(0),
-    lastRetireFence(Fence::NO_FENCE), lastDisplayFence(Fence::NO_FENCE),
-    outbufHandle(NULL), outbufAcquireFence(Fence::NO_FENCE),
-    events(0)
-{}
-
-HWComposer::DisplayData::~DisplayData() {
-    free(list);
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 1de5e48..dba6f7c 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -176,12 +176,6 @@
     return NO_ERROR;
 }
 
-#ifndef USE_HWC2
-status_t VirtualDisplaySurface::compositionComplete() {
-    return NO_ERROR;
-}
-#endif
-
 status_t VirtualDisplaySurface::advanceFrame() {
     if (mDisplayId < 0)
         return NO_ERROR;
@@ -221,7 +215,6 @@
 
     status_t result = NO_ERROR;
     if (fbBuffer != NULL) {
-#ifdef USE_HWC2
         uint32_t hwcSlot = 0;
         sp<GraphicBuffer> hwcBuffer;
         mHwcBufferCache.getHwcBuffer(mFbProducerSlot, fbBuffer,
@@ -230,9 +223,6 @@
         // TODO: Correctly propagate the dataspace from GL composition
         result = mHwc.setClientTarget(mDisplayId, hwcSlot, mFbFence,
                 hwcBuffer, HAL_DATASPACE_UNKNOWN);
-#else
-        result = mHwc.fbPost(mDisplayId, mFbFence, fbBuffer);
-#endif
     }
 
     return result;
@@ -246,22 +236,14 @@
             "Unexpected onFrameCommitted() in %s state", dbgStateStr());
     mDbgState = DBG_STATE_IDLE;
 
-#ifdef USE_HWC2
     sp<Fence> retireFence = mHwc.getPresentFence(mDisplayId);
-#else
-    sp<Fence> fbFence = mHwc.getAndResetReleaseFence(mDisplayId);
-#endif
     if (mCompositionType == COMPOSITION_MIXED && mFbProducerSlot >= 0) {
         // release the scratch buffer back to the pool
         Mutex::Autolock lock(mMutex);
         int sslot = mapProducer2SourceSlot(SOURCE_SCRATCH, mFbProducerSlot);
         VDS_LOGV("onFrameCommitted: release scratch sslot=%d", sslot);
-#ifdef USE_HWC2
         addReleaseFenceLocked(sslot, mProducerBuffers[mFbProducerSlot],
                 retireFence);
-#else
-        addReleaseFenceLocked(sslot, mProducerBuffers[mFbProducerSlot], fbFence);
-#endif
         releaseBufferLocked(sslot, mProducerBuffers[mFbProducerSlot],
                 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
     }
@@ -269,9 +251,6 @@
     if (mOutputProducerSlot >= 0) {
         int sslot = mapProducer2SourceSlot(SOURCE_SINK, mOutputProducerSlot);
         QueueBufferOutput qbo;
-#ifndef USE_HWC2
-        sp<Fence> outFence = mHwc.getLastRetireFence(mDisplayId);
-#endif
         VDS_LOGV("onFrameCommitted: queue sink sslot=%d", sslot);
         if (mMustRecompose) {
             status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot,
@@ -280,11 +259,7 @@
                         HAL_DATASPACE_UNKNOWN,
                         Rect(mSinkBufferWidth, mSinkBufferHeight),
                         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0 /* transform */,
-#ifdef USE_HWC2
                         retireFence),
-#else
-                        outFence),
-#endif
                     &qbo);
             if (result == NO_ERROR) {
                 updateQueueBufferOutput(std::move(qbo));
@@ -294,11 +269,7 @@
             // through the motions of updating the display to keep our state
             // machine happy. We cancel the buffer to avoid triggering another
             // re-composition and causing an infinite loop.
-#ifdef USE_HWC2
             mSource[SOURCE_SINK]->cancelBuffer(sslot, retireFence);
-#else
-            mSource[SOURCE_SINK]->cancelBuffer(sslot, outFence);
-#endif
         }
     }
 
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index 1671aba..5c8acea 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -84,9 +84,6 @@
     //
     virtual status_t beginFrame(bool mustRecompose);
     virtual status_t prepareFrame(CompositionType compositionType);
-#ifndef USE_HWC2
-    virtual status_t compositionComplete();
-#endif
     virtual status_t advanceFrame();
     virtual void onFrameCommitted();
     virtual void dumpAsString(String8& result) const;
@@ -253,10 +250,7 @@
 
     bool mMustRecompose;
 
-#ifdef USE_HWC2
     HWComposerBufferCache mHwcBufferCache;
-#endif
-
 
     bool mForceHwcCopy;
 };
diff --git a/services/surfaceflinger/EventControlThread.cpp b/services/surfaceflinger/EventControlThread.cpp
index 052a959..02eea47 100644
--- a/services/surfaceflinger/EventControlThread.cpp
+++ b/services/surfaceflinger/EventControlThread.cpp
@@ -53,12 +53,7 @@
         }
 
         bool enable = requestedVsyncState == VsyncState::On;
-#ifdef USE_HWC2
         mFlinger->setVsyncEnabled(HWC_DISPLAY_PRIMARY, enable);
-#else
-        mFlinger->eventControl(HWC_DISPLAY_PRIMARY,
-                SurfaceFlinger::EVENT_VSYNC, enable);
-#endif
         currentVsyncState = requestedVsyncState;
     }
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 80987a4..aa3100e 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -85,9 +85,6 @@
         mFiltering(false),
         mNeedsFiltering(false),
         mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
-#ifndef USE_HWC2
-        mIsGlesComposition(false),
-#endif
         mProtectedByApp(false),
         mClientRef(client),
         mPotentialCursor(false),
@@ -128,13 +125,9 @@
     // drawing state & current state are identical
     mDrawingState = mCurrentState;
 
-#ifdef USE_HWC2
     const auto& hwc = flinger->getHwComposer();
     const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY);
     nsecs_t displayPeriod = activeConfig->getVsyncPeriod();
-#else
-    nsecs_t displayPeriod = flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
-#endif
     mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
 
     CompositorTiming compositorTiming;
@@ -157,12 +150,7 @@
  * 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*/) {}
-#else
-void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
-                             HWComposer::HWCLayerInterface* /*layer*/) {}
-#endif
 
 void Layer::onRemovedFromCurrentState() {
     // the layer is removed from SF mCurrentState to mLayersPendingRemoval
@@ -187,9 +175,7 @@
     // the layer is removed from SF mLayersPendingRemoval
     abandon();
 
-#ifdef USE_HWC2
     destroyAllHwcLayers();
-#endif
 
     for (const auto& child : mCurrentChildren) {
         child->onRemoved();
@@ -217,7 +203,6 @@
 // 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);
     HWC2::Layer* layer = hwc->createLayer(hwcId);
@@ -254,7 +239,6 @@
     LOG_ALWAYS_FATAL_IF(!mHwcLayers.empty(),
                         "All hardware composer layers should have been destroyed");
 }
-#endif
 
 Rect Layer::getContentCrop() const {
     // this is the crop rectangle that applies to the buffer
@@ -470,21 +454,12 @@
     return crop;
 }
 
-#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)
-#endif
 {
-#ifdef USE_HWC2
     const auto hwcId = displayDevice->getHwcDisplayId();
     auto& hwcInfo = mHwcLayers[hwcId];
-#else
-    layer.setDefaultState();
-#endif
 
     // enable this layer
-#ifdef USE_HWC2
     hwcInfo.forceClientComposition = false;
 
     if (isSecure() && !displayDevice->isSecure()) {
@@ -492,17 +467,9 @@
     }
 
     auto& hwcLayer = hwcInfo.layer;
-#else
-    layer.setSkip(false);
-
-    if (isSecure() && !hw->isSecure()) {
-        layer.setSkip(true);
-    }
-#endif
 
     // this gives us only the "orientation" component of the transform
     const State& s(getDrawingState());
-#ifdef USE_HWC2
     auto blendMode = HWC2::BlendMode::None;
     if (!isOpaque(s) || getAlpha() != 1.0f) {
         blendMode =
@@ -514,11 +481,6 @@
              " %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);
-    }
-#endif
 
     // apply the layer's transform, followed by the display's global transform
     // here we're guaranteed that the layer's transform preserves rects
@@ -527,11 +489,7 @@
     if (!s.crop.isEmpty()) {
         Rect activeCrop(s.crop);
         activeCrop = t.transform(activeCrop);
-#ifdef USE_HWC2
         if (!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) {
-#else
-        if (!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
-#endif
             activeCrop.clear();
         }
         activeCrop = t.inverse().transform(activeCrop, true);
@@ -558,7 +516,6 @@
             frame.clear();
         }
     }
-#ifdef USE_HWC2
     if (!frame.intersect(displayDevice->getViewport(), &frame)) {
         frame.clear();
     }
@@ -607,15 +564,6 @@
     error = hwcLayer->setInfo(type, appId);
     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();
-    }
-    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())));
-#endif
 
     /*
      * Transformations are applied in this order:
@@ -650,7 +598,6 @@
 
     // this gives us only the "orientation" component of the transform
     const uint32_t orientation = transform.getOrientation();
-#ifdef USE_HWC2
     if (orientation & Transform::ROT_INVALID) {
         // we can only handle simple transformation
         hwcInfo.forceClientComposition = true;
@@ -663,17 +610,8 @@
                  mName.string(), to_string(transform).c_str(), to_string(error).c_str(),
                  static_cast<int32_t>(error));
     }
-#else
-    if (orientation & Transform::ROT_INVALID) {
-        // we can only handle simple transformation
-        layer.setSkip(true);
-    } else {
-        layer.setTransform(orientation);
-    }
-#endif
 }
 
-#ifdef USE_HWC2
 void Layer::forceClientComposition(int32_t hwcId) {
     if (mHwcLayers.count(hwcId) == 0) {
         ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
@@ -682,32 +620,7 @@
 
     mHwcLayers[hwcId].forceClientComposition = true;
 }
-#else
-void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
-                                  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.
-    // Apply this display's projection's viewport to the visible region
-    // before giving it to the HWC HAL.
-    const Transform& tr = hw->getTransform();
-    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
-    layer.setVisibleRegionScreen(visible);
-    layer.setSurfaceDamage(surfaceDamageRegion);
-    mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER);
 
-    if (mSidebandStream.get()) {
-        layer.setSidebandStream(mSidebandStream);
-    } else {
-        // NOTE: buffer can be NULL if the client never drew into this
-        // layer yet, or if we ran out of memory
-        layer.setBuffer(mActiveBuffer);
-    }
-}
-#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) {
@@ -740,28 +653,6 @@
              mName.string(), position.left, position.top, to_string(error).c_str(),
              static_cast<int32_t>(error));
 }
-#else
-Rect Layer::getPosition(const sp<const DisplayDevice>& hw) {
-    // this gives us only the "orientation" component of the transform
-    const State& s(getCurrentState());
-
-    // apply the layer's transform, followed by the display's global transform
-    // here we're guaranteed that the layer's transform preserves rects
-    Rect win(s.active.w, s.active.h);
-    if (!s.crop.isEmpty()) {
-        win.intersect(s.crop, &win);
-    }
-    // subtract the transparent region and snap to the bounds
-    Rect bounds = reduce(win, s.activeTransparentRegion);
-    Rect frame(getTransform().transform(bounds));
-    frame.intersect(hw->getViewport(), &frame);
-    if (!s.finalCrop.isEmpty()) {
-        frame.intersect(s.finalCrop, &frame);
-    }
-    const Transform& tr(hw->getTransform());
-    return Rect(tr.transform(frame));
-}
-#endif
 
 // ---------------------------------------------------------------------------
 // drawing...
@@ -791,7 +682,6 @@
     clearWithOpenGL(renderArea, 0, 0, 0, 0);
 }
 
-#ifdef USE_HWC2
 void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type, bool callIntoHwc) {
     if (mHwcLayers.count(hwcId) == 0) {
         ALOGE("setCompositionType called without a valid HWC layer");
@@ -843,7 +733,6 @@
     }
     return mHwcLayers.at(hwcId).clearClientTarget;
 }
-#endif
 
 bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
     if (point->getFrameNumber() <= mCurrentFrameNumber) {
@@ -1496,7 +1385,7 @@
     info.mContentDirty = contentDirty;
     return info;
 }
-#ifdef USE_HWC2
+
 void Layer::miniDumpHeader(String8& result) {
     result.append("----------------------------------------");
     result.append("---------------------------------------\n");
@@ -1539,7 +1428,6 @@
     result.append("- - - - - - - - - - - - - - - - - - - - ");
     result.append("- - - - - - - - - - - - - - - - - - - -\n");
 }
-#endif
 
 void Layer::dumpFrameStats(String8& result) const {
     mFrameTracker.dumpStats(result);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 0580b9f..c125a3c 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -297,7 +297,6 @@
 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);
     virtual void setPerFrameData(const sp<const DisplayDevice>& displayDevice) = 0;
@@ -309,23 +308,11 @@
     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);
-    virtual void setAcquireFence(const sp<const DisplayDevice>& hw,
-                                 HWComposer::HWCLayerInterface& layer) = 0;
-    Rect getPosition(const sp<const DisplayDevice>& hw);
-#endif
 
     /*
      * called after page-flip
      */
-#ifdef USE_HWC2
     virtual void onLayerDisplayed(const sp<Fence>& releaseFence);
-#else
-    virtual void onLayerDisplayed(const sp<const DisplayDevice>& hw,
-                                  HWComposer::HWCLayerInterface* layer);
-#endif
 
     virtual void abandon() = 0;
 
@@ -346,10 +333,8 @@
                                    const std::shared_ptr<FenceTime>& presentFence,
                                    const CompositorTiming& compositorTiming) = 0;
 
-#ifdef USE_HWC2
     // If a buffer was replaced this frame, release the former buffer
     virtual void releasePendingBuffer(nsecs_t dequeueReadyTime) = 0;
-#endif
 
     /*
      * draw - performs some global clipping optimizations
@@ -425,7 +410,6 @@
 
     int32_t getQueuedFrameCount() const { return mQueuedFrames; }
 
-#ifdef USE_HWC2
     // -----------------------------------------------------------------------
 
     bool createHwcLayer(HWComposer* hwc, int32_t hwcId);
@@ -441,7 +425,6 @@
         return mHwcLayers[hwcId].layer;
     }
 
-#endif
     // -----------------------------------------------------------------------
 
     void clearWithOpenGL(const RenderArea& renderArea) const;
@@ -458,10 +441,8 @@
     LayerDebugInfo getLayerDebugInfo() const;
 
     /* always call base class first */
-#ifdef USE_HWC2
     static void miniDumpHeader(String8& result);
     void miniDump(String8& result, int32_t hwcId) const;
-#endif
     void dumpFrameStats(String8& result) const;
     void dumpFrameEvents(String8& result);
     void clearFrameStats();
@@ -673,7 +654,6 @@
 
     bool mPendingRemoval = false;
 
-#ifdef USE_HWC2
     // HWC items, accessed from the main thread
     struct HWCInfo {
         HWCInfo()
@@ -698,9 +678,6 @@
     // case we need to keep track. In non-mirror mode, a layer will have only one
     // HWCInfo. This map key is a display layerStack.
     std::unordered_map<int32_t, HWCInfo> mHwcLayers;
-#else
-    bool mIsGlesComposition;
-#endif
 
     // page-flip thread (currently main thread)
     bool mProtectedByApp; // application requires protected path to external sink
diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h
index faf1ec6..44b9dc9 100644
--- a/services/surfaceflinger/RenderArea.h
+++ b/services/surfaceflinger/RenderArea.h
@@ -24,10 +24,8 @@
     int getReqHeight() const { return mReqHeight; };
     int getReqWidth() const { return mReqWidth; };
     Transform::orientation_flags getRotationFlags() const { return mRotationFlags; };
-#ifdef USE_HWC2
     virtual bool getWideColorSupport() const = 0;
     virtual android_color_mode_t getActiveColorMode() const = 0;
-#endif
 
     status_t updateDimensions();
 
@@ -37,4 +35,4 @@
     Transform::orientation_flags mRotationFlags;
 };
 
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index daaa11e..3ae7042 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -44,7 +44,6 @@
 #include <fstream>
 
 // ---------------------------------------------------------------------------
-#ifdef USE_HWC2
 bool checkGlError(const char* op, int lineNumber) {
     bool errorFound = false;
     GLint error = glGetError();
@@ -103,7 +102,6 @@
     }
     file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
 }
-#endif
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -132,7 +130,6 @@
 
     //mColorBlindnessCorrection = M;
 
-#ifdef USE_HWC2
     if (mPlatformHasWideColor) {
         // Compute sRGB to DisplayP3 color transform
         // NOTE: For now, we are limiting wide-color support to
@@ -145,7 +142,6 @@
         mat4 gamutTransform(srgbToP3);
         mSrgbToDisplayP3 = gamutTransform;
     }
-#endif
 }
 
 GLES20RenderEngine::~GLES20RenderEngine() {
@@ -222,7 +218,6 @@
     }
 }
 
-#ifdef USE_HWC2
 void GLES20RenderEngine::setColorMode(android_color_mode mode) {
     ALOGV("setColorMode: %s (0x%x)", decodeColorMode(mode).c_str(), mode);
 
@@ -256,7 +251,6 @@
 bool GLES20RenderEngine::usesWideColor() {
     return mUseWideColor;
 }
-#endif
 
 void GLES20RenderEngine::setupLayerTexturing(const Texture& texture) {
     GLuint target = texture.getTextureTarget();
@@ -344,7 +338,6 @@
             mesh.getByteStride(),
             mesh.getPositions());
 
-#ifdef USE_HWC2
     if (usesWideColor()) {
         Description wideColorState = mState;
         if (mDataSpace != HAL_DATASPACE_DISPLAY_P3) {
@@ -366,11 +359,6 @@
 
         glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
     }
-#else
-    ProgramCache::getInstance().useProgram(mState);
-
-    glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
-#endif
 
     if (mesh.getTexCoordsSize()) {
         glDisableVertexAttribArray(Program::texCoords);
@@ -379,13 +367,11 @@
 
 void GLES20RenderEngine::dump(String8& result) {
     RenderEngine::dump(result);
-#ifdef USE_HWC2
     if (usesWideColor()) {
         result.append("Wide-color: On\n");
     } else {
         result.append("Wide-color: Off\n");
     }
-#endif
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index 5ac12fc..b96bfe0 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -70,7 +70,6 @@
             Transform::orientation_flags rotation);
     virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque,
             bool disableTexture, const half4& color) override;
-#ifdef USE_HWC2
 
     // Color management related functions and state
     void setColorMode(android_color_mode mode);
@@ -91,7 +90,6 @@
 
     // Currently only supporting sRGB and DisplayP3 color spaces
     mat4 mSrgbToDisplayP3;
-#endif
     bool mPlatformHasWideColor = false;
 
     virtual void setupLayerTexturing(const Texture& texture);
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index fa65979..7e05cec 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -101,12 +101,10 @@
             Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation) = 0;
     virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque,
             bool disableTexture, const half4& color) = 0;
-#ifdef USE_HWC2
     virtual void setColorMode(android_color_mode mode) = 0;
     virtual void setSourceDataSpace(android_dataspace source) = 0;
     virtual void setWideColor(bool hasWideColor) = 0;
     virtual bool usesWideColor() = 0;
-#endif
     virtual void setupLayerTexturing(const Texture& texture) = 0;
     virtual void setupLayerBlackedOut() = 0;
     virtual void setupFillWithColor(float r, float g, float b, float a) = 0;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index d13b188..96ba5fb 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2675,12 +2675,10 @@
     if (hasClientComposition) {
         ALOGV("hasClientComposition");
 
-#ifdef USE_HWC2
         mRenderEngine->setWideColor(
                 displayDevice->getWideColorSupport() && !mForceNativeColorMode);
         mRenderEngine->setColorMode(mForceNativeColorMode ?
                 HAL_COLOR_MODE_NATIVE : displayDevice->getActiveColorMode());
-#endif
         if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) {
             ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
                   displayDevice->getDisplayName().string());
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index d10b41b..67e4607 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -63,12 +63,8 @@
 #include "SurfaceTracing.h"
 #include "StartPropertySetThread.h"
 
-#ifdef USE_HWC2
 #include "DisplayHardware/HWC2.h"
 #include "DisplayHardware/HWComposer.h"
-#else
-#include "DisplayHardware/HWComposer_hwc1.h"
-#endif
 
 #include "Effects/Daltonizer.h"
 
@@ -117,11 +113,7 @@
 class SurfaceFlinger : public BnSurfaceComposer,
                        public PriorityDumper,
                        private IBinder::DeathRecipient,
-#ifdef USE_HWC2
                        private HWC2::ComposerCallback
-#else
-                       private HWComposer::EventHandler
-#endif
 {
 public:
 
@@ -217,11 +209,7 @@
 
     // enable/disable h/w composer event
     // TODO: this should be made accessible only to EventThread
-#ifdef USE_HWC2
     void setVsyncEnabled(int disp, int enabled);
-#else
-    void eventControl(int disp, int event, int enabled);
-#endif
 
     // called on the main thread by MessageQueue when an internal message
     // is received
@@ -344,18 +332,12 @@
     /* ------------------------------------------------------------------------
      * HWC2::ComposerCallback / HWComposer::EventHandler interface
      */
-#ifdef USE_HWC2
     void onVsyncReceived(int32_t sequenceId, hwc2_display_t display,
                          int64_t timestamp) override;
     void onHotplugReceived(int32_t sequenceId, hwc2_display_t display,
                            HWC2::Connection connection,
                            bool primaryDisplay) override;
     void onRefreshReceived(int32_t sequenceId, hwc2_display_t display) override;
-#else
-    void onVSyncReceived(HWComposer* composer, int type, nsecs_t timestamp) override;
-    void onHotplugReceived(HWComposer* composer, int disp, bool connected) override;
-    void onInvalidateReceived(HWComposer* composer) override;
-#endif
 
     /* ------------------------------------------------------------------------
      * Message handling
@@ -372,12 +354,8 @@
     // called on the main thread in response to setActiveConfig()
     void setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode);
     // called on the main thread in response to setPowerMode()
-#ifdef USE_HWC2
     void setPowerModeInternal(const sp<DisplayDevice>& hw, int mode,
                               bool stateLockHeld);
-#else
-    void setPowerModeInternal(const sp<DisplayDevice>& hw, int mode);
-#endif
 
     // Called on the main thread in response to setActiveColorMode()
     void setActiveColorModeInternal(const sp<DisplayDevice>& hw, android_color_mode_t colorMode);
@@ -463,17 +441,10 @@
                                  const sp<IGraphicBufferProducer>& producer,
                                  bool useIdentityTransform);
 
-#ifdef USE_HWC2
     status_t captureScreenImplLocked(const RenderArea& renderArea,
                                      TraverseLayersFunction traverseLayers,
                                      ANativeWindowBuffer* buffer, bool useIdentityTransform,
                                      bool isLocalScreenshot, int* outSyncFd);
-#else
-    status_t captureScreenImplLocked(const RenderArea& renderArea,
-                                     TraverseLayersFunction traverseLayers,
-                                     const sp<IGraphicBufferProducer>& producer,
-                                     bool useIdentityTransform, bool isLocalScreenshot);
-#endif
     void traverseLayersInDisplay(const sp<const DisplayDevice>& display, int32_t minLayerZ,
                                  int32_t maxLayerZ, const LayerVector::Visitor& visitor);
 
@@ -540,10 +511,6 @@
     // region of all screens presenting this layer stack.
     void invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty);
 
-#ifndef USE_HWC2
-    int32_t allocateHwcDisplayId(DisplayDevice::DisplayType type);
-#endif
-
     /* ------------------------------------------------------------------------
      * H/W composer
      */
@@ -642,7 +609,6 @@
     }
     status_t doDump(int fd, const Vector<String16>& args, bool asProto);
 
-#ifdef USE_HWC2
     /* ------------------------------------------------------------------------
      * VrFlinger
      */
@@ -650,7 +616,6 @@
 
     // Check to see if we should handoff to vr flinger.
     void updateVrFlinger();
-#endif
 
     /* ------------------------------------------------------------------------
      * Attributes
@@ -695,9 +660,7 @@
     // acquiring mStateLock.
     std::unique_ptr<HWComposer> mHwc;
 
-#ifdef USE_HWC2
     const std::string mHwcServiceName; // "default" for real use, something else for testing.
-#endif
 
     // constant members (no synchronization needed for access)
     RenderEngine* mRenderEngine;
@@ -716,17 +679,11 @@
     // don't need synchronization
     State mDrawingState{LayerVector::StateSet::Drawing};
     bool mVisibleRegionsDirty;
-#ifndef USE_HWC2
-    bool mHwWorkListDirty;
-#else
     bool mGeometryInvalid;
-#endif
     bool mAnimCompositionPending;
-#ifdef USE_HWC2
     std::vector<sp<Layer>> mLayersWithQueuedFrames;
     sp<Fence> mPreviousPresentFence = Fence::NO_FENCE;
     bool mHadClientComposition = false;
-#endif
     FenceTimeline mGlCompositionDoneTimeline;
     FenceTimeline mDisplayTimeline;
 
@@ -745,9 +702,7 @@
     nsecs_t mLastTransactionTime;
     bool mBootFinished;
     bool mForceFullDamage;
-#ifdef USE_HWC2
     bool mPropagateBackpressure = true;
-#endif
     SurfaceInterceptor mInterceptor;
     SurfaceTracing mTracing;
     bool mUseHwcVirtualDisplays = false;
@@ -789,9 +744,6 @@
     bool mInjectVSyncs;
 
     Daltonizer mDaltonizer;
-#ifndef USE_HWC2
-    bool mDaltonize;
-#endif
 
     mat4 mPreviousColorMatrix;
     mat4 mColorMatrix;
@@ -833,7 +785,6 @@
     // either AID_GRAPHICS or AID_SYSTEM.
     status_t CheckTransactCodeCredentials(uint32_t code);
 
-#ifdef USE_HWC2
     std::unique_ptr<dvr::VrFlinger> mVrFlinger;
     std::atomic<bool> mVrFlingerRequestsDisplay;
     static bool useVrFlinger;
@@ -842,7 +793,6 @@
     // use to differentiate callbacks from different hardware composer
     // instances. Each hardware composer instance gets a different sequence id.
     int32_t mComposerSequenceId;
-#endif
 
     float mSaturation = 1.0f;
     bool mForceNativeColorMode = false;
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index abc8fde..e17bb58 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -89,11 +89,7 @@
     }
 
     // Release the previous buffer.
-#ifdef USE_HWC2
     err = updateAndReleaseLocked(item, &mPendingRelease);
-#else
-    err = updateAndReleaseLocked(item);
-#endif
     if (err != NO_ERROR) {
         return err;
     }
@@ -197,7 +193,6 @@
     return ConsumerBase::mPrevFinalReleaseFence;
 }
 
-#ifdef USE_HWC2
 void SurfaceFlingerConsumer::setReleaseFence(const sp<Fence>& fence)
 {
     if (!mPendingRelease.isPending) {
@@ -230,7 +225,6 @@
     mPendingRelease = PendingRelease();
     return true;
 }
-#endif
 
 void SurfaceFlingerConsumer::setContentsChangedListener(
         const wp<ContentsChangedListener>& listener) {
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index 1126233..53b4915 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -81,10 +81,8 @@
     nsecs_t computeExpectedPresent(const DispSync& dispSync);
 
     sp<Fence> getPrevFinalReleaseFence() const;
-#ifdef USE_HWC2
     virtual void setReleaseFence(const sp<Fence>& fence) override;
     bool releasePendingBuffer();
-#endif
 
     void onDisconnect() override;
     void addAndGetFrameTimestamps(
@@ -104,11 +102,9 @@
     // The portion of this surface that has changed since the previous frame
     Region mSurfaceDamage;
 
-#ifdef USE_HWC2
     // A release that is pending on the receipt of a new release fence from
     // presentDisplay
     PendingRelease mPendingRelease;
-#endif
 
     // The layer for this SurfaceFlingerConsumer
     const wp<Layer> mLayer;
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
deleted file mode 100644
index ccadd44..0000000
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ /dev/null
@@ -1,4169 +0,0 @@
-/*
- * Copyright (C) 2007 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 ATRACE_TAG ATRACE_TAG_GRAPHICS
-
-#include <dlfcn.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <math.h>
-#include <stdatomic.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <mutex>
-
-#include <EGL/egl.h>
-
-#include <cutils/properties.h>
-#include <log/log.h>
-
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/PermissionCache.h>
-
-#include <ui/DisplayInfo.h>
-#include <ui/DisplayStatInfo.h>
-
-#include <gui/BufferQueue.h>
-#include <gui/GuiConfig.h>
-#include <gui/IDisplayEventConnection.h>
-#include <gui/LayerDebugInfo.h>
-#include <gui/Surface.h>
-
-#include <ui/GraphicBufferAllocator.h>
-#include <ui/HdrCapabilities.h>
-#include <ui/PixelFormat.h>
-#include <ui/UiConfig.h>
-
-#include <utils/misc.h>
-#include <utils/String8.h>
-#include <utils/String16.h>
-#include <utils/StopWatch.h>
-#include <utils/Timers.h>
-#include <utils/Trace.h>
-
-#include <private/android_filesystem_config.h>
-#include <private/gui/SyncFeatures.h>
-
-#include <set>
-
-#include "Client.h"
-#include "clz.h"
-#include "Colorizer.h"
-#include "DdmConnection.h"
-#include "DisplayDevice.h"
-#include "DispSync.h"
-#include "EventControlThread.h"
-#include "EventThread.h"
-#include "Layer.h"
-#include "BufferLayer.h"
-#include "LayerVector.h"
-#include "ColorLayer.h"
-#include "MonitoredProducer.h"
-#include "SurfaceFlinger.h"
-
-#include "DisplayHardware/FramebufferSurface.h"
-#include "DisplayHardware/HWComposer.h"
-#include "DisplayHardware/VirtualDisplaySurface.h"
-
-#include "Effects/Daltonizer.h"
-
-#include "RenderEngine/RenderEngine.h"
-#include <cutils/compiler.h>
-
-#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
-#include <configstore/Utils.h>
-
-#include <layerproto/LayerProtoParser.h>
-
-#define DISPLAY_COUNT       1
-
-/*
- * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all
- * black pixels.
- */
-#define DEBUG_SCREENSHOTS   false
-
-extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-using namespace android::hardware::configstore;
-using namespace android::hardware::configstore::V1_0;
-
-const String16 sHardwareTest("android.permission.HARDWARE_TEST");
-const String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
-const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
-const String16 sDump("android.permission.DUMP");
-
-// ---------------------------------------------------------------------------
-int64_t SurfaceFlinger::vsyncPhaseOffsetNs;
-int64_t SurfaceFlinger::sfVsyncPhaseOffsetNs;
-bool SurfaceFlinger::useContextPriority;
-int64_t SurfaceFlinger::dispSyncPresentTimeOffset;
-bool SurfaceFlinger::useHwcForRgbToYuv;
-uint64_t SurfaceFlinger::maxVirtualDisplaySize;
-bool SurfaceFlinger::hasSyncFramework;
-int64_t SurfaceFlinger::maxFrameBufferAcquiredBuffers;
-
-SurfaceFlinger::SurfaceFlinger()
-    :   BnSurfaceComposer(),
-        mTransactionFlags(0),
-        mTransactionPending(false),
-        mAnimTransactionPending(false),
-        mLayersRemoved(false),
-        mLayersAdded(false),
-        mRepaintEverything(0),
-        mRenderEngine(NULL),
-        mBootTime(systemTime()),
-        mVisibleRegionsDirty(false),
-        mHwWorkListDirty(false),
-        mAnimCompositionPending(false),
-        mDebugRegion(0),
-        mDebugDDMS(0),
-        mDebugDisableHWC(0),
-        mDebugDisableTransformHint(0),
-        mDebugInSwapBuffers(0),
-        mLastSwapBufferTime(0),
-        mDebugInTransaction(0),
-        mLastTransactionTime(0),
-        mBootFinished(false),
-        mForceFullDamage(false),
-        mInterceptor(this),
-        mPrimaryDispSync("PrimaryDispSync"),
-        mPrimaryHWVsyncEnabled(false),
-        mHWVsyncAvailable(false),
-        mDaltonize(false),
-        mHasColorMatrix(false),
-        mHasPoweredOff(false),
-        mFrameBuckets(),
-        mTotalTime(0),
-        mLastSwapTime(0),
-        mNumLayers(0)
-{
-    ALOGI("SurfaceFlinger is starting");
-
-    vsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
-            &ISurfaceFlingerConfigs::vsyncEventPhaseOffsetNs>(1000000);
-
-    sfVsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
-            &ISurfaceFlingerConfigs::vsyncSfEventPhaseOffsetNs>(1000000);
-
-    maxVirtualDisplaySize = getUInt64<ISurfaceFlingerConfigs,
-            &ISurfaceFlingerConfigs::maxVirtualDisplaySize>(0);
-
-    hasSyncFramework = getBool< ISurfaceFlingerConfigs,
-            &ISurfaceFlingerConfigs::hasSyncFramework>(true);
-
-    useContextPriority = getBool< ISurfaceFlingerConfigs,
-            &ISurfaceFlingerConfigs::useContextPriority>(false);
-
-    dispSyncPresentTimeOffset = getInt64< ISurfaceFlingerConfigs,
-            &ISurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs>(0);
-
-    useHwcForRgbToYuv = getBool< ISurfaceFlingerConfigs,
-            &ISurfaceFlingerConfigs::useHwcForRGBtoYUV>(false);
-
-    maxFrameBufferAcquiredBuffers = getInt64< ISurfaceFlingerConfigs,
-            &ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2);
-
-    mPrimaryDispSync.init(hasSyncFramework, dispSyncPresentTimeOffset);
-
-    char value[PROPERTY_VALUE_MAX];
-
-    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
-    mGpuToCpuSupported = !atoi(value);
-
-    property_get("debug.sf.showupdates", value, "0");
-    mDebugRegion = atoi(value);
-
-    property_get("debug.sf.ddms", value, "0");
-    mDebugDDMS = atoi(value);
-    if (mDebugDDMS) {
-        if (!startDdmConnection()) {
-            // start failed, and DDMS debugging not enabled
-            mDebugDDMS = 0;
-        }
-    }
-    ALOGI_IF(mDebugRegion, "showupdates enabled");
-    ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
-
-    property_get("debug.sf.enable_hwc_vds", value, "0");
-    mUseHwcVirtualDisplays = atoi(value);
-    ALOGI_IF(!mUseHwcVirtualDisplays, "Enabling HWC virtual displays");
-
-    property_get("ro.sf.disable_triple_buffer", value, "1");
-    mLayerTripleBufferingDisabled = atoi(value);
-    ALOGI_IF(mLayerTripleBufferingDisabled, "Disabling Triple Buffering");
-}
-
-void SurfaceFlinger::onFirstRef()
-{
-    mEventQueue.init(this);
-}
-
-SurfaceFlinger::~SurfaceFlinger()
-{
-    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-    eglTerminate(display);
-}
-
-void SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
-{
-    // the window manager died on us. prepare its eulogy.
-
-    // restore initial conditions (default device unblank, etc)
-    initializeDisplays();
-
-    // restart the boot-animation
-    startBootAnim();
-}
-
-static sp<ISurfaceComposerClient> initClient(const sp<Client>& client) {
-    status_t err = client->initCheck();
-    if (err == NO_ERROR) {
-        return client;
-    }
-    return nullptr;
-}
-
-sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
-    return initClient(new Client(this));
-}
-
-sp<ISurfaceComposerClient> SurfaceFlinger::createScopedConnection(
-        const sp<IGraphicBufferProducer>& gbp) {
-    if (authenticateSurfaceTexture(gbp) == false) {
-        return nullptr;
-    }
-    const auto& layer = (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
-    if (layer == nullptr) {
-        return nullptr;
-    }
-
-   return initClient(new Client(this, layer));
-}
-
-sp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
-        bool secure)
-{
-    class DisplayToken : public BBinder {
-        sp<SurfaceFlinger> flinger;
-        virtual ~DisplayToken() {
-             // no more references, this display must be terminated
-             Mutex::Autolock _l(flinger->mStateLock);
-             flinger->mCurrentState.displays.removeItem(this);
-             flinger->setTransactionFlags(eDisplayTransactionNeeded);
-         }
-     public:
-        explicit DisplayToken(const sp<SurfaceFlinger>& flinger)
-            : flinger(flinger) {
-        }
-    };
-
-    sp<BBinder> token = new DisplayToken(this);
-
-    Mutex::Autolock _l(mStateLock);
-    DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL, secure);
-    info.displayName = displayName;
-    mCurrentState.displays.add(token, info);
-    mInterceptor.saveDisplayCreation(info);
-    return token;
-}
-
-void SurfaceFlinger::destroyDisplay(const sp<IBinder>& display) {
-    Mutex::Autolock _l(mStateLock);
-
-    ssize_t idx = mCurrentState.displays.indexOfKey(display);
-    if (idx < 0) {
-        ALOGW("destroyDisplay: invalid display token");
-        return;
-    }
-
-    const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
-    if (!info.isVirtualDisplay()) {
-        ALOGE("destroyDisplay called for non-virtual display");
-        return;
-    }
-    mInterceptor.saveDisplayDeletion(info.displayId);
-    mCurrentState.displays.removeItemsAt(idx);
-    setTransactionFlags(eDisplayTransactionNeeded);
-}
-
-void SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
-    ALOGW_IF(mBuiltinDisplays[type],
-            "Overwriting display token for display type %d", type);
-    mBuiltinDisplays[type] = new BBinder();
-    // All non-virtual displays are currently considered secure.
-    DisplayDeviceState info(type, true);
-    mCurrentState.displays.add(mBuiltinDisplays[type], info);
-    mInterceptor.saveDisplayCreation(info);
-}
-
-sp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
-    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
-        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
-        return NULL;
-    }
-    return mBuiltinDisplays[id];
-}
-
-void SurfaceFlinger::bootFinished()
-{
-    if (mStartPropertySetThread->join() != NO_ERROR) {
-        ALOGE("Join StartPropertySetThread failed!");
-    }
-    const nsecs_t now = systemTime();
-    const nsecs_t duration = now - mBootTime;
-    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
-    mBootFinished = true;
-
-    // wait patiently for the window manager death
-    const String16 name("window");
-    sp<IBinder> window(defaultServiceManager()->getService(name));
-    if (window != 0) {
-        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
-    }
-
-    // stop boot animation
-    // formerly we would just kill the process, but we now ask it to exit so it
-    // can choose where to stop the animation.
-    property_set("service.bootanim.exit", "1");
-
-    const int LOGTAG_SF_STOP_BOOTANIM = 60110;
-    LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
-                   ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
-}
-
-void SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
-    class MessageDestroyGLTexture : public MessageBase {
-        RenderEngine& engine;
-        uint32_t texture;
-    public:
-        MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
-            : engine(engine), texture(texture) {
-        }
-        virtual bool handler() {
-            engine.deleteTextures(1, &texture);
-            return true;
-        }
-    };
-    postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
-}
-
-class DispSyncSource : public VSyncSource, private DispSync::Callback {
-public:
-    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
-        const char* name) :
-            mName(name),
-            mValue(0),
-            mTraceVsync(traceVsync),
-            mVsyncOnLabel(String8::format("VsyncOn-%s", name)),
-            mVsyncEventLabel(String8::format("VSYNC-%s", name)),
-            mDispSync(dispSync),
-            mCallbackMutex(),
-            mCallback(),
-            mVsyncMutex(),
-            mPhaseOffset(phaseOffset),
-            mEnabled(false) {}
-
-    virtual ~DispSyncSource() {}
-
-    virtual void setVSyncEnabled(bool enable) {
-        Mutex::Autolock lock(mVsyncMutex);
-        if (enable) {
-            status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
-                    static_cast<DispSync::Callback*>(this));
-            if (err != NO_ERROR) {
-                ALOGE("error registering vsync callback: %s (%d)",
-                        strerror(-err), err);
-            }
-            //ATRACE_INT(mVsyncOnLabel.string(), 1);
-        } else {
-            status_t err = mDispSync->removeEventListener(
-                    static_cast<DispSync::Callback*>(this));
-            if (err != NO_ERROR) {
-                ALOGE("error unregistering vsync callback: %s (%d)",
-                        strerror(-err), err);
-            }
-            //ATRACE_INT(mVsyncOnLabel.string(), 0);
-        }
-        mEnabled = enable;
-    }
-
-    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
-        Mutex::Autolock lock(mCallbackMutex);
-        mCallback = callback;
-    }
-
-    virtual void setPhaseOffset(nsecs_t phaseOffset) {
-        Mutex::Autolock lock(mVsyncMutex);
-
-        // Normalize phaseOffset to [0, period)
-        auto period = mDispSync->getPeriod();
-        phaseOffset %= period;
-        if (phaseOffset < 0) {
-            // If we're here, then phaseOffset is in (-period, 0). After this
-            // operation, it will be in (0, period)
-            phaseOffset += period;
-        }
-        mPhaseOffset = phaseOffset;
-
-        // If we're not enabled, we don't need to mess with the listeners
-        if (!mEnabled) {
-            return;
-        }
-
-        // Remove the listener with the old offset
-        status_t err = mDispSync->removeEventListener(
-                static_cast<DispSync::Callback*>(this));
-        if (err != NO_ERROR) {
-            ALOGE("error unregistering vsync callback: %s (%d)",
-                    strerror(-err), err);
-        }
-
-        // Add a listener with the new offset
-        err = mDispSync->addEventListener(mName, mPhaseOffset,
-                static_cast<DispSync::Callback*>(this));
-        if (err != NO_ERROR) {
-            ALOGE("error registering vsync callback: %s (%d)",
-                    strerror(-err), err);
-        }
-    }
-
-private:
-    virtual void onDispSyncEvent(nsecs_t when) {
-        sp<VSyncSource::Callback> callback;
-        {
-            Mutex::Autolock lock(mCallbackMutex);
-            callback = mCallback;
-
-            if (mTraceVsync) {
-                mValue = (mValue + 1) % 2;
-                ATRACE_INT(mVsyncEventLabel.string(), mValue);
-            }
-        }
-
-        if (callback != NULL) {
-            callback->onVSyncEvent(when);
-        }
-    }
-
-    const char* const mName;
-
-    int mValue;
-
-    const bool mTraceVsync;
-    const String8 mVsyncOnLabel;
-    const String8 mVsyncEventLabel;
-
-    DispSync* mDispSync;
-
-    Mutex mCallbackMutex; // Protects the following
-    sp<VSyncSource::Callback> mCallback;
-
-    Mutex mVsyncMutex; // Protects the following
-    nsecs_t mPhaseOffset;
-    bool mEnabled;
-};
-
-class InjectVSyncSource : public VSyncSource {
-public:
-    InjectVSyncSource() {}
-
-    virtual ~InjectVSyncSource() {}
-
-    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
-        std::lock_guard<std::mutex> lock(mCallbackMutex);
-        mCallback = callback;
-    }
-
-    virtual void onInjectSyncEvent(nsecs_t when) {
-        std::lock_guard<std::mutex> lock(mCallbackMutex);
-        mCallback->onVSyncEvent(when);
-    }
-
-    virtual void setVSyncEnabled(bool) {}
-    virtual void setPhaseOffset(nsecs_t) {}
-
-private:
-    std::mutex mCallbackMutex; // Protects the following
-    sp<VSyncSource::Callback> mCallback;
-};
-
-// Do not call property_set on main thread which will be blocked by init
-// Use StartPropertySetThread instead.
-void SurfaceFlinger::init() {
-    ALOGI(  "SurfaceFlinger's main thread ready to run. "
-            "Initializing graphics H/W...");
-
-    Mutex::Autolock _l(mStateLock);
-
-    // initialize EGL for the default display
-    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    eglInitialize(mEGLDisplay, NULL, NULL);
-
-    // start the EventThread
-    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
-            vsyncPhaseOffsetNs, true, "app");
-    mEventThread = new EventThread(vsyncSrc, *this, false);
-    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
-            sfVsyncPhaseOffsetNs, true, "sf");
-    mSFEventThread = new EventThread(sfVsyncSrc, *this, true);
-    mEventQueue.setEventThread(mSFEventThread);
-
-    // set EventThread and SFEventThread to SCHED_FIFO to minimize jitter
-    struct sched_param param = {0};
-    param.sched_priority = 2;
-    if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, &param) != 0) {
-        ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
-    }
-    if (sched_setscheduler(mEventThread->getTid(), SCHED_FIFO, &param) != 0) {
-        ALOGE("Couldn't set SCHED_FIFO for EventThread");
-    }
-
-    // Initialize the H/W composer object.  There may or may not be an
-    // actual hardware composer underneath.
-    mHwc.reset(new HWComposer(this,
-            *static_cast<HWComposer::EventHandler *>(this)));
-
-    // get a RenderEngine for the given display / config (can't fail)
-    mRenderEngine = RenderEngine::create(mEGLDisplay,
-            mHwc->getVisualID(), 0);
-
-    // retrieve the EGL context that was selected/created
-    mEGLContext = mRenderEngine->getEGLContext();
-
-    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
-            "couldn't create EGLContext");
-
-    // initialize our non-virtual displays
-    for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
-        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
-        // set-up the displays that are already connected
-        if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
-            // All non-virtual displays are currently considered secure.
-            bool isSecure = true;
-            createBuiltinDisplayLocked(type);
-            wp<IBinder> token = mBuiltinDisplays[i];
-
-            sp<IGraphicBufferProducer> producer;
-            sp<IGraphicBufferConsumer> consumer;
-            BufferQueue::createBufferQueue(&producer, &consumer);
-
-            sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,
-                    consumer);
-            int32_t hwcId = allocateHwcDisplayId(type);
-            sp<DisplayDevice> hw = new DisplayDevice(this,
-                    type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
-                    fbs, producer,
-                    mRenderEngine->getEGLConfig(), false);
-            if (i > DisplayDevice::DISPLAY_PRIMARY) {
-                // FIXME: currently we don't get blank/unblank requests
-                // for displays other than the main display, so we always
-                // assume a connected display is unblanked.
-                ALOGD("marking display %zu as acquired/unblanked", i);
-                hw->setPowerMode(HWC_POWER_MODE_NORMAL);
-            }
-            mDisplays.add(token, hw);
-        }
-    }
-
-    // make the GLContext current so that we can create textures when creating Layers
-    // (which may happens before we render something)
-    getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext);
-
-    mEventControlThread = new EventControlThread(this);
-    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
-
-    // set a fake vsync period if there is no HWComposer
-    if (mHwc->initCheck() != NO_ERROR) {
-        mPrimaryDispSync.setPeriod(16666667);
-    }
-
-    // initialize our drawing state
-    mDrawingState = mCurrentState;
-
-    // set initial conditions (e.g. unblank default device)
-    initializeDisplays();
-
-    mRenderEngine->primeCache();
-
-    // Inform native graphics APIs that the present timestamp is NOT supported:
-    mStartPropertySetThread = new StartPropertySetThread(false);
-    if (mStartPropertySetThread->Start() != NO_ERROR) {
-        ALOGE("Run StartPropertySetThread failed!");
-    }
-
-    ALOGV("Done initializing");
-}
-
-int32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) {
-    return (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) ?
-            type : mHwc->allocateDisplayId();
-}
-
-void SurfaceFlinger::startBootAnim() {
-    // Start boot animation service by setting a property mailbox
-    // if property setting thread is already running, Start() will be just a NOP
-    mStartPropertySetThread->Start();
-    // Wait until property was set
-    if (mStartPropertySetThread->join() != NO_ERROR) {
-        ALOGE("Join StartPropertySetThread failed!");
-    }
-}
-
-size_t SurfaceFlinger::getMaxTextureSize() const {
-    return mRenderEngine->getMaxTextureSize();
-}
-
-size_t SurfaceFlinger::getMaxViewportDims() const {
-    return mRenderEngine->getMaxViewportDims();
-}
-
-// ----------------------------------------------------------------------------
-
-bool SurfaceFlinger::authenticateSurfaceTexture(
-        const sp<IGraphicBufferProducer>& bufferProducer) const {
-    Mutex::Autolock _l(mStateLock);
-    return authenticateSurfaceTextureLocked(bufferProducer);
-}
-
-bool SurfaceFlinger::authenticateSurfaceTextureLocked(
-        const sp<IGraphicBufferProducer>& bufferProducer) const {
-    sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
-    return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
-}
-
-status_t SurfaceFlinger::getSupportedFrameTimestamps(
-        std::vector<FrameEvent>* outSupported) const {
-    *outSupported = {
-        FrameEvent::REQUESTED_PRESENT,
-        FrameEvent::ACQUIRE,
-        FrameEvent::LATCH,
-        FrameEvent::FIRST_REFRESH_START,
-        FrameEvent::LAST_REFRESH_START,
-        FrameEvent::GPU_COMPOSITION_DONE,
-        FrameEvent::DEQUEUE_READY,
-        FrameEvent::RELEASE,
-    };
-    return NO_ERROR;
-}
-
-status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
-        Vector<DisplayInfo>* configs) {
-    if ((configs == NULL) || (display.get() == NULL)) {
-        return BAD_VALUE;
-    }
-
-    int32_t type = getDisplayType(display);
-    if (type < 0) return type;
-
-    // TODO: Not sure if display density should handled by SF any longer
-    class Density {
-        static int getDensityFromProperty(char const* propName) {
-            char property[PROPERTY_VALUE_MAX];
-            int density = 0;
-            if (property_get(propName, property, NULL) > 0) {
-                density = atoi(property);
-            }
-            return density;
-        }
-    public:
-        static int getEmuDensity() {
-            return getDensityFromProperty("qemu.sf.lcd_density"); }
-        static int getBuildDensity()  {
-            return getDensityFromProperty("ro.sf.lcd_density"); }
-    };
-
-    configs->clear();
-
-    const Vector<HWComposer::DisplayConfig>& hwConfigs =
-            getHwComposer().getConfigs(type);
-    for (size_t c = 0; c < hwConfigs.size(); ++c) {
-        const HWComposer::DisplayConfig& hwConfig = hwConfigs[c];
-        DisplayInfo info = DisplayInfo();
-
-        float xdpi = hwConfig.xdpi;
-        float ydpi = hwConfig.ydpi;
-
-        if (type == DisplayDevice::DISPLAY_PRIMARY) {
-            // The density of the device is provided by a build property
-            float density = Density::getBuildDensity() / 160.0f;
-            if (density == 0) {
-                // the build doesn't provide a density -- this is wrong!
-                // use xdpi instead
-                ALOGE("ro.sf.lcd_density must be defined as a build property");
-                density = xdpi / 160.0f;
-            }
-            if (Density::getEmuDensity()) {
-                // if "qemu.sf.lcd_density" is specified, it overrides everything
-                xdpi = ydpi = density = Density::getEmuDensity();
-                density /= 160.0f;
-            }
-            info.density = density;
-
-            // TODO: this needs to go away (currently needed only by webkit)
-            sp<const DisplayDevice> hw(getDefaultDisplayDevice());
-            info.orientation = hw->getOrientation();
-        } else {
-            // TODO: where should this value come from?
-            static const int TV_DENSITY = 213;
-            info.density = TV_DENSITY / 160.0f;
-            info.orientation = 0;
-        }
-
-        info.w = hwConfig.width;
-        info.h = hwConfig.height;
-        info.xdpi = xdpi;
-        info.ydpi = ydpi;
-        info.fps = float(1e9 / hwConfig.refresh);
-        info.appVsyncOffset = vsyncPhaseOffsetNs;
-
-        // This is how far in advance a buffer must be queued for
-        // presentation at a given time.  If you want a buffer to appear
-        // on the screen at time N, you must submit the buffer before
-        // (N - presentationDeadline).
-        //
-        // Normally it's one full refresh period (to give SF a chance to
-        // latch the buffer), but this can be reduced by configuring a
-        // DispSync offset.  Any additional delays introduced by the hardware
-        // composer or panel must be accounted for here.
-        //
-        // We add an additional 1ms to allow for processing time and
-        // differences between the ideal and actual refresh rate.
-        info.presentationDeadline =
-                hwConfig.refresh - sfVsyncPhaseOffsetNs + 1000000;
-
-        // All non-virtual displays are currently considered secure.
-        info.secure = true;
-
-        configs->push_back(info);
-    }
-
-    return NO_ERROR;
-}
-
-status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& /* display */,
-        DisplayStatInfo* stats) {
-    if (stats == NULL) {
-        return BAD_VALUE;
-    }
-
-    // FIXME for now we always return stats for the primary display
-    memset(stats, 0, sizeof(*stats));
-    stats->vsyncTime   = mPrimaryDispSync.computeNextRefresh(0);
-    stats->vsyncPeriod = mPrimaryDispSync.getPeriod();
-    return NO_ERROR;
-}
-
-int SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
-    sp<const DisplayDevice> device(getDisplayDevice(display));
-    if (device != NULL) {
-        return device->getActiveConfig();
-    }
-    return BAD_VALUE;
-}
-
-void SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) {
-    ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
-          this);
-    int32_t type = hw->getDisplayType();
-    int currentMode = hw->getActiveConfig();
-
-    if (mode == currentMode) {
-        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
-        return;
-    }
-
-    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
-        ALOGW("Trying to set config for virtual display");
-        return;
-    }
-
-    hw->setActiveConfig(mode);
-    getHwComposer().setActiveConfig(type, mode);
-}
-
-status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
-    class MessageSetActiveConfig: public MessageBase {
-        SurfaceFlinger& mFlinger;
-        sp<IBinder> mDisplay;
-        int mMode;
-    public:
-        MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp,
-                               int mode) :
-            mFlinger(flinger), mDisplay(disp) { mMode = mode; }
-        virtual bool handler() {
-            Vector<DisplayInfo> configs;
-            mFlinger.getDisplayConfigs(mDisplay, &configs);
-            if (mMode < 0 || mMode >= static_cast<int>(configs.size())) {
-                ALOGE("Attempt to set active config = %d for display with %zu configs",
-                        mMode, configs.size());
-            }
-            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
-            if (hw == NULL) {
-                ALOGE("Attempt to set active config = %d for null display %p",
-                        mMode, mDisplay.get());
-            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
-                ALOGW("Attempt to set active config = %d for virtual display",
-                        mMode);
-            } else {
-                mFlinger.setActiveConfigInternal(hw, mMode);
-            }
-            return true;
-        }
-    };
-    sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode);
-    postMessageSync(msg);
-    return NO_ERROR;
-}
-
-status_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& display,
-        Vector<android_color_mode_t>* outColorModes) {
-    if (outColorModes == nullptr || display.get() == nullptr) {
-        return BAD_VALUE;
-    }
-
-    int32_t type = getDisplayType(display);
-    if (type < 0) return type;
-
-    std::set<android_color_mode_t> colorModes;
-    for (const HWComposer::DisplayConfig& hwConfig : getHwComposer().getConfigs(type)) {
-        colorModes.insert(hwConfig.colorMode);
-    }
-
-    outColorModes->clear();
-    std::copy(colorModes.cbegin(), colorModes.cend(), std::back_inserter(*outColorModes));
-
-    return NO_ERROR;
-}
-
-android_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) {
-    if (display.get() == nullptr) return static_cast<android_color_mode_t>(BAD_VALUE);
-
-    int32_t type = getDisplayType(display);
-    if (type < 0) return static_cast<android_color_mode_t>(type);
-
-    return getHwComposer().getColorMode(type);
-}
-
-status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& display,
-        android_color_mode_t colorMode) {
-    if (display.get() == nullptr || colorMode < 0) {
-        return BAD_VALUE;
-    }
-
-    int32_t type = getDisplayType(display);
-    if (type < 0) return type;
-    const Vector<HWComposer::DisplayConfig>& hwConfigs = getHwComposer().getConfigs(type);
-    HWComposer::DisplayConfig desiredConfig = hwConfigs[getHwComposer().getCurrentConfig(type)];
-    desiredConfig.colorMode = colorMode;
-    for (size_t c = 0; c < hwConfigs.size(); ++c) {
-        const HWComposer::DisplayConfig config = hwConfigs[c];
-        if (config == desiredConfig) {
-            return setActiveConfig(display, c);
-        }
-    }
-    return BAD_VALUE;
-}
-
-status_t SurfaceFlinger::clearAnimationFrameStats() {
-    Mutex::Autolock _l(mStateLock);
-    mAnimFrameTracker.clearStats();
-    return NO_ERROR;
-}
-
-status_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {
-    Mutex::Autolock _l(mStateLock);
-    mAnimFrameTracker.getStats(outStats);
-    return NO_ERROR;
-}
-
-status_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& /*display*/,
-        HdrCapabilities* outCapabilities) const {
-    // HWC1 does not provide HDR capabilities
-    *outCapabilities = HdrCapabilities();
-    return NO_ERROR;
-}
-
-status_t SurfaceFlinger::enableVSyncInjections(bool enable) {
-    if (enable == mInjectVSyncs) {
-        return NO_ERROR;
-    }
-
-    if (enable) {
-        mInjectVSyncs = enable;
-        ALOGV("VSync Injections enabled");
-        if (mVSyncInjector.get() == nullptr) {
-            mVSyncInjector = new InjectVSyncSource();
-            mInjectorEventThread = new EventThread(mVSyncInjector, *this, false);
-        }
-        mEventQueue.setEventThread(mInjectorEventThread);
-    } else {
-        mInjectVSyncs = enable;
-        ALOGV("VSync Injections disabled");
-        mEventQueue.setEventThread(mSFEventThread);
-        mVSyncInjector.clear();
-    }
-    return NO_ERROR;
-}
-
-status_t SurfaceFlinger::injectVSync(nsecs_t when) {
-    if (!mInjectVSyncs) {
-        ALOGE("VSync Injections not enabled");
-        return BAD_VALUE;
-    }
-    if (mInjectVSyncs && mInjectorEventThread.get() != nullptr) {
-        ALOGV("Injecting VSync inside SurfaceFlinger");
-        mVSyncInjector->onInjectSyncEvent(when);
-    }
-    return NO_ERROR;
-}
-
-status_t SurfaceFlinger::getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const {
-    IPCThreadState* ipc = IPCThreadState::self();
-    const int pid = ipc->getCallingPid();
-    const int uid = ipc->getCallingUid();
-    if ((uid != AID_SHELL) &&
-            !PermissionCache::checkPermission(sDump, pid, uid)) {
-        ALOGE("Layer debug info permission denied for pid=%d, uid=%d", pid, uid);
-        return PERMISSION_DENIED;
-    }
-
-    // Try to acquire a lock for 1s, fail gracefully
-    status_t err = mStateLock.timedLock(s2ns(1));
-    bool locked = (err == NO_ERROR);
-    if (!locked) {
-        ALOGE("LayerDebugInfo: SurfaceFlinger unresponsive (%s [%d]) - exit", strerror(-err), err);
-        return TIMED_OUT;
-    }
-
-    outLayers->clear();
-    mCurrentState.traverseInZOrder([&](Layer* layer) {
-            outLayers->push_back(layer->getLayerDebugInfo());
-        });
-
-    mStateLock.unlock();
-
-    return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
-        ISurfaceComposer::VsyncSource vsyncSource) {
-    if (vsyncSource == eVsyncSourceSurfaceFlinger) {
-        return mSFEventThread->createEventConnection();
-    } else {
-        return mEventThread->createEventConnection();
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-void SurfaceFlinger::waitForEvent() {
-    mEventQueue.waitMessage();
-}
-
-void SurfaceFlinger::signalTransaction() {
-    mEventQueue.invalidate();
-}
-
-void SurfaceFlinger::signalLayerUpdate() {
-    mEventQueue.invalidate();
-}
-
-void SurfaceFlinger::signalRefresh() {
-    mEventQueue.refresh();
-}
-
-status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
-        nsecs_t reltime, uint32_t /* flags */) {
-    return mEventQueue.postMessage(msg, reltime);
-}
-
-status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
-        nsecs_t reltime, uint32_t /* flags */) {
-    status_t res = mEventQueue.postMessage(msg, reltime);
-    if (res == NO_ERROR) {
-        msg->wait();
-    }
-    return res;
-}
-
-void SurfaceFlinger::run() {
-    do {
-        waitForEvent();
-    } while (true);
-}
-
-void SurfaceFlinger::enableHardwareVsync() {
-    Mutex::Autolock _l(mHWVsyncLock);
-    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
-        mPrimaryDispSync.beginResync();
-        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
-        mEventControlThread->setVsyncEnabled(true);
-        mPrimaryHWVsyncEnabled = true;
-    }
-}
-
-void SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
-    Mutex::Autolock _l(mHWVsyncLock);
-
-    if (makeAvailable) {
-        mHWVsyncAvailable = true;
-    } else if (!mHWVsyncAvailable) {
-        // Hardware vsync is not currently available, so abort the resync
-        // attempt for now
-        return;
-    }
-
-    const nsecs_t period =
-            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
-
-    mPrimaryDispSync.reset();
-    mPrimaryDispSync.setPeriod(period);
-
-    if (!mPrimaryHWVsyncEnabled) {
-        mPrimaryDispSync.beginResync();
-        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
-        mEventControlThread->setVsyncEnabled(true);
-        mPrimaryHWVsyncEnabled = true;
-    }
-}
-
-void SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
-    Mutex::Autolock _l(mHWVsyncLock);
-    if (mPrimaryHWVsyncEnabled) {
-        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
-        mEventControlThread->setVsyncEnabled(false);
-        mPrimaryDispSync.endResync();
-        mPrimaryHWVsyncEnabled = false;
-    }
-    if (makeUnavailable) {
-        mHWVsyncAvailable = false;
-    }
-}
-
-void SurfaceFlinger::resyncWithRateLimit() {
-    static constexpr nsecs_t kIgnoreDelay = ms2ns(500);
-    if (systemTime() - mLastSwapTime > kIgnoreDelay) {
-        resyncToHardwareVsync(false);
-    }
-}
-
-void SurfaceFlinger::onVSyncReceived(HWComposer* /*composer*/, int type,
-                                     nsecs_t timestamp) {
-    bool needsHwVsync = false;
-
-    { // Scope for the lock
-        Mutex::Autolock _l(mHWVsyncLock);
-        if (type == 0 && mPrimaryHWVsyncEnabled) {
-            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
-        }
-    }
-
-    if (needsHwVsync) {
-        enableHardwareVsync();
-    } else {
-        disableHardwareVsync(false);
-    }
-}
-
-void SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) {
-    std::lock_guard<std::mutex> lock(mCompositorTimingLock);
-    *compositorTiming = mCompositorTiming;
-}
-
-void SurfaceFlinger::onHotplugReceived(HWComposer* /*composer*/, int type, bool connected) {
-    if (mEventThread == NULL) {
-        // This is a temporary workaround for b/7145521.  A non-null pointer
-        // does not mean EventThread has finished initializing, so this
-        // is not a correct fix.
-        ALOGW("WARNING: EventThread not started, ignoring hotplug");
-        return;
-    }
-
-    if (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
-        Mutex::Autolock _l(mStateLock);
-        if (connected) {
-            createBuiltinDisplayLocked((DisplayDevice::DisplayType)type);
-        } else {
-            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
-            mBuiltinDisplays[type].clear();
-        }
-        setTransactionFlags(eDisplayTransactionNeeded);
-
-        // Defer EventThread notification until SF has updated mDisplays.
-    }
-}
-
-void SurfaceFlinger::onInvalidateReceived(HWComposer* /*composer*/) {
-    repaintEverything();
-}
-
-void SurfaceFlinger::eventControl(int disp, int event, int enabled) {
-    ATRACE_CALL();
-    getHwComposer().eventControl(disp, event, enabled);
-}
-
-void SurfaceFlinger::onMessageReceived(int32_t what) {
-    ATRACE_CALL();
-    switch (what) {
-        case MessageQueue::INVALIDATE: {
-            bool refreshNeeded = handleMessageTransaction();
-            refreshNeeded |= handleMessageInvalidate();
-            refreshNeeded |= mRepaintEverything;
-            if (refreshNeeded) {
-                // Signal a refresh if a transaction modified the window state,
-                // a new buffer was latched, or if HWC has requested a full
-                // repaint
-                signalRefresh();
-            }
-            break;
-        }
-        case MessageQueue::REFRESH: {
-            handleMessageRefresh();
-            break;
-        }
-    }
-}
-
-bool SurfaceFlinger::handleMessageTransaction() {
-    uint32_t transactionFlags = peekTransactionFlags();
-    if (transactionFlags) {
-        handleTransaction(transactionFlags);
-        return true;
-    }
-    return false;
-}
-
-bool SurfaceFlinger::handleMessageInvalidate() {
-    ATRACE_CALL();
-    return handlePageFlip();
-}
-
-void SurfaceFlinger::handleMessageRefresh() {
-    ATRACE_CALL();
-
-    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
-
-    preComposition(refreshStartTime);
-    rebuildLayerStacks();
-    setUpHWComposer();
-    doDebugFlashRegions();
-    doComposition();
-    postComposition(refreshStartTime);
-}
-
-void SurfaceFlinger::doDebugFlashRegions()
-{
-    // is debugging enabled
-    if (CC_LIKELY(!mDebugRegion))
-        return;
-
-    const bool repaintEverything = mRepaintEverything;
-    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-        const sp<DisplayDevice>& hw(mDisplays[dpy]);
-        if (hw->isDisplayOn()) {
-            // transform the dirty region into this screen's coordinate space
-            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
-            if (!dirtyRegion.isEmpty()) {
-                // redraw the whole screen
-                doComposeSurfaces(hw, Region(hw->bounds()));
-
-                // and draw the dirty region
-                const int32_t height = hw->getHeight();
-                RenderEngine& engine(getRenderEngine());
-                engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
-
-                hw->compositionComplete();
-                hw->swapBuffers(getHwComposer());
-            }
-        }
-    }
-
-    postFramebuffer();
-
-    if (mDebugRegion > 1) {
-        usleep(mDebugRegion * 1000);
-    }
-
-    HWComposer& hwc(getHwComposer());
-    if (hwc.initCheck() == NO_ERROR) {
-        status_t err = hwc.prepare();
-        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
-    }
-}
-
-void SurfaceFlinger::preComposition(nsecs_t refreshStartTime)
-{
-    bool needExtraInvalidate = false;
-    mDrawingState.traverseInZOrder([&](Layer* layer) {
-        if (layer->onPreComposition(refreshStartTime)) {
-            needExtraInvalidate = true;
-        }
-    });
-
-    if (needExtraInvalidate) {
-        signalLayerUpdate();
-    }
-}
-
-void SurfaceFlinger::updateCompositorTiming(
-        nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeTime,
-        std::shared_ptr<FenceTime>& presentFenceTime) {
-    // Update queue of past composite+present times and determine the
-    // most recently known composite to present latency.
-    mCompositePresentTimes.push({compositeTime, presentFenceTime});
-    nsecs_t compositeToPresentLatency = -1;
-    while (!mCompositePresentTimes.empty()) {
-        CompositePresentTime& cpt = mCompositePresentTimes.front();
-        // Cached values should have been updated before calling this method,
-        // which helps avoid duplicate syscalls.
-        nsecs_t displayTime = cpt.display->getCachedSignalTime();
-        if (displayTime == Fence::SIGNAL_TIME_PENDING) {
-            break;
-        }
-        compositeToPresentLatency = displayTime - cpt.composite;
-        mCompositePresentTimes.pop();
-    }
-
-    // Don't let mCompositePresentTimes grow unbounded, just in case.
-    while (mCompositePresentTimes.size() > 16) {
-        mCompositePresentTimes.pop();
-    }
-
-    setCompositorTimingSnapped(
-            vsyncPhase, vsyncInterval, compositeToPresentLatency);
-}
-
-void SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase,
-        nsecs_t vsyncInterval, nsecs_t compositeToPresentLatency) {
-    // Integer division and modulo round toward 0 not -inf, so we need to
-    // treat negative and positive offsets differently.
-    nsecs_t idealLatency = (sfVsyncPhaseOffsetNs > 0) ?
-            (vsyncInterval - (sfVsyncPhaseOffsetNs % vsyncInterval)) :
-            ((-sfVsyncPhaseOffsetNs) % vsyncInterval);
-
-    // Just in case sfVsyncPhaseOffsetNs == -vsyncInterval.
-    if (idealLatency <= 0) {
-        idealLatency = vsyncInterval;
-    }
-
-    // Snap the latency to a value that removes scheduling jitter from the
-    // composition and present times, which often have >1ms of jitter.
-    // Reducing jitter is important if an app attempts to extrapolate
-    // something (such as user input) to an accurate diasplay time.
-    // Snapping also allows an app to precisely calculate sfVsyncPhaseOffsetNs
-    // with (presentLatency % interval).
-    nsecs_t bias = vsyncInterval / 2;
-    int64_t extraVsyncs =
-            (compositeToPresentLatency - idealLatency + bias) / vsyncInterval;
-    nsecs_t snappedCompositeToPresentLatency = (extraVsyncs > 0) ?
-            idealLatency + (extraVsyncs * vsyncInterval) : idealLatency;
-
-    std::lock_guard<std::mutex> lock(mCompositorTimingLock);
-    mCompositorTiming.deadline = vsyncPhase - idealLatency;
-    mCompositorTiming.interval = vsyncInterval;
-    mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
-}
-
-void SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
-{
-    const HWComposer& hwc = getHwComposer();
-    const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
-
-    mGlCompositionDoneTimeline.updateSignalTimes();
-    std::shared_ptr<FenceTime> glCompositionDoneFenceTime;
-    if (getHwComposer().hasGlesComposition(hw->getHwcDisplayId())) {
-        glCompositionDoneFenceTime =
-                std::make_shared<FenceTime>(hw->getClientTargetAcquireFence());
-        mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime);
-    } else {
-        glCompositionDoneFenceTime = FenceTime::NO_FENCE;
-    }
-
-    mDisplayTimeline.updateSignalTimes();
-    sp<Fence> retireFence = mHwc->getDisplayFence(HWC_DISPLAY_PRIMARY);
-    auto retireFenceTime = std::make_shared<FenceTime>(retireFence);
-    mDisplayTimeline.push(retireFenceTime);
-
-    nsecs_t vsyncPhase = mPrimaryDispSync.computeNextRefresh(0);
-    nsecs_t vsyncInterval = mPrimaryDispSync.getPeriod();
-
-    // We use the refreshStartTime which might be sampled a little later than
-    // when we started doing work for this frame, but that should be okay
-    // since updateCompositorTiming has snapping logic.
-    updateCompositorTiming(
-        vsyncPhase, vsyncInterval, refreshStartTime, retireFenceTime);
-    CompositorTiming compositorTiming;
-    {
-        std::lock_guard<std::mutex> lock(mCompositorTimingLock);
-        compositorTiming = mCompositorTiming;
-    }
-
-    mDrawingState.traverseInZOrder([&](Layer* layer) {
-        // TODO(brianderson): The retire fence is incorrectly passed in as the
-        // present fence. Fix this if this file lives on.
-        bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime,
-                retireFenceTime, compositorTiming);
-        if (frameLatched) {
-            recordBufferingStats(layer->getName().string(),
-                    layer->getOccupancyHistory(false));
-        }
-    });
-
-    if (retireFence->isValid()) {
-        if (mPrimaryDispSync.addPresentFence(retireFenceTime)) {
-            enableHardwareVsync();
-        } else {
-            disableHardwareVsync(false);
-        }
-    }
-
-    if (!hasSyncFramework) {
-        if (hw->isDisplayOn()) {
-            enableHardwareVsync();
-        }
-    }
-
-    if (mAnimCompositionPending) {
-        mAnimCompositionPending = false;
-
-        if (retireFenceTime->isValid()) {
-            mAnimFrameTracker.setActualPresentFence(std::move(retireFenceTime));
-        } else {
-            // The HWC doesn't support present fences, so use the refresh
-            // timestamp instead.
-            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
-            mAnimFrameTracker.setActualPresentTime(presentTime);
-        }
-        mAnimFrameTracker.advanceFrame();
-    }
-
-    if (hw->getPowerMode() == HWC_POWER_MODE_OFF) {
-        return;
-    }
-
-    nsecs_t currentTime = systemTime();
-    if (mHasPoweredOff) {
-        mHasPoweredOff = false;
-    } else {
-        nsecs_t period = mPrimaryDispSync.getPeriod();
-        nsecs_t elapsedTime = currentTime - mLastSwapTime;
-        size_t numPeriods = static_cast<size_t>(elapsedTime / period);
-        if (numPeriods < NUM_BUCKETS - 1) {
-            mFrameBuckets[numPeriods] += elapsedTime;
-        } else {
-            mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime;
-        }
-        mTotalTime += elapsedTime;
-    }
-    mLastSwapTime = currentTime;
-}
-
-void SurfaceFlinger::rebuildLayerStacks() {
-    // rebuild the visible layer list per screen
-    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
-        ATRACE_CALL();
-        mVisibleRegionsDirty = false;
-        invalidateHwcGeometry();
-
-        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-            Region opaqueRegion;
-            Region dirtyRegion;
-            Vector< sp<Layer> > layersSortedByZ;
-            const sp<DisplayDevice>& hw(mDisplays[dpy]);
-            const Transform& tr(hw->getTransform());
-            const Rect bounds(hw->getBounds());
-            if (hw->isDisplayOn()) {
-                computeVisibleRegions(hw, dirtyRegion, opaqueRegion);
-
-                mDrawingState.traverseInZOrder([&](Layer* layer) {
-                    if (layer->getLayerStack() == hw->getLayerStack()) {
-                        Region drawRegion(tr.transform(
-                                layer->visibleNonTransparentRegion));
-                        drawRegion.andSelf(bounds);
-                        if (!drawRegion.isEmpty()) {
-                            layersSortedByZ.add(layer);
-                        }
-                    }
-                });
-            }
-            hw->setVisibleLayersSortedByZ(layersSortedByZ);
-            hw->undefinedRegion.set(bounds);
-            hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion));
-            hw->dirtyRegion.orSelf(dirtyRegion);
-        }
-    }
-}
-
-void SurfaceFlinger::setUpHWComposer() {
-    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-        bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
-        bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;
-        bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;
-
-        // If nothing has changed (!dirty), don't recompose.
-        // If something changed, but we don't currently have any visible layers,
-        //   and didn't when we last did a composition, then skip it this time.
-        // The second rule does two things:
-        // - When all layers are removed from a display, we'll emit one black
-        //   frame, then nothing more until we get new layers.
-        // - When a display is created with a private layer stack, we won't
-        //   emit any black frames until a layer is added to the layer stack.
-        bool mustRecompose = dirty && !(empty && wasEmpty);
-
-        ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
-                "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy,
-                mustRecompose ? "doing" : "skipping",
-                dirty ? "+" : "-",
-                empty ? "+" : "-",
-                wasEmpty ? "+" : "-");
-
-        mDisplays[dpy]->beginFrame(mustRecompose);
-
-        if (mustRecompose) {
-            mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;
-        }
-    }
-
-    HWComposer& hwc(getHwComposer());
-    if (hwc.initCheck() == NO_ERROR) {
-        // build the h/w work list
-        if (CC_UNLIKELY(mHwWorkListDirty)) {
-            mHwWorkListDirty = false;
-            for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-                sp<const DisplayDevice> hw(mDisplays[dpy]);
-                const int32_t id = hw->getHwcDisplayId();
-                if (id >= 0) {
-                    const Vector< sp<Layer> >& currentLayers(
-                        hw->getVisibleLayersSortedByZ());
-                    const size_t count = currentLayers.size();
-                    if (hwc.createWorkList(id, count) == NO_ERROR) {
-                        HWComposer::LayerListIterator cur = hwc.begin(id);
-                        const HWComposer::LayerListIterator end = hwc.end(id);
-                        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
-                            const sp<Layer>& layer(currentLayers[i]);
-                            layer->setGeometry(hw, *cur);
-                            if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) {
-                                cur->setSkip(true);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        // set the per-frame data
-        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-            sp<const DisplayDevice> hw(mDisplays[dpy]);
-            const int32_t id = hw->getHwcDisplayId();
-            if (id >= 0) {
-                const Vector< sp<Layer> >& currentLayers(
-                    hw->getVisibleLayersSortedByZ());
-                const size_t count = currentLayers.size();
-                HWComposer::LayerListIterator cur = hwc.begin(id);
-                const HWComposer::LayerListIterator end = hwc.end(id);
-                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
-                    /*
-                     * update the per-frame h/w composer data for each layer
-                     * and build the transparent region of the FB
-                     */
-                    const sp<Layer>& layer(currentLayers[i]);
-                    layer->setPerFrameData(hw, *cur);
-                }
-            }
-        }
-
-        // If possible, attempt to use the cursor overlay on each display.
-        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-            sp<const DisplayDevice> hw(mDisplays[dpy]);
-            const int32_t id = hw->getHwcDisplayId();
-            if (id >= 0) {
-                const Vector< sp<Layer> >& currentLayers(
-                    hw->getVisibleLayersSortedByZ());
-                const size_t count = currentLayers.size();
-                HWComposer::LayerListIterator cur = hwc.begin(id);
-                const HWComposer::LayerListIterator end = hwc.end(id);
-                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
-                    const sp<Layer>& layer(currentLayers[i]);
-                    if (layer->isPotentialCursor()) {
-                        cur->setIsCursorLayerHint();
-                        break;
-                    }
-                }
-            }
-        }
-
-        status_t err = hwc.prepare();
-        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
-
-        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-            sp<const DisplayDevice> hw(mDisplays[dpy]);
-            hw->prepareFrame(hwc);
-        }
-    }
-}
-
-void SurfaceFlinger::doComposition() {
-    ATRACE_CALL();
-    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
-    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-        const sp<DisplayDevice>& hw(mDisplays[dpy]);
-        if (hw->isDisplayOn()) {
-            // transform the dirty region into this screen's coordinate space
-            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
-
-            // repaint the framebuffer (if needed)
-            doDisplayComposition(hw, dirtyRegion);
-
-            hw->dirtyRegion.clear();
-            hw->flip(hw->swapRegion);
-            hw->swapRegion.clear();
-        }
-        // inform the h/w that we're done compositing
-        hw->compositionComplete();
-    }
-    postFramebuffer();
-}
-
-void SurfaceFlinger::postFramebuffer()
-{
-    ATRACE_CALL();
-
-    const nsecs_t now = systemTime();
-    mDebugInSwapBuffers = now;
-
-    HWComposer& hwc(getHwComposer());
-    if (hwc.initCheck() == NO_ERROR) {
-        if (!hwc.supportsFramebufferTarget()) {
-            // EGL spec says:
-            //   "surface must be bound to the calling thread's current context,
-            //    for the current rendering API."
-            getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
-        }
-        hwc.commit();
-    }
-
-    // make the default display current because the VirtualDisplayDevice code cannot
-    // deal with dequeueBuffer() being called outside of the composition loop; however
-    // the code below can call glFlush() which is allowed (and does in some case) call
-    // dequeueBuffer().
-    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
-
-    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-        sp<const DisplayDevice> hw(mDisplays[dpy]);
-        const Vector< sp<Layer> >& currentLayers(hw->getVisibleLayersSortedByZ());
-        hw->onSwapBuffersCompleted(hwc);
-        const size_t count = currentLayers.size();
-        int32_t id = hw->getHwcDisplayId();
-        if (id >=0 && hwc.initCheck() == NO_ERROR) {
-            HWComposer::LayerListIterator cur = hwc.begin(id);
-            const HWComposer::LayerListIterator end = hwc.end(id);
-            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
-                currentLayers[i]->onLayerDisplayed(hw, &*cur);
-            }
-        } else {
-            for (size_t i = 0; i < count; i++) {
-                currentLayers[i]->onLayerDisplayed(hw, NULL);
-            }
-        }
-    }
-
-    mLastSwapBufferTime = systemTime() - now;
-    mDebugInSwapBuffers = 0;
-
-    uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
-    if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
-        logFrameStats();
-    }
-}
-
-void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
-{
-    ATRACE_CALL();
-
-    // here we keep a copy of the drawing state (that is the state that's
-    // going to be overwritten by handleTransactionLocked()) outside of
-    // mStateLock so that the side-effects of the State assignment
-    // don't happen with mStateLock held (which can cause deadlocks).
-    State drawingState(mDrawingState);
-
-    Mutex::Autolock _l(mStateLock);
-    const nsecs_t now = systemTime();
-    mDebugInTransaction = now;
-
-    // Here we're guaranteed that some transaction flags are set
-    // so we can call handleTransactionLocked() unconditionally.
-    // We call getTransactionFlags(), which will also clear the flags,
-    // with mStateLock held to guarantee that mCurrentState won't change
-    // until the transaction is committed.
-
-    transactionFlags = getTransactionFlags(eTransactionMask);
-    handleTransactionLocked(transactionFlags);
-
-    mLastTransactionTime = systemTime() - now;
-    mDebugInTransaction = 0;
-    invalidateHwcGeometry();
-    // here the transaction has been committed
-}
-
-void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
-{
-    // Notify all layers of available frames
-    mCurrentState.traverseInZOrder([](Layer* layer) {
-        layer->notifyAvailableFrames();
-    });
-
-    /*
-     * Traversal of the children
-     * (perform the transaction for each of them if needed)
-     */
-
-    if (transactionFlags & eTraversalNeeded) {
-        mCurrentState.traverseInZOrder([&](Layer* layer) {
-            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
-            if (!trFlags) return;
-
-            const uint32_t flags = layer->doTransaction(0);
-            if (flags & Layer::eVisibleRegion)
-                mVisibleRegionsDirty = true;
-        });
-    }
-
-    /*
-     * Perform display own transactions if needed
-     */
-
-    if (transactionFlags & eDisplayTransactionNeeded) {
-        // here we take advantage of Vector's copy-on-write semantics to
-        // improve performance by skipping the transaction entirely when
-        // know that the lists are identical
-        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
-        const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
-        if (!curr.isIdenticalTo(draw)) {
-            mVisibleRegionsDirty = true;
-            const size_t cc = curr.size();
-                  size_t dc = draw.size();
-
-            // find the displays that were removed
-            // (ie: in drawing state but not in current state)
-            // also handle displays that changed
-            // (ie: displays that are in both lists)
-            for (size_t i=0 ; i<dc ; i++) {
-                const ssize_t j = curr.indexOfKey(draw.keyAt(i));
-                if (j < 0) {
-                    // in drawing state but not in current state
-                    if (!draw[i].isMainDisplay()) {
-                        // Call makeCurrent() on the primary display so we can
-                        // be sure that nothing associated with this display
-                        // is current.
-                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDeviceLocked());
-                        defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
-                        sp<DisplayDevice> hw(getDisplayDeviceLocked(draw.keyAt(i)));
-                        if (hw != NULL)
-                            hw->disconnect(getHwComposer());
-                        if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
-                            mEventThread->onHotplugReceived(draw[i].type, false);
-                        mDisplays.removeItem(draw.keyAt(i));
-                    } else {
-                        ALOGW("trying to remove the main display");
-                    }
-                } else {
-                    // this display is in both lists. see if something changed.
-                    const DisplayDeviceState& state(curr[j]);
-                    const wp<IBinder>& display(curr.keyAt(j));
-                    const sp<IBinder> state_binder = IInterface::asBinder(state.surface);
-                    const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface);
-                    if (state_binder != draw_binder) {
-                        // changing the surface is like destroying and
-                        // recreating the DisplayDevice, so we just remove it
-                        // from the drawing state, so that it get re-added
-                        // below.
-                        sp<DisplayDevice> hw(getDisplayDeviceLocked(display));
-                        if (hw != NULL)
-                            hw->disconnect(getHwComposer());
-                        mDisplays.removeItem(display);
-                        mDrawingState.displays.removeItemsAt(i);
-                        dc--; i--;
-                        // at this point we must loop to the next item
-                        continue;
-                    }
-
-                    const sp<DisplayDevice> disp(getDisplayDeviceLocked(display));
-                    if (disp != NULL) {
-                        if (state.layerStack != draw[i].layerStack) {
-                            disp->setLayerStack(state.layerStack);
-                        }
-                        if ((state.orientation != draw[i].orientation)
-                                || (state.viewport != draw[i].viewport)
-                                || (state.frame != draw[i].frame))
-                        {
-                            disp->setProjection(state.orientation,
-                                    state.viewport, state.frame);
-                        }
-                        if (state.width != draw[i].width || state.height != draw[i].height) {
-                            disp->setDisplaySize(state.width, state.height);
-                        }
-                    }
-                }
-            }
-
-            // find displays that were added
-            // (ie: in current state but not in drawing state)
-            for (size_t i=0 ; i<cc ; i++) {
-                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
-                    const DisplayDeviceState& state(curr[i]);
-
-                    sp<DisplaySurface> dispSurface;
-                    sp<IGraphicBufferProducer> producer;
-                    sp<IGraphicBufferProducer> bqProducer;
-                    sp<IGraphicBufferConsumer> bqConsumer;
-                    BufferQueue::createBufferQueue(&bqProducer, &bqConsumer);
-
-                    int32_t hwcDisplayId = -1;
-                    if (state.isVirtualDisplay()) {
-                        // Virtual displays without a surface are dormant:
-                        // they have external state (layer stack, projection,
-                        // etc.) but no internal state (i.e. a DisplayDevice).
-                        if (state.surface != NULL) {
-
-                            int width = 0;
-                            int status = state.surface->query(
-                                    NATIVE_WINDOW_WIDTH, &width);
-                            ALOGE_IF(status != NO_ERROR,
-                                    "Unable to query width (%d)", status);
-                            int height = 0;
-                            status = state.surface->query(
-                                    NATIVE_WINDOW_HEIGHT, &height);
-                            ALOGE_IF(status != NO_ERROR,
-                                    "Unable to query height (%d)", status);
-                            if (mUseHwcVirtualDisplays &&
-                                    (SurfaceFlinger::maxVirtualDisplaySize == 0 ||
-                                    (width <= static_cast<int>(SurfaceFlinger::maxVirtualDisplaySize) &&
-                                     height <= static_cast<int>(SurfaceFlinger::maxVirtualDisplaySize)))) {
-                                hwcDisplayId = allocateHwcDisplayId(state.type);
-                            }
-
-                            sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(
-                                    *mHwc, hwcDisplayId, state.surface,
-                                    bqProducer, bqConsumer, state.displayName);
-
-                            dispSurface = vds;
-                            producer = vds;
-                        }
-                    } else {
-                        ALOGE_IF(state.surface!=NULL,
-                                "adding a supported display, but rendering "
-                                "surface is provided (%p), ignoring it",
-                                state.surface.get());
-                        hwcDisplayId = allocateHwcDisplayId(state.type);
-                        // for supported (by hwc) displays we provide our
-                        // own rendering surface
-                        dispSurface = new FramebufferSurface(*mHwc, state.type,
-                                bqConsumer);
-                        producer = bqProducer;
-                    }
-
-                    const wp<IBinder>& display(curr.keyAt(i));
-                    if (dispSurface != NULL) {
-                        sp<DisplayDevice> hw = new DisplayDevice(this,
-                                state.type, hwcDisplayId,
-                                mHwc->getFormat(hwcDisplayId), state.isSecure,
-                                display, dispSurface, producer,
-                                mRenderEngine->getEGLConfig(), false);
-                        hw->setLayerStack(state.layerStack);
-                        hw->setProjection(state.orientation,
-                                state.viewport, state.frame);
-                        hw->setDisplayName(state.displayName);
-                        mDisplays.add(display, hw);
-                        if (state.isVirtualDisplay()) {
-                            if (hwcDisplayId >= 0) {
-                                mHwc->setVirtualDisplayProperties(hwcDisplayId,
-                                        hw->getWidth(), hw->getHeight(),
-                                        hw->getFormat());
-                            }
-                        } else {
-                            mEventThread->onHotplugReceived(state.type, true);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
-        // The transform hint might have changed for some layers
-        // (either because a display has changed, or because a layer
-        // as changed).
-        //
-        // Walk through all the layers in currentLayers,
-        // and update their transform hint.
-        //
-        // If a layer is visible only on a single display, then that
-        // display is used to calculate the hint, otherwise we use the
-        // default display.
-        //
-        // NOTE: we do this here, rather than in rebuildLayerStacks() so that
-        // the hint is set before we acquire a buffer from the surface texture.
-        //
-        // NOTE: layer transactions have taken place already, so we use their
-        // drawing state. However, SurfaceFlinger's own transaction has not
-        // happened yet, so we must use the current state layer list
-        // (soon to become the drawing state list).
-        //
-        sp<const DisplayDevice> disp;
-        uint32_t currentlayerStack = 0;
-        bool first = true;
-        mCurrentState.traverseInZOrder([&](Layer* layer) {
-            // NOTE: we rely on the fact that layers are sorted by
-            // layerStack first (so we don't have to traverse the list
-            // of displays for every layer).
-            uint32_t layerStack = layer->getLayerStack();
-            if (first || currentlayerStack != layerStack) {
-                currentlayerStack = layerStack;
-                // figure out if this layerstack is mirrored
-                // (more than one display) if so, pick the default display,
-                // if not, pick the only display it's on.
-                disp.clear();
-                for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-                    sp<const DisplayDevice> hw(mDisplays[dpy]);
-                    if (hw->getLayerStack() == currentlayerStack) {
-                        if (disp == NULL) {
-                            disp = hw;
-                        } else {
-                            disp = NULL;
-                            break;
-                        }
-                    }
-                }
-            }
-            if (disp == NULL) {
-                // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
-                // redraw after transform hint changes. See bug 8508397.
-
-                // could be null when this layer is using a layerStack
-                // that is not visible on any display. Also can occur at
-                // screen off/on times.
-                disp = getDefaultDisplayDeviceLocked();
-            }
-            layer->updateTransformHint(disp);
-
-            first = false;
-        });
-    }
-
-
-    /*
-     * Perform our own transaction if needed
-     */
-
-    if (mLayersAdded) {
-        mLayersAdded = false;
-        // Layers have been added.
-        mVisibleRegionsDirty = true;
-    }
-
-    // some layers might have been removed, so
-    // we need to update the regions they're exposing.
-    if (mLayersRemoved) {
-        mLayersRemoved = false;
-        mVisibleRegionsDirty = true;
-        mDrawingState.traverseInZOrder([&](Layer* layer) {
-            if (mLayersPendingRemoval.indexOf(layer) >= 0) {
-                // this layer is not visible anymore
-                // TODO: we could traverse the tree from front to back and
-                //       compute the actual visible region
-                // TODO: we could cache the transformed region
-                Region visibleReg;
-                visibleReg.set(layer->computeScreenBounds());
-                invalidateLayerStack(layer, visibleReg);
-            }
-        });
-    }
-
-    commitTransaction();
-
-    updateCursorAsync();
-}
-
-void SurfaceFlinger::updateCursorAsync()
-{
-    HWComposer& hwc(getHwComposer());
-    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-        sp<const DisplayDevice> hw(mDisplays[dpy]);
-        const int32_t id = hw->getHwcDisplayId();
-        if (id < 0) {
-            continue;
-        }
-        const Vector< sp<Layer> >& currentLayers(
-            hw->getVisibleLayersSortedByZ());
-        const size_t count = currentLayers.size();
-        HWComposer::LayerListIterator cur = hwc.begin(id);
-        const HWComposer::LayerListIterator end = hwc.end(id);
-        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
-            if (cur->getCompositionType() != HWC_CURSOR_OVERLAY) {
-                continue;
-            }
-            const sp<Layer>& layer(currentLayers[i]);
-            Rect cursorPos = layer->getPosition(hw);
-            hwc.setCursorPositionAsync(id, cursorPos);
-            break;
-        }
-    }
-}
-
-void SurfaceFlinger::commitTransaction()
-{
-    if (!mLayersPendingRemoval.isEmpty()) {
-        // Notify removed layers now that they can't be drawn from
-        for (const auto& l : mLayersPendingRemoval) {
-            recordBufferingStats(l->getName().string(),
-                    l->getOccupancyHistory(true));
-            l->onRemoved();
-        }
-        mLayersPendingRemoval.clear();
-    }
-
-    // If this transaction is part of a window animation then the next frame
-    // we composite should be considered an animation as well.
-    mAnimCompositionPending = mAnimTransactionPending;
-
-    mDrawingState = mCurrentState;
-    mDrawingState.traverseInZOrder([](Layer* layer) {
-        layer->commitChildList();
-    });
-    mTransactionPending = false;
-    mAnimTransactionPending = false;
-    mTransactionCV.broadcast();
-}
-
-void SurfaceFlinger::computeVisibleRegions(const sp<const DisplayDevice>& displayDevice,
-        Region& outDirtyRegion, Region& outOpaqueRegion)
-{
-    ATRACE_CALL();
-
-    Region aboveOpaqueLayers;
-    Region aboveCoveredLayers;
-    Region dirty;
-
-    outDirtyRegion.clear();
-
-    mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
-        // start with the whole surface at its current location
-        const Layer::State& s(layer->getDrawingState());
-
-        // only consider the layers on the given layer stack
-        if (layer->getLayerStack() != displayDevice->getLayerStack())
-            return;
-
-        /*
-         * opaqueRegion: area of a surface that is fully opaque.
-         */
-        Region opaqueRegion;
-
-        /*
-         * visibleRegion: area of a surface that is visible on screen
-         * and not fully transparent. This is essentially the layer's
-         * footprint minus the opaque regions above it.
-         * Areas covered by a translucent surface are considered visible.
-         */
-        Region visibleRegion;
-
-        /*
-         * coveredRegion: area of a surface that is covered by all
-         * visible regions above it (which includes the translucent areas).
-         */
-        Region coveredRegion;
-
-        /*
-         * transparentRegion: area of a surface that is hinted to be completely
-         * transparent. This is only used to tell when the layer has no visible
-         * non-transparent regions and can be removed from the layer list. It
-         * does not affect the visibleRegion of this layer or any layers
-         * beneath it. The hint may not be correct if apps don't respect the
-         * SurfaceView restrictions (which, sadly, some don't).
-         */
-        Region transparentRegion;
-
-
-        // handle hidden surfaces by setting the visible region to empty
-        if (CC_LIKELY(layer->isVisible())) {
-            const bool translucent = !layer->isOpaque(s);
-            Rect bounds(layer->computeScreenBounds());
-            visibleRegion.set(bounds);
-            Transform tr = layer->getTransform();
-            if (!visibleRegion.isEmpty()) {
-                // Remove the transparent area from the visible region
-                if (translucent) {
-                    if (tr.preserveRects()) {
-                        // transform the transparent region
-                        transparentRegion = tr.transform(s.activeTransparentRegion);
-                    } else {
-                        // transformation too complex, can't do the
-                        // transparent region optimization.
-                        transparentRegion.clear();
-                    }
-                }
-
-                // compute the opaque region
-                const int32_t layerOrientation = tr.getOrientation();
-                if (layer->getAlpha()==1.0f && !translucent &&
-                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
-                    // the opaque region is the layer's footprint
-                    opaqueRegion = visibleRegion;
-                }
-            }
-        }
-
-        // Clip the covered region to the visible region
-        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
-
-        // Update aboveCoveredLayers for next (lower) layer
-        aboveCoveredLayers.orSelf(visibleRegion);
-
-        // subtract the opaque region covered by the layers above us
-        visibleRegion.subtractSelf(aboveOpaqueLayers);
-
-        // compute this layer's dirty region
-        if (layer->contentDirty) {
-            // we need to invalidate the whole region
-            dirty = visibleRegion;
-            // as well, as the old visible region
-            dirty.orSelf(layer->visibleRegion);
-            layer->contentDirty = false;
-        } else {
-            /* compute the exposed region:
-             *   the exposed region consists of two components:
-             *   1) what's VISIBLE now and was COVERED before
-             *   2) what's EXPOSED now less what was EXPOSED before
-             *
-             * note that (1) is conservative, we start with the whole
-             * visible region but only keep what used to be covered by
-             * something -- which mean it may have been exposed.
-             *
-             * (2) handles areas that were not covered by anything but got
-             * exposed because of a resize.
-             */
-            const Region newExposed = visibleRegion - coveredRegion;
-            const Region oldVisibleRegion = layer->visibleRegion;
-            const Region oldCoveredRegion = layer->coveredRegion;
-            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
-            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
-        }
-        dirty.subtractSelf(aboveOpaqueLayers);
-
-        // accumulate to the screen dirty region
-        outDirtyRegion.orSelf(dirty);
-
-        // Update aboveOpaqueLayers for next (lower) layer
-        aboveOpaqueLayers.orSelf(opaqueRegion);
-
-        // Store the visible region in screen space
-        layer->setVisibleRegion(visibleRegion);
-        layer->setCoveredRegion(coveredRegion);
-        layer->setVisibleNonTransparentRegion(
-                visibleRegion.subtract(transparentRegion));
-    });
-
-    outOpaqueRegion = aboveOpaqueLayers;
-}
-
-void SurfaceFlinger::invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty) {
-    uint32_t layerStack = layer->getLayerStack();
-    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-        const sp<DisplayDevice>& hw(mDisplays[dpy]);
-        if (hw->getLayerStack() == layerStack) {
-            hw->dirtyRegion.orSelf(dirty);
-        }
-    }
-}
-
-bool SurfaceFlinger::handlePageFlip()
-{
-    nsecs_t latchTime = systemTime();
-    Region dirtyRegion;
-
-    bool visibleRegions = false;
-    bool frameQueued = false;
-
-    // Store the set of layers that need updates. This set must not change as
-    // buffers are being latched, as this could result in a deadlock.
-    // Example: Two producers share the same command stream and:
-    // 1.) Layer 0 is latched
-    // 2.) Layer 0 gets a new frame
-    // 2.) Layer 1 gets a new frame
-    // 3.) Layer 1 is latched.
-    // Display is now waiting on Layer 1's frame, which is behind layer 0's
-    // second frame. But layer 0's second frame could be waiting on display.
-    Vector<Layer*> layersWithQueuedFrames;
-    mDrawingState.traverseInZOrder([&](Layer* layer) {
-        if (layer->hasQueuedFrame()) {
-            frameQueued = true;
-            if (layer->shouldPresentNow(mPrimaryDispSync)) {
-                layersWithQueuedFrames.push_back(layer);
-            } else {
-                layer->useEmptyDamage();
-            }
-        } else {
-            layer->useEmptyDamage();
-        }
-    });
-    for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
-        Layer* layer = layersWithQueuedFrames[i];
-        const Region dirty(layer->latchBuffer(visibleRegions, latchTime));
-        layer->useSurfaceDamage();
-        invalidateLayerStack(layer, dirty);
-    }
-
-    mVisibleRegionsDirty |= visibleRegions;
-
-    // If we will need to wake up at some time in the future to deal with a
-    // queued frame that shouldn't be displayed during this vsync period, wake
-    // up during the next vsync period to check again.
-    if (frameQueued && layersWithQueuedFrames.empty()) {
-        signalLayerUpdate();
-    }
-
-    // Only continue with the refresh if there is actually new work to do
-    return !layersWithQueuedFrames.empty();
-}
-
-void SurfaceFlinger::invalidateHwcGeometry()
-{
-    mHwWorkListDirty = true;
-}
-
-
-void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
-        const Region& inDirtyRegion)
-{
-    // We only need to actually compose the display if:
-    // 1) It is being handled by hardware composer, which may need this to
-    //    keep its virtual display state machine in sync, or
-    // 2) There is work to be done (the dirty region isn't empty)
-    bool isHwcDisplay = hw->getHwcDisplayId() >= 0;
-    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
-        return;
-    }
-
-    Region dirtyRegion(inDirtyRegion);
-
-    // compute the invalid region
-    hw->swapRegion.orSelf(dirtyRegion);
-
-    uint32_t flags = hw->getFlags();
-    if (flags & DisplayDevice::SWAP_RECTANGLE) {
-        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
-        // takes a rectangle, we must make sure to update that whole
-        // rectangle in that case
-        dirtyRegion.set(hw->swapRegion.bounds());
-    } else {
-        if (flags & DisplayDevice::PARTIAL_UPDATES) {
-            // We need to redraw the rectangle that will be updated
-            // (pushed to the framebuffer).
-            // This is needed because PARTIAL_UPDATES only takes one
-            // rectangle instead of a region (see DisplayDevice::flip())
-            dirtyRegion.set(hw->swapRegion.bounds());
-        } else {
-            // we need to redraw everything (the whole screen)
-            dirtyRegion.set(hw->bounds());
-            hw->swapRegion = dirtyRegion;
-        }
-    }
-
-    if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) {
-        if (!doComposeSurfaces(hw, dirtyRegion)) return;
-    } else {
-        RenderEngine& engine(getRenderEngine());
-        mat4 colorMatrix = mColorMatrix;
-        if (mDaltonize) {
-            colorMatrix = colorMatrix * mDaltonizer();
-        }
-        mat4 oldMatrix = engine.setupColorTransform(colorMatrix);
-        doComposeSurfaces(hw, dirtyRegion);
-        engine.setupColorTransform(oldMatrix);
-    }
-
-    // update the swap region and clear the dirty region
-    hw->swapRegion.orSelf(dirtyRegion);
-
-    // swap buffers (presentation)
-    hw->swapBuffers(getHwComposer());
-}
-
-bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
-{
-    DisplayRenderArea renderArea(hw);
-
-    RenderEngine& engine(getRenderEngine());
-    const int32_t id = hw->getHwcDisplayId();
-    HWComposer& hwc(getHwComposer());
-    HWComposer::LayerListIterator cur = hwc.begin(id);
-    const HWComposer::LayerListIterator end = hwc.end(id);
-
-    bool hasGlesComposition = hwc.hasGlesComposition(id);
-    if (hasGlesComposition) {
-        if (!hw->makeCurrent(mEGLDisplay, mEGLContext)) {
-            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
-                  hw->getDisplayName().string());
-            eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-            if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) {
-              ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
-            }
-            return false;
-        }
-
-        // Never touch the framebuffer if we don't have any framebuffer layers
-        const bool hasHwcComposition = hwc.hasHwcComposition(id);
-        if (hasHwcComposition) {
-            // when using overlays, we assume a fully transparent framebuffer
-            // NOTE: we could reduce how much we need to clear, for instance
-            // remove where there are opaque FB layers. however, on some
-            // GPUs doing a "clean slate" clear might be more efficient.
-            // We'll revisit later if needed.
-            engine.clearWithColor(0, 0, 0, 0);
-        } else {
-            // we start with the whole screen area
-            const Region bounds(hw->getBounds());
-
-            // we remove the scissor part
-            // we're left with the letterbox region
-            // (common case is that letterbox ends-up being empty)
-            const Region letterbox(bounds.subtract(hw->getScissor()));
-
-            // compute the area to clear
-            Region region(hw->undefinedRegion.merge(letterbox));
-
-            // but limit it to the dirty region
-            region.andSelf(dirty);
-
-            // screen is already cleared here
-            if (!region.isEmpty()) {
-                // can happen with SurfaceView
-                drawWormhole(hw, region);
-            }
-        }
-
-        if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
-            // just to be on the safe side, we don't set the
-            // scissor on the main display. It should never be needed
-            // anyways (though in theory it could since the API allows it).
-            const Rect& bounds(hw->getBounds());
-            const Rect& scissor(hw->getScissor());
-            if (scissor != bounds) {
-                // scissor doesn't match the screen's dimensions, so we
-                // need to clear everything outside of it and enable
-                // the GL scissor so we don't draw anything where we shouldn't
-
-                // enable scissor for this frame
-                const uint32_t height = hw->getHeight();
-                engine.setScissor(scissor.left, height - scissor.bottom,
-                        scissor.getWidth(), scissor.getHeight());
-            }
-        }
-    }
-
-    /*
-     * and then, render the layers targeted at the framebuffer
-     */
-
-    const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ());
-    const size_t count = layers.size();
-    const Transform& tr = hw->getTransform();
-    if (cur != end) {
-        // we're using h/w composer
-        for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
-            const sp<Layer>& layer(layers[i]);
-            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
-            if (!clip.isEmpty()) {
-                switch (cur->getCompositionType()) {
-                    case HWC_CURSOR_OVERLAY:
-                    case HWC_OVERLAY: {
-                        const Layer::State& state(layer->getDrawingState());
-                        if ((cur->getHints() & HWC_HINT_CLEAR_FB)
-                                && i
-                                && layer->isOpaque(state) && (state.color.a == 1.0f)
-                                && hasGlesComposition) {
-                            // never clear the very first layer since we're
-                            // guaranteed the FB is already cleared
-                            layer->clearWithOpenGL(renderArea);
-                        }
-                        break;
-                    }
-                    case HWC_FRAMEBUFFER: {
-                        layer->draw(renderArea, clip);
-                        break;
-                    }
-                    case HWC_FRAMEBUFFER_TARGET: {
-                        // this should not happen as the iterator shouldn't
-                        // let us get there.
-                        ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%zu)", i);
-                        break;
-                    }
-                }
-            }
-            layer->setAcquireFence(hw, *cur);
-        }
-    } else {
-        // we're not using h/w composer
-        for (size_t i=0 ; i<count ; ++i) {
-            const sp<Layer>& layer(layers[i]);
-            const Region clip(dirty.intersect(
-                    tr.transform(layer->visibleRegion)));
-            if (!clip.isEmpty()) {
-                layer->draw(renderArea, clip);
-            }
-        }
-    }
-
-    // disable scissor at the end of the frame
-    engine.disableScissor();
-    return true;
-}
-
-void SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const {
-    const int32_t height = hw->getHeight();
-    RenderEngine& engine(getRenderEngine());
-    engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
-}
-
-status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
-        const sp<IBinder>& handle,
-        const sp<IGraphicBufferProducer>& gbc,
-        const sp<Layer>& lbc,
-        const sp<Layer>& parent)
-{
-    // add this layer to the current state list
-    {
-        Mutex::Autolock _l(mStateLock);
-        if (mNumLayers >= MAX_LAYERS) {
-            return NO_MEMORY;
-        }
-        if (parent == nullptr) {
-            mCurrentState.layersSortedByZ.add(lbc);
-        } else {
-            if (mCurrentState.layersSortedByZ.indexOf(parent) < 0) {
-                ALOGE("addClientLayer called with a removed parent");
-                return NAME_NOT_FOUND;
-            }
-            parent->addChild(lbc);
-        }
-
-        mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
-        mLayersAdded = true;
-        mNumLayers++;
-    }
-
-    // attach this layer to the client
-    client->attachLayer(handle, lbc);
-
-    return NO_ERROR;
-}
-
-status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer, bool topLevelOnly) {
-    Mutex::Autolock _l(mStateLock);
-
-    const auto& p = layer->getParent();
-    ssize_t index;
-    if (p != nullptr) {
-        if (topLevelOnly) {
-            return NO_ERROR;
-        }
-
-        sp<Layer> ancestor = p;
-        while (ancestor->getParent() != nullptr) {
-            ancestor = ancestor->getParent();
-        }
-        if (mCurrentState.layersSortedByZ.indexOf(ancestor) < 0) {
-            ALOGE("removeLayer called with a layer whose parent has been removed");
-            return NAME_NOT_FOUND;
-        }
-
-        index = p->removeChild(layer);
-    } else {
-        index = mCurrentState.layersSortedByZ.remove(layer);
-    }
-
-    // As a matter of normal operation, the LayerCleaner will produce a second
-    // attempt to remove the surface. The Layer will be kept alive in mDrawingState
-    // so we will succeed in promoting it, but it's already been removed
-    // from mCurrentState. As long as we can find it in mDrawingState we have no problem
-    // otherwise something has gone wrong and we are leaking the layer.
-    if (index < 0 && mDrawingState.layersSortedByZ.indexOf(layer) < 0) {
-        ALOGE("Failed to find layer (%s) in layer parent (%s).",
-                layer->getName().string(),
-                (p != nullptr) ? p->getName().string() : "no-parent");
-        return BAD_VALUE;
-    } else if (index < 0) {
-        return NO_ERROR;
-    }
-
-    layer->onRemovedFromCurrentState();
-    mLayersPendingRemoval.add(layer);
-    mLayersRemoved = true;
-    mNumLayers -= 1 + layer->getChildrenCount();
-    setTransactionFlags(eTransactionNeeded);
-    return NO_ERROR;
-}
-
-uint32_t SurfaceFlinger::peekTransactionFlags() {
-    return android_atomic_release_load(&mTransactionFlags);
-}
-
-uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
-    return android_atomic_and(~flags, &mTransactionFlags) & flags;
-}
-
-uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
-    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
-    if ((old & flags)==0) { // wake the server up
-        signalTransaction();
-    }
-    return old;
-}
-
-void SurfaceFlinger::setTransactionState(
-        const Vector<ComposerState>& state,
-        const Vector<DisplayState>& displays,
-        uint32_t flags)
-{
-    ATRACE_CALL();
-    Mutex::Autolock _l(mStateLock);
-    uint32_t transactionFlags = 0;
-
-    if (flags & eAnimation) {
-        // For window updates that are part of an animation we must wait for
-        // previous animation "frames" to be handled.
-        while (mAnimTransactionPending) {
-            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
-            if (CC_UNLIKELY(err != NO_ERROR)) {
-                // just in case something goes wrong in SF, return to the
-                // caller after a few seconds.
-                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
-                        "waiting for previous animation frame");
-                mAnimTransactionPending = false;
-                break;
-            }
-        }
-    }
-
-    size_t count = displays.size();
-    for (size_t i=0 ; i<count ; i++) {
-        const DisplayState& s(displays[i]);
-        transactionFlags |= setDisplayStateLocked(s);
-    }
-
-    count = state.size();
-    for (size_t i=0 ; i<count ; i++) {
-        const ComposerState& s(state[i]);
-        // Here we need to check that the interface we're given is indeed
-        // one of our own. A malicious client could give us a NULL
-        // IInterface, or one of its own or even one of our own but a
-        // different type. All these situations would cause us to crash.
-        //
-        // NOTE: it would be better to use RTTI as we could directly check
-        // that we have a Client*. however, RTTI is disabled in Android.
-        if (s.client != NULL) {
-            sp<IBinder> binder = IInterface::asBinder(s.client);
-            if (binder != NULL) {
-                if (binder->queryLocalInterface(ISurfaceComposerClient::descriptor) != NULL) {
-                    sp<Client> client( static_cast<Client *>(s.client.get()) );
-                    transactionFlags |= setClientStateLocked(client, s.state);
-                }
-            }
-        }
-    }
-
-    // If a synchronous transaction is explicitly requested without any changes,
-    // force a transaction anyway. This can be used as a flush mechanism for
-    // previous async transactions.
-    if (transactionFlags == 0 && (flags & eSynchronous)) {
-        transactionFlags = eTransactionNeeded;
-    }
-
-    if (transactionFlags) {
-        if (mInterceptor.isEnabled()) {
-            mInterceptor.saveTransaction(state, mCurrentState.displays, displays, flags);
-        }
-
-        // this triggers the transaction
-        setTransactionFlags(transactionFlags);
-
-        // if this is a synchronous transaction, wait for it to take effect
-        // before returning.
-        if (flags & eSynchronous) {
-            mTransactionPending = true;
-        }
-        if (flags & eAnimation) {
-            mAnimTransactionPending = true;
-        }
-        while (mTransactionPending) {
-            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
-            if (CC_UNLIKELY(err != NO_ERROR)) {
-                // just in case something goes wrong in SF, return to the
-                // called after a few seconds.
-                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
-                mTransactionPending = false;
-                break;
-            }
-        }
-    }
-}
-
-uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
-{
-    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
-    if (dpyIdx < 0)
-        return 0;
-
-    uint32_t flags = 0;
-    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
-    if (disp.isValid()) {
-        const uint32_t what = s.what;
-        if (what & DisplayState::eSurfaceChanged) {
-            if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) {
-                disp.surface = s.surface;
-                flags |= eDisplayTransactionNeeded;
-            }
-        }
-        if (what & DisplayState::eLayerStackChanged) {
-            if (disp.layerStack != s.layerStack) {
-                disp.layerStack = s.layerStack;
-                flags |= eDisplayTransactionNeeded;
-            }
-        }
-        if (what & DisplayState::eDisplayProjectionChanged) {
-            if (disp.orientation != s.orientation) {
-                disp.orientation = s.orientation;
-                flags |= eDisplayTransactionNeeded;
-            }
-            if (disp.frame != s.frame) {
-                disp.frame = s.frame;
-                flags |= eDisplayTransactionNeeded;
-            }
-            if (disp.viewport != s.viewport) {
-                disp.viewport = s.viewport;
-                flags |= eDisplayTransactionNeeded;
-            }
-        }
-        if (what & DisplayState::eDisplaySizeChanged) {
-            if (disp.width != s.width) {
-                disp.width = s.width;
-                flags |= eDisplayTransactionNeeded;
-            }
-            if (disp.height != s.height) {
-                disp.height = s.height;
-                flags |= eDisplayTransactionNeeded;
-            }
-        }
-    }
-    return flags;
-}
-
-uint32_t SurfaceFlinger::setClientStateLocked(
-        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 (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) {
-            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");
-                }
-            }
-            // 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::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;
-}
-
-status_t SurfaceFlinger::createLayer(
-        const String8& name,
-        const sp<Client>& client,
-        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
-        uint32_t windowType, uint32_t ownerUid, sp<IBinder>* handle,
-        sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent)
-{
-    if (int32_t(w|h) < 0) {
-        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
-                int(w), int(h));
-        return BAD_VALUE;
-    }
-
-    status_t result = NO_ERROR;
-
-    sp<Layer> layer;
-
-    String8 uniqueName = getUniqueLayerName(name);
-
-    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
-        case ISurfaceComposerClient::eFXSurfaceNormal:
-            result = createBufferLayer(client,
-                    uniqueName, w, h, flags, format,
-                    handle, gbp, &layer);
-            break;
-        case ISurfaceComposerClient::eFXSurfaceColor:
-            result = createColorLayer(client,
-                    uniqueName, w, h, flags,
-                    handle, &layer);
-            break;
-        default:
-            result = BAD_VALUE;
-            break;
-    }
-
-    if (result != NO_ERROR) {
-        return result;
-    }
-
-    layer->setInfo(windowType, ownerUid);
-
-    result = addClientLayer(client, *handle, *gbp, layer, *parent);
-    if (result != NO_ERROR) {
-        return result;
-    }
-    mInterceptor.saveSurfaceCreation(layer);
-
-    setTransactionFlags(eTransactionNeeded);
-    return result;
-}
-
-String8 SurfaceFlinger::getUniqueLayerName(const String8& name)
-{
-    bool matchFound = true;
-    uint32_t dupeCounter = 0;
-
-    // Tack on our counter whether there is a hit or not, so everyone gets a tag
-    String8 uniqueName = name + "#" + String8(std::to_string(dupeCounter).c_str());
-
-    // Loop over layers until we're sure there is no matching name
-    while (matchFound) {
-        matchFound = false;
-        mDrawingState.traverseInZOrder([&](Layer* layer) {
-            if (layer->getName() == uniqueName) {
-                matchFound = true;
-                uniqueName = name + "#" + String8(std::to_string(++dupeCounter).c_str());
-            }
-        });
-    }
-
-    ALOGD_IF(dupeCounter > 0, "duplicate layer name: changing %s to %s", name.c_str(), uniqueName.c_str());
-
-    return uniqueName;
-}
-
-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)
-{
-    // initialize the surfaces
-    switch (format) {
-    case PIXEL_FORMAT_TRANSPARENT:
-    case PIXEL_FORMAT_TRANSLUCENT:
-        format = PIXEL_FORMAT_RGBA_8888;
-        break;
-    case PIXEL_FORMAT_OPAQUE:
-        format = PIXEL_FORMAT_RGBX_8888;
-        break;
-    }
-
-    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 = layer->getHandle();
-        *gbp = layer->getProducer();
-        *outLayer = layer;
-    }
-
-    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<Layer>* outLayer)
-{
-    *outLayer = new ColorLayer(this, client, name, w, h, flags);
-    *handle = (*outLayer)->getHandle();
-    return NO_ERROR;
-}
-
-status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
-{
-    // called by a client when it wants to remove a Layer
-    status_t err = NO_ERROR;
-    sp<Layer> l(client->getLayerUser(handle));
-    if (l != NULL) {
-        mInterceptor.saveSurfaceDeletion(l);
-        err = removeLayer(l);
-        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
-                "error removing layer=%p (%s)", l.get(), strerror(-err));
-    }
-    return err;
-}
-
-status_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
-{
-    // called by ~LayerCleaner() when all references to the IBinder (handle)
-    // are gone
-    sp<Layer> l = layer.promote();
-    if (l == nullptr) {
-        // The layer has already been removed, carry on
-        return NO_ERROR;
-    }
-    // If we have a parent, then we can continue to live as long as it does.
-    return removeLayer(l, true);
-}
-
-// ---------------------------------------------------------------------------
-
-void SurfaceFlinger::onInitializeDisplays() {
-    // reset screen orientation and use primary layer stack
-    Vector<ComposerState> state;
-    Vector<DisplayState> displays;
-    DisplayState d;
-    d.what = DisplayState::eDisplayProjectionChanged |
-             DisplayState::eLayerStackChanged;
-    d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
-    d.layerStack = 0;
-    d.orientation = DisplayState::eOrientationDefault;
-    d.frame.makeInvalid();
-    d.viewport.makeInvalid();
-    d.width = 0;
-    d.height = 0;
-    displays.add(d);
-    setTransactionState(state, displays, 0);
-    setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
-
-    const nsecs_t period =
-            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
-    mAnimFrameTracker.setDisplayRefreshPeriod(period);
-
-    // Use phase of 0 since phase is not known.
-    // Use latency of 0, which will snap to the ideal latency.
-    setCompositorTimingSnapped(0, period, 0);
-}
-
-void SurfaceFlinger::initializeDisplays() {
-    class MessageScreenInitialized : public MessageBase {
-        SurfaceFlinger* flinger;
-    public:
-        explicit MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
-        virtual bool handler() {
-            flinger->onInitializeDisplays();
-            return true;
-        }
-    };
-    sp<MessageBase> msg = new MessageScreenInitialized(this);
-    postMessageAsync(msg);  // we may be called from main thread, use async message
-}
-
-void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
-        int mode) {
-    ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
-            this);
-    int32_t type = hw->getDisplayType();
-    int currentMode = hw->getPowerMode();
-
-    if (mode == currentMode) {
-        ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
-        return;
-    }
-
-    hw->setPowerMode(mode);
-    if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
-        ALOGW("Trying to set power mode for virtual display");
-        return;
-    }
-
-    if (mInterceptor.isEnabled()) {
-        Mutex::Autolock _l(mStateLock);
-        ssize_t idx = mCurrentState.displays.indexOfKey(hw->getDisplayToken());
-        if (idx < 0) {
-            ALOGW("Surface Interceptor SavePowerMode: invalid display token");
-            return;
-        }
-        mInterceptor.savePowerModeUpdate(mCurrentState.displays.valueAt(idx).displayId, mode);
-    }
-
-    if (currentMode == HWC_POWER_MODE_OFF) {
-        // Turn on the display
-        getHwComposer().setPowerMode(type, mode);
-        if (type == DisplayDevice::DISPLAY_PRIMARY &&
-            mode != HWC_POWER_MODE_DOZE_SUSPEND) {
-            // FIXME: eventthread only knows about the main display right now
-            mEventThread->onScreenAcquired();
-            resyncToHardwareVsync(true);
-        }
-
-        mVisibleRegionsDirty = true;
-        mHasPoweredOff = true;
-        repaintEverything();
-
-        struct sched_param param = {0};
-        param.sched_priority = 1;
-        if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
-            ALOGW("Couldn't set SCHED_FIFO on display on");
-        }
-    } else if (mode == HWC_POWER_MODE_OFF) {
-        // Turn off the display
-        struct sched_param param = {0};
-        if (sched_setscheduler(0, SCHED_OTHER, &param) != 0) {
-            ALOGW("Couldn't set SCHED_OTHER on display off");
-        }
-
-        if (type == DisplayDevice::DISPLAY_PRIMARY &&
-            currentMode != HWC_POWER_MODE_DOZE_SUSPEND) {
-            disableHardwareVsync(true); // also cancels any in-progress resync
-
-            // FIXME: eventthread only knows about the main display right now
-            mEventThread->onScreenReleased();
-        }
-
-        getHwComposer().setPowerMode(type, mode);
-        mVisibleRegionsDirty = true;
-        // from this point on, SF will stop drawing on this display
-    } else if (mode == HWC_POWER_MODE_DOZE ||
-               mode == HWC_POWER_MODE_NORMAL) {
-        // Update display while dozing
-        getHwComposer().setPowerMode(type, mode);
-        if (type == DisplayDevice::DISPLAY_PRIMARY &&
-            currentMode == HWC_POWER_MODE_DOZE_SUSPEND) {
-            // FIXME: eventthread only knows about the main display right now
-            mEventThread->onScreenAcquired();
-            resyncToHardwareVsync(true);
-        }
-    } else if (mode == HWC_POWER_MODE_DOZE_SUSPEND) {
-        // Leave display going to doze
-        if (type == DisplayDevice::DISPLAY_PRIMARY) {
-            disableHardwareVsync(true); // also cancels any in-progress resync
-            // FIXME: eventthread only knows about the main display right now
-            mEventThread->onScreenReleased();
-        }
-        getHwComposer().setPowerMode(type, mode);
-    } else {
-        ALOGE("Attempting to set unknown power mode: %d\n", mode);
-        getHwComposer().setPowerMode(type, mode);
-    }
-}
-
-void SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
-    class MessageSetPowerMode: public MessageBase {
-        SurfaceFlinger& mFlinger;
-        sp<IBinder> mDisplay;
-        int mMode;
-    public:
-        MessageSetPowerMode(SurfaceFlinger& flinger,
-                const sp<IBinder>& disp, int mode) : mFlinger(flinger),
-                    mDisplay(disp) { mMode = mode; }
-        virtual bool handler() {
-            sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
-            if (hw == NULL) {
-                ALOGE("Attempt to set power mode = %d for null display %p",
-                        mMode, mDisplay.get());
-            } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
-                ALOGW("Attempt to set power mode = %d for virtual display",
-                        mMode);
-            } else {
-                mFlinger.setPowerModeInternal(hw, mMode);
-            }
-            return true;
-        }
-    };
-    sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode);
-    postMessageSync(msg);
-}
-
-// ---------------------------------------------------------------------------
-
-status_t SurfaceFlinger::doDump(int fd, const Vector<String16>& args, bool asProto) {
-    String8 result;
-
-    IPCThreadState* ipc = IPCThreadState::self();
-    const int pid = ipc->getCallingPid();
-    const int uid = ipc->getCallingUid();
-
-    if (asProto) {
-        // Return early as SurfaceFlinger does not support dumping sections in proto format
-        return OK;
-    }
-
-    if ((uid != AID_SHELL) &&
-            !PermissionCache::checkPermission(sDump, pid, uid)) {
-        result.appendFormat("Permission Denial: "
-                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
-    } else {
-        // Try to get the main lock, but give up after one second
-        // (this would indicate SF is stuck, but we want to be able to
-        // print something in dumpsys).
-        status_t err = mStateLock.timedLock(s2ns(1));
-        bool locked = (err == NO_ERROR);
-        if (!locked) {
-            result.appendFormat(
-                    "SurfaceFlinger appears to be unresponsive (%s [%d]), "
-                    "dumping anyways (no locks held)\n", strerror(-err), err);
-        }
-
-        bool dumpAll = true;
-        size_t index = 0;
-        size_t numArgs = args.size();
-        if (numArgs) {
-            if ((index < numArgs) &&
-                    (args[index] == String16("--list"))) {
-                index++;
-                listLayersLocked(args, index, result);
-                dumpAll = false;
-            }
-
-            if ((index < numArgs) &&
-                    (args[index] == String16("--latency"))) {
-                index++;
-                dumpStatsLocked(args, index, result);
-                dumpAll = false;
-            }
-
-            if ((index < numArgs) &&
-                    (args[index] == String16("--latency-clear"))) {
-                index++;
-                clearStatsLocked(args, index, result);
-                dumpAll = false;
-            }
-
-            if ((index < numArgs) &&
-                    (args[index] == String16("--dispsync"))) {
-                index++;
-                mPrimaryDispSync.dump(result);
-                dumpAll = false;
-            }
-
-            if ((index < numArgs) &&
-                    (args[index] == String16("--static-screen"))) {
-                index++;
-                dumpStaticScreenStats(result);
-                dumpAll = false;
-            }
-
-            if ((index < numArgs) &&
-                    (args[index] == String16("--frame-events"))) {
-                index++;
-                dumpFrameEventsLocked(result);
-                dumpAll = false;
-            }
-
-            if ((index < numArgs) && (args[index] == String16("--proto"))) {
-                index++;
-                LayersProto layersProto = dumpProtoInfo();
-                result.append(layersProto.SerializeAsString().c_str(), layersProto.ByteSize());
-                dumpAll = false;
-            }
-        }
-
-        if (dumpAll) {
-            dumpAllLocked(args, index, result);
-        }
-
-        if (locked) {
-            mStateLock.unlock();
-        }
-    }
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-void SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
-        size_t& /* index */, String8& result) const
-{
-    mCurrentState.traverseInZOrder([&](Layer* layer) {
-        result.appendFormat("%s\n", layer->getName().string());
-    });
-}
-
-void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
-        String8& result) const
-{
-    String8 name;
-    if (index < args.size()) {
-        name = String8(args[index]);
-        index++;
-    }
-
-    const nsecs_t period =
-            getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
-    result.appendFormat("%" PRId64 "\n", period);
-
-    if (name.isEmpty()) {
-        mAnimFrameTracker.dumpStats(result);
-    } else {
-        mCurrentState.traverseInZOrder([&](Layer* layer) {
-            if (name == layer->getName()) {
-                layer->dumpFrameStats(result);
-            }
-        });
-    }
-}
-
-void SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
-        String8& /* result */)
-{
-    String8 name;
-    if (index < args.size()) {
-        name = String8(args[index]);
-        index++;
-    }
-
-    mCurrentState.traverseInZOrder([&](Layer* layer) {
-        if (name.isEmpty() || (name == layer->getName())) {
-            layer->clearFrameStats();
-        }
-    });
-
-    mAnimFrameTracker.clearStats();
-}
-
-// This should only be called from the main thread.  Otherwise it would need
-// the lock and should use mCurrentState rather than mDrawingState.
-void SurfaceFlinger::logFrameStats() {
-    mDrawingState.traverseInZOrder([&](Layer* layer) {
-        layer->logFrameStats();
-    });
-
-    mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
-}
-
-void SurfaceFlinger::appendSfConfigString(String8& result) const
-{
-    result.append(" [sf");
-    result.appendFormat(" HAS_CONTEXT_PRIORITY=%d", useContextPriority);
-
-    if (isLayerTripleBufferingDisabled())
-        result.append(" DISABLE_TRIPLE_BUFFERING");
-
-    result.appendFormat(" PRESENT_TIME_OFFSET=%" PRId64, dispSyncPresentTimeOffset);
-    result.appendFormat(" FORCE_HWC_FOR_RBG_TO_YUV=%d", useHwcForRgbToYuv);
-    result.appendFormat(" MAX_VIRT_DISPLAY_DIM=%" PRIu64, maxVirtualDisplaySize);
-    result.appendFormat(" RUNNING_WITHOUT_SYNC_FRAMEWORK=%d", !hasSyncFramework);
-    result.appendFormat(" NUM_FRAMEBUFFER_SURFACE_BUFFERS=%" PRId64,
-                        maxFrameBufferAcquiredBuffers);
-    result.append("]");
-}
-
-void SurfaceFlinger::dumpStaticScreenStats(String8& result) const
-{
-    result.appendFormat("Static screen stats:\n");
-    for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) {
-        float bucketTimeSec = mFrameBuckets[b] / 1e9;
-        float percent = 100.0f *
-                static_cast<float>(mFrameBuckets[b]) / mTotalTime;
-        result.appendFormat("  < %zd frames: %.3f s (%.1f%%)\n",
-                b + 1, bucketTimeSec, percent);
-    }
-    float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9;
-    float percent = 100.0f *
-            static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime;
-    result.appendFormat("  %zd+ frames: %.3f s (%.1f%%)\n",
-            NUM_BUCKETS - 1, bucketTimeSec, percent);
-}
-
-void SurfaceFlinger::dumpFrameEventsLocked(String8& result) {
-    result.appendFormat("Layer frame timestamps:\n");
-
-    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
-    const size_t count = currentLayers.size();
-    for (size_t i=0 ; i<count ; i++) {
-        currentLayers[i]->dumpFrameEvents(result);
-    }
-}
-
-void SurfaceFlinger::recordBufferingStats(const char* layerName,
-        std::vector<OccupancyTracker::Segment>&& history) {
-    Mutex::Autolock lock(mBufferingStatsMutex);
-    auto& stats = mBufferingStats[layerName];
-    for (const auto& segment : history) {
-        if (!segment.usedThirdBuffer) {
-            stats.twoBufferTime += segment.totalTime;
-        }
-        if (segment.occupancyAverage < 1.0f) {
-            stats.doubleBufferedTime += segment.totalTime;
-        } else if (segment.occupancyAverage < 2.0f) {
-            stats.tripleBufferedTime += segment.totalTime;
-        }
-        ++stats.numSegments;
-        stats.totalTime += segment.totalTime;
-    }
-}
-
-void SurfaceFlinger::dumpBufferingStats(String8& result) const {
-    result.append("Buffering stats:\n");
-    result.append("  [Layer name] <Active time> <Two buffer> "
-            "<Double buffered> <Triple buffered>\n");
-    Mutex::Autolock lock(mBufferingStatsMutex);
-    typedef std::tuple<std::string, float, float, float> BufferTuple;
-    std::map<float, BufferTuple, std::greater<float>> sorted;
-    for (const auto& statsPair : mBufferingStats) {
-        const char* name = statsPair.first.c_str();
-        const BufferingStats& stats = statsPair.second;
-        if (stats.numSegments == 0) {
-            continue;
-        }
-        float activeTime = ns2ms(stats.totalTime) / 1000.0f;
-        float twoBufferRatio = static_cast<float>(stats.twoBufferTime) /
-                stats.totalTime;
-        float doubleBufferRatio = static_cast<float>(
-                stats.doubleBufferedTime) / stats.totalTime;
-        float tripleBufferRatio = static_cast<float>(
-                stats.tripleBufferedTime) / stats.totalTime;
-        sorted.insert({activeTime, {name, twoBufferRatio,
-                doubleBufferRatio, tripleBufferRatio}});
-    }
-    for (const auto& sortedPair : sorted) {
-        float activeTime = sortedPair.first;
-        const BufferTuple& values = sortedPair.second;
-        result.appendFormat("  [%s] %.2f %.3f %.3f %.3f\n",
-                std::get<0>(values).c_str(), activeTime,
-                std::get<1>(values), std::get<2>(values),
-                std::get<3>(values));
-    }
-    result.append("\n");
-}
-
-LayersProto SurfaceFlinger::dumpProtoInfo() const {
-    LayersProto layersProto;
-    mCurrentState.traverseInZOrder([&](Layer* layer) {
-        LayerProto* layerProto = layersProto.add_layers();
-        layer->writeToProto(layerProto, LayerVector::StateSet::Current);
-    });
-
-    return layersProto;
-}
-
-void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
-        String8& result) const
-{
-    bool colorize = false;
-    if (index < args.size()
-            && (args[index] == String16("--color"))) {
-        colorize = true;
-        index++;
-    }
-
-    Colorizer colorizer(colorize);
-
-    // figure out if we're stuck somewhere
-    const nsecs_t now = systemTime();
-    const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
-    const nsecs_t inTransaction(mDebugInTransaction);
-    nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
-    nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
-
-    /*
-     * Dump library configuration.
-     */
-
-    colorizer.bold(result);
-    result.append("Build configuration:");
-    colorizer.reset(result);
-    appendSfConfigString(result);
-    appendUiConfigString(result);
-    appendGuiConfigString(result);
-    result.append("\n");
-
-    colorizer.bold(result);
-    result.append("Sync configuration: ");
-    colorizer.reset(result);
-    result.append(SyncFeatures::getInstance().toString());
-    result.append("\n");
-
-    colorizer.bold(result);
-    result.append("DispSync configuration: ");
-    colorizer.reset(result);
-    result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, "
-            "present offset %" PRId64 " ns (refresh %" PRId64 " ns)",
-        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, dispSyncPresentTimeOffset,
-        mHwc->getRefreshPeriod(HWC_DISPLAY_PRIMARY));
-    result.append("\n");
-
-    // Dump static screen stats
-    result.append("\n");
-    dumpStaticScreenStats(result);
-    result.append("\n");
-
-    dumpBufferingStats(result);
-
-    /*
-     * Dump the visible layer list
-     */
-    colorizer.bold(result);
-    result.appendFormat("Visible layers (count = %zu)\n", mNumLayers);
-    colorizer.reset(result);
-
-    LayersProto layersProto = dumpProtoInfo();
-    auto layerTree = LayerProtoParser::generateLayerTree(layersProto);
-    result.append(LayerProtoParser::layersToString(layerTree).c_str());
-
-    /*
-     * Dump Display state
-     */
-
-    colorizer.bold(result);
-    result.appendFormat("Displays (%zu entries)\n", mDisplays.size());
-    colorizer.reset(result);
-    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
-        hw->dump(result);
-    }
-
-    /*
-     * Dump SurfaceFlinger global state
-     */
-
-    colorizer.bold(result);
-    result.append("SurfaceFlinger global state:\n");
-    colorizer.reset(result);
-
-    HWComposer& hwc(getHwComposer());
-    sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
-
-    colorizer.bold(result);
-    result.appendFormat("EGL implementation : %s\n",
-            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
-    colorizer.reset(result);
-    result.appendFormat("%s\n",
-            eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
-
-    mRenderEngine->dump(result);
-
-    hw->undefinedRegion.dump(result, "undefinedRegion");
-    result.appendFormat("  orientation=%d, isDisplayOn=%d\n",
-            hw->getOrientation(), hw->isDisplayOn());
-    result.appendFormat(
-            "  last eglSwapBuffers() time: %f us\n"
-            "  last transaction time     : %f us\n"
-            "  transaction-flags         : %08x\n"
-            "  refresh-rate              : %f fps\n"
-            "  x-dpi                     : %f\n"
-            "  y-dpi                     : %f\n"
-            "  gpu_to_cpu_unsupported    : %d\n"
-            ,
-            mLastSwapBufferTime/1000.0,
-            mLastTransactionTime/1000.0,
-            mTransactionFlags,
-            1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY),
-            hwc.getDpiX(HWC_DISPLAY_PRIMARY),
-            hwc.getDpiY(HWC_DISPLAY_PRIMARY),
-            !mGpuToCpuSupported);
-
-    result.appendFormat("  eglSwapBuffers time: %f us\n",
-            inSwapBuffersDuration/1000.0);
-
-    result.appendFormat("  transaction time: %f us\n",
-            inTransactionDuration/1000.0);
-
-    /*
-     * VSYNC state
-     */
-    mEventThread->dump(result);
-
-    /*
-     * Dump HWComposer state
-     */
-    colorizer.bold(result);
-    result.append("h/w composer state:\n");
-    colorizer.reset(result);
-    result.appendFormat("  h/w composer %s and %s\n",
-            hwc.initCheck()==NO_ERROR ? "present" : "not present",
-                    (mDebugDisableHWC || mDebugRegion || mDaltonize
-                            || mHasColorMatrix) ? "disabled" : "enabled");
-    hwc.dump(result);
-
-    /*
-     * Dump gralloc state
-     */
-    const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
-    alloc.dump(result);
-}
-
-const Vector< sp<Layer> >&
-SurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
-    // Note: mStateLock is held here
-    wp<IBinder> dpy;
-    for (size_t i=0 ; i<mDisplays.size() ; i++) {
-        if (mDisplays.valueAt(i)->getHwcDisplayId() == id) {
-            dpy = mDisplays.keyAt(i);
-            break;
-        }
-    }
-    if (dpy == NULL) {
-        ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
-        // Just use the primary display so we have something to return
-        dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
-    }
-    return getDisplayDeviceLocked(dpy)->getVisibleLayersSortedByZ();
-}
-
-bool SurfaceFlinger::startDdmConnection()
-{
-    void* libddmconnection_dso =
-            dlopen("libsurfaceflinger_ddmconnection.so", RTLD_NOW);
-    if (!libddmconnection_dso) {
-        return false;
-    }
-    void (*DdmConnection_start)(const char* name);
-    DdmConnection_start =
-            (decltype(DdmConnection_start))dlsym(libddmconnection_dso, "DdmConnection_start");
-    if (!DdmConnection_start) {
-        dlclose(libddmconnection_dso);
-        return false;
-    }
-    (*DdmConnection_start)(getServiceName());
-    return true;
-}
-
-status_t SurfaceFlinger::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch (code) {
-        case CREATE_CONNECTION:
-        case CREATE_DISPLAY:
-        case BOOT_FINISHED:
-        case CLEAR_ANIMATION_FRAME_STATS:
-        case GET_ANIMATION_FRAME_STATS:
-        case SET_POWER_MODE:
-        case GET_HDR_CAPABILITIES:
-        {
-            // codes that require permission check
-            IPCThreadState* ipc = IPCThreadState::self();
-            const int pid = ipc->getCallingPid();
-            const int uid = ipc->getCallingUid();
-            if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) &&
-                    !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
-                ALOGE("Permission Denial: "
-                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
-                return PERMISSION_DENIED;
-            }
-            break;
-        }
-        /*
-         * Calling setTransactionState is safe, because you need to have been
-         * granted a reference to Client* and Handle* to do anything with it.
-         *
-         * Creating a scoped connection is safe, as per discussion in ISurfaceComposer.h
-         */
-        case SET_TRANSACTION_STATE:
-        case CREATE_SCOPED_CONNECTION:
-        {
-            break;
-        }
-        case CAPTURE_SCREEN:
-        {
-            // codes that require permission check
-            IPCThreadState* ipc = IPCThreadState::self();
-            const int pid = ipc->getCallingPid();
-            const int uid = ipc->getCallingUid();
-            if ((uid != AID_GRAPHICS) &&
-                    !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
-                ALOGE("Permission Denial: "
-                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
-                return PERMISSION_DENIED;
-            }
-            break;
-        }
-        case CAPTURE_LAYERS:
-        {
-            IPCThreadState* ipc = IPCThreadState::self();
-            const int pid = ipc->getCallingPid();
-            const int uid = ipc->getCallingUid();
-            if ((uid != AID_GRAPHICS) &&
-                !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) {
-                ALOGE("Permission Denial: can't read framebuffer pid=%d, uid=%d", pid, uid);
-                return PERMISSION_DENIED;
-            }
-            break;
-        }
-    }
-
-    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
-    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
-        CHECK_INTERFACE(ISurfaceComposer, data, reply);
-        if (CC_UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) {
-            IPCThreadState* ipc = IPCThreadState::self();
-            const int pid = ipc->getCallingPid();
-            const int uid = ipc->getCallingUid();
-            ALOGE("Permission Denial: "
-                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
-            return PERMISSION_DENIED;
-        }
-        int n;
-        switch (code) {
-            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
-            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
-                return NO_ERROR;
-            case 1002:  // SHOW_UPDATES
-                n = data.readInt32();
-                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
-                invalidateHwcGeometry();
-                repaintEverything();
-                return NO_ERROR;
-            case 1004:{ // repaint everything
-                repaintEverything();
-                return NO_ERROR;
-            }
-            case 1005:{ // force transaction
-                setTransactionFlags(
-                        eTransactionNeeded|
-                        eDisplayTransactionNeeded|
-                        eTraversalNeeded);
-                return NO_ERROR;
-            }
-            case 1006:{ // send empty update
-                signalRefresh();
-                return NO_ERROR;
-            }
-            case 1008:  // toggle use of hw composer
-                n = data.readInt32();
-                mDebugDisableHWC = n ? 1 : 0;
-                invalidateHwcGeometry();
-                repaintEverything();
-                return NO_ERROR;
-            case 1009:  // toggle use of transform hint
-                n = data.readInt32();
-                mDebugDisableTransformHint = n ? 1 : 0;
-                invalidateHwcGeometry();
-                repaintEverything();
-                return NO_ERROR;
-            case 1010:  // interrogate.
-                reply->writeInt32(0);
-                reply->writeInt32(0);
-                reply->writeInt32(mDebugRegion);
-                reply->writeInt32(0);
-                reply->writeInt32(mDebugDisableHWC);
-                return NO_ERROR;
-            case 1013: {
-                Mutex::Autolock _l(mStateLock);
-                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
-                reply->writeInt32(hw->getPageFlipCount());
-                return NO_ERROR;
-            }
-            case 1014: {
-                // daltonize
-                n = data.readInt32();
-                switch (n % 10) {
-                    case 1:
-                        mDaltonizer.setType(ColorBlindnessType::Protanomaly);
-                        break;
-                    case 2:
-                        mDaltonizer.setType(ColorBlindnessType::Deuteranomaly);
-                        break;
-                    case 3:
-                        mDaltonizer.setType(ColorBlindnessType::Tritanomaly);
-                        break;
-                }
-                if (n >= 10) {
-                    mDaltonizer.setMode(ColorBlindnessMode::Correction);
-                } else {
-                    mDaltonizer.setMode(ColorBlindnessMode::Simulation);
-                }
-                mDaltonize = n > 0;
-                invalidateHwcGeometry();
-                repaintEverything();
-                return NO_ERROR;
-            }
-            case 1015: {
-                // apply a color matrix
-                n = data.readInt32();
-                mHasColorMatrix = n ? 1 : 0;
-                if (n) {
-                    // color matrix is sent as mat3 matrix followed by vec3
-                    // offset, then packed into a mat4 where the last row is
-                    // the offset and extra values are 0
-                    for (size_t i = 0 ; i < 4; i++) {
-                      for (size_t j = 0; j < 4; j++) {
-                          mColorMatrix[i][j] = data.readFloat();
-                      }
-                    }
-                } else {
-                    mColorMatrix = mat4();
-                }
-                invalidateHwcGeometry();
-                repaintEverything();
-                return NO_ERROR;
-            }
-            // This is an experimental interface
-            // Needs to be shifted to proper binder interface when we productize
-            case 1016: {
-                n = data.readInt32();
-                mPrimaryDispSync.setRefreshSkipCount(n);
-                return NO_ERROR;
-            }
-            case 1017: {
-                n = data.readInt32();
-                mForceFullDamage = static_cast<bool>(n);
-                return NO_ERROR;
-            }
-            case 1018: { // Modify Choreographer's phase offset
-                n = data.readInt32();
-                mEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
-                return NO_ERROR;
-            }
-            case 1019: { // Modify SurfaceFlinger's phase offset
-                n = data.readInt32();
-                mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
-                return NO_ERROR;
-            }
-            case 1020: { // Layer updates interceptor
-                n = data.readInt32();
-                if (n) {
-                    ALOGV("Interceptor enabled");
-                    mInterceptor.enable(mDrawingState.layersSortedByZ, mDrawingState.displays);
-                }
-                else{
-                    ALOGV("Interceptor disabled");
-                    mInterceptor.disable();
-                }
-                return NO_ERROR;
-            }
-            case 1021: { // Disable HWC virtual displays
-                n = data.readInt32();
-                mUseHwcVirtualDisplays = !n;
-                return NO_ERROR;
-            }
-        }
-    }
-    return err;
-}
-
-void SurfaceFlinger::repaintEverything() {
-    android_atomic_or(1, &mRepaintEverything);
-    signalTransaction();
-}
-
-// ---------------------------------------------------------------------------
-// Capture screen into an IGraphiBufferProducer
-// ---------------------------------------------------------------------------
-
-/* The code below is here to handle b/8734824
- *
- * We create a IGraphicBufferProducer wrapper that forwards all calls
- * from the surfaceflinger thread to the calling binder thread, where they
- * are executed. This allows the calling thread in the calling process to be
- * reused and not depend on having "enough" binder threads to handle the
- * requests.
- */
-class GraphicProducerWrapper : public BBinder, public MessageHandler {
-    /* Parts of GraphicProducerWrapper are run on two different threads,
-     * communicating by sending messages via Looper but also by shared member
-     * data. Coherence maintenance is subtle and in places implicit (ugh).
-     *
-     * Don't rely on Looper's sendMessage/handleMessage providing
-     * release/acquire semantics for any data not actually in the Message.
-     * Data going from surfaceflinger to binder threads needs to be
-     * synchronized explicitly.
-     *
-     * Barrier open/wait do provide release/acquire semantics. This provides
-     * implicit synchronization for data coming back from binder to
-     * surfaceflinger threads.
-     */
-
-    sp<IGraphicBufferProducer> impl;
-    sp<Looper> looper;
-    status_t result;
-    bool exitPending;
-    bool exitRequested;
-    Barrier barrier;
-    uint32_t code;
-    Parcel const* data;
-    Parcel* reply;
-
-    enum {
-        MSG_API_CALL,
-        MSG_EXIT
-    };
-
-    /*
-     * Called on surfaceflinger thread. This is called by our "fake"
-     * BpGraphicBufferProducer. We package the data and reply Parcel and
-     * forward them to the binder thread.
-     */
-    virtual status_t transact(uint32_t code,
-            const Parcel& data, Parcel* reply, uint32_t /* flags */) {
-        this->code = code;
-        this->data = &data;
-        this->reply = reply;
-        if (exitPending) {
-            // if we've exited, we run the message synchronously right here.
-            // note (JH): as far as I can tell from looking at the code, this
-            // never actually happens. if it does, i'm not sure if it happens
-            // on the surfaceflinger or binder thread.
-            handleMessage(Message(MSG_API_CALL));
-        } else {
-            barrier.close();
-            // Prevent stores to this->{code, data, reply} from being
-            // reordered later than the construction of Message.
-            atomic_thread_fence(memory_order_release);
-            looper->sendMessage(this, Message(MSG_API_CALL));
-            barrier.wait();
-        }
-        return result;
-    }
-
-    /*
-     * here we run on the binder thread. All we've got to do is
-     * call the real BpGraphicBufferProducer.
-     */
-    virtual void handleMessage(const Message& message) {
-        int what = message.what;
-        // Prevent reads below from happening before the read from Message
-        atomic_thread_fence(memory_order_acquire);
-        if (what == MSG_API_CALL) {
-            result = IInterface::asBinder(impl)->transact(code, data[0], reply);
-            barrier.open();
-        } else if (what == MSG_EXIT) {
-            exitRequested = true;
-        }
-    }
-
-public:
-    explicit GraphicProducerWrapper(const sp<IGraphicBufferProducer>& impl)
-    :   impl(impl),
-        looper(new Looper(true)),
-        result(NO_ERROR),
-        exitPending(false),
-        exitRequested(false),
-        code(0),
-        data(NULL),
-        reply(NULL)
-    {}
-
-    // Binder thread
-    status_t waitForResponse() {
-        do {
-            looper->pollOnce(-1);
-        } while (!exitRequested);
-        return result;
-    }
-
-    // Client thread
-    void exit(status_t result) {
-        this->result = result;
-        exitPending = true;
-        // Ensure this->result is visible to the binder thread before it
-        // handles the message.
-        atomic_thread_fence(memory_order_release);
-        looper->sendMessage(this, Message(MSG_EXIT));
-    }
-};
-
-status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
-    const sp<IGraphicBufferProducer>& producer,
-    Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
-    int32_t minLayerZ, int32_t maxLayerZ,
-    bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
-    ATRACE_CALL();
-    if (CC_UNLIKELY(display == 0))
-        return BAD_VALUE;
-
-    const sp<const DisplayDevice> device(getDisplayDeviceLocked(display));
-    DisplayRenderArea renderArea(device, sourceCrop, reqHeight, reqWidth, rotation);
-
-    auto traverseLayers = std::bind(std::mem_fn(&SurfaceFlinger::traverseLayersInDisplay), this,
-                                    device, minLayerZ, maxLayerZ, std::placeholders::_1);
-    return captureScreenCommon(renderArea, traverseLayers, producer, useIdentityTransform);
-}
-
-status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
-                                       const sp<IGraphicBufferProducer>& producer,
-                                       ISurfaceComposer::Rotation rotation) {
-    ATRACE_CALL();
-    class LayerRenderArea : public RenderArea {
-    public:
-        LayerRenderArea(const sp<Layer>& layer, ISurfaceComposer::Rotation rotation)
-              : RenderArea(layer->getCurrentState().active.h, layer->getCurrentState().active.w,
-                           rotation),
-                mLayer(layer) {}
-        const Transform& getTransform() const override {
-            // Make the top level transform the inverse the transform and it's parent so it sets
-            // the whole capture back to 0,0
-            return *new Transform(mLayer->getTransform().inverse());
-        }
-        Rect getBounds() const override {
-            const Layer::State& layerState(mLayer->getDrawingState());
-            return Rect(layerState.active.w, layerState.active.h);
-        }
-        int getHeight() const override { return mLayer->getDrawingState().active.h; }
-        int getWidth() const override { return mLayer->getDrawingState().active.w; }
-        bool isSecure() const override { return false; }
-        bool needsFiltering() const override { return false; }
-
-        Rect getSourceCrop() const override { return getBounds(); }
-
-    private:
-        const sp<Layer>& mLayer;
-    };
-
-    auto layerHandle = reinterpret_cast<Layer::Handle*>(layerHandleBinder.get());
-    auto parent = layerHandle->owner.promote();
-
-    LayerRenderArea renderArea(parent, rotation);
-    auto traverseLayers = [parent](const LayerVector::Visitor& visitor) {
-        parent->traverseChildrenInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
-            if (!layer->isVisible()) {
-                return;
-            }
-            visitor(layer);
-        });
-    };
-    return captureScreenCommon(renderArea, traverseLayers, producer, false);
-}
-
-status_t SurfaceFlinger::captureScreenCommon(RenderArea& renderArea,
-                                             TraverseLayersFunction traverseLayers,
-                                             const sp<IGraphicBufferProducer>& producer,
-                                             bool useIdentityTransform) {
-    if (CC_UNLIKELY(producer == 0))
-        return BAD_VALUE;
-
-    // if we have secure windows on this display, never allow the screen capture
-    // unless the producer interface is local (i.e.: we can take a screenshot for
-    // ourselves).
-    bool isLocalScreenshot = IInterface::asBinder(producer)->localBinder();
-
-    class MessageCaptureScreen : public MessageBase {
-        SurfaceFlinger* flinger;
-        const RenderArea* renderArea;
-        TraverseLayersFunction traverseLayers;
-        sp<IGraphicBufferProducer> producer;
-        bool useIdentityTransform;
-        status_t result;
-        bool isLocalScreenshot;
-    public:
-        MessageCaptureScreen(SurfaceFlinger* flinger, const RenderArea* renderArea,
-                             TraverseLayersFunction traverseLayers,
-                             const sp<IGraphicBufferProducer>& producer, bool useIdentityTransform,
-                             bool isLocalScreenshot)
-              : flinger(flinger),
-                renderArea(renderArea),
-                traverseLayers(traverseLayers),
-                producer(producer),
-                useIdentityTransform(useIdentityTransform),
-                result(PERMISSION_DENIED),
-                isLocalScreenshot(isLocalScreenshot) {}
-        status_t getResult() const {
-            return result;
-        }
-        virtual bool handler() {
-            Mutex::Autolock _l(flinger->mStateLock);
-            result = flinger->captureScreenImplLocked(*renderArea, traverseLayers, producer,
-                                                      useIdentityTransform, isLocalScreenshot);
-            static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result);
-            return true;
-        }
-    };
-
-    // this creates a "fake" BBinder which will serve as a "fake" remote
-    // binder to receive the marshaled calls and forward them to the
-    // real remote (a BpGraphicBufferProducer)
-    sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer);
-
-    // the asInterface() call below creates our "fake" BpGraphicBufferProducer
-    // which does the marshaling work forwards to our "fake remote" above.
-    sp<MessageBase> msg = new MessageCaptureScreen(this,
-            &renderArea, traverseLayers, IGraphicBufferProducer::asInterface( wrapper ),
-            useIdentityTransform, isLocalScreenshot);
-
-    status_t res = postMessageAsync(msg);
-    if (res == NO_ERROR) {
-        res = wrapper->waitForResponse();
-    }
-    return res;
-}
-
-void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, TraverseLayersFunction traverseLayers,
-        bool yswap, bool useIdentityTransform)
-{
-    ATRACE_CALL();
-    RenderEngine& engine(getRenderEngine());
-
-    // get screen geometry
-    const auto raWidth = renderArea.getWidth();
-    const auto raHeight = renderArea.getHeight();
-
-    const auto reqWidth = renderArea.getReqWidth();
-    const auto reqHeight = renderArea.getReqHeight();
-    Rect sourceCrop = renderArea.getSourceCrop();
-
-    const bool filtering = static_cast<int32_t>(reqWidth) != raWidth ||
-        static_cast<int32_t>(reqHeight) != raHeight;
-
-    // if a default or invalid sourceCrop is passed in, set reasonable values
-    if (sourceCrop.width() == 0 || sourceCrop.height() == 0 ||
-            !sourceCrop.isValid()) {
-        sourceCrop.setLeftTop(Point(0, 0));
-        sourceCrop.setRightBottom(Point(raWidth, raHeight));
-    }
-
-    // ensure that sourceCrop is inside screen
-    if (sourceCrop.left < 0) {
-        ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
-    }
-    if (sourceCrop.right > raWidth) {
-        ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, raWidth);
-    }
-    if (sourceCrop.top < 0) {
-        ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
-    }
-    if (sourceCrop.bottom > raHeight) {
-        ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, raHeight);
-    }
-
-    // make sure to clear all GL error flags
-    engine.checkErrors();
-
-    // set-up our viewport
-    engine.setViewportAndProjection(
-        reqWidth, reqHeight, sourceCrop, raHeight, yswap, renderArea.getRotationFlags());
-    engine.disableTexturing();
-
-    // redraw the screen entirely...
-    engine.clearWithColor(0, 0, 0, 1);
-
-    traverseLayers([&](Layer* layer) {
-        if (filtering) layer->setFiltering(true);
-        layer->draw(renderArea, useIdentityTransform);
-        if (filtering) layer->setFiltering(false);
-    });
-
-    // compositionComplete is needed for older driver
-//    hw->compositionComplete();
-//    hw->setViewportAndProjection();
-}
-
-status_t SurfaceFlinger::captureScreenImplLocked(const RenderArea& renderArea,
-                                                 TraverseLayersFunction traverseLayers,
-                                                 const sp<IGraphicBufferProducer>& producer,
-                                                 bool useIdentityTransform,
-                                                 bool isLocalScreenshot) {
-    ATRACE_CALL();
-
-    bool secureLayerIsVisible = false;
-    traverseLayers([&](Layer *layer) {
-        secureLayerIsVisible = secureLayerIsVisible || (layer->isVisible() &&
-            layer->isSecure());
-    });
-
-    if (!isLocalScreenshot && secureLayerIsVisible) {
-        ALOGW("FB is protected: PERMISSION_DENIED");
-        return PERMISSION_DENIED;
-    }
-
-    // create a surface (because we're a producer, and we need to
-    // dequeue/queue a buffer)
-    sp<Surface> sur = new Surface(producer, false);
-    ANativeWindow* window = sur.get();
-
-    status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
-    if (result == NO_ERROR) {
-        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
-                        GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
-
-        int err = 0;
-        err = native_window_set_buffers_dimensions(window, renderArea.getReqWidth(),
-                                                   renderArea.getReqHeight());
-        err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
-        err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
-        err |= native_window_set_usage(window, usage);
-
-        if (err == NO_ERROR) {
-            ANativeWindowBuffer* buffer;
-            /* TODO: Once we have the sync framework everywhere this can use
-             * server-side waits on the fence that dequeueBuffer returns.
-             */
-            result = native_window_dequeue_buffer_and_wait(window,  &buffer);
-            if (result == NO_ERROR) {
-                int syncFd = -1;
-                // create an EGLImage from the buffer so we can later
-                // turn it into a texture
-                EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
-                        EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
-                if (image != EGL_NO_IMAGE_KHR) {
-                    // this binds the given EGLImage as a framebuffer for the
-                    // duration of this scope.
-                    RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
-                    if (imageBond.getStatus() == NO_ERROR) {
-                        // this will in fact render into our dequeued buffer
-                        // via an FBO, which means we didn't have to create
-                        // an EGLSurface and therefore we're not
-                        // dependent on the context's EGLConfig.
-                        renderScreenImplLocked(renderArea, traverseLayers, true, useIdentityTransform);
-
-                        // Attempt to create a sync khr object that can produce a sync point. If that
-                        // isn't available, create a non-dupable sync object in the fallback path and
-                        // wait on it directly.
-                        EGLSyncKHR sync;
-                        if (!DEBUG_SCREENSHOTS) {
-                           sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
-                           // native fence fd will not be populated until flush() is done.
-                           getRenderEngine().flush();
-                        } else {
-                            sync = EGL_NO_SYNC_KHR;
-                        }
-                        if (sync != EGL_NO_SYNC_KHR) {
-                            // get the sync fd
-                            syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
-                            if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
-                                ALOGW("captureScreen: failed to dup sync khr object");
-                                syncFd = -1;
-                            }
-                            eglDestroySyncKHR(mEGLDisplay, sync);
-                        } else {
-                            // fallback path
-                            sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
-                            if (sync != EGL_NO_SYNC_KHR) {
-                                EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
-                                    EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
-                                EGLint eglErr = eglGetError();
-                                if (result == EGL_TIMEOUT_EXPIRED_KHR) {
-                                    ALOGW("captureScreen: fence wait timed out");
-                                } else {
-                                    ALOGW_IF(eglErr != EGL_SUCCESS,
-                                            "captureScreen: error waiting on EGL fence: %#x", eglErr);
-                                }
-                                eglDestroySyncKHR(mEGLDisplay, sync);
-                            } else {
-                                ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
-                            }
-                        }
-                        if (DEBUG_SCREENSHOTS) {
-                            uint32_t* pixels = new uint32_t[renderArea.getReqWidth() *
-                                                            renderArea.getReqHeight()];
-                            getRenderEngine().readPixels(0, 0, renderArea.getReqWidth(),
-                                                         renderArea.getReqHeight(), pixels);
-                            checkScreenshot(renderArea.getReqWidth(), renderArea.getReqHeight(),
-                                            renderArea.getReqWidth(), pixels, traverseLayers);
-                            delete [] pixels;
-                        }
-
-                    } else {
-                        ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
-                        result = INVALID_OPERATION;
-                        window->cancelBuffer(window, buffer, syncFd);
-                        buffer = NULL;
-                    }
-                    // destroy our image
-                    eglDestroyImageKHR(mEGLDisplay, image);
-                } else {
-                    result = BAD_VALUE;
-                }
-                if (buffer) {
-                    // queueBuffer takes ownership of syncFd
-                    result = window->queueBuffer(window, buffer, syncFd);
-                }
-            }
-        } else {
-            result = BAD_VALUE;
-        }
-        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
-    }
-
-    return result;
-}
-
-void SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
-    TraverseLayersFunction traverseLayers) {
-    if (DEBUG_SCREENSHOTS) {
-        for (size_t y=0 ; y<h ; y++) {
-            uint32_t const * p = (uint32_t const *)vaddr + y*s;
-            for (size_t x=0 ; x<w ; x++) {
-                if (p[x] != 0xFF000000) return;
-            }
-        }
-        ALOGE("*** we just took a black screenshot ***");
-
-        size_t i = 0;
-        traverseLayers([&](Layer* layer) {
-            const Layer::State& state(layer->getDrawingState());
-            ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f",
-                layer->isVisible() ? '+' : '-',
-                i, layer->getName().string(), layer->getLayerStack(), state.z,
-                layer->isVisible(), state.flags, static_cast<float>(state.color.a));
-            i++;
-        });
-    }
-}
-
-// ---------------------------------------------------------------------------
-
-void SurfaceFlinger::State::traverseInZOrder(const LayerVector::Visitor& visitor) const {
-    layersSortedByZ.traverseInZOrder(stateSet, visitor);
-}
-
-void SurfaceFlinger::State::traverseInReverseZOrder(const LayerVector::Visitor& visitor) const {
-    layersSortedByZ.traverseInReverseZOrder(stateSet, visitor);
-}
-
-void SurfaceFlinger::traverseLayersInDisplay(const sp<const DisplayDevice>& hw,
-    int32_t minLayerZ, int32_t maxLayerZ, const LayerVector::Visitor& visitor) {
-
-    // We loop through the first level of layers without traversing,
-    // as we need to interpret min/max layer Z in the top level Z space.
-    for (const auto& layer : mDrawingState.layersSortedByZ) {
-        if (!layer->belongsToDisplay(hw->getLayerStack(), false)) {
-            continue;
-        }
-        const Layer::State& state(layer->getDrawingState());
-        if (state.z < minLayerZ || state.z > maxLayerZ) {
-            continue;
-        }
-        layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
-            if (!layer->isVisible()) {
-                return;
-            }
-            visitor(layer);
-        });
-    }
-}
-
-}; // 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/tests/fakehwc/FakeComposerClient.h b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h
index 2a5a8ad..b944182 100644
--- a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h
+++ b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h
@@ -16,7 +16,11 @@
 
 #pragma once
 
+#define HWC2_USE_CPP11
+#define HWC2_INCLUDE_STRINGIFICATION
 #include "ComposerClient.h"
+#undef HWC2_USE_CPP11
+#undef HWC2_INCLUDE_STRINGIFICATION
 #include "RenderState.h"
 
 // Needed for display type/ID enums
