diff --git a/drmdisplaycomposition.cpp b/drmdisplaycomposition.cpp
index 2089157..2af9d5a 100644
--- a/drmdisplaycomposition.cpp
+++ b/drmdisplaycomposition.cpp
@@ -113,11 +113,8 @@
 }
 
 int DrmDisplayComposition::AddPlaneDisable(DrmPlane *plane) {
-  composition_planes_.emplace_back(
-      DrmCompositionPlane{.plane = plane,
-                          .crtc = crtc_,
-                          .type = DrmCompositionPlaneType::kDisable,
-                          .source_layer = -1});
+  composition_planes_.emplace_back(DrmCompositionPlaneType::kDisable, plane,
+                                   crtc_);
   return 0;
 }
 
@@ -153,8 +150,7 @@
 }
 
 void DrmDisplayComposition::EmplaceCompositionPlane(
-    DrmCompositionPlaneType type, int source_layer,
-    std::vector<DrmPlane *> *primary_planes,
+    DrmCompositionPlaneType type, std::vector<DrmPlane *> *primary_planes,
     std::vector<DrmPlane *> *overlay_planes) {
   DrmPlane *plane = TakePlane(crtc_, primary_planes, overlay_planes);
   if (plane == NULL) {
@@ -163,11 +159,21 @@
         "remaining");
     return;
   }
