Merge remote-tracking branch 'aosp/upstream-master' into HEAD

* aosp/upstream-master:
  drm_hwcomposer: Fix returned fence in PresentDisplay
  drm_hwcomposer: Add safe guard for unknown connector type
  drm_hwcomposer: Fix compilation issues with Android 9
  drm_hwcomposer: Fix missing definition build error on P and earlier
  drm_hwcomposer: Add property hwc.drm.primary_display_order
  drm_hwcomposer: Add DrmConnector::name function
  drm_hwcomposer: Apply same logic for 'CURSOR' layers as for 'DEVICE'
  drm_hwcomposer: Fix mixed layer composition
  drm_hwcomposer: Add Imagination platform support
  drm_hwcomposer: avoid using signed errno on uint32 type

Mostly updates and bugfixes, along with support for Imagination
hardware on TI platforms.

Change-Id: I8082c9fb1436809775cd4b09961d9fed6ee4150c
Signed-off-by: John Stultz <john.stultz@linaro.org>
diff --git a/Android.bp b/Android.bp
index 5681cb7..85be0b5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -110,6 +110,15 @@
     include_dirs: ["external/minigbm/cros_gralloc"],
 }
 
+// Used by hwcomposer.drm_imagination
+filegroup {
+    name: "drm_hwcomposer_platformimagination",
+    srcs: [
+        "platform/platformdrmgeneric.cpp",
+        "platform/platformimagination.cpp",
+    ],
+}
+
 // Used by hwcomposer.drm_hikey and hwcomposer.drm_hikey960
 filegroup {
     name: "drm_hwcomposer_platformhisi",
diff --git a/drm/drmconnector.cpp b/drm/drmconnector.cpp
index 543827d..7cde7cd 100644
--- a/drm/drmconnector.cpp
+++ b/drm/drmconnector.cpp
@@ -22,11 +22,16 @@
 #include <errno.h>
 #include <stdint.h>
 
+#include <array>
+#include <sstream>
+
 #include <log/log.h>
 #include <xf86drmMode.h>
 
 namespace android {
 
+constexpr size_t TYPES_COUNT = 17;
+
 DrmConnector::DrmConnector(DrmDevice *drm, drmModeConnectorPtr c,
                            DrmEncoder *current_encoder,
                            std::vector<DrmEncoder *> &possible_encoders)
@@ -35,6 +40,7 @@
       encoder_(current_encoder),
       display_(-1),
       type_(c->connector_type),
+      type_id_(c->connector_type_id),
       state_(c->connection),
       mm_width_(c->mmWidth),
       mm_height_(c->mmHeight),
@@ -112,6 +118,22 @@
   return internal() || external() || writeback();
 }
 
+std::string DrmConnector::name() const {
+  constexpr std::array<const char *, TYPES_COUNT> names =
+      {"None",   "VGA",  "DVI-I",     "DVI-D",   "DVI-A", "Composite",
+       "SVIDEO", "LVDS", "Component", "DIN",     "DP",    "HDMI-A",
+       "HDMI-B", "TV",   "eDP",       "Virtual", "DSI"};
+
+  if (type_ < TYPES_COUNT) {
+    std::ostringstream name_buf;
+    name_buf << names[type_] << "-" << type_id_;
+    return name_buf.str();
+  } else {
+    ALOGE("Unknown type in connector %d, could not make his name", id_);
+    return "None";
+  }
+}
+
 int DrmConnector::UpdateModes() {
   int fd = drm_->fd();
 
diff --git a/drm/drmdevice.cpp b/drm/drmdevice.cpp
index 2007fdd..bcb9ddd 100644
--- a/drm/drmdevice.cpp
+++ b/drm/drmdevice.cpp
@@ -30,11 +30,91 @@
 #include <xf86drmMode.h>
 #include <cinttypes>
 
+#include <algorithm>
+#include <array>
+#include <string>
+
 #include <cutils/properties.h>
 #include <log/log.h>
 
+static void trim_left(std::string &str) {
+  str.erase(std::begin(str),
+            std::find_if(std::begin(str), std::end(str),
+                         [](int ch) { return !std::isspace(ch); }));
+}
+
+static void trim_right(std::string &str) {
+  str.erase(std::find_if(std::rbegin(str), std::rend(str),
+                         [](int ch) { return !std::isspace(ch); })
+                .base(),
+            std::end(str));
+}
+
+static void trim(std::string &str) {
+  trim_left(str);
+  trim_right(str);
+}
+
 namespace android {
 
+static std::vector<std::string> read_primary_display_order_prop() {
+  std::array<char, PROPERTY_VALUE_MAX> display_order_buf;
+  property_get("hwc.drm.primary_display_order", display_order_buf.data(),
+               "...");
+
+  std::vector<std::string> display_order;
+  std::istringstream str(display_order_buf.data());
+  for (std::string conn_name = ""; std::getline(str, conn_name, ',');) {
+    trim(conn_name);
+    display_order.push_back(std::move(conn_name));
+  }
+  return display_order;
+}
+
+static std::vector<DrmConnector *> make_primary_display_candidates(
+    std::vector<std::unique_ptr<DrmConnector>> &connectors) {
+  std::vector<DrmConnector *> primary_candidates;
+  std::transform(std::begin(connectors), std::end(connectors),
+                 std::back_inserter(primary_candidates),
+                 [](std::unique_ptr<DrmConnector> &conn) {
+                   return conn.get();
+                 });
+  primary_candidates.erase(std::remove_if(std::begin(primary_candidates),
+                                          std::end(primary_candidates),
+                                          [](const DrmConnector *conn) {
+                                            return conn->state() !=
+                                                   DRM_MODE_CONNECTED;
+                                          }),
+                           std::end(primary_candidates));
+
+  std::vector<std::string> display_order = read_primary_display_order_prop();
+  bool use_other = display_order.back() == "...";
+
+  // putting connectors from primary_display_order first
+  auto curr_connector = std::begin(primary_candidates);
+  for (const std::string &display_name : display_order) {
+    auto it = std::find_if(std::begin(primary_candidates),
+                           std::end(primary_candidates),
+                           [&display_name](const DrmConnector *conn) {
+                             return conn->name() == display_name;
+                           });
+    if (it != std::end(primary_candidates)) {
+      std::iter_swap(it, curr_connector);
+      ++curr_connector;
+    }
+  }
+
+  if (use_other) {
+    // then putting internal connectors second, everything else afterwards
+    std::partition(curr_connector, std::end(primary_candidates),
+                   [](const DrmConnector *conn) { return conn->internal(); });
+  } else {
+    primary_candidates.erase(curr_connector, std::end(primary_candidates));
+  }
+
+  return primary_candidates;
+}
+
 DrmDevice::DrmDevice() : event_listener_(this) {
 }
 
@@ -173,19 +253,26 @@
       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(num_displays);
-      displays_[num_displays] = num_displays;
-      ++num_displays;
-      found_primary = true;
-      break;
-    }
+  // Primary display priority:
+  // 1) hwc.drm.primary_display_order property
+  // 2) internal connectors
+  // 3) anything else
+  std::vector<DrmConnector *>
+      primary_candidates = make_primary_display_candidates(connectors_);
+  if (!primary_candidates.empty() && !found_primary) {
+    DrmConnector &conn = **std::begin(primary_candidates);
+    conn.set_display(num_displays);
+    displays_[num_displays] = num_displays;
+    ++num_displays;
+    found_primary = true;
+  } else {
+    ALOGE(
+        "Failed to find primary display from \"hwc.drm.primary_display_order\" "
+        "property");
   }
 
-  // Then pick first available as primary and for the others assign
-  // consecutive display_numbers.
+  // If no priority display were found then pick first available as primary and
+  // for the others assign consecutive display_numbers.
   for (auto &conn : connectors_) {
     if (conn->external() || conn->internal()) {
       if (!found_primary) {
diff --git a/drmhwctwo.cpp b/drmhwctwo.cpp
index 814d8f7..ffc5fcd 100644
--- a/drmhwctwo.cpp
+++ b/drmhwctwo.cpp
@@ -547,19 +547,25 @@
   return HWC2::Error::None;
 }
 
-void DrmHwcTwo::HwcDisplay::AddFenceToRetireFence(int fd) {
-  supported(__func__);
+void DrmHwcTwo::HwcDisplay::AddFenceToPresentFence(int fd) {
   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));
+  if (present_fence_.get() >= 0) {
+    int old_fence = present_fence_.get();
+    present_fence_.Set(sync_merge("dc_present", old_fence, fd));
+    close(fd);
   } else {
-    next_retire_fence_.Set(dup(fd));
+    present_fence_.Set(fd);
   }
 }
 
+bool DrmHwcTwo::HwcDisplay::HardwareSupportsLayerType(
+    HWC2::Composition comp_type) {
+  return comp_type == HWC2::Composition::Device ||
+         comp_type == HWC2::Composition::Cursor;
+}
+
 HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(bool test) {
   std::vector<DrmCompositionDisplayLayersMap> layers_map;
   layers_map.emplace_back();
@@ -573,17 +579,7 @@
   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();
-      if (comp_type == HWC2::Composition::Device) {
-        if (!importer_->CanImportBuffer(l.second.buffer()))
-          comp_type = HWC2::Composition::Client;
-      }
-    } else
-      comp_type = l.second.validated_type();
-
-    switch (comp_type) {
+    switch (l.second.validated_type()) {
       case HWC2::Composition::Device:
         z_map.emplace(std::make_pair(l.second.z_order(), &l.second));
         break;
@@ -646,8 +642,8 @@
   if (test) {
     ret = compositor_.TestComposition(composition.get());
   } else {
-    AddFenceToRetireFence(composition->take_out_fence());
     ret = compositor_.ApplyComposition(std::move(composition));
+    AddFenceToPresentFence(compositor_.TakeOutFence());
   }
   if (ret) {
     if (!test)
@@ -657,23 +653,20 @@
   return HWC2::Error::None;
 }
 
-HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) {
+HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *present_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;
+    *present_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_);
+  *present_fence = present_fence_.Release();
 
   ++frame_no_;
   return HWC2::Error::None;
@@ -798,22 +791,6 @@
   *num_types = 0;
   *num_requests = 0;
   size_t avail_planes = primary_planes_.size() + overlay_planes_.size();
-  bool comp_failed = false;
-
-  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)
-    comp_failed = true;
-
-  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
@@ -822,22 +799,29 @@
   if (avail_planes < layers_.size())
     avail_planes--;
 
+  std::map<uint32_t, DrmHwcTwo::HwcLayer *, std::greater<int>> z_map;
+  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_)
+    z_map.emplace(std::make_pair(l.second.z_order(), &l.second));
+
+  bool gpu_block = false;
   for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
-    if (comp_failed || !avail_planes--)
-      break;
-    if (importer_->CanImportBuffer(l.second->buffer()))
-      l.second->set_validated_type(HWC2::Composition::Device);
+    if (gpu_block || avail_planes == 0 ||
+        !HardwareSupportsLayerType(l.second->sf_type()) ||
+        !importer_->CanImportBuffer(l.second->buffer())) {
+      gpu_block = true;
+      ++*num_types;
+    } else {
+      avail_planes--;
+    }
+
+    l.second->set_validated_type(gpu_block ? HWC2::Composition::Client
+                                           : HWC2::Composition::Device);
   }
 
-  for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
-    DrmHwcTwo::HwcLayer &layer = l.second;
-    // We can only handle layers of Device type, send everything else to SF
-    if (layer.sf_type() != HWC2::Composition::Device ||
-        layer.validated_type() != HWC2::Composition::Device) {
-      layer.set_validated_type(HWC2::Composition::Client);
-      ++*num_types;
-    }
-  }
+  if (CreateComposition(true) != HWC2::Error::None)
+    for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_)
+      l.second.set_validated_type(HWC2::Composition::Client);
+
   return *num_types ? HWC2::Error::HasChanges : HWC2::Error::None;
 }
 
