diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index f008099..39b4528 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -17,14 +17,12 @@
     LayerDim.cpp \
     MessageQueue.cpp \
     MonitoredProducer.cpp \
-    SurfaceFlinger.cpp \
     SurfaceFlingerConsumer.cpp \
     SurfaceInterceptor.cpp \
     Transform.cpp \
     DisplayHardware/FramebufferSurface.cpp \
     DisplayHardware/HWC2.cpp \
     DisplayHardware/HWC2On1Adapter.cpp \
-    DisplayHardware/HWComposer.cpp \
     DisplayHardware/PowerHAL.cpp \
     DisplayHardware/VirtualDisplaySurface.cpp \
     Effects/Daltonizer.cpp \
@@ -49,6 +47,17 @@
 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
+
 ifeq ($(TARGET_BOARD_PLATFORM),omap4)
     LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY
 endif
@@ -157,6 +166,10 @@
     LOCAL_CFLAGS += -DENABLE_CPUSETS
 endif
 
+ifeq ($(TARGET_USES_HWC2),true)
+    LOCAL_CFLAGS += -DUSE_HWC2
+endif
+
 LOCAL_SRC_FILES := \
     main_surfaceflinger.cpp
 
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 43fb19d..6c18ef7 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -37,7 +37,9 @@
 
 #include "DisplayHardware/DisplaySurface.h"
 #include "DisplayHardware/HWComposer.h"
+#ifdef USE_HWC2
 #include "DisplayHardware/HWC2.h"
+#endif
 #include "RenderEngine/RenderEngine.h"
 
 #include "clz.h"
@@ -72,6 +74,9 @@
         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,
@@ -87,6 +92,9 @@
       mSurface(EGL_NO_SURFACE),
       mDisplayWidth(),
       mDisplayHeight(),
+#ifndef USE_HWC2
+      mFormat(),
+#endif
       mFlags(),
       mPageFlipCount(),
       mIsSecure(isSecure),
@@ -106,7 +114,11 @@
     EGLSurface eglSurface;
     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     if (config == EGL_NO_CONFIG) {
+#ifdef USE_HWC2
         config = RenderEngine::chooseEglConfig(display, PIXEL_FORMAT_RGBA_8888);
+#else
+        config = RenderEngine::chooseEglConfig(display, format);
+#endif
     }
     eglSurface = eglCreateWindowSurface(display, config, window, NULL);
     eglQuerySurface(display, eglSurface, EGL_WIDTH,  &mDisplayWidth);
@@ -125,6 +137,9 @@
     mConfig = config;
     mDisplay = display;
     mSurface = eglSurface;
+#ifndef USE_HWC2
+    mFormat = format;
+#endif
     mPageFlipCount = 0;
     mViewport.makeInvalid();
     mFrame.makeInvalid();
@@ -165,6 +180,10 @@
 void DisplayDevice::disconnect(HWComposer& hwc) {
     if (mHwcDisplayId >= 0) {
         hwc.disconnectDisplay(mHwcDisplayId);
+#ifndef USE_HWC2
+        if (mHwcDisplayId >= DISPLAY_VIRTUAL)
+            hwc.freeDisplayId(mHwcDisplayId);
+#endif
         mHwcDisplayId = -1;
     }
 }
@@ -181,6 +200,12 @@
     return mDisplayHeight;
 }
 
+#ifndef USE_HWC2
+PixelFormat DisplayDevice::getFormat() const {
+    return mFormat;
+}
+#endif
+
 EGLSurface DisplayDevice::getEGLSurface() const {
     return mSurface;
 }
@@ -196,6 +221,12 @@
     return mPageFlipCount;
 }
 
+#ifndef USE_HWC2
+status_t DisplayDevice::compositionComplete() const {
+    return mDisplaySurface->compositionComplete();
+}
+#endif
+
 void DisplayDevice::flip(const Region& dirty) const
 {
     mFlinger->getRenderEngine().checkErrors();
@@ -216,6 +247,7 @@
     return mDisplaySurface->beginFrame(mustRecompose);
 }
 
+#ifdef USE_HWC2
 status_t DisplayDevice::prepareFrame(HWComposer& hwc) {
     status_t error = hwc.prepare(*this);
     if (error != NO_ERROR) {
@@ -239,9 +271,41 @@
     }
     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();
@@ -263,9 +327,17 @@
     }
 }
 
+#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
 {
@@ -343,6 +415,7 @@
 }
 
 // ----------------------------------------------------------------------------
+#ifdef USE_HWC2
 void DisplayDevice::setActiveColorMode(android_color_mode_t mode) {
     mActiveColorMode = mode;
 }
@@ -350,6 +423,7 @@
 android_color_mode_t DisplayDevice::getActiveColorMode() const {
     return mActiveColorMode;
 }
+#endif
 
 // ----------------------------------------------------------------------------
 
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 7e8f156..92ede08 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -21,20 +21,27 @@
 
 #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>
 
 #include <hardware/hwcomposer_defs.h>
 
+#ifdef USE_HWC2
 #include <memory>
+#endif
 
 struct ANativeWindow;
 
@@ -80,6 +87,9 @@
             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,
@@ -102,6 +112,9 @@
 
     int         getWidth() const;
     int         getHeight() const;
+#ifndef USE_HWC2
+    PixelFormat getFormat() const;
+#endif
     uint32_t    getFlags() const;
 
     EGLSurface  getEGLSurface() const;
@@ -131,12 +144,23 @@
     // 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);
+#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);
@@ -158,8 +182,10 @@
     void setPowerMode(int mode);
     bool isDisplayOn() const;
 
+#ifdef USE_HWC2
     android_color_mode_t getActiveColorMode() const;
     void setActiveColorMode(android_color_mode_t mode);
