OSDN Git Service

drm_hwcomposer: Do not close duplicate gem handles in nvimporter
[android-x86/external-drm_hwcomposer.git] / drmcompositor.cpp
index bf95601..b486d7b 100644 (file)
 #define LOG_TAG "hwc-drm-compositor"
 
 #include "drmcompositor.h"
-#include "drmcrtc.h"
-#include "drmplane.h"
+#include "drmdisplaycompositor.h"
 #include "drmresources.h"
 
-#include <pthread.h>
 #include <sstream>
 #include <stdlib.h>
-#include <time.h>
 
 #include <cutils/log.h>
-#include <sync/sync.h>
 
 namespace android {
 
-DrmCompositor::DrmCompositor(DrmResources *drm)
-    : drm_(drm),
-      worker_(this),
-      active_composition_(NULL),
-      frame_no_(0),
-      initialized_(false),
-      dump_frames_composited_(0),
-      dump_last_timestamp_ns_(0) {
-  struct timespec ts;
-  if (clock_gettime(CLOCK_MONOTONIC, &ts))
-    return;
-  dump_last_timestamp_ns_ = ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec;
+DrmCompositor::DrmCompositor(DrmResources *drm) : drm_(drm), frame_no_(0) {
 }
 
 DrmCompositor::~DrmCompositor() {
-  if (initialized_)
-    pthread_mutex_destroy(&lock_);
 }
 
 int DrmCompositor::Init() {
-  int ret = pthread_mutex_init(&lock_, NULL);
-  if (ret) {
-    ALOGE("Failed to initialize drm compositor lock %d\n", ret);
-    return ret;
-  }
-  ret = worker_.Init();
-  if (ret) {
-    pthread_mutex_destroy(&lock_);
-    ALOGE("Failed to initialize compositor worker %d\n", ret);
-    return ret;
+  for (DrmResources::ConnectorIter iter = drm_->begin_connectors();
+       iter != drm_->end_connectors(); ++iter) {
+    int display = (*iter)->display();
+    int ret = compositor_map_[display].Init(drm_, display);
+    if (ret) {
+      ALOGE("Failed to initialize display compositor for %d", display);
+      return ret;
+    }
   }
 
-  initialized_ = true;
   return 0;
 }
 
-Composition *DrmCompositor::CreateComposition(Importer *importer) {
-  DrmComposition *composition = new DrmComposition(drm_, importer, frame_no_++);
+DrmComposition *DrmCompositor::CreateComposition(Importer *importer) {
+  DrmComposition *composition = new DrmComposition(drm_, importer);
   if (!composition) {
     ALOGE("Failed to allocate drm composition");
     return NULL;
   }
-  int ret = composition->Init();
+  int ret = composition->Init(++frame_no_);
   if (ret) {
     ALOGE("Failed to initialize drm composition %d", ret);
     delete composition;
@@ -82,225 +62,41 @@ Composition *DrmCompositor::CreateComposition(Importer *importer) {
   return composition;
 }
 
-int DrmCompositor::QueueComposition(Composition *composition) {
-  int ret = pthread_mutex_lock(&lock_);
+int DrmCompositor::QueueComposition(
+    std::unique_ptr<DrmComposition> composition) {
+  int ret = composition->DisableUnusedPlanes();
   if (ret) {
-    ALOGE("Failed to acquire compositor lock %d", ret);
+    ALOGE("Failed to disable unused planes %d", ret);
     return ret;
   }
 
-  composite_queue_.push((DrmComposition *)composition);
-
-  ret = pthread_mutex_unlock(&lock_);
-  if (ret) {
-    ALOGE("Failed to release compositor lock %d", ret);
-    return ret;
-  }
-
-  worker_.Signal();
-  return 0;
-}
-
-int DrmCompositor::PerformModeset(DrmCompositionLayerMap_t::iterator begin,
-                                  DrmCompositionLayerMap_t::iterator end) {
-  DrmCompositionLayer *layer = NULL;
-  for (DrmCompositionLayerMap_t::iterator iter = begin; iter != end; ++iter) {
-    if (iter->second.layer.compositionType == HWC_FRAMEBUFFER_TARGET) {
-      layer = &iter->second;
-      break;
-    }
-  }
-  int display = begin->first;
-  if (!layer) {
-    ALOGE("Could not find target framebuffer for display %d", display);
-    return -ENOENT;
-  }
-
-  drmModeModeInfo m;
-  DrmConnector *connector = drm_->GetConnectorForDisplay(display);
-  connector->active_mode().ToModeModeInfo(&m);
-
-  uint32_t connectors = connector->id();
-  int ret = drmModeSetCrtc(drm_->fd(), layer->crtc->id(), layer->bo.fb_id, 0, 0,
-                           &connectors, 1, &m);
-  if (ret)
-    ALOGE("Failed set crtc for disp %d/%d", display, ret);
-  else
-    layer->crtc->set_requires_modeset(false);
-
-  return ret;
-}
-
-int DrmCompositor::CompositeDisplay(DrmCompositionLayerMap_t::iterator begin,
-                                    DrmCompositionLayerMap_t::iterator end) {
-  int ret = 0;
-  // Wait for all acquire fences to signal
-  for (DrmCompositionLayerMap_t::iterator iter = begin; iter != end; ++iter) {
-    hwc_layer_1_t *layer = &iter->second.layer;
-
-    if (layer->acquireFenceFd < 0)
-      continue;
-
-    ret = sync_wait(layer->acquireFenceFd, -1);
-    if (ret) {
-      ALOGE("Failed to wait for acquire %d/%d", layer->acquireFenceFd, ret);
-      return ret;
-    }
-    close(layer->acquireFenceFd);
-    layer->acquireFenceFd = -1;
-  }
-
-  DrmCrtc *crtc = begin->second.crtc;
-  if (crtc->requires_modeset()) {
-    ret = PerformModeset(begin, end);
-    if (ret)
-      ALOGE("Failed modeset on display %d", begin->first);
-    return ret;
-  }
-
-  drmModePropertySetPtr pset = drmModePropertySetAlloc();
-  if (!pset) {
-    ALOGE("Failed to allocate property set");
-    return -ENOMEM;
-  }
-
-  for (DrmCompositionLayerMap_t::iterator iter = begin; iter != end; ++iter) {
-    DrmCompositionLayer_t *comp = &iter->second;
-    hwc_layer_1_t *layer = &comp->layer;
-    DrmPlane *plane = comp->plane;
-
-    ret =
-        drmModePropertySetAdd(pset, plane->id(), plane->crtc_property().id(),
-                              crtc->id()) ||
-        drmModePropertySetAdd(pset, plane->id(), plane->fb_property().id(),
-                              comp->bo.fb_id) ||
-        drmModePropertySetAdd(pset, plane->id(), plane->crtc_x_property().id(),
-                              layer->displayFrame.left) ||
-        drmModePropertySetAdd(pset, plane->id(), plane->crtc_y_property().id(),
-                              layer->displayFrame.top) ||
-        drmModePropertySetAdd(
-            pset, plane->id(), plane->crtc_w_property().id(),
-            layer->displayFrame.right - layer->displayFrame.left) ||
-        drmModePropertySetAdd(
-            pset, plane->id(), plane->crtc_h_property().id(),
-            layer->displayFrame.bottom - layer->displayFrame.top) ||
-        drmModePropertySetAdd(pset, plane->id(), plane->src_x_property().id(),
-                              layer->sourceCropf.left) ||
-        drmModePropertySetAdd(pset, plane->id(), plane->src_y_property().id(),
-                              layer->sourceCropf.top) ||
-        drmModePropertySetAdd(
-            pset, plane->id(), plane->src_w_property().id(),
-            (int)(layer->sourceCropf.right - layer->sourceCropf.left) << 16) ||
-        drmModePropertySetAdd(
-            pset, plane->id(), plane->src_h_property().id(),
-            (int)(layer->sourceCropf.bottom - layer->sourceCropf.top) << 16);
-    if (ret) {
-      ALOGE("Failed to add plane %d to set", plane->id());
-      break;
-    }
-  }
-
-  if (!ret) {
-    ret = drmModePropertySetCommit(drm_->fd(), 0, drm_, pset);
-    if (ret)
-      ALOGE("Failed to commit pset ret=%d\n", ret);
-  }
-  if (pset)
-    drmModePropertySetFree(pset);
-
-  return ret;
-}
-
-int DrmCompositor::Composite() {
-  int ret = pthread_mutex_lock(&lock_);
-  if (ret) {
-    ALOGE("Failed to acquire compositor lock %d", ret);
-    return ret;
-  }
-  if (composite_queue_.empty()) {
-    ret = pthread_mutex_unlock(&lock_);
-    if (ret)
-      ALOGE("Failed to release compositor lock %d", ret);
-    return ret;
-  }
-
-  DrmComposition *composition = composite_queue_.front();
-  composite_queue_.pop();
-  ++dump_frames_composited_;
-
-  ret = pthread_mutex_unlock(&lock_);
-  if (ret) {
-    ALOGE("Failed to release compositor lock %d", ret);
-    return ret;
-  }
-
-  DrmCompositionLayerMap_t *map = composition->GetCompositionMap();
   for (DrmResources::ConnectorIter iter = drm_->begin_connectors();
        iter != drm_->end_connectors(); ++iter) {
     int display = (*iter)->display();
-    std::pair<DrmCompositionLayerMap_t::iterator,
-              DrmCompositionLayerMap_t::iterator> layer_iters =
-        map->equal_range(display);
-
-    if (layer_iters.first != layer_iters.second) {
-      ret = CompositeDisplay(layer_iters.first, layer_iters.second);
-      if (ret) {
-        ALOGE("Composite failed for display %d:", display);
-        break;
-      }
+    int ret = compositor_map_[display].QueueComposition(
+        composition->TakeDisplayComposition(display));
+    if (ret) {
+      ALOGE("Failed to queue composition for display %d (%d)", display, ret);
+      return ret;
     }
   }
 
-  if (active_composition_) {
-    active_composition_->FinishComposition();
-    delete active_composition_;
-  }
-  active_composition_ = composition;
-  return ret;
+  return 0;
 }
 
-bool DrmCompositor::HaveQueuedComposites() const {
-  int ret = pthread_mutex_lock(&lock_);
-  if (ret) {
-    ALOGE("Failed to acquire compositor lock %d", ret);
-    return false;
-  }
-
-  bool empty_ret = !composite_queue_.empty();
-
-  ret = pthread_mutex_unlock(&lock_);
-  if (ret) {
-    ALOGE("Failed to release compositor lock %d", ret);
-    return false;
-  }
-
-  return empty_ret;
+int DrmCompositor::Composite() {
+  /*
+   * This shouldn't be called, we should be calling Composite() on the display
+   * compositors directly.
+   */
+  ALOGE("Calling base drm compositor Composite() function");
+  return -EINVAL;
 }
 
 void DrmCompositor::Dump(std::ostringstream *out) const {
-  uint64_t cur_ts;
-
-  int ret = pthread_mutex_lock(&lock_);
-  if (ret)
-    return;
-
-  uint64_t num_frames = dump_frames_composited_;
-  dump_frames_composited_ = 0;
-
-  struct timespec ts;
-  ret = clock_gettime(CLOCK_MONOTONIC, &ts);
-
-  ret |= pthread_mutex_unlock(&lock_);
-  if (ret)
-    return;
-
-  cur_ts = ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec;
-  uint64_t num_ms = (cur_ts - dump_last_timestamp_ns_) / (1000 * 1000);
-  unsigned fps = num_ms ? (num_frames * 1000) / (num_ms) : 0;
-
-  *out << "DrmCompositor: num_frames=" << num_frames << " num_ms=" << num_ms <<
-          " fps=" << fps << "\n";
-
-  dump_last_timestamp_ns_ = cur_ts;
+  *out << "DrmCompositor stats:\n";
+  for (DrmResources::ConnectorIter iter = drm_->begin_connectors();
+       iter != drm_->end_connectors(); ++iter)
+    compositor_map_[(*iter)->display()].Dump(out);
 }
 }