-  composition_planes_.emplace_back(
-      DrmCompositionPlane{.plane = plane,
-                          .crtc = crtc_,
-                          .type = type,
-                          .source_layer = source_layer});
+  composition_planes_.emplace_back(type, plane, crtc_);
+}
+
+void DrmDisplayComposition::EmplaceCompositionPlane(
+    size_t source_layer, std::vector<DrmPlane *> *primary_planes,
+    std::vector<DrmPlane *> *overlay_planes) {
+  DrmPlane *plane = TakePlane(crtc_, primary_planes, overlay_planes);
+  if (plane == NULL) {
+    ALOGE(
+        "Failed to add composition plane because there are no planes "
+        "remaining");
+    return;
+  }
+  composition_planes_.emplace_back(DrmCompositionPlaneType::kLayer, plane,
+                                   crtc_, source_layer);
 }
 
 static std::vector<size_t> SetBitsToVector(uint64_t in, size_t *index_map) {
@@ -275,10 +281,12 @@
   }
 
   for (const DrmCompositionPlane &plane : composition_planes_) {
-    if (plane.type == DrmCompositionPlaneType::kLayer) {
-      DrmHwcLayer *source_layer = &layers_[plane.source_layer];
-      comp_layers.emplace(source_layer);
-      pre_comp_layers.erase(source_layer);
+    if (plane.type() == DrmCompositionPlaneType::kLayer) {
+      for (auto i : plane.source_layers()) {
+        DrmHwcLayer *source_layer = &layers_[i];
+        comp_layers.emplace(source_layer);
+        pre_comp_layers.erase(source_layer);
+      }
     }
   }
 
@@ -393,8 +401,7 @@
 
   if (planes_can_use == 0 && layers_remaining.size() > 0) {
     for (auto i : protected_layers)
-      EmplaceCompositionPlane(DrmCompositionPlaneType::kLayer, i,
-                              primary_planes, overlay_planes);
+      EmplaceCompositionPlane(i, primary_planes, overlay_planes);
 
     ALOGE("Protected layers consumed all hardware planes");
     return CreateAndAssignReleaseFences();
@@ -430,15 +437,13 @@
     // that again.
     if (protected_idx < protected_layers.size() &&
         idx > protected_layers[protected_idx]) {
-      EmplaceCompositionPlane(DrmCompositionPlaneType::kLayer,
-                              protected_layers[protected_idx], primary_planes,
+      EmplaceCompositionPlane(protected_layers[protected_idx], primary_planes,
                               overlay_planes);
       protected_idx++;
       continue;
     }
 
-    EmplaceCompositionPlane(DrmCompositionPlaneType::kLayer,
-                            layers_remaining[last_hw_comp_layer],
+    EmplaceCompositionPlane(layers_remaining[last_hw_comp_layer],
                             primary_planes, overlay_planes);
     last_hw_comp_layer++;
     planes_can_use--;
@@ -449,14 +454,13 @@
 
   // Enqueue the rest of the protected layers (if any) between the hw composited
   // overlay layers and the squash/precomp layers.
-  for (int i = protected_idx; i < protected_layers.size(); ++i)
-    EmplaceCompositionPlane(DrmCompositionPlaneType::kLayer,
-                            protected_layers[i], primary_planes,
+  for (size_t i = protected_idx; i < protected_layers.size(); ++i)
+    EmplaceCompositionPlane(protected_layers[i], primary_planes,
                             overlay_planes);
 
   if (layers_remaining.size() > 0) {
-    EmplaceCompositionPlane(DrmCompositionPlaneType::kPrecomp, -1,
-                            primary_planes, overlay_planes);
+    EmplaceCompositionPlane(DrmCompositionPlaneType::kPrecomp, primary_planes,
+                            overlay_planes);
     SeparateLayers(layers_.data(), layers_remaining.data(),
                    layers_remaining.size(), protected_layers.data(),
                    protected_layers.size(), exclude_rects.data(),
@@ -464,8 +468,8 @@
   }
 
   if (use_squash_framebuffer) {
-    EmplaceCompositionPlane(DrmCompositionPlaneType::kSquash, -1,
-                            primary_planes, overlay_planes);
+    EmplaceCompositionPlane(DrmCompositionPlaneType::kSquash, primary_planes,
+                            overlay_planes);
   }
 
   return CreateAndAssignReleaseFences();
@@ -631,9 +635,9 @@
   for (size_t i = 0; i < composition_planes_.size(); i++) {
     const DrmCompositionPlane &comp_plane = composition_planes_[i];
     *out << "      [" << i << "]"
-         << " plane=" << (comp_plane.plane ? comp_plane.plane->id() : -1)
+         << " plane=" << (comp_plane.plane() ? comp_plane.plane()->id() : -1)
          << " type=";
-    switch (comp_plane.type) {
+    switch (comp_plane.type()) {
       case DrmCompositionPlaneType::kDisable:
         *out << "DISABLE";
         break;
@@ -651,7 +655,11 @@
         break;
     }
 
-    *out << " source_layer=" << comp_plane.source_layer << "\n";
+    *out << " source_layer=";
+    for (auto i : comp_plane.source_layers()) {
+      *out << i << " ";
+    }
+    *out << "\n";
   }
 
   *out << "    Squash Regions: count=" << squash_regions_.size() << "\n";
diff --git a/drmdisplaycomposition.h b/drmdisplaycomposition.h
index 0362404..768ccfb 100644
--- a/drmdisplaycomposition.h
+++ b/drmdisplaycomposition.h
@@ -53,11 +53,51 @@
   kSquash,
 };
 
-struct DrmCompositionPlane {
-  DrmCompositionPlaneType type;
-  DrmPlane *plane;
-  DrmCrtc *crtc;
-  int source_layer;
+class DrmCompositionPlane {
+ public:
+  DrmCompositionPlane() = default;
+  DrmCompositionPlane(DrmCompositionPlane &&rhs) = default;
+  DrmCompositionPlane &operator=(DrmCompositionPlane &&other) = default;
+  DrmCompositionPlane(DrmCompositionPlaneType type, DrmPlane *plane,
+                      DrmCrtc *crtc)
+      : type_(type), plane_(plane), crtc_(crtc) {
+  }
+  DrmCompositionPlane(DrmCompositionPlaneType type, DrmPlane *plane,
+                      DrmCrtc *crtc, size_t source_layer)
+      : type_(type),
+        plane_(plane),
+        crtc_(crtc),
+        source_layers_(1, source_layer) {
+  }
+
+  DrmCompositionPlaneType type() const {
+    return type_;
+  }
+
+  DrmPlane *plane() const {
+    return plane_;
+  }
+  void set_plane(DrmPlane *plane) {
+    plane_ = plane;
+  }
+
+  DrmCrtc *crtc() const {
+    return crtc_;
+  }
+
+  std::vector<size_t> &source_layers() {
+    return source_layers_;
+  }
+
+  const std::vector<size_t> &source_layers() const {
+    return source_layers_;
+  }
+
+ private:
+  DrmCompositionPlaneType type_ = DrmCompositionPlaneType::kDisable;
+  DrmPlane *plane_ = NULL;
+  DrmCrtc *crtc_ = NULL;
+  std::vector<size_t> source_layers_;
 };
 
 class DrmDisplayComposition {
@@ -139,7 +179,10 @@
 
   int IncreaseTimelineToPoint(int point);
 
-  void EmplaceCompositionPlane(DrmCompositionPlaneType type, int source_layer,
+  void EmplaceCompositionPlane(DrmCompositionPlaneType type,
+                               std::vector<DrmPlane *> *primary_planes,
+                               std::vector<DrmPlane *> *overlay_planes);
+  void EmplaceCompositionPlane(size_t source_layer,
                                std::vector<DrmPlane *> *primary_planes,
                                std::vector<DrmPlane *> *overlay_planes);
   int CreateAndAssignReleaseFences();
diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index c9cf40c..fc040dc 100644
--- a/drmdisplaycompositor.cpp
+++ b/drmdisplaycompositor.cpp
@@ -172,7 +172,7 @@
 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 == DrmCompositionPlaneType::kSquash;
+    return plane.type() == DrmCompositionPlaneType::kSquash;
   });
 }
 
@@ -488,7 +488,7 @@
   std::vector<DrmCompositionPlane> &comp_planes =
       display_comp->composition_planes();
   for (DrmCompositionPlane &comp_plane : comp_planes) {
-    DrmPlane *plane = comp_plane.plane;
+    DrmPlane *plane = comp_plane.plane();
     ret = drmModeAtomicAddProperty(pset, plane->id(),
                                    plane->crtc_property().id(), 0) < 0 ||
           drmModeAtomicAddProperty(pset, plane->id(), plane->fb_property().id(),
@@ -572,9 +572,13 @@
   }
 
   for (DrmCompositionPlane &comp_plane : comp_planes) {
-    switch (comp_plane.type) {
+    std::vector<size_t> &source_layers = comp_plane.source_layers();
+    switch (comp_plane.type()) {
       case DrmCompositionPlaneType::kSquash:
-        comp_plane.source_layer = squash_layer_index;
+        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 DrmCompositionPlaneType::kPrecomp:
         if (!do_pre_comp) {
@@ -583,7 +587,9 @@
               "regions");
           return -EINVAL;
         }
-        comp_plane.source_layer = pre_comp_layer_index;
+        // Replace source_layers with the output of the precomposite
+        source_layers.clear();
+        source_layers.push_back(pre_comp_layer_index);
         break;
       default:
         break;
@@ -636,8 +642,9 @@
   }
 
   for (DrmCompositionPlane &comp_plane : comp_planes) {
-    DrmPlane *plane = comp_plane.plane;
-    DrmCrtc *crtc = comp_plane.crtc;
+    DrmPlane *plane = comp_plane.plane();
+    DrmCrtc *crtc = comp_plane.crtc();
+    std::vector<size_t> &source_layers = comp_plane.source_layers();
 
     int fb_id = -1;
     DrmHwcRect<int> display_frame;
@@ -645,14 +652,19 @@
     uint64_t rotation = 0;
     uint64_t alpha = 0xFF;
 
-    if (comp_plane.type != DrmCompositionPlaneType::kDisable) {
-      if (comp_plane.source_layer < 0 ||
-          static_cast<size_t>(comp_plane.source_layer) >= layers.size()) {
-        ALOGE("Source layer index %d out of bounds %zu type=%d",
-              comp_plane.source_layer, layers.size(), comp_plane.type);
+    if (comp_plane.type() != DrmCompositionPlaneType::kDisable) {
+      if (source_layers.size() > 1) {
+        ALOGE("Can't handle more than one source layer sz=%zu type=%d",
+              source_layers.size(), comp_plane.type());
+        continue;
+      }
+
+      if (source_layers.empty() || source_layers.front() >= layers.size()) {
+        ALOGE("Source layer index %zu out of bounds %zu type=%d",
+              source_layers.front(), layers.size(), comp_plane.type());
         break;
       }
-      DrmHwcLayer &layer = layers[comp_plane.source_layer];
+      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;
@@ -1029,7 +1041,7 @@
   // 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 == DrmCompositionPlaneType::kLayer;
+        return p.type() == DrmCompositionPlaneType::kLayer;
       });
   if (src_planes_with_layer <= 1)
     return -EALREADY;
@@ -1047,35 +1059,36 @@
   std::vector<DrmHwcLayer> dst_layers;
   for (DrmCompositionPlane &comp_plane : src_planes) {
     // Composition planes without DRM planes should never happen
-    if (comp_plane.plane == NULL) {
+    if (comp_plane.plane() == NULL) {
       ALOGE("Skipping squash all because of NULL plane");
       ret = -EINVAL;
       goto move_layers_back;
     }
 
-    if (comp_plane.type == DrmCompositionPlaneType::kDisable ||
-        comp_plane.source_layer < 0)
+    if (comp_plane.type() == DrmCompositionPlaneType::kDisable)
       continue;
 
-    DrmHwcLayer &layer = src_layers[comp_plane.source_layer];
+    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;
+      // 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));
     }
 
-    // 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));
-
-    if (comp_plane.plane->type() == DRM_PLANE_TYPE_PRIMARY &&
+    if (comp_plane.plane()->type() == DRM_PLANE_TYPE_PRIMARY &&
         primary_planes.size() == 0)
-      primary_planes.push_back(comp_plane.plane);
+      primary_planes.push_back(comp_plane.plane());
     else
-      dst->AddPlaneDisable(comp_plane.plane);
+      dst->AddPlaneDisable(comp_plane.plane());
   }
 
   ret = dst->SetLayers(dst_layers.data(), dst_layers.size(), false);
@@ -1100,9 +1113,14 @@
   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 == DrmCompositionPlaneType::kPrecomp)
-      plane.source_layer = pre_comp_layer_index;
+  for (DrmCompositionPlane &plane : dst->composition_planes()) {
+    if (plane.type() == DrmCompositionPlaneType::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;
 
@@ -1110,10 +1128,13 @@
 // composition.
 move_layers_back:
   for (size_t plane_index = 0;
-       plane_index < src_planes.size() && plane_index < dst_layers.size();
-       plane_index++) {
-    size_t source_layer_index = src_planes[plane_index].source_layer;
-    src_layers[source_layer_index] = std::move(dst_layers[plane_index]);
+       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;
