diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..43bce5f
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,19 @@
+image: ubuntu:16.04
+
+before_script:
+  - apt-get --quiet update --yes >/dev/null
+  - apt-get --quiet install --yes clang-format-3.5 git >/dev/null
+
+stages:
+  - style
+
+clang-format:
+  stage: style
+  script:
+    - git fetch https://gitlab.freedesktop.org/drm-hwcomposer/drm-hwcomposer.git
+    - git diff -U0 --no-color FETCH_HEAD...HEAD -- | clang-format-diff-3.5 -p 1 -style=file > format-fixup.patch
+    - if [ -s format-fixup.patch ]; then cat format-fixup.patch && exit 1; fi
+  artifacts:
+    when: on_failure
+    paths:
+      - format-fixup.patch
diff --git a/Android.mk b/Android.mk
index 7bbe332..3d48ba5 100644
--- a/Android.mk
+++ b/Android.mk
@@ -36,6 +36,7 @@
 LOCAL_CFLAGS := $(common_drm_hwcomposer_cflags)
 
 LOCAL_MODULE := libdrmhwc_utils
+LOCAL_VENDOR_MODULE := true
 
 include $(BUILD_STATIC_LIBRARY)
 
@@ -47,8 +48,6 @@
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
 	libdrm \
-	libEGL \
-	libGLESv2 \
 	libhardware \
 	liblog \
 	libsync \
@@ -58,41 +57,46 @@
 LOCAL_STATIC_LIBRARIES := libdrmhwc_utils
 
 LOCAL_C_INCLUDES := \
-	external/drm_gralloc \
-	external/libdrm \
-	external/libdrm/include/drm \
-	system/core/include/utils \
-	system/core/libsync \
-	system/core/libsync/include \
+	system/core/libsync
 
 LOCAL_SRC_FILES := \
+	autolock.cpp \
 	drmresources.cpp \
-	drmcomposition.cpp \
-	drmcompositor.cpp \
 	drmconnector.cpp \
 	drmcrtc.cpp \
 	drmdisplaycomposition.cpp \
 	drmdisplaycompositor.cpp \
 	drmencoder.cpp \
 	drmeventlistener.cpp \
+	drmhwctwo.cpp \
 	drmmode.cpp \
 	drmplane.cpp \
 	drmproperty.cpp \
-	glworker.cpp \
-	hwcomposer.cpp \
+	hwcutils.cpp \
 	platform.cpp \
-	separate_rects.cpp \
-	virtualcompositorworker.cpp \
+	platformdrmgeneric.cpp \
 	vsyncworker.cpp
 
 LOCAL_CFLAGS := $(common_drm_hwcomposer_cflags)
 
-ifeq ($(strip $(BOARD_DRM_HWCOMPOSER_BUFFER_IMPORTER)),nvidia-gralloc)
-LOCAL_CPPFLAGS += -DUSE_NVIDIA_IMPORTER
-LOCAL_SRC_FILES += platformnv.cpp
+LOCAL_CPPFLAGS += \
+	-DHWC2_USE_CPP11 \
+	-DHWC2_INCLUDE_STRINGIFICATION
+
+
+ifeq ($(TARGET_PRODUCT),hikey960)
+LOCAL_CPPFLAGS += -DUSE_HISI_IMPORTER
+LOCAL_SRC_FILES += platformhisi.cpp
+LOCAL_C_INCLUDES += device/linaro/hikey/gralloc960/
+else ifeq ($(TARGET_PRODUCT),hikey)
+LOCAL_CPPFLAGS += -DUSE_HISI_IMPORTER
+LOCAL_SRC_FILES += platformhisi.cpp
+LOCAL_C_INCLUDES += device/linaro/hikey/gralloc/
+else ifeq ($(strip $(BOARD_DRM_HWCOMPOSER_BUFFER_IMPORTER)),minigbm)
+LOCAL_SRC_FILES += platformminigbm.cpp
+LOCAL_C_INCLUDES += external/minigbm/cros_gralloc/
 else
 LOCAL_CPPFLAGS += -DUSE_DRM_GENERIC_IMPORTER
-LOCAL_SRC_FILES += platformdrmgeneric.cpp
 endif
 
 LOCAL_MODULE := hwcomposer.drm
@@ -100,6 +104,8 @@
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_MODULE_CLASS := SHARED_LIBRARIES
 LOCAL_MODULE_SUFFIX := $(TARGET_SHLIB_SUFFIX)
+LOCAL_VENDOR_MODULE := true
+
 include $(BUILD_SHARED_LIBRARY)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..260ac9b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,19 @@
+drm_hwcomposer
+======
+
+Patches to drm_hwcomposer are very much welcome, we really want this to be the
+universal HW composer implementation for Android and similar platforms
+So please bring on porting patches, bugfixes, improvements for documentation
+and new features.
+
+A short list of contribution guidelines:
+* Submit changes via gitlab merge requests on gitlab.freedesktop.org
+* drm_hwcomposer is Apache 2.0 Licensed and we require contributions to follow the developer's certificate of origin: http://developercertificate.org/
+* When submitting new code please follow the naming conventions documented in the generated documentation. Also please make full use of all the helpers and convenience macros provided by drm_hwcomposer. The below command can help you with formatting of your patches:
+  
+      `git diff | clang-format-diff-3.5 -p 1 -style=file`
+* Hardware specific changes should be tested on relevant platforms before committing.
+
+If you need inspiration, please checkout our [TODO issues](https://gitlab.freedesktop.org/drm-hwcomposer/drm-hwcomposer/issues?label_name%5B%5D=TODO)
+
+Happy hacking!
diff --git a/autogl.h b/autogl.h
deleted file mode 100644
index fc77fb0..0000000
--- a/autogl.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2015 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_AUTO_GL_H_
-#define ANDROID_AUTO_GL_H_
-
-#include <memory>
-#define EGL_EGLEXT_PROTOTYPES
-#define GL_GLEXT_PROTOTYPES
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-// TODO(zachr): use hwc_drm_bo to turn buffer handles into textures
-#ifndef EGL_NATIVE_HANDLE_ANDROID_NVX
-#define EGL_NATIVE_HANDLE_ANDROID_NVX 0x322A
-#endif
-
-namespace android {
-
-#define AUTO_GL_TYPE(name, type, zero, deleter) \
-  struct name##Deleter {                        \
-    typedef type pointer;                       \
-                                                \
-    void operator()(pointer p) const {          \
-      if (p != zero) {                          \
-        deleter;                                \
-      }                                         \
-    }                                           \
-  };                                            \
-  typedef std::unique_ptr<type, name##Deleter> name;
-
-AUTO_GL_TYPE(AutoGLFramebuffer, GLuint, 0, glDeleteFramebuffers(1, &p))
-AUTO_GL_TYPE(AutoGLBuffer, GLuint, 0, glDeleteBuffers(1, &p))
-AUTO_GL_TYPE(AutoGLTexture, GLuint, 0, glDeleteTextures(1, &p))
-AUTO_GL_TYPE(AutoGLShader, GLint, 0, glDeleteShader(p))
-AUTO_GL_TYPE(AutoGLProgram, GLint, 0, glDeleteProgram(p))
-
-struct AutoEGLDisplayImage {
-  AutoEGLDisplayImage() = default;
-
-  AutoEGLDisplayImage(EGLDisplay display, EGLImageKHR image)
-      : display_(display), image_(image) {
-  }
-
-  AutoEGLDisplayImage(const AutoEGLDisplayImage& rhs) = delete;
-  AutoEGLDisplayImage(AutoEGLDisplayImage&& rhs) {
-    display_ = rhs.display_;
-    image_ = rhs.image_;
-    rhs.display_ = EGL_NO_DISPLAY;
-    rhs.image_ = EGL_NO_IMAGE_KHR;
-  }
-
-  ~AutoEGLDisplayImage() {
-    clear();
-  }
-
-  AutoEGLDisplayImage& operator=(const AutoEGLDisplayImage& rhs) = delete;
-  AutoEGLDisplayImage& operator=(AutoEGLDisplayImage&& rhs) {
-    clear();
-    std::swap(display_, rhs.display_);
-    std::swap(image_, rhs.image_);
-    return *this;
-  }
-
-  void reset(EGLDisplay display, EGLImageKHR image) {
-    clear();
-    display_ = display;
-    image_ = image;
-  }
-
-  void clear() {
-    if (image_ != EGL_NO_IMAGE_KHR) {
-      eglDestroyImageKHR(display_, image_);
-      display_ = EGL_NO_DISPLAY;
-      image_ = EGL_NO_IMAGE_KHR;
-    }
-  }
-
-  EGLImageKHR image() const {
-    return image_;
-  }
-
- private:
-  EGLDisplay display_ = EGL_NO_DISPLAY;
-  EGLImageKHR image_ = EGL_NO_IMAGE_KHR;
-};
-
-struct AutoEGLImageAndGLTexture {
-  AutoEGLDisplayImage image;
-  AutoGLTexture texture;
-};
-}
-
-#endif
diff --git a/autolock.cpp b/autolock.cpp
new file mode 100644
index 0000000..795a8c2
--- /dev/null
+++ b/autolock.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 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
+#define LOG_TAG "hwc-drm-auto-lock"
+
+#include "autolock.h"
+
+#include <errno.h>
+#include <pthread.h>
+
+#include <log/log.h>
+
+namespace android {
+
+int AutoLock::Lock() {
+  if (locked_) {
+    ALOGE("Invalid attempt to double lock AutoLock %s", name_);
+    return -EINVAL;
+  }
+  int ret = pthread_mutex_lock(mutex_);
+  if (ret) {
+    ALOGE("Failed to acquire %s lock %d", name_, ret);
+    return ret;
+  }
+  locked_ = true;
+  return 0;
+}
+
+int AutoLock::Unlock() {
+  if (!locked_) {
+    ALOGE("Invalid attempt to unlock unlocked AutoLock %s", name_);
+    return -EINVAL;
+  }
+  int ret = pthread_mutex_unlock(mutex_);
+  if (ret) {
+    ALOGE("Failed to release %s lock %d", name_, ret);
+    return ret;
+  }
+  locked_ = false;
+  return 0;
+}
+}
diff --git a/autolock.h b/autolock.h
new file mode 100644
index 0000000..3b824e2
--- /dev/null
+++ b/autolock.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <pthread.h>
+
+namespace android {
+
+class AutoLock {
+ public:
+  AutoLock(pthread_mutex_t *mutex, const char *const name)
+      : mutex_(mutex), name_(name) {
+  }
+  ~AutoLock() {
+    if (locked_)
+      Unlock();
+  }
+
+  AutoLock(const AutoLock &rhs) = delete;
+  AutoLock &operator=(const AutoLock &rhs) = delete;
+
+  int Lock();
+  int Unlock();
+
+ private:
+  pthread_mutex_t *const mutex_;
+  bool locked_ = false;
+  const char *const name_;
+};
+}
diff --git a/drmcomposition.cpp b/drmcomposition.cpp
deleted file mode 100644
index 1aaf920..0000000
--- a/drmcomposition.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "hwc-drm-composition"
-
-#include "drmcomposition.h"
-#include "drmcrtc.h"
-#include "drmplane.h"
-#include "drmresources.h"
-#include "platform.h"
-
-#include <stdlib.h>
-
-#include <cutils/log.h>
-#include <cutils/properties.h>
-#include <sw_sync.h>
-#include <sync/sync.h>
-
-namespace android {
-
-DrmComposition::DrmComposition(DrmResources *drm, Importer *importer,
-                               Planner *planner)
-    : drm_(drm), importer_(importer), planner_(planner) {
-  char use_overlay_planes_prop[PROPERTY_VALUE_MAX];
-  property_get("hwc.drm.use_overlay_planes", use_overlay_planes_prop, "1");
-  bool use_overlay_planes = atoi(use_overlay_planes_prop);
-
-  for (auto &plane : drm->planes()) {
-    if (plane->type() == DRM_PLANE_TYPE_PRIMARY)
-      primary_planes_.push_back(plane.get());
-    else if (use_overlay_planes && plane->type() == DRM_PLANE_TYPE_OVERLAY)
-      overlay_planes_.push_back(plane.get());
-  }
-}
-
-int DrmComposition::Init(uint64_t frame_no) {
-  for (auto &conn : drm_->connectors()) {
-    int display = conn->display();
-    composition_map_[display].reset(new DrmDisplayComposition());
-    if (!composition_map_[display]) {
-      ALOGE("Failed to allocate new display composition\n");
-      return -ENOMEM;
-    }
-
-    // If the display hasn't been modeset yet, this will be NULL
-    DrmCrtc *crtc = drm_->GetCrtcForDisplay(display);
-
-    int ret = composition_map_[display]->Init(drm_, crtc, importer_, planner_,
-                                              frame_no);
-    if (ret) {
-      ALOGE("Failed to init display composition for %d", display);
-      return ret;
-    }
-  }
-  return 0;
-}
-
-int DrmComposition::SetLayers(size_t num_displays,
-                              DrmCompositionDisplayLayersMap *maps) {
-  int ret = 0;
-  for (size_t display_index = 0; display_index < num_displays;
-       display_index++) {
-    DrmCompositionDisplayLayersMap &map = maps[display_index];
-    int display = map.display;
-
-    if (!drm_->GetConnectorForDisplay(display)) {
-      ALOGE("Invalid display given to SetLayers %d", display);
-      continue;
-    }
-
-    ret = composition_map_[display]->SetLayers(
-        map.layers.data(), map.layers.size(), map.geometry_changed);
-    if (ret)
-      return ret;
-  }
-
-  return 0;
-}
-
-int DrmComposition::SetDpmsMode(int display, uint32_t dpms_mode) {
-  return composition_map_[display]->SetDpmsMode(dpms_mode);
-}
-
-int DrmComposition::SetDisplayMode(int display, const DrmMode &display_mode) {
-  return composition_map_[display]->SetDisplayMode(display_mode);
-}
-
-std::unique_ptr<DrmDisplayComposition> DrmComposition::TakeDisplayComposition(
-    int display) {
-  return std::move(composition_map_[display]);
-}
-
-int DrmComposition::Plan(std::map<int, DrmDisplayCompositor> &compositor_map) {
-  int ret = 0;
-  for (auto &conn : drm_->connectors()) {
-    int display = conn->display();
-    DrmDisplayComposition *comp = GetDisplayComposition(display);
-    ret = comp->Plan(compositor_map[display].squash_state(), &primary_planes_,
-                     &overlay_planes_);
-    if (ret) {
-      ALOGE("Failed to plan composition for dislay %d", display);
-      return ret;
-    }
-  }
-
-  return 0;
-}
-
-int DrmComposition::DisableUnusedPlanes() {
-  for (auto &conn : drm_->connectors()) {
-    int display = conn->display();
-    DrmDisplayComposition *comp = GetDisplayComposition(display);
-
-    /*
-     * Leave empty compositions alone
-     * TODO: re-visit this and potentially disable leftover planes after the
-     *       active compositions have gobbled up all they can
-     */
-    if (comp->type() == DRM_COMPOSITION_TYPE_EMPTY ||
-        comp->type() == DRM_COMPOSITION_TYPE_MODESET)
-      continue;
-
-    DrmCrtc *crtc = drm_->GetCrtcForDisplay(display);
-    if (!crtc) {
-      ALOGE("Failed to find crtc for display %d", display);
-      continue;
-    }
-
-    for (std::vector<DrmPlane *>::iterator iter = primary_planes_.begin();
-         iter != primary_planes_.end(); ++iter) {
-      if ((*iter)->GetCrtcSupported(*crtc)) {
-        comp->AddPlaneDisable(*iter);
-        primary_planes_.erase(iter);
-        break;
-      }
-    }
-    for (std::vector<DrmPlane *>::iterator iter = overlay_planes_.begin();
-         iter != overlay_planes_.end();) {
-      if ((*iter)->GetCrtcSupported(*crtc)) {
-        comp->AddPlaneDisable(*iter);
-        iter = overlay_planes_.erase(iter);
-      } else {
-        iter++;
-      }
-    }
-  }
-  return 0;
-}
-
-DrmDisplayComposition *DrmComposition::GetDisplayComposition(int display) {
-  return composition_map_[display].get();
-}
-}
diff --git a/drmcomposition.h b/drmcomposition.h
deleted file mode 100644
index eae8cde..0000000
--- a/drmcomposition.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2015 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_DRM_COMPOSITION_H_
-#define ANDROID_DRM_COMPOSITION_H_
-
-#include "drmhwcomposer.h"
-#include "drmdisplaycomposition.h"
-#include "drmplane.h"
-#include "platform.h"
-
-#include <map>
-#include <vector>
-
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer.h>
-
-namespace android {
-
-class DrmDisplayCompositor;
-
-struct DrmCompositionDisplayLayersMap {
-  int display;
-  bool geometry_changed = true;
-  std::vector<DrmHwcLayer> layers;
-
-  DrmCompositionDisplayLayersMap() = default;
-  DrmCompositionDisplayLayersMap(DrmCompositionDisplayLayersMap &&rhs) =
-      default;
-};
-
-class DrmComposition {
- public:
-  DrmComposition(DrmResources *drm, Importer *importer, Planner *planner);
-
-  int Init(uint64_t frame_no);
-
-  int SetLayers(size_t num_displays, DrmCompositionDisplayLayersMap *maps);
-  int SetDpmsMode(int display, uint32_t dpms_mode);
-  int SetDisplayMode(int display, const DrmMode &display_mode);
-
-  std::unique_ptr<DrmDisplayComposition> TakeDisplayComposition(int display);
-  DrmDisplayComposition *GetDisplayComposition(int display);
-
-  int Plan(std::map<int, DrmDisplayCompositor> &compositor_map);
-  int DisableUnusedPlanes();
-
- private:
-  DrmComposition(const DrmComposition &) = delete;
-
-  DrmResources *drm_;
-  Importer *importer_;
-  Planner *planner_;
-
-  std::vector<DrmPlane *> primary_planes_;
-  std::vector<DrmPlane *> overlay_planes_;
-
-  /*
-   * This _must_ be read-only after it's passed to QueueComposition. Otherwise
-   * locking is required to maintain consistency across the compositor threads.
-   */
-  std::map<int, std::unique_ptr<DrmDisplayComposition>> composition_map_;
-};
-}
-
-#endif  // ANDROID_DRM_COMPOSITION_H_
diff --git a/drmcompositor.cpp b/drmcompositor.cpp
deleted file mode 100644
index c1f3ed8..0000000
--- a/drmcompositor.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "hwc-drm-compositor"
-
-#include "drmcompositor.h"
-#include "drmdisplaycompositor.h"
-#include "drmresources.h"
-#include "platform.h"
-
-#include <sstream>
-#include <stdlib.h>
-
-#include <cutils/log.h>
-
-namespace android {
-
-DrmCompositor::DrmCompositor(DrmResources *drm) : drm_(drm), frame_no_(0) {
-}
-
-DrmCompositor::~DrmCompositor() {
-}
-
-int DrmCompositor::Init() {
-  for (auto &conn : drm_->connectors()) {
-    int display = conn->display();
-    int ret = compositor_map_[display].Init(drm_, display);
-    if (ret) {
-      ALOGE("Failed to initialize display compositor for %d", display);
-      return ret;
-    }
-  }
-  planner_ = Planner::CreateInstance(drm_);
-  if (!planner_) {
-    ALOGE("Failed to create planner instance for composition");
-    return -ENOMEM;
-  }
-
-  return 0;
-}
-
-std::unique_ptr<DrmComposition> DrmCompositor::CreateComposition(
-    Importer *importer) {
-  std::unique_ptr<DrmComposition> composition(
-      new DrmComposition(drm_, importer, planner_.get()));
-  int ret = composition->Init(++frame_no_);
-  if (ret) {
-    ALOGE("Failed to initialize drm composition %d", ret);
-    return nullptr;
-  }
-  return composition;
-}
-
-int DrmCompositor::QueueComposition(
-    std::unique_ptr<DrmComposition> composition) {
-  int ret;
-
-  ret = composition->Plan(compositor_map_);
-  if (ret)
-    return ret;
-
-  ret = composition->DisableUnusedPlanes();
-  if (ret)
-    return ret;
-
-  for (auto &conn : drm_->connectors()) {
-    int display = conn->display();
-    int ret = compositor_map_[display].QueueComposition(
-        composition->TakeDisplayComposition(display));
-    if (ret) {
-      ALOGE("Failed to queue composition for display %d (%d)", display, ret);
-      return ret;
-    }
-  }
-
-  return 0;
-}
-
-int DrmCompositor::Composite() {
-  /*
-   * This shouldn't be called, we should be calling Composite() on the display
-   * compositors directly.
-   */
-  ALOGE("Calling base drm compositor Composite() function");
-  return -EINVAL;
-}
-
-void DrmCompositor::Dump(std::ostringstream *out) const {
-  *out << "DrmCompositor stats:\n";
-  for (auto &conn : drm_->connectors())
-    compositor_map_[conn->display()].Dump(out);
-}
-}
diff --git a/drmcompositor.h b/drmcompositor.h
deleted file mode 100644
index 19271b5..0000000
--- a/drmcompositor.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2015 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_DRM_COMPOSITOR_H_
-#define ANDROID_DRM_COMPOSITOR_H_
-
-#include "drmcomposition.h"
-#include "drmdisplaycompositor.h"
-#include "platform.h"
-
-#include <map>
-#include <memory>
-#include <sstream>
-
-namespace android {
-
-class DrmCompositor {
- public:
-  DrmCompositor(DrmResources *drm);
-  ~DrmCompositor();
-
-  int Init();
-
-  std::unique_ptr<DrmComposition> CreateComposition(Importer *importer);
-
-  int QueueComposition(std::unique_ptr<DrmComposition> composition);
-  int Composite();
-  void Dump(std::ostringstream *out) const;
-
- private:
-  DrmCompositor(const DrmCompositor &) = delete;
-
-  DrmResources *drm_;
-  std::unique_ptr<Planner> planner_;
-
-  uint64_t frame_no_;
-
-  // mutable for Dump() propagation
-  mutable std::map<int, DrmDisplayCompositor> compositor_map_;
-};
-}
-
-#endif  // ANDROID_DRM_COMPOSITOR_H_
diff --git a/drmconnector.cpp b/drmconnector.cpp
index ccb38e2..10b96b5 100644
--- a/drmconnector.cpp
+++ b/drmconnector.cpp
@@ -22,7 +22,7 @@
 #include <errno.h>
 #include <stdint.h>
 
-#include <cutils/log.h>
+#include <log/log.h>
 #include <xf86drmMode.h>
 
 namespace android {
@@ -67,11 +67,21 @@
   display_ = display;
 }
 
-bool DrmConnector::built_in() const {
+bool DrmConnector::internal() const {
   return type_ == DRM_MODE_CONNECTOR_LVDS || type_ == DRM_MODE_CONNECTOR_eDP ||
          type_ == DRM_MODE_CONNECTOR_DSI || type_ == DRM_MODE_CONNECTOR_VIRTUAL;
 }
 
+bool DrmConnector::external() const {
+  return type_ == DRM_MODE_CONNECTOR_HDMIA || type_ == DRM_MODE_CONNECTOR_DisplayPort ||
+         type_ == DRM_MODE_CONNECTOR_DVID || type_ == DRM_MODE_CONNECTOR_DVII ||
+         type_ == DRM_MODE_CONNECTOR_VGA;
+}
+
+bool DrmConnector::valid_type() const {
+  return internal() || external();
+}
+
 int DrmConnector::UpdateModes() {
   int fd = drm_->fd();
 
diff --git a/drmconnector.h b/drmconnector.h
index e1488bb..5601e06 100644
--- a/drmconnector.h
+++ b/drmconnector.h
@@ -44,7 +44,9 @@
   int display() const;
   void set_display(int display);
 
-  bool built_in() const;
+  bool internal() const;
+  bool external() const;
+  bool valid_type() const;
 
   int UpdateModes();
 
diff --git a/drmcrtc.cpp b/drmcrtc.cpp
index 1fbdc12..4033269 100644
--- a/drmcrtc.cpp
+++ b/drmcrtc.cpp
@@ -22,7 +22,7 @@
 #include <stdint.h>
 #include <xf86drmMode.h>
 
-#include <cutils/log.h>
+#include <log/log.h>
 
 namespace android {
 
@@ -31,12 +31,7 @@
       id_(c->crtc_id),
       pipe_(pipe),
       display_(-1),
-      x_(c->x),
-      y_(c->y),
-      width_(c->width),
-      height_(c->height),
-      mode_(&c->mode),
-      mode_valid_(c->mode_valid) {
+      mode_(&c->mode) {
 }
 
 int DrmCrtc::Init() {
@@ -51,6 +46,12 @@
     ALOGE("Failed to get MODE_ID property");
     return ret;
   }
+
+  ret = drm_->GetCrtcProperty(*this, "OUT_FENCE_PTR", &out_fence_ptr_property_);
+  if (ret) {
+    ALOGE("Failed to get OUT_FENCE_PTR property");
+    return ret;
+  }
   return 0;
 }
 
@@ -81,4 +82,8 @@
 const DrmProperty &DrmCrtc::mode_property() const {
   return mode_property_;
 }
+
+const DrmProperty &DrmCrtc::out_fence_ptr_property() const {
+  return out_fence_ptr_property_;
+}
 }
diff --git a/drmcrtc.h b/drmcrtc.h
index ad95352..c5a5599 100644
--- a/drmcrtc.h
+++ b/drmcrtc.h
@@ -45,6 +45,7 @@
 
   const DrmProperty &active_property() const;
   const DrmProperty &mode_property() const;
+  const DrmProperty &out_fence_ptr_property() const;
 
  private:
   DrmResources *drm_;
@@ -53,16 +54,11 @@
   unsigned pipe_;
   int display_;
 
-  uint32_t x_;
-  uint32_t y_;
-  uint32_t width_;
-  uint32_t height_;
-
   DrmMode mode_;
-  bool mode_valid_;
 
   DrmProperty active_property_;
   DrmProperty mode_property_;
+  DrmProperty out_fence_ptr_property_;
 };
 }
 
diff --git a/drmdisplaycomposition.cpp b/drmdisplaycomposition.cpp
index b7f8d1a..129bec2 100644
--- a/drmdisplaycomposition.cpp
+++ b/drmdisplaycomposition.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "hwc-drm-display-composition"
 
 #include "drmdisplaycomposition.h"
+#include "drmdisplaycompositor.h"
 #include "drmcrtc.h"
 #include "drmplane.h"
 #include "drmresources.h"
@@ -27,18 +28,13 @@
 #include <algorithm>
 #include <unordered_set>
 
-#include <cutils/log.h>
-#include <sw_sync.h>
+#include <log/log.h>
 #include <sync/sync.h>
 #include <xf86drmMode.h>
 
 namespace android {
 
 DrmDisplayComposition::~DrmDisplayComposition() {
-  if (timeline_fd_ >= 0) {
-    SignalCompositionDone();
-    close(timeline_fd_);
-  }
 }
 
 int DrmDisplayComposition::Init(DrmResources *drm, DrmCrtc *crtc,
@@ -50,12 +46,6 @@
   planner_ = planner;
   frame_no_ = frame_no;
 
-  int ret = sw_sync_timeline_create();
-  if (ret < 0) {
-    ALOGE("Failed to create sw sync timeline %d", ret);
-    return ret;
-  }
-  timeline_fd_ = ret;
   return 0;
 }
 
@@ -63,26 +53,6 @@
   return type_ == DRM_COMPOSITION_TYPE_EMPTY || type_ == des;
 }
 
-int DrmDisplayComposition::CreateNextTimelineFence() {
-  ++timeline_;
-  return sw_sync_fence_create(timeline_fd_, "hwc drm display composition fence",
-                              timeline_);
-}
-
-int DrmDisplayComposition::IncreaseTimelineToPoint(int point) {
-  int timeline_increase = point - timeline_current_;
-  if (timeline_increase <= 0)
-    return 0;
-
-  int ret = sw_sync_timeline_inc(timeline_fd_, timeline_increase);
-  if (ret)
-    ALOGE("Failed to increment sync timeline %d", ret);
-  else
-    timeline_current_ = point;
-
-  return ret;
-}
-
 int DrmDisplayComposition::SetLayers(DrmHwcLayer *layers, size_t num_layers,
                                      bool geometry_changed) {
   if (!validate_composition_type(DRM_COMPOSITION_TYPE_FRAME))
@@ -121,249 +91,25 @@
   return 0;
 }
 
-static std::vector<size_t> SetBitsToVector(
-    uint64_t in, const std::vector<size_t> &index_map) {
-  std::vector<size_t> out;
-  size_t msb = sizeof(in) * 8 - 1;
-  uint64_t mask = (uint64_t)1 << msb;
-  for (size_t i = msb; mask != (uint64_t)0; i--, mask >>= 1)
-    if (in & mask)
-      out.push_back(index_map[i]);
-  return out;
-}
-
 int DrmDisplayComposition::AddPlaneComposition(DrmCompositionPlane plane) {
   composition_planes_.emplace_back(std::move(plane));
   return 0;
 }
 
-void DrmDisplayComposition::SeparateLayers(DrmHwcRect<int> *exclude_rects,
-                                           size_t num_exclude_rects) {
-  DrmCompositionPlane *comp = NULL;
-  std::vector<size_t> dedicated_layers;
-
-  // Go through the composition and find the precomp layer as well as any
-  // layers that have a dedicated plane located below the precomp layer.
-  for (auto &i : composition_planes_) {
-    if (i.type() == DrmCompositionPlane::Type::kLayer) {
-      dedicated_layers.insert(dedicated_layers.end(), i.source_layers().begin(),
-                              i.source_layers().end());
-    } else if (i.type() == DrmCompositionPlane::Type::kPrecomp) {
-      comp = &i;
-      break;
-    }
-  }
-  if (!comp)
-    return;
-
-  const std::vector<size_t> &comp_layers = comp->source_layers();
-  if (comp_layers.size() > 64) {
-    ALOGE("Failed to separate layers because there are more than 64");
-    return;
-  }
-
-  // Index at which the actual layers begin
-  size_t layer_offset = num_exclude_rects + dedicated_layers.size();
-  if (comp_layers.size() + layer_offset > 64) {
-    ALOGW(
-        "Exclusion rectangles are being truncated to make the rectangle count "
-        "fit into 64");
-    num_exclude_rects = 64 - comp_layers.size() - dedicated_layers.size();
-  }
-
-  // We inject all the exclude rects into the rects list. Any resulting rect
-  // that includes ANY of the first num_exclude_rects is rejected. After the
-  // exclude rects, we add the lower layers. The rects that intersect with
-  // these layers will be inspected and only those which are to be composited
-  // above the layer will be included in the composition regions.
-  std::vector<DrmHwcRect<int>> layer_rects(comp_layers.size() + layer_offset);
-  std::copy(exclude_rects, exclude_rects + num_exclude_rects,
-            layer_rects.begin());
-  std::transform(
-      dedicated_layers.begin(), dedicated_layers.end(),
-      layer_rects.begin() + num_exclude_rects,
-      [=](size_t layer_index) { return layers_[layer_index].display_frame; });
-  std::transform(comp_layers.begin(), comp_layers.end(),
-                 layer_rects.begin() + layer_offset, [=](size_t layer_index) {
-    return layers_[layer_index].display_frame;
-  });
-
-  std::vector<separate_rects::RectSet<uint64_t, int>> separate_regions;
-  separate_rects::separate_rects_64(layer_rects, &separate_regions);
-  uint64_t exclude_mask = ((uint64_t)1 << num_exclude_rects) - 1;
-  uint64_t dedicated_mask = (((uint64_t)1 << dedicated_layers.size()) - 1)
-                            << num_exclude_rects;
-
-  for (separate_rects::RectSet<uint64_t, int> &region : separate_regions) {
-    if (region.id_set.getBits() & exclude_mask)
-      continue;
-
-    // If a rect intersects one of the dedicated layers, we need to remove the
-    // layers from the composition region which appear *below* the dedicated
-    // layer. This effectively punches a hole through the composition layer such
-    // that the dedicated layer can be placed below the composition and not
-    // be occluded.
-    uint64_t dedicated_intersect = region.id_set.getBits() & dedicated_mask;
-    for (size_t i = 0; dedicated_intersect && i < dedicated_layers.size();
-         ++i) {
-      // Only exclude layers if they intersect this particular dedicated layer
-      if (!(dedicated_intersect & (1 << (i + num_exclude_rects))))
-        continue;
-
-      for (size_t j = 0; j < comp_layers.size(); ++j) {
-        if (comp_layers[j] < dedicated_layers[i])
-          region.id_set.subtract(j + layer_offset);
-      }
-    }
-    if (!(region.id_set.getBits() >> layer_offset))
-      continue;
-
-    pre_comp_regions_.emplace_back(DrmCompositionRegion{
-        region.rect,
-        SetBitsToVector(region.id_set.getBits() >> layer_offset, comp_layers)});
-  }
-}
-
-int DrmDisplayComposition::CreateAndAssignReleaseFences() {
-  std::unordered_set<DrmHwcLayer *> squash_layers;
-  std::unordered_set<DrmHwcLayer *> pre_comp_layers;
-  std::unordered_set<DrmHwcLayer *> comp_layers;
-
-  for (const DrmCompositionRegion &region : squash_regions_) {
-    for (size_t source_layer_index : region.source_layers) {
-      DrmHwcLayer *source_layer = &layers_[source_layer_index];
-      squash_layers.emplace(source_layer);
-    }
-  }
-
-  for (const DrmCompositionRegion &region : pre_comp_regions_) {
-    for (size_t source_layer_index : region.source_layers) {
-      DrmHwcLayer *source_layer = &layers_[source_layer_index];
-      pre_comp_layers.emplace(source_layer);
-      squash_layers.erase(source_layer);
-    }
-  }
-
-  for (const DrmCompositionPlane &plane : composition_planes_) {
-    if (plane.type() == DrmCompositionPlane::Type::kLayer) {
-      for (auto i : plane.source_layers()) {
-        DrmHwcLayer *source_layer = &layers_[i];
-        comp_layers.emplace(source_layer);
-        pre_comp_layers.erase(source_layer);
-      }
-    }
-  }
-
-  for (DrmHwcLayer *layer : squash_layers) {
-    if (!layer->release_fence)
-      continue;
-    int ret = layer->release_fence.Set(CreateNextTimelineFence());
-    if (ret < 0)
-      return ret;
-  }
-  timeline_squash_done_ = timeline_;
-
-  for (DrmHwcLayer *layer : pre_comp_layers) {
-    if (!layer->release_fence)
-      continue;
-    int ret = layer->release_fence.Set(CreateNextTimelineFence());
-    if (ret < 0)
-      return ret;
-  }
-  timeline_pre_comp_done_ = timeline_;
-
-  for (DrmHwcLayer *layer : comp_layers) {
-    if (!layer->release_fence)
-      continue;
-    int ret = layer->release_fence.Set(CreateNextTimelineFence());
-    if (ret < 0)
-      return ret;
-  }
-
-  return 0;
-}
-
-int DrmDisplayComposition::Plan(SquashState *squash,
-                                std::vector<DrmPlane *> *primary_planes,
+int DrmDisplayComposition::Plan(std::vector<DrmPlane *> *primary_planes,
                                 std::vector<DrmPlane *> *overlay_planes) {
   if (type_ != DRM_COMPOSITION_TYPE_FRAME)
     return 0;
 
-  // Used to track which layers should be sent to the planner. We exclude layers
-  // that are entirely squashed so the planner can provision a precomposition
-  // layer as appropriate (ex: if 5 layers are squashed and 1 is not, we don't
-  // want to plan a precomposition layer that will be comprised of the already
-  // squashed layers).
   std::map<size_t, DrmHwcLayer *> to_composite;
 
-  bool use_squash_framebuffer = false;
-  // Used to determine which layers were entirely squashed
-  std::vector<int> layer_squash_area(layers_.size(), 0);
-  // Used to avoid rerendering regions that were squashed
-  std::vector<DrmHwcRect<int>> exclude_rects;
-  if (squash != NULL) {
-    if (geometry_changed_) {
-      squash->Init(layers_.data(), layers_.size());
-    } else {
-      std::vector<bool> changed_regions;
-      squash->GenerateHistory(layers_.data(), layers_.size(), changed_regions);
-
-      std::vector<bool> stable_regions;
-      squash->StableRegionsWithMarginalHistory(changed_regions, stable_regions);
-
-      // Only if SOME region is stable
-      use_squash_framebuffer =
-          std::find(stable_regions.begin(), stable_regions.end(), true) !=
-          stable_regions.end();
-
-      squash->RecordHistory(layers_.data(), layers_.size(), changed_regions);
-
-      // Changes in which regions are squashed triggers a rerender via
-      // squash_regions.
-      bool render_squash = squash->RecordAndCompareSquashed(stable_regions);
-
-      for (size_t region_index = 0; region_index < stable_regions.size();
-           region_index++) {
-        const SquashState::Region &region = squash->regions()[region_index];
-        if (!stable_regions[region_index])
-          continue;
-
-        exclude_rects.emplace_back(region.rect);
-
-        if (render_squash) {
-          squash_regions_.emplace_back();
-          squash_regions_.back().frame = region.rect;
-        }
-
-        int frame_area = region.rect.area();
-        // Source layers are sorted front to back i.e. top layer has lowest
-        // index.
-        for (size_t layer_index = layers_.size();
-             layer_index-- > 0;  // Yes, I double checked this
-             /* See condition */) {
-          if (!region.layer_refs[layer_index])
-            continue;
-          layer_squash_area[layer_index] += frame_area;
-          if (render_squash)
-            squash_regions_.back().source_layers.push_back(layer_index);
-        }
-      }
-    }
-
-    for (size_t i = 0; i < layers_.size(); ++i) {
-      if (layer_squash_area[i] < layers_[i].display_frame.area())
-        to_composite.emplace(std::make_pair(i, &layers_[i]));
-    }
-  } else {
-    for (size_t i = 0; i < layers_.size(); ++i)
-      to_composite.emplace(std::make_pair(i, &layers_[i]));
-  }
+  for (size_t i = 0; i < layers_.size(); ++i)
+    to_composite.emplace(std::make_pair(i, &layers_[i]));
 
   int ret;
   std::vector<DrmCompositionPlane> plan;
-  std::tie(ret, composition_planes_) =
-      planner_->ProvisionPlanes(to_composite, use_squash_framebuffer, crtc_,
-                                primary_planes, overlay_planes);
+  std::tie(ret, composition_planes_) = planner_->ProvisionPlanes(
+      to_composite, crtc_, primary_planes, overlay_planes);
   if (ret) {
     ALOGE("Planner failed provisioning planes ret=%d", ret);
     return ret;
@@ -391,17 +137,7 @@
     }
   }
 
-  return FinalizeComposition(exclude_rects.data(), exclude_rects.size());
-}
-
-int DrmDisplayComposition::FinalizeComposition() {
-  return FinalizeComposition(NULL, 0);
-}
-
-int DrmDisplayComposition::FinalizeComposition(DrmHwcRect<int> *exclude_rects,
-                                               size_t num_exclude_rects) {
-  SeparateLayers(exclude_rects, num_exclude_rects);
-  return CreateAndAssignReleaseFences();
+  return 0;
 }
 
 static const char *DrmCompositionTypeToString(DrmCompositionType type) {
@@ -501,23 +237,6 @@
   }
 }
 
