OSDN Git Service

drm_hwcomposer: Remove hwc.drm.use_framebuffer_target property
[android-x86/external-drm_hwcomposer.git] / drmcomposition.cpp
index 07e08da..09bdba7 100644 (file)
 #include <stdlib.h>
 
 #include <cutils/log.h>
+#include <cutils/properties.h>
 #include <sw_sync.h>
 #include <sync/sync.h>
 
 namespace android {
 
-static const bool kUseOverlayPlanes = true;
+DrmComposition::DrmComposition(DrmResources *drm, Importer *importer)
+    : drm_(drm), importer_(importer) {
+  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);
 
-DrmCompositionLayer::DrmCompositionLayer() : crtc(NULL), plane(NULL) {
-  memset(&layer, 0, sizeof(layer));
-  layer.acquireFenceFd = -1;
-  memset(&bo, 0, sizeof(bo));
-}
-
-DrmCompositionLayer::~DrmCompositionLayer() {
-}
-
-DrmComposition::DrmComposition(DrmResources *drm, Importer *importer,
-                               uint64_t frame_no)
-    : drm_(drm),
-      importer_(importer),
-      frame_no_(frame_no),
-      timeline_fd_(-1),
-      timeline_(0) {
   for (DrmResources::PlaneIter iter = drm_->begin_planes();
        iter != drm_->end_planes(); ++iter) {
     if ((*iter)->type() == DRM_PLANE_TYPE_PRIMARY)
       primary_planes_.push_back(*iter);
-    else if (kUseOverlayPlanes && (*iter)->type() == DRM_PLANE_TYPE_OVERLAY)
+    else if (use_overlay_planes && (*iter)->type() == DRM_PLANE_TYPE_OVERLAY)
       overlay_planes_.push_back(*iter);
   }
 }
 
-DrmComposition::~DrmComposition() {
-  for (DrmCompositionLayerMap_t::iterator iter = composition_map_.begin();
-       iter != composition_map_.end(); ++iter) {
-    importer_->ReleaseBuffer(&iter->second.bo);
-
-    if (iter->second.layer.acquireFenceFd >= 0)
-      close(iter->second.layer.acquireFenceFd);
-  }
+int DrmComposition::Init(uint64_t frame_no) {
+  for (DrmResources::ConnectorIter iter = drm_->begin_connectors();
+       iter != drm_->end_connectors(); ++iter) {
+    int display = (*iter)->display();
+    composition_map_[display].reset(new DrmDisplayComposition());
+    if (!composition_map_[display]) {
+      ALOGE("Failed to allocate new display composition\n");
+      return -ENOMEM;
+    }
 
-  if (timeline_fd_ >= 0)
-    close(timeline_fd_);
-}
+    // If the display hasn't been modeset yet, this will be NULL
+    DrmCrtc *crtc = drm_->GetCrtcForDisplay(display);
 
-int DrmComposition::Init() {
-  int ret = sw_sync_timeline_create();
-  if (ret < 0) {
-    ALOGE("Failed to create sw sync timeline %d", ret);
-    return ret;
+    int ret = composition_map_[display]->Init(drm_, crtc, importer_, frame_no);
+    if (ret) {
+      ALOGE("Failed to init display composition for %d", display);
+      return ret;
+    }
   }
-  timeline_fd_ = ret;
   return 0;
 }
 
-unsigned DrmComposition::GetRemainingLayers(int display,
-                                            unsigned num_needed) const {
-  DrmCrtc *crtc = drm_->GetCrtcForDisplay(display);
-  if (!crtc) {
-    ALOGW("Failed to find crtc for display %d", display);
-    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;
+    }
 
-  unsigned num_planes = 0;
-  for (std::vector<DrmPlane *>::const_iterator iter = primary_planes_.begin();
-       iter != primary_planes_.end(); ++iter) {
-    if ((*iter)->GetCrtcSupported(*crtc))
-      ++num_planes;
+    ret = composition_map_[display]->SetLayers(map.layers.data(),
+                                               map.layers.size());
+    if (ret)
+      return ret;
   }
-  for (std::deque<DrmPlane *>::const_iterator iter = overlay_planes_.begin();
-       iter != overlay_planes_.end(); ++iter) {
-    if ((*iter)->GetCrtcSupported(*crtc))
-      ++num_planes;
-  }
-  return std::min(num_planes, num_needed);
+
+  return 0;
 }
 
-int DrmComposition::AddLayer(int display, hwc_layer_1_t *layer,
-                             hwc_drm_bo *bo) {
-  if (layer->transform != 0)
-    return -EINVAL;
+int DrmComposition::SetDpmsMode(int display, uint32_t dpms_mode) {
+  return composition_map_[display]->SetDpmsMode(dpms_mode);
+}
 
-  DrmCrtc *crtc = drm_->GetCrtcForDisplay(display);
-  if (!crtc) {
-    ALOGE("Could not find crtc for display %d", display);
-    return -ENODEV;
-  }
+int DrmComposition::SetDisplayMode(int display, const DrmMode &display_mode) {
+  return composition_map_[display]->SetDisplayMode(display_mode);
+}
 
-  ++timeline_;
-  layer->releaseFenceFd =
-      sw_sync_fence_create(timeline_fd_, "drm_fence", timeline_);
-  if (layer->releaseFenceFd < 0) {
-    ALOGE("Could not create release fence %d", layer->releaseFenceFd);
-    return layer->releaseFenceFd;
-  }
+std::unique_ptr<DrmDisplayComposition> DrmComposition::TakeDisplayComposition(
+    int display) {
+  return std::move(composition_map_[display]);
+}
 
-  DrmCompositionLayer_t c_layer;
-  c_layer.layer = *layer;
-  c_layer.bo = *bo;
-  c_layer.crtc = crtc;
-
-  // First try to find a primary plane for the layer, then fallback on overlays
-  for (std::vector<DrmPlane *>::iterator iter = primary_planes_.begin();
-       iter != primary_planes_.end(); ++iter) {
-    if ((*iter)->GetCrtcSupported(*crtc)) {
-      c_layer.plane = (*iter);
-      primary_planes_.erase(iter);
-      break;
-    }
-  }
-  for (std::deque<DrmPlane *>::iterator iter = overlay_planes_.begin();
-       !c_layer.plane && iter != overlay_planes_.end(); ++iter) {
-    if ((*iter)->GetCrtcSupported(*crtc)) {
-      c_layer.plane = (*iter);
-      overlay_planes_.erase(iter);
-      break;
+int DrmComposition::Plan(std::map<int, DrmDisplayCompositor> &compositor_map) {
+  int ret = 0;
+  for (DrmResources::ConnectorIter iter = drm_->begin_connectors();
+       iter != drm_->end_connectors(); ++iter) {
+    int display = (*iter)->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;
     }
   }
-  if (!c_layer.plane) {
-    close(layer->releaseFenceFd);
-    layer->releaseFenceFd = -1;
-    return -ENOENT;
-  }
 
-  layer->acquireFenceFd = -1;  // We own this now
-  composition_map_.insert(DrmCompositionLayerPair_t(display, c_layer));
   return 0;
 }
 
-int DrmComposition::FinishComposition() {
-  int ret = sw_sync_timeline_inc(timeline_fd_, timeline_);
-  if (ret)
-    ALOGE("Failed to increment sync timeline %d", ret);
+int DrmComposition::DisableUnusedPlanes() {
+  for (DrmResources::ConnectorIter iter = drm_->begin_connectors();
+       iter != drm_->end_connectors(); ++iter) {
+    int display = (*iter)->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;
+    }
 
-  return ret;
+    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;
 }
 
-DrmCompositionLayerMap_t *DrmComposition::GetCompositionMap() {
-  return &composition_map_;
+DrmDisplayComposition *DrmComposition::GetDisplayComposition(int display) {
+  return composition_map_[display].get();
 }
 }