+#endif
 
     /* ------------------------------------------------------------------------
      * Display active config management.
@@ -194,6 +220,9 @@
     EGLSurface      mSurface;
     int             mDisplayWidth;
     int             mDisplayHeight;
+#ifndef USE_HWC2
+    PixelFormat     mFormat;
+#endif
     uint32_t        mFlags;
     mutable uint32_t mPageFlipCount;
     String8         mDisplayName;
@@ -228,8 +257,10 @@
     int mPowerMode;
     // Current active config
     int mActiveConfig;
+#ifdef USE_HWC2
     // current active color mode
     android_color_mode_t mActiveColorMode;
+#endif
 };
 
 struct DisplayDeviceState {
diff --git a/services/surfaceflinger/DisplayHardware/DisplaySurface.h b/services/surfaceflinger/DisplayHardware/DisplaySurface.h
index d39a3aa..d801bb3 100644
--- a/services/surfaceflinger/DisplayHardware/DisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/DisplaySurface.h
@@ -49,6 +49,14 @@
     };
     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 a50b550..18c7945 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -62,20 +62,32 @@
     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(NUM_FRAMEBUFFER_SURFACE_BUFFERS - 1);
 }
 
@@ -88,6 +100,7 @@
 }
 
 status_t FramebufferSurface::advanceFrame() {
+#ifdef USE_HWC2
     sp<GraphicBuffer> buf;
     sp<Fence> acquireFence(Fence::NO_FENCE);
     android_dataspace_t dataspace = HAL_DATASPACE_UNKNOWN;
@@ -102,10 +115,20 @@
         ALOGE("error posting framebuffer: %d", 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(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;
@@ -128,9 +151,19 @@
     // 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;
@@ -138,10 +171,30 @@
 
     outFence = item.mFence;
     outBuffer = mCurrentBuffer;
+#ifdef USE_HWC2
     outDataspace = item.mDataSpace;
+#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) {
@@ -150,6 +203,7 @@
 }
 
 void FramebufferSurface::onFrameCommitted() {
+#ifdef USE_HWC2
     if (mHasPendingRelease) {
         sp<Fence> fence = mHwc.getRetireFence(mDisplayType);
         if (fence->isValid()) {
@@ -166,14 +220,34 @@
         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 {
     ConsumerBase::dumpState(result);
 }
 
 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 eb70479..439435a 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -41,6 +41,9 @@
 
     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;
@@ -54,6 +57,9 @@
 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;
@@ -61,8 +67,12 @@
     // 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(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;
@@ -82,10 +92,12 @@
     // Hardware composer, owned by SurfaceFlinger.
     HWComposer& mHwc;
 
+#ifdef USE_HWC2
     // 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 b25f5ad..41671f6 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 
+#ifndef USE_HWC2
+#include "HWComposer_hwc1.h"
+#else
+
 #ifndef ANDROID_SF_HWCOMPOSER_H
 #define ANDROID_SF_HWCOMPOSER_H
 
@@ -220,3 +224,5 @@
 }; // 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
new file mode 100644
index 0000000..2102457
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
@@ -0,0 +1,1344 @@
+/*
+ * 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/log.h>
+#include <cutils/properties.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() {
+    mFlinger->repaintEverything();
+}
+
+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(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(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_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(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/HWComposer_hwc1.h b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
new file mode 100644
index 0000000..170e382
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
@@ -0,0 +1,398 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_SF_HWCOMPOSER_HWC1_H
+#define ANDROID_SF_HWCOMPOSER_HWC1_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <hardware/hwcomposer_defs.h>
+
+#include <system/graphics.h>
+
+#include <ui/Fence.h>
+
+#include <utils/BitSet.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+#include <utils/StrongPointer.h>
+#include <utils/Thread.h>
+#include <utils/Timers.h>
+#include <utils/Vector.h>
+
+extern "C" int clock_nanosleep(clockid_t clock_id, int flags,
+                           const struct timespec *request,
+                           struct timespec *remain);
+
+struct hwc_composer_device_1;
+struct hwc_display_contents_1;
+struct hwc_layer_1;
+struct hwc_procs;
+struct framebuffer_device_t;
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+class Fence;
+class FloatRect;
+class GraphicBuffer;
+class NativeHandle;
+class Region;
+class String8;
+class SurfaceFlinger;
+
+class HWComposer
+{
+public:
+    class EventHandler {
+        friend class HWComposer;
+        virtual void onVSyncReceived(int disp, nsecs_t timestamp) = 0;
+        virtual void onHotplugReceived(int disp, bool connected) = 0;
+    protected:
+        virtual ~EventHandler() {}
+    };
+
+    enum {
+        NUM_BUILTIN_DISPLAYS = HWC_NUM_PHYSICAL_DISPLAY_TYPES,
+        MAX_HWC_DISPLAYS = HWC_NUM_DISPLAY_TYPES,
+        VIRTUAL_DISPLAY_ID_BASE = HWC_DISPLAY_VIRTUAL,
+    };
+
+    HWComposer(
+            const sp<SurfaceFlinger>& flinger,
+            EventHandler& handler);
+
+    ~HWComposer();
+
+    status_t initCheck() const;
+
+    // Returns a display ID starting at VIRTUAL_DISPLAY_ID_BASE, this ID is to
+    // be used with createWorkList (and all other methods requiring an ID
+    // below).
+    // IDs below NUM_BUILTIN_DISPLAYS are pre-defined and therefore are
+    // always valid.
+    // Returns -1 if an ID cannot be allocated
+    int32_t allocateDisplayId();
+
+    // Recycles the given virtual display ID and frees the associated worklist.
+    // IDs below NUM_BUILTIN_DISPLAYS are not recycled.
+    status_t freeDisplayId(int32_t id);
+
+
+    // Asks the HAL what it can do
+    status_t prepare();
+
+    // commits the list
+    status_t commit();
+
+    // set power mode
+    status_t setPowerMode(int disp, int mode);
+
+    // set active config
+    status_t setActiveConfig(int disp, int mode);
+
+    // reset state when an external, non-virtual display is disconnected
+    void disconnectDisplay(int disp);
+
+    // create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED.
+    status_t createWorkList(int32_t id, size_t numLayers);
+
+    bool supportsFramebufferTarget() const;
+
+    // does this display have layers handled by HWC
+    bool hasHwcComposition(int32_t id) const;
+
+    // does this display have layers handled by GLES
+    bool hasGlesComposition(int32_t id) const;
+
+    // get the releaseFence file descriptor for a display's framebuffer layer.
+    // the release fence is only valid after commit()
+    sp<Fence> getAndResetReleaseFence(int32_t id);
+
+    // needed forward declarations
+    class LayerListIterator;
+
+    // return the visual id to be used to find a suitable EGLConfig for
+    // *ALL* displays.
+    int getVisualID() const;
+
+    // Forwarding to FB HAL for pre-HWC-1.1 code (see FramebufferSurface).
+    int fbPost(int32_t id, const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buf);
+    int fbCompositionComplete();
+    void fbDump(String8& result);
+
+    // Set the output buffer and acquire fence for a virtual display.
+    // Returns INVALID_OPERATION if id is not a virtual display.
+    status_t setOutputBuffer(int32_t id, const sp<Fence>& acquireFence,
+            const sp<GraphicBuffer>& buf);
+
+    // Get the retire fence for the last committed frame. This fence will
+    // signal when the h/w composer is completely finished with the frame.
+    // For physical displays, it is no longer being displayed. For virtual
+    // displays, writes to the output buffer are complete.
+    sp<Fence> getLastRetireFence(int32_t id) const;
+
+    status_t setCursorPositionAsync(int32_t id, const Rect &pos);
+
+    /*
+     * Interface to hardware composer's layers functionality.
+     * This abstracts the HAL interface to layers which can evolve in
+     * incompatible ways from one release to another.
+     * The idea is that we could extend this interface as we add
+     * features to h/w composer.
+     */
+    class HWCLayerInterface {
+    protected:
+        virtual ~HWCLayerInterface() { }
+    public:
+        virtual int32_t getCompositionType() const = 0;
+        virtual uint32_t getHints() const = 0;
+        virtual sp<Fence> getAndResetReleaseFence() = 0;
+        virtual void setDefaultState() = 0;
+        virtual void setSkip(bool skip) = 0;
+        virtual void setIsCursorLayerHint(bool isCursor = true) = 0;
+        virtual void setBlending(uint32_t blending) = 0;
+        virtual void setTransform(uint32_t transform) = 0;
+        virtual void setFrame(const Rect& frame) = 0;
+        virtual void setCrop(const FloatRect& crop) = 0;
+        virtual void setVisibleRegionScreen(const Region& reg) = 0;
+        virtual void setSurfaceDamage(const Region& reg) = 0;
+        virtual void setSidebandStream(const sp<NativeHandle>& stream) = 0;
+        virtual void setBuffer(const sp<GraphicBuffer>& buffer) = 0;
+        virtual void setAcquireFenceFd(int fenceFd) = 0;
+        virtual void setPlaneAlpha(uint8_t alpha) = 0;
+        virtual void onDisplayed() = 0;
+    };
+
+    /*
+     * Interface used to implement an iterator to a list
+     * of HWCLayer.
+     */
+    class HWCLayer : public HWCLayerInterface {
+        friend class LayerListIterator;
+        // select the layer at the given index
+        virtual status_t setLayer(size_t index) = 0;
+        virtual HWCLayer* dup() = 0;
+        static HWCLayer* copy(HWCLayer *rhs) {
+            return rhs ? rhs->dup() : NULL;
+        }
+    protected:
+        virtual ~HWCLayer() { }
+    };
+
+    /*
+     * Iterator through a HWCLayer list.
+     * This behaves more or less like a forward iterator.
+     */
+    class LayerListIterator {
+        friend class HWComposer;
+        HWCLayer* const mLayerList;
+        size_t mIndex;
+
+        LayerListIterator() : mLayerList(NULL), mIndex(0) { }
+
+        LayerListIterator(HWCLayer* layer, size_t index)
+            : mLayerList(layer), mIndex(index) { }
+
+        // we don't allow assignment, because we don't need it for now
+        LayerListIterator& operator = (const LayerListIterator& rhs);
+
+    public:
+        // copy operators
+        LayerListIterator(const LayerListIterator& rhs)
+            : mLayerList(HWCLayer::copy(rhs.mLayerList)), mIndex(rhs.mIndex) {
+        }
+
+        ~LayerListIterator() { delete mLayerList; }
+
+        // pre-increment
+        LayerListIterator& operator++() {
+            mLayerList->setLayer(++mIndex);
+            return *this;
+        }
+
+        // dereference
+        HWCLayerInterface& operator * () { return *mLayerList; }
+        HWCLayerInterface* operator -> () { return mLayerList; }
+
+        // comparison
+        bool operator == (const LayerListIterator& rhs) const {
+            return mIndex == rhs.mIndex;
+        }
+        bool operator != (const LayerListIterator& rhs) const {
+            return !operator==(rhs);
+        }
+    };
+
+    // Returns an iterator to the beginning of the layer list
+    LayerListIterator begin(int32_t id);
+
+    // Returns an iterator to the end of the layer list
+    LayerListIterator end(int32_t id);
+
+
+    // Events handling ---------------------------------------------------------
+
+    enum {
+        EVENT_VSYNC = HWC_EVENT_VSYNC
+    };
+
+    void eventControl(int disp, int event, int enabled);
+
+    struct DisplayConfig {
+        uint32_t width;
+        uint32_t height;
+        float xdpi;
+        float ydpi;
+        nsecs_t refresh;
+        android_color_mode_t colorMode;
+        bool operator==(const DisplayConfig& rhs) const {
+            return width == rhs.width &&
+                    height == rhs.height &&
+                    xdpi == rhs.xdpi &&
+                    ydpi == rhs.ydpi &&
+                    refresh == rhs.refresh &&
+                    colorMode == rhs.colorMode;
+        }
+    };
+
+    // Query display parameters.  Pass in a display index (e.g.
+    // HWC_DISPLAY_PRIMARY).
+    nsecs_t getRefreshTimestamp(int disp) const;
+    sp<Fence> getDisplayFence(int disp) const;
+    uint32_t getFormat(int disp) const;
+    bool isConnected(int disp) const;
+
+    // These return the values for the current config of a given display index.
+    // To get the values for all configs, use getConfigs below.
+    uint32_t getWidth(int disp) const;
+    uint32_t getHeight(int disp) const;
+    float getDpiX(int disp) const;
+    float getDpiY(int disp) const;
+    nsecs_t getRefreshPeriod(int disp) const;
+    android_color_mode_t getColorMode(int disp) const;
+
+    const Vector<DisplayConfig>& getConfigs(int disp) const;
+    size_t getCurrentConfig(int disp) const;
+
+    status_t setVirtualDisplayProperties(int32_t id, uint32_t w, uint32_t h,
+            uint32_t format);
+
+    // this class is only used to fake the VSync event on systems that don't
+    // have it.
+    class VSyncThread : public Thread {
+        HWComposer& mHwc;
+        mutable Mutex mLock;
+        Condition mCondition;
+        bool mEnabled;
+        mutable nsecs_t mNextFakeVSync;
+        nsecs_t mRefreshPeriod;
+        virtual void onFirstRef();
+        virtual bool threadLoop();
+    public:
+        VSyncThread(HWComposer& hwc);
+        void setEnabled(bool enabled);
+    };
+
+    friend class VSyncThread;
+
+    // for debugging ----------------------------------------------------------
+    void dump(String8& out) const;
+
+private:
+    void loadHwcModule();
+    int loadFbHalModule();
+
+    LayerListIterator getLayerIterator(int32_t id, size_t index);
+
+    struct cb_context;
+
+    static void hook_invalidate(const struct hwc_procs* procs);
+    static void hook_vsync(const struct hwc_procs* procs, int disp,
+            int64_t timestamp);
+    static void hook_hotplug(const struct hwc_procs* procs, int disp,
+            int connected);
+
+    inline void invalidate();
+    inline void vsync(int disp, int64_t timestamp);
+    inline void hotplug(int disp, int connected);
+
+    status_t queryDisplayProperties(int disp);
+
+    status_t setFramebufferTarget(int32_t id,
+            const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buf);
+
+    struct DisplayData {
+        DisplayData();
+        ~DisplayData();
+        Vector<DisplayConfig> configs;
+        size_t currentConfig;
+        uint32_t format;    // pixel format from FB hal, for pre-hwc-1.1
+        bool connected;
+        bool hasFbComp;
+        bool hasOvComp;
+        size_t capacity;
+        hwc_display_contents_1* list;
+        hwc_layer_1* framebufferTarget;
+        buffer_handle_t fbTargetHandle;
+        sp<Fence> lastRetireFence;  // signals when the last set op retires
+        sp<Fence> lastDisplayFence; // signals when the last set op takes
+                                    // effect on screen
+        buffer_handle_t outbufHandle;
+        sp<Fence> outbufAcquireFence;
+
+        // protected by mEventControlLock
+        int32_t events;
+
+        // We need to hold "copies" of these for memory management purposes. The
+        // actual hwc_layer_1_t holds pointers to the memory within. Vector<>
+        // internally doesn't copy the memory unless one of the copies is
+        // modified.
+        Vector<Region> visibleRegions;
+        Vector<Region> surfaceDamageRegions;
+    };
+
+    sp<SurfaceFlinger>              mFlinger;
+    framebuffer_device_t*           mFbDev;
+    struct hwc_composer_device_1*   mHwc;
+    // invariant: mLists[0] != NULL iff mHwc != NULL
+    // mLists[i>0] can be NULL. that display is to be ignored
+    struct hwc_display_contents_1*  mLists[MAX_HWC_DISPLAYS];
+    DisplayData                     mDisplayData[MAX_HWC_DISPLAYS];
+    // protect mDisplayData from races between prepare and dump
+    mutable Mutex mDisplayLock;
+    size_t                          mNumDisplays;
+
+    cb_context*                     mCBContext;
+    EventHandler&                   mEventHandler;
+    size_t                          mVSyncCounts[HWC_NUM_PHYSICAL_DISPLAY_TYPES];
+    sp<VSyncThread>                 mVSyncThread;
+    bool                            mDebugForceFakeVSync;
+    BitSet32                        mAllocatedDisplayIDs;
+
+    // protected by mLock
+    mutable Mutex mLock;
+    mutable nsecs_t mLastHwVSync[HWC_NUM_PHYSICAL_DISPLAY_TYPES];
+
+    // thread-safe
+    mutable Mutex mEventControlLock;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_SF_HWCOMPOSER_H
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index a9271c2..2190466 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -175,6 +175,12 @@
     return NO_ERROR;
 }
 