-static void DumpRegion(const DrmCompositionRegion &region,
-                       std::ostringstream *out) {
-  *out << "frame";
-  region.frame.Dump(out);
-  *out << " source_layers=(";
-
-  const std::vector<size_t> &source_layers = region.source_layers;
-  for (size_t i = 0; i < source_layers.size(); i++) {
-    *out << source_layers[i];
-    if (i < source_layers.size() - 1) {
-      *out << " ";
-    }
-  }
-
-  *out << ")";
-}
-
 void DrmDisplayComposition::Dump(std::ostringstream *out) const {
   *out << "----DrmDisplayComposition"
        << " crtc=" << (crtc_ ? crtc_->id() : -1)
@@ -535,10 +254,6 @@
       break;
   }
 
-  *out << " timeline[current/squash/pre-comp/done]=" << timeline_current_ << "/"
-       << timeline_squash_done_ << "/" << timeline_pre_comp_done_ << "/"
-       << timeline_ << "\n";
-
   *out << "    Layers: count=" << layers_.size() << "\n";
   for (size_t i = 0; i < layers_.size(); i++) {
     const DrmHwcLayer &layer = layers_[i];
@@ -552,12 +267,7 @@
     *out << " transform=";
     DumpTransform(layer.transform, out);
     *out << " blending[a=" << (int)layer.alpha
-         << "]=" << BlendingToString(layer.blending) << " source_crop";
-    layer.source_crop.Dump(out);
-    *out << " display_frame";
-    layer.display_frame.Dump(out);
-
-    *out << "\n";
+         << "]=" << BlendingToString(layer.blending) << "\n";
   }
 
   *out << "    Planes: count=" << composition_planes_.size() << "\n";
@@ -573,12 +283,6 @@
       case DrmCompositionPlane::Type::kLayer:
         *out << "LAYER";
         break;
-      case DrmCompositionPlane::Type::kPrecomp:
-        *out << "PRECOMP";
-        break;
-      case DrmCompositionPlane::Type::kSquash:
-        *out << "SQUASH";
-        break;
       default:
         *out << "<invalid>";
         break;
@@ -590,19 +294,5 @@
     }
     *out << "\n";
   }
-
-  *out << "    Squash Regions: count=" << squash_regions_.size() << "\n";
-  for (size_t i = 0; i < squash_regions_.size(); i++) {
-    *out << "      [" << i << "] ";
-    DumpRegion(squash_regions_[i], out);
-    *out << "\n";
-  }
-
-  *out << "    Pre-Comp Regions: count=" << pre_comp_regions_.size() << "\n";
-  for (size_t i = 0; i < pre_comp_regions_.size(); i++) {
-    *out << "      [" << i << "] ";
-    DumpRegion(pre_comp_regions_[i], out);
-    *out << "\n";
-  }
 }
 }
diff --git a/drmdisplaycomposition.h b/drmdisplaycomposition.h
index 13da19d..b4c5892 100644
--- a/drmdisplaycomposition.h
+++ b/drmdisplaycomposition.h
@@ -20,12 +20,10 @@
 #include "drmcrtc.h"
 #include "drmhwcomposer.h"
 #include "drmplane.h"
-#include "glworker.h"
 
 #include <sstream>
 #include <vector>
 
-#include <hardware/gralloc.h>
 #include <hardware/hardware.h>
 #include <hardware/hwcomposer.h>
 
@@ -42,8 +40,17 @@
   DRM_COMPOSITION_TYPE_MODESET,
 };
 
+struct DrmCompositionDisplayLayersMap {
+  int display;
+  bool geometry_changed = true;
+  std::vector<DrmHwcLayer> layers;
+
+  DrmCompositionDisplayLayersMap() = default;
+  DrmCompositionDisplayLayersMap(DrmCompositionDisplayLayersMap &&rhs) =
+      default;
+};
+
 struct DrmCompositionRegion {
-  DrmHwcRect<int> frame;
   std::vector<size_t> source_layers;
 };
 
@@ -52,8 +59,6 @@
   enum class Type : int32_t {
     kDisable,
     kLayer,
-    kPrecomp,
-    kSquash,
   };
 
   DrmCompositionPlane() = default;
@@ -115,34 +120,13 @@
   int SetDpmsMode(uint32_t dpms_mode);
   int SetDisplayMode(const DrmMode &display_mode);
 
-  int Plan(SquashState *squash, std::vector<DrmPlane *> *primary_planes,
+  int Plan(std::vector<DrmPlane *> *primary_planes,
            std::vector<DrmPlane *> *overlay_planes);
 
-  int FinalizeComposition();
-
-  int CreateNextTimelineFence();
-  int SignalSquashDone() {
-    return IncreaseTimelineToPoint(timeline_squash_done_);
-  }
-  int SignalPreCompDone() {
-    return IncreaseTimelineToPoint(timeline_pre_comp_done_);
-  }
-  int SignalCompositionDone() {
-    return IncreaseTimelineToPoint(timeline_);
-  }
-
   std::vector<DrmHwcLayer> &layers() {
     return layers_;
   }
 
-  std::vector<DrmCompositionRegion> &squash_regions() {
-    return squash_regions_;
-  }
-
-  std::vector<DrmCompositionRegion> &pre_comp_regions() {
-    return pre_comp_regions_;
-  }
-
   std::vector<DrmCompositionPlane> &composition_planes() {
     return composition_planes_;
   }
@@ -179,18 +163,19 @@
     return planner_;
   }
 
+  int take_out_fence() {
+    return out_fence_.Release();
+  }
+
+  void set_out_fence(int out_fence) {
+    out_fence_.Set(out_fence);
+  }
+
   void Dump(std::ostringstream *out) const;
 
  private:
   bool validate_composition_type(DrmCompositionType desired);
 
-  int IncreaseTimelineToPoint(int point);
-
-  int FinalizeComposition(DrmHwcRect<int> *exclude_rects,
-                          size_t num_exclude_rects);
-  void SeparateLayers(DrmHwcRect<int> *exclude_rects, size_t num_exclude_rects);
-  int CreateAndAssignReleaseFences();
-
   DrmResources *drm_ = NULL;
   DrmCrtc *crtc_ = NULL;
   Importer *importer_ = NULL;
@@ -200,16 +185,10 @@
   uint32_t dpms_mode_ = DRM_MODE_DPMS_ON;
   DrmMode display_mode_;
 
-  int timeline_fd_ = -1;
-  int timeline_ = 0;
-  int timeline_current_ = 0;
-  int timeline_squash_done_ = 0;
-  int timeline_pre_comp_done_ = 0;
+  UniqueFd out_fence_ = -1;
 
   bool geometry_changed_;
   std::vector<DrmHwcLayer> layers_;
-  std::vector<DrmCompositionRegion> squash_regions_;
-  std::vector<DrmCompositionRegion> pre_comp_regions_;
   std::vector<DrmCompositionPlane> composition_planes_;
 
   uint64_t frame_no_ = 0;
diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index 14b87aa..e7e0694 100644
--- a/drmdisplaycompositor.cpp
+++ b/drmdisplaycompositor.cpp
@@ -19,215 +19,33 @@
 
 #include "drmdisplaycompositor.h"
 
+#include <pthread.h>
 #include <sched.h>
 #include <stdlib.h>
 #include <time.h>
-#include <algorithm>
-#include <bitset>
-#include <cinttypes>
-#include <mutex>
 #include <sstream>
 #include <vector>
 
-#include <cutils/log.h>
+#include <log/log.h>
 #include <drm/drm_mode.h>
 #include <sync/sync.h>
 #include <utils/Trace.h>
 
+#include "autolock.h"
 #include "drmcrtc.h"
 #include "drmplane.h"
 #include "drmresources.h"
