drm_hwcomposer: add scene flattening

Flattening of a scene is triggered if it doesn't change for a while.
As of now there is a separate thread which triggers flattening if the
scene did not change in last 60 vsyncs.

There are two options for flattening a scene:
* Serial, by using a writeback connector attached to the same crtc as
  the one driving the display. This happens only if possible_clones
  mask reports that the display encoder and writeback encoder could
  work simultaneously.
The steps for achieving this are:
1. Build a commit that enables writeback connector, we don't need to
   build a commit that contains the entire active_composition, just
   set the writeback specific properties a let the kernel duplicate
   the rest of the state.
2. Commit and wait for writeback_fence to fire.
3. Setup a composition with just one plane enabled.
4. Apply the composition if a new one has not been applied meanwhile.

* Concurrent, by comitting the scene to a new unused crtc (state !=
  DRM_MODE_CONNECTED) and getting the result back through a writeback
  connector.
The steps for achieving this are:
1. Copy layers from active composition.
2. Plan layers of copy on the unused crtc. This is realized by using a
   newly created DrmDisplayCompositor object.
3. Commit copy to the unsed crtc and get the result as a drmhwclayer.
4. Setup a composition with just one plane enabled. Re-importing the
   buffers might be needed since we might have been using a different
   dri node.
5. Apply the composition if a new one has not been applied while doing
   the flattening

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
diff --git a/drmdevice.cpp b/drmdevice.cpp
index b2f350c..58f639e 100644
--- a/drmdevice.cpp
+++ b/drmdevice.cpp
@@ -277,6 +277,31 @@
   return NULL;
 }
 
+// TODO what happens when hotplugging
+DrmConnector *DrmDevice::AvailableWritebackConnector(int display) const {
+  DrmConnector *writeback_conn = GetWritebackConnectorForDisplay(display);
+  DrmConnector *display_conn = GetConnectorForDisplay(display);
+  // If we have a writeback already attached to the same CRTC just use that,
+  // if possible.
+  if (display_conn && writeback_conn &&
+      writeback_conn->encoder()->CanClone(display_conn->encoder()))
+    return writeback_conn;
+
+  // Use another CRTC if available and doesn't have any connector
+  for (auto &crtc : crtcs_) {
+    if (crtc->display() == display)
+      continue;
+    display_conn = GetConnectorForDisplay(crtc->display());
+    // If we have a display connected don't use it for writeback
+    if (display_conn && display_conn->state() == DRM_MODE_CONNECTED)
+      continue;
+    writeback_conn = GetWritebackConnectorForDisplay(crtc->display());
+    if (writeback_conn)
+      return writeback_conn;
+  }
+  return NULL;
+}
+
 DrmCrtc *DrmDevice::GetCrtcForDisplay(int display) const {
   for (auto &crtc : crtcs_) {
     if (crtc->display() == display)