diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index 05832cb..7427729 100644
--- a/drmdisplaycompositor.cpp
+++ b/drmdisplaycompositor.cpp
@@ -36,8 +36,24 @@
 #include "drmdevice.h"
 #include "drmplane.h"
 
+static const uint32_t kWaitWritebackFence = 100;  // ms
+
 namespace android {
 
+class CompositorVsyncCallback : public VsyncCallback {
+ public:
+  CompositorVsyncCallback(DrmDisplayCompositor *compositor)
+      : compositor_(compositor) {
+  }
+
+  void Callback(int display, int64_t timestamp) {
+    compositor_->Vsync(display, timestamp);
+  }
+
+ private:
+  DrmDisplayCompositor *compositor_;
+};
+
 DrmDisplayCompositor::DrmDisplayCompositor()
     : resource_manager_(NULL),
       display_(-1),
@@ -45,7 +61,9 @@
       active_(false),
       use_hw_overlays_(true),
       dump_frames_composited_(0),
-      dump_last_timestamp_ns_(0) {
+      dump_last_timestamp_ns_(0),
+      flatten_countdown_(FLATTEN_COUNTDOWN_INIT),
+      writeback_fence_(-1) {
   struct timespec ts;
   if (clock_gettime(CLOCK_MONOTONIC, &ts))
     return;
@@ -56,6 +74,7 @@
   if (!initialized_)
     return;
 
+  vsync_worker_.Exit();
   int ret = pthread_mutex_lock(&lock_);
   if (ret)
     ALOGE("Failed to acquire compositor lock %d", ret);
@@ -77,7 +96,8 @@
 int DrmDisplayCompositor::Init(ResourceManager *resource_manager, int display) {
   resource_manager_ = resource_manager;
   display_ = display;
-  if (!resource_manager_->GetDrmDevice(display)) {
+  DrmDevice *drm = resource_manager_->GetDrmDevice(display);
+  if (!drm) {
     ALOGE("Could not find drmdevice for display");
     return -EINVAL;
   }
@@ -86,6 +106,11 @@
     ALOGE("Failed to initialize drm compositor lock %d\n", ret);
     return ret;
   }
+  planner_ = Planner::CreateInstance(drm);
+
+  vsync_worker_.Init(drm, display_);
+  auto callback = std::make_shared<CompositorVsyncCallback>(this);
+  vsync_worker_.RegisterCallback(callback);
 
   initialized_ = true;
   return 0;
@@ -96,6 +121,28 @@
   return std::unique_ptr<DrmDisplayComposition>(new DrmDisplayComposition());
 }
 
+std::unique_ptr<DrmDisplayComposition>
+DrmDisplayCompositor::CreateInitializedComposition() const {
+  DrmDevice *drm = resource_manager_->GetDrmDevice(display_);
+  DrmCrtc *crtc = drm->GetCrtcForDisplay(display_);
+  if (!crtc) {
+    ALOGE("Failed to find crtc for display = %d", display_);
+    return std::unique_ptr<DrmDisplayComposition>();
+  }
+  std::unique_ptr<DrmDisplayComposition> comp = CreateComposition();
+  std::shared_ptr<Importer> importer = resource_manager_->GetImporter(display_);
+  if (!importer) {
+    ALOGE("Failed to find resources for display = %d", display_);
+    return std::unique_ptr<DrmDisplayComposition>();
+  }
+  int ret = comp->Init(drm, crtc, importer.get(), planner_.get(), 0);
+  if (ret) {
+    ALOGE("Failed to init composition for display = %d", display_);
+    return std::unique_ptr<DrmDisplayComposition>();
+  }
+  return comp;
+}
+
 std::tuple<uint32_t, uint32_t, int>
 DrmDisplayCompositor::GetActiveModeResolution() {
   DrmDevice *drm = resource_manager_->GetDrmDevice(display_);
@@ -144,8 +191,49 @@
   return 0;
 }
 
+int DrmDisplayCompositor::SetupWritebackCommit(drmModeAtomicReqPtr pset,
+                                               uint32_t crtc_id,
+                                               DrmConnector *writeback_conn,
+                                               DrmHwcBuffer *writeback_buffer) {
+  int ret = 0;
+  if (writeback_conn->writeback_fb_id().id() == 0 ||
+      writeback_conn->writeback_out_fence().id() == 0) {
+    ALOGE("Writeback properties don't exit");
+    return -EINVAL;
+  }
+  if ((*writeback_buffer)->fb_id == 0) {
+    ALOGE("Invalid writeback buffer");
+    return -EINVAL;
+  }
+  ret = drmModeAtomicAddProperty(pset, writeback_conn->id(),
+                                 writeback_conn->writeback_fb_id().id(),
+                                 (*writeback_buffer)->fb_id);
+  if (ret < 0) {
+    ALOGE("Failed to add writeback_fb_id");
+    return ret;
+  }
+  ret = drmModeAtomicAddProperty(pset, writeback_conn->id(),
+                                 writeback_conn->writeback_out_fence().id(),
+                                 (uint64_t)&writeback_fence_);
+  if (ret < 0) {
+    ALOGE("Failed to add writeback_out_fence");
+    return ret;
+  }
+
+  ret = drmModeAtomicAddProperty(pset, writeback_conn->id(),
+                                 writeback_conn->crtc_id_property().id(),
+                                 crtc_id);
+  if (ret < 0) {
+    ALOGE("Failed to  attach writeback");
+    return ret;
+  }
+  return 0;
+}
+
 int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
-                                      bool test_only) {
+                                      bool test_only,
+                                      DrmConnector *writeback_conn,
+                                      DrmHwcBuffer *writeback_buffer) {
   ATRACE_CALL();
 
   int ret = 0;
@@ -173,6 +261,18 @@
     return -ENOMEM;
   }
 
+  if (writeback_buffer != NULL) {
+    if (writeback_conn == NULL) {
+      ALOGE("Invalid arguments requested writeback without writeback conn");
+      return -EINVAL;
+    }
+    ret = SetupWritebackCommit(pset, crtc->id(), writeback_conn,
+                               writeback_buffer);
+    if (ret < 0) {
+      ALOGE("Failed to Setup Writeback Commit ret = %d", ret);
+      return ret;
+    }
+  }
   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()]);