-#include "glworker.h"
-
-#define DRM_DISPLAY_COMPOSITOR_MAX_QUEUE_DEPTH 2
 
 namespace android {
 
-static const int64_t kSquashWait = 500LL;
-
-void SquashState::Init(DrmHwcLayer *layers, size_t num_layers) {
-  generation_number_++;
-  valid_history_ = 0;
-  regions_.clear();
-  last_handles_.clear();
-
-  std::vector<DrmHwcRect<int>> in_rects;
-  for (size_t i = 0; i < num_layers; i++) {
-    DrmHwcLayer *layer = &layers[i];
-    in_rects.emplace_back(layer->display_frame);
-    last_handles_.push_back(layer->sf_handle);
-  }
-
-  std::vector<separate_rects::RectSet<uint64_t, int>> out_regions;
-  separate_rects::separate_rects_64(in_rects, &out_regions);
-
-  for (const separate_rects::RectSet<uint64_t, int> &out_region : out_regions) {
-    regions_.emplace_back();
-    Region &region = regions_.back();
-    region.rect = out_region.rect;
-    region.layer_refs = out_region.id_set.getBits();
-  }
-}
-
-void SquashState::GenerateHistory(DrmHwcLayer *layers, size_t num_layers,
-                                  std::vector<bool> &changed_regions) const {
-  changed_regions.resize(regions_.size());
-  if (num_layers != last_handles_.size()) {
-    ALOGE("SquashState::GenerateHistory expected %zu layers but got %zu layers",
-          last_handles_.size(), num_layers);
-    return;
-  }
-  std::bitset<kMaxLayers> changed_layers;
-  for (size_t i = 0; i < last_handles_.size(); i++) {
-    DrmHwcLayer *layer = &layers[i];
-    // Protected layers can't be squashed so we treat them as constantly
-    // changing.
-    if (layer->protected_usage() || last_handles_[i] != layer->sf_handle)
-      changed_layers.set(i);
-  }
-
-  for (size_t i = 0; i < regions_.size(); i++) {
-    changed_regions[i] = (regions_[i].layer_refs & changed_layers).any();
-  }
-}
-
-void SquashState::StableRegionsWithMarginalHistory(
-    const std::vector<bool> &changed_regions,
-    std::vector<bool> &stable_regions) const {
-  stable_regions.resize(regions_.size());
-  for (size_t i = 0; i < regions_.size(); i++) {
-    stable_regions[i] = !changed_regions[i] && is_stable(i);
-  }
-}
-
-void SquashState::RecordHistory(DrmHwcLayer *layers, size_t num_layers,
-                                const std::vector<bool> &changed_regions) {
-  if (num_layers != last_handles_.size()) {
-    ALOGE("SquashState::RecordHistory expected %zu layers but got %zu layers",
-          last_handles_.size(), num_layers);
-    return;
-  }
-  if (changed_regions.size() != regions_.size()) {
-    ALOGE("SquashState::RecordHistory expected %zu regions but got %zu regions",
-          regions_.size(), changed_regions.size());
-    return;
-  }
-
-  for (size_t i = 0; i < last_handles_.size(); i++) {
-    DrmHwcLayer *layer = &layers[i];
-    last_handles_[i] = layer->sf_handle;
-  }
-
-  for (size_t i = 0; i < regions_.size(); i++) {
-    regions_[i].change_history <<= 1;
-    regions_[i].change_history.set(/* LSB */ 0, changed_regions[i]);
-  }
-
-  valid_history_++;
-}
-
-bool SquashState::RecordAndCompareSquashed(
-    const std::vector<bool> &squashed_regions) {
-  if (squashed_regions.size() != regions_.size()) {
-    ALOGE(
-        "SquashState::RecordAndCompareSquashed expected %zu regions but got "
-        "%zu regions",
-        regions_.size(), squashed_regions.size());
-    return false;
-  }
-  bool changed = false;
-  for (size_t i = 0; i < regions_.size(); i++) {
-    if (regions_[i].squashed != squashed_regions[i]) {
-      regions_[i].squashed = squashed_regions[i];
-      changed = true;
-    }
-  }
-  return changed;
-}
-
-void SquashState::Dump(std::ostringstream *out) const {
-  *out << "----SquashState generation=" << generation_number_
-       << " history=" << valid_history_ << "\n"
-       << "    Regions: count=" << regions_.size() << "\n";
-  for (size_t i = 0; i < regions_.size(); i++) {
-    const Region &region = regions_[i];
-    *out << "      [" << i << "]"
-         << " history=" << region.change_history << " rect";
-    region.rect.Dump(out);
-    *out << " layers=(";
-    bool first = true;
-    for (size_t layer_index = 0; layer_index < kMaxLayers; layer_index++) {
-      if ((region.layer_refs &
-           std::bitset<kMaxLayers>((size_t)1 << layer_index))
-              .any()) {
-        if (!first)
-          *out << " ";
-        first = false;
-        *out << layer_index;
-      }
-    }
-    *out << ")";
-    if (region.squashed)
-      *out << " squashed";
-    *out << "\n";
-  }
-}
-
-static bool UsesSquash(const std::vector<DrmCompositionPlane> &comp_planes) {
-  return std::any_of(comp_planes.begin(), comp_planes.end(),
-                     [](const DrmCompositionPlane &plane) {
-    return plane.type() == DrmCompositionPlane::Type::kSquash;
-  });
-}
-
-DrmDisplayCompositor::FrameWorker::FrameWorker(DrmDisplayCompositor *compositor)
-    : QueueWorker("frame-worker", HAL_PRIORITY_URGENT_DISPLAY),
-      compositor_(compositor) {
-}
-
-int DrmDisplayCompositor::FrameWorker::Init() {
-  set_max_queue_size(DRM_DISPLAY_COMPOSITOR_MAX_QUEUE_DEPTH);
-  return InitWorker();
-}
-
-void DrmDisplayCompositor::FrameWorker::QueueFrame(
-    std::unique_ptr<DrmDisplayComposition> composition, int status) {
-  std::unique_ptr<FrameState> frame(
-      new FrameState(std::move(composition), status));
-
-  auto start = std::chrono::high_resolution_clock::now();
-  int ret = QueueWork(std::move(frame));
-  if (ret) {
-    ALOGE("Unable to queue frame work (%d)", ret);
-    // TODO: error handling (timeout or exit)
-    return;
-  }
-  auto end = std::chrono::high_resolution_clock::now();
-
-  uint64_t duration_us =
-      std::chrono::duration_cast<std::chrono::microseconds>(end - start)
-          .count();
-  if (duration_us > max_duration_us)
-    max_duration_us = duration_us;
-}
-
-void DrmDisplayCompositor::FrameWorker::ProcessWork(
-    std::unique_ptr<FrameState> frame) {
-  compositor_->ApplyFrame(std::move(frame->composition), frame->status);
-}
-
 DrmDisplayCompositor::DrmDisplayCompositor()
-    : QueueWorker("drm-compositor", HAL_PRIORITY_URGENT_DISPLAY),
-      drm_(NULL),
+    : drm_(NULL),
       display_(-1),
-      frame_worker_(this),
+      initialized_(false),
       active_(false),
       use_hw_overlays_(true),
-      framebuffer_index_(0),
-      squash_framebuffer_index_(0),
       dump_frames_composited_(0),
-      dump_last_timestamp_ns_(0),
-      max_duration_us(0) {
+      dump_last_timestamp_ns_(0) {
   struct timespec ts;
   if (clock_gettime(CLOCK_MONOTONIC, &ts))
     return;
@@ -235,13 +53,12 @@
 }
 
 DrmDisplayCompositor::~DrmDisplayCompositor() {
-  if (!initialized())
+  if (!initialized_)
     return;
 
-  frame_worker_.Exit();
-  Exit();
-
-  std::lock_guard<std::mutex> lk(mutex_);
+  int ret = pthread_mutex_lock(&lock_);
+  if (ret)
+    ALOGE("Failed to acquire compositor lock %d", ret);
 
   if (mode_.blob_id)
     drm_->DestroyPropertyBlob(mode_.blob_id);
@@ -249,18 +66,26 @@
     drm_->DestroyPropertyBlob(mode_.old_blob_id);
 
   active_composition_.reset();
+
+  ret = pthread_mutex_unlock(&lock_);
+  if (ret)
+    ALOGE("Failed to acquire compositor lock %d", ret);
+
+  pthread_mutex_destroy(&lock_);
 }
 
 int DrmDisplayCompositor::Init(DrmResources *drm, int display) {
   drm_ = drm;
   display_ = display;
 
-  frame_worker_.Init();
+  int ret = pthread_mutex_init(&lock_, NULL);
+  if (ret) {
+    ALOGE("Failed to initialize drm compositor lock %d\n", ret);
+    return ret;
+  }
 
-  set_max_queue_size(DRM_DISPLAY_COMPOSITOR_MAX_QUEUE_DEPTH);
-  set_idle_timeout(kSquashWait);
-
-  return InitWorker();
+  initialized_ = true;
+  return 0;
 }
 
 std::unique_ptr<DrmDisplayComposition> DrmDisplayCompositor::CreateComposition()
@@ -268,49 +93,6 @@
   return std::unique_ptr<DrmDisplayComposition>(new DrmDisplayComposition());
 }
 
-int DrmDisplayCompositor::QueueComposition(
-    std::unique_ptr<DrmDisplayComposition> composition) {
-  switch (composition->type()) {
-    case DRM_COMPOSITION_TYPE_FRAME:
-      if (!active_)
-        return -ENODEV;
-      break;
-    case DRM_COMPOSITION_TYPE_DPMS:
-      /*
-       * Update the state as soon as we get it so we can start/stop queuing
-       * frames asap.
-       */
-      active_ = (composition->dpms_mode() == DRM_MODE_DPMS_ON);
-      break;
-    case DRM_COMPOSITION_TYPE_MODESET:
-      break;
-    case DRM_COMPOSITION_TYPE_EMPTY:
-      return 0;
-    default:
-      ALOGE("Unknown composition type %d/%d", composition->type(), display_);
-      return -ENOENT;
-  }
-
-  auto start = std::chrono::high_resolution_clock::now();
-
-  int ret = QueueWork(std::move(composition));
-  if (ret) {
-    ALOGE("Unable to queue work (%d)", ret);
-    // TODO: error handling (timeout or exit)
-    return ret;
-  }
-
-  auto end = std::chrono::high_resolution_clock::now();
-
-  uint64_t duration_us =
-      std::chrono::duration_cast<std::chrono::microseconds>(end - start)
-          .count();
-  if (duration_us > max_duration_us)
-    max_duration_us = duration_us;
-
-  return 0;
-}
-
 std::tuple<uint32_t, uint32_t, int>
 DrmDisplayCompositor::GetActiveModeResolution() {
   DrmConnector *connector = drm_->GetConnectorForDisplay(display_);
@@ -324,110 +106,6 @@
   return std::make_tuple(mode.h_display(), mode.v_display(), 0);
 }
 
-int DrmDisplayCompositor::PrepareFramebuffer(
-    DrmFramebuffer &fb, DrmDisplayComposition *display_comp) {
-  int ret = fb.WaitReleased(-1);
-  if (ret) {
-    ALOGE("Failed to wait for framebuffer release %d", ret);
-    return ret;
-  }
-  uint32_t width, height;
-  std::tie(width, height, ret) = GetActiveModeResolution();
-  if (ret) {
-    ALOGE(
-        "Failed to allocate framebuffer because the display resolution could "
-        "not be determined %d",
-        ret);
-    return ret;
-  }
-
-  fb.set_release_fence_fd(-1);
-  if (!fb.Allocate(width, height)) {
-    ALOGE("Failed to allocate framebuffer with size %dx%d", width, height);
-    return -ENOMEM;
-  }
-
-  display_comp->layers().emplace_back();
-  DrmHwcLayer &pre_comp_layer = display_comp->layers().back();
-  pre_comp_layer.sf_handle = fb.buffer()->handle;
-  pre_comp_layer.blending = DrmHwcBlending::kPreMult;
-  pre_comp_layer.source_crop = DrmHwcRect<float>(0, 0, width, height);
-  pre_comp_layer.display_frame = DrmHwcRect<int>(0, 0, width, height);
-  ret = pre_comp_layer.buffer.ImportBuffer(fb.buffer()->handle,
-                                           display_comp->importer());
-  if (ret) {
-    ALOGE("Failed to import framebuffer for display %d", ret);
-    return ret;
-  }
-
-  return ret;
-}
-
-int DrmDisplayCompositor::ApplySquash(DrmDisplayComposition *display_comp) {
-  int ret = 0;
-
-  DrmFramebuffer &fb = squash_framebuffers_[squash_framebuffer_index_];
-  ret = PrepareFramebuffer(fb, display_comp);
-  if (ret) {
-    ALOGE("Failed to prepare framebuffer for squash %d", ret);
-    return ret;
-  }
-
-  std::vector<DrmCompositionRegion> &regions = display_comp->squash_regions();
-  ret = pre_compositor_->Composite(display_comp->layers().data(),
-                                   regions.data(), regions.size(), fb.buffer());
-  pre_compositor_->Finish();
-
-  if (ret) {
-    ALOGE("Failed to squash layers");
-    return ret;
-  }
-
-  ret = display_comp->CreateNextTimelineFence();
-  if (ret <= 0) {
-    ALOGE("Failed to create squash framebuffer release fence %d", ret);
-    return ret;
-  }
-
-  fb.set_release_fence_fd(ret);
-  display_comp->SignalSquashDone();
-
-  return 0;
-}
-
-int DrmDisplayCompositor::ApplyPreComposite(
-    DrmDisplayComposition *display_comp) {
-  int ret = 0;
-
-  DrmFramebuffer &fb = framebuffers_[framebuffer_index_];
-  ret = PrepareFramebuffer(fb, display_comp);
-  if (ret) {
-    ALOGE("Failed to prepare framebuffer for pre-composite %d", ret);
-    return ret;
-  }
-
-  std::vector<DrmCompositionRegion> &regions = display_comp->pre_comp_regions();
-  ret = pre_compositor_->Composite(display_comp->layers().data(),
-                                   regions.data(), regions.size(), fb.buffer());
-  pre_compositor_->Finish();
-
-  if (ret) {
-    ALOGE("Failed to pre-composite layers");
-    return ret;
-  }
-
-  ret = display_comp->CreateNextTimelineFence();
-  if (ret <= 0) {
-    ALOGE("Failed to create pre-composite framebuffer release fence %d", ret);
-    return ret;
-  }
-
-  fb.set_release_fence_fd(ret);
-  display_comp->SignalPreCompDone();
-
-  return 0;
-}
-
 int DrmDisplayCompositor::DisablePlanes(DrmDisplayComposition *display_comp) {
   drmModeAtomicReqPtr pset = drmModeAtomicAlloc();
   if (!pset) {
@@ -462,94 +140,6 @@
   return 0;
 }
 
-int DrmDisplayCompositor::PrepareFrame(DrmDisplayComposition *display_comp) {
-  int ret = 0;
-
-  std::vector<DrmHwcLayer> &layers = display_comp->layers();
-  std::vector<DrmCompositionPlane> &comp_planes =
-      display_comp->composition_planes();
-  std::vector<DrmCompositionRegion> &squash_regions =
-      display_comp->squash_regions();
-  std::vector<DrmCompositionRegion> &pre_comp_regions =
-      display_comp->pre_comp_regions();
-
-  int squash_layer_index = -1;
-  if (squash_regions.size() > 0) {
-    squash_framebuffer_index_ = (squash_framebuffer_index_ + 1) % 2;
-    ret = ApplySquash(display_comp);
-    if (ret)
-      return ret;
-
-    squash_layer_index = layers.size() - 1;
-  } else {
-    if (UsesSquash(comp_planes)) {
-      DrmFramebuffer &fb = squash_framebuffers_[squash_framebuffer_index_];
-      layers.emplace_back();
-      squash_layer_index = layers.size() - 1;
-      DrmHwcLayer &squash_layer = layers.back();
-      ret = squash_layer.buffer.ImportBuffer(fb.buffer()->handle,
-                                             display_comp->importer());
-      if (ret) {
-        ALOGE("Failed to import old squashed framebuffer %d", ret);
-        return ret;
-      }
-      squash_layer.sf_handle = fb.buffer()->handle;
-      squash_layer.blending = DrmHwcBlending::kPreMult;
-      squash_layer.source_crop = DrmHwcRect<float>(
-          0, 0, squash_layer.buffer->width, squash_layer.buffer->height);
-      squash_layer.display_frame = DrmHwcRect<int>(
-          0, 0, squash_layer.buffer->width, squash_layer.buffer->height);
-      ret = display_comp->CreateNextTimelineFence();
-
-      if (ret <= 0) {
-        ALOGE("Failed to create squash framebuffer release fence %d", ret);
-        return ret;
-      }
-
-      fb.set_release_fence_fd(ret);
-      ret = 0;
-    }
-  }
-
-  bool do_pre_comp = pre_comp_regions.size() > 0;
-  int pre_comp_layer_index = -1;
-  if (do_pre_comp) {
-    ret = ApplyPreComposite(display_comp);
-    if (ret)
-      return ret;
-
-    pre_comp_layer_index = layers.size() - 1;
-    framebuffer_index_ = (framebuffer_index_ + 1) % DRM_DISPLAY_BUFFERS;
-  }
-
-  for (DrmCompositionPlane &comp_plane : comp_planes) {
-    std::vector<size_t> &source_layers = comp_plane.source_layers();
-    switch (comp_plane.type()) {
-      case DrmCompositionPlane::Type::kSquash:
-        if (source_layers.size())
-          ALOGE("Squash source_layers is expected to be empty (%zu/%d)",
-                source_layers[0], squash_layer_index);
-        source_layers.push_back(squash_layer_index);
-        break;
-      case DrmCompositionPlane::Type::kPrecomp:
-        if (!do_pre_comp) {
-          ALOGE(
-              "Can not use pre composite framebuffer with no pre composite "
-              "regions");
-          return -EINVAL;
-        }
-        // Replace source_layers with the output of the precomposite
-        source_layers.clear();
-        source_layers.push_back(pre_comp_layer_index);
-        break;
-      default:
-        break;
-    }
-  }
-
-  return ret;
-}
-
 int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
                                       bool test_only) {
   ATRACE_CALL();
@@ -559,8 +149,7 @@
   std::vector<DrmHwcLayer> &layers = display_comp->layers();
   std::vector<DrmCompositionPlane> &comp_planes =
       display_comp->composition_planes();
-  std::vector<DrmCompositionRegion> &pre_comp_regions =
-      display_comp->pre_comp_regions();
+  uint64_t out_fences[drm_->crtcs().size()];
 
   DrmConnector *connector = drm_->GetConnectorForDisplay(display_);
   if (!connector) {
@@ -579,7 +168,24 @@
     return -ENOMEM;
   }
 
+  if (crtc->out_fence_ptr_property().id() != 0) {
+    ret = drmModeAtomicAddProperty(pset, crtc->id(), crtc->out_fence_ptr_property().id(),
+                                   (uint64_t) &out_fences[crtc->pipe()]);
+    if (ret < 0) {
+      ALOGE("Failed to add OUT_FENCE_PTR property to pset: %d", ret);
+      drmModeAtomicFree(pset);
+      return ret;
+    }
+  }
+
   if (mode_.needs_modeset) {
+    ret = drmModeAtomicAddProperty(pset, crtc->id(), crtc->active_property().id(), 1);
+    if (ret < 0) {
+      ALOGE("Failed to add crtc active to pset\n");
+      drmModeAtomicFree(pset);
+      return ret;
+    }
+
     ret = drmModeAtomicAddProperty(pset, crtc->id(), crtc->mode_property().id(),
                                    mode_.blob_id) < 0 ||
           drmModeAtomicAddProperty(pset, connector->id(),
@@ -598,10 +204,11 @@
     std::vector<size_t> &source_layers = comp_plane.source_layers();
 
     int fb_id = -1;
-    DrmHwcRect<int> display_frame;
-    DrmHwcRect<float> source_crop;
+    int fence_fd = -1;
+    hwc_rect_t display_frame;
+    hwc_frect_t source_crop;
     uint64_t rotation = 0;
-    uint64_t alpha = 0xFF;
+    uint64_t alpha = 0xFFFF;
 
     if (comp_plane.type() != DrmCompositionPlane::Type::kDisable) {
       if (source_layers.size() > 1) {
@@ -616,28 +223,12 @@
         break;
       }
       DrmHwcLayer &layer = layers[source_layers.front()];
-      if (!test_only && layer.acquire_fence.get() >= 0) {
-        int acquire_fence = layer.acquire_fence.get();
-        int total_fence_timeout = 0;
-        for (int i = 0; i < kAcquireWaitTries; ++i) {
-          int fence_timeout = kAcquireWaitTimeoutMs * (1 << i);
-          total_fence_timeout += fence_timeout;
-          ret = sync_wait(acquire_fence, fence_timeout);
-          if (ret)
-            ALOGW("Acquire fence %d wait %d failed (%d). Total time %d",
-                  acquire_fence, i, ret, total_fence_timeout);
-        }
-        if (ret) {
-          ALOGE("Failed to wait for acquire %d/%d", acquire_fence, ret);
-          break;
-        }
-        layer.acquire_fence.Close();
-      }
       if (!layer.buffer) {
         ALOGE("Expected a valid framebuffer for pset");
         break;
       }
       fb_id = layer.buffer->fb_id;
+      fence_fd = layer.acquire_fence.get();
       display_frame = layer.display_frame;
       source_crop = layer.source_crop;
       if (layer.blending == DrmHwcBlending::kPreMult)
@@ -645,16 +236,32 @@
 
       rotation = 0;
       if (layer.transform & DrmHwcTransform::kFlipH)
-        rotation |= 1 << DRM_REFLECT_X;
+        rotation |= DRM_MODE_REFLECT_X;
       if (layer.transform & DrmHwcTransform::kFlipV)
-        rotation |= 1 << DRM_REFLECT_Y;
+        rotation |= DRM_MODE_REFLECT_Y;
       if (layer.transform & DrmHwcTransform::kRotate90)
-        rotation |= 1 << DRM_ROTATE_90;
+        rotation |= DRM_MODE_ROTATE_90;
       else if (layer.transform & DrmHwcTransform::kRotate180)
-        rotation |= 1 << DRM_ROTATE_180;
+        rotation |= DRM_MODE_ROTATE_180;
       else if (layer.transform & DrmHwcTransform::kRotate270)
-        rotation |= 1 << DRM_ROTATE_270;
+        rotation |= DRM_MODE_ROTATE_270;
+      else
+        rotation |= DRM_MODE_ROTATE_0;
+
+      if (fence_fd >= 0) {
+        int prop_id = plane->in_fence_fd_property().id();
+        if (prop_id == 0) {
+                ALOGE("Failed to get IN_FENCE_FD property id");
+                break;
+        }
+        ret = drmModeAtomicAddProperty(pset, plane->id(), prop_id, fence_fd);
+        if (ret < 0) {
+          ALOGE("Failed to add IN_FENCE_FD property to pset: %d", ret);
+          break;
+        }
+      }
     }
+
     // Disable the plane if there's no framebuffer
     if (fb_id < 0) {
       ret = drmModeAtomicAddProperty(pset, plane->id(),
@@ -669,15 +276,15 @@
     }
 
     // TODO: Once we have atomic test, this should fall back to GL
-    if (rotation && plane->rotation_property().id() == 0) {
-      ALOGE("Rotation is not supported on plane %d", plane->id());
+    if (rotation != DRM_MODE_ROTATE_0 && plane->rotation_property().id() == 0) {
+      ALOGV("Rotation is not supported on plane %d", plane->id());
       ret = -EINVAL;
       break;
     }
 
     // TODO: Once we have atomic test, this should fall back to GL
-    if (alpha != 0xFF && plane->alpha_property().id() == 0) {
-      ALOGE("Alpha is not supported on plane %d", plane->id());
+    if (alpha != 0xFFFF && plane->alpha_property().id() == 0) {
+      ALOGV("Alpha is not supported on plane %d", plane->id());
       ret = -EINVAL;
       break;
     }
@@ -738,7 +345,6 @@
     }
   }
 
-out:
   if (!ret) {
     uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
     if (test_only)
@@ -746,9 +352,7 @@
 
     ret = drmModeAtomicCommit(drm_->fd(), pset, flags, drm_);
     if (ret) {
-      if (test_only)
-        ALOGI("Commit test pset failed ret=%d\n", ret);
-      else
+      if (!test_only)
         ALOGE("Failed to commit pset ret=%d\n", ret);
       drmModeAtomicFree(pset);
       return ret;
@@ -778,6 +382,10 @@
     mode_.needs_modeset = false;
   }
 
+  if (crtc->out_fence_ptr_property().id()) {
+    display_comp->set_out_fence((int) out_fences[crtc->pipe()]);
+  }
+
   return ret;
 }
 
@@ -816,15 +424,17 @@
 }
 
 void DrmDisplayCompositor::ClearDisplay() {
-  std::lock_guard<std::mutex> lk(mutex_);
+  AutoLock lock(&lock_, "compositor");
+  int ret = lock.Lock();
+  if (ret)
+    return;
+
   if (!active_composition_)
     return;
 
   if (DisablePlanes(active_composition_.get()))
     return;
 
-  active_composition_->SignalCompositionDone();
-
   active_composition_.reset(NULL);
 }
 
@@ -844,68 +454,41 @@
   }
   ++dump_frames_composited_;
 
-  if (active_composition_)
-    active_composition_->SignalCompositionDone();
+  ret = pthread_mutex_lock(&lock_);
+  if (ret)
+    ALOGE("Failed to acquire lock for active_composition swap");
 
-  std::lock_guard<std::mutex> lk(mutex_);
   active_composition_.swap(composition);
+
+  if (!ret)
+    ret = pthread_mutex_unlock(&lock_);
+  if (ret)
+    ALOGE("Failed to release lock for active_composition swap");
 }
 
-void DrmDisplayCompositor::ProcessWork(
+int DrmDisplayCompositor::ApplyComposition(
     std::unique_ptr<DrmDisplayComposition> composition) {
-  ATRACE_CALL();
-
-  if (!pre_compositor_) {
-    pre_compositor_.reset(new GLWorkerCompositor());
-    int ret = pre_compositor_->Init();
-    if (ret) {
-      ALOGE("Failed to initialize OpenGL compositor %d", ret);
-      return;
-    }
-  }
-
-  int ret;
+  int ret = 0;
   switch (composition->type()) {
     case DRM_COMPOSITION_TYPE_FRAME:
-      ret = PrepareFrame(composition.get());
-      if (ret) {
-        ALOGE("Failed to prepare frame for display %d", display_);
-        return;
-      }
       if (composition->geometry_changed()) {
         // Send the composition to the kernel to ensure we can commit it. This
-        // is just a test, it won't actually commit the frame. If rejected,
-        // squash the frame into one layer and use the squashed composition
+        // is just a test, it won't actually commit the frame.
         ret = CommitFrame(composition.get(), true);
-        if (ret)
-          ALOGI("Commit test failed, squashing frame for display %d", display_);
-        use_hw_overlays_ = !ret;
-      }
-
-      // If use_hw_overlays_ is false, we can't use hardware to composite the
-      // frame. So squash all layers into a single composition and queue that
-      // instead.
-      if (!use_hw_overlays_) {
-        std::unique_ptr<DrmDisplayComposition> squashed = CreateComposition();
-        ret = SquashFrame(composition.get(), squashed.get());
-        if (!ret) {
-          composition = std::move(squashed);
-        } else {
-          ALOGE("Failed to squash frame for display %d", display_);
-          // Disable the hw used by the last active composition. This allows us
-          // to signal the release fences from that composition to avoid
-          // hanging.
-          ClearDisplay();
-          return;
+        if (ret) {
+          ALOGE("Commit test failed for display %d, FIXME", display_);
+          return ret;
         }
       }
-      frame_worker_.QueueFrame(std::move(composition), ret);
+
+      ApplyFrame(std::move(composition), ret);
       break;
     case DRM_COMPOSITION_TYPE_DPMS:
+      active_ = (composition->dpms_mode() == DRM_MODE_DPMS_ON);
       ret = ApplyDpms(composition.get());
       if (ret)
         ALOGE("Failed to apply dpms for display %d", display_);
-      break;
+      return ret;
     case DRM_COMPOSITION_TYPE_MODESET:
       mode_.mode = composition->display_mode();
       if (mode_.blob_id)
@@ -913,170 +496,34 @@
       std::tie(ret, mode_.blob_id) = CreateModeBlob(mode_.mode);
       if (ret) {
         ALOGE("Failed to create mode blob for display %d", display_);
-        return;
+        return ret;
       }
       mode_.needs_modeset = true;
-      break;
+      return 0;
     default:
       ALOGE("Unknown composition type %d", composition->type());
-      break;
+      return -EINVAL;
   }
-}
-
-int DrmDisplayCompositor::SquashAll() {
-  std::unique_lock<std::mutex> lk(mutex_);
-  int ret;
-
-  if (!active_composition_)
-    return 0;
-
-  std::unique_ptr<DrmDisplayComposition> comp = CreateComposition();
-  ret = SquashFrame(active_composition_.get(), comp.get());
-
-  // ApplyFrame needs the lock
-  lk.unlock();
-
-  if (!ret)
-    ApplyFrame(std::move(comp), 0);
 
   return ret;
 }
 
-// Returns:
-//   - 0 if src is successfully squashed into dst
-//   - -EALREADY if the src is already squashed
-//   - Appropriate error if the squash fails
-int DrmDisplayCompositor::SquashFrame(DrmDisplayComposition *src,
-                                      DrmDisplayComposition *dst) {
-  if (src->type() != DRM_COMPOSITION_TYPE_FRAME)
-    return -ENOTSUP;
-
-  std::vector<DrmCompositionPlane> &src_planes = src->composition_planes();
-  std::vector<DrmHwcLayer> &src_layers = src->layers();
-
-  // Make sure there is more than one layer to squash.
-  size_t src_planes_with_layer = std::count_if(
-      src_planes.begin(), src_planes.end(), [](DrmCompositionPlane &p) {
-        return p.type() != DrmCompositionPlane::Type::kDisable;
-      });
-  if (src_planes_with_layer <= 1)
-    return -EALREADY;
-
-  int pre_comp_layer_index;
-
-  int ret = dst->Init(drm_, src->crtc(), src->importer(), src->planner(),
-                      src->frame_no());
-  if (ret) {
-    ALOGE("Failed to init squash all composition %d", ret);
-    return ret;
-  }
-
-  DrmCompositionPlane squashed_comp(DrmCompositionPlane::Type::kPrecomp, NULL,
-                                    src->crtc());
-  std::vector<DrmHwcLayer> dst_layers;
-  for (DrmCompositionPlane &comp_plane : src_planes) {
-    // Composition planes without DRM planes should never happen
-    if (comp_plane.plane() == NULL) {
-      ALOGE("Skipping squash all because of NULL plane");
-      ret = -EINVAL;
-      goto move_layers_back;
-    }
-
-    if (comp_plane.plane()->type() == DRM_PLANE_TYPE_PRIMARY)
-      squashed_comp.set_plane(comp_plane.plane());
-    else
-      dst->AddPlaneDisable(comp_plane.plane());
-
-    if (comp_plane.type() == DrmCompositionPlane::Type::kDisable)
-      continue;
-
-    for (auto i : comp_plane.source_layers()) {
-      DrmHwcLayer &layer = src_layers[i];
-
-      // Squashing protected layers is impossible.
-      if (layer.protected_usage()) {
-        ret = -ENOTSUP;
-        goto move_layers_back;
-      }
-
-      // The OutputFds point to freed memory after hwc_set returns. They are
-      // returned to the default to prevent DrmDisplayComposition::Plan from
-      // filling the OutputFds.
-      layer.release_fence = OutputFd();
-      dst_layers.emplace_back(std::move(layer));
-      squashed_comp.source_layers().push_back(
-          squashed_comp.source_layers().size());
-    }
-  }
-
-  if (squashed_comp.plane() == NULL) {
-    ALOGE("Primary plane not found for squash");
-    ret = -ENOTSUP;
-    goto move_layers_back;
-  }
-
-  ret = dst->SetLayers(dst_layers.data(), dst_layers.size(), false);
-  if (ret) {
-    ALOGE("Failed to set layers for squash all composition %d", ret);
-    goto move_layers_back;
-  }
-
-  ret = dst->AddPlaneComposition(std::move(squashed_comp));
-  if (ret) {
-    ALOGE("Failed to add squashed plane composition %d", ret);
-    goto move_layers_back;
-  }
-
-  ret = dst->FinalizeComposition();
-  if (ret) {
-    ALOGE("Failed to plan for squash all composition %d", ret);
-    goto move_layers_back;
-  }
-
-  ret = ApplyPreComposite(dst);
-  if (ret) {
-    ALOGE("Failed to pre-composite for squash all composition %d", ret);
-    goto move_layers_back;
-  }
-
-  pre_comp_layer_index = dst->layers().size() - 1;
-  framebuffer_index_ = (framebuffer_index_ + 1) % DRM_DISPLAY_BUFFERS;
-
-  for (DrmCompositionPlane &plane : dst->composition_planes()) {
-    if (plane.type() == DrmCompositionPlane::Type::kPrecomp) {
-      // Replace source_layers with the output of the precomposite
-      plane.source_layers().clear();
-      plane.source_layers().push_back(pre_comp_layer_index);
-      break;
-    }
-  }
-
-  return 0;
-
-// TODO(zachr): think of a better way to transfer ownership back to the active
-// composition.
-move_layers_back:
-  for (size_t plane_index = 0;
-       plane_index < src_planes.size() && plane_index < dst_layers.size();) {
-    if (src_planes[plane_index].source_layers().empty()) {
-      plane_index++;
-      continue;
-    }
-    for (auto i : src_planes[plane_index].source_layers())
-      src_layers[i] = std::move(dst_layers[plane_index++]);
-  }
-
-  return ret;
+int DrmDisplayCompositor::TestComposition(DrmDisplayComposition *composition) {
+  return CommitFrame(composition, true);
 }
 
 void DrmDisplayCompositor::Dump(std::ostringstream *out) const {
-  std::lock_guard<std::mutex> lk(mutex_);
+  int ret = pthread_mutex_lock(&lock_);
+  if (ret)
+    return;
+
   uint64_t num_frames = dump_frames_composited_;
   dump_frames_composited_ = 0;
 
   struct timespec ts;
-  int ret = clock_gettime(CLOCK_MONOTONIC, &ts);
+  ret = clock_gettime(CLOCK_MONOTONIC, &ts);
   if (ret) {
+    pthread_mutex_unlock(&lock_);
     return;
   }
 
@@ -1090,21 +537,6 @@
 
   dump_last_timestamp_ns_ = cur_ts;
 
-  *out << "----Jank Stats: "
-       << " compositor_max_q_wait_us=" << max_duration_us
-       << " frameworker_max_q_wait_us=" << frame_worker_.max_duration_us
-       << "\n";
-
-  max_duration_us = 0;
-  frame_worker_.max_duration_us = 0;
-
-  if (active_composition_)
-    active_composition_->Dump(out);
-
-  squash_state_.Dump(out);
-}
-
-void DrmDisplayCompositor::ProcessIdle() {
-  SquashAll();
+  pthread_mutex_unlock(&lock_);
 }
 }
diff --git a/drmdisplaycompositor.h b/drmdisplaycompositor.h
index 961fe72..0d85949 100644
--- a/drmdisplaycompositor.h
+++ b/drmdisplaycompositor.h
@@ -17,15 +17,12 @@
 #ifndef ANDROID_DRM_DISPLAY_COMPOSITOR_H_
 #define ANDROID_DRM_DISPLAY_COMPOSITOR_H_
 
-#include "drmcomposition.h"
-#include "drmframebuffer.h"
 #include "drmhwcomposer.h"
-#include "queue_worker.h"
-#include "separate_rects.h"
+#include "drmdisplaycomposition.h"
+#include "drmframebuffer.h"
 
-#include <chrono>
+#include <pthread.h>
 #include <memory>
-#include <queue>
 #include <sstream>
 #include <tuple>
 
@@ -38,50 +35,7 @@
 
 namespace android {
 
-class GLWorkerCompositor;
-
-class SquashState {
- public:
-  static const unsigned kHistoryLength = 6;  // TODO: make this number not magic
-  static const unsigned kMaxLayers = 64;
-
-  struct Region {
-    DrmHwcRect<int> rect;
-    std::bitset<kMaxLayers> layer_refs;
-    std::bitset<kHistoryLength> change_history;
-    bool squashed = false;
-  };
-
-  bool is_stable(int region_index) const {
-    return valid_history_ >= kHistoryLength &&
-           regions_[region_index].change_history.none();
-  }
-
-  const std::vector<Region> &regions() const {
-    return regions_;
-  }
-
-  void Init(DrmHwcLayer *layers, size_t num_layers);
-  void GenerateHistory(DrmHwcLayer *layers, size_t num_layers,
-                       std::vector<bool> &changed_regions) const;
-  void StableRegionsWithMarginalHistory(
-      const std::vector<bool> &changed_regions,
-      std::vector<bool> &stable_regions) const;
-  void RecordHistory(DrmHwcLayer *layers, size_t num_layers,
-                     const std::vector<bool> &changed_regions);
-  bool RecordAndCompareSquashed(const std::vector<bool> &squashed_regions);
-
-  void Dump(std::ostringstream *out) const;
-
- private:
-  size_t generation_number_ = 0;
-  unsigned valid_history_ = 0;
-  std::vector<buffer_handle_t> last_handles_;
-
-  std::vector<Region> regions_;
-};
-
-class DrmDisplayCompositor : public QueueWorker<DrmDisplayComposition> {
+class DrmDisplayCompositor {
  public:
   DrmDisplayCompositor();
   ~DrmDisplayCompositor();
@@ -89,45 +43,14 @@
   int Init(DrmResources *drm, int display);
 
   std::unique_ptr<DrmDisplayComposition> CreateComposition() const;
-  int QueueComposition(std::unique_ptr<DrmDisplayComposition> composition);
-  void ProcessWork(std::unique_ptr<DrmDisplayComposition> composition);
-  void ProcessIdle();
-  int SquashAll();
+  int ApplyComposition(std::unique_ptr<DrmDisplayComposition> composition);
+  int TestComposition(DrmDisplayComposition *composition);
+  int Composite();
   void Dump(std::ostringstream *out) const;
 
   std::tuple<uint32_t, uint32_t, int> GetActiveModeResolution();
 
-  SquashState *squash_state() {
-    return &squash_state_;
-  }
-
  private:
-  struct FrameState {
-    FrameState(std::unique_ptr<DrmDisplayComposition> composition, int status)
-        : composition(std::move(composition)), status(status) {
-    }
-
-    std::unique_ptr<DrmDisplayComposition> composition;
-    int status = 0;
-  };
-
-  class FrameWorker : public QueueWorker<FrameState> {
-   public:
-    FrameWorker(DrmDisplayCompositor *compositor);
-
-    int Init();
-    void QueueFrame(std::unique_ptr<DrmDisplayComposition> composition,
-                    int status);
-
-    mutable uint64_t max_duration_us;
-
-   protected:
-    void ProcessWork(std::unique_ptr<FrameState> frame);
-
-   private:
-    DrmDisplayCompositor *compositor_;
-  };
-
   struct ModeState {
     bool needs_modeset = false;
     DrmMode mode;
@@ -144,11 +67,8 @@
 
   int PrepareFramebuffer(DrmFramebuffer &fb,
                          DrmDisplayComposition *display_comp);
-  int ApplySquash(DrmDisplayComposition *display_comp);
-  int ApplyPreComposite(DrmDisplayComposition *display_comp);
   int PrepareFrame(DrmDisplayComposition *display_comp);
   int CommitFrame(DrmDisplayComposition *display_comp, bool test_only);
-  int SquashFrame(DrmDisplayComposition *src, DrmDisplayComposition *dst);
   int ApplyDpms(DrmDisplayComposition *display_comp);
   int DisablePlanes(DrmDisplayComposition *display_comp);
 
@@ -161,10 +81,9 @@
   DrmResources *drm_;
   int display_;
 
-  FrameWorker frame_worker_;
-
   std::unique_ptr<DrmDisplayComposition> active_composition_;
 
+  bool initialized_;
   bool active_;
   bool use_hw_overlays_;
 
@@ -172,20 +91,14 @@
 
   int framebuffer_index_;
   DrmFramebuffer framebuffers_[DRM_DISPLAY_BUFFERS];
-  std::unique_ptr<GLWorkerCompositor> pre_compositor_;
 
-  SquashState squash_state_;
-  int squash_framebuffer_index_;
-  DrmFramebuffer squash_framebuffers_[2];
-
-  // mutable since we need to acquire in HaveQueuedComposites
-  mutable std::mutex mutex_;
+  // mutable since we need to acquire in Dump()
+  mutable pthread_mutex_t lock_;
 
   // State tracking progress since our last Dump(). These are mutable since
   // we need to reset them on every Dump() call.
   mutable uint64_t dump_frames_composited_;
   mutable uint64_t dump_last_timestamp_ns_;
-  mutable uint64_t max_duration_us;
 };
 }
 
diff --git a/drmencoder.cpp b/drmencoder.cpp
index 1d4ebdc..3d762f3 100644
--- a/drmencoder.cpp
+++ b/drmencoder.cpp
@@ -27,7 +27,6 @@
                        const std::vector<DrmCrtc *> &possible_crtcs)
     : id_(e->encoder_id),
       crtc_(current_crtc),
-      type_(e->encoder_type),
       possible_crtcs_(possible_crtcs) {
 }
 
diff --git a/drmencoder.h b/drmencoder.h
index ed3c21e..58ccbfb 100644
--- a/drmencoder.h
+++ b/drmencoder.h
@@ -45,8 +45,6 @@
   uint32_t id_;
   DrmCrtc *crtc_;
 
-  uint32_t type_;
-
   std::vector<DrmCrtc *> possible_crtcs_;
 };
 }
diff --git a/drmeventlistener.cpp b/drmeventlistener.cpp
index a07bd89..9cdff81 100644
--- a/drmeventlistener.cpp
+++ b/drmeventlistener.cpp
@@ -14,18 +14,19 @@
  * limitations under the License.
  */
 
-#include <assert.h>
-
 #define LOG_TAG "hwc-drm-event-listener"
 
 #include "drmeventlistener.h"
 #include "drmresources.h"
 
+#include <assert.h>
+#include <errno.h>
 #include <linux/netlink.h>
 #include <sys/socket.h>
 
-#include <assert.h>
-#include <cutils/log.h>
+#include <log/log.h>
+#include <hardware/hardware.h>
+#include <hardware/hwcomposer.h>
 #include <xf86drm.h>
 
 namespace android {
@@ -45,7 +46,7 @@
   struct sockaddr_nl addr;
   memset(&addr, 0, sizeof(addr));
   addr.nl_family = AF_NETLINK;
-  addr.nl_pid = getpid();
+  addr.nl_pid = 0;
   addr.nl_groups = 0xFFFFFFFF;
 
   int ret = bind(uevent_fd_.get(), (struct sockaddr *)&addr, sizeof(addr));
@@ -126,7 +127,7 @@
 
   if (FD_ISSET(drm_->fd(), &fds_)) {
     drmEventContext event_context = {
-        .version = DRM_EVENT_CONTEXT_VERSION,
+        .version = 2,
         .vblank_handler = NULL,
         .page_flip_handler = DrmEventListener::FlipHandler};
     drmHandleEvent(drm_->fd(), &event_context);
diff --git a/drmhwcgralloc.h b/drmhwcgralloc.h
index 765c897..759746a 100644
--- a/drmhwcgralloc.h
+++ b/drmhwcgralloc.h
@@ -19,43 +19,11 @@
 
 #include <stdint.h>
 
-enum {
-  /* perform(const struct gralloc_module_t *mod,
-   *	   int op,
-   *	   int drm_fd,
-   *	   buffer_handle_t buffer,
-   *	   struct hwc_drm_bo *bo);
-   */
-  GRALLOC_MODULE_PERFORM_DRM_IMPORT = 0xffeeff00,
-
-  /* perform(const struct gralloc_module_t *mod,
-   *	   int op,
-   *	   buffer_handle_t buffer,
-   *	   void (*free_callback)(void *),
-   *	   void *priv);
-   */
-  GRALLOC_MODULE_PERFORM_SET_IMPORTER_PRIVATE = 0xffeeff01,
-
-  /* perform(const struct gralloc_module_t *mod,
-   *	   int op,
-   *	   buffer_handle_t buffer,
-   *	   void (*free_callback)(void *),
-   *	   void **priv);
-   */
-  GRALLOC_MODULE_PERFORM_GET_IMPORTER_PRIVATE = 0xffeeff02,
-
-  /* perform(const struct gralloc_module_t *mod,
-   *     int op,
-   *     buffer_handle_t buffer,
-   *     int *usage);
-   */
-  GRALLOC_MODULE_PERFORM_GET_USAGE = 0xffeeff03,
-};
-
 typedef struct hwc_drm_bo {
   uint32_t width;
   uint32_t height;
   uint32_t format; /* DRM_FORMAT_* from drm_fourcc.h */
+  uint32_t usage;
   uint32_t pitches[4];
   uint32_t offsets[4];
   uint32_t gem_handles[4];
diff --git a/drmhwcomposer.h b/drmhwcomposer.h
index d087873..f3b000b 100644
--- a/drmhwcomposer.h
+++ b/drmhwcomposer.h
@@ -20,10 +20,11 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#include <vector>
+
 #include <hardware/hardware.h>
 #include <hardware/hwcomposer.h>
 #include "autofd.h"
-#include "separate_rects.h"
 #include "drmhwcgralloc.h"
 
 struct hwc_import_context;
@@ -81,13 +82,10 @@
  public:
   DrmHwcNativeHandle() = default;
 
-  DrmHwcNativeHandle(const gralloc_module_t *gralloc, native_handle_t *handle)
-      : gralloc_(gralloc), handle_(handle) {
+  DrmHwcNativeHandle(native_handle_t *handle) : handle_(handle) {
   }
 
   DrmHwcNativeHandle(DrmHwcNativeHandle &&rhs) {
-    gralloc_ = rhs.gralloc_;
-    rhs.gralloc_ = NULL;
     handle_ = rhs.handle_;
     rhs.handle_ = NULL;
   }
@@ -96,14 +94,12 @@
 
   DrmHwcNativeHandle &operator=(DrmHwcNativeHandle &&rhs) {
     Clear();
-    gralloc_ = rhs.gralloc_;
-    rhs.gralloc_ = NULL;
     handle_ = rhs.handle_;
     rhs.handle_ = NULL;
     return *this;
   }
 
-  int CopyBufferHandle(buffer_handle_t handle, const gralloc_module_t *gralloc);
+  int CopyBufferHandle(buffer_handle_t handle);
 
   void Clear();
 
@@ -112,13 +108,9 @@
   }
 
  private:
-  const gralloc_module_t *gralloc_ = NULL;
   native_handle_t *handle_ = NULL;
 };
 
-template <typename T>
-using DrmHwcRect = separate_rects::Rect<T>;
-
 enum DrmHwcTransform {
   kIdentity = 0,
   kFlipH = 1 << 0,
@@ -141,16 +133,18 @@
   DrmHwcNativeHandle handle;
   uint32_t transform;
   DrmHwcBlending blending = DrmHwcBlending::kNone;
-  uint8_t alpha = 0xff;
-  DrmHwcRect<float> source_crop;
-  DrmHwcRect<int> display_frame;
-  std::vector<DrmHwcRect<int>> source_damage;
+  uint16_t alpha = 0xffff;
+  hwc_frect_t source_crop;
+  hwc_rect_t display_frame;
 
   UniqueFd acquire_fence;
   OutputFd release_fence;
 
-  int InitFromHwcLayer(hwc_layer_1_t *sf_layer, Importer *importer,
-                       const gralloc_module_t *gralloc);
+  int ImportBuffer(Importer *importer);
+
+  void SetTransform(int32_t sf_transform);
+  void SetSourceCrop(hwc_frect_t const &crop);
+  void SetDisplayFrame(hwc_rect_t const &frame);
 
   buffer_handle_t get_usable_handle() const {
     return handle.get() != NULL ? handle.get() : sf_handle;
diff --git a/drmhwctwo.cpp b/drmhwctwo.cpp
new file mode 100644
index 0000000..6bab17b
--- /dev/null
+++ b/drmhwctwo.cpp
@@ -0,0 +1,1125 @@
+/*
+ * Copyright (C) 2016 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
+#define LOG_TAG "hwc-drm-two"
+
+#include "drmdisplaycomposition.h"
+#include "drmhwcomposer.h"
+#include "drmhwctwo.h"
+#include "platform.h"
+#include "vsyncworker.h"
+
+#include <inttypes.h>
+#include <string>
+
+#include <log/log.h>
+#include <cutils/properties.h>
+#include <hardware/hardware.h>
+#include <hardware/hwcomposer2.h>
+
+namespace android {
+
+class DrmVsyncCallback : public VsyncCallback {
+ public:
+  DrmVsyncCallback(hwc2_callback_data_t data, hwc2_function_pointer_t hook)
+      : data_(data), hook_(hook) {
+  }
+
+  void Callback(int display, int64_t timestamp) {
+    auto hook = reinterpret_cast<HWC2_PFN_VSYNC>(hook_);
+    hook(data_, display, timestamp);
+  }
+
+ private:
+  hwc2_callback_data_t data_;
+  hwc2_function_pointer_t hook_;
+};
+
+DrmHwcTwo::DrmHwcTwo() {
+  common.tag = HARDWARE_DEVICE_TAG;
+  common.version = HWC_DEVICE_API_VERSION_2_0;
+  common.close = HookDevClose;
+  getCapabilities = HookDevGetCapabilities;
+  getFunction = HookDevGetFunction;
+}
+
+HWC2::Error DrmHwcTwo::Init() {
+  int ret = drm_.Init();
+  if (ret) {
+    ALOGE("Can't initialize drm object %d", ret);
+    return HWC2::Error::NoResources;
+  }
+
+  importer_.reset(Importer::CreateInstance(&drm_));
+  if (!importer_) {
+    ALOGE("Failed to create importer instance");
+    return HWC2::Error::NoResources;
+  }
+
+  displays_.emplace(std::piecewise_construct,
+                    std::forward_as_tuple(HWC_DISPLAY_PRIMARY),
+                    std::forward_as_tuple(&drm_, importer_, HWC_DISPLAY_PRIMARY,
+                                          HWC2::DisplayType::Physical));
+
+  DrmCrtc *crtc = drm_.GetCrtcForDisplay(static_cast<int>(HWC_DISPLAY_PRIMARY));
+  if (!crtc) {
+    ALOGE("Failed to get crtc for display %d",
+          static_cast<int>(HWC_DISPLAY_PRIMARY));
+    return HWC2::Error::BadDisplay;
+  }
+
+  std::vector<DrmPlane *> display_planes;
+  for (auto &plane : drm_.planes()) {
+    if (plane->GetCrtcSupported(*crtc))
+      display_planes.push_back(plane.get());
+  }
+  displays_.at(HWC_DISPLAY_PRIMARY).Init(&display_planes);
+  return HWC2::Error::None;
+}
+
+template <typename... Args>
+static inline HWC2::Error unsupported(char const *func, Args... /*args*/) {
+  ALOGV("Unsupported function: %s", func);
+  return HWC2::Error::Unsupported;
+}
+
+static inline void supported(char const *func) {
+  ALOGV("Supported function: %s", func);
+}
+
+HWC2::Error DrmHwcTwo::CreateVirtualDisplay(uint32_t width, uint32_t height,
+                                            int32_t *format,
+                                            hwc2_display_t *display) {
+  // TODO: Implement virtual display
+  return unsupported(__func__, width, height, format, display);
+}
+
+HWC2::Error DrmHwcTwo::DestroyVirtualDisplay(hwc2_display_t display) {
+  // TODO: Implement virtual display
+  return unsupported(__func__, display);
+}
+
+void DrmHwcTwo::Dump(uint32_t *size, char *buffer) {
+  // TODO: Implement dump
+  unsupported(__func__, size, buffer);
+}
+
+uint32_t DrmHwcTwo::GetMaxVirtualDisplayCount() {
+  // TODO: Implement virtual display
+  unsupported(__func__);
+  return 0;
+}
+
+HWC2::Error DrmHwcTwo::RegisterCallback(int32_t descriptor,
+                                        hwc2_callback_data_t data,
+                                        hwc2_function_pointer_t function) {
+  supported(__func__);
+  auto callback = static_cast<HWC2::Callback>(descriptor);
+  callbacks_.emplace(callback, HwcCallback(data, function));
+
+  switch (callback) {
+    case HWC2::Callback::Hotplug: {
+      auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(function);
+      hotplug(data, HWC_DISPLAY_PRIMARY,
+              static_cast<int32_t>(HWC2::Connection::Connected));
+      break;
+    }
+    case HWC2::Callback::Vsync: {
+      for (std::pair<const hwc2_display_t, DrmHwcTwo::HwcDisplay> &d :
+           displays_)
+        d.second.RegisterVsyncCallback(data, function);
+      break;
+    }
+    default:
+      break;
+  }
+  return HWC2::Error::None;
+}
+
+DrmHwcTwo::HwcDisplay::HwcDisplay(DrmResources *drm,
+                                  std::shared_ptr<Importer> importer,
+                                  hwc2_display_t handle, HWC2::DisplayType type)
+    : drm_(drm), importer_(importer), handle_(handle), type_(type) {
+  supported(__func__);
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::Init(std::vector<DrmPlane *> *planes) {
+  supported(__func__);
+  planner_ = Planner::CreateInstance(drm_);
+  if (!planner_) {
+    ALOGE("Failed to create planner instance for composition");
+    return HWC2::Error::NoResources;
+  }
+
+  int display = static_cast<int>(handle_);
+  int ret = compositor_.Init(drm_, display);
+  if (ret) {
+    ALOGE("Failed display compositor init for display %d (%d)", display, ret);
+    return HWC2::Error::NoResources;
+  }
+
+  // Split up the given display planes into primary and overlay to properly
+  // interface with the composition
+  char use_overlay_planes_prop[PROPERTY_VALUE_MAX];
+  property_get("hwc.drm.use_overlay_planes", use_overlay_planes_prop, "1");
+  bool use_overlay_planes = atoi(use_overlay_planes_prop);
+  for (auto &plane : *planes) {
+    if (plane->type() == DRM_PLANE_TYPE_PRIMARY)
+      primary_planes_.push_back(plane);
+    else if (use_overlay_planes && (plane)->type() == DRM_PLANE_TYPE_OVERLAY)
+      overlay_planes_.push_back(plane);
+  }
+
+  crtc_ = drm_->GetCrtcForDisplay(display);
+  if (!crtc_) {
+    ALOGE("Failed to get crtc for display %d", display);
+    return HWC2::Error::BadDisplay;
+  }
+
+  connector_ = drm_->GetConnectorForDisplay(display);
+  if (!connector_) {
+    ALOGE("Failed to get connector for display %d", display);
+    return HWC2::Error::BadDisplay;
+  }
+
+  // Fetch the number of modes from the display
+  uint32_t num_configs;
+  HWC2::Error err = GetDisplayConfigs(&num_configs, NULL);
+  if (err != HWC2::Error::None || !num_configs)
+    return err;
+
+  // Grab the first mode, we'll choose this as the active mode
+  // TODO: Should choose the preferred mode here
+  hwc2_config_t default_config;
+  num_configs = 1;
+  err = GetDisplayConfigs(&num_configs, &default_config);
+  if (err != HWC2::Error::None)
+    return err;
+
+  ret = vsync_worker_.Init(drm_, display);
+  if (ret) {
+    ALOGE("Failed to create event worker for d=%d %d\n", display, ret);
+    return HWC2::Error::BadDisplay;
+  }
+
+  return SetActiveConfig(default_config);
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::RegisterVsyncCallback(
+    hwc2_callback_data_t data, hwc2_function_pointer_t func) {
+  supported(__func__);
+  auto callback = std::make_shared<DrmVsyncCallback>(data, func);
+  vsync_worker_.RegisterCallback(std::move(callback));
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::AcceptDisplayChanges() {
+  supported(__func__);
+  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_)
+    l.second.accept_type_change();
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::CreateLayer(hwc2_layer_t *layer) {
+  supported(__func__);
+  layers_.emplace(static_cast<hwc2_layer_t>(layer_idx_), HwcLayer());
+  *layer = static_cast<hwc2_layer_t>(layer_idx_);
+  ++layer_idx_;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::DestroyLayer(hwc2_layer_t layer) {
+  supported(__func__);
+  layers_.erase(layer);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetActiveConfig(hwc2_config_t *config) {
+  supported(__func__);
+  DrmMode const &mode = connector_->active_mode();
+  if (mode.id() == 0)
+    return HWC2::Error::BadConfig;
+
+  *config = mode.id();
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetChangedCompositionTypes(
+    uint32_t *num_elements, hwc2_layer_t *layers, int32_t *types) {
+  supported(__func__);
+  uint32_t num_changes = 0;
+  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
+    if (l.second.type_changed()) {
+      if (layers && num_changes < *num_elements)
+        layers[num_changes] = l.first;
+      if (types && num_changes < *num_elements)
+        types[num_changes] = static_cast<int32_t>(l.second.validated_type());
+      ++num_changes;
+    }
+  }
+  if (!layers && !types)
+    *num_elements = num_changes;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetClientTargetSupport(uint32_t width,
+                                                          uint32_t height,
+                                                          int32_t /*format*/,
+                                                          int32_t dataspace) {
+  supported(__func__);
+  std::pair<uint32_t, uint32_t> min = drm_->min_resolution();
+  std::pair<uint32_t, uint32_t> max = drm_->max_resolution();
+
+  if (width < min.first || height < min.second)
+    return HWC2::Error::Unsupported;
+
+  if (width > max.first || height > max.second)
+    return HWC2::Error::Unsupported;
+
+  if (dataspace != HAL_DATASPACE_UNKNOWN &&
+      dataspace != HAL_DATASPACE_STANDARD_UNSPECIFIED)
+    return HWC2::Error::Unsupported;
+
+  // TODO: Validate format can be handled by either GL or planes
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetColorModes(uint32_t *num_modes,
+                                                 int32_t *modes) {
+  supported(__func__);
+  if (!modes)
+    *num_modes = 1;
+
+  if (modes)
+    *modes = HAL_COLOR_MODE_NATIVE;
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayAttribute(hwc2_config_t config,
+                                                       int32_t attribute_in,
+                                                       int32_t *value) {
+  supported(__func__);
+  auto mode =
+      std::find_if(connector_->modes().begin(), connector_->modes().end(),
+                   [config](DrmMode const &m) { return m.id() == config; });
+  if (mode == connector_->modes().end()) {
+    ALOGE("Could not find active mode for %d", config);
+    return HWC2::Error::BadConfig;
+  }
+
+  static const int32_t kUmPerInch = 25400;
+  uint32_t mm_width = connector_->mm_width();
+  uint32_t mm_height = connector_->mm_height();
+  auto attribute = static_cast<HWC2::Attribute>(attribute_in);
+  switch (attribute) {
+    case HWC2::Attribute::Width:
+      *value = mode->h_display();
+      break;
+    case HWC2::Attribute::Height:
+      *value = mode->v_display();
+      break;
+    case HWC2::Attribute::VsyncPeriod:
+      // in nanoseconds
+      *value = 1000 * 1000 * 1000 / mode->v_refresh();
+      break;
+    case HWC2::Attribute::DpiX:
+      // Dots per 1000 inches
+      *value = mm_width ? (mode->h_display() * kUmPerInch) / mm_width : -1;
+      break;
+    case HWC2::Attribute::DpiY:
+      // Dots per 1000 inches
+      *value = mm_height ? (mode->v_display() * kUmPerInch) / mm_height : -1;
+      break;
+    default:
+      *value = -1;
+      return HWC2::Error::BadConfig;
+  }
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayConfigs(uint32_t *num_configs,
+                                                     hwc2_config_t *configs) {
+  supported(__func__);
+  // Since this callback is normally invoked twice (once to get the count, and
+  // once to populate configs), we don't really want to read the edid
+  // redundantly. Instead, only update the modes on the first invocation. While
+  // it's possible this will result in stale modes, it'll all come out in the
+  // wash when we try to set the active config later.
+  if (!configs) {
+    int ret = connector_->UpdateModes();
+    if (ret) {
+      ALOGE("Failed to update display modes %d", ret);
+      return HWC2::Error::BadDisplay;
+    }
+  }
+
+  auto num_modes = static_cast<uint32_t>(connector_->modes().size());
+  if (!configs) {
+    *num_configs = num_modes;
+    return HWC2::Error::None;
+  }
+
+  uint32_t idx = 0;
+  for (const DrmMode &mode : connector_->modes()) {
+    if (idx >= *num_configs)
+      break;
+    configs[idx++] = mode.id();
+  }
+  *num_configs = idx;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayName(uint32_t *size, char *name) {
+  supported(__func__);
+  std::ostringstream stream;
+  stream << "display-" << connector_->id();
+  std::string string = stream.str();
+  size_t length = string.length();
+  if (!name) {
+    *size = length;
+    return HWC2::Error::None;
+  }
+
+  *size = std::min<uint32_t>(static_cast<uint32_t>(length - 1), *size);
+  strncpy(name, string.c_str(), *size);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayRequests(int32_t *display_requests,
+                                                      uint32_t *num_elements,
+                                                      hwc2_layer_t *layers,
+                                                      int32_t *layer_requests) {
+  supported(__func__);
+  // TODO: I think virtual display should request
+  //      HWC2_DISPLAY_REQUEST_WRITE_CLIENT_TARGET_TO_OUTPUT here
+  unsupported(__func__, display_requests, num_elements, layers, layer_requests);
+  *num_elements = 0;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayType(int32_t *type) {
+  supported(__func__);
+  *type = static_cast<int32_t>(type_);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetDozeSupport(int32_t *support) {
+  supported(__func__);
+  *support = 0;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetHdrCapabilities(
+    uint32_t *num_types, int32_t */*types*/, float */*max_luminance*/,
+    float */*max_average_luminance*/, float */*min_luminance*/) {
+  supported(__func__);
+  *num_types = 0;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::GetReleaseFences(uint32_t *num_elements,
+                                                    hwc2_layer_t *layers,
+                                                    int32_t *fences) {
+  supported(__func__);
+  uint32_t num_layers = 0;
+
+  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
+    ++num_layers;
+    if (layers == NULL || fences == NULL) {
+      continue;
+    } else if (num_layers > *num_elements) {
+      ALOGW("Overflow num_elements %d/%d", num_layers, *num_elements);
+      return HWC2::Error::None;
+    }
+
+    layers[num_layers - 1] = l.first;
+    fences[num_layers - 1] = l.second.take_release_fence();
+  }
+  *num_elements = num_layers;
+  return HWC2::Error::None;
+}
+
+void DrmHwcTwo::HwcDisplay::AddFenceToRetireFence(int fd) {
+  supported(__func__);
+  if (fd < 0)
+    return;
+
+  if (next_retire_fence_.get() >= 0) {
+    int old_fence = next_retire_fence_.get();
+    next_retire_fence_.Set(sync_merge("dc_retire", old_fence, fd));
+  } else {
+    next_retire_fence_.Set(dup(fd));
+  }
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(bool test) {
+  std::vector<DrmCompositionDisplayLayersMap> layers_map;
+  layers_map.emplace_back();
+  DrmCompositionDisplayLayersMap &map = layers_map.back();
+
+  map.display = static_cast<int>(handle_);
+  map.geometry_changed = true;  // TODO: Fix this
+
+  // order the layers by z-order
+  bool use_client_layer = false;
+  uint32_t client_z_order = UINT32_MAX;
+  std::map<uint32_t, DrmHwcTwo::HwcLayer *> z_map;
+  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
+    HWC2::Composition comp_type;
+    if (test)
+      comp_type = l.second.sf_type();
+    else
+      comp_type = l.second.validated_type();
+
+    switch (comp_type) {
+      case HWC2::Composition::Device:
+        z_map.emplace(std::make_pair(l.second.z_order(), &l.second));
+        break;
+      case HWC2::Composition::Client:
+        // Place it at the z_order of the lowest client layer
+        use_client_layer = true;
+        client_z_order = std::min(client_z_order, l.second.z_order());
+        break;
+      default:
+        continue;
+    }
+  }
+  if (use_client_layer)
+    z_map.emplace(std::make_pair(client_z_order, &client_layer_));
+
+  if (z_map.empty())
+    return HWC2::Error::BadLayer;
+
+  // now that they're ordered by z, add them to the composition
+  for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
+    DrmHwcLayer layer;
+    l.second->PopulateDrmLayer(&layer);
+    int ret = layer.ImportBuffer(importer_.get());
+    if (ret) {
+      ALOGE("Failed to import layer, ret=%d", ret);
+      return HWC2::Error::NoResources;
+    }
+    map.layers.emplace_back(std::move(layer));
+  }
+
+  std::unique_ptr<DrmDisplayComposition> composition =
+      compositor_.CreateComposition();
+  composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_);
+
+  // TODO: Don't always assume geometry changed
+  int ret = composition->SetLayers(map.layers.data(), map.layers.size(), true);
+  if (ret) {
+    ALOGE("Failed to set layers in the composition ret=%d", ret);
+    return HWC2::Error::BadLayer;
+  }
+
+  std::vector<DrmPlane *> primary_planes(primary_planes_);
+  std::vector<DrmPlane *> overlay_planes(overlay_planes_);
+  ret = composition->Plan(&primary_planes, &overlay_planes);
+  if (ret) {
+    ALOGE("Failed to plan the composition ret=%d", ret);
+    return HWC2::Error::BadConfig;
+  }
+
+  // Disable the planes we're not using
+  for (auto i = primary_planes.begin(); i != primary_planes.end();) {
+    composition->AddPlaneDisable(*i);
+    i = primary_planes.erase(i);
+  }
+  for (auto i = overlay_planes.begin(); i != overlay_planes.end();) {
+    composition->AddPlaneDisable(*i);
+    i = overlay_planes.erase(i);
+  }
+
+  if (test) {
+    ret = compositor_.TestComposition(composition.get());
+  } else {
+    AddFenceToRetireFence(composition->take_out_fence());
+    ret = compositor_.ApplyComposition(std::move(composition));
+  }
+  if (ret) {
+    if (!test)
+      ALOGE("Failed to apply the frame composition ret=%d", ret);
+    return HWC2::Error::BadParameter;
+  }
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) {
+  supported(__func__);
+  HWC2::Error ret;
+
+  ret = CreateComposition(false);
+  if (ret == HWC2::Error::BadLayer) {
+    // Can we really have no client or device layers?
+    *retire_fence = -1;
+    return HWC2::Error::None;
+  }
+  if (ret != HWC2::Error::None)
+    return ret;
+
+  // The retire fence returned here is for the last frame, so return it and
+  // promote the next retire fence
+  *retire_fence = retire_fence_.Release();
+  retire_fence_ = std::move(next_retire_fence_);
+
+  ++frame_no_;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfig(hwc2_config_t config) {
+  supported(__func__);
+  auto mode =
+      std::find_if(connector_->modes().begin(), connector_->modes().end(),
+                   [config](DrmMode const &m) { return m.id() == config; });
+  if (mode == connector_->modes().end()) {
+    ALOGE("Could not find active mode for %d", config);
+    return HWC2::Error::BadConfig;
+  }
+
+  std::unique_ptr<DrmDisplayComposition> composition =
+      compositor_.CreateComposition();
+  composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_);
+  int ret = composition->SetDisplayMode(*mode);
+  ret = compositor_.ApplyComposition(std::move(composition));
+  if (ret) {
+    ALOGE("Failed to queue dpms composition on %d", ret);
+    return HWC2::Error::BadConfig;
+  }
+  if (connector_->active_mode().id() == 0)
+    connector_->set_active_mode(*mode);
+
+  // Setup the client layer's dimensions
+  hwc_rect_t display_frame = {.left = 0,
+                              .top = 0,
+                              .right = static_cast<int>(mode->h_display()),
+                              .bottom = static_cast<int>(mode->v_display())};
+  client_layer_.SetLayerDisplayFrame(display_frame);
+  hwc_frect_t source_crop = {.left = 0.0f,
+                             .top = 0.0f,
+                             .right = mode->h_display() + 0.0f,
+                             .bottom = mode->v_display() + 0.0f};
+  client_layer_.SetLayerSourceCrop(source_crop);
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::SetClientTarget(buffer_handle_t target,
+                                                   int32_t acquire_fence,
+                                                   int32_t dataspace,
+                                                   hwc_region_t /*damage*/) {
+  supported(__func__);
+  UniqueFd uf(acquire_fence);
+
+  client_layer_.set_buffer(target);
+  client_layer_.set_acquire_fence(uf.get());
+  client_layer_.SetLayerDataspace(dataspace);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::SetColorMode(int32_t mode) {
+  supported(__func__);
+
+  if (mode != HAL_COLOR_MODE_NATIVE)
+    return HWC2::Error::Unsupported;
+
+  color_mode_ = mode;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::SetColorTransform(const float *matrix,
+                                                     int32_t hint) {
+  supported(__func__);
+  // TODO: Force client composition if we get this
+  return unsupported(__func__, matrix, hint);
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::SetOutputBuffer(buffer_handle_t buffer,
+                                                   int32_t release_fence) {
+  supported(__func__);
+  // TODO: Need virtual display support
+  return unsupported(__func__, buffer, release_fence);
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::SetPowerMode(int32_t mode_in) {
+  supported(__func__);
+  uint64_t dpms_value = 0;
+  auto mode = static_cast<HWC2::PowerMode>(mode_in);
+  switch (mode) {
+    case HWC2::PowerMode::Off:
+      dpms_value = DRM_MODE_DPMS_OFF;
+      break;
+    case HWC2::PowerMode::On:
+      dpms_value = DRM_MODE_DPMS_ON;
+      break;
+    default:
+      ALOGI("Power mode %d is unsupported\n", mode);
+      return HWC2::Error::Unsupported;
+  };
+
+  std::unique_ptr<DrmDisplayComposition> composition =
+      compositor_.CreateComposition();
+  composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_);
+  composition->SetDpmsMode(dpms_value);
+  int ret = compositor_.ApplyComposition(std::move(composition));
+  if (ret) {
+    ALOGE("Failed to apply the dpms composition ret=%d", ret);
+    return HWC2::Error::BadParameter;
+  }
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::SetVsyncEnabled(int32_t enabled) {
+  supported(__func__);
+  vsync_worker_.VSyncControl(enabled);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types,
+                                                   uint32_t *num_requests) {
+  supported(__func__);
+  size_t plane_count = 0;
+  *num_types = 0;
+  *num_requests = 0;
+  size_t avail_planes = primary_planes_.size() + overlay_planes_.size();
+
+  HWC2::Error ret;
+
+  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_)
+    l.second.set_validated_type(HWC2::Composition::Invalid);
+
+  ret = CreateComposition(true);
+  if (ret != HWC2::Error::None)
+    // Assume the test failed due to overlay planes
+    avail_planes = 1;
+
+  std::map<uint32_t, DrmHwcTwo::HwcLayer *, std::greater<int>> z_map;
+  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
+    if (l.second.sf_type() == HWC2::Composition::Device)
+      z_map.emplace(std::make_pair(l.second.z_order(), &l.second));
+  }
+
+  /*
+   * If more layers then planes, save one plane
+   * for client composited layers
+   */
+  if (avail_planes < layers_.size())
+    avail_planes--;
+
+  for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
+    if (!avail_planes--)
+      break;
+    l.second->set_validated_type(HWC2::Composition::Device);
+  }
+
+  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
+    DrmHwcTwo::HwcLayer &layer = l.second;
+    switch (layer.sf_type()) {
+      case HWC2::Composition::Device:
+        if (layer.validated_type() == HWC2::Composition::Device)
+          break;
+      // fall thru
+      case HWC2::Composition::SolidColor:
+      case HWC2::Composition::Cursor:
+      case HWC2::Composition::Sideband:
+      default:
+        layer.set_validated_type(HWC2::Composition::Client);
+        ++*num_types;
+        break;
+    }
+  }
+  return *num_types ? HWC2::Error::HasChanges : HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetCursorPosition(int32_t x, int32_t y) {
+  supported(__func__);
+  cursor_x_ = x;
+  cursor_y_ = y;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBlendMode(int32_t mode) {
+  supported(__func__);
+  blending_ = static_cast<HWC2::BlendMode>(mode);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBuffer(buffer_handle_t buffer,
+                                                int32_t acquire_fence) {
+  supported(__func__);
+  UniqueFd uf(acquire_fence);
+
+  // The buffer and acquire_fence are handled elsewhere
+  if (sf_type_ == HWC2::Composition::Client ||
+      sf_type_ == HWC2::Composition::Sideband ||
+      sf_type_ == HWC2::Composition::SolidColor)
+    return HWC2::Error::None;
+
+  set_buffer(buffer);
+  set_acquire_fence(uf.get());
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerColor(hwc_color_t color) {
+  // TODO: Punt to client composition here?
+  return unsupported(__func__, color);
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerCompositionType(int32_t type) {
+  sf_type_ = static_cast<HWC2::Composition>(type);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDataspace(int32_t dataspace) {
+  supported(__func__);
+  dataspace_ = static_cast<android_dataspace_t>(dataspace);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDisplayFrame(hwc_rect_t frame) {
+  supported(__func__);
+  display_frame_ = frame;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerPlaneAlpha(float alpha) {
+  supported(__func__);
+  alpha_ = alpha;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSidebandStream(
+    const native_handle_t *stream) {
+  supported(__func__);
+  // TODO: We don't support sideband
+  return unsupported(__func__, stream);
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSourceCrop(hwc_frect_t crop) {
+  supported(__func__);
+  source_crop_ = crop;
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSurfaceDamage(hwc_region_t damage) {
+  supported(__func__);
+  // TODO: We don't use surface damage, marking as unsupported
+  unsupported(__func__, damage);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerTransform(int32_t transform) {
+  supported(__func__);
+  transform_ = static_cast<HWC2::Transform>(transform);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerVisibleRegion(hwc_region_t visible) {
+  supported(__func__);
+  // TODO: We don't use this information, marking as unsupported
+  unsupported(__func__, visible);
+  return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcLayer::SetLayerZOrder(uint32_t order) {
+  supported(__func__);
+  z_order_ = order;
+  return HWC2::Error::None;
+}
+
+void DrmHwcTwo::HwcLayer::PopulateDrmLayer(DrmHwcLayer *layer) {
+  supported(__func__);
+  switch (blending_) {
+    case HWC2::BlendMode::None:
+      layer->blending = DrmHwcBlending::kNone;
+      break;
+    case HWC2::BlendMode::Premultiplied:
+      layer->blending = DrmHwcBlending::kPreMult;
+      break;
+    case HWC2::BlendMode::Coverage:
+      layer->blending = DrmHwcBlending::kCoverage;
+      break;
+    default:
+      ALOGE("Unknown blending mode b=%d", blending_);
+      layer->blending = DrmHwcBlending::kNone;
+      break;
+  }
+
+  OutputFd release_fence = release_fence_output();
+
+  layer->sf_handle = buffer_;
+  layer->acquire_fence = acquire_fence_.Release();
+  layer->release_fence = std::move(release_fence);
+  layer->SetDisplayFrame(display_frame_);
+  layer->alpha = static_cast<uint16_t>(65535.0f * alpha_ + 0.5f);
+  layer->SetSourceCrop(source_crop_);
+  layer->SetTransform(static_cast<int32_t>(transform_));
+}
+
+// static
+int DrmHwcTwo::HookDevClose(hw_device_t * /*dev*/) {
+  unsupported(__func__);
+  return 0;
+}
+
+// static
+void DrmHwcTwo::HookDevGetCapabilities(hwc2_device_t * /*dev*/,
+                                       uint32_t *out_count,
+                                       int32_t * /*out_capabilities*/) {
+  supported(__func__);
+  *out_count = 0;
+}
+
+// static
+hwc2_function_pointer_t DrmHwcTwo::HookDevGetFunction(
+    struct hwc2_device * /*dev*/, int32_t descriptor) {
+  supported(__func__);
+  auto func = static_cast<HWC2::FunctionDescriptor>(descriptor);
+  switch (func) {
+    // Device functions
+    case HWC2::FunctionDescriptor::CreateVirtualDisplay:
+      return ToHook<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
+          DeviceHook<int32_t, decltype(&DrmHwcTwo::CreateVirtualDisplay),
+                     &DrmHwcTwo::CreateVirtualDisplay, uint32_t, uint32_t,
+                     int32_t*, hwc2_display_t *>);
+    case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
+      return ToHook<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
+          DeviceHook<int32_t, decltype(&DrmHwcTwo::DestroyVirtualDisplay),
+                     &DrmHwcTwo::DestroyVirtualDisplay, hwc2_display_t>);
+    case HWC2::FunctionDescriptor::Dump:
+      return ToHook<HWC2_PFN_DUMP>(
+          DeviceHook<void, decltype(&DrmHwcTwo::Dump), &DrmHwcTwo::Dump,
+                     uint32_t *, char *>);
+    case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
+      return ToHook<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
+          DeviceHook<uint32_t, decltype(&DrmHwcTwo::GetMaxVirtualDisplayCount),
+                     &DrmHwcTwo::GetMaxVirtualDisplayCount>);
+    case HWC2::FunctionDescriptor::RegisterCallback:
+      return ToHook<HWC2_PFN_REGISTER_CALLBACK>(
+          DeviceHook<int32_t, decltype(&DrmHwcTwo::RegisterCallback),
+                     &DrmHwcTwo::RegisterCallback, int32_t,
+                     hwc2_callback_data_t, hwc2_function_pointer_t>);
+
+    // Display functions
+    case HWC2::FunctionDescriptor::AcceptDisplayChanges:
+      return ToHook<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
+          DisplayHook<decltype(&HwcDisplay::AcceptDisplayChanges),
+                      &HwcDisplay::AcceptDisplayChanges>);
+    case HWC2::FunctionDescriptor::CreateLayer:
+      return ToHook<HWC2_PFN_CREATE_LAYER>(
+          DisplayHook<decltype(&HwcDisplay::CreateLayer),
+                      &HwcDisplay::CreateLayer, hwc2_layer_t *>);
+    case HWC2::FunctionDescriptor::DestroyLayer:
+      return ToHook<HWC2_PFN_DESTROY_LAYER>(
+          DisplayHook<decltype(&HwcDisplay::DestroyLayer),
+                      &HwcDisplay::DestroyLayer, hwc2_layer_t>);
+    case HWC2::FunctionDescriptor::GetActiveConfig:
+      return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>(
+          DisplayHook<decltype(&HwcDisplay::GetActiveConfig),
+                      &HwcDisplay::GetActiveConfig, hwc2_config_t *>);
+    case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
+      return ToHook<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
+          DisplayHook<decltype(&HwcDisplay::GetChangedCompositionTypes),
+                      &HwcDisplay::GetChangedCompositionTypes, uint32_t *,
+                      hwc2_layer_t *, int32_t *>);
+    case HWC2::FunctionDescriptor::GetClientTargetSupport:
+      return ToHook<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
+          DisplayHook<decltype(&HwcDisplay::GetClientTargetSupport),
+                      &HwcDisplay::GetClientTargetSupport, uint32_t, uint32_t,
+                      int32_t, int32_t>);
+    case HWC2::FunctionDescriptor::GetColorModes:
+      return ToHook<HWC2_PFN_GET_COLOR_MODES>(
+          DisplayHook<decltype(&HwcDisplay::GetColorModes),
+                      &HwcDisplay::GetColorModes, uint32_t *, int32_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayAttribute:
+      return ToHook<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(DisplayHook<
+          decltype(&HwcDisplay::GetDisplayAttribute),
+          &HwcDisplay::GetDisplayAttribute, hwc2_config_t, int32_t, int32_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayConfigs:
+      return ToHook<HWC2_PFN_GET_DISPLAY_CONFIGS>(DisplayHook<
+          decltype(&HwcDisplay::GetDisplayConfigs),
+          &HwcDisplay::GetDisplayConfigs, uint32_t *, hwc2_config_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayName:
+      return ToHook<HWC2_PFN_GET_DISPLAY_NAME>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayName),
+                      &HwcDisplay::GetDisplayName, uint32_t *, char *>);
+    case HWC2::FunctionDescriptor::GetDisplayRequests:
+      return ToHook<HWC2_PFN_GET_DISPLAY_REQUESTS>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayRequests),
+                      &HwcDisplay::GetDisplayRequests, int32_t *, uint32_t *,
+                      hwc2_layer_t *, int32_t *>);
+    case HWC2::FunctionDescriptor::GetDisplayType:
+      return ToHook<HWC2_PFN_GET_DISPLAY_TYPE>(
+          DisplayHook<decltype(&HwcDisplay::GetDisplayType),
+                      &HwcDisplay::GetDisplayType, int32_t *>);
+    case HWC2::FunctionDescriptor::GetDozeSupport:
+      return ToHook<HWC2_PFN_GET_DOZE_SUPPORT>(
+          DisplayHook<decltype(&HwcDisplay::GetDozeSupport),
+                      &HwcDisplay::GetDozeSupport, int32_t *>);
+    case HWC2::FunctionDescriptor::GetHdrCapabilities:
+      return ToHook<HWC2_PFN_GET_HDR_CAPABILITIES>(
+          DisplayHook<decltype(&HwcDisplay::GetHdrCapabilities),
+                      &HwcDisplay::GetHdrCapabilities, uint32_t *, int32_t *,
+                      float *, float *, float *>);
+    case HWC2::FunctionDescriptor::GetReleaseFences:
+      return ToHook<HWC2_PFN_GET_RELEASE_FENCES>(
+          DisplayHook<decltype(&HwcDisplay::GetReleaseFences),
+                      &HwcDisplay::GetReleaseFences, uint32_t *, hwc2_layer_t *,
+                      int32_t *>);
+    case HWC2::FunctionDescriptor::PresentDisplay:
+      return ToHook<HWC2_PFN_PRESENT_DISPLAY>(
+          DisplayHook<decltype(&HwcDisplay::PresentDisplay),
+                      &HwcDisplay::PresentDisplay, int32_t *>);
+    case HWC2::FunctionDescriptor::SetActiveConfig:
+      return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG>(
+          DisplayHook<decltype(&HwcDisplay::SetActiveConfig),
+                      &HwcDisplay::SetActiveConfig, hwc2_config_t>);
+    case HWC2::FunctionDescriptor::SetClientTarget:
+      return ToHook<HWC2_PFN_SET_CLIENT_TARGET>(DisplayHook<
+          decltype(&HwcDisplay::SetClientTarget), &HwcDisplay::SetClientTarget,
+          buffer_handle_t, int32_t, int32_t, hwc_region_t>);
+    case HWC2::FunctionDescriptor::SetColorMode:
+      return ToHook<HWC2_PFN_SET_COLOR_MODE>(
+          DisplayHook<decltype(&HwcDisplay::SetColorMode),
+                      &HwcDisplay::SetColorMode, int32_t>);
+    case HWC2::FunctionDescriptor::SetColorTransform:
+      return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>(
+          DisplayHook<decltype(&HwcDisplay::SetColorTransform),
+                      &HwcDisplay::SetColorTransform, const float *, int32_t>);
+    case HWC2::FunctionDescriptor::SetOutputBuffer:
+      return ToHook<HWC2_PFN_SET_OUTPUT_BUFFER>(
+          DisplayHook<decltype(&HwcDisplay::SetOutputBuffer),
+                      &HwcDisplay::SetOutputBuffer, buffer_handle_t, int32_t>);
+    case HWC2::FunctionDescriptor::SetPowerMode:
+      return ToHook<HWC2_PFN_SET_POWER_MODE>(
+          DisplayHook<decltype(&HwcDisplay::SetPowerMode),
+                      &HwcDisplay::SetPowerMode, int32_t>);
+    case HWC2::FunctionDescriptor::SetVsyncEnabled:
+      return ToHook<HWC2_PFN_SET_VSYNC_ENABLED>(
+          DisplayHook<decltype(&HwcDisplay::SetVsyncEnabled),
+                      &HwcDisplay::SetVsyncEnabled, int32_t>);
+    case HWC2::FunctionDescriptor::ValidateDisplay:
+      return ToHook<HWC2_PFN_VALIDATE_DISPLAY>(
+          DisplayHook<decltype(&HwcDisplay::ValidateDisplay),
+                      &HwcDisplay::ValidateDisplay, uint32_t *, uint32_t *>);
+
+    // Layer functions
+    case HWC2::FunctionDescriptor::SetCursorPosition:
+      return ToHook<HWC2_PFN_SET_CURSOR_POSITION>(
+          LayerHook<decltype(&HwcLayer::SetCursorPosition),
+                    &HwcLayer::SetCursorPosition, int32_t, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerBlendMode:
+      return ToHook<HWC2_PFN_SET_LAYER_BLEND_MODE>(
+          LayerHook<decltype(&HwcLayer::SetLayerBlendMode),
+                    &HwcLayer::SetLayerBlendMode, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerBuffer:
+      return ToHook<HWC2_PFN_SET_LAYER_BUFFER>(
+          LayerHook<decltype(&HwcLayer::SetLayerBuffer),
+                    &HwcLayer::SetLayerBuffer, buffer_handle_t, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerColor:
+      return ToHook<HWC2_PFN_SET_LAYER_COLOR>(
+          LayerHook<decltype(&HwcLayer::SetLayerColor),
+                    &HwcLayer::SetLayerColor, hwc_color_t>);
+    case HWC2::FunctionDescriptor::SetLayerCompositionType:
+      return ToHook<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
+          LayerHook<decltype(&HwcLayer::SetLayerCompositionType),
+                    &HwcLayer::SetLayerCompositionType, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerDataspace:
+      return ToHook<HWC2_PFN_SET_LAYER_DATASPACE>(
+          LayerHook<decltype(&HwcLayer::SetLayerDataspace),
+                    &HwcLayer::SetLayerDataspace, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
+      return ToHook<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
+          LayerHook<decltype(&HwcLayer::SetLayerDisplayFrame),
+                    &HwcLayer::SetLayerDisplayFrame, hwc_rect_t>);
+    case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
+      return ToHook<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
+          LayerHook<decltype(&HwcLayer::SetLayerPlaneAlpha),
+                    &HwcLayer::SetLayerPlaneAlpha, float>);
+    case HWC2::FunctionDescriptor::SetLayerSidebandStream:
+      return ToHook<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(LayerHook<
+          decltype(&HwcLayer::SetLayerSidebandStream),
+          &HwcLayer::SetLayerSidebandStream, const native_handle_t *>);
+    case HWC2::FunctionDescriptor::SetLayerSourceCrop:
+      return ToHook<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
+          LayerHook<decltype(&HwcLayer::SetLayerSourceCrop),
+                    &HwcLayer::SetLayerSourceCrop, hwc_frect_t>);
+    case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
+      return ToHook<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
+          LayerHook<decltype(&HwcLayer::SetLayerSurfaceDamage),
+                    &HwcLayer::SetLayerSurfaceDamage, hwc_region_t>);
+    case HWC2::FunctionDescriptor::SetLayerTransform:
+      return ToHook<HWC2_PFN_SET_LAYER_TRANSFORM>(
+          LayerHook<decltype(&HwcLayer::SetLayerTransform),
+                    &HwcLayer::SetLayerTransform, int32_t>);
+    case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
+      return ToHook<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
+          LayerHook<decltype(&HwcLayer::SetLayerVisibleRegion),
+                    &HwcLayer::SetLayerVisibleRegion, hwc_region_t>);
+    case HWC2::FunctionDescriptor::SetLayerZOrder:
+      return ToHook<HWC2_PFN_SET_LAYER_Z_ORDER>(
+          LayerHook<decltype(&HwcLayer::SetLayerZOrder),
+                    &HwcLayer::SetLayerZOrder, uint32_t>);
+    case HWC2::FunctionDescriptor::Invalid:
+    default:
+      return NULL;
+  }
+}
+
+// static
+int DrmHwcTwo::HookDevOpen(const struct hw_module_t *module, const char *name,
+                           struct hw_device_t **dev) {
+  supported(__func__);
+  if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
+    ALOGE("Invalid module name- %s", name);
+    return -EINVAL;
+  }
+
+  std::unique_ptr<DrmHwcTwo> ctx(new DrmHwcTwo());
+  if (!ctx) {
+    ALOGE("Failed to allocate DrmHwcTwo");
+    return -ENOMEM;
+  }
+
+  HWC2::Error err = ctx->Init();
+  if (err != HWC2::Error::None) {
+    ALOGE("Failed to initialize DrmHwcTwo err=%d\n", err);
+    return -EINVAL;
+  }
+
+  ctx->common.module = const_cast<hw_module_t *>(module);
+  *dev = &ctx->common;
+  ctx.release();
+  return 0;
+}
+}
+
+static struct hw_module_methods_t hwc2_module_methods = {
+    .open = android::DrmHwcTwo::HookDevOpen,
+};
+
+hw_module_t HAL_MODULE_INFO_SYM = {
+    .tag = HARDWARE_MODULE_TAG,
+    .module_api_version = HARDWARE_MODULE_API_VERSION(2, 0),
+    .id = HWC_HARDWARE_MODULE_ID,
+    .name = "DrmHwcTwo module",
+    .author = "The Android Open Source Project",
+    .methods = &hwc2_module_methods,
+    .dso = NULL,
+    .reserved = {0},
+};
diff --git a/drmhwctwo.h b/drmhwctwo.h
new file mode 100644
index 0000000..82a9768
--- /dev/null
+++ b/drmhwctwo.h
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "drmdisplaycompositor.h"
+#include "drmhwcomposer.h"
+#include "drmresources.h"
+#include "platform.h"
+#include "vsyncworker.h"
+
+#include <hardware/hwcomposer2.h>
+
+#include <map>
+
+namespace android {
+
+class DrmHwcTwo : public hwc2_device_t {
+ public:
+  static int HookDevOpen(const struct hw_module_t *module, const char *name,
+                         struct hw_device_t **dev);
+
+  DrmHwcTwo();
+
+  HWC2::Error Init();
+
+ private:
+  class HwcLayer {
+   public:
+    HWC2::Composition sf_type() const {
+      return sf_type_;
+    }
+    HWC2::Composition validated_type() const {
+      return validated_type_;
+    }
+    void accept_type_change() {
+      sf_type_ = validated_type_;
+    }
+    void set_validated_type(HWC2::Composition type) {
+      validated_type_ = type;
+    }
+    bool type_changed() const {
+      return sf_type_ != validated_type_;
+    }
+
+    uint32_t z_order() const {
+      return z_order_;
+    }
+
+    buffer_handle_t buffer() {
+      return buffer_;
+    }
+    void set_buffer(buffer_handle_t buffer) {
+      buffer_ = buffer;
+    }
+
+    int take_acquire_fence() {
+      return acquire_fence_.Release();
+    }
+    void set_acquire_fence(int acquire_fence) {
+      acquire_fence_.Set(dup(acquire_fence));
+    }
+
+    int release_fence() {
+      return release_fence_.get();
+    }
+    int take_release_fence() {
+      return release_fence_.Release();
+    }
+    void manage_release_fence() {
+      release_fence_.Set(release_fence_raw_);
+      release_fence_raw_ = -1;
+    }
+    OutputFd release_fence_output() {
+      return OutputFd(&release_fence_raw_);
+    }
+
+    void PopulateDrmLayer(DrmHwcLayer *layer);
+
+    // Layer hooks
+    HWC2::Error SetCursorPosition(int32_t x, int32_t y);
+    HWC2::Error SetLayerBlendMode(int32_t mode);
+    HWC2::Error SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence);
+    HWC2::Error SetLayerColor(hwc_color_t color);
+    HWC2::Error SetLayerCompositionType(int32_t type);
+    HWC2::Error SetLayerDataspace(int32_t dataspace);
+    HWC2::Error SetLayerDisplayFrame(hwc_rect_t frame);
+    HWC2::Error SetLayerPlaneAlpha(float alpha);
+    HWC2::Error SetLayerSidebandStream(const native_handle_t *stream);
+    HWC2::Error SetLayerSourceCrop(hwc_frect_t crop);
+    HWC2::Error SetLayerSurfaceDamage(hwc_region_t damage);
+    HWC2::Error SetLayerTransform(int32_t transform);
+    HWC2::Error SetLayerVisibleRegion(hwc_region_t visible);
+    HWC2::Error SetLayerZOrder(uint32_t z);
+
+   private:
+    // sf_type_ stores the initial type given to us by surfaceflinger,
+    // validated_type_ stores the type after running ValidateDisplay
+    HWC2::Composition sf_type_ = HWC2::Composition::Invalid;
+    HWC2::Composition validated_type_ = HWC2::Composition::Invalid;
+
+    HWC2::BlendMode blending_ = HWC2::BlendMode::None;
+    buffer_handle_t buffer_;
+    UniqueFd acquire_fence_;
+    int release_fence_raw_ = -1;
+    UniqueFd release_fence_;
+    hwc_rect_t display_frame_;
+    float alpha_ = 1.0f;
+    hwc_frect_t source_crop_;
+    int32_t cursor_x_;
+    int32_t cursor_y_;
+    HWC2::Transform transform_ = HWC2::Transform::None;
+    uint32_t z_order_ = 0;
+    android_dataspace_t dataspace_ = HAL_DATASPACE_UNKNOWN;
+  };
+
+  struct HwcCallback {
+    HwcCallback(hwc2_callback_data_t d, hwc2_function_pointer_t f)
+        : data(d), func(f) {
+    }
+    hwc2_callback_data_t data;
+    hwc2_function_pointer_t func;
+  };
+
+  class HwcDisplay {
+   public:
+    HwcDisplay(DrmResources *drm, std::shared_ptr<Importer> importer,
+               hwc2_display_t handle, HWC2::DisplayType type);
+    HwcDisplay(const HwcDisplay &) = delete;
+    HWC2::Error Init(std::vector<DrmPlane *> *planes);
+
+    HWC2::Error RegisterVsyncCallback(hwc2_callback_data_t data,
+                                      hwc2_function_pointer_t func);
+
+    // HWC Hooks
+    HWC2::Error AcceptDisplayChanges();
+    HWC2::Error CreateLayer(hwc2_layer_t *layer);
+    HWC2::Error DestroyLayer(hwc2_layer_t layer);
+    HWC2::Error GetActiveConfig(hwc2_config_t *config);
+    HWC2::Error GetChangedCompositionTypes(uint32_t *num_elements,
+                                           hwc2_layer_t *layers,
+                                           int32_t *types);
+    HWC2::Error GetClientTargetSupport(uint32_t width, uint32_t height,
+                                       int32_t format, int32_t dataspace);
+    HWC2::Error GetColorModes(uint32_t *num_modes, int32_t *modes);
+    HWC2::Error GetDisplayAttribute(hwc2_config_t config, int32_t attribute,
+                                    int32_t *value);
+    HWC2::Error GetDisplayConfigs(uint32_t *num_configs,
+                                  hwc2_config_t *configs);
+    HWC2::Error GetDisplayName(uint32_t *size, char *name);
+    HWC2::Error GetDisplayRequests(int32_t *display_requests,
+                                   uint32_t *num_elements, hwc2_layer_t *layers,
+                                   int32_t *layer_requests);
+    HWC2::Error GetDisplayType(int32_t *type);
+    HWC2::Error GetDozeSupport(int32_t *support);
+    HWC2::Error GetHdrCapabilities(uint32_t *num_types, int32_t *types,
+                                   float *max_luminance,
+                                   float *max_average_luminance,
+                                   float *min_luminance);
+    HWC2::Error GetReleaseFences(uint32_t *num_elements, hwc2_layer_t *layers,
+                                 int32_t *fences);
+    HWC2::Error PresentDisplay(int32_t *retire_fence);
+    HWC2::Error SetActiveConfig(hwc2_config_t config);
+    HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
+                                int32_t dataspace, hwc_region_t damage);
+    HWC2::Error SetColorMode(int32_t mode);
+    HWC2::Error SetColorTransform(const float *matrix, int32_t hint);
+    HWC2::Error SetOutputBuffer(buffer_handle_t buffer, int32_t release_fence);
+    HWC2::Error SetPowerMode(int32_t mode);
+    HWC2::Error SetVsyncEnabled(int32_t enabled);
+    HWC2::Error ValidateDisplay(uint32_t *num_types, uint32_t *num_requests);
+    HwcLayer &get_layer(hwc2_layer_t layer) {
+      return layers_.at(layer);
+    }
+
+   private:
+    HWC2::Error CreateComposition(bool test);
+    void AddFenceToRetireFence(int fd);
+
+    DrmResources *drm_;
+    DrmDisplayCompositor compositor_;
+    std::shared_ptr<Importer> importer_;
+    std::unique_ptr<Planner> planner_;
+
+    std::vector<DrmPlane *> primary_planes_;
+    std::vector<DrmPlane *> overlay_planes_;
+
+    VSyncWorker vsync_worker_;
+    DrmConnector *connector_ = NULL;
+    DrmCrtc *crtc_ = NULL;
+    hwc2_display_t handle_;
+    HWC2::DisplayType type_;
+    uint32_t layer_idx_ = 0;
+    std::map<hwc2_layer_t, HwcLayer> layers_;
+    HwcLayer client_layer_;
+    UniqueFd retire_fence_;
+    UniqueFd next_retire_fence_;
+    int32_t color_mode_;
+
+    uint32_t frame_no_ = 0;
+  };
+
+  static DrmHwcTwo *toDrmHwcTwo(hwc2_device_t *dev) {
+    return static_cast<DrmHwcTwo *>(dev);
+  }
+
+  template <typename PFN, typename T>
+  static hwc2_function_pointer_t ToHook(T function) {
+    static_assert(std::is_same<PFN, T>::value, "Incompatible fn pointer");
+    return reinterpret_cast<hwc2_function_pointer_t>(function);
+  }
+
+  template <typename T, typename HookType, HookType func, typename... Args>
+  static T DeviceHook(hwc2_device_t *dev, Args... args) {
+    DrmHwcTwo *hwc = toDrmHwcTwo(dev);
+    return static_cast<T>(((*hwc).*func)(std::forward<Args>(args)...));
+  }
+
+  template <typename HookType, HookType func, typename... Args>
+  static int32_t DisplayHook(hwc2_device_t *dev, hwc2_display_t display_handle,
+                             Args... args) {
+    DrmHwcTwo *hwc = toDrmHwcTwo(dev);
+    HwcDisplay &display = hwc->displays_.at(display_handle);
+    return static_cast<int32_t>((display.*func)(std::forward<Args>(args)...));
+  }
+
+  template <typename HookType, HookType func, typename... Args>
+  static int32_t LayerHook(hwc2_device_t *dev, hwc2_display_t display_handle,
+                           hwc2_layer_t layer_handle, Args... args) {
+    DrmHwcTwo *hwc = toDrmHwcTwo(dev);
+    HwcDisplay &display = hwc->displays_.at(display_handle);
+    HwcLayer &layer = display.get_layer(layer_handle);
+    return static_cast<int32_t>((layer.*func)(std::forward<Args>(args)...));
+  }
+
+  // hwc2_device_t hooks
+  static int HookDevClose(hw_device_t *dev);
+  static void HookDevGetCapabilities(hwc2_device_t *dev, uint32_t *out_count,
+                                     int32_t *out_capabilities);
+  static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device *device,
+                                                    int32_t descriptor);
+
+  // Device functions
+  HWC2::Error CreateVirtualDisplay(uint32_t width, uint32_t height,
+                                   int32_t *format,
+                                   hwc2_display_t *display);
+  HWC2::Error DestroyVirtualDisplay(hwc2_display_t display);
+  void Dump(uint32_t *size, char *buffer);
+  uint32_t GetMaxVirtualDisplayCount();
+  HWC2::Error RegisterCallback(int32_t descriptor, hwc2_callback_data_t data,
+                               hwc2_function_pointer_t function);
+
+  DrmResources drm_;
+  std::shared_ptr<Importer> importer_;  // Shared with HwcDisplay
+  std::map<hwc2_display_t, HwcDisplay> displays_;
+  std::map<HWC2::Callback, HwcCallback> callbacks_;
+};
+}
diff --git a/drmplane.cpp b/drmplane.cpp
index c4ea722..4449256 100644
--- a/drmplane.cpp
+++ b/drmplane.cpp
@@ -23,7 +23,7 @@
 #include <errno.h>
 #include <stdint.h>
 
-#include <cutils/log.h>
+#include <log/log.h>
 #include <xf86drmMode.h>
 
 namespace android {
@@ -126,6 +126,10 @@
   if (ret)
     ALOGI("Could not get alpha property");
 
+  ret = drm_->GetPlaneProperty(*this, "IN_FENCE_FD", &in_fence_fd_property_);
+  if (ret)
+    ALOGI("Could not get IN_FENCE_FD property");
+
   return 0;
 }
 
@@ -188,4 +192,8 @@
 const DrmProperty &DrmPlane::alpha_property() const {
   return alpha_property_;
 }
+
+const DrmProperty &DrmPlane::in_fence_fd_property() const {
+  return in_fence_fd_property_;
+}
 }
diff --git a/drmplane.h b/drmplane.h
index 2e06986..5b73b08 100644
--- a/drmplane.h
+++ b/drmplane.h
@@ -54,6 +54,7 @@
   const DrmProperty &src_h_property() const;
   const DrmProperty &rotation_property() const;
   const DrmProperty &alpha_property() const;
+  const DrmProperty &in_fence_fd_property() const;
 
  private:
   DrmResources *drm_;
@@ -75,6 +76,7 @@
   DrmProperty src_h_property_;
   DrmProperty rotation_property_;
   DrmProperty alpha_property_;
+  DrmProperty in_fence_fd_property_;
 };
 }
 
diff --git a/drmresources.cpp b/drmresources.cpp
index e433239..ec6664c 100644
--- a/drmresources.cpp
+++ b/drmresources.cpp
@@ -30,12 +30,12 @@
 #include <xf86drm.h>
 #include <xf86drmMode.h>
 
-#include <cutils/log.h>
+#include <log/log.h>
 #include <cutils/properties.h>
 
 namespace android {
 
-DrmResources::DrmResources() : compositor_(this), event_listener_(this) {
+DrmResources::DrmResources() : event_listener_(this) {
 }
 
 DrmResources::~DrmResources() {
@@ -71,6 +71,11 @@
     return -ENODEV;
   }
 
+  min_resolution_ =
+      std::pair<uint32_t, uint32_t>(res->min_width, res->min_height);
+  max_resolution_ =
+      std::pair<uint32_t, uint32_t>(res->max_width, res->max_height);
+
   bool found_primary = false;
   int display_num = 1;
 
@@ -149,16 +154,28 @@
       break;
     }
 
-    if (conn->built_in() && !found_primary) {
+    connectors_.emplace_back(std::move(conn));
+  }
+
+  // First look for primary amongst internal connectors
+  for (auto &conn : connectors_) {
+    if (conn->internal() && !found_primary) {
       conn->set_display(0);
       found_primary = true;
     } else {
       conn->set_display(display_num);
       ++display_num;
     }
-
-    connectors_.emplace_back(std::move(conn));
   }
+
+  // Then look for primary amongst external connectors
+  for (auto &conn : connectors_) {
+    if (conn->external() && !found_primary) {
+      conn->set_display(0);
+      found_primary = true;
+    }
+  }
+
   if (res)
     drmModeFreeResources(res);
 
@@ -196,10 +213,6 @@
   if (ret)
     return ret;
 
-  ret = compositor_.Init();
-  if (ret)
-    return ret;
-
   ret = event_listener_.Init();
   if (ret) {
     ALOGE("Can't initialize event listener %d", ret);
@@ -240,6 +253,10 @@
   return NULL;
 }
 
+const std::vector<std::unique_ptr<DrmCrtc>> & DrmResources::crtcs() const {
+  return crtcs_;
+}
+
 uint32_t DrmResources::next_mode_id() {
   return ++mode_id_;
 }
@@ -328,54 +345,6 @@
   return 0;
 }
 
-int DrmResources::SetDisplayActiveMode(int display, const DrmMode &mode) {
-  std::unique_ptr<DrmComposition> comp(compositor_.CreateComposition(NULL));
-  if (!comp) {
-    ALOGE("Failed to create composition for dpms on %d", display);
-    return -ENOMEM;
-  }
-  int ret = comp->SetDisplayMode(display, mode);
-  if (ret) {
-    ALOGE("Failed to add mode to composition on %d %d", display, ret);
-    return ret;
-  }
-  ret = compositor_.QueueComposition(std::move(comp));
-  if (ret) {
-    ALOGE("Failed to queue dpms composition on %d %d", display, ret);
-    return ret;
-  }
-  return 0;
-}
-
-int DrmResources::SetDpmsMode(int display, uint64_t mode) {
-  if (mode != DRM_MODE_DPMS_ON && mode != DRM_MODE_DPMS_OFF) {
-    ALOGE("Invalid dpms mode %" PRIu64, mode);
-    return -EINVAL;
-  }
-
-  std::unique_ptr<DrmComposition> comp(compositor_.CreateComposition(NULL));
-  if (!comp) {
-    ALOGE("Failed to create composition for dpms on %d", display);
-    return -ENOMEM;
-  }
-  int ret = comp->SetDpmsMode(display, mode);
-  if (ret) {
-    ALOGE("Failed to add dpms %" PRIu64 " to composition on %d %d", mode,
-          display, ret);
-    return ret;
-  }
-  ret = compositor_.QueueComposition(std::move(comp));
-  if (ret) {
-    ALOGE("Failed to queue dpms composition on %d %d", display, ret);
-    return ret;
-  }
-  return 0;
-}
-
-DrmCompositor *DrmResources::compositor() {
-  return &compositor_;
-}
-
 DrmEventListener *DrmResources::event_listener() {
   return &event_listener_;
 }
diff --git a/drmresources.h b/drmresources.h
index 64e6b57..4cca48c 100644
--- a/drmresources.h
+++ b/drmresources.h
@@ -17,7 +17,6 @@
 #ifndef ANDROID_DRM_H_
 #define ANDROID_DRM_H_
 
-#include "drmcompositor.h"
 #include "drmconnector.h"
 #include "drmcrtc.h"
 #include "drmencoder.h"
@@ -47,10 +46,17 @@
     return planes_;
   }
 
+  std::pair<uint32_t, uint32_t> min_resolution() const {
+    return min_resolution_;
+  }
+
+  std::pair<uint32_t, uint32_t> max_resolution() const {
+    return max_resolution_;
+  }
+
   DrmConnector *GetConnectorForDisplay(int display) const;
   DrmCrtc *GetCrtcForDisplay(int display) const;
   DrmPlane *GetPlane(uint32_t id) const;
-  DrmCompositor *compositor();
   DrmEventListener *event_listener();
 
   int GetPlaneProperty(const DrmPlane &plane, const char *prop_name,
@@ -60,9 +66,8 @@
   int GetConnectorProperty(const DrmConnector &connector, const char *prop_name,
                            DrmProperty *property);
 
+  const std::vector<std::unique_ptr<DrmCrtc>> &crtcs() const;
   uint32_t next_mode_id();
-  int SetDisplayActiveMode(int display, const DrmMode &mode);
-  int SetDpmsMode(int display, uint64_t mode);
 
   int CreatePropertyBlob(void *data, size_t length, uint32_t *blob_id);
   int DestroyPropertyBlob(uint32_t blob_id);
@@ -81,8 +86,10 @@
   std::vector<std::unique_ptr<DrmEncoder>> encoders_;
   std::vector<std::unique_ptr<DrmCrtc>> crtcs_;
   std::vector<std::unique_ptr<DrmPlane>> planes_;
-  DrmCompositor compositor_;
   DrmEventListener event_listener_;
+
+  std::pair<uint32_t, uint32_t> min_resolution_;
+  std::pair<uint32_t, uint32_t> max_resolution_;
 };
 }
 
diff --git a/glworker.cpp b/glworker.cpp
deleted file mode 100644
index 6ce2de3..0000000
--- a/glworker.cpp
+++ /dev/null
@@ -1,803 +0,0 @@
-/*
- * Copyright (C) 2015 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
-#define LOG_TAG "hwc-gl-worker"
-
-#include <algorithm>
-#include <string>
-#include <sstream>
-#include <unordered_set>
-
-#include <sys/resource.h>
-
-#include <cutils/properties.h>
-
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer.h>
-
-#include <ui/GraphicBuffer.h>
-#include <ui/PixelFormat.h>
-
-#include <utils/Trace.h>
-
-#include "drmdisplaycomposition.h"
-
-#include "glworker.h"
-
-// TODO(zachr): use hwc_drm_bo to turn buffer handles into textures
-#ifndef EGL_NATIVE_HANDLE_ANDROID_NVX
-#define EGL_NATIVE_HANDLE_ANDROID_NVX 0x322A
-#endif
-
-#define MAX_OVERLAPPING_LAYERS 64
-
-namespace android {
-
-// clang-format off
-// Column-major order:
-// float mat[4] = { 1, 2, 3, 4 } ===
-// [ 1 3 ]
-// [ 2 4 ]
-float kTextureTransformMatrices[] = {
-   1.0f,  0.0f,  0.0f,  1.0f, // identity matrix
-   0.0f,  1.0f,  1.0f,  0.0f, // swap x and y
-};
-// clang-format on
-
-static const char *GetGLError(void) {
-  switch (glGetError()) {
-    case GL_NO_ERROR:
-      return "GL_NO_ERROR";
-    case GL_INVALID_ENUM:
-      return "GL_INVALID_ENUM";
-    case GL_INVALID_VALUE:
-      return "GL_INVALID_VALUE";
-    case GL_INVALID_OPERATION:
-      return "GL_INVALID_OPERATION";
-    case GL_INVALID_FRAMEBUFFER_OPERATION:
-      return "GL_INVALID_FRAMEBUFFER_OPERATION";
-    case GL_OUT_OF_MEMORY:
-      return "GL_OUT_OF_MEMORY";
-    default:
-      return "Unknown error";
-  }
-}
-
-static const char *GetGLFramebufferError(void) {
-  switch (glCheckFramebufferStatus(GL_FRAMEBUFFER)) {
-    case GL_FRAMEBUFFER_COMPLETE:
-      return "GL_FRAMEBUFFER_COMPLETE";
-    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
-      return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
-    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
-      return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
-    case GL_FRAMEBUFFER_UNSUPPORTED:
-      return "GL_FRAMEBUFFER_UNSUPPORTED";
-    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
-      return "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
-    default:
-      return "Unknown error";
-  }
-}
-
-static const char *GetEGLError(void) {
-  switch (eglGetError()) {
-    case EGL_SUCCESS:
-      return "EGL_SUCCESS";
-    case EGL_NOT_INITIALIZED:
-      return "EGL_NOT_INITIALIZED";
-    case EGL_BAD_ACCESS:
-      return "EGL_BAD_ACCESS";
-    case EGL_BAD_ALLOC:
-      return "EGL_BAD_ALLOC";
-    case EGL_BAD_ATTRIBUTE:
-      return "EGL_BAD_ATTRIBUTE";
-    case EGL_BAD_CONTEXT:
-      return "EGL_BAD_CONTEXT";
-    case EGL_BAD_CONFIG:
-      return "EGL_BAD_CONFIG";
-    case EGL_BAD_CURRENT_SURFACE:
-      return "EGL_BAD_CURRENT_SURFACE";
-    case EGL_BAD_DISPLAY:
-      return "EGL_BAD_DISPLAY";
-    case EGL_BAD_SURFACE:
-      return "EGL_BAD_SURFACE";
-    case EGL_BAD_MATCH:
-      return "EGL_BAD_MATCH";
-    case EGL_BAD_PARAMETER:
-      return "EGL_BAD_PARAMETER";
-    case EGL_BAD_NATIVE_PIXMAP:
-      return "EGL_BAD_NATIVE_PIXMAP";
-    case EGL_BAD_NATIVE_WINDOW:
-      return "EGL_BAD_NATIVE_WINDOW";
-    case EGL_CONTEXT_LOST:
-      return "EGL_CONTEXT_LOST";
-    default:
-      return "Unknown error";
-  }
-}
-
-static bool HasExtension(const char *extension, const char *extensions) {
-  const char *start, *where, *terminator;
-  start = extensions;
-  for (;;) {
-    where = (char *)strstr((const char *)start, extension);
-    if (!where)
-      break;
-    terminator = where + strlen(extension);
-    if (where == start || *(where - 1) == ' ')
-      if (*terminator == ' ' || *terminator == '\0')
-        return true;
-    start = terminator;
-  }
-  return false;
-}
-
-static AutoGLShader CompileAndCheckShader(GLenum type, unsigned source_count,
-                                          const GLchar **sources,
-                                          std::ostringstream *shader_log) {
-  GLint status;
-  AutoGLShader shader(glCreateShader(type));
-  if (shader.get() == 0) {
-    if (shader_log)
-      *shader_log << "Failed glCreateShader call";
-    return 0;
-  }
-
-  glShaderSource(shader.get(), source_count, sources, NULL);
-  glCompileShader(shader.get());
-  glGetShaderiv(shader.get(), GL_COMPILE_STATUS, &status);
-  if (!status) {
-    if (shader_log) {
-      GLint log_length;
-      glGetShaderiv(shader.get(), GL_INFO_LOG_LENGTH, &log_length);
-      std::string info_log(log_length, ' ');
-      glGetShaderInfoLog(shader.get(), log_length, NULL, &info_log.front());
-      *shader_log << "Failed to compile shader:\n" << info_log.c_str()
-                  << "\nShader Source:\n";
-      for (unsigned i = 0; i < source_count; i++) {
-        *shader_log << sources[i];
-      }
-      *shader_log << "\n";
-    }
-    return 0;
-  }
-
-  return shader;
-}
-
-static std::string GenerateVertexShader(int layer_count) {
-  std::ostringstream vertex_shader_stream;
-  vertex_shader_stream
-      << "#version 300 es\n"
-      << "#define LAYER_COUNT " << layer_count << "\n"
-      << "precision mediump int;\n"
-      << "uniform vec4 uViewport;\n"
-      << "uniform vec4 uLayerCrop[LAYER_COUNT];\n"
-      << "uniform mat2 uTexMatrix[LAYER_COUNT];\n"
-      << "in vec2 vPosition;\n"
-      << "in vec2 vTexCoords;\n"
-      << "out vec2 fTexCoords[LAYER_COUNT];\n"
-      << "void main() {\n"
-      << "  for (int i = 0; i < LAYER_COUNT; i++) {\n"
-      << "    vec2 tempCoords = vTexCoords * uTexMatrix[i];\n"
-      << "    fTexCoords[i] =\n"
-      << "        uLayerCrop[i].xy + tempCoords * uLayerCrop[i].zw;\n"
-      << "  }\n"
-      << "  vec2 scaledPosition = uViewport.xy + vPosition * uViewport.zw;\n"
-      << "  gl_Position =\n"
-      << "      vec4(scaledPosition * vec2(2.0) - vec2(1.0), 0.0, 1.0);\n"
-      << "}\n";
-  return vertex_shader_stream.str();
-}
-
-static std::string GenerateFragmentShader(int layer_count) {
-  std::ostringstream fragment_shader_stream;
-  fragment_shader_stream << "#version 300 es\n"
-                         << "#define LAYER_COUNT " << layer_count << "\n"
-                         << "#extension GL_OES_EGL_image_external : require\n"
-                         << "precision mediump float;\n";
-  for (int i = 0; i < layer_count; ++i) {
-    fragment_shader_stream << "uniform samplerExternalOES uLayerTexture" << i
-                           << ";\n";
-  }
-  fragment_shader_stream << "uniform float uLayerAlpha[LAYER_COUNT];\n"
-                         << "uniform float uLayerPremult[LAYER_COUNT];\n"
-                         << "in vec2 fTexCoords[LAYER_COUNT];\n"
-                         << "out vec4 oFragColor;\n"
-                         << "void main() {\n"
-                         << "  vec3 color = vec3(0.0, 0.0, 0.0);\n"
-                         << "  float alphaCover = 1.0;\n"
-                         << "  vec4 texSample;\n"
-                         << "  vec3 multRgb;\n";
-  for (int i = 0; i < layer_count; ++i) {
-    if (i > 0)
-      fragment_shader_stream << "  if (alphaCover > 0.5/255.0) {\n";
-    // clang-format off
-    fragment_shader_stream
-        << "  texSample = texture2D(uLayerTexture" << i << ",\n"
-        << "                        fTexCoords[" << i << "]);\n"
-        << "  multRgb = texSample.rgb *\n"
-        << "            max(texSample.a, uLayerPremult[" << i << "]);\n"
-        << "  color += multRgb * uLayerAlpha[" << i << "] * alphaCover;\n"
-        << "  alphaCover *= 1.0 - texSample.a * uLayerAlpha[" << i << "];\n";
-    // clang-format on
-  }
-  for (int i = 0; i < layer_count - 1; ++i)
-    fragment_shader_stream << "  }\n";
-  fragment_shader_stream << "  oFragColor = vec4(color, 1.0 - alphaCover);\n"
-                         << "}\n";
-  return fragment_shader_stream.str();
-}
-
-static AutoGLProgram GenerateProgram(unsigned num_textures,
-                                     std::ostringstream *shader_log) {
-  std::string vertex_shader_string = GenerateVertexShader(num_textures);
-  const GLchar *vertex_shader_source = vertex_shader_string.c_str();
-  AutoGLShader vertex_shader = CompileAndCheckShader(
-      GL_VERTEX_SHADER, 1, &vertex_shader_source, shader_log);
-  if (!vertex_shader.get())
-    return 0;
-
-  std::string fragment_shader_string = GenerateFragmentShader(num_textures);
-  const GLchar *fragment_shader_source = fragment_shader_string.c_str();
-  AutoGLShader fragment_shader = CompileAndCheckShader(
-      GL_FRAGMENT_SHADER, 1, &fragment_shader_source, shader_log);
-  if (!fragment_shader.get())
-    return 0;
-
-  AutoGLProgram program(glCreateProgram());
-  if (!program.get()) {
-    if (shader_log)
-      *shader_log << "Failed to create program: " << GetGLError() << "\n";
-    return 0;
-  }
-
-  glAttachShader(program.get(), vertex_shader.get());
-  glAttachShader(program.get(), fragment_shader.get());
-  glBindAttribLocation(program.get(), 0, "vPosition");
-  glBindAttribLocation(program.get(), 1, "vTexCoords");
-  glLinkProgram(program.get());
-  glDetachShader(program.get(), vertex_shader.get());
-  glDetachShader(program.get(), fragment_shader.get());
-
-  GLint status;
-  glGetProgramiv(program.get(), GL_LINK_STATUS, &status);
-  if (!status) {
-    if (shader_log) {
-      GLint log_length;
-      glGetProgramiv(program.get(), GL_INFO_LOG_LENGTH, &log_length);
-      std::string program_log(log_length, ' ');
-      glGetProgramInfoLog(program.get(), log_length, NULL,
-                          &program_log.front());
-      *shader_log << "Failed to link program:\n" << program_log.c_str() << "\n";
-    }
-    return 0;
-  }
-
-  return program;
-}
-
-struct RenderingCommand {
-  struct TextureSource {
-    unsigned texture_index;
-    float crop_bounds[4];
-    float alpha;
-    float premult;
-    float texture_matrix[4];
-  };
-
-  float bounds[4];
-  unsigned texture_count = 0;
-  TextureSource textures[MAX_OVERLAPPING_LAYERS];
-};
-
-static void ConstructCommand(const DrmHwcLayer *layers,
-                             const DrmCompositionRegion &region,
-                             RenderingCommand &cmd) {
-  std::copy_n(region.frame.bounds, 4, cmd.bounds);
-
-  for (size_t texture_index : region.source_layers) {
-    const DrmHwcLayer &layer = layers[texture_index];
-
-    DrmHwcRect<float> display_rect(layer.display_frame);
-    float display_size[2] = {display_rect.bounds[2] - display_rect.bounds[0],
-                             display_rect.bounds[3] - display_rect.bounds[1]};
-
-    float tex_width = layer.buffer->width;
-    float tex_height = layer.buffer->height;
-    DrmHwcRect<float> crop_rect(layer.source_crop.left / tex_width,
-                                layer.source_crop.top / tex_height,
-                                layer.source_crop.right / tex_width,
-                                layer.source_crop.bottom / tex_height);
-
-    float crop_size[2] = {crop_rect.bounds[2] - crop_rect.bounds[0],
-                          crop_rect.bounds[3] - crop_rect.bounds[1]};
-
-    RenderingCommand::TextureSource &src = cmd.textures[cmd.texture_count];
-    cmd.texture_count++;
-    src.texture_index = texture_index;
-
-    bool swap_xy = false;
-    bool flip_xy[2] = { false, false };
-
-    if (layer.transform == DrmHwcTransform::kRotate180) {
-      swap_xy = false;
-      flip_xy[0] = true;
-      flip_xy[1] = true;
-    } else if (layer.transform == DrmHwcTransform::kRotate270) {
-      swap_xy = true;
-      flip_xy[0] = true;
-      flip_xy[1] = false;
-    } else if (layer.transform & DrmHwcTransform::kRotate90) {
-      swap_xy = true;
-      if (layer.transform & DrmHwcTransform::kFlipH) {
-        flip_xy[0] = true;
-        flip_xy[1] = true;
-      } else if (layer.transform & DrmHwcTransform::kFlipV) {
-        flip_xy[0] = false;
-        flip_xy[1] = false;
-      } else {
-        flip_xy[0] = false;
-        flip_xy[1] = true;
-      }
-    } else {
-      if (layer.transform & DrmHwcTransform::kFlipH)
-        flip_xy[0] = true;
-      if (layer.transform & DrmHwcTransform::kFlipV)
-        flip_xy[1] = true;
-    }
-
-    if (swap_xy)
-      std::copy_n(&kTextureTransformMatrices[4], 4, src.texture_matrix);
-    else
-      std::copy_n(&kTextureTransformMatrices[0], 4, src.texture_matrix);
-
-    for (int j = 0; j < 4; j++) {
-      int b = j ^ (swap_xy ? 1 : 0);
-      float bound_percent =
-          (cmd.bounds[b] - display_rect.bounds[b % 2]) / display_size[b % 2];
-      if (flip_xy[j % 2]) {
-        src.crop_bounds[j] =
-            crop_rect.bounds[j % 2 + 2] - bound_percent * crop_size[j % 2];
-      } else {
-        src.crop_bounds[j] =
-            crop_rect.bounds[j % 2] + bound_percent * crop_size[j % 2];
-      }
-    }
-
-    if (layer.blending == DrmHwcBlending::kNone) {
-      src.alpha = src.premult = 1.0f;
-      // This layer is opaque. There is no point in using layers below this one.
-      break;
-    }
-
-    src.alpha = layer.alpha / 255.0f;
-    src.premult = (layer.blending == DrmHwcBlending::kPreMult) ? 1.0f : 0.0f;
-  }
-}
-
-static int EGLFenceWait(EGLDisplay egl_display, int acquireFenceFd) {
-  int ret = 0;
-
-  EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, acquireFenceFd,
-                      EGL_NONE};
-  EGLSyncKHR egl_sync =
-      eglCreateSyncKHR(egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
-  if (egl_sync == EGL_NO_SYNC_KHR) {
-    ALOGE("Failed to make EGLSyncKHR from acquireFenceFd: %s", GetEGLError());
-    close(acquireFenceFd);
-    return 1;
-  }
-
-  EGLint success = eglWaitSyncKHR(egl_display, egl_sync, 0);
-  if (success == EGL_FALSE) {
-    ALOGE("Failed to wait for acquire: %s", GetEGLError());
-    ret = 1;
-  }
-  eglDestroySyncKHR(egl_display, egl_sync);
-
-  return ret;
-}
-
-static int CreateTextureFromHandle(EGLDisplay egl_display,
-                                   buffer_handle_t handle,
-                                   AutoEGLImageAndGLTexture *out) {
-  EGLImageKHR image = eglCreateImageKHR(
-      egl_display, EGL_NO_CONTEXT, EGL_NATIVE_HANDLE_ANDROID_NVX,
-      (EGLClientBuffer)handle, NULL /* no attribs */);
-
-  if (image == EGL_NO_IMAGE_KHR) {
-    ALOGE("Failed to make image %s %p", GetEGLError(), handle);
-    return -EINVAL;
-  }
-
-  GLuint texture;
-  glGenTextures(1, &texture);
-  glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
-  glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)image);
-  glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-  glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-  glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_REPEAT);
-  glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_REPEAT);
-  glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
-
-  out->image.reset(egl_display, image);
-  out->texture.reset(texture);
-
-  return 0;
-}
-
-GLWorkerCompositor::GLWorkerCompositor()
-    : egl_display_(EGL_NO_DISPLAY), egl_ctx_(EGL_NO_CONTEXT) {
-}
-
-int GLWorkerCompositor::Init() {
-  int ret = 0;
-  const char *egl_extensions;
-  const char *gl_extensions;
-  EGLint num_configs;
-  EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE};
-  EGLConfig egl_config;
-
-  // clang-format off
-  const GLfloat verts[] = {
-    0.0f,  0.0f,    0.0f, 0.0f,
-    0.0f,  2.0f,    0.0f, 2.0f,
-    2.0f,  0.0f,    2.0f, 0.0f
-  };
-  // clang-format on
-
-  const EGLint config_attribs[] = {EGL_RENDERABLE_TYPE,
-                                   EGL_OPENGL_ES2_BIT,
-                                   EGL_RED_SIZE,
-                                   8,
-                                   EGL_GREEN_SIZE,
-                                   8,
-                                   EGL_BLUE_SIZE,
-                                   8,
-                                   EGL_NONE};
-
-  const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
-
-  egl_display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  if (egl_display_ == EGL_NO_DISPLAY) {
-    ALOGE("Failed to get egl display");
-    return 1;
-  }
-
-  if (!eglInitialize(egl_display_, NULL, NULL)) {
-    ALOGE("Failed to initialize egl: %s", GetEGLError());
-    return 1;
-  }
-
-  egl_extensions = eglQueryString(egl_display_, EGL_EXTENSIONS);
-
-  // These extensions are all technically required but not always reported due
-  // to meta EGL filtering them out.
-  if (!HasExtension("EGL_KHR_image_base", egl_extensions))
-    ALOGW("EGL_KHR_image_base extension not supported");
-
-  if (!HasExtension("EGL_ANDROID_image_native_buffer", egl_extensions))
-    ALOGW("EGL_ANDROID_image_native_buffer extension not supported");
-
-  if (!HasExtension("EGL_ANDROID_native_fence_sync", egl_extensions))
-    ALOGW("EGL_ANDROID_native_fence_sync extension not supported");
-
-  if (!eglChooseConfig(egl_display_, config_attribs, &egl_config, 1,
-                       &num_configs)) {
-    ALOGE("eglChooseConfig() failed with error: %s", GetEGLError());
-    return 1;
-  }
-
-  egl_ctx_ =
-      eglCreateContext(egl_display_, egl_config,
-                       EGL_NO_CONTEXT /* No shared context */, context_attribs);
-
-  if (egl_ctx_ == EGL_NO_CONTEXT) {
-    ALOGE("Failed to create OpenGL ES Context: %s", GetEGLError());
-    return 1;
-  }
-
-  if (!eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_ctx_)) {
-    ALOGE("Failed to make the OpenGL ES Context current: %s", GetEGLError());
-    return 1;
-  }
-
-  gl_extensions = (const char *)glGetString(GL_EXTENSIONS);
-
-  if (!HasExtension("GL_OES_EGL_image", gl_extensions))
-    ALOGW("GL_OES_EGL_image extension not supported");
-
-  if (!HasExtension("GL_OES_EGL_image_external", gl_extensions))
-    ALOGW("GL_OES_EGL_image_external extension not supported");
-
-  GLuint vertex_buffer;
-  glGenBuffers(1, &vertex_buffer);
-  glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
-  glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
-  glBindBuffer(GL_ARRAY_BUFFER, 0);
-  vertex_buffer_.reset(vertex_buffer);
-
-  std::ostringstream shader_log;
-  blend_programs_.emplace_back(GenerateProgram(1, &shader_log));
-  if (blend_programs_.back().get() == 0) {
-    ALOGE("%s", shader_log.str().c_str());
-    return 1;
-  }
-
-  return 0;
-}
-
-GLWorkerCompositor::~GLWorkerCompositor() {
-  if (egl_display_ != EGL_NO_DISPLAY && egl_ctx_ != EGL_NO_CONTEXT)
-    if (eglDestroyContext(egl_display_, egl_ctx_) == EGL_FALSE)
-      ALOGE("Failed to destroy OpenGL ES Context: %s", GetEGLError());
-}
-
-int GLWorkerCompositor::Composite(DrmHwcLayer *layers,
-                                  DrmCompositionRegion *regions,
-                                  size_t num_regions,
-                                  const sp<GraphicBuffer> &framebuffer) {
-  ATRACE_CALL();
-  int ret = 0;
-  std::vector<AutoEGLImageAndGLTexture> layer_textures;
-  std::vector<RenderingCommand> commands;
-
-  if (num_regions == 0) {
-    return -EALREADY;
-  }
-
-  GLint frame_width = framebuffer->getWidth();
-  GLint frame_height = framebuffer->getHeight();
-  CachedFramebuffer *cached_framebuffer =
-      PrepareAndCacheFramebuffer(framebuffer);
-  if (cached_framebuffer == NULL) {
-    ALOGE("Composite failed because of failed framebuffer");
-    return -EINVAL;
-  }
-
-  std::unordered_set<size_t> layers_used_indices;
-  for (size_t region_index = 0; region_index < num_regions; region_index++) {
-    DrmCompositionRegion &region = regions[region_index];
-    layers_used_indices.insert(region.source_layers.begin(),
-                               region.source_layers.end());
-    commands.emplace_back();
-    ConstructCommand(layers, region, commands.back());
-  }
-
-  for (size_t layer_index = 0; layer_index < MAX_OVERLAPPING_LAYERS;
-       layer_index++) {
-    DrmHwcLayer *layer = &layers[layer_index];
-
-    layer_textures.emplace_back();
-
-    if (layers_used_indices.count(layer_index) == 0)
-      continue;
-
-    ret = CreateTextureFromHandle(egl_display_, layer->get_usable_handle(),
-                                  &layer_textures.back());
-
-    if (!ret) {
-      ret = EGLFenceWait(egl_display_, layer->acquire_fence.Release());
-    }
-    if (ret) {
-      layer_textures.pop_back();
-      ret = -EINVAL;
-    }
-  }
-
-  if (ret)
-    return ret;
-
-  glViewport(0, 0, frame_width, frame_height);
-
-  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-  glClear(GL_COLOR_BUFFER_BIT);
-
-  glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_.get());
-  glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, NULL);
-  glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4,
-                        (void *)(sizeof(float) * 2));
-  glEnableVertexAttribArray(0);
-  glEnableVertexAttribArray(1);
-  glEnable(GL_SCISSOR_TEST);
-
-  for (const RenderingCommand &cmd : commands) {
-    if (cmd.texture_count == 0)
-      continue;
-
-    // TODO(zachr): handle the case of too many overlapping textures for one
-    // area by falling back to rendering as many layers as possible using
-    // multiple blending passes.
-    GLint program = PrepareAndCacheProgram(cmd.texture_count);
-    if (program == 0) {
-      ALOGE("Too many layers to render in one area");
-      continue;
-    }
-
-    glUseProgram(program);
-    GLint gl_viewport_loc = glGetUniformLocation(program, "uViewport");
-    GLint gl_crop_loc = glGetUniformLocation(program, "uLayerCrop");
-    GLint gl_alpha_loc = glGetUniformLocation(program, "uLayerAlpha");
-    GLint gl_premult_loc = glGetUniformLocation(program, "uLayerPremult");
-    GLint gl_tex_matrix_loc = glGetUniformLocation(program, "uTexMatrix");
-    glUniform4f(gl_viewport_loc, cmd.bounds[0] / (float)frame_width,
-                cmd.bounds[1] / (float)frame_height,
-                (cmd.bounds[2] - cmd.bounds[0]) / (float)frame_width,
-                (cmd.bounds[3] - cmd.bounds[1]) / (float)frame_height);
-
-    for (unsigned src_index = 0; src_index < cmd.texture_count; src_index++) {
-      std::ostringstream texture_name_formatter;
-      texture_name_formatter << "uLayerTexture" << src_index;
-      GLint gl_tex_loc =
-          glGetUniformLocation(program, texture_name_formatter.str().c_str());
-
-      const RenderingCommand::TextureSource &src = cmd.textures[src_index];
-      glUniform1f(gl_alpha_loc + src_index, src.alpha);
-      glUniform1f(gl_premult_loc + src_index, src.premult);
-      glUniform4f(gl_crop_loc + src_index, src.crop_bounds[0],
-                  src.crop_bounds[1], src.crop_bounds[2] - src.crop_bounds[0],
-                  src.crop_bounds[3] - src.crop_bounds[1]);
-      glUniform1i(gl_tex_loc, src_index);
-      glUniformMatrix2fv(gl_tex_matrix_loc + src_index, 1, GL_FALSE,
-                         src.texture_matrix);
-      glActiveTexture(GL_TEXTURE0 + src_index);
-      glBindTexture(GL_TEXTURE_EXTERNAL_OES,
-                    layer_textures[src.texture_index].texture.get());
-    }
-
-    glScissor(cmd.bounds[0], cmd.bounds[1], cmd.bounds[2] - cmd.bounds[0],
-              cmd.bounds[3] - cmd.bounds[1]);
-    glDrawArrays(GL_TRIANGLES, 0, 3);
-
-    for (unsigned src_index = 0; src_index < cmd.texture_count; src_index++) {
-      glActiveTexture(GL_TEXTURE0 + src_index);
-      glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
-    }
-  }
-
-  glDisable(GL_SCISSOR_TEST);
-  glActiveTexture(GL_TEXTURE0);
-  glDisableVertexAttribArray(0);
-  glDisableVertexAttribArray(1);
-  glBindBuffer(GL_ARRAY_BUFFER, 0);
-  glUseProgram(0);
-
-  glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
-  return ret;
-}
-
-void GLWorkerCompositor::Finish() {
-  ATRACE_CALL();
-  glFinish();
-
-  char use_framebuffer_cache_opt[PROPERTY_VALUE_MAX];
-  property_get("hwc.drm.use_framebuffer_cache", use_framebuffer_cache_opt, "1");
-  bool use_framebuffer_cache = atoi(use_framebuffer_cache_opt);
-
-  if (use_framebuffer_cache) {
-    for (auto &fb : cached_framebuffers_)
-      fb.strong_framebuffer.clear();
-  } else {
-    cached_framebuffers_.clear();
-  }
-}
-
-GLWorkerCompositor::CachedFramebuffer::CachedFramebuffer(
-    const sp<GraphicBuffer> &gb, AutoEGLDisplayImage &&image,
-    AutoGLTexture &&tex, AutoGLFramebuffer &&fb)
-    : strong_framebuffer(gb),
-      weak_framebuffer(gb),
-      egl_fb_image(std::move(image)),
-      gl_fb_tex(std::move(tex)),
-      gl_fb(std::move(fb)) {
-}
-
-bool GLWorkerCompositor::CachedFramebuffer::Promote() {
-  if (strong_framebuffer.get() != NULL)
-    return true;
-  strong_framebuffer = weak_framebuffer.promote();
-  return strong_framebuffer.get() != NULL;
-}
-
-GLWorkerCompositor::CachedFramebuffer *
-GLWorkerCompositor::FindCachedFramebuffer(
-    const sp<GraphicBuffer> &framebuffer) {
-  for (auto &fb : cached_framebuffers_)
-    if (fb.weak_framebuffer == framebuffer)
-      return &fb;
-  return NULL;
-}
-
-GLWorkerCompositor::CachedFramebuffer *
-GLWorkerCompositor::PrepareAndCacheFramebuffer(
-    const sp<GraphicBuffer> &framebuffer) {
-  CachedFramebuffer *cached_framebuffer = FindCachedFramebuffer(framebuffer);
-  if (cached_framebuffer != NULL) {
-    if (cached_framebuffer->Promote()) {
-      glBindFramebuffer(GL_FRAMEBUFFER, cached_framebuffer->gl_fb.get());
-      return cached_framebuffer;
-    }
-
-    for (auto it = cached_framebuffers_.begin();
-         it != cached_framebuffers_.end(); ++it) {
-      if (it->weak_framebuffer == framebuffer) {
-        cached_framebuffers_.erase(it);
-        break;
-      }
-    }
-  }
-
-  AutoEGLDisplayImage egl_fb_image(
-      egl_display_,
-      eglCreateImageKHR(egl_display_, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
-                        (EGLClientBuffer)framebuffer->getNativeBuffer(),
-                        NULL /* no attribs */));
-
-  if (egl_fb_image.image() == EGL_NO_IMAGE_KHR) {
-    ALOGE("Failed to make image from target buffer: %s", GetEGLError());
-    return NULL;
-  }
-
-  GLuint gl_fb_tex;
-  glGenTextures(1, &gl_fb_tex);
-  AutoGLTexture gl_fb_tex_auto(gl_fb_tex);
-  glBindTexture(GL_TEXTURE_2D, gl_fb_tex);
-  glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
-                               (GLeglImageOES)egl_fb_image.image());
-  glBindTexture(GL_TEXTURE_2D, 0);
-
-  GLuint gl_fb;
-  glGenFramebuffers(1, &gl_fb);
-  AutoGLFramebuffer gl_fb_auto(gl_fb);
-  glBindFramebuffer(GL_FRAMEBUFFER, gl_fb);
-  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-                         gl_fb_tex, 0);
-
-  if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
-    ALOGE("Failed framebuffer check for created target buffer: %s",
-          GetGLFramebufferError());
-    return NULL;
-  }
-
-  cached_framebuffers_.emplace_back(framebuffer, std::move(egl_fb_image),
-                                    std::move(gl_fb_tex_auto),
-                                    std::move(gl_fb_auto));
-  return &cached_framebuffers_.back();
-}
-
-GLint GLWorkerCompositor::PrepareAndCacheProgram(unsigned texture_count) {
-  if (blend_programs_.size() >= texture_count) {
-    GLint program = blend_programs_[texture_count - 1].get();
-    if (program != 0)
-      return program;
-  }
-
-  AutoGLProgram program = GenerateProgram(texture_count, NULL);
-  if (program.get() != 0) {
-    if (blend_programs_.size() < texture_count)
-      blend_programs_.resize(texture_count);
-    blend_programs_[texture_count - 1] = std::move(program);
-    return blend_programs_[texture_count - 1].get();
-  }
-
-  return 0;
-}
-
-}  // namespace android
diff --git a/glworker.h b/glworker.h
deleted file mode 100644
index 222cf6f..0000000
--- a/glworker.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2015 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_GL_WORKER_H_
-#define ANDROID_GL_WORKER_H_
-
-#include <vector>
-
-#define EGL_EGLEXT_PROTOTYPES
-#define GL_GLEXT_PROTOTYPES
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include <ui/GraphicBuffer.h>
-
-#include "autogl.h"
-
-namespace android {
-
-struct DrmHwcLayer;
-struct DrmCompositionRegion;
-
-class GLWorkerCompositor {
- public:
-  GLWorkerCompositor();
-  ~GLWorkerCompositor();
-
-  int Init();
-  int Composite(DrmHwcLayer *layers, DrmCompositionRegion *regions,
-                size_t num_regions, const sp<GraphicBuffer> &framebuffer);
-  void Finish();
-
- private:
-  struct CachedFramebuffer {
-    // If the strong_framebuffer is non-NULL, we are holding a strong reference
-    // until we are sure rendering is done. The weak reference will be equal in
-    // that case.
-    sp<GraphicBuffer> strong_framebuffer;
-    wp<GraphicBuffer> weak_framebuffer;
-    AutoEGLDisplayImage egl_fb_image;
-    AutoGLTexture gl_fb_tex;
-    AutoGLFramebuffer gl_fb;
-
-    CachedFramebuffer(const sp<GraphicBuffer> &gb, AutoEGLDisplayImage &&image,
-                      AutoGLTexture &&tex, AutoGLFramebuffer &&fb);
-
-    bool Promote();
-  };
-
-  CachedFramebuffer *FindCachedFramebuffer(
-      const sp<GraphicBuffer> &framebuffer);
-  CachedFramebuffer *PrepareAndCacheFramebuffer(
-      const sp<GraphicBuffer> &framebuffer);
-
-  GLint PrepareAndCacheProgram(unsigned texture_count);
-
-  EGLDisplay egl_display_;
-  EGLContext egl_ctx_;
-
-  std::vector<AutoGLProgram> blend_programs_;
-  AutoGLBuffer vertex_buffer_;
-
-  std::vector<CachedFramebuffer> cached_framebuffers_;
-};
-}
-
-#endif
diff --git a/hwcomposer.cpp b/hwcomposer.cpp
deleted file mode 100644
index 8d8e1d0..0000000
--- a/hwcomposer.cpp
+++ /dev/null
@@ -1,986 +0,0 @@
-/*
- * Copyright (C) 2015 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
-#define LOG_TAG "hwcomposer-drm"
-
-#include "drmhwcomposer.h"
-#include "drmeventlistener.h"
-#include "drmresources.h"
-#include "platform.h"
-#include "virtualcompositorworker.h"
-#include "vsyncworker.h"
-
-#include <stdlib.h>
-
-#include <cinttypes>
-#include <map>
-#include <vector>
-#include <sstream>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/param.h>
-#include <sys/resource.h>
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-
-#include <cutils/log.h>
-#include <cutils/properties.h>
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer.h>
-#include <sw_sync.h>
-#include <sync/sync.h>
-#include <utils/Trace.h>
-
-#define UM_PER_INCH 25400
-
-namespace android {
-
-class DummySwSyncTimeline {
- public:
-  int Init() {
-    int ret = timeline_fd_.Set(sw_sync_timeline_create());
-    if (ret < 0)
-      return ret;
-    return 0;
-  }
-
-  UniqueFd CreateDummyFence() {
-    int ret = sw_sync_fence_create(timeline_fd_.get(), "dummy fence",
-                                   timeline_pt_ + 1);
-    if (ret < 0) {
-      ALOGE("Failed to create dummy fence %d", ret);
-      return ret;
-    }
-
-    UniqueFd ret_fd(ret);
-
-    ret = sw_sync_timeline_inc(timeline_fd_.get(), 1);
-    if (ret) {
-      ALOGE("Failed to increment dummy sync timeline %d", ret);
-      return ret;
-    }
-
-    ++timeline_pt_;
-    return ret_fd;
-  }
-
- private:
-  UniqueFd timeline_fd_;
-  int timeline_pt_ = 0;
-};
-
-struct CheckedOutputFd {
-  CheckedOutputFd(int *fd, const char *description,
-                  DummySwSyncTimeline &timeline)
-      : fd_(fd), description_(description), timeline_(timeline) {
-  }
-  CheckedOutputFd(CheckedOutputFd &&rhs)
-      : description_(rhs.description_), timeline_(rhs.timeline_) {
-    std::swap(fd_, rhs.fd_);
-  }
-
-  CheckedOutputFd &operator=(const CheckedOutputFd &rhs) = delete;
-
-  ~CheckedOutputFd() {
-    if (fd_ == NULL)
-      return;
-
-    if (*fd_ >= 0)
-      return;
-
-    *fd_ = timeline_.CreateDummyFence().Release();
-
-    if (*fd_ < 0)
-      ALOGE("Failed to fill %s (%p == %d) before destruction",
-            description_.c_str(), fd_, *fd_);
-  }
-
- private:
-  int *fd_ = NULL;
-  std::string description_;
-  DummySwSyncTimeline &timeline_;
-};
-
-typedef struct hwc_drm_display {
-  struct hwc_context_t *ctx;
-  int display;
-
-  std::vector<uint32_t> config_ids;
-
-  VSyncWorker vsync_worker;
-} hwc_drm_display_t;
-
-class DrmHotplugHandler : public DrmEventHandler {
- public:
-  void Init(DrmResources *drm, const struct hwc_procs *procs) {
-    drm_ = drm;
-    procs_ = procs;
-  }
-
-  void HandleEvent(uint64_t timestamp_us) {
-    for (auto &conn : drm_->connectors()) {
-      drmModeConnection old_state = conn->state();
-
-      conn->UpdateModes();
-
-      drmModeConnection cur_state = conn->state();
-
-      if (cur_state == old_state)
-        continue;
-
-      ALOGI("%s event @%" PRIu64 " for connector %u\n",
-            cur_state == DRM_MODE_CONNECTED ? "Plug" : "Unplug", timestamp_us,
-            conn->id());
-
-      if (cur_state == DRM_MODE_CONNECTED) {
-        // Take the first one, then look for the preferred
-        DrmMode mode = *(conn->modes().begin());
-        for (auto &m : conn->modes()) {
-          if (m.type() & DRM_MODE_TYPE_PREFERRED) {
-            mode = m;
-            break;
-          }
-        }
-        ALOGI("Setting mode %dx%d for connector %d\n", mode.h_display(),
-              mode.v_display(), conn->id());
-        int ret = drm_->SetDisplayActiveMode(conn->display(), mode);
-        if (ret) {
-          ALOGE("Failed to set active config %d", ret);
-          return;
-        }
-      } else {
-        int ret = drm_->SetDpmsMode(conn->display(), DRM_MODE_DPMS_OFF);
-        if (ret) {
-          ALOGE("Failed to set dpms mode off %d", ret);
-          return;
-        }
-      }
-
-      procs_->hotplug(procs_, conn->display(),
-                      cur_state == DRM_MODE_CONNECTED ? 1 : 0);
-    }
-  }
-
- private:
-  DrmResources *drm_ = NULL;
-  const struct hwc_procs *procs_ = NULL;
-};
-
-struct hwc_context_t {
-  // map of display:hwc_drm_display_t
-  typedef std::map<int, hwc_drm_display_t> DisplayMap;
-
-  ~hwc_context_t() {
-    virtual_compositor_worker.Exit();
-  }
-
-  hwc_composer_device_1_t device;
-  hwc_procs_t const *procs = NULL;
-
-  DisplayMap displays;
-  DrmResources drm;
-  std::unique_ptr<Importer> importer;
-  const gralloc_module_t *gralloc;
-  DummySwSyncTimeline dummy_timeline;
-  VirtualCompositorWorker virtual_compositor_worker;
-  DrmHotplugHandler hotplug_handler;
-};
-
-static native_handle_t *dup_buffer_handle(buffer_handle_t handle) {
-  native_handle_t *new_handle =
-      native_handle_create(handle->numFds, handle->numInts);
-  if (new_handle == NULL)
-    return NULL;
-
-  const int *old_data = handle->data;
-  int *new_data = new_handle->data;
-  for (int i = 0; i < handle->numFds; i++) {
-    *new_data = dup(*old_data);
-    old_data++;
-    new_data++;
-  }
-  memcpy(new_data, old_data, sizeof(int) * handle->numInts);
-
-  return new_handle;
-}
-
-static void free_buffer_handle(native_handle_t *handle) {
-  int ret = native_handle_close(handle);
-  if (ret)
-    ALOGE("Failed to close native handle %d", ret);
-  ret = native_handle_delete(handle);
-  if (ret)
-    ALOGE("Failed to delete native handle %d", ret);
-}
-
-const hwc_drm_bo *DrmHwcBuffer::operator->() const {
-  if (importer_ == NULL) {
-    ALOGE("Access of non-existent BO");
-    exit(1);
-    return NULL;
-  }
-  return &bo_;
-}
-
-void DrmHwcBuffer::Clear() {
-  if (importer_ != NULL) {
-    importer_->ReleaseBuffer(&bo_);
-    importer_ = NULL;
-  }
-}
-
-int DrmHwcBuffer::ImportBuffer(buffer_handle_t handle, Importer *importer) {
-  hwc_drm_bo tmp_bo;
-
-  int ret = importer->ImportBuffer(handle, &tmp_bo);
-  if (ret)
-    return ret;
-
-  if (importer_ != NULL) {
-    importer_->ReleaseBuffer(&bo_);
-  }
-
-  importer_ = importer;
-
-  bo_ = tmp_bo;
-
-  return 0;
-}
-
-int DrmHwcNativeHandle::CopyBufferHandle(buffer_handle_t handle,
-                                         const gralloc_module_t *gralloc) {
-  native_handle_t *handle_copy = dup_buffer_handle(handle);
-  if (handle_copy == NULL) {
-    ALOGE("Failed to duplicate handle");
-    return -ENOMEM;
-  }
-
-  int ret = gralloc->registerBuffer(gralloc, handle_copy);
-  if (ret) {
-    ALOGE("Failed to register buffer handle %d", ret);
-    free_buffer_handle(handle_copy);
-    return ret;
-  }
-
-  Clear();
-
-  gralloc_ = gralloc;
-  handle_ = handle_copy;
-
-  return 0;
-}
-
-DrmHwcNativeHandle::~DrmHwcNativeHandle() {
-  Clear();
-}
-
-void DrmHwcNativeHandle::Clear() {
-  if (gralloc_ != NULL && handle_ != NULL) {
-    gralloc_->unregisterBuffer(gralloc_, handle_);
-    free_buffer_handle(handle_);
-    gralloc_ = NULL;
-    handle_ = NULL;
-  }
-}
-
-int DrmHwcLayer::InitFromHwcLayer(hwc_layer_1_t *sf_layer, Importer *importer,
-                                  const gralloc_module_t *gralloc) {
-  sf_handle = sf_layer->handle;
-  alpha = sf_layer->planeAlpha;
-
-  source_crop = DrmHwcRect<float>(
-      sf_layer->sourceCropf.left, sf_layer->sourceCropf.top,
-      sf_layer->sourceCropf.right, sf_layer->sourceCropf.bottom);
-  display_frame = DrmHwcRect<int>(
-      sf_layer->displayFrame.left, sf_layer->displayFrame.top,
-      sf_layer->displayFrame.right, sf_layer->displayFrame.bottom);
-
-  transform = 0;
-  // 270* and 180* cannot be combined with flips. More specifically, they
-  // already contain both horizontal and vertical flips, so those fields are
-  // redundant in this case. 90* rotation can be combined with either horizontal
-  // flip or vertical flip, so treat it differently
-  if (sf_layer->transform == HWC_TRANSFORM_ROT_270) {
-    transform = DrmHwcTransform::kRotate270;
-  } else if (sf_layer->transform == HWC_TRANSFORM_ROT_180) {
-    transform = DrmHwcTransform::kRotate180;
-  } else {
-    if (sf_layer->transform & HWC_TRANSFORM_FLIP_H)
-      transform |= DrmHwcTransform::kFlipH;
-    if (sf_layer->transform & HWC_TRANSFORM_FLIP_V)
-      transform |= DrmHwcTransform::kFlipV;
-    if (sf_layer->transform & HWC_TRANSFORM_ROT_90)
-      transform |= DrmHwcTransform::kRotate90;
-  }
-
-  switch (sf_layer->blending) {
-    case HWC_BLENDING_NONE:
-      blending = DrmHwcBlending::kNone;
-      break;
-    case HWC_BLENDING_PREMULT:
-      blending = DrmHwcBlending::kPreMult;
-      break;
-    case HWC_BLENDING_COVERAGE:
-      blending = DrmHwcBlending::kCoverage;
-      break;
-    default:
-      ALOGE("Invalid blending in hwc_layer_1_t %d", sf_layer->blending);
-      return -EINVAL;
-  }
-
-  int ret = buffer.ImportBuffer(sf_layer->handle, importer);
-  if (ret)
-    return ret;
-
-  ret = handle.CopyBufferHandle(sf_layer->handle, gralloc);
-  if (ret)
-    return ret;
-
-  ret = gralloc->perform(gralloc, GRALLOC_MODULE_PERFORM_GET_USAGE,
-                         handle.get(), &gralloc_buffer_usage);
-  if (ret) {
-    ALOGE("Failed to get usage for buffer %p (%d)", handle.get(), ret);
-    return ret;
-  }
-
-  return 0;
-}
-
-static void hwc_dump(struct hwc_composer_device_1 *dev, char *buff,
-                     int buff_len) {
-  struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common;
-  std::ostringstream out;
-
-  ctx->drm.compositor()->Dump(&out);
-  std::string out_str = out.str();
-  strncpy(buff, out_str.c_str(),
-          std::min((size_t)buff_len, out_str.length() + 1));
-  buff[buff_len - 1] = '\0';
-}
-
-static bool hwc_skip_layer(const std::pair<int, int> &indices, int i) {
-  return indices.first >= 0 && i >= indices.first && i <= indices.second;
-}
-
-static int hwc_prepare(hwc_composer_device_1_t *dev, size_t num_displays,
-                       hwc_display_contents_1_t **display_contents) {
-  struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common;
-
-  for (int i = 0; i < (int)num_displays; ++i) {
-    if (!display_contents[i])
-      continue;
-
-    bool use_framebuffer_target = false;
-    DrmMode mode;
-    if (i == HWC_DISPLAY_VIRTUAL) {
-      use_framebuffer_target = true;
-    } else {
-      DrmConnector *c = ctx->drm.GetConnectorForDisplay(i);
-      if (!c) {
-        ALOGE("Failed to get DrmConnector for display %d", i);
-        return -ENODEV;
-      }
-      mode = c->active_mode();
-    }
-
-    // Since we can't composite HWC_SKIP_LAYERs by ourselves, we'll let SF
-    // handle all layers in between the first and last skip layers. So find the
-    // outer indices and mark everything in between as HWC_FRAMEBUFFER
-    std::pair<int, int> skip_layer_indices(-1, -1);
-    int num_layers = display_contents[i]->numHwLayers;
-    for (int j = 0; !use_framebuffer_target && j < num_layers; ++j) {
-      hwc_layer_1_t *layer = &display_contents[i]->hwLayers[j];
-
-      if (!(layer->flags & HWC_SKIP_LAYER))
-        continue;
-
-      if (skip_layer_indices.first == -1)
-        skip_layer_indices.first = j;
-      skip_layer_indices.second = j;
-    }
-
-    for (int j = 0; j < num_layers; ++j) {
-      hwc_layer_1_t *layer = &display_contents[i]->hwLayers[j];
-
-      if (!use_framebuffer_target && !hwc_skip_layer(skip_layer_indices, j)) {
-        // If the layer is off the screen, don't earmark it for an overlay.
-        // We'll leave it as-is, which effectively just drops it from the frame
-        const hwc_rect_t *frame = &layer->displayFrame;
-        if ((frame->right - frame->left) <= 0 ||
-            (frame->bottom - frame->top) <= 0 ||
-            frame->right <= 0 || frame->bottom <= 0 ||
-            frame->left >= (int)mode.h_display() ||
-            frame->top >= (int)mode.v_display())
-            continue;
-
-        if (layer->compositionType == HWC_FRAMEBUFFER)
-          layer->compositionType = HWC_OVERLAY;
-      } else {
-        switch (layer->compositionType) {
-          case HWC_OVERLAY:
-          case HWC_BACKGROUND:
-          case HWC_SIDEBAND:
-          case HWC_CURSOR_OVERLAY:
-            layer->compositionType = HWC_FRAMEBUFFER;
-            break;
-        }
-      }
-    }
-  }
-
-  return 0;
-}
-
-static void hwc_add_layer_to_retire_fence(
-    hwc_layer_1_t *layer, hwc_display_contents_1_t *display_contents) {
-  if (layer->releaseFenceFd < 0)
-    return;
-
-  if (display_contents->retireFenceFd >= 0) {
-    int old_retire_fence = display_contents->retireFenceFd;
-    display_contents->retireFenceFd =
-        sync_merge("dc_retire", old_retire_fence, layer->releaseFenceFd);
-    close(old_retire_fence);
-  } else {
-    display_contents->retireFenceFd = dup(layer->releaseFenceFd);
-  }
-}
-
-static int hwc_set(hwc_composer_device_1_t *dev, size_t num_displays,
-                   hwc_display_contents_1_t **sf_display_contents) {
-  ATRACE_CALL();
-  struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common;
-  int ret = 0;
-
-  std::vector<CheckedOutputFd> checked_output_fences;
-  std::vector<DrmHwcDisplayContents> displays_contents;
-  std::vector<DrmCompositionDisplayLayersMap> layers_map;
-  std::vector<std::vector<size_t>> layers_indices;
-  displays_contents.reserve(num_displays);
-  // layers_map.reserve(num_displays);
-  layers_indices.reserve(num_displays);
-
-  // Phase one does nothing that would cause errors. Only take ownership of FDs.
-  for (size_t i = 0; i < num_displays; ++i) {
-    hwc_display_contents_1_t *dc = sf_display_contents[i];
-    displays_contents.emplace_back();
-    DrmHwcDisplayContents &display_contents = displays_contents.back();
-    layers_indices.emplace_back();
-    std::vector<size_t> &indices_to_composite = layers_indices.back();
-
-    if (!sf_display_contents[i])
-      continue;
-
-    if (i == HWC_DISPLAY_VIRTUAL) {
-      ctx->virtual_compositor_worker.QueueComposite(dc);
-      continue;
-    }
-
-    std::ostringstream display_index_formatter;
-    display_index_formatter << "retire fence for display " << i;
-    std::string display_fence_description(display_index_formatter.str());
-    checked_output_fences.emplace_back(&dc->retireFenceFd,
-                                       display_fence_description.c_str(),
-                                       ctx->dummy_timeline);
-    display_contents.retire_fence = OutputFd(&dc->retireFenceFd);
-
-    size_t num_dc_layers = dc->numHwLayers;
-    int framebuffer_target_index = -1;
-    for (size_t j = 0; j < num_dc_layers; ++j) {
-      hwc_layer_1_t *sf_layer = &dc->hwLayers[j];
-      if (sf_layer->compositionType == HWC_FRAMEBUFFER_TARGET) {
-        framebuffer_target_index = j;
-        break;
-      }
-    }
-
-    for (size_t j = 0; j < num_dc_layers; ++j) {
-      hwc_layer_1_t *sf_layer = &dc->hwLayers[j];
-
-      display_contents.layers.emplace_back();
-      DrmHwcLayer &layer = display_contents.layers.back();
-
-      // In prepare() we marked all layers FRAMEBUFFER between SKIP_LAYER's.
-      // This means we should insert the FB_TARGET layer in the composition
-      // stack at the location of the first skip layer, and ignore the rest.
-      if (sf_layer->flags & HWC_SKIP_LAYER) {
-        if (framebuffer_target_index < 0)
-          continue;
-        int idx = framebuffer_target_index;
-        framebuffer_target_index = -1;
-        hwc_layer_1_t *fbt_layer = &dc->hwLayers[idx];
-        if (!fbt_layer->handle || (fbt_layer->flags & HWC_SKIP_LAYER)) {
-          ALOGE("Invalid HWC_FRAMEBUFFER_TARGET with HWC_SKIP_LAYER present");
-          continue;
-        }
-        indices_to_composite.push_back(idx);
-        continue;
-      }
-
-      if (sf_layer->compositionType == HWC_OVERLAY)
-        indices_to_composite.push_back(j);
-
-      layer.acquire_fence.Set(sf_layer->acquireFenceFd);
-      sf_layer->acquireFenceFd = -1;
-
-      std::ostringstream layer_fence_formatter;
-      layer_fence_formatter << "release fence for layer " << j << " of display "
-                            << i;
-      std::string layer_fence_description(layer_fence_formatter.str());
-      checked_output_fences.emplace_back(&sf_layer->releaseFenceFd,
-                                         layer_fence_description.c_str(),
-                                         ctx->dummy_timeline);
-      layer.release_fence = OutputFd(&sf_layer->releaseFenceFd);
-    }
-
-    // This is a catch-all in case we get a frame without any overlay layers, or
-    // skip layers, but with a value fb_target layer. This _shouldn't_ happen,
-    // but it's not ruled out by the hwc specification
-    if (indices_to_composite.empty() && framebuffer_target_index >= 0) {
-      hwc_layer_1_t *sf_layer = &dc->hwLayers[framebuffer_target_index];
-      if (!sf_layer->handle || (sf_layer->flags & HWC_SKIP_LAYER)) {
-        ALOGE(
-            "Expected valid layer with HWC_FRAMEBUFFER_TARGET when all "
-            "HWC_OVERLAY layers are skipped.");
-        ret = -EINVAL;
-      }
-      indices_to_composite.push_back(framebuffer_target_index);
-    }
-  }
-
-  if (ret)
-    return ret;
-
-  for (size_t i = 0; i < num_displays; ++i) {
-    hwc_display_contents_1_t *dc = sf_display_contents[i];
-    DrmHwcDisplayContents &display_contents = displays_contents[i];
-    if (!sf_display_contents[i] || i == HWC_DISPLAY_VIRTUAL)
-      continue;
-
-    layers_map.emplace_back();
-    DrmCompositionDisplayLayersMap &map = layers_map.back();
-    map.display = i;
-    map.geometry_changed =
-        (dc->flags & HWC_GEOMETRY_CHANGED) == HWC_GEOMETRY_CHANGED;
-    std::vector<size_t> &indices_to_composite = layers_indices[i];
-    for (size_t j : indices_to_composite) {
-      hwc_layer_1_t *sf_layer = &dc->hwLayers[j];
-
-      DrmHwcLayer &layer = display_contents.layers[j];
-
-      ret = layer.InitFromHwcLayer(sf_layer, ctx->importer.get(), ctx->gralloc);
-      if (ret) {
-        ALOGE("Failed to init composition from layer %d", ret);
-        return ret;
-      }
-      map.layers.emplace_back(std::move(layer));
-    }
-  }
-
-  std::unique_ptr<DrmComposition> composition(
-      ctx->drm.compositor()->CreateComposition(ctx->importer.get()));
-  if (!composition) {
-    ALOGE("Drm composition init failed");
-    return -EINVAL;
-  }
-
-  ret = composition->SetLayers(layers_map.size(), layers_map.data());
-  if (ret) {
-    return -EINVAL;
-  }
-
-  ret = ctx->drm.compositor()->QueueComposition(std::move(composition));
-  if (ret) {
-    return -EINVAL;
-  }
-
-  for (size_t i = 0; i < num_displays; ++i) {
-    hwc_display_contents_1_t *dc = sf_display_contents[i];
-    if (!dc)
-      continue;
-
-    size_t num_dc_layers = dc->numHwLayers;
-    for (size_t j = 0; j < num_dc_layers; ++j) {
-      hwc_layer_1_t *layer = &dc->hwLayers[j];
-      if (layer->flags & HWC_SKIP_LAYER)
-        continue;
-      hwc_add_layer_to_retire_fence(layer, dc);
-    }
-  }
-
-  composition.reset(NULL);
-
-  return ret;
-}
-
-static int hwc_event_control(struct hwc_composer_device_1 *dev, int display,
-                             int event, int enabled) {
-  if (event != HWC_EVENT_VSYNC || (enabled != 0 && enabled != 1))
-    return -EINVAL;
-
-  struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common;
-  hwc_drm_display_t *hd = &ctx->displays[display];
-  hd->vsync_worker.VSyncControl(enabled);
-  return 0;
-}
-
-static int hwc_set_power_mode(struct hwc_composer_device_1 *dev, int display,
-                              int mode) {
-  struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common;
-
-  uint64_t dpmsValue = 0;
-  switch (mode) {
-    case HWC_POWER_MODE_OFF:
-      dpmsValue = DRM_MODE_DPMS_OFF;
-      break;
-
-    /* We can't support dozing right now, so go full on */
-    case HWC_POWER_MODE_DOZE:
-    case HWC_POWER_MODE_DOZE_SUSPEND:
-    case HWC_POWER_MODE_NORMAL:
-      dpmsValue = DRM_MODE_DPMS_ON;
-      break;
-  };
-  return ctx->drm.SetDpmsMode(display, dpmsValue);
-}
-
-static int hwc_query(struct hwc_composer_device_1 * /* dev */, int what,
-                     int *value) {
-  switch (what) {
-    case HWC_BACKGROUND_LAYER_SUPPORTED:
-      *value = 0; /* TODO: We should do this */
-      break;
-    case HWC_VSYNC_PERIOD:
-      ALOGW("Query for deprecated vsync value, returning 60Hz");
-      *value = 1000 * 1000 * 1000 / 60;
-      break;
-    case HWC_DISPLAY_TYPES_SUPPORTED:
-      *value = HWC_DISPLAY_PRIMARY_BIT | HWC_DISPLAY_EXTERNAL_BIT |
-               HWC_DISPLAY_VIRTUAL_BIT;
-      break;
-  }
-  return 0;
-}
-
-static void hwc_register_procs(struct hwc_composer_device_1 *dev,
-                               hwc_procs_t const *procs) {
-  struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common;
-
-  ctx->procs = procs;
-
-  for (std::pair<const int, hwc_drm_display> &display_entry : ctx->displays)
-    display_entry.second.vsync_worker.SetProcs(procs);
-
-  ctx->hotplug_handler.Init(&ctx->drm, procs);
-  ctx->drm.event_listener()->RegisterHotplugHandler(&ctx->hotplug_handler);
-}
-
-static int hwc_get_display_configs(struct hwc_composer_device_1 *dev,
-                                   int display, uint32_t *configs,
-                                   size_t *num_configs) {
-  if (!*num_configs)
-    return 0;
-
-  struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common;
-  hwc_drm_display_t *hd = &ctx->displays[display];
-  hd->config_ids.clear();
-
-  DrmConnector *connector = ctx->drm.GetConnectorForDisplay(display);
-  if (!connector) {
-    ALOGE("Failed to get connector for display %d", display);
-    return -ENODEV;
-  }
-
-  int ret = connector->UpdateModes();
-  if (ret) {
-    ALOGE("Failed to update display modes %d", ret);
-    return ret;
-  }
-
-  for (const DrmMode &mode : connector->modes()) {
-    size_t idx = hd->config_ids.size();
-    if (idx == *num_configs)
-      break;
-    hd->config_ids.push_back(mode.id());
-    configs[idx] = mode.id();
-  }
-  *num_configs = hd->config_ids.size();
-  return *num_configs == 0 ? -1 : 0;
-}
-
-static int hwc_get_display_attributes(struct hwc_composer_device_1 *dev,
-                                      int display, uint32_t config,
-                                      const uint32_t *attributes,
-                                      int32_t *values) {
-  struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common;
-  DrmConnector *c = ctx->drm.GetConnectorForDisplay(display);
-  if (!c) {
-    ALOGE("Failed to get DrmConnector for display %d", display);
-    return -ENODEV;
-  }
-  DrmMode mode;
-  for (const DrmMode &conn_mode : c->modes()) {
-    if (conn_mode.id() == config) {
-      mode = conn_mode;
-      break;
-    }
-  }
-  if (mode.id() == 0) {
-    ALOGE("Failed to find active mode for display %d", display);
-    return -ENOENT;
-  }
-
-  uint32_t mm_width = c->mm_width();
-  uint32_t mm_height = c->mm_height();
-  for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; ++i) {
-    switch (attributes[i]) {
-      case HWC_DISPLAY_VSYNC_PERIOD:
-        values[i] = 1000 * 1000 * 1000 / mode.v_refresh();
-        break;
-      case HWC_DISPLAY_WIDTH:
-        values[i] = mode.h_display();
-        break;
-      case HWC_DISPLAY_HEIGHT:
-        values[i] = mode.v_display();
-        break;
-      case HWC_DISPLAY_DPI_X:
-        /* Dots per 1000 inches */
-        values[i] = mm_width ? (mode.h_display() * UM_PER_INCH) / mm_width : 0;
-        break;
-      case HWC_DISPLAY_DPI_Y:
-        /* Dots per 1000 inches */
-        values[i] =
-            mm_height ? (mode.v_display() * UM_PER_INCH) / mm_height : 0;
-        break;
-    }
-  }
-  return 0;
-}
-
-static int hwc_get_active_config(struct hwc_composer_device_1 *dev,
-                                 int display) {
-  struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common;
-  DrmConnector *c = ctx->drm.GetConnectorForDisplay(display);
-  if (!c) {
-    ALOGE("Failed to get DrmConnector for display %d", display);
-    return -ENODEV;
-  }
-
-  DrmMode mode = c->active_mode();
-  hwc_drm_display_t *hd = &ctx->displays[display];
-  for (size_t i = 0; i < hd->config_ids.size(); ++i) {
-    if (hd->config_ids[i] == mode.id())
-      return i;
-  }
-  return -1;
-}
-
-static int hwc_set_active_config(struct hwc_composer_device_1 *dev, int display,
-                                 int index) {
-  struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common;
-  hwc_drm_display_t *hd = &ctx->displays[display];
-  if (index >= (int)hd->config_ids.size()) {
-    ALOGE("Invalid config index %d passed in", index);
-    return -EINVAL;
-  }
-
-  DrmConnector *c = ctx->drm.GetConnectorForDisplay(display);
-  if (!c) {
-    ALOGE("Failed to get connector for display %d", display);
-    return -ENODEV;
-  }
-
-  if (c->state() != DRM_MODE_CONNECTED)
-    return -ENODEV;
-
-  DrmMode mode;
-  for (const DrmMode &conn_mode : c->modes()) {
-    if (conn_mode.id() == hd->config_ids[index]) {
-      mode = conn_mode;
-      break;
-    }
-  }
-  if (mode.id() != hd->config_ids[index]) {
-    ALOGE("Could not find active mode for %d/%d", index, hd->config_ids[index]);
-    return -ENOENT;
-  }
-  int ret = ctx->drm.SetDisplayActiveMode(display, mode);
-  if (ret) {
-    ALOGE("Failed to set active config %d", ret);
-    return ret;
-  }
-  ret = ctx->drm.SetDpmsMode(display, DRM_MODE_DPMS_ON);
-  if (ret) {
-    ALOGE("Failed to set dpms mode on %d", ret);
-    return ret;
-  }
-  return ret;
-}
-
-static int hwc_device_close(struct hw_device_t *dev) {
-  struct hwc_context_t *ctx = (struct hwc_context_t *)dev;
-  delete ctx;
-  return 0;
-}
-
-/*
- * TODO: This function sets the active config to the first one in the list. This
- * should be fixed such that it selects the preferred mode for the display, or
- * some other, saner, method of choosing the config.
- */
-static int hwc_set_initial_config(hwc_drm_display_t *hd) {
-  uint32_t config;
-  size_t num_configs = 1;
-  int ret = hwc_get_display_configs(&hd->ctx->device, hd->display, &config,
-                                    &num_configs);
-  if (ret || !num_configs)
-    return 0;
-
-  ret = hwc_set_active_config(&hd->ctx->device, hd->display, 0);
-  if (ret) {
-    ALOGE("Failed to set active config d=%d ret=%d", hd->display, ret);
-    return ret;
-  }
-
-  return ret;
-}
-
-static int hwc_initialize_display(struct hwc_context_t *ctx, int display) {
-  hwc_drm_display_t *hd = &ctx->displays[display];
-  hd->ctx = ctx;
-  hd->display = display;
-
-  int ret = hwc_set_initial_config(hd);
-  if (ret) {
-    ALOGE("Failed to set initial config for d=%d ret=%d", display, ret);
-    return ret;
-  }
-
-  ret = hd->vsync_worker.Init(&ctx->drm, display);
-  if (ret) {
-    ALOGE("Failed to create event worker for display %d %d\n", display, ret);
-    return ret;
-  }
-
-  return 0;
-}
-
-static int hwc_enumerate_displays(struct hwc_context_t *ctx) {
-  int ret;
-  for (auto &conn : ctx->drm.connectors()) {
-    ret = hwc_initialize_display(ctx, conn->display());
-    if (ret) {
-      ALOGE("Failed to initialize display %d", conn->display());
-      return ret;
-    }
-  }
-
-  ret = ctx->virtual_compositor_worker.Init();
-  if (ret) {
-    ALOGE("Failed to initialize virtual compositor worker");
-    return ret;
-  }
-  return 0;
-}
-
-static int hwc_device_open(const struct hw_module_t *module, const char *name,
-                           struct hw_device_t **dev) {
-  if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
-    ALOGE("Invalid module name- %s", name);
-    return -EINVAL;
-  }
-
-  std::unique_ptr<hwc_context_t> ctx(new hwc_context_t());
-  if (!ctx) {
-    ALOGE("Failed to allocate hwc context");
-    return -ENOMEM;
-  }
-
-  int ret = ctx->drm.Init();
-  if (ret) {
-    ALOGE("Can't initialize Drm object %d", ret);
-    return ret;
-  }
-
-  ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
-                      (const hw_module_t **)&ctx->gralloc);
-  if (ret) {
-    ALOGE("Failed to open gralloc module %d", ret);
-    return ret;
-  }
-
-  ret = ctx->dummy_timeline.Init();
-  if (ret) {
-    ALOGE("Failed to create dummy sw sync timeline %d", ret);
-    return ret;
-  }
-
-  ctx->importer.reset(Importer::CreateInstance(&ctx->drm));
-  if (!ctx->importer) {
-    ALOGE("Failed to create importer instance");
-    return ret;
-  }
-
-  ret = hwc_enumerate_displays(ctx.get());
-  if (ret) {
-    ALOGE("Failed to enumerate displays: %s", strerror(ret));
-    return ret;
-  }
-
-  ctx->device.common.tag = HARDWARE_DEVICE_TAG;
-  ctx->device.common.version = HWC_DEVICE_API_VERSION_1_4;
-  ctx->device.common.module = const_cast<hw_module_t *>(module);
-  ctx->device.common.close = hwc_device_close;
-
-  ctx->device.dump = hwc_dump;
-  ctx->device.prepare = hwc_prepare;
-  ctx->device.set = hwc_set;
-  ctx->device.eventControl = hwc_event_control;
-  ctx->device.setPowerMode = hwc_set_power_mode;
-  ctx->device.query = hwc_query;
-  ctx->device.registerProcs = hwc_register_procs;
-  ctx->device.getDisplayConfigs = hwc_get_display_configs;
-  ctx->device.getDisplayAttributes = hwc_get_display_attributes;
-  ctx->device.getActiveConfig = hwc_get_active_config;
-  ctx->device.setActiveConfig = hwc_set_active_config;
-  ctx->device.setCursorPositionAsync = NULL; /* TODO: Add cursor */
-
-  *dev = &ctx->device.common;
-  ctx.release();
-
-  return 0;
-}
-}
-
-static struct hw_module_methods_t hwc_module_methods = {
-  .open = android::hwc_device_open
-};
-
-hwc_module_t HAL_MODULE_INFO_SYM = {
-  .common = {
-    .tag = HARDWARE_MODULE_TAG,
-    .version_major = 1,
-    .version_minor = 0,
-    .id = HWC_HARDWARE_MODULE_ID,
-    .name = "DRM hwcomposer module",
-    .author = "The Android Open Source Project",
-    .methods = &hwc_module_methods,
-    .dso = NULL,
-    .reserved = {0},
-  }
-};
diff --git a/hwcutils.cpp b/hwcutils.cpp
new file mode 100644
index 0000000..e452bc8
--- /dev/null
+++ b/hwcutils.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2016 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
+#define LOG_TAG "hwc-drm-utils"
+
+#include "drmhwcomposer.h"
+#include "platform.h"
+
+#include <log/log.h>
+#include <ui/GraphicBufferMapper.h>
+
+namespace android {
+
+const hwc_drm_bo *DrmHwcBuffer::operator->() const {
+  if (importer_ == NULL) {
+    ALOGE("Access of non-existent BO");
+    exit(1);
+    return NULL;
+  }
+  return &bo_;
+}
+
+void DrmHwcBuffer::Clear() {
+  if (importer_ != NULL) {
+    importer_->ReleaseBuffer(&bo_);
+    importer_ = NULL;
+  }
+}
+
+int DrmHwcBuffer::ImportBuffer(buffer_handle_t handle, Importer *importer) {
+  hwc_drm_bo tmp_bo;
+
+  int ret = importer->ImportBuffer(handle, &tmp_bo);
+  if (ret)
+    return ret;
+
+  if (importer_ != NULL) {
+    importer_->ReleaseBuffer(&bo_);
+  }
+
+  importer_ = importer;
+
+  bo_ = tmp_bo;
+
+  return 0;
+}
+
+int DrmHwcNativeHandle::CopyBufferHandle(buffer_handle_t handle) {
+  native_handle_t *handle_copy;
+  GraphicBufferMapper &gm(GraphicBufferMapper::get());
+  int ret =
+      gm.importBuffer(handle, const_cast<buffer_handle_t *>(&handle_copy));
+  if (ret) {
+    ALOGE("Failed to import buffer handle %d", ret);
+    return ret;
+  }
+
+  Clear();
+
+  handle_ = handle_copy;
+
+  return 0;
+}
+
+DrmHwcNativeHandle::~DrmHwcNativeHandle() {
+  Clear();
+}
+
+void DrmHwcNativeHandle::Clear() {
+  if (handle_ != NULL) {
+    GraphicBufferMapper &gm(GraphicBufferMapper::get());
+    int ret = gm.freeBuffer(handle_);
+    if (ret) {
+      ALOGE("Failed to free buffer handle %d", ret);
+    }
+    handle_ = NULL;
+  }
+}
+
+int DrmHwcLayer::ImportBuffer(Importer *importer) {
+  int ret = buffer.ImportBuffer(sf_handle, importer);
+  if (ret)
+    return ret;
+
+  ret = handle.CopyBufferHandle(sf_handle);
+  if (ret)
+    return ret;
+
+  gralloc_buffer_usage = buffer.operator->()->usage;
+
+  return 0;
+}
+
+void DrmHwcLayer::SetSourceCrop(hwc_frect_t const &crop) {
+  source_crop = crop;
+}
+
+void DrmHwcLayer::SetDisplayFrame(hwc_rect_t const &frame) {
+  display_frame = frame;
+}
+
+void DrmHwcLayer::SetTransform(int32_t sf_transform) {
+  transform = 0;
+  // 270* and 180* cannot be combined with flips. More specifically, they
+  // already contain both horizontal and vertical flips, so those fields are
+  // redundant in this case. 90* rotation can be combined with either horizontal
+  // flip or vertical flip, so treat it differently
+  if (sf_transform == HWC_TRANSFORM_ROT_270) {
+    transform = DrmHwcTransform::kRotate270;
+  } else if (sf_transform == HWC_TRANSFORM_ROT_180) {
+    transform = DrmHwcTransform::kRotate180;
+  } else {
+    if (sf_transform & HWC_TRANSFORM_FLIP_H)
+      transform |= DrmHwcTransform::kFlipH;
+    if (sf_transform & HWC_TRANSFORM_FLIP_V)
+      transform |= DrmHwcTransform::kFlipV;
+    if (sf_transform & HWC_TRANSFORM_ROT_90)
+      transform |= DrmHwcTransform::kRotate90;
+  }
+}
+}
diff --git a/platform.cpp b/platform.cpp
index e920872..b6c39d0 100644
--- a/platform.cpp
+++ b/platform.cpp
@@ -19,7 +19,7 @@
 #include "drmresources.h"
 #include "platform.h"
 