+#ifndef USE_HWC2
+status_t VirtualDisplaySurface::compositionComplete() {
+    return NO_ERROR;
+}
+#endif
+
 status_t VirtualDisplaySurface::advanceFrame() {
     if (mDisplayId < 0)
         return NO_ERROR;
@@ -214,9 +220,13 @@
 
     status_t result = NO_ERROR;
     if (fbBuffer != NULL) {
+#ifdef USE_HWC2
         // TODO: Correctly propagate the dataspace from GL composition
         result = mHwc.setClientTarget(mDisplayId, mFbFence, fbBuffer,
                 HAL_DATASPACE_UNKNOWN);
+#else
+        result = mHwc.fbPost(mDisplayId, mFbFence, fbBuffer);
+#endif
     }
 
     return result;
@@ -230,14 +240,22 @@
             "Unexpected onFrameCommitted() in %s state", dbgStateStr());
     mDbgState = DBG_STATE_IDLE;
 
+#ifdef USE_HWC2
     sp<Fence> retireFence = mHwc.getRetireFence(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);
     }
@@ -245,6 +263,9 @@
     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,
@@ -253,7 +274,11 @@
                         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(qbo);
@@ -263,7 +288,11 @@
             // 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 884460d..70f717f 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -83,6 +83,9 @@
     //
     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;
diff --git a/services/surfaceflinger/EventControlThread.cpp b/services/surfaceflinger/EventControlThread.cpp
index 26822c8..ee6e886 100644
--- a/services/surfaceflinger/EventControlThread.cpp
+++ b/services/surfaceflinger/EventControlThread.cpp
@@ -35,7 +35,12 @@
 
     bool vsyncEnabled = mVsyncEnabled;
 
+#ifdef USE_HWC2
     mFlinger->setVsyncEnabled(HWC_DISPLAY_PRIMARY, mVsyncEnabled);
+#else
+    mFlinger->eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC,
+            mVsyncEnabled);
+#endif
 
     while (true) {
         status_t err = mCond.wait(mMutex);
@@ -46,7 +51,12 @@
         }
 
         if (vsyncEnabled != mVsyncEnabled) {
+#ifdef USE_HWC2
             mFlinger->setVsyncEnabled(HWC_DISPLAY_PRIMARY, mVsyncEnabled);
+#else
+            mFlinger->eventControl(HWC_DISPLAY_PRIMARY,
+                    SurfaceFlinger::EVENT_VSYNC, mVsyncEnabled);
+#endif
             vsyncEnabled = mVsyncEnabled;
         }
     }
diff --git a/services/surfaceflinger/FenceTracker.cpp b/services/surfaceflinger/FenceTracker.cpp
index a3aaf42..0e18a93 100644
--- a/services/surfaceflinger/FenceTracker.cpp
+++ b/services/surfaceflinger/FenceTracker.cpp
@@ -141,6 +141,7 @@
 
         layers[i]->getFenceData(&name, &frameNumber, &glesComposition,
                 &postedTime, &acquireFence, &prevReleaseFence);
+#ifdef USE_HWC2
         if (glesComposition) {
             frame.layers.emplace(std::piecewise_construct,
                     std::forward_as_tuple(layerId),
@@ -157,6 +158,16 @@
                 prevLayer->second.releaseFence = prevReleaseFence;
             }
         }
+#else
+        frame.layers.emplace(std::piecewise_construct,
+                std::forward_as_tuple(layerId),
+                std::forward_as_tuple(name, frameNumber, glesComposition,
+                postedTime, 0, 0, acquireFence,
+                glesComposition ? Fence::NO_FENCE : prevReleaseFence));
+        if (glesComposition) {
+            wasGlesCompositionDone = true;
+        }
+#endif
         frame.layers.emplace(std::piecewise_construct,
                 std::forward_as_tuple(layerId),
                 std::forward_as_tuple(name, frameNumber, glesComposition,
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 9350fa5..6a3d62b 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -85,6 +85,9 @@
         mFiltering(false),
         mNeedsFiltering(false),
         mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
+#ifndef USE_HWC2
+        mIsGlesComposition(false),
+#endif
         mProtectedByApp(false),
         mHasSurface(false),
         mClientRef(client),
@@ -97,7 +100,9 @@
         mAutoRefresh(false),
         mFreezePositionUpdates(false)
 {
+#ifdef USE_HWC2
     ALOGV("Creating Layer %s", name.string());
+#endif
 
     mCurrentCrop.makeInvalid();
     mFlinger->getRenderEngine().genTextures(1, &mTextureName);
@@ -122,7 +127,11 @@
     mCurrentState.crop.makeInvalid();
     mCurrentState.finalCrop.makeInvalid();
     mCurrentState.z = 0;
+#ifdef USE_HWC2
     mCurrentState.alpha = 1.0f;
+#else
+    mCurrentState.alpha = 0xFF;
+#endif
     mCurrentState.layerStack = 0;
     mCurrentState.flags = layerFlags;
     mCurrentState.sequence = 0;
@@ -131,9 +140,14 @@
     // 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);
 }
 
@@ -176,12 +190,22 @@
 // callbacks
 // ---------------------------------------------------------------------------
 
+#ifdef USE_HWC2
 void Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
     if (mHwcLayers.empty()) {
         return;
     }
     mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
 }
+#else
+void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
+        HWComposer::HWCLayerInterface* layer) {
+    if (layer) {
+        layer->onDisplayed();
+        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
+    }
+}
+#endif
 
 void Layer::onFrameAvailable(const BufferItem& item) {
     // Add this buffer from our internal queue tracker
@@ -453,12 +477,23 @@
     return crop;
 }
 
+#ifdef USE_HWC2
 void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice)
+#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()) {
@@ -466,9 +501,17 @@
     }
 
     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
     if (!isOpaque(s) || s.alpha != 1.0f) {
         auto blendMode = mPremultipliedAlpha ?
                 HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
@@ -477,6 +520,13 @@
                 " %s (%d)", mName.string(), to_string(blendMode).c_str(),
                 to_string(error).c_str(), static_cast<int32_t>(error));
     }