diff --git a/include/drmconnector.h b/include/drmconnector.h
index 9c526c8..c9fd7ab 100644
--- a/include/drmconnector.h
+++ b/include/drmconnector.h
@@ -23,6 +23,7 @@
 
 #include <stdint.h>
 #include <xf86drmMode.h>
+#include <string>
 #include <vector>
 
 namespace android {
@@ -49,6 +50,8 @@
   bool writeback() const;
   bool valid_type() const;
 
+  std::string name() const;
+
   int UpdateModes();
 
   const std::vector<DrmMode> &modes() const {
@@ -86,6 +89,7 @@
   int display_;
 
   uint32_t type_;
+  uint32_t type_id_;
   drmModeConnection state_;
 
   uint32_t mm_width_;
diff --git a/include/drmdisplaycompositor.h b/include/drmdisplaycompositor.h
index 1005598..477f226 100644
--- a/include/drmdisplaycompositor.h
+++ b/include/drmdisplaycompositor.h
@@ -56,6 +56,11 @@
   void Dump(std::ostringstream *out) const;
   void Vsync(int display, int64_t timestamp);
   void ClearDisplay();
+  int TakeOutFence() {
+    if (!active_composition_)
+      return -1;
+    return active_composition_->take_out_fence();
+  }
 
   std::tuple<uint32_t, uint32_t, int> GetActiveModeResolution();
 
diff --git a/include/drmhwcomposer.h b/include/drmhwcomposer.h
index 2af7e6e..69313d9 100644
--- a/include/drmhwcomposer.h
+++ b/include/drmhwcomposer.h
@@ -158,10 +158,6 @@
   }
 };
 