-#include <cutils/log.h>
+#include <log/log.h>
 
 namespace android {
 
@@ -37,7 +37,7 @@
 }
 
 std::tuple<int, std::vector<DrmCompositionPlane>> Planner::ProvisionPlanes(
-    std::map<size_t, DrmHwcLayer *> &layers, bool use_squash_fb, DrmCrtc *crtc,
+    std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
     std::vector<DrmPlane *> *primary_planes,
     std::vector<DrmPlane *> *overlay_planes) {
   std::vector<DrmCompositionPlane> composition;
@@ -48,30 +48,6 @@
     return std::make_tuple(-ENODEV, std::vector<DrmCompositionPlane>());
   }
 
-  // If needed, reserve the squash plane at the highest z-order
-  DrmPlane *squash_plane = NULL;
-  if (use_squash_fb) {
-    if (!planes.empty()) {
-      squash_plane = planes.back();
-      planes.pop_back();
-    } else {
-      ALOGI("Not enough planes to reserve for squash fb");
-    }
-  }
-
-  // If needed, reserve the precomp plane at the next highest z-order
-  DrmPlane *precomp_plane = NULL;
-  if (layers.size() > planes.size()) {
-    if (!planes.empty()) {
-      precomp_plane = planes.back();
-      planes.pop_back();
-      composition.emplace_back(DrmCompositionPlane::Type::kPrecomp,
-                               precomp_plane, crtc);
-    } else {
-      ALOGE("Not enough planes to reserve for precomp fb");
-    }
-  }
-
   // Go through the provisioning stages and provision planes
   for (auto &i : stages_) {
     int ret = i->ProvisionPlanes(&composition, layers, crtc, &planes);
@@ -81,10 +57,6 @@
     }
   }
 