+#else
+    if (!isOpaque(s) || s.alpha != 0xFF) {
+        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
@@ -484,7 +534,11 @@
     if (!s.crop.isEmpty()) {
         Rect activeCrop(s.crop);
         activeCrop = s.active.transform.transform(activeCrop);
+#ifdef USE_HWC2
         if(!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) {
+#else
+        if(!activeCrop.intersect(hw->getViewport(), &activeCrop)) {
+#endif
             activeCrop.clear();
         }
         activeCrop = s.active.transform.inverse().transform(activeCrop, true);
@@ -512,6 +566,7 @@
             frame.clear();
         }
     }
+#ifdef USE_HWC2
     if (!frame.intersect(displayDevice->getViewport(), &frame)) {
         frame.clear();
     }
@@ -547,6 +602,15 @@
     ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)",
             mName.string(), s.z, to_string(error).c_str(),
             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(s.alpha);
+#endif
 
     /*
      * Transformations are applied in this order:
@@ -577,6 +641,7 @@
 
     // 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;
@@ -587,8 +652,17 @@
                 "%s (%d)", mName.string(), to_string(transform).c_str(),
                 to_string(error).c_str(), static_cast<int32_t>(error));
     }
+#else
+    if (orientation & Transform::ROT_INVALID) {
+        // 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);
@@ -597,7 +671,9 @@
 
     mHwcLayers[hwcId].forceClientComposition = true;
 }
+#endif
 
+#ifdef USE_HWC2
 void Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
     // Apply this display's projection's viewport to the visible region
     // before giving it to the HWC HAL.
@@ -680,7 +756,31 @@
                 static_cast<int32_t>(error));
     }
 }
+#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 ||
@@ -714,6 +814,49 @@
             position.top, to_string(error).c_str(),
             static_cast<int32_t>(error));
 }
+#else
+void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
+        HWComposer::HWCLayerInterface& layer) {
+    int fenceFd = -1;
+
+    // TODO: there is a possible optimization here: we only need to set the
+    // acquire fence the first time a new buffer is acquired on EACH display.
+
+    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
+        sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
+        if (fence->isValid()) {
+            fenceFd = fence->dup();
+            if (fenceFd == -1) {
+                ALOGW("failed to dup layer fence, skipping sync: %d", errno);
+            }
+        }
+    }
+    layer.setAcquireFenceFd(fenceFd);
+}
+
+Rect Layer::getPosition(
+    const sp<const DisplayDevice>& hw)
+{
+    // 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(s.active.transform.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...
@@ -898,6 +1041,7 @@
     engine.disableBlending();
 }
 
+#ifdef USE_HWC2
 void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type,
         bool callIntoHwc) {
     if (mHwcLayers.count(hwcId) == 0) {
@@ -949,6 +1093,7 @@
     }
     return mHwcLayers.at(hwcId).clearClientTarget;
 }
+#endif
 
 uint32_t Layer::getProducerStickyTransform() const {
     int producerStickyTransform = 0;
@@ -985,6 +1130,7 @@
 }
 
 bool Layer::headFenceHasSignaled() const {
+#ifdef USE_HWC2
     if (latchUnsignaledBuffers()) {
         return true;
     }
@@ -1001,6 +1147,9 @@
         return true;
     }
     return mQueueItems[0].mFence->getSignalTime() != INT64_MAX;
+#else
+    return true;
+#endif
 }
 
 bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
@@ -1440,7 +1589,11 @@
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
+#ifdef USE_HWC2
 bool Layer::setAlpha(float alpha) {
+#else
+bool Layer::setAlpha(uint8_t alpha) {
+#endif
     if (mCurrentState.alpha == alpha)
         return false;
     mCurrentState.sequence++;
@@ -1595,7 +1748,11 @@
         }
 
         const HWComposer& hwc = mFlinger->getHwComposer();
+#ifdef USE_HWC2
         sp<Fence> presentFence = hwc.getRetireFence(HWC_DISPLAY_PRIMARY);
+#else
+        sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
+#endif
         if (presentFence->isValid()) {
             mFrameTracker.setActualPresentFence(presentFence);
         } else {
@@ -1611,14 +1768,21 @@
     return frameLatencyNeeded;
 }
 
+#ifdef USE_HWC2
 void Layer::releasePendingBuffer() {
     mSurfaceFlingerConsumer->releasePendingBuffer();
 }
+#endif
 
 bool Layer::isVisible() const {
     const Layer::State& s(mDrawingState);
+#ifdef USE_HWC2
     return !(s.flags & layer_state_t::eLayerHidden) && s.alpha > 0.0f
             && (mActiveBuffer != NULL || mSidebandStream != NULL);
+#else
+    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
+            && (mActiveBuffer != NULL || mSidebandStream != NULL);
+#endif
 }
 
 Region Layer::latchBuffer(bool& recomputeVisibleRegions)
@@ -2022,7 +2186,11 @@
             "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), "
             "crop=(%4d,%4d,%4d,%4d), finalCrop=(%4d,%4d,%4d,%4d), "
             "isOpaque=%1d, invalidate=%1d, "
+#ifdef USE_HWC2
             "alpha=%.3f, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
+#else
+            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
+#endif
             "      client=%p\n",
             s.layerStack, s.z, s.active.transform.tx(), s.active.transform.ty(), s.active.w, s.active.h,
             s.crop.left, s.crop.top,
@@ -2055,6 +2223,7 @@
     }
 }
 
+#ifdef USE_HWC2
 void Layer::miniDumpHeader(String8& result) {
     result.append("----------------------------------------");
     result.append("---------------------------------------\n");
@@ -2100,6 +2269,7 @@
     result.append("- - - - - - - - - - - - - - - - - - - - ");
     result.append("- - - - - - - - - - - - - - - - - - - -\n");
 }
+#endif
 
 void Layer::dumpFrameStats(String8& result) const {
     mFrameTracker.dumpStats(result);
@@ -2123,9 +2293,13 @@
     *outName = mName;
     *outFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
 
+#ifdef USE_HWC2
     *outIsGlesComposition = mHwcLayers.count(HWC_DISPLAY_PRIMARY) ?
             mHwcLayers.at(HWC_DISPLAY_PRIMARY).compositionType ==
             HWC2::Composition::Client : true;
+#else
+    *outIsGlesComposition = mIsGlesComposition;
+#endif
     *outPostedTime = mSurfaceFlingerConsumer->getTimestamp();
     *outAcquireFence = mSurfaceFlingerConsumer->getCurrentFence();
     *outPrevReleaseFence = mSurfaceFlingerConsumer->getPrevReleaseFence();
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 59129c7..efb0fb8 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -110,7 +110,11 @@
         Geometry requested;
         uint32_t z;
         uint32_t layerStack;
+#ifdef USE_HWC2
         float alpha;
+#else
+        uint8_t alpha;
+#endif
         uint8_t flags;
         uint8_t mask;
         uint8_t reserved[2];
@@ -148,7 +152,11 @@
     bool setPosition(float x, float y, bool immediate);
     bool setLayer(uint32_t z);
     bool setSize(uint32_t w, uint32_t h);
+#ifdef USE_HWC2
     bool setAlpha(float alpha);
+#else
+    bool setAlpha(uint8_t alpha);
+#endif
     bool setMatrix(const layer_state_t::matrix22_t& matrix);
     bool setTransparentRegionHint(const Region& transparent);
     bool setFlags(uint8_t flags, uint8_t mask);
@@ -220,6 +228,7 @@
 public:
     // -----------------------------------------------------------------------
 
+#ifdef USE_HWC2
     void setGeometry(const sp<const DisplayDevice>& displayDevice);
     void forceClientComposition(int32_t hwcId);
     void setPerFrameData(const sp<const DisplayDevice>& displayDevice);
@@ -234,11 +243,26 @@
     bool getClearClientTarget(int32_t hwcId) const;
 
     void updateCursorPosition(const sp<const DisplayDevice>& hw);
+#else
+    void setGeometry(const sp<const DisplayDevice>& hw,
+            HWComposer::HWCLayerInterface& layer);
+    void setPerFrameData(const sp<const DisplayDevice>& hw,
+            HWComposer::HWCLayerInterface& layer);
+    void setAcquireFence(const sp<const DisplayDevice>& hw,
+            HWComposer::HWCLayerInterface& layer);
+
+    Rect getPosition(const sp<const DisplayDevice>& hw);
+#endif
 
     /*
      * called after page-flip
      */
+#ifdef USE_HWC2
     void onLayerDisplayed(const sp<Fence>& releaseFence);
+#else
+    void onLayerDisplayed(const sp<const DisplayDevice>& hw,
+            HWComposer::HWCLayerInterface* layer);
+#endif
 
     bool shouldPresentNow(const DispSync& dispSync) const;
 
@@ -254,8 +278,10 @@
      */
     bool onPostComposition();
 
+#ifdef USE_HWC2
     // If a buffer was replaced this frame, release the former buffer
     void releasePendingBuffer();
+#endif
 
     /*
      * draw - performs some global clipping optimizations
@@ -324,6 +350,7 @@
     bool hasQueuedFrame() const { return mQueuedFrames > 0 ||
             mSidebandStreamChanged || mAutoRefresh; }
 
+#ifdef USE_HWC2
     // -----------------------------------------------------------------------
 
     bool hasHwcLayer(int32_t hwcId) {
@@ -353,6 +380,7 @@
         }
     }
 
+#endif
     // -----------------------------------------------------------------------
 
     void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
@@ -369,8 +397,10 @@
 
     /* always call base class first */
     void dump(String8& result, Colorizer& colorizer) const;
+#ifdef USE_HWC2
     static void miniDumpHeader(String8& result);
     void miniDump(String8& result, int32_t hwcId) const;
+#endif
     void dumpFrameStats(String8& result) const;
     void clearFrameStats();
     void logFrameStats();
@@ -571,6 +601,7 @@
     // The texture used to draw the layer in GLES composition mode
     mutable Texture mTexture;
 
+#ifdef USE_HWC2
     // HWC items, accessed from the main thread
     struct HWCInfo {
         HWCInfo()
@@ -587,6 +618,9 @@
         FloatRect sourceCrop;
     };
     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/RenderEngine/GLES10RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES10RenderEngine.cpp
index 00b1cd2..579affb 100644
--- a/services/surfaceflinger/RenderEngine/GLES10RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES10RenderEngine.cpp
@@ -28,25 +28,43 @@
 }
 
 void GLES10RenderEngine::setupLayerBlending(
+#ifdef USE_HWC2
     bool premultipliedAlpha, bool opaque, float alpha) {
+#else
+    bool premultipliedAlpha, bool opaque, int alpha) {
+#endif
     // OpenGL ES 1.0 doesn't support texture combiners.
     // This path doesn't properly handle opaque layers that have non-opaque
     // alpha values. The alpha channel will be copied into the framebuffer or
     // screenshot, so if the framebuffer or screenshot is blended on top of
     // something else,  whatever is below the window will incorrectly show
     // through.
+#ifdef USE_HWC2
     if (CC_UNLIKELY(alpha < 1.0f)) {
         if (premultipliedAlpha) {
             glColor4f(alpha, alpha, alpha, alpha);
         } else {
             glColor4f(1.0f, 1.0f, 1.0f, alpha);
         }
+#else
+    if (CC_UNLIKELY(alpha < 0xFF)) {
+        GLfloat floatAlpha = alpha * (1.0f / 255.0f);
+        if (premultipliedAlpha) {
+            glColor4f(floatAlpha, floatAlpha, floatAlpha, floatAlpha);
+        } else {
+            glColor4f(1.0f, 1.0f, 1.0f, floatAlpha);
+        }
+#endif
         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
     } else {
         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
     }
 
+#ifdef USE_HWC2
     if (alpha < 1.0f || !opaque) {
+#else
+    if (alpha < 0xFF || !opaque) {
+#endif
         glEnable(GL_BLEND);
         glBlendFunc(premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA,
                     GL_ONE_MINUS_SRC_ALPHA);
diff --git a/services/surfaceflinger/RenderEngine/GLES10RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES10RenderEngine.h
index c416408..61abd6a 100644
--- a/services/surfaceflinger/RenderEngine/GLES10RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES10RenderEngine.h
@@ -30,8 +30,12 @@
 class GLES10RenderEngine : public GLES11RenderEngine {
     virtual ~GLES10RenderEngine();
 protected:
+#ifdef USE_HWC2
     virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque,
             float alpha) override;
+#else
+    virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha);
+#endif
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
index a6d66f7..847cdb3 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
@@ -107,20 +107,33 @@
     glMatrixMode(GL_MODELVIEW);
 }
 
+#ifdef USE_HWC2
 void GLES11RenderEngine::setupLayerBlending(bool premultipliedAlpha,
         bool opaque, float alpha) {
+#else
+void GLES11RenderEngine::setupLayerBlending(
+    bool premultipliedAlpha, bool opaque, int alpha) {
+#endif
     GLenum combineRGB;
     GLenum combineAlpha;
     GLenum src0Alpha;
     GLfloat envColor[4];
 
+#ifdef USE_HWC2
     if (CC_UNLIKELY(alpha < 1.0f)) {
+#else
+    if (CC_UNLIKELY(alpha < 0xFF)) {
+#endif
         // Cv = premultiplied ? Cs*alpha : Cs
         // Av = !opaque       ? As*alpha : As
         combineRGB   = premultipliedAlpha ? GL_MODULATE : GL_REPLACE;
         combineAlpha = !opaque            ? GL_MODULATE : GL_REPLACE;
         src0Alpha    = GL_CONSTANT;
+#ifdef USE_HWC2
         envColor[0]  = alpha;
+#else
+        envColor[0]  = alpha * (1.0f / 255.0f);
+#endif
     } else {
         // Cv = Cs
         // Av = opaque ? 1.0 : As
@@ -152,7 +165,11 @@
         glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, envColor);
     }
 
+#ifdef USE_HWC2
     if (alpha < 1.0f || !opaque) {
+#else
+    if (alpha < 0xFF || !opaque) {
+#endif
         glEnable(GL_BLEND);
         glBlendFunc(premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA,
                     GL_ONE_MINUS_SRC_ALPHA);
@@ -161,16 +178,28 @@
     }
 }
 
+#ifdef USE_HWC2
 void GLES11RenderEngine::setupDimLayerBlending(float alpha) {
+#else
+void GLES11RenderEngine::setupDimLayerBlending(int alpha) {
+#endif
     glDisable(GL_TEXTURE_EXTERNAL_OES);
     glDisable(GL_TEXTURE_2D);
+#ifdef USE_HWC2
     if (alpha == 1.0f) {
+#else
+    if (alpha == 0xFF) {
+#endif
         glDisable(GL_BLEND);
     } else {
         glEnable(GL_BLEND);
         glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
     }
+#ifdef USE_HWC2
     glColor4f(0, 0, 0, alpha);
+#else
+    glColor4f(0, 0, 0, alpha/255.0f);
+#endif
 }
 
 void GLES11RenderEngine::setupLayerTexturing(const Texture& texture) {
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
index fdaa533..4cd968d 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
@@ -53,9 +53,15 @@
     virtual void setViewportAndProjection(size_t vpw, size_t vph,
             Rect sourceCrop, size_t hwh, bool yswap,
             Transform::orientation_flags rotation);
+#ifdef USE_HWC2
     virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque,
             float alpha) override;
     virtual void setupDimLayerBlending(float alpha) override;
+#else
+    virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque,
+            int alpha);
+    virtual void setupDimLayerBlending(int alpha);
+#endif
     virtual void setupLayerTexturing(const Texture& texture);
     virtual void setupLayerBlackedOut();
     virtual void setupFillWithColor(float r, float g, float b, float a) ;
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 2503b27..406e611 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -117,14 +117,25 @@
     mVpHeight = vph;
 }
 
+#ifdef USE_HWC2
 void GLES20RenderEngine::setupLayerBlending(bool premultipliedAlpha,
         bool opaque, float alpha) {
+#else
+void GLES20RenderEngine::setupLayerBlending(
+    bool premultipliedAlpha, bool opaque, int alpha) {
+#endif
 
     mState.setPremultipliedAlpha(premultipliedAlpha);
     mState.setOpaque(opaque);
+#ifdef USE_HWC2
     mState.setPlaneAlpha(alpha);
 
     if (alpha < 1.0f || !opaque) {
+#else
+    mState.setPlaneAlpha(alpha / 255.0f);
+
+    if (alpha < 0xFF || !opaque) {
+#endif
         glEnable(GL_BLEND);
         glBlendFunc(premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     } else {
@@ -132,14 +143,26 @@
     }
 }
 
+#ifdef USE_HWC2
 void GLES20RenderEngine::setupDimLayerBlending(float alpha) {
+#else
+void GLES20RenderEngine::setupDimLayerBlending(int alpha) {
+#endif
     mState.setPlaneAlpha(1.0f);
     mState.setPremultipliedAlpha(true);
     mState.setOpaque(false);
+#ifdef USE_HWC2
     mState.setColor(0, 0, 0, alpha);
+#else
+    mState.setColor(0, 0, 0, alpha/255.0f);
+#endif
     mState.disableTexture();
 
+#ifdef USE_HWC2
     if (alpha == 1.0f) {
+#else
+    if (alpha == 0xFF) {
+#endif
         glDisable(GL_BLEND);
     } else {
         glEnable(GL_BLEND);
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index 735e174..7c3f9b5 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -68,9 +68,15 @@
     virtual void setViewportAndProjection(size_t vpw, size_t vph,
             Rect sourceCrop, size_t hwh, bool yswap,
             Transform::orientation_flags rotation);
+#ifdef USE_HWC2
     virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque,
             float alpha) override;
     virtual void setupDimLayerBlending(float alpha) override;
+#else
+    virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque,
+            int alpha);
+    virtual void setupDimLayerBlending(int alpha);
+#endif
     virtual void setupLayerTexturing(const Texture& texture);
     virtual void setupLayerBlackedOut();
     virtual void setupFillWithColor(float r, float g, float b, float a);
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index bd45bae..0259881 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -95,8 +95,13 @@
     virtual void checkErrors() const;
     virtual void setViewportAndProjection(size_t vpw, size_t vph,
             Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation) = 0;
+#ifdef USE_HWC2
     virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, float alpha) = 0;
     virtual void setupDimLayerBlending(float alpha) = 0;
+#else
+    virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha) = 0;
+    virtual void setupDimLayerBlending(int alpha) = 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.h b/services/surfaceflinger/SurfaceFlinger.h
index 9c37223..6449e57 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -129,7 +129,11 @@
 
     // 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
@@ -377,6 +381,10 @@
     // region of all screens presenting this layer stack.
     void invalidateLayerStack(uint32_t layerStack, const Region& dirty);
 
+#ifndef USE_HWC2
+    int32_t allocateHwcDisplayId(DisplayDevice::DisplayType type);
+#endif
+
     /* ------------------------------------------------------------------------
      * H/W composer
      */
@@ -482,11 +490,17 @@
     // don't need synchronization
     State mDrawingState;
     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
 
     // this may only be written from the main thread with mStateLock held
     // it may be read from other threads with mStateLock held
@@ -504,7 +518,9 @@
     bool mBootFinished;
     bool mForceFullDamage;
     FenceTracker mFenceTracker;
+#ifdef USE_HWC2
     bool mPropagateBackpressure = true;
+#endif
     SurfaceInterceptor mInterceptor;
     bool mUseHwcVirtualDisplays = true;
 
@@ -529,6 +545,9 @@
     bool mInjectVSyncs;
 
     Daltonizer mDaltonizer;
+#ifndef USE_HWC2
+    bool mDaltonize;
+#endif
 
     mat4 mPreviousColorMatrix;
     mat4 mColorMatrix;
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index eb78b67..e0e4c61 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -88,7 +88,11 @@
     }
 
     // Release the previous buffer.
+#ifdef USE_HWC2
     err = updateAndReleaseLocked(item, &mPendingRelease);
+#else
+    err = updateAndReleaseLocked(item);
+#endif
     if (err != NO_ERROR) {
         return err;
     }
@@ -185,6 +189,7 @@
     return nextRefresh + extraPadding;
 }
 
+#ifdef USE_HWC2
 void SurfaceFlingerConsumer::setReleaseFence(const sp<Fence>& fence)
 {
     mPrevReleaseFence = fence;
@@ -217,6 +222,12 @@
             strerror(-result), result);
     mPendingRelease = PendingRelease();
 }
+#else
+void SurfaceFlingerConsumer::setReleaseFence(const sp<Fence>& fence) {
+    mPrevReleaseFence = fence;
+    GLConsumer::setReleaseFence(fence);
+}
+#endif
 
 sp<Fence> SurfaceFlingerConsumer::getPrevReleaseFence() const {
     return mPrevReleaseFence;
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index 0f9a0b4..4271039 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -81,7 +81,9 @@
 
     virtual void setReleaseFence(const sp<Fence>& fence) override;
     sp<Fence> getPrevReleaseFence() const;
+#ifdef USE_HWC2
     void releasePendingBuffer();
+#endif
 
     virtual bool getFrameTimestamps(uint64_t frameNumber,
             FrameTimestamps* outTimestamps) const override;
@@ -99,9 +101,11 @@
     // 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 release fence of the already displayed buffer (previous frame).
     sp<Fence> mPrevReleaseFence;
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
new file mode 100644
index 0000000..3ae2c04
--- /dev/null
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -0,0 +1,3827 @@
+/*
+ * 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 <stdint.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <math.h>
+#include <mutex>
+#include <dlfcn.h>
+#include <inttypes.h>
+#include <stdatomic.h>
+
+#include <EGL/egl.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/MemoryHeapBase.h>
+#include <binder/PermissionCache.h>
+
+#include <ui/DisplayInfo.h>
+#include <ui/DisplayStatInfo.h>
+
+#include <gui/BitTube.h>
+#include <gui/BufferQueue.h>
+#include <gui/GuiConfig.h>
+#include <gui/IDisplayEventConnection.h>
+#include <gui/Surface.h>
+#include <gui/GraphicBufferAlloc.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 "LayerDim.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>
+
+#define DISPLAY_COUNT       1
+
+/*
+ * DEBUG_SCREENSHOTS: set to true to check that screenshots are not all
+ * black pixels.
+ */
+#define DEBUG_SCREENSHOTS   false
+
+EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
+
+// Workaround for b/30067360: /proc/self/environ inaccessible in SurfaceFlinger
+// => ASan fails to read ASAN_OPTIONS => alloc-dealloc-mismatch bug is not
+// suppressed and prevents the device from booting.
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+#if __has_feature(address_sanitizer)
+__attribute__((visibility("default")))
+extern "C" const char *__asan_default_options() {
+  return "alloc_dealloc_mismatch=0";
+}
+#endif
+
+namespace android {
+
+// This is the phase offset in nanoseconds of the software vsync event
+// relative to the vsync event reported by HWComposer.  The software vsync
+// event is when SurfaceFlinger and Choreographer-based applications run each
+// frame.
+//
+// This phase offset allows adjustment of the minimum latency from application
+// wake-up (by Choregographer) time to the time at which the resulting window
+// image is displayed.  This value may be either positive (after the HW vsync)
+// or negative (before the HW vsync).  Setting it to 0 will result in a
+// minimum latency of two vsync periods because the app and SurfaceFlinger
+// will run just after the HW vsync.  Setting it to a positive number will
+// result in the minimum latency being:
+//
+//     (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD))
+//
+// Note that reducing this latency makes it more likely for the applications
+// to not have their window content image ready in time.  When this happens
+// the latency will end up being an additional vsync period, and animations
+// will hiccup.  Therefore, this latency should be tuned somewhat
+// conservatively (or at least with awareness of the trade-off being made).
+static const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS;
+
+// This is the phase offset at which SurfaceFlinger's composition runs.
+static const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS;
+
+// ---------------------------------------------------------------------------
+
+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");
+
+// ---------------------------------------------------------------------------
+
+SurfaceFlinger::SurfaceFlinger()
+    :   BnSurfaceComposer(),
+        mTransactionFlags(0),
+        mTransactionPending(false),
+        mAnimTransactionPending(false),
+        mLayersRemoved(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(),
+        mPrimaryDispSync("PrimaryDispSync"),
+        mPrimaryHWVsyncEnabled(false),
+        mHWVsyncAvailable(false),
+        mDaltonize(false),
+        mHasColorMatrix(false),
+        mHasPoweredOff(false),
+        mFrameBuckets(),
+        mTotalTime(0),
+        mLastSwapTime(0)
+{
+    ALOGI("SurfaceFlinger is starting");
+
+    // debugging stuff...
+    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.disable_hwc_vds", value, "0");
+    mUseHwcVirtualDisplays = !atoi(value);
+    ALOGI_IF(!mUseHwcVirtualDisplays, "Disabling HWC virtual displays");
+}
+
+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();
+}
+
+sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
+{
+    sp<ISurfaceComposerClient> bclient;
+    sp<Client> client(new Client(this));
+    status_t err = client->initCheck();
+    if (err == NO_ERROR) {
+        bclient = client;
+    }
+    return bclient;
+}
+
+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];
+}
+
+sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
+{
+    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
+    return gba;
+}
+
+void SurfaceFlinger::bootFinished()
+{
+    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;
+};
+
+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 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");
+    }
+
+
+    // Initialize the H/W composer object.  There may or may not be an
+    // actual hardware composer underneath.
+    mHwc = 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());
+
+    // 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,
+                    new GraphicBufferAlloc());
+
+            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());
+            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)
+    getDefaultDisplayDevice()->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();
+
+    // start boot animation
+    startBootAnim();
+}
+
+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
+    property_set("service.bootanim.exit", "0");
+    property_set("ctl.start", "bootanim");
+}
+
+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);
+    sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
+    return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
+}
+
+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 = VSYNC_EVENT_PHASE_OFFSET_NS;
+
+        // 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 - SF_VSYNC_EVENT_PHASE_OFFSET_NS + 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<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;
+}
+
+// ----------------------------------------------------------------------------
+
+sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
+    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(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::onHotplugReceived(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::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(eTransactionMask);
+    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();
+    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()
+{
+    bool needExtraInvalidate = false;
+    const LayerVector& layers(mDrawingState.layersSortedByZ);
+    const size_t count = layers.size();
+    for (size_t i=0 ; i<count ; i++) {
+        if (layers[i]->onPreComposition()) {
+            needExtraInvalidate = true;
+        }
+    }
+    if (needExtraInvalidate) {
+        signalLayerUpdate();
+    }
+}
+
+void SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
+{
+    const LayerVector& layers(mDrawingState.layersSortedByZ);
+    const size_t count = layers.size();
+    for (size_t i=0 ; i<count ; i++) {
+        bool frameLatched = layers[i]->onPostComposition();
+        if (frameLatched) {
+            recordBufferingStats(layers[i]->getName().string(),
+                    layers[i]->getOccupancyHistory(false));
+        }
+    }
+
+    const HWComposer& hwc = getHwComposer();
+    sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
+
+    if (presentFence->isValid()) {
+        if (mPrimaryDispSync.addPresentFence(presentFence)) {
+            enableHardwareVsync();
+        } else {
+            disableHardwareVsync(false);
+        }
+    }
+
+    const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+    if (kIgnorePresentFences) {
+        if (hw->isDisplayOn()) {
+            enableHardwareVsync();
+        }
+    }
+
+    mFenceTracker.addFrame(refreshStartTime, presentFence,
+            hw->getVisibleLayersSortedByZ(), hw->getClientTargetAcquireFence());
+
+    if (mAnimCompositionPending) {
+        mAnimCompositionPending = false;
+
+        if (presentFence->isValid()) {
+            mAnimFrameTracker.setActualPresentFence(presentFence);
+        } 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();
+
+        const LayerVector& layers(mDrawingState.layersSortedByZ);
+        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()) {
+                SurfaceFlinger::computeVisibleRegions(layers,
+                        hw->getLayerStack(), dirtyRegion, opaqueRegion);
+
+                const size_t count = layers.size();
+                for (size_t i=0 ; i<count ; i++) {
+                    const sp<Layer>& layer(layers[i]);
+                    const Layer::State& s(layer->getDrawingState());
+                    if (s.layerStack == 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)
+{
+    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
+    const size_t count = currentLayers.size();
+
+    // Notify all layers of available frames
+    for (size_t i = 0; i < count; ++i) {
+        currentLayers[i]->notifyAvailableFrames();
+    }
+
+    /*
+     * Traversal of the children
+     * (perform the transaction for each of them if needed)
+     */
+
+    if (transactionFlags & eTraversalNeeded) {
+        for (size_t i=0 ; i<count ; i++) {
+            const sp<Layer>& layer(currentLayers[i]);
+            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
+            if (!trFlags) continue;
+
+            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(getDefaultDisplayDevice());
+                        defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
+                        sp<DisplayDevice> hw(getDisplayDevice(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(getDisplayDevice(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(getDisplayDevice(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,
+                            new GraphicBufferAlloc());
+
+                    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 &&
+                                    (MAX_VIRTUAL_DISPLAY_DIMENSION == 0 ||
+                                    (width <= MAX_VIRTUAL_DISPLAY_DIMENSION &&
+                                     height <= MAX_VIRTUAL_DISPLAY_DIMENSION))) {
+                                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());
+                        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;
+        for (size_t i=0; i<count; i++) {
+            // 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).
+            const sp<Layer>& layer(currentLayers[i]);
+            uint32_t layerStack = layer->getDrawingState().layerStack;
+            if (i==0 || 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 = getDefaultDisplayDevice();
+            }
+            layer->updateTransformHint(disp);
+        }
+    }
+
+
+    /*
+     * Perform our own transaction if needed
+     */
+
+    const LayerVector& layers(mDrawingState.layersSortedByZ);
+    if (currentLayers.size() > layers.size()) {
+        // 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;
+        const size_t count = layers.size();
+        for (size_t i=0 ; i<count ; i++) {
+            const sp<Layer>& layer(layers[i]);
+            if (currentLayers.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
+                const Layer::State& s(layer->getDrawingState());
+                Region visibleReg = s.active.transform.transform(
+                        Region(Rect(s.active.w, s.active.h)));
+                invalidateLayerStack(s.layerStack, 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 (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
+            recordBufferingStats(mLayersPendingRemoval[i]->getName().string(),
+                    mLayersPendingRemoval[i]->getOccupancyHistory(true));
+            mLayersPendingRemoval[i]->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;
+    mTransactionPending = false;
+    mAnimTransactionPending = false;
+    mTransactionCV.broadcast();
+}
+
+void SurfaceFlinger::computeVisibleRegions(
+        const LayerVector& currentLayers, uint32_t layerStack,
+        Region& outDirtyRegion, Region& outOpaqueRegion)
+{
+    ATRACE_CALL();
+
+    Region aboveOpaqueLayers;
+    Region aboveCoveredLayers;
+    Region dirty;
+
+    outDirtyRegion.clear();
+
+    size_t i = currentLayers.size();
+    while (i--) {
+        const sp<Layer>& layer = currentLayers[i];
+
+        // 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 (s.layerStack != layerStack)
+            continue;
+
+        /*
+         * 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(s.active.transform.transform(layer->computeBounds()));
+            visibleRegion.set(bounds);
+            if (!visibleRegion.isEmpty()) {
+                // Remove the transparent area from the visible region
+                if (translucent) {
+                    const Transform tr(s.active.transform);
+                    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 = s.active.transform.getOrientation();
+                if (s.alpha==255 && !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(uint32_t layerStack,
+        const Region& dirty) {
+    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()
+{
+    Region dirtyRegion;
+
+    bool visibleRegions = false;
+    const LayerVector& layers(mDrawingState.layersSortedByZ);
+    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;
+    for (size_t i = 0, count = layers.size(); i<count ; i++) {
+        const sp<Layer>& layer(layers[i]);
+        if (layer->hasQueuedFrame()) {
+            frameQueued = true;
+            if (layer->shouldPresentNow(mPrimaryDispSync)) {
+                layersWithQueuedFrames.push_back(layer.get());
+            } 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));
+        layer->useSurfaceDamage();
+        const Layer::State& s(layer->getDrawingState());
+        invalidateLayerStack(s.layerStack, 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)
+{
+    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.alpha == 0xFF)
+                                && hasGlesComposition) {
+                            // never clear the very first layer since we're
+                            // guaranteed the FB is already cleared
+                            layer->clearWithOpenGL(hw, clip);
+                        }
+                        break;
+                    }
+                    case HWC_FRAMEBUFFER: {
+                        layer->draw(hw, 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(hw, 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)
+{
+    // add this layer to the current state list
+    {
+        Mutex::Autolock _l(mStateLock);
+        if (mCurrentState.layersSortedByZ.size() >= MAX_LAYERS) {
+            return NO_MEMORY;
+        }
+        mCurrentState.layersSortedByZ.add(lbc);
+        mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
+    }
+
+    // attach this layer to the client
+    client->attachLayer(handle, lbc);
+
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
+    Mutex::Autolock _l(mStateLock);
+    sp<Layer> layer = weakLayer.promote();
+    if (layer == nullptr) {
+        // The layer has already been removed, carry on
+        return NO_ERROR;
+    }
+
+    ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
+    if (index >= 0) {
+        mLayersPendingRemoval.push(layer);
+        mLayersRemoved = true;
+        setTransactionFlags(eTransactionNeeded);
+        return NO_ERROR;
+    }
+    return status_t(index);
+}
+
+uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) {
+    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) {
+                String16 desc(binder->getInterfaceDescriptor());
+                if (desc == ISurfaceComposerClient::descriptor) {
+                    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
+            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;
+            }
+        }
+        if (what & layer_state_t::eSizeChanged) {
+            if (layer->setSize(s.w, s.h)) {
+                flags |= eTraversalNeeded;
+            }
+        }
+        if (what & layer_state_t::eAlphaChanged) {
+            if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
+                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))
+                flags |= eTraversalNeeded;
+        }
+        if (what & layer_state_t::eLayerStackChanged) {
+            // NOTE: index needs to be calculated before we update the state
+            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
+            if (layer->setLayerStack(s.layerStack) && idx >= 0) {
+                mCurrentState.layersSortedByZ.removeAt(idx);
+                mCurrentState.layersSortedByZ.add(layer);
+                // we need traversal (state changed)
+                // AND transaction (list changed)
+                flags |= eTransactionNeeded|eTraversalNeeded;
+            }
+        }
+        if (what & layer_state_t::eDeferTransaction) {
+            layer->deferTransactionUntil(s.handle, s.frameNumber);
+            // 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::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,
+        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
+{
+    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;
+
+    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
+        case ISurfaceComposerClient::eFXSurfaceNormal:
+            result = createNormalLayer(client,
+                    name, w, h, flags, format,
+                    handle, gbp, &layer);
+            break;
+        case ISurfaceComposerClient::eFXSurfaceDim:
+            result = createDimLayer(client,
+                    name, w, h, flags,
+                    handle, gbp, &layer);
+            break;
+        default:
+            result = BAD_VALUE;
+            break;
+    }
+
+    if (result != NO_ERROR) {
+        return result;
+    }
+
+    result = addClientLayer(client, *handle, *gbp, layer);
+    if (result != NO_ERROR) {
+        return result;
+    }
+    mInterceptor.saveSurfaceCreation(layer);
+
+    setTransactionFlags(eTransactionNeeded);
+    return result;
+}
+
+status_t SurfaceFlinger::createNormalLayer(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;
+    }
+
+    *outLayer = new Layer(this, client, name, w, h, flags);
+    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
+    if (err == NO_ERROR) {
+        *handle = (*outLayer)->getHandle();
+        *gbp = (*outLayer)->getProducer();
+    }
+
+    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
+    return err;
+}
+
+status_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
+        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
+        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
+{
+    *outLayer = new LayerDim(this, client, name, w, h, flags);
+    *handle = (*outLayer)->getHandle();
+    *gbp = (*outLayer)->getProducer();
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
+{
+    // called by the window manager 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
+    return removeLayer(layer);
+}
+
+// ---------------------------------------------------------------------------
+
+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);
+}
+
+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) {
+            // 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) {
+            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 {
+        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::dump(int fd, const Vector<String16>& args)
+{
+    String8 result;
+
+    IPCThreadState* ipc = IPCThreadState::self();
+    const int pid = ipc->getCallingPid();
+    const int uid = ipc->getCallingUid();
+    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("--fences"))) {
+                index++;
+                mFenceTracker.dump(&result);
+                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
+{
+    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+    const size_t count = currentLayers.size();
+    for (size_t i=0 ; i<count ; i++) {
+        const sp<Layer>& layer(currentLayers[i]);
+        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 {
+        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+        const size_t count = currentLayers.size();
+        for (size_t i=0 ; i<count ; i++) {
+            const sp<Layer>& layer(currentLayers[i]);
+            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++;
+    }
+
+    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+    const size_t count = currentLayers.size();
+    for (size_t i=0 ; i<count ; i++) {
+        const sp<Layer>& layer(currentLayers[i]);
+        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() {
+    const LayerVector& drawingLayers = mDrawingState.layersSortedByZ;
+    const size_t count = drawingLayers.size();
+    for (size_t i=0 ; i<count ; i++) {
+        const sp<Layer>& layer(drawingLayers[i]);
+        layer->logFrameStats();
+    }
+
+    mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
+}
+
+/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result)
+{
+    static const char* config =
+            " [sf"
+#ifdef HAS_CONTEXT_PRIORITY
+            " HAS_CONTEXT_PRIORITY"
+#endif
+#ifdef NEVER_DEFAULT_TO_ASYNC_MODE
+            " NEVER_DEFAULT_TO_ASYNC_MODE"
+#endif
+#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
+            " TARGET_DISABLE_TRIPLE_BUFFERING"
+#endif
+            "]";
+    result.append(config);
+}
+
+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::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");
+}
+
+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 %d ns (refresh %" PRId64 " ns)",
+        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, PRESENT_TIME_OFFSET_FROM_VSYNC_NS,
+        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
+     */
+    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+    const size_t count = currentLayers.size();
+    colorizer.bold(result);
+    result.appendFormat("Visible layers (count = %zu)\n", count);
+    colorizer.reset(result);
+    for (size_t i=0 ; i<count ; i++) {
+        const sp<Layer>& layer(currentLayers[i]);
+        layer->dump(result, colorizer);
+    }
+
+    /*
+     * 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(getDefaultDisplayDevice());
+
+    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 getDisplayDevice(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 SET_TRANSACTION_STATE:
+        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;
+        }
+        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;
+        }
+    }
+
+    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,
+        uint32_t minLayerZ, uint32_t maxLayerZ,
+        bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
+
+    if (CC_UNLIKELY(display == 0))
+        return BAD_VALUE;
+
+    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();
+
+    // Convert to surfaceflinger's internal rotation type.
+    Transform::orientation_flags rotationFlags;
+    switch (rotation) {
+        case ISurfaceComposer::eRotateNone:
+            rotationFlags = Transform::ROT_0;
+            break;
+        case ISurfaceComposer::eRotate90:
+            rotationFlags = Transform::ROT_90;
+            break;
+        case ISurfaceComposer::eRotate180:
+            rotationFlags = Transform::ROT_180;
+            break;
+        case ISurfaceComposer::eRotate270:
+            rotationFlags = Transform::ROT_270;
+            break;
+        default:
+            rotationFlags = Transform::ROT_0;
+            ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
+            break;
+    }
+
+    class MessageCaptureScreen : public MessageBase {
+        SurfaceFlinger* flinger;
+        sp<IBinder> display;
+        sp<IGraphicBufferProducer> producer;
+        Rect sourceCrop;
+        uint32_t reqWidth, reqHeight;
+        uint32_t minLayerZ,maxLayerZ;
+        bool useIdentityTransform;
+        Transform::orientation_flags rotation;
+        status_t result;
+        bool isLocalScreenshot;
+    public:
+        MessageCaptureScreen(SurfaceFlinger* flinger,
+                const sp<IBinder>& display,
+                const sp<IGraphicBufferProducer>& producer,
+                Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
+                uint32_t minLayerZ, uint32_t maxLayerZ,
+                bool useIdentityTransform,
+                Transform::orientation_flags rotation,
+                bool isLocalScreenshot)
+            : flinger(flinger), display(display), producer(producer),
+              sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
+              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
+              useIdentityTransform(useIdentityTransform),
+              rotation(rotation), result(PERMISSION_DENIED),
+              isLocalScreenshot(isLocalScreenshot)
+        {
+        }
+        status_t getResult() const {
+            return result;
+        }
+        virtual bool handler() {
+            Mutex::Autolock _l(flinger->mStateLock);
+            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
+            result = flinger->captureScreenImplLocked(hw, producer,
+                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
+                    useIdentityTransform, rotation, 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,
+            display, IGraphicBufferProducer::asInterface( wrapper ),
+            sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
+            useIdentityTransform, rotationFlags, isLocalScreenshot);
+
+    status_t res = postMessageAsync(msg);
+    if (res == NO_ERROR) {
+        res = wrapper->waitForResponse();
+    }
+    return res;
+}
+
+
+void SurfaceFlinger::renderScreenImplLocked(
+        const sp<const DisplayDevice>& hw,
+        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
+        uint32_t minLayerZ, uint32_t maxLayerZ,
+        bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation)
+{
+    ATRACE_CALL();
+    RenderEngine& engine(getRenderEngine());
+
+    // get screen geometry
+    const int32_t hw_w = hw->getWidth();
+    const int32_t hw_h = hw->getHeight();
+    const bool filtering = static_cast<int32_t>(reqWidth) != hw_w ||
+                           static_cast<int32_t>(reqHeight) != hw_h;
+
+    // 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(hw_w, hw_h));
+    }
+
+    // ensure that sourceCrop is inside screen
+    if (sourceCrop.left < 0) {
+        ALOGE("Invalid crop rect: l = %d (< 0)", sourceCrop.left);
+    }
+    if (sourceCrop.right > hw_w) {
+        ALOGE("Invalid crop rect: r = %d (> %d)", sourceCrop.right, hw_w);
+    }
+    if (sourceCrop.top < 0) {
+        ALOGE("Invalid crop rect: t = %d (< 0)", sourceCrop.top);
+    }
+    if (sourceCrop.bottom > hw_h) {
+        ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, hw_h);
+    }
+
+    // make sure to clear all GL error flags
+    engine.checkErrors();
+
+    // set-up our viewport
+    engine.setViewportAndProjection(
+        reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
+    engine.disableTexturing();
+
+    // redraw the screen entirely...
+    engine.clearWithColor(0, 0, 0, 1);
+
+    const LayerVector& layers( mDrawingState.layersSortedByZ );
+    const size_t count = layers.size();
+    for (size_t i=0 ; i<count ; ++i) {
+        const sp<Layer>& layer(layers[i]);
+        const Layer::State& state(layer->getDrawingState());
+        if (state.layerStack == hw->getLayerStack()) {
+            if (state.z >= minLayerZ && state.z <= maxLayerZ) {
+                if (layer->isVisible()) {
+                    if (filtering) layer->setFiltering(true);
+                    layer->draw(hw, useIdentityTransform);
+                    if (filtering) layer->setFiltering(false);
+                }
+            }
+        }
+    }
+
+    // compositionComplete is needed for older driver
+    hw->compositionComplete();
+    hw->setViewportAndProjection();
+}
+
+
+status_t SurfaceFlinger::captureScreenImplLocked(
+        const sp<const DisplayDevice>& hw,
+        const sp<IGraphicBufferProducer>& producer,
+        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
+        uint32_t minLayerZ, uint32_t maxLayerZ,
+        bool useIdentityTransform, Transform::orientation_flags rotation,
+        bool isLocalScreenshot)
+{
+    ATRACE_CALL();
+
+    // get screen geometry
+    uint32_t hw_w = hw->getWidth();
+    uint32_t hw_h = hw->getHeight();
+
+    if (rotation & Transform::ROT_90) {
+        std::swap(hw_w, hw_h);
+    }
+
+    if ((reqWidth > hw_w) || (reqHeight > hw_h)) {
+        ALOGE("size mismatch (%d, %d) > (%d, %d)",
+                reqWidth, reqHeight, hw_w, hw_h);
+        return BAD_VALUE;
+    }
+
+    reqWidth  = (!reqWidth)  ? hw_w : reqWidth;
+    reqHeight = (!reqHeight) ? hw_h : reqHeight;
+
+    bool secureLayerIsVisible = false;
+    const LayerVector& layers(mDrawingState.layersSortedByZ);
+    const size_t count = layers.size();
+    for (size_t i = 0 ; i < count ; ++i) {
+        const sp<Layer>& layer(layers[i]);
+        const Layer::State& state(layer->getDrawingState());
+        if (state.layerStack == hw->getLayerStack() && state.z >= minLayerZ &&
+                state.z <= maxLayerZ && layer->isVisible() &&
+                layer->isSecure()) {
+            secureLayerIsVisible = true;
+        }
+    }
+
+    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, reqWidth, reqHeight);
+        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(
+                            hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
+                            useIdentityTransform, rotation);
+
+                        // 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[reqWidth*reqHeight];
+                            getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
+                            checkScreenshot(reqWidth, reqHeight, reqWidth, pixels,
+                                    hw, minLayerZ, maxLayerZ);
+                            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;
+}
+
+bool SurfaceFlinger::getFrameTimestamps(const Layer& layer,
+        uint64_t frameNumber, FrameTimestamps* outTimestamps) {
+    return mFenceTracker.getFrameTimestamps(layer, frameNumber, outTimestamps);
+}
+
+void SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
+        const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) {
+    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 ***\n"
+                "requested minz=%d, maxz=%d, layerStack=%d",
+                minLayerZ, maxLayerZ, hw->getLayerStack());
+        const LayerVector& layers( mDrawingState.layersSortedByZ );
+        const size_t count = layers.size();
+        for (size_t i=0 ; i<count ; ++i) {
+            const sp<Layer>& layer(layers[i]);
+            const Layer::State& state(layer->getDrawingState());
+            const bool visible = (state.layerStack == hw->getLayerStack())
+                                && (state.z >= minLayerZ && state.z <= maxLayerZ)
+                                && (layer->isVisible());
+            ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%x",
+                    visible ? '+' : '-',
+                            i, layer->getName().string(), state.layerStack, state.z,
+                            layer->isVisible(), state.flags, state.alpha);
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+SurfaceFlinger::LayerVector::LayerVector() {
+}
+
+SurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
+    : SortedVector<sp<Layer> >(rhs) {
+}
+
+int SurfaceFlinger::LayerVector::do_compare(const void* lhs,
+    const void* rhs) const
+{
+    // sort layers per layer-stack, then by z-order and finally by sequence
+    const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs));
+    const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs));
+
+    uint32_t ls = l->getCurrentState().layerStack;
+    uint32_t rs = r->getCurrentState().layerStack;
+    if (ls != rs)
+        return ls - rs;
+
+    uint32_t lz = l->getCurrentState().z;
+    uint32_t rz = r->getCurrentState().z;
+    if (lz != rz)
+        return lz - rz;
+
+    return l->sequence - r->sequence;
+}
+
+}; // 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