-struct DrmHwcDisplayContents {
-  OutputFd retire_fence;
-  std::vector<DrmHwcLayer> layers;
-};
 }  // namespace android
 
 #endif
diff --git a/include/drmhwctwo.h b/include/drmhwctwo.h
index 8c75fc0..c6ce640 100644
--- a/include/drmhwctwo.h
+++ b/include/drmhwctwo.h
@@ -172,7 +172,7 @@
                                    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 PresentDisplay(int32_t *present_fence);
     HWC2::Error SetActiveConfig(hwc2_config_t config);
     HWC2::Error ChosePreferredConfig();
     HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
@@ -192,7 +192,8 @@
 
    private:
     HWC2::Error CreateComposition(bool test);
-    void AddFenceToRetireFence(int fd);
+    void AddFenceToPresentFence(int fd);
+    bool HardwareSupportsLayerType(HWC2::Composition comp_type);
 
     ResourceManager *resource_manager_;
     DrmDevice *drm_;
@@ -211,8 +212,7 @@
     uint32_t layer_idx_ = 0;
     std::map<hwc2_layer_t, HwcLayer> layers_;
     HwcLayer client_layer_;
-    UniqueFd retire_fence_;
-    UniqueFd next_retire_fence_;
+    UniqueFd present_fence_;
     int32_t color_mode_;
 
     uint32_t frame_no_ = 0;