-  if (squash_plane)
-    composition.emplace_back(DrmCompositionPlane::Type::kSquash, squash_plane,
-                             crtc);
-
   return std::make_tuple(0, std::move(composition));
 }
 
@@ -109,62 +81,6 @@
     i = layers.erase(i);
   }
 
-  if (protected_zorder == -1)
-    return 0;
-
-  // Add any layers below the protected content to the precomposition since we
-  // need to punch a hole through them.
-  for (auto i = layers.begin(); i != layers.end();) {
-    // Skip layers above the z-order of the protected content
-    if (i->first > static_cast<size_t>(protected_zorder)) {
-      ++i;
-      continue;
-    }
-
-    // If there's no precomp layer already queued, queue one now.
-    DrmCompositionPlane *precomp = GetPrecomp(composition);
-    if (precomp) {
-      precomp->source_layers().emplace_back(i->first);
-    } else {
-      if (!planes->empty()) {
-        DrmPlane *precomp_plane = planes->back();
-        planes->pop_back();
-        composition->emplace_back(DrmCompositionPlane::Type::kPrecomp,
-                                  precomp_plane, crtc, i->first);
-      } else {
-        ALOGE("Not enough planes to reserve for precomp fb");
-      }
-    }
-    i = layers.erase(i);
-  }
-  return 0;
-}
-
-int PlanStagePrecomp::ProvisionPlanes(
-    std::vector<DrmCompositionPlane> *composition,
-    std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
-    std::vector<DrmPlane *> *planes) {
-  DrmCompositionPlane *precomp = GetPrecomp(composition);
-  if (!precomp || precomp->source_layers().empty())
-    return 0;
-
-  // Find lowest zorder out of precomp layers
-  size_t precomp_zorder = *std::min_element(
-      precomp->source_layers().begin(), precomp->source_layers().end(),
-      [](size_t a, size_t b) { return a < b; });
-
-  // if there are any remaining layers on top of any of the precomp layers,
-  // add them to precomp to avoid blending issues since precomp is always at
-  // highest zorder
-  for (auto i = layers.begin(); i != layers.end();) {
-    if (i->first < precomp_zorder) {
-      i++;
-      continue;
-    }
-    precomp->source_layers().emplace_back(i->first);
-    i = layers.erase(i);
-  }
-
   return 0;
 }
 
@@ -183,13 +99,6 @@
       ALOGE("Failed to emplace layer %zu, dropping it", i->first);
   }
 
-  // Put the rest of the layers in the precomp plane
-  DrmCompositionPlane *precomp = GetPrecomp(composition);
-  if (precomp) {
-    for (auto i = layers.begin(); i != layers.end(); i = layers.erase(i))
-      precomp->source_layers().emplace_back(i->first);
-  }
-
   return 0;
 }
 }
diff --git a/platform.h b/platform.h
index 70e5e81..068499e 100644
--- a/platform.h
+++ b/platform.h
@@ -73,17 +73,7 @@
       return plane;
     }
 
-    // Finds and returns the squash layer from the composition
-    static DrmCompositionPlane *GetPrecomp(
-        std::vector<DrmCompositionPlane> *composition) {
-      auto l = GetPrecompIter(composition);
-      if (l == composition->end())
-        return NULL;
-      return &(*l);
-    }
-
-    // Inserts the given layer:plane in the composition right before the precomp
-    // layer
+    // Inserts the given layer:plane in the composition at the back
     static int Emplace(std::vector<DrmCompositionPlane> *composition,
                        std::vector<DrmPlane *> *planes,
                        DrmCompositionPlane::Type type, DrmCrtc *crtc,
@@ -92,41 +82,26 @@
       if (!plane)
         return -ENOENT;
 
-      auto precomp = GetPrecompIter(composition);
-      composition->emplace(precomp, type, plane, crtc, source_layer);
+      composition->emplace_back(type, plane, crtc, source_layer);
       return 0;
     }
-
-   private:
-    static std::vector<DrmCompositionPlane>::iterator GetPrecompIter(
-        std::vector<DrmCompositionPlane> *composition) {
-      return std::find_if(composition->begin(), composition->end(),
-                          [](const DrmCompositionPlane &p) {
-        return p.type() == DrmCompositionPlane::Type::kPrecomp;
-      });
-    }
   };
 
   // Creates a planner instance with platform-specific planning stages
   static std::unique_ptr<Planner> CreateInstance(DrmResources *drm);
 
   // Takes a stack of layers and provisions hardware planes for them. If the
-  // entire stack can't fit in hardware, the Planner may place the remaining
-  // layers in a PRECOMP plane. Layers in the PRECOMP plane will be composited
-  // using GL. PRECOMP planes should be placed above any 1:1 layer:plane
-  // compositions. If use_squash_fb is true, the Planner should try to reserve a
-  // plane at the highest z-order with type SQUASH.
+  // entire stack can't fit in hardware, FIXME
   //
   // @layers: a map of index:layer of layers to composite
-  // @use_squash_fb: reserve a squash framebuffer
   // @primary_planes: a vector of primary planes available for this frame
   // @overlay_planes: a vector of overlay planes available for this frame
   //
   // Returns: A tuple with the status of the operation (0 for success) and
   //          a vector of the resulting plan (ie: layer->plane mapping).
   std::tuple<int, std::vector<DrmCompositionPlane>> ProvisionPlanes(
-      std::map<size_t, DrmHwcLayer *> &layers, bool use_squash_fb,
-      DrmCrtc *crtc, std::vector<DrmPlane *> *primary_planes,
+      std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
+      std::vector<DrmPlane *> *primary_planes,
       std::vector<DrmPlane *> *overlay_planes);
 
   template <typename T, typename... A>
@@ -152,18 +127,6 @@
                       std::vector<DrmPlane *> *planes);
 };
 
-// This plan stage provisions the precomp plane with any remaining layers that
-// are on top of the current precomp layers. This stage should be included in
-// all platforms before loosely allocating layers (i.e. PlanStageGreedy) if
-// any previous plan could have modified the precomp plane layers
-// (ex. PlanStageProtected).
-class PlanStagePrecomp : public Planner::PlanStage {
- public:
-  int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
-                      std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
-                      std::vector<DrmPlane *> *planes);
-};
-
 // This plan stage places as many layers on dedicated planes as possible (first
 // come first serve), and then sticks the rest in a precomposition plane (if
 // needed).
diff --git a/platformdrmgeneric.cpp b/platformdrmgeneric.cpp
index 90ba0e2..7c4758d 100644
--- a/platformdrmgeneric.cpp
+++ b/platformdrmgeneric.cpp
@@ -24,8 +24,8 @@
 #include <xf86drm.h>
 #include <xf86drmMode.h>
 
-#include <cutils/log.h>
-#include <gralloc_drm_handle.h>
+#include <log/log.h>
+#include <gralloc_handle.h>
 #include <hardware/gralloc.h>
 
 namespace android {
@@ -84,7 +84,7 @@
 }
 
 int DrmGenericImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) {
-  gralloc_drm_handle_t *gr_handle = gralloc_drm_handle(handle);
+  gralloc_handle_t *gr_handle = gralloc_handle(handle);
   if (!gr_handle)
     return -EINVAL;
 
@@ -99,6 +99,7 @@
   bo->width = gr_handle->width;
   bo->height = gr_handle->height;
   bo->format = ConvertHalFormatToDrm(gr_handle->format);
+  bo->usage = gr_handle->usage;
   bo->pitches[0] = gr_handle->stride;
   bo->gem_handles[0] = gem_handle;
   bo->offsets[0] = 0;
@@ -127,10 +128,14 @@
 
     gem_close.handle = bo->gem_handles[i];
     int ret = drmIoctl(drm_->fd(), DRM_IOCTL_GEM_CLOSE, &gem_close);
-    if (ret)
+    if (ret) {
       ALOGE("Failed to close gem handle %d %d", i, ret);
-    else
+    } else {
+      for (int j = i + 1; j < num_gem_handles; j++)
+        if (bo->gem_handles[j] == bo->gem_handles[i])
+          bo->gem_handles[j] = 0;
       bo->gem_handles[i] = 0;
+    }
   }
   return 0;
 }
diff --git a/platformdrmgeneric.h b/platformdrmgeneric.h
index 3400876..0339e1e 100644
--- a/platformdrmgeneric.h
+++ b/platformdrmgeneric.h
@@ -34,8 +34,8 @@
   int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
   int ReleaseBuffer(hwc_drm_bo_t *bo) override;
 
- private:
   uint32_t ConvertHalFormatToDrm(uint32_t hal_format);
+ private:
 
   DrmResources *drm_;
 
diff --git a/platformhisi.cpp b/platformhisi.cpp
new file mode 100644
index 0000000..d4428d0
--- /dev/null
+++ b/platformhisi.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "hwc-platform-hisi"
+
+#include "drmresources.h"
+#include "platform.h"
+#include "platformhisi.h"
+
+
+#include <drm/drm_fourcc.h>
+#include <cinttypes>
+#include <stdatomic.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#include <log/log.h>
+#include <hardware/gralloc.h>
+#include "gralloc_priv.h"
+
+#define MALI_ALIGN(value, base) (((value) + ((base)-1)) & ~((base)-1))
+
+namespace android {
+
+Importer *Importer::CreateInstance(DrmResources *drm) {
+  HisiImporter *importer = new HisiImporter(drm);
+  if (!importer)
+    return NULL;
+
+  int ret = importer->Init();
+  if (ret) {
+    ALOGE("Failed to initialize the hisi importer %d", ret);
+    delete importer;
+    return NULL;
+  }
+  return importer;
+}
+
+HisiImporter::HisiImporter(DrmResources *drm) : DrmGenericImporter(drm), drm_(drm) {
+}
+
+HisiImporter::~HisiImporter() {
+}
+
+int HisiImporter::Init() {
+  int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
+                          (const hw_module_t **)&gralloc_);
+  if (ret) {
+    ALOGE("Failed to open gralloc module %d", ret);
+    return ret;
+  }
+
+  if (strcasecmp(gralloc_->common.author, "ARM Ltd."))
+    ALOGW("Using non-ARM gralloc module: %s/%s\n", gralloc_->common.name,
+          gralloc_->common.author);
+
+  return 0;
+}
+
+int HisiImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) {
+  private_handle_t const *hnd =
+      reinterpret_cast<private_handle_t const *>(handle);
+  if (!hnd)
+    return -EINVAL;
+
+  uint32_t gem_handle;
+  int ret = drmPrimeFDToHandle(drm_->fd(), hnd->share_fd, &gem_handle);
+  if (ret) {
+    ALOGE("failed to import prime fd %d ret=%d", hnd->share_fd, ret);
+    return ret;
+  }
+
+  int32_t fmt = ConvertHalFormatToDrm(hnd->req_format);
+  if (fmt < 0)
+    return fmt;
+
+  memset(bo, 0, sizeof(hwc_drm_bo_t));
+  bo->width = hnd->width;
+  bo->height = hnd->height;
+  bo->format = fmt;
+  bo->usage = hnd->usage;
+
+  bo->pitches[0] = hnd->byte_stride;
+  bo->gem_handles[0] = gem_handle;
+  bo->offsets[0] = 0;
+
+  switch (fmt) {
+    case DRM_FORMAT_YVU420: {
+      int align = 128;
+      if (hnd->usage &
+          (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
+        align = 16;
+      int adjusted_height = MALI_ALIGN(hnd->height, 2);
+      int y_size = adjusted_height * hnd->byte_stride;
+      int vu_stride = MALI_ALIGN(hnd->byte_stride / 2, align);
+      int v_size = vu_stride * (adjusted_height / 2);
+
+      /* V plane*/
+      bo->gem_handles[1] = gem_handle;
+      bo->pitches[1] = vu_stride;
+      bo->offsets[1] = y_size;
+      /* U plane */
+      bo->gem_handles[2] = gem_handle;
+      bo->pitches[2] = vu_stride;
+      bo->offsets[2] = y_size + v_size;
+      break;
+    }
+    default:
+      break;
+  }
+
+  ret = drmModeAddFB2(drm_->fd(), bo->width, bo->height, bo->format,
+                      bo->gem_handles, bo->pitches, bo->offsets, &bo->fb_id, 0);
+  if (ret) {
+    ALOGE("could not create drm fb %d", ret);
+    return ret;
+  }
+
+  return ret;
+}
+
+std::unique_ptr<Planner> Planner::CreateInstance(DrmResources *) {
+  std::unique_ptr<Planner> planner(new Planner);
+  planner->AddStage<PlanStageGreedy>();
+  return planner;
+}
+}
diff --git a/platformhisi.h b/platformhisi.h
new file mode 100644
index 0000000..a098692
--- /dev/null
+++ b/platformhisi.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 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_PLATFORM_HISI_H_
+#define ANDROID_PLATFORM_HISI_H_
+
+#include "drmresources.h"
+#include "platform.h"
+#include "platformdrmgeneric.h"
+
+#include <stdatomic.h>
+
+#include <hardware/gralloc.h>
+
+namespace android {
+
+class HisiImporter : public DrmGenericImporter {
+ public:
+  HisiImporter(DrmResources *drm);
+  ~HisiImporter() override;
+
+  int Init();
+
+  int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
+
+ private:
+
+  DrmResources *drm_;
+
+  const gralloc_module_t *gralloc_;
+};
+}
+
+#endif
diff --git a/platformminigbm.cpp b/platformminigbm.cpp
new file mode 100644
index 0000000..8e3cc65
--- /dev/null
+++ b/platformminigbm.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "hwc-platform-drm-minigbm"
+
+#include "drmresources.h"
+#include "platform.h"
+#include "platformminigbm.h"
+
+#include <drm/drm_fourcc.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#include <log/log.h>
+#include <hardware/gralloc.h>
+
+#include "cros_gralloc_handle.h"
+
+namespace android {
+
+Importer *Importer::CreateInstance(DrmResources *drm) {
+  DrmMinigbmImporter *importer = new DrmMinigbmImporter(drm);
+  if (!importer)
+    return NULL;
+
+  int ret = importer->Init();
+  if (ret) {
+    ALOGE("Failed to initialize the minigbm importer %d", ret);
+    delete importer;
+    return NULL;
+  }
+  return importer;
+}
+
+DrmMinigbmImporter::DrmMinigbmImporter(DrmResources *drm) : DrmGenericImporter(drm), drm_(drm) {
+}
+
+DrmMinigbmImporter::~DrmMinigbmImporter() {
+}
+
+int DrmMinigbmImporter::Init() {
+  int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
+                          (const hw_module_t **)&gralloc_);
+  if (ret) {
+    ALOGE("Failed to open gralloc module %d", ret);
+    return ret;
+  }
+
+  if (strcasecmp(gralloc_->common.author, "Chrome OS"))
+    ALOGW("Using non-minigbm gralloc module: %s/%s\n", gralloc_->common.name,
+          gralloc_->common.author);
+
+  return 0;
+}
+
+int DrmMinigbmImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) {
+  cros_gralloc_handle *gr_handle = (cros_gralloc_handle *)handle;
+  if (!gr_handle)
+    return -EINVAL;
+
+  uint32_t gem_handle;
+  int ret = drmPrimeFDToHandle(drm_->fd(), gr_handle->fds[0], &gem_handle);
+  if (ret) {
+    ALOGE("failed to import prime fd %d ret=%d", gr_handle->fds[0], ret);
+    return ret;
+  }
+
+  memset(bo, 0, sizeof(hwc_drm_bo_t));
+  bo->width = gr_handle->width;
+  bo->height = gr_handle->height;
+  bo->format = gr_handle->format;
+  bo->usage = gr_handle->usage;
+  bo->pitches[0] = gr_handle->strides[0];
+  bo->offsets[0] = gr_handle->offsets[0];
+  bo->gem_handles[0] = gem_handle;
+
+  ret = drmModeAddFB2(drm_->fd(), bo->width, bo->height, bo->format,
+                      bo->gem_handles, bo->pitches, bo->offsets, &bo->fb_id, 0);
+  if (ret) {
+    ALOGE("could not create drm fb %d", ret);
+    return ret;
+  }
+
+  return ret;
+}
+
+std::unique_ptr<Planner> Planner::CreateInstance(DrmResources *) {
+  std::unique_ptr<Planner> planner(new Planner);
+  planner->AddStage<PlanStageGreedy>();
+  return planner;
+}
+
+}
diff --git a/platformminigbm.h b/platformminigbm.h
new file mode 100644
index 0000000..f25bf7b
--- /dev/null
+++ b/platformminigbm.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_PLATFORM_DRM_MINIGBM_H_
+#define ANDROID_PLATFORM_DRM_MINIGBM_H_
+
+#include "drmresources.h"
+#include "platform.h"
+#include "platformdrmgeneric.h"
+
+#include <hardware/gralloc.h>
+
+namespace android {
+
+class DrmMinigbmImporter : public DrmGenericImporter {
+ public:
+  DrmMinigbmImporter(DrmResources *drm);
+  ~DrmMinigbmImporter() override;
+
+  int Init();
+
+  int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
+
+ private:
+  DrmResources *drm_;
+
+  const gralloc_module_t *gralloc_;
+};
+
+}
+
+#endif
diff --git a/platformnv.cpp b/platformnv.cpp
deleted file mode 100644
index e05d1bb..0000000
--- a/platformnv.cpp
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "hwc-platform-nv"
-
-#include "drmresources.h"
-#include "platform.h"
-#include "platformnv.h"
-
-#include <cinttypes>
-#include <stdatomic.h>
-#include <drm/drm_fourcc.h>
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-
-#include <cutils/log.h>
-#include <hardware/gralloc.h>
-
-namespace android {
-
-#ifdef USE_NVIDIA_IMPORTER
-// static
-Importer *Importer::CreateInstance(DrmResources *drm) {
-  NvImporter *importer = new NvImporter(drm);
-  if (!importer)
-    return NULL;
-
-  int ret = importer->Init();
-  if (ret) {
-    ALOGE("Failed to initialize the nv importer %d", ret);
-    delete importer;
-    return NULL;
-  }
-  return importer;
-}
-#endif
-
-NvImporter::NvImporter(DrmResources *drm) : drm_(drm) {
-}
-
-NvImporter::~NvImporter() {
-}
-
-int NvImporter::Init() {
-  int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
-                          (const hw_module_t **)&gralloc_);
-  if (ret) {
-    ALOGE("Failed to open gralloc module %d", ret);
-    return ret;
-  }
-
-  if (strcasecmp(gralloc_->common.author, "NVIDIA"))
-    ALOGW("Using non-NVIDIA gralloc module: %s/%s\n", gralloc_->common.name,
-          gralloc_->common.author);
-
-  return 0;
-}
-
-int NvImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) {
-  memset(bo, 0, sizeof(hwc_drm_bo_t));
-  NvBuffer_t *buf = GrallocGetNvBuffer(handle);
-  if (buf) {
-    atomic_fetch_add(&buf->ref, 1);
-    *bo = buf->bo;
-    return 0;
-  }
-
-  buf = new NvBuffer_t();
-  if (!buf) {
-    ALOGE("Failed to allocate new NvBuffer_t");
-    return -ENOMEM;
-  }
-  buf->bo.priv = buf;
-  buf->importer = this;
-
-  // We initialize the reference count to 2 since NvGralloc is still using this
-  // buffer (will be cleared in the NvGrallocRelease), and the other
-  // reference is for HWC (this ImportBuffer call).
-  atomic_init(&buf->ref, 2);
-
-  int ret = gralloc_->perform(gralloc_, GRALLOC_MODULE_PERFORM_DRM_IMPORT,
-                              drm_->fd(), handle, &buf->bo);
-  if (ret) {
-    ALOGE("GRALLOC_MODULE_PERFORM_DRM_IMPORT failed %d", ret);
-    delete buf;
-    return ret;
-  }
-
-  ret = drmModeAddFB2(drm_->fd(), buf->bo.width, buf->bo.height, buf->bo.format,
-                      buf->bo.gem_handles, buf->bo.pitches, buf->bo.offsets,
-                      &buf->bo.fb_id, 0);
-  if (ret) {
-    ALOGE("Failed to add fb %d", ret);
-    ReleaseBufferImpl(&buf->bo);
-    delete buf;
-    return ret;
-  }
-
-  ret = GrallocSetNvBuffer(handle, buf);
-  if (ret) {
-    /* This will happen is persist.tegra.gpu_mapping_cache is 0/off,
-     * or if NV gralloc runs out of "priv slots" (currently 3 per buffer,
-     * only one of which should be used by drm_hwcomposer). */
-    ALOGE("Failed to register free callback for imported buffer %d", ret);
-    ReleaseBufferImpl(&buf->bo);
-    delete buf;
-    return ret;
-  }
-  *bo = buf->bo;
-  return 0;
-}
-
-int NvImporter::ReleaseBuffer(hwc_drm_bo_t *bo) {
-  NvBuffer_t *buf = (NvBuffer_t *)bo->priv;
-  if (!buf) {
-    ALOGE("Freeing bo %" PRIu32 ", buf is NULL!", bo->fb_id);
-    return 0;
-  }
-  if (atomic_fetch_sub(&buf->ref, 1) > 1)
-    return 0;
-
-  ReleaseBufferImpl(bo);
-  delete buf;
-  return 0;
-}
-
-// static
-void NvImporter::NvGrallocRelease(void *nv_buffer) {
-  NvBuffer_t *buf = (NvBuffer *)nv_buffer;
-  buf->importer->ReleaseBuffer(&buf->bo);
-}
-
-void NvImporter::ReleaseBufferImpl(hwc_drm_bo_t *bo) {
-  if (bo->fb_id) {
-    int ret = drmModeRmFB(drm_->fd(), bo->fb_id);
-    if (ret)
-      ALOGE("Failed to rm fb %d", ret);
-  }
-
-  struct drm_gem_close gem_close;
-  memset(&gem_close, 0, sizeof(gem_close));
-  int num_gem_handles = sizeof(bo->gem_handles) / sizeof(bo->gem_handles[0]);
-  for (int i = 0; i < num_gem_handles; i++) {
-    if (!bo->gem_handles[i])
-      continue;
-
-    gem_close.handle = bo->gem_handles[i];
-    int ret = drmIoctl(drm_->fd(), DRM_IOCTL_GEM_CLOSE, &gem_close);
-    if (ret) {
-      ALOGE("Failed to close gem handle %d %d", i, ret);
-    } else {
-      /* Clear any duplicate gem handle as well but don't close again */
-      for (int j = i + 1; j < num_gem_handles; j++)
-        if (bo->gem_handles[j] == bo->gem_handles[i])
-          bo->gem_handles[j] = 0;
-      bo->gem_handles[i] = 0;
-    }
-  }
-}
-
-NvImporter::NvBuffer_t *NvImporter::GrallocGetNvBuffer(buffer_handle_t handle) {
-  void *priv = NULL;
-  int ret =
-      gralloc_->perform(gralloc_, GRALLOC_MODULE_PERFORM_GET_IMPORTER_PRIVATE,
-                        handle, NvGrallocRelease, &priv);
-  return ret ? NULL : (NvBuffer_t *)priv;
-}
-
-int NvImporter::GrallocSetNvBuffer(buffer_handle_t handle, NvBuffer_t *buf) {
-  return gralloc_->perform(gralloc_,
-                           GRALLOC_MODULE_PERFORM_SET_IMPORTER_PRIVATE, handle,
-                           NvGrallocRelease, buf);
-}
-
-#ifdef USE_NVIDIA_IMPORTER
-// static
-std::unique_ptr<Planner> Planner::CreateInstance(DrmResources *) {
-  std::unique_ptr<Planner> planner(new Planner);
-  planner->AddStage<PlanStageNvLimits>();
-  planner->AddStage<PlanStageProtectedRotated>();
-  planner->AddStage<PlanStageProtected>();
-  planner->AddStage<PlanStagePrecomp>();
-  planner->AddStage<PlanStageGreedy>();
-  return planner;
-}
-#endif
-
-static DrmPlane *GetCrtcPrimaryPlane(DrmCrtc *crtc,
-                                     std::vector<DrmPlane *> *planes) {
-  for (auto i = planes->begin(); i != planes->end(); ++i) {
-    if ((*i)->GetCrtcSupported(*crtc)) {
-      DrmPlane *plane = *i;
-      planes->erase(i);
-      return plane;
-    }
-  }
-  return NULL;
-}
-
-int PlanStageProtectedRotated::ProvisionPlanes(
-    std::vector<DrmCompositionPlane> *composition,
-    std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
-    std::vector<DrmPlane *> *planes) {
-  int ret;
-  int protected_zorder = -1;
-  for (auto i = layers.begin(); i != layers.end();) {
-    if (!i->second->protected_usage() || !i->second->transform) {
-      ++i;
-      continue;
-    }
-
-    auto primary_iter = planes->begin();
-    for (; primary_iter != planes->end(); ++primary_iter) {
-      if ((*primary_iter)->type() == DRM_PLANE_TYPE_PRIMARY)
-        break;
-    }
-
-    // We cheat a little here. Since there can only be one primary plane per
-    // crtc, we know we'll only hit this case once. So we blindly insert the
-    // protected content at the beginning of the composition, knowing this path
-    // won't be taken a second time during the loop.
-    if (primary_iter != planes->end()) {
-      composition->emplace(composition->begin(),
-                           DrmCompositionPlane::Type::kLayer, *primary_iter,
-                           crtc, i->first);
-      planes->erase(primary_iter);
-      protected_zorder = i->first;
-    } else {
-      ALOGE("Could not provision primary plane for protected/rotated layer");
-    }
-    i = layers.erase(i);
-  }
-
-  if (protected_zorder == -1)
-    return 0;
-
-  // Add any layers below the protected content to the precomposition since we
-  // need to punch a hole through them.
-  for (auto i = layers.begin(); i != layers.end();) {
-    // Skip layers above the z-order of the protected content
-    if (i->first > static_cast<size_t>(protected_zorder)) {
-      ++i;
-      continue;
-    }
-
-    // If there's no precomp layer already queued, queue one now.
-    DrmCompositionPlane *precomp = GetPrecomp(composition);
-    if (precomp) {
-      precomp->source_layers().emplace_back(i->first);
-    } else {
-      if (planes->size()) {
-        DrmPlane *precomp_plane = planes->back();
-        planes->pop_back();
-        composition->emplace_back(DrmCompositionPlane::Type::kPrecomp,
-                                  precomp_plane, crtc, i->first);
-      } else {
-        ALOGE("Not enough planes to reserve for precomp fb");
-      }
-    }
-    i = layers.erase(i);
-  }
-  return 0;
-}
-
-bool PlanStageNvLimits::CheckLayer(size_t zorder, DrmHwcLayer *layer) {
-    auto src_w = layer->source_crop.width();
-    auto src_h = layer->source_crop.height();
-    auto dst_w = layer->display_frame.width();
-    auto dst_h = layer->display_frame.height();
-    int h_limit = 4;
-    int v_limit;
-
-    switch (layer->buffer->format) {
-      case DRM_FORMAT_ARGB8888:
-      case DRM_FORMAT_ABGR8888:
-      case DRM_FORMAT_XBGR8888:
-      case DRM_FORMAT_XRGB8888:
-        // tegra driver assumes any layer with alpha channel has premult
-        // blending, avoid handling it this is not the case. This is not an
-        // issue for bottom-most layer since there's nothing to blend with
-        if (zorder > 0 && layer->blending != DrmHwcBlending::kPreMult)
-          return false;
-
-        v_limit = 2;
-        break;
-      case DRM_FORMAT_YVU420:
-      case DRM_FORMAT_YUV420:
-      case DRM_FORMAT_YUV422:
-      case DRM_FORMAT_UYVY:
-      case DRM_FORMAT_YUYV:
-      case DRM_FORMAT_NV12:
-      case DRM_FORMAT_NV21:
-      case DRM_FORMAT_RGB565:
-      case DRM_FORMAT_BGR565:
-        v_limit = 4;
-        break;
-      default:
-        v_limit = 2;
-        break;
-    }
-
-    if (layer->transform &
-        (DrmHwcTransform::kRotate90 | DrmHwcTransform::kRotate270))
-      std::swap(dst_w, dst_h);
-
-    // check for max supported down scaling
-    if (((src_w / dst_w) > h_limit) || ((src_h / dst_h) > v_limit))
-      return false;
-
-    return true;
-}
-
-int PlanStageNvLimits::ProvisionPlanes(
-    std::vector<DrmCompositionPlane> *composition,
-    std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
-    std::vector<DrmPlane *> *planes) {
-  int ret;
-
-  for (auto i = layers.begin(); i != layers.end();) {
-    // Skip layer if supported
-    if (CheckLayer(i->first, i->second)) {
-      i++;
-      continue;
-    }
-
-    if (i->second->protected_usage()) {
-      // Drop the layer if unsupported and protected, this will just display
-      // black in the area of this layer but it's better than failing miserably
-      i = layers.erase(i);
-      continue;
-    }
-
-    // If there's no precomp layer already queued, queue one now.
-    DrmCompositionPlane *precomp = GetPrecomp(composition);
-    if (precomp) {
-      precomp->source_layers().emplace_back(i->first);
-    } else if (!planes->empty()) {
-      DrmPlane *precomp_plane = planes->back();
-      planes->pop_back();
-      composition->emplace_back(DrmCompositionPlane::Type::kPrecomp,
-                                precomp_plane, crtc, i->first);
-    } else {
-      ALOGE("Not enough planes to reserve for precomp fb");
-    }
-    i = layers.erase(i);
-  }
-
-  return 0;
-}
-}
diff --git a/platformnv.h b/platformnv.h
deleted file mode 100644
index e379ea9..0000000
--- a/platformnv.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2015 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_PLATFORM_NV_H_
-#define ANDROID_PLATFORM_NV_H_
-
-#include "drmresources.h"
-#include "platform.h"
-#include "platformdrmgeneric.h"
-
-#include <stdatomic.h>
-
-#include <hardware/gralloc.h>
-
-namespace android {
-
-class NvImporter : public Importer {
- public:
-  NvImporter(DrmResources *drm);
-  ~NvImporter() override;
-
-  int Init();
-
-  int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
-  int ReleaseBuffer(hwc_drm_bo_t *bo) override;
-
- private:
-  typedef struct NvBuffer {
-    NvImporter *importer;
-    hwc_drm_bo_t bo;
-    atomic_int ref;
-  } NvBuffer_t;
-
-  static void NvGrallocRelease(void *nv_buffer);
-  void ReleaseBufferImpl(hwc_drm_bo_t *bo);
-
-  NvBuffer_t *GrallocGetNvBuffer(buffer_handle_t handle);
-  int GrallocSetNvBuffer(buffer_handle_t handle, NvBuffer_t *buf);
-
-  DrmResources *drm_;
-
-  const gralloc_module_t *gralloc_;
-};
-
-// This stage looks for any layers that contain transformed protected content
-// and puts it in the primary plane since Tegra doesn't support planar rotation
-// on the overlay planes.
-//
-// There are two caveats to this approach: 1- Protected content isn't
-// necessarily planar, but it's usually a safe bet, and 2- This doesn't catch
-// non-protected planar content. If we wanted to fix this, we'd need to import
-// the buffer in this stage and peek at it's format. The overhead of doing this
-// doesn't seem worth it since we'll end up displaying the right thing in both
-// cases anyways.
-class PlanStageProtectedRotated : public Planner::PlanStage {
- public:
-  int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
-                      std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
-                      std::vector<DrmPlane *> *planes);
-};
-
-// This stage looks for layers that would not be supported by Tegra driver due
-// to limitations such as downscaling. If the layer is unprotected it will be
-// punted for precomp to handle, other wise if protected it will be dropped as
-// it cannot be supported by any means.
-class PlanStageNvLimits : public Planner::PlanStage {
- public:
-  int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
-                      std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
-                      std::vector<DrmPlane *> *planes);
- protected:
-  bool CheckLayer(size_t zorder, DrmHwcLayer *layer);
-};
-}
-
-#endif
diff --git a/queue_worker.h b/queue_worker.h
deleted file mode 100644
index 7e96eec..0000000
--- a/queue_worker.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2016 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_QUEUE_WORKER_H_
-#define ANDROID_QUEUE_WORKER_H_
-
-#include "worker.h"
-
-#include <queue>
-
-namespace android {
-
-template <typename T>
-class QueueWorker : public Worker {
- public:
-  static const size_t kDefaultMaxQueueSize = 2;
-  static const int64_t kTimeoutDisabled = -1;
-
-  QueueWorker(const char *name, int priority)
-      : Worker(name, priority),
-        max_queue_size_(kDefaultMaxQueueSize),
-        queue_timeout_ms_(kTimeoutDisabled),
-        idle_timeout_ms_(kTimeoutDisabled),
-        idled_out_(false) {
-  }
-
-  int QueueWork(std::unique_ptr<T> workitem);
-
-  bool IsWorkPending() const {
-    return !queue_.empty();
-  }
-  bool idle() const {
-    return idled_out_;
-  }
-
-  int64_t idle_timeout() {
-    return idle_timeout_ms_;
-  }
-  void set_idle_timeout(int64_t timeout_ms) {
-    idle_timeout_ms_ = timeout_ms;
-  }
-
-  int64_t queue_timeout() {
-    return queue_timeout_ms_;
-  }
-  void set_queue_timeout(int64_t timeout_ms) {
-    queue_timeout_ms_ = timeout_ms;
-  }
-
-  size_t max_queue_size() const {
-    return max_queue_size_;
-  }
-  void set_max_queue_size(size_t size) {
-    max_queue_size_ = size;
-  }
-
- protected:
-  virtual void ProcessWork(std::unique_ptr<T> workitem) = 0;
-  virtual void ProcessIdle(){}
-  virtual void Routine();
-
-  template <typename Predicate>
-  int WaitCond(std::unique_lock<std::mutex> &lock, Predicate pred,
-               int64_t max_msecs);
-
- private:
-  std::queue<std::unique_ptr<T>> queue_;
-  size_t max_queue_size_;
-  int64_t queue_timeout_ms_;
-  int64_t idle_timeout_ms_;
-  bool idled_out_;
-};
-
-template <typename T>
-template <typename Predicate>
-int QueueWorker<T>::WaitCond(std::unique_lock<std::mutex> &lock, Predicate pred,
-                             int64_t max_msecs) {
-  bool ret = true;
-  auto wait_func = [&] { return pred() || should_exit(); };
-
-  if (max_msecs < 0) {
-    cond_.wait(lock, wait_func);
-  } else {
-    auto timeout = std::chrono::milliseconds(max_msecs);
-    ret = cond_.wait_for(lock, timeout, wait_func);
-  }
-
-  if (!ret)
-    return -ETIMEDOUT;
-  else if (should_exit())
-    return -EINTR;
-
-  return 0;
-}
-
-template <typename T>
-void QueueWorker<T>::Routine() {
-  std::unique_lock<std::mutex> lk(mutex_);
-  std::unique_ptr<T> workitem;
-
-  auto wait_func = [&] { return !queue_.empty(); };
-  int ret =
-      WaitCond(lk, wait_func, idled_out_ ? kTimeoutDisabled : idle_timeout_ms_);
-  switch (ret) {
-    case 0:
-      break;
-    case -ETIMEDOUT:
-      ProcessIdle();
-      idled_out_ = true;
-      return;
-    case -EINTR:
-    default:
-      return;
-  }
-
-  if (!queue_.empty()) {
-    workitem = std::move(queue_.front());
-    queue_.pop();
-  }
-  lk.unlock();
-  cond_.notify_all();
-
-  idled_out_ = false;
-  ProcessWork(std::move(workitem));
-}
-
-template <typename T>
-int QueueWorker<T>::QueueWork(std::unique_ptr<T> workitem) {
-  std::unique_lock<std::mutex> lk(mutex_);
-
-  auto wait_func = [&] { return queue_.size() < max_queue_size_; };
-  int ret = WaitCond(lk, wait_func, queue_timeout_ms_);
-  if (ret)
-    return ret;
-
-  queue_.push(std::move(workitem));
-  lk.unlock();
-
-  cond_.notify_one();
-
-  return 0;
-}
-};
-#endif
diff --git a/separate_rects.cpp b/separate_rects.cpp
deleted file mode 100644
index 9fd1ae4..0000000
--- a/separate_rects.cpp
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "separate_rects.h"
-#include <algorithm>
-#include <assert.h>
-#include <iostream>
-#include <map>
-#include <set>
-#include <utility>
-#include <vector>
-
-namespace separate_rects {
-
-enum EventType { START, END };
-
-template <typename TId, typename TNum>
-struct StartedRect {
-  IdSet<TId> id_set;
-  TNum left, top, bottom;
-
-  // Note that this->left is not part of the key. That field is only to mark the
-  // left edge of the rectangle.
-  bool operator<(const StartedRect<TId, TNum> &rhs) const {
-    return (top < rhs.top || (top == rhs.top && bottom < rhs.bottom)) ||
-           (top == rhs.top && bottom == rhs.bottom && id_set < rhs.id_set);
-  }
-};
-
-template <typename TId, typename TNum>
-struct SweepEvent {
-  EventType type;
-  union {
-    TNum x;
-    TNum y;
-  };
-
-  TId rect_id;
-
-  bool operator<(const SweepEvent<TId, TNum> &rhs) const {
-    return (y < rhs.y || (y == rhs.y && rect_id < rhs.rect_id));
-  }
-};
-
-template <typename TNum>
-std::ostream &operator<<(std::ostream &os, const Rect<TNum> &rect) {
-  return os << rect.bounds[0] << ", " << rect.bounds[1] << ", "
-            << rect.bounds[2] << ", " << rect.bounds[3];
-}
-
-template <typename TUInt>
-std::ostream &operator<<(std::ostream &os, const IdSet<TUInt> &obj) {
-  int bits = IdSet<TUInt>::max_elements;
-  TUInt mask = ((TUInt)0x1) << (bits - 1);
-  for (int i = 0; i < bits; i++)
-    os << ((obj.getBits() & (mask >> i)) ? "1" : "0");
-  return os;
-}
-
-template <typename TNum, typename TId>
-void separate_rects(const std::vector<Rect<TNum>> &in,
-                    std::vector<RectSet<TId, TNum>> *out) {
-  // Overview:
-  // This algorithm is a line sweep algorithm that travels from left to right.
-  // The sweep stops at each vertical edge of each input rectangle in sorted
-  // order of x-coordinate. At each stop, the sweep line is examined in order of
-  // y-coordinate from top to bottom. Along the way, a running set of rectangle
-  // IDs is either added to or subtracted from as the top and bottom edges are
-  // encountered, respectively. At each change of that running set, a copy of
-  // that set is recorded in along with the the y-coordinate it happened at in a
-  // list. This list is then interpreted as a sort of vertical cross section of
-  // our output set of non-overlapping rectangles. Based of the algorithm found
-  // at: http://stackoverflow.com/a/2755498
-
-  if (in.size() > IdSet<TId>::max_elements) {
-    return;
-  }
-
-  // Events are when the sweep line encounters the starting or ending edge of
-  // any input rectangle.
-  std::set<SweepEvent<TId, TNum>> sweep_h_events;  // Left or right bounds
-  std::set<SweepEvent<TId, TNum>> sweep_v_events;  // Top or bottom bounds
-
-  // A started rect is a rectangle whose left, top, bottom edge, and set of
-  // rectangle IDs is known. The key of this map includes all that information
-  // (except the left edge is never used to determine key equivalence or
-  // ordering),
-  std::map<StartedRect<TId, TNum>, bool> started_rects;
-
-  // This is cleared after every event. Its declaration is here to avoid
-  // reallocating a vector and its buffers every event.
-  std::vector<std::pair<TNum, IdSet<TId>>> active_regions;
-
-  // This pass will add rectangle start and end events to be triggered as the
-  // algorithm sweeps from left to right.
-  for (TId i = 0; i < in.size(); i++) {
-    const Rect<TNum> &rect = in[i];
-
-    // Filter out empty or invalid rects.
-    if (rect.left >= rect.right || rect.top >= rect.bottom)
-      continue;
-
-    SweepEvent<TId, TNum> evt;
-    evt.rect_id = i;
-
-    evt.type = START;
-    evt.x = rect.left;
-    sweep_h_events.insert(evt);
-
-    evt.type = END;
-    evt.x = rect.right;
-    sweep_h_events.insert(evt);
-  }
-
-  for (typename std::set<SweepEvent<TId, TNum>>::iterator it =
-           sweep_h_events.begin();
-       it != sweep_h_events.end(); ++it) {
-    const SweepEvent<TId, TNum> &h_evt = *it;
-    const Rect<TNum> &rect = in[h_evt.rect_id];
-
-    // During this event, we have encountered a vertical starting or ending edge
-    // of a rectangle so want to append or remove (respectively) that rectangles
-    // top and bottom from the vertical sweep line.
-    SweepEvent<TId, TNum> v_evt;
-    v_evt.rect_id = h_evt.rect_id;
-    if (h_evt.type == START) {
-      v_evt.type = START;
-      v_evt.y = rect.top;
-      sweep_v_events.insert(v_evt);
-
-      v_evt.type = END;
-      v_evt.y = rect.bottom;
-      sweep_v_events.insert(v_evt);
-    } else {
-      v_evt.type = START;
-      v_evt.y = rect.top;
-      typename std::set<SweepEvent<TId, TNum>>::iterator start_it =
-          sweep_v_events.find(v_evt);
-      assert(start_it != sweep_v_events.end());
-      sweep_v_events.erase(start_it);
-
-      v_evt.type = END;
-      v_evt.y = rect.bottom;
-      typename std::set<SweepEvent<TId, TNum>>::iterator end_it =
-          sweep_v_events.find(v_evt);
-      assert(end_it != sweep_v_events.end());
-      sweep_v_events.erase(end_it);
-    }
-
-    // Peeks ahead to see if there are other rectangles sharing a vertical edge
-    // with the current sweep line. If so, we want to continue marking up the
-    // sweep line before actually processing the rectangles the sweep line is
-    // intersecting.
-    typename std::set<SweepEvent<TId, TNum>>::iterator next_it = it;
-    ++next_it;
-    if (next_it != sweep_h_events.end()) {
-      if (next_it->x == h_evt.x) {
-        continue;
-      }
-    }
-
-#ifdef RECTS_DEBUG
-    std::cout << h_evt.x << std::endl;
-#endif
-
-    // After the following for loop, active_regions will be a list of
-    // y-coordinates paired with the set of rectangle IDs that are intersect at
-    // that y-coordinate (and the current sweep line's x-coordinate). For
-    // example if the current sweep line were the left edge of a scene with only
-    // one rectangle of ID 0 and bounds (left, top, right, bottom) == (2, 3, 4,
-    // 5), active_regions will be [({ 0 }, 3), {}, 5].
-    active_regions.clear();
-    IdSet<TId> active_set;
-    for (typename std::set<SweepEvent<TId, TNum>>::iterator it =
-             sweep_v_events.begin();
-         it != sweep_v_events.end(); ++it) {
-      const SweepEvent<TId, TNum> &v_evt = *it;
-
-      if (v_evt.type == START) {
-        active_set.add(v_evt.rect_id);
-      } else {
-        active_set.subtract(v_evt.rect_id);
-      }
-
-      if (active_regions.size() > 0 && active_regions.back().first == v_evt.y) {
-        active_regions.back().second = active_set;
-      } else {
-        active_regions.push_back(std::make_pair(v_evt.y, active_set));
-      }
-    }
-
-#ifdef RECTS_DEBUG
-    std::cout << "x:" << h_evt.x;
-    for (std::vector<std::pair<TNum, IdSet>>::iterator it =
-             active_regions.begin();
-         it != active_regions.end(); ++it) {
-      std::cout << " " << it->first << "(" << it->second << ")"
-                << ",";
-    }
-    std::cout << std::endl;
-#endif
-
-    // To determine which started rectangles are ending this event, we make them
-    // all as false, or unseen during this sweep line.
-    for (typename std::map<StartedRect<TId, TNum>, bool>::iterator it =
-             started_rects.begin();
-         it != started_rects.end(); ++it) {
-      it->second = false;
-    }
-
-    // This for loop will iterate all potential new rectangles and either
-    // discover it was already started (and then mark it true), or that it is a
-    // new rectangle and add it to the started rectangles. A started rectangle
-    // is unique if it has a distinct top, bottom, and set of rectangle IDs.
-    // This is tricky because a potential rectangle could be encountered here
-    // that has a non-unique top and bottom, so it shares geometry with an
-    // already started rectangle, but the set of rectangle IDs differs. In that
-    // case, we have a new rectangle, and the already existing started rectangle
-    // will not be marked as seen ("true" in the std::pair) and will get ended
-    // by the for loop after this one. This is as intended.
-    for (typename std::vector<std::pair<TNum, IdSet<TId>>>::iterator it =
-             active_regions.begin();
-         it != active_regions.end(); ++it) {
-      IdSet<TId> region_set = it->second;
-
-      if (region_set.isEmpty())
-        continue;
-
-      // An important property of active_regions is that each region where a set
-      // of rectangles applies is bounded at the bottom by the next (in the
-      // vector) region's starting y-coordinate.
-      typename std::vector<std::pair<TNum, IdSet<TId>>>::iterator next_it = it;
-      ++next_it;
-      assert(next_it != active_regions.end());
-
-      TNum region_top = it->first;
-      TNum region_bottom = next_it->first;
-
-      StartedRect<TId, TNum> rect_key;
-      rect_key.id_set = region_set;
-      rect_key.left = h_evt.x;
-      rect_key.top = region_top;
-      rect_key.bottom = region_bottom;
-
-      // Remember that rect_key.left is ignored for the purposes of searching
-      // the started rects. This follows from the fact that a previously started
-      // rectangle would by definition have a left bound less than the current
-      // event's x-coordinate. We are interested in continuing the started
-      // rectangles by marking them seen (true) but we don't know, care, or wish
-      // to change the left bound at this point. If there are no matching
-      // rectangles for this region, start a new one and mark it as seen (true).
-      typename std::map<StartedRect<TId, TNum>, bool>::iterator
-          started_rect_it = started_rects.find(rect_key);
-      if (started_rect_it == started_rects.end()) {
-        started_rects[rect_key] = true;
-      } else {
-        started_rect_it->second = true;
-      }
-    }
-
-    // This for loop ends all rectangles that were unseen during this event.
-    // Because this is the first event where we didn't see this rectangle, it's
-    // right edge is exactly the current event's x-coordinate. With this, we
-    // have the final piece of information to output this rectangle's geometry
-    // and set of input rectangle IDs. To end a started rectangle, we erase it
-    // from the started_rects map and append the completed rectangle to the
-    // output vector.
-    for (typename std::map<StartedRect<TId, TNum>, bool>::iterator it =
-             started_rects.begin();
-         it != started_rects.end();
-         /* inc in body */) {
-      if (!it->second) {
-        const StartedRect<TId, TNum> &proto_rect = it->first;
-        Rect<TNum> out_rect;
-        out_rect.left = proto_rect.left;
-        out_rect.top = proto_rect.top;
-        out_rect.right = h_evt.x;
-        out_rect.bottom = proto_rect.bottom;
-        out->push_back(RectSet<TId, TNum>(proto_rect.id_set, out_rect));
-        started_rects.erase(it++);  // Also increments out iterator.
-
-#ifdef RECTS_DEBUG
-        std::cout << "    <" << proto_rect.id_set << "(" << rect << ")"
-                  << std::endl;
-#endif
-      } else {
-        // Remember this for loop has no built in increment step. We do it here.
-        ++it;
-      }
-    }
-  }
-}
-
-void separate_frects_64(const std::vector<Rect<float>> &in,
-                        std::vector<RectSet<uint64_t, float>> *out) {
-  separate_rects(in, out);
-}
-
-void separate_rects_64(const std::vector<Rect<int>> &in,
-                       std::vector<RectSet<uint64_t, int>> *out) {
-  separate_rects(in, out);
-}
-
-}  // namespace separate_rects
-
-#ifdef RECTS_TEST
-
-using namespace separate_rects;
-
-int main(int argc, char **argv) {
-#define RectSet RectSet<TId, TNum>
-#define Rect Rect<TNum>
-#define IdSet IdSet<TId>
-  typedef uint64_t TId;
-  typedef float TNum;
-
-  std::vector<Rect> in;
-  std::vector<RectSet> out;
-  std::vector<RectSet> expected_out;
-
-  in.push_back({0, 0, 4, 5});
-  in.push_back({2, 0, 6, 6});
-  in.push_back({4, 0, 8, 5});
-  in.push_back({0, 7, 8, 9});
-
-  in.push_back({10, 0, 18, 5});
-  in.push_back({12, 0, 16, 5});
-
-  in.push_back({20, 11, 24, 17});
-  in.push_back({22, 13, 26, 21});
-  in.push_back({32, 33, 36, 37});
-  in.push_back({30, 31, 38, 39});
-
-  in.push_back({40, 43, 48, 45});
-  in.push_back({44, 41, 46, 47});
-
-  in.push_back({50, 51, 52, 53});
-  in.push_back({50, 51, 52, 53});
-  in.push_back({50, 51, 52, 53});
-
-  in.push_back({0, 0, 0, 10});
-  in.push_back({0, 0, 10, 0});
-  in.push_back({10, 0, 0, 10});
-  in.push_back({0, 10, 10, 0});
-
-  for (int i = 0; i < 100000; i++) {
-    out.clear();
-    separate_rects(in, &out);
-  }
-
-  for (int i = 0; i < out.size(); i++) {
-    std::cout << out[i].id_set << "(" << out[i].rect << ")" << std::endl;
-  }
-
-  std::cout << "# of rects: " << out.size() << std::endl;
-
-  expected_out.push_back(RectSet(IdSet(0), Rect(0, 0, 2, 5)));
-  expected_out.push_back(RectSet(IdSet(1), Rect(2, 5, 6, 6)));
-  expected_out.push_back(RectSet(IdSet(1) | 0, Rect(2, 0, 4, 5)));
-  expected_out.push_back(RectSet(IdSet(1) | 2, Rect(4, 0, 6, 5)));
-  expected_out.push_back(RectSet(IdSet(2), Rect(6, 0, 8, 5)));
-  expected_out.push_back(RectSet(IdSet(3), Rect(0, 7, 8, 9)));
-  expected_out.push_back(RectSet(IdSet(4), Rect(10, 0, 12, 5)));
-  expected_out.push_back(RectSet(IdSet(5) | 4, Rect(12, 0, 16, 5)));
-  expected_out.push_back(RectSet(IdSet(4), Rect(16, 0, 18, 5)));
-  expected_out.push_back(RectSet(IdSet(6), Rect(20, 11, 22, 17)));
-  expected_out.push_back(RectSet(IdSet(6) | 7, Rect(22, 13, 24, 17)));
-  expected_out.push_back(RectSet(IdSet(6), Rect(22, 11, 24, 13)));
-  expected_out.push_back(RectSet(IdSet(7), Rect(22, 17, 24, 21)));
-  expected_out.push_back(RectSet(IdSet(7), Rect(24, 13, 26, 21)));
-  expected_out.push_back(RectSet(IdSet(9), Rect(30, 31, 32, 39)));
-  expected_out.push_back(RectSet(IdSet(8) | 9, Rect(32, 33, 36, 37)));
-  expected_out.push_back(RectSet(IdSet(9), Rect(32, 37, 36, 39)));
-  expected_out.push_back(RectSet(IdSet(9), Rect(32, 31, 36, 33)));
-  expected_out.push_back(RectSet(IdSet(9), Rect(36, 31, 38, 39)));
-  expected_out.push_back(RectSet(IdSet(10), Rect(40, 43, 44, 45)));
-  expected_out.push_back(RectSet(IdSet(10) | 11, Rect(44, 43, 46, 45)));
-  expected_out.push_back(RectSet(IdSet(11), Rect(44, 41, 46, 43)));
-  expected_out.push_back(RectSet(IdSet(11), Rect(44, 45, 46, 47)));
-  expected_out.push_back(RectSet(IdSet(10), Rect(46, 43, 48, 45)));
-  expected_out.push_back(RectSet(IdSet(12) | 13 | 14, Rect(50, 51, 52, 53)));
-
-  for (int i = 0; i < expected_out.size(); i++) {
-    RectSet &ex_out = expected_out[i];
-    if (std::find(out.begin(), out.end(), ex_out) == out.end()) {
-      std::cout << "Missing Rect: " << ex_out.id_set << "(" << ex_out.rect
-                << ")" << std::endl;
-    }
-  }
-
-  for (int i = 0; i < out.size(); i++) {
-    RectSet &actual_out = out[i];
-    if (std::find(expected_out.begin(), expected_out.end(), actual_out) ==
-        expected_out.end()) {
-      std::cout << "Extra Rect: " << actual_out.id_set << "(" << actual_out.rect
-                << ")" << std::endl;
-    }
-  }
-
-  return 0;
-}
-
-#endif
diff --git a/separate_rects.h b/separate_rects.h
deleted file mode 100644
index de8b660..0000000
--- a/separate_rects.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2015 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 DRM_HWCOMPOSER_SEPARATE_RECTS_H_
-#define DRM_HWCOMPOSER_SEPARATE_RECTS_H_
-
-#include <stdint.h>
-
-#include <sstream>
-#include <vector>
-
-namespace separate_rects {
-
-template <typename TFloat>
-struct Rect {
-  union {
-    struct {
-      TFloat left, top, right, bottom;
-    };
-    struct {
-      TFloat x1, y1, x2, y2;
-    };
-    TFloat bounds[4];
-  };
-
-  typedef TFloat TNum;
-
-  Rect() {
-  }
-
-  Rect(TFloat xx1, TFloat yy1, TFloat xx2, TFloat yy2)
-      : x1(xx1), y1(yy1), x2(xx2), y2(yy2) {
-  }
-
-  template <typename T>
-  Rect(const Rect<T> &rhs) {
-    for (int i = 0; i < 4; i++)
-      bounds[i] = rhs.bounds[i];
-  }
-
-  template <typename T>
-  Rect<TFloat> &operator=(const Rect<T> &rhs) {
-    for (int i = 0; i < 4; i++)
-      bounds[i] = rhs.bounds[i];
-    return *this;
-  }
-
-  bool operator==(const Rect &rhs) const {
-    for (int i = 0; i < 4; i++) {
-      if (bounds[i] != rhs.bounds[i])
-        return false;
-    }
-
-    return true;
-  }
-
-  TFloat width() const {
-    return bounds[2] - bounds[0];
-  }
-
-  TFloat height() const {
-    return bounds[3] - bounds[1];
-  }
-
-  TFloat area() const {
-    return width() * height();
-  }
-
-  void Dump(std::ostringstream *out) const {
-    *out << "[x/y/w/h]=" << left << "/" << top << "/" << width() << "/"
-         << height();
-  }
-};
-
-template <typename TUInt>
-struct IdSet {
- public:
-  typedef TUInt TId;
-
-  IdSet() : bitset(0) {
-  }
-
-  IdSet(TId id) : bitset(0) {
-    add(id);
-  }
-
-  void add(TId id) {
-    bitset |= ((TUInt)1) << id;
-  }
-
-  void subtract(TId id) {
-    bitset &= ~(((TUInt)1) << id);
-  }
-
-  bool isEmpty() const {
-    return bitset == 0;
-  }
-
-  TUInt getBits() const {
-    return bitset;
-  }
-
-  bool operator==(const IdSet<TId> &rhs) const {
-    return bitset == rhs.bitset;
-  }
-
-  bool operator<(const IdSet<TId> &rhs) const {
-    return bitset < rhs.bitset;
-  }
-
-  IdSet<TId> operator|(const IdSet<TId> &rhs) const {
-    IdSet ret;
-    ret.bitset = bitset | rhs.bitset;
-    return ret;
-  }
-
-  IdSet<TId> operator|(TId id) const {
-    IdSet<TId> ret;
-    ret.bitset = bitset;
-    ret.add(id);
-    return ret;
-  }
-
-  static const int max_elements = sizeof(TId) * 8;
-
- private:
-  TUInt bitset;
-};
-
-template <typename TId, typename TNum>
-struct RectSet {
-  IdSet<TId> id_set;
-  Rect<TNum> rect;
-
-  RectSet(const IdSet<TId> &i, const Rect<TNum> &r) : id_set(i), rect(r) {
-  }
-
-  bool operator==(const RectSet<TId, TNum> &rhs) const {
-    return id_set == rhs.id_set && rect == rhs.rect;
-  }
-};
-
-// Separates up to a maximum of 64 input rectangles into mutually non-
-// overlapping rectangles that cover the exact same area and outputs those non-
-// overlapping rectangles. Each output rectangle also includes the set of input
-// rectangle indices that overlap the output rectangle encoded in a bitset. For
-// example, an output rectangle that overlaps input rectangles in[0], in[1], and
-// in[4], the bitset would be (ommitting leading zeroes) 10011.
-void separate_frects_64(const std::vector<Rect<float>> &in,
-                        std::vector<RectSet<uint64_t, float>> *out);
-void separate_rects_64(const std::vector<Rect<int>> &in,
-                       std::vector<RectSet<uint64_t, int>> *out);
-
-}  // namespace separate_rects
-
-#endif
diff --git a/tests/Android.mk b/tests/Android.mk
index b86cca6..b498d62 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -3,11 +3,13 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
-	queue_worker_test.cpp \
 	worker_test.cpp
 
 LOCAL_MODULE := hwc-drm-tests
