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