diff --git a/platform/platformdrmgeneric.cpp b/platform/platformdrmgeneric.cpp
index 9ac601f..0883b90 100644
--- a/platform/platformdrmgeneric.cpp
+++ b/platform/platformdrmgeneric.cpp
@@ -20,7 +20,6 @@
 #include "drmdevice.h"
 #include "platform.h"
 
-#include <drm/drm_fourcc.h>
 #include <xf86drm.h>
 #include <xf86drmMode.h>
 
@@ -89,7 +88,7 @@
       return DRM_FORMAT_YVU420;
     default:
       ALOGE("Cannot convert hal format to drm format %u", hal_format);
-      return -EINVAL;
+      return DRM_FORMAT_INVALID;
   }
 }
 
@@ -128,6 +127,8 @@
   bo->height = gr_handle->height;
   bo->hal_format = gr_handle->format;
   bo->format = ConvertHalFormatToDrm(gr_handle->format);
+  if (bo->format == DRM_FORMAT_INVALID)
+    return -EINVAL;
   bo->usage = gr_handle->usage;
   bo->pixel_stride = (gr_handle->stride * 8) /
                      DrmFormatToBitsPerPixel(bo->format);
diff --git a/platform/platformdrmgeneric.h b/platform/platformdrmgeneric.h
index 88bff5f..7bb2ea2 100644
--- a/platform/platformdrmgeneric.h
+++ b/platform/platformdrmgeneric.h
@@ -22,6 +22,12 @@
 
 #include <hardware/gralloc.h>
 
