1b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul/*
2b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul * Copyright (C) 2015 The Android Open Source Project
3b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul *
4b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul * Licensed under the Apache License, Version 2.0 (the "License");
5b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul * you may not use this file except in compliance with the License.
6b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul * You may obtain a copy of the License at
7b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul *
8b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul *      http://www.apache.org/licenses/LICENSE-2.0
9b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul *
10b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul * Unless required by applicable law or agreed to in writing, software
11b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul * distributed under the License is distributed on an "AS IS" BASIS,
12b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul * See the License for the specific language governing permissions and
14b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul * limitations under the License.
15b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul */
16b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul
17b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul#define LOG_TAG "hwc-drm-composition"
18b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul
19b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul#include "drmcomposition.h"
20b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul#include "drmcrtc.h"
21b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul#include "drmplane.h"
22b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul#include "drmresources.h"
23b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul
24b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul#include <stdlib.h>
25b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul
26b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul#include <cutils/log.h>
271946fa79833304216f7d8997250f6c6a7092cae4Zach Reizner#include <cutils/properties.h>
28b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul#include <sw_sync.h>
29b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul#include <sync/sync.h>
30b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul
31b386f1b1b3716c06831d82493e9ba5a156094701Sean Paulnamespace android {
32b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul
3398e73c89a683a92f44c99fb8dc85e51bdda243baSean PaulDrmComposition::DrmComposition(DrmResources *drm, Importer *importer)
3498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul    : drm_(drm), importer_(importer) {
351946fa79833304216f7d8997250f6c6a7092cae4Zach Reizner  char use_overlay_planes_prop[PROPERTY_VALUE_MAX];
361946fa79833304216f7d8997250f6c6a7092cae4Zach Reizner  property_get("hwc.drm.use_overlay_planes", use_overlay_planes_prop, "1");
371946fa79833304216f7d8997250f6c6a7092cae4Zach Reizner  bool use_overlay_planes = atoi(use_overlay_planes_prop);
381946fa79833304216f7d8997250f6c6a7092cae4Zach Reizner
39b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul  for (DrmResources::PlaneIter iter = drm_->begin_planes();
40b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul       iter != drm_->end_planes(); ++iter) {
41b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul    if ((*iter)->type() == DRM_PLANE_TYPE_PRIMARY)
42b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul      primary_planes_.push_back(*iter);
431946fa79833304216f7d8997250f6c6a7092cae4Zach Reizner    else if (use_overlay_planes && (*iter)->type() == DRM_PLANE_TYPE_OVERLAY)
44b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul      overlay_planes_.push_back(*iter);
45b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul  }
46b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul}
47b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul
48bdc67bffcffaa838836b1111f6dcf07cba5ff134Sean Paulint DrmComposition::Init(uint64_t frame_no) {
4998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul  for (DrmResources::ConnectorIter iter = drm_->begin_connectors();
5098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul       iter != drm_->end_connectors(); ++iter) {
5198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul    int display = (*iter)->display();
5298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul    composition_map_[display].reset(new DrmDisplayComposition());
5398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul    if (!composition_map_[display]) {
5498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul      ALOGE("Failed to allocate new display composition\n");
5598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul      return -ENOMEM;
5698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul    }
572143d3bc9da37525cacd432cd51b6e4f459c47a2Sean Paul
582143d3bc9da37525cacd432cd51b6e4f459c47a2Sean Paul    // If the display hasn't been modeset yet, this will be NULL
59098070590ae648ede5f2ef846298de178ccd3637Zach Reizner    DrmCrtc *crtc = drm_->GetCrtcForDisplay(display);
602143d3bc9da37525cacd432cd51b6e4f459c47a2Sean Paul
617e88be90cf44838fd183ee3d4981c19d7171e501Zach Reizner    int ret = composition_map_[display]->Init(drm_, crtc, importer_, frame_no);
6298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul    if (ret) {
637e88be90cf44838fd183ee3d4981c19d7171e501Zach Reizner      ALOGE("Failed to init display composition for %d", display);
6498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul      return ret;
6598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul    }
66b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul  }
67b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul  return 0;
68b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul}
69b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul
70098070590ae648ede5f2ef846298de178ccd3637Zach Reiznerint DrmComposition::SetLayers(size_t num_displays,
714a253659cef3d82bfb0b25b3ff4c7b073d7a0460Zach Reizner                              DrmCompositionDisplayLayersMap *maps) {
72098070590ae648ede5f2ef846298de178ccd3637Zach Reizner  int ret = 0;
73098070590ae648ede5f2ef846298de178ccd3637Zach Reizner  for (size_t display_index = 0; display_index < num_displays;
74098070590ae648ede5f2ef846298de178ccd3637Zach Reizner       display_index++) {
754a253659cef3d82bfb0b25b3ff4c7b073d7a0460Zach Reizner    DrmCompositionDisplayLayersMap &map = maps[display_index];
76098070590ae648ede5f2ef846298de178ccd3637Zach Reizner    int display = map.display;
77098070590ae648ede5f2ef846298de178ccd3637Zach Reizner
78c0b35480d6fa2bddd69a1c0255f307203c160788Sean Paul    if (!drm_->GetConnectorForDisplay(display)) {
79c0b35480d6fa2bddd69a1c0255f307203c160788Sean Paul      ALOGE("Invalid display given to SetLayers %d", display);
80c0b35480d6fa2bddd69a1c0255f307203c160788Sean Paul      continue;
81c0b35480d6fa2bddd69a1c0255f307203c160788Sean Paul    }
82c0b35480d6fa2bddd69a1c0255f307203c160788Sean Paul
835757e82631820372382d3369c54cc3a1ffef812fZach Reizner    ret = composition_map_[display]->SetLayers(
845757e82631820372382d3369c54cc3a1ffef812fZach Reizner        map.layers.data(), map.layers.size(), map.geometry_changed);
85098070590ae648ede5f2ef846298de178ccd3637Zach Reizner    if (ret)
86098070590ae648ede5f2ef846298de178ccd3637Zach Reizner      return ret;
87b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul  }
88b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul
8992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner  return 0;
90b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul}
91b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul
92098070590ae648ede5f2ef846298de178ccd3637Zach Reiznerint DrmComposition::SetDpmsMode(int display, uint32_t dpms_mode) {
93098070590ae648ede5f2ef846298de178ccd3637Zach Reizner  return composition_map_[display]->SetDpmsMode(dpms_mode);
94db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul}
95db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul
96573554106db499d323bea12ff00363b1816f8c8aSean Paulint DrmComposition::SetDisplayMode(int display, const DrmMode &display_mode) {
97573554106db499d323bea12ff00363b1816f8c8aSean Paul  return composition_map_[display]->SetDisplayMode(display_mode);
98573554106db499d323bea12ff00363b1816f8c8aSean Paul}
99573554106db499d323bea12ff00363b1816f8c8aSean Paul
10098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paulstd::unique_ptr<DrmDisplayComposition> DrmComposition::TakeDisplayComposition(
10198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul    int display) {
10298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul  return std::move(composition_map_[display]);
103b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul}
1042e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul
10592f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reiznerint DrmComposition::Plan(std::map<int, DrmDisplayCompositor> &compositor_map) {
10692f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner  int ret = 0;
10792f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner  for (DrmResources::ConnectorIter iter = drm_->begin_connectors();
10892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner       iter != drm_->end_connectors(); ++iter) {
10992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner    int display = (*iter)->display();
11092f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner    DrmDisplayComposition *comp = GetDisplayComposition(display);
11192f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner    ret = comp->Plan(compositor_map[display].squash_state(), &primary_planes_,
11292f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner                     &overlay_planes_);
11392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner    if (ret) {
11492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner      ALOGE("Failed to plan composition for dislay %d", display);
11592f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner      return ret;
11692f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner    }
11792f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner  }
11892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner
11992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner  return 0;
12092f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner}
12192f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner
1222e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paulint DrmComposition::DisableUnusedPlanes() {
1232e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul  for (DrmResources::ConnectorIter iter = drm_->begin_connectors();
1242e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul       iter != drm_->end_connectors(); ++iter) {
1252e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul    int display = (*iter)->display();
1262e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul    DrmDisplayComposition *comp = GetDisplayComposition(display);
1272e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul
1282e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul    /*
1292e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul     * Leave empty compositions alone
1302e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul     * TODO: re-visit this and potentially disable leftover planes after the
1312e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul     *       active compositions have gobbled up all they can
1322e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul     */
133573554106db499d323bea12ff00363b1816f8c8aSean Paul    if (comp->type() == DRM_COMPOSITION_TYPE_EMPTY ||
134573554106db499d323bea12ff00363b1816f8c8aSean Paul        comp->type() == DRM_COMPOSITION_TYPE_MODESET)
1352e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul      continue;
1362e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul
1372e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul    DrmCrtc *crtc = drm_->GetCrtcForDisplay(display);
1382e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul    if (!crtc) {
1392e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul      ALOGE("Failed to find crtc for display %d", display);
1402e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul      continue;
1412e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul    }
1422e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul
1432e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul    for (std::vector<DrmPlane *>::iterator iter = primary_planes_.begin();
1442e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul         iter != primary_planes_.end(); ++iter) {
1452e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul      if ((*iter)->GetCrtcSupported(*crtc)) {
1462e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul        comp->AddPlaneDisable(*iter);
1472e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul        primary_planes_.erase(iter);
1482e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul        break;
1492e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul      }
1502e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul    }
1512e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul    for (std::vector<DrmPlane *>::iterator iter = overlay_planes_.begin();
1522e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul         iter != overlay_planes_.end();) {
1532e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul      if ((*iter)->GetCrtcSupported(*crtc)) {
1542e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul        comp->AddPlaneDisable(*iter);
1552e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul        iter = overlay_planes_.erase(iter);
1562e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul      } else {
1572e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul        iter++;
1582e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul      }
1592e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul    }
1602e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul  }
1612e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul  return 0;
1622e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul}
1632e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul
1642e46fbd90b1aae158ec0437f564dd610e7392f7aSean PaulDrmDisplayComposition *DrmComposition::GetDisplayComposition(int display) {
1652e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul  return composition_map_[display].get();
1662e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul}
167b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul}
168