Home | History | Annotate | Download | only in drm_hwcomposer
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "hwc-drm-display-composition"
     18 
     19 #include "drmdisplaycomposition.h"
     20 #include "drmcrtc.h"
     21 #include "drmplane.h"
     22 #include "drmresources.h"
     23 
     24 #include <stdlib.h>
     25 
     26 #include <cutils/log.h>
     27 #include <sw_sync.h>
     28 #include <sync/sync.h>
     29 #include <xf86drmMode.h>
     30 
     31 namespace android {
     32 
     33 DrmCompositionLayer::DrmCompositionLayer() : crtc(NULL), plane(NULL) {
     34   memset(&layer, 0, sizeof(layer));
     35   layer.acquireFenceFd = -1;
     36   memset(&bo, 0, sizeof(bo));
     37 }
     38 
     39 DrmCompositionLayer::~DrmCompositionLayer() {
     40 }
     41 
     42 DrmDisplayComposition::DrmDisplayComposition()
     43     : drm_(NULL),
     44       importer_(NULL),
     45       type_(DRM_COMPOSITION_TYPE_EMPTY),
     46       timeline_fd_(-1),
     47       timeline_(0),
     48       dpms_mode_(DRM_MODE_DPMS_ON) {
     49 }
     50 
     51 DrmDisplayComposition::~DrmDisplayComposition() {
     52   for (DrmCompositionLayerVector_t::iterator iter = layers_.begin();
     53        iter != layers_.end(); ++iter) {
     54     if (importer_)
     55       importer_->ReleaseBuffer(&iter->bo);
     56 
     57     if (iter->layer.acquireFenceFd >= 0)
     58       close(iter->layer.acquireFenceFd);
     59   }
     60 
     61   if (timeline_fd_ >= 0)
     62     close(timeline_fd_);
     63 }
     64 
     65 int DrmDisplayComposition::Init(DrmResources *drm, Importer *importer) {
     66   drm_ = drm;
     67   importer_ = importer;
     68 
     69   int ret = sw_sync_timeline_create();
     70   if (ret < 0) {
     71     ALOGE("Failed to create sw sync timeline %d", ret);
     72     return ret;
     73   }
     74   timeline_fd_ = ret;
     75   return 0;
     76 }
     77 
     78 DrmCompositionType DrmDisplayComposition::type() const {
     79   return type_;
     80 }
     81 
     82 bool DrmDisplayComposition::validate_composition_type(DrmCompositionType des) {
     83   return type_ == DRM_COMPOSITION_TYPE_EMPTY || type_ == des;
     84 }
     85 
     86 int DrmDisplayComposition::AddLayer(hwc_layer_1_t *layer, hwc_drm_bo_t *bo,
     87                                     DrmCrtc *crtc, DrmPlane *plane) {
     88   if (layer->transform != 0)
     89     return -EINVAL;
     90 
     91   if (!validate_composition_type(DRM_COMPOSITION_TYPE_FRAME))
     92     return -EINVAL;
     93 
     94   ++timeline_;
     95   layer->releaseFenceFd =
     96       sw_sync_fence_create(timeline_fd_, "drm_fence", timeline_);
     97   if (layer->releaseFenceFd < 0) {
     98     ALOGE("Could not create release fence %d", layer->releaseFenceFd);
     99     return layer->releaseFenceFd;
    100   }
    101 
    102   DrmCompositionLayer_t c_layer;
    103   c_layer.layer = *layer;
    104   c_layer.bo = *bo;
    105   c_layer.crtc = crtc;
    106   c_layer.plane = plane;
    107 
    108   layer->acquireFenceFd = -1;  // We own this now
    109   layers_.push_back(c_layer);
    110   type_ = DRM_COMPOSITION_TYPE_FRAME;
    111   return 0;
    112 }
    113 
    114 int DrmDisplayComposition::AddDpmsMode(uint32_t dpms_mode) {
    115   if (!validate_composition_type(DRM_COMPOSITION_TYPE_DPMS))
    116     return -EINVAL;
    117   dpms_mode_ = dpms_mode;
    118   type_ = DRM_COMPOSITION_TYPE_DPMS;
    119   return 0;
    120 }
    121 
    122 int DrmDisplayComposition::FinishComposition() {
    123   int ret = sw_sync_timeline_inc(timeline_fd_, timeline_);
    124   if (ret)
    125     ALOGE("Failed to increment sync timeline %d", ret);
    126 
    127   return ret;
    128 }
    129 
    130 DrmCompositionLayerVector_t *DrmDisplayComposition::GetCompositionLayers() {
    131   return &layers_;
    132 }
    133 
    134 uint32_t DrmDisplayComposition::dpms_mode() const {
    135   return dpms_mode_;
    136 }
    137 }
    138