+#include <drm/drm_fourcc.h>
+
+#ifndef DRM_FORMAT_INVALID
+#define DRM_FORMAT_INVALID 0
+#endif
+
 namespace android {
 
 class DrmGenericImporter : public Importer {
diff --git a/platform/platformhisi.cpp b/platform/platformhisi.cpp
index 64b410b..2e6ac43 100644
--- a/platform/platformhisi.cpp
+++ b/platform/platformhisi.cpp
@@ -20,7 +20,6 @@
 #include "drmdevice.h"
 #include "platform.h"
 
-#include <drm/drm_fourcc.h>
 #include <stdatomic.h>
 #include <xf86drm.h>
 #include <xf86drmMode.h>
@@ -121,9 +120,9 @@
     return ret;
   }
 
-  int32_t fmt = ConvertHalFormatToDrm(hnd->req_format);
-  if (fmt < 0)
-    return fmt;
+  uint32_t fmt = ConvertHalFormatToDrm(hnd->req_format);
+  if (fmt == DRM_FORMAT_INVALID)
+    return -EINVAL;
 
   is_rgb = IsDrmFormatRgb(fmt);
   modifiers[0] = ConvertGrallocFormatToDrmModifiers(hnd->internal_format,
diff --git a/platform/platformimagination.cpp b/platform/platformimagination.cpp
new file mode 100644
index 0000000..565e6ee
--- /dev/null
+++ b/platform/platformimagination.cpp
@@ -0,0 +1,80 @@
+#define LOG_TAG "hwc-platform-imagination"
+
+#include "platformimagination.h"
+#include <log/log.h>
+#include <xf86drm.h>
+
+#include "img_gralloc1_public.h"
+
+namespace android {
+
+Importer *Importer::CreateInstance(DrmDevice *drm) {
+  ImaginationImporter *importer = new ImaginationImporter(drm);
+  if (!importer)
+    return NULL;
+
+  int ret = importer->Init();
+  if (ret) {
+    ALOGE("Failed to initialize the Imagination importer %d", ret);
+    delete importer;
+    return NULL;
+  }
+  return importer;
+}
+
+int ImaginationImporter::ImportBuffer(buffer_handle_t handle,
+                                      hwc_drm_bo_t *bo) {
+  IMG_native_handle_t *hnd = (IMG_native_handle_t *)handle;
+  if (!hnd)
+    return -EINVAL;
+
+  uint32_t gem_handle;
+  int ret = drmPrimeFDToHandle(drm_->fd(), hnd->fd[0], &gem_handle);
+  if (ret) {
+    ALOGE("failed to import prime fd %d ret=%d", hnd->fd[0], ret);
+    return ret;
+  }
+
+  /* Extra bits are responsible for buffer compression and memory layout */
+  if (hnd->iFormat & ~0x10f) {
+    ALOGE("Special buffer formats are not supported");
+    return -EINVAL;
+  }
+
+  memset(bo, 0, sizeof(hwc_drm_bo_t));
+  bo->width = hnd->iWidth;
+  bo->height = hnd->iHeight;
+  bo->usage = hnd->usage;
+  bo->gem_handles[0] = gem_handle;
+  bo->pitches[0] = ALIGN(hnd->iWidth, HW_ALIGN) * hnd->uiBpp >> 3;
+
+  switch (hnd->iFormat) {
+#ifdef HAL_PIXEL_FORMAT_BGRX_8888
+    case HAL_PIXEL_FORMAT_BGRX_8888:
+      bo->format = DRM_FORMAT_XRGB8888;
+      break;
+#endif
+    default:
+      bo->format = ConvertHalFormatToDrm(hnd->iFormat & 0xf);
+      if (bo->format == DRM_FORMAT_INVALID) {
+        ALOGE("Cannot convert hal format to drm format %u", hnd->iFormat);
+        return -EINVAL;
+      }
+  }
+
+  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 ret: %d", ret);
+    return ret;
+  }
+
+  return 0;
+}
+
+std::unique_ptr<Planner> Planner::CreateInstance(DrmDevice *) {
+  std::unique_ptr<Planner> planner(new Planner);
+  planner->AddStage<PlanStageGreedy>();
+  return planner;
+}
+}  // namespace android
diff --git a/platform/platformimagination.h b/platform/platformimagination.h
new file mode 100644
index 0000000..85dfc45
--- /dev/null
+++ b/platform/platformimagination.h
@@ -0,0 +1,22 @@
+#ifndef PLATFORMIMAGINATION_H
+#define PLATFORMIMAGINATION_H
+
+#include "drmdevice.h"
+#include "platform.h"
+#include "platformdrmgeneric.h"
+
+#include <stdatomic.h>
+
+#include <hardware/gralloc.h>
+
+namespace android {
+
+class ImaginationImporter : public DrmGenericImporter {
+ public:
+  using DrmGenericImporter::DrmGenericImporter;
+
+  int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
+};
+}  // namespace android
+
+#endif  // PLATFORMIMAGINATION_H
diff --git a/platform/platformmeson.cpp b/platform/platformmeson.cpp
index 7bde5cd..5184972 100644
--- a/platform/platformmeson.cpp
+++ b/platform/platformmeson.cpp
@@ -20,7 +20,6 @@
 #include "drmdevice.h"
 #include "platform.h"
 
-#include <drm/drm_fourcc.h>
 #include <stdatomic.h>
 #include <xf86drm.h>
 #include <xf86drmMode.h>
@@ -98,9 +97,9 @@
     return ret;
   }
 
-  int32_t fmt = ConvertHalFormatToDrm(hnd->req_format);
-  if (fmt < 0)
-    return fmt;
+  uint32_t fmt = ConvertHalFormatToDrm(hnd->req_format);
+  if (fmt == DRM_FORMAT_INVALID)
+    return -EINVAL;
 
   modifiers[0] = ConvertGrallocFormatToDrmModifiers(hnd->internal_format);
 
diff --git a/platform/platformminigbm.cpp b/platform/platformminigbm.cpp
index ad0a373..a65e196 100644
--- a/platform/platformminigbm.cpp
+++ b/platform/platformminigbm.cpp
@@ -20,7 +20,6 @@
 #include "drmdevice.h"
 #include "platform.h"
 
-#include <drm/drm_fourcc.h>
 #include <xf86drm.h>
 #include <xf86drmMode.h>