@@ -438,17 +538,24 @@
     return;
 
   active_composition_.reset(NULL);
+  vsync_worker_.VSyncControl(false);
 }
 
 void DrmDisplayCompositor::ApplyFrame(
-    std::unique_ptr<DrmDisplayComposition> composition, int status) {
+    std::unique_ptr<DrmDisplayComposition> composition, int status,
+    bool writeback) {
   AutoLock lock(&lock_, __func__);
   if (lock.Lock())
     return;
   int ret = status;
 
-  if (!ret)
+  if (!ret) {
+    if (writeback && !CountdownExpired()) {
+      ALOGE("Abort playing back scene");
+      return;
+    }
     ret = CommitFrame(composition.get(), false);
+  }
 
   if (ret) {
     ALOGE("Composite failed for display %d", display_);
@@ -461,6 +568,8 @@
 
   active_composition_.swap(composition);
 
+  flatten_countdown_ = FLATTEN_COUNTDOWN_INIT;
+  vsync_worker_.VSyncControl(!writeback);
 }
 
 int DrmDisplayCompositor::ApplyComposition(
@@ -510,6 +619,336 @@
   return CommitFrame(composition, true);
 }
 
+// Flatten a scene on the display by using a writeback connector
+// and returns the composition result as a DrmHwcLayer.
+int DrmDisplayCompositor::FlattenOnDisplay(
+    std::unique_ptr<DrmDisplayComposition> &src, DrmConnector *writeback_conn,
+    DrmMode &src_mode, DrmHwcLayer *writeback_layer) {
+  int ret = 0;
+  DrmDevice *drm = resource_manager_->GetDrmDevice(display_);
+  ret = writeback_conn->UpdateModes();
+  if (ret) {
+    ALOGE("Failed to update modes %d", ret);
+    return ret;
+  }
+  for (const DrmMode &mode : writeback_conn->modes()) {
+    if (mode.h_display() == src_mode.h_display() &&
+        mode.v_display() == src_mode.v_display()) {
+      mode_.mode = mode;
+      if (mode_.blob_id)
+        drm->DestroyPropertyBlob(mode_.blob_id);
+      std::tie(ret, mode_.blob_id) = CreateModeBlob(mode_.mode);
+      if (ret) {
+        ALOGE("Failed to create mode blob for display %d", display_);
+        return ret;
+      }
+      mode_.needs_modeset = true;
+      break;
+    }
+  }
+  if (mode_.blob_id <= 0) {
+    ALOGE("Failed to find similar mode");
+    return -EINVAL;
+  }
+
+  DrmCrtc *crtc = drm->GetCrtcForDisplay(display_);
+  if (!crtc) {
+    ALOGE("Failed to find crtc for display %d", display_);
+    return -EINVAL;
+  }
+  // TODO what happens if planes could go to both CRTCs, I don't think it's
+  // handled anywhere
+  std::vector<DrmPlane *> primary_planes;
+  std::vector<DrmPlane *> overlay_planes;
+  for (auto &plane : drm->planes()) {
+    if (!plane->GetCrtcSupported(*crtc))
+      continue;
+    if (plane->type() == DRM_PLANE_TYPE_PRIMARY)
+      primary_planes.push_back(plane.get());
+    else if (plane->type() == DRM_PLANE_TYPE_OVERLAY)
+      overlay_planes.push_back(plane.get());
+  }
+
+  ret = src->Plan(&primary_planes, &overlay_planes);
+  if (ret) {
+    ALOGE("Failed to plan the composition ret = %d", ret);
+    return ret;
+  }
+
+  // Disable the planes we're not using
+  for (auto i = primary_planes.begin(); i != primary_planes.end();) {
+    src->AddPlaneDisable(*i);
+    i = primary_planes.erase(i);
+  }
+  for (auto i = overlay_planes.begin(); i != overlay_planes.end();) {
+    src->AddPlaneDisable(*i);
+    i = overlay_planes.erase(i);
+  }
+
+  AutoLock lock(&lock_, __func__);
+  ret = lock.Lock();
+  if (ret)
+    return ret;
+  DrmFramebuffer *writeback_fb = &framebuffers_[framebuffer_index_];
+  framebuffer_index_ = (framebuffer_index_ + 1) % DRM_DISPLAY_BUFFERS;
+  if (!writeback_fb->Allocate(mode_.mode.h_display(), mode_.mode.v_display())) {
+    ALOGE("Failed to allocate writeback buffer");
+    return -ENOMEM;
+  }
+  DrmHwcBuffer *writeback_buffer = &writeback_layer->buffer;
+  writeback_layer->sf_handle = writeback_fb->buffer()->handle;
+  ret = writeback_layer->ImportBuffer(
+      resource_manager_->GetImporter(display_).get());
+  if (ret) {
+    ALOGE("Failed to import writeback buffer");
+    return ret;
+  }
+
+  ret = CommitFrame(src.get(), true, writeback_conn, writeback_buffer);
+  if (ret) {
+    ALOGE("Atomic check failed");
+    return ret;
+  }
+  ret = CommitFrame(src.get(), false, writeback_conn, writeback_buffer);
+  if (ret) {
+    ALOGE("Atomic commit failed");
+    return ret;
+  }
+
+  ret = sync_wait(writeback_fence_, kWaitWritebackFence);
+  writeback_layer->acquire_fence.Set(writeback_fence_);
+  writeback_fence_ = -1;
+  if (ret) {
+    ALOGE("Failed to wait on writeback fence");
+    return ret;
+  }
+  return 0;
+}
+
+// Flatten a scene by enabling the writeback connector attached
+// to the same CRTC as the one driving the display.
+int DrmDisplayCompositor::FlattenSerial(DrmConnector *writeback_conn) {
+  ALOGV("FlattenSerial by enabling writeback connector to the same crtc");
+  // Flattened composition with only one layer that is obtained
+  // using the writeback connector
+  std::unique_ptr<DrmDisplayComposition> writeback_comp =
+      CreateInitializedComposition();
+  if (!writeback_comp)
+    return -EINVAL;
+
+  AutoLock lock(&lock_, __func__);
+  int ret = lock.Lock();
+  if (ret)
+    return ret;
+  if (!CountdownExpired() || active_composition_->layers().size() < 2) {
+    ALOGV("Flattening is not needed");
+    return -EALREADY;
+  }
+
+  DrmFramebuffer *writeback_fb = &framebuffers_[framebuffer_index_];
+  framebuffer_index_ = (framebuffer_index_ + 1) % DRM_DISPLAY_BUFFERS;
+  lock.Unlock();
+
+  if (!writeback_fb->Allocate(mode_.mode.h_display(), mode_.mode.v_display())) {
+    ALOGE("Failed to allocate writeback buffer");
+    return -ENOMEM;
+  }
+  writeback_comp->layers().emplace_back();
+
+  DrmHwcLayer &writeback_layer = writeback_comp->layers().back();
+  writeback_layer.sf_handle = writeback_fb->buffer()->handle;
+  writeback_layer.source_crop = {0, 0, (float)mode_.mode.h_display(),
+                                 (float)mode_.mode.v_display()};
+  writeback_layer.display_frame = {0, 0, (int)mode_.mode.h_display(),
+                                   (int)mode_.mode.v_display()};
+  ret = writeback_layer.ImportBuffer(
+      resource_manager_->GetImporter(display_).get());
+  if (ret || writeback_comp->layers().size() != 1) {
+    ALOGE("Failed to import writeback buffer");
+    return ret;
+  }
+
+  drmModeAtomicReqPtr pset = drmModeAtomicAlloc();
+  if (!pset) {
+    ALOGE("Failed to allocate property set");
+    return -ENOMEM;
+  }
+  DrmDevice *drm = resource_manager_->GetDrmDevice(display_);
+  DrmCrtc *crtc = drm->GetCrtcForDisplay(display_);
+  if (!crtc) {
+    ALOGE("Failed to find crtc for display %d", display_);
+    return -EINVAL;
+  }
+  ret = SetupWritebackCommit(pset, crtc->id(), writeback_conn,
+                             &writeback_layer.buffer);
+  if (ret < 0) {
+    ALOGE("Failed to Setup Writeback Commit");
+    return ret;
+  }
+  ret = drmModeAtomicCommit(drm->fd(), pset, 0, drm);
+  if (ret) {
+    ALOGE("Failed to enable writeback %d", ret);
+    return ret;
+  }
+  ret = sync_wait(writeback_fence_, kWaitWritebackFence);
+  writeback_layer.acquire_fence.Set(writeback_fence_);
+  writeback_fence_ = -1;
+  if (ret) {
+    ALOGE("Failed to wait on writeback fence");
+    return ret;
+  }
+
+  DrmCompositionPlane squashed_comp(DrmCompositionPlane::Type::kLayer, NULL,
+                                    crtc);
+  for (auto &drmplane : drm->planes()) {
+    if (!drmplane->GetCrtcSupported(*crtc))
+      continue;
+    if (!squashed_comp.plane() && drmplane->type() == DRM_PLANE_TYPE_PRIMARY)
+      squashed_comp.set_plane(drmplane.get());
+    else
+      writeback_comp->AddPlaneDisable(drmplane.get());
+  }
+  squashed_comp.source_layers().push_back(0);
+  ret = writeback_comp->AddPlaneComposition(std::move(squashed_comp));
+  if (ret) {
+    ALOGE("Failed to add flatten scene");
+    return ret;
+  }
+
+  ApplyFrame(std::move(writeback_comp), 0, true);
+  return 0;
+}
+
+// Flatten a scene by using a crtc which works concurrent with
+// the one driving the display.
+int DrmDisplayCompositor::FlattenConcurrent(DrmConnector *writeback_conn) {
+  ALOGV("FlattenConcurrent by using an unused crtc/display");
+  int ret = 0;
+  DrmDisplayCompositor drmdisplaycompositor;
+  ret = drmdisplaycompositor.Init(resource_manager_, writeback_conn->display());
+  if (ret) {
+    ALOGE("Failed to init  drmdisplaycompositor = %d", ret);
+    return ret;
+  }
+  // Copy of the active_composition, needed because of two things:
+  // 1) Not to hold the lock for the whole time we are accessing
+  //    active_composition
+  // 2) It will be committed on a crtc that might not be on the same
+  //     dri node, so buffers need to be imported on the right node.
+  std::unique_ptr<DrmDisplayComposition> copy_comp =
+      drmdisplaycompositor.CreateInitializedComposition();
+
+  // Writeback composition that will be committed to the display.
+  std::unique_ptr<DrmDisplayComposition> writeback_comp =
+      CreateInitializedComposition();
+
+  if (!copy_comp || !writeback_comp)
+    return -EINVAL;
+  AutoLock lock(&lock_, __func__);
+  ret = lock.Lock();
+  if (ret)
+    return ret;
+  if (!CountdownExpired() || active_composition_->layers().size() < 2) {
+    ALOGV("Flattening is not needed");
+    return -EALREADY;
+  }
+  DrmCrtc *crtc = active_composition_->crtc();
+
+  std::vector<DrmHwcLayer> copy_layers;
+  for (DrmHwcLayer &src_layer : active_composition_->layers()) {
+    DrmHwcLayer copy;
+    ret = copy.InitFromDrmHwcLayer(
+        &src_layer,
+        resource_manager_->GetImporter(writeback_conn->display()).get());
+    if (ret) {
+      ALOGE("Failed to import buffer ret = %d", ret);
+      return -EINVAL;
+    }
+    copy_layers.emplace_back(std::move(copy));
+  }
+  ret = copy_comp->SetLayers(copy_layers.data(), copy_layers.size(), true);
+  if (ret) {
+    ALOGE("Failed to set copy_comp layers");
+    return ret;
+  }
+
+  lock.Unlock();
+  DrmHwcLayer writeback_layer;
+  ret = drmdisplaycompositor.FlattenOnDisplay(copy_comp, writeback_conn,
+                                              mode_.mode, &writeback_layer);
+  if (ret) {
+    ALOGE("Failed to flatten on display ret = %d", ret);
+    return ret;
+  }
+
+  DrmCompositionPlane squashed_comp(DrmCompositionPlane::Type::kLayer, NULL,
+                                    crtc);
+  for (auto &drmplane : resource_manager_->GetDrmDevice(display_)->planes()) {
+    if (!drmplane->GetCrtcSupported(*crtc))
+      continue;
+    if (drmplane->type() == DRM_PLANE_TYPE_PRIMARY)
+      squashed_comp.set_plane(drmplane.get());
+    else
+      writeback_comp->AddPlaneDisable(drmplane.get());
+  }
+  writeback_comp->layers().emplace_back();
+  DrmHwcLayer &next_layer = writeback_comp->layers().back();
+  next_layer.sf_handle = writeback_layer.get_usable_handle();
+  next_layer.blending = DrmHwcBlending::kPreMult;
+  next_layer.source_crop = {0, 0, (float)mode_.mode.h_display(),
+                            (float)mode_.mode.v_display()};
+  next_layer.display_frame = {0, 0, (int)mode_.mode.h_display(),
+                              (int)mode_.mode.v_display()};
+  ret = next_layer.ImportBuffer(resource_manager_->GetImporter(display_).get());
+  if (ret) {
+    ALOGE("Failed to import framebuffer for display %d", ret);
+    return ret;
+  }
+  squashed_comp.source_layers().push_back(0);
+  ret = writeback_comp->AddPlaneComposition(std::move(squashed_comp));
+  if (ret) {
+    ALOGE("Failed to add plane composition %d", ret);
+    return ret;
+  }
+  ApplyFrame(std::move(writeback_comp), 0, true);
+  return ret;
+}
+
+int DrmDisplayCompositor::FlattenActiveComposition() {
+  DrmConnector *writeback_conn =
+      resource_manager_->AvailableWritebackConnector(display_);
+  if (!active_composition_ || !writeback_conn) {
+    ALOGV("No writeback connector available");
+    return -EINVAL;
+  }
+
+  if (writeback_conn->display() != display_) {
+    return FlattenConcurrent(writeback_conn);
+  } else {
+    return FlattenSerial(writeback_conn);
+  }
+
+  return 0;
+}
+
+bool DrmDisplayCompositor::CountdownExpired() const {
+  return flatten_countdown_ <= 0;
+}
+
+void DrmDisplayCompositor::Vsync(int display, int64_t timestamp) {
+  AutoLock lock(&lock_, __func__);
+  if (lock.Lock())
+    return;
+  flatten_countdown_--;
+  if (!CountdownExpired())
+    return;
+  lock.Unlock();
+  int ret = FlattenActiveComposition();
+  ALOGV("scene flattening triggered for display %d at timestamp %" PRIu64
+        " result = %d \n",
+        display, timestamp, ret);
+}
+
 void DrmDisplayCompositor::Dump(std::ostringstream *out) const {
   int ret = pthread_mutex_lock(&lock_);
   if (ret)