+LOCAL_VENDOR_MODULE := true
+LOCAL_HEADER_LIBRARIES := libhardware_headers
 LOCAL_STATIC_LIBRARIES := libdrmhwc_utils
+LOCAL_SHARED_LIBRARIES := hwcomposer.drm
 LOCAL_C_INCLUDES := external/drm_hwcomposer
 
 include $(BUILD_NATIVE_TEST)
diff --git a/tests/queue_worker_test.cpp b/tests/queue_worker_test.cpp
deleted file mode 100644
index d1c0470..0000000
--- a/tests/queue_worker_test.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-#include <gtest/gtest.h>
-#include <hardware/hardware.h>
-
-#include <chrono>
-#include <mutex>
-
-#include "queue_worker.h"
-
-using android::QueueWorker;
-
-#define UNUSED_ARG(x) (void)(x)
-
-struct TestData {
-  TestData(int val) : value(val) {
-  }
-  virtual ~TestData() {
-  }
-
-  virtual void CheckValue(int prev_value) {
-    ASSERT_EQ(prev_value + 1, value);
-  }
-
-  int value;
-};
-
-struct TestQueueWorker : public QueueWorker<TestData> {
-  TestQueueWorker()
-      : QueueWorker("test-queueworker", HAL_PRIORITY_URGENT_DISPLAY), value(0) {
-  }
-
-  int Init() {
-    return InitWorker();
-  }
-
-  void ProcessWork(std::unique_ptr<TestData> data) {
-    std::lock_guard<std::mutex> blk(block);
-    data->CheckValue(value);
-    {
-      std::lock_guard<std::mutex> lk(lock);
-      value = data->value;
-    }
-    cond.notify_one();
-  }
-
-  void ProcessIdle() {
-    ASSERT_FALSE(idle());
-  }
-
-  std::mutex lock;
-  std::mutex block;
-  std::condition_variable cond;
-  int value;
-};
-
-struct QueueWorkerTest : public testing::Test {
-  static const int kTimeoutMs = 1000;
-  TestQueueWorker qw;
-
-  virtual void SetUp() {
-    qw.Init();
-  }
-  bool QueueValue(int val) {
-    std::unique_ptr<TestData> data(new TestData(val));
-    return !qw.QueueWork(std::move(data));
-  }
-
-  bool WaitFor(int val, int timeout_ms = kTimeoutMs) {
-    std::unique_lock<std::mutex> lk(qw.lock);
-
-    auto timeout = std::chrono::milliseconds(timeout_ms);
-    return qw.cond.wait_for(lk, timeout, [&] { return qw.value == val; });
-  }
-};
-
-struct IdleQueueWorkerTest : public QueueWorkerTest {
-  const int64_t kIdleTimeoutMs = 100;
-
-  virtual void SetUp() {
-    qw.set_idle_timeout(kIdleTimeoutMs);
-    qw.Init();
-  }
-};
-
-TEST_F(QueueWorkerTest, single_queue) {
-  // already isInitialized so should fail
-  ASSERT_NE(qw.Init(), 0);
-
-  ASSERT_EQ(qw.value, 0);
-  ASSERT_TRUE(QueueValue(1));
-  ASSERT_TRUE(WaitFor(1));
-  ASSERT_EQ(qw.value, 1);
-  ASSERT_FALSE(qw.IsWorkPending());
-}
-
-TEST_F(QueueWorkerTest, multiple_waits) {
-  for (int i = 1; i <= 100; i++) {
-    ASSERT_TRUE(QueueValue(i));
-    ASSERT_TRUE(WaitFor(i));
-    ASSERT_EQ(qw.value, i);
-    ASSERT_FALSE(qw.IsWorkPending());
-  }
-}
-
-TEST_F(QueueWorkerTest, multiple_queue) {
-  for (int i = 1; i <= 100; i++) {
-    ASSERT_TRUE(QueueValue(i));
-  }
-  ASSERT_TRUE(WaitFor(100));
-  ASSERT_EQ(qw.value, 100);
-  ASSERT_FALSE(qw.IsWorkPending());
-}
-
-TEST_F(QueueWorkerTest, blocking) {
-  // First wait for inital value to be setup
-  ASSERT_TRUE(QueueValue(1));
-  ASSERT_TRUE(WaitFor(1));
-
-  // Block processing and fill up the queue
-  std::unique_lock<std::mutex> lk(qw.block);
-  size_t expected_value = qw.max_queue_size() + 2;
-  for (size_t i = 2; i <= expected_value; i++) {
-    ASSERT_TRUE(QueueValue(i));
-  }
-
-  qw.set_queue_timeout(100);
-  // any additional queueing should fail
-  ASSERT_FALSE(QueueValue(expected_value + 1));
-
-  // make sure value is not changed while blocked
-  {
-    std::unique_lock<std::mutex> lock(qw.lock);
-    auto timeout = std::chrono::milliseconds(100);
-    ASSERT_FALSE(
-        qw.cond.wait_for(lock, timeout, [&] { return qw.value != 1; }));
-  }
-  ASSERT_EQ(qw.value, 1);
-  ASSERT_TRUE(qw.IsWorkPending());
-
-  // unblock and wait for value to be reached
-  lk.unlock();
-  ASSERT_TRUE(WaitFor(expected_value));
-  ASSERT_FALSE(qw.IsWorkPending());
-}
-
-TEST_F(QueueWorkerTest, exit_slow) {
-  struct SlowData : public TestData {
-    SlowData(int val) : TestData(val) {
-    }
-    void CheckValue(int prev_value) {
-      UNUSED_ARG(prev_value);
-
-      std::this_thread::sleep_for(std::chrono::milliseconds(100));
-    }
-  };
-  std::unique_ptr<SlowData> data(new SlowData(1));
-  ASSERT_EQ(qw.QueueWork(std::move(data)), 0);
-  data = std::unique_ptr<SlowData>(new SlowData(2));
-  ASSERT_EQ(qw.QueueWork(std::move(data)), 0);
-  qw.Exit();
-  ASSERT_FALSE(qw.initialized());
-}
-
-TEST_F(QueueWorkerTest, exit_empty) {
-  qw.Exit();
-  ASSERT_FALSE(qw.initialized());
-}
-
-TEST_F(QueueWorkerTest, queue_worker_noidling) {
-  ASSERT_TRUE(QueueValue(1));
-  ASSERT_TRUE(WaitFor(1));
-
-  ASSERT_FALSE(qw.idle());
-  auto timeout = std::chrono::milliseconds(200);
-  std::this_thread::sleep_for(timeout);
-  ASSERT_FALSE(qw.idle());
-}
-
-TEST_F(IdleQueueWorkerTest, queue_worker_idling) {
-  ASSERT_TRUE(QueueValue(1));
-  ASSERT_TRUE(WaitFor(1));
-  ASSERT_FALSE(qw.idle());
-
-  auto timeout = std::chrono::milliseconds(kIdleTimeoutMs + 10);
-  std::this_thread::sleep_for(timeout);
-  ASSERT_TRUE(qw.idle());
-  ASSERT_TRUE(QueueValue(2));
-  ASSERT_TRUE(WaitFor(2));
-  ASSERT_FALSE(qw.idle());
-
-  std::this_thread::sleep_for(3 * timeout);
-  ASSERT_TRUE(qw.idle());
-
-  ASSERT_TRUE(QueueValue(3));
-  ASSERT_TRUE(WaitFor(3));
-  for (int i = 4; i <= 100; i++) {
-    QueueValue(i);
-  }
-  ASSERT_FALSE(qw.idle());
-  qw.Exit();
-  ASSERT_FALSE(qw.initialized());
-}
\ No newline at end of file
diff --git a/tests/worker_test.cpp b/tests/worker_test.cpp
index 38f91db..82523f0 100644
--- a/tests/worker_test.cpp
+++ b/tests/worker_test.cpp
@@ -66,7 +66,7 @@
 };
 
 TEST_F(WorkerTest, test_worker) {
-  // already isInitialized so should fail
+  // already isInitialized so should succeed
   ASSERT_TRUE(worker.initialized());
 
   int val = worker.value;
diff --git a/virtualcompositorworker.cpp b/virtualcompositorworker.cpp
deleted file mode 100644
index c1a6d2f..0000000
--- a/virtualcompositorworker.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2015-2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "hwc-virtual-compositor-worker"
-
-#include "virtualcompositorworker.h"
-
-#include <cutils/log.h>
-#include <sw_sync.h>
-#include <sync/sync.h>
-
-namespace android {
-
-static const int kMaxQueueDepth = 3;
-static const int kAcquireWaitTimeoutMs = 3000;
-
-VirtualCompositorWorker::VirtualCompositorWorker()
-    : QueueWorker("virtual-compositor", HAL_PRIORITY_URGENT_DISPLAY),
-      timeline_fd_(-1),
-      timeline_(0),
-      timeline_current_(0) {
-}
-
-VirtualCompositorWorker::~VirtualCompositorWorker() {
-  if (timeline_fd_ >= 0) {
-    FinishComposition(timeline_);
-    close(timeline_fd_);
-    timeline_fd_ = -1;
-  }
-}
-
-int VirtualCompositorWorker::Init() {
-  int ret = sw_sync_timeline_create();
-  if (ret < 0) {
-    ALOGE("Failed to create sw sync timeline %d", ret);
-    return ret;
-  }
-  timeline_fd_ = ret;
-
-  set_max_queue_size(kMaxQueueDepth);
-  return InitWorker();
-}
-
-void VirtualCompositorWorker::QueueComposite(hwc_display_contents_1_t *dc) {
-  std::unique_ptr<VirtualComposition> composition(new VirtualComposition);
-
-  composition->outbuf_acquire_fence.Set(dc->outbufAcquireFenceFd);
-  dc->outbufAcquireFenceFd = -1;
-  if (dc->retireFenceFd >= 0)
-    close(dc->retireFenceFd);
-  dc->retireFenceFd = CreateNextTimelineFence();
-
-  for (size_t i = 0; i < dc->numHwLayers; ++i) {
-    hwc_layer_1_t *layer = &dc->hwLayers[i];
-    if (layer->flags & HWC_SKIP_LAYER)
-      continue;
-    composition->layer_acquire_fences.emplace_back(layer->acquireFenceFd);
-    layer->acquireFenceFd = -1;
-    if (layer->releaseFenceFd >= 0)
-      close(layer->releaseFenceFd);
-    layer->releaseFenceFd = CreateNextTimelineFence();
-  }
-
-  composition->release_timeline = timeline_;
-
-  QueueWork(std::move(composition));
-}
-
-int VirtualCompositorWorker::CreateNextTimelineFence() {
-  ++timeline_;
-  return sw_sync_fence_create(timeline_fd_, "drm_fence", timeline_);
-}
-
-int VirtualCompositorWorker::FinishComposition(int point) {
-  int timeline_increase = point - timeline_current_;
-  if (timeline_increase <= 0)
-    return 0;
-  int ret = sw_sync_timeline_inc(timeline_fd_, timeline_increase);
-  if (ret)
-    ALOGE("Failed to increment sync timeline %d", ret);
-  else
-    timeline_current_ = point;
-  return ret;
-}
-
-void VirtualCompositorWorker::ProcessWork(
-    std::unique_ptr<VirtualComposition> composition) {
-  if (!composition.get())
-    return;
-
-  int ret;
-  int outbuf_acquire_fence = composition->outbuf_acquire_fence.get();
-  if (outbuf_acquire_fence >= 0) {
-    ret = sync_wait(outbuf_acquire_fence, kAcquireWaitTimeoutMs);
-    if (ret) {
-      ALOGE("Failed to wait for outbuf acquire %d/%d", outbuf_acquire_fence,
-            ret);
-      return;
-    }
-    composition->outbuf_acquire_fence.Close();
-  }
-  for (size_t i = 0; i < composition->layer_acquire_fences.size(); ++i) {
-    int layer_acquire_fence = composition->layer_acquire_fences[i].get();
-    if (layer_acquire_fence >= 0) {
-      ret = sync_wait(layer_acquire_fence, kAcquireWaitTimeoutMs);
-      if (ret) {
-        ALOGE("Failed to wait for layer acquire %d/%d", layer_acquire_fence,
-              ret);
-        return;
-      }
-      composition->layer_acquire_fences[i].Close();
-    }
-  }
-  FinishComposition(composition->release_timeline);
-}
-}
diff --git a/virtualcompositorworker.h b/virtualcompositorworker.h
deleted file mode 100644
index 885cf31..0000000
--- a/virtualcompositorworker.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2015-2016 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_VIRTUAL_COMPOSITOR_WORKER_H_
-#define ANDROID_VIRTUAL_COMPOSITOR_WORKER_H_
-
-#include "drmhwcomposer.h"
-#include "queue_worker.h"
-
-namespace android {
-
-struct VirtualComposition {
-  UniqueFd outbuf_acquire_fence;
-  std::vector<UniqueFd> layer_acquire_fences;
-  int release_timeline;
-};
-
-class VirtualCompositorWorker : public QueueWorker<VirtualComposition> {
- public:
-  VirtualCompositorWorker();
-  ~VirtualCompositorWorker() override;
-
-  int Init();
-  void QueueComposite(hwc_display_contents_1_t *dc);
-
- protected:
-  void ProcessWork(std::unique_ptr<VirtualComposition> composition);
-
- private:
-  int CreateNextTimelineFence();
-  int FinishComposition(int timeline);
-
-  int timeline_fd_;
-  int timeline_;
-  int timeline_current_;
-};
-}
-
-#endif
diff --git a/vsyncworker.cpp b/vsyncworker.cpp
index ee140cb..6ac016d 100644
--- a/vsyncworker.cpp
+++ b/vsyncworker.cpp
@@ -26,7 +26,7 @@
 #include <xf86drm.h>
 #include <xf86drmMode.h>
 
-#include <cutils/log.h>
+#include <log/log.h>
 #include <hardware/hardware.h>
 
 namespace android {
@@ -34,8 +34,8 @@
 VSyncWorker::VSyncWorker()
     : Worker("vsync", HAL_PRIORITY_URGENT_DISPLAY),
       drm_(NULL),
-      procs_(NULL),
       display_(-1),
+      enabled_(false),
       last_timestamp_(-1) {
 }
 
@@ -49,9 +49,9 @@
   return InitWorker();
 }
 
-void VSyncWorker::SetProcs(hwc_procs_t const *procs) {
+void VSyncWorker::RegisterCallback(std::shared_ptr<VsyncCallback> callback) {
   Lock();
-  procs_ = procs;
+  callback_ = callback;
   Unlock();
 }
 
@@ -120,13 +120,14 @@
   if (!enabled_) {
     ret = WaitForSignalOrExitLocked();
     if (ret == -EINTR) {
+      Unlock();
       return;
     }
   }
 
   bool enabled = enabled_;
   int display = display_;
-  hwc_procs_t const *procs = procs_;
+  std::shared_ptr<VsyncCallback> callback(callback_);
   Unlock();
 
   if (!enabled)
@@ -159,16 +160,16 @@
   }
 
   /*
-   * There's a race here where a change in procs_ will not take effect until
+   * There's a race here where a change in callback_ will not take effect until
    * the next subsequent requested vsync. This is unavoidable since we can't
    * call the vsync hook while holding the thread lock.
    *
-   * We could shorten the race window by caching procs_ right before calling
-   * the hook. However, in practice, procs_ is only updated once, so it's not
+   * We could shorten the race window by caching callback_ right before calling
+   * the hook. However, in practice, callback_ is only updated once, so it's not
    * worth the overhead.
    */
-  if (procs && procs->vsync)
-    procs->vsync(procs, display, timestamp);
+  if (callback)
+    callback->Callback(display, timestamp);
   last_timestamp_ = timestamp;
 }
 }
diff --git a/vsyncworker.h b/vsyncworker.h
index 3e1f814..787152e 100644
--- a/vsyncworker.h
+++ b/vsyncworker.h
@@ -28,13 +28,20 @@
 
 namespace android {
 
+class VsyncCallback {
+ public:
+  virtual ~VsyncCallback() {
+  }
+  virtual void Callback(int display, int64_t timestamp) = 0;
+};
+
 class VSyncWorker : public Worker {
  public:
   VSyncWorker();
   ~VSyncWorker() override;
 
   int Init(DrmResources *drm, int display);
-  void SetProcs(hwc_procs_t const *procs);
+  void RegisterCallback(std::shared_ptr<VsyncCallback> callback);
 
   void VSyncControl(bool enabled);
 
@@ -46,7 +53,11 @@
   int SyntheticWaitVBlank(int64_t *timestamp);
 
   DrmResources *drm_;
-  hwc_procs_t const *procs_;
+
+  // shared_ptr since we need to use this outside of the thread lock (to
+  // actually call the hook) and we don't want the memory freed until we're
+  // done
+  std::shared_ptr<VsyncCallback> callback_ = NULL;
 
   int display_;
   bool enabled_;
