drmcomposition.cpp revision 7e88be90cf44838fd183ee3d4981c19d7171e501
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 78098070590ae648ede5f2ef846298de178ccd3637Zach Reizner ret = composition_map_[display]->SetLayers( 794a253659cef3d82bfb0b25b3ff4c7b073d7a0460Zach Reizner map.layers.data(), map.layers.size(), &primary_planes_, 80098070590ae648ede5f2ef846298de178ccd3637Zach Reizner &overlay_planes_); 81098070590ae648ede5f2ef846298de178ccd3637Zach Reizner if (ret) 82098070590ae648ede5f2ef846298de178ccd3637Zach Reizner return ret; 83b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul } 84b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul 85098070590ae648ede5f2ef846298de178ccd3637Zach Reizner return DisableUnusedPlanes(); 86b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul} 87b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul 88098070590ae648ede5f2ef846298de178ccd3637Zach Reiznerint DrmComposition::SetDpmsMode(int display, uint32_t dpms_mode) { 89098070590ae648ede5f2ef846298de178ccd3637Zach Reizner return composition_map_[display]->SetDpmsMode(dpms_mode); 90db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul} 91db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul 92573554106db499d323bea12ff00363b1816f8c8aSean Paulint DrmComposition::SetDisplayMode(int display, const DrmMode &display_mode) { 93573554106db499d323bea12ff00363b1816f8c8aSean Paul return composition_map_[display]->SetDisplayMode(display_mode); 94573554106db499d323bea12ff00363b1816f8c8aSean Paul} 95573554106db499d323bea12ff00363b1816f8c8aSean Paul 9698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paulstd::unique_ptr<DrmDisplayComposition> DrmComposition::TakeDisplayComposition( 9798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul int display) { 9898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return std::move(composition_map_[display]); 99b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul} 1002e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul 1012e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paulint DrmComposition::DisableUnusedPlanes() { 1022e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul for (DrmResources::ConnectorIter iter = drm_->begin_connectors(); 1032e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul iter != drm_->end_connectors(); ++iter) { 1042e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul int display = (*iter)->display(); 1052e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul DrmDisplayComposition *comp = GetDisplayComposition(display); 1062e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul 1072e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul /* 1082e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul * Leave empty compositions alone 1092e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul * TODO: re-visit this and potentially disable leftover planes after the 1102e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul * active compositions have gobbled up all they can 1112e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul */ 112573554106db499d323bea12ff00363b1816f8c8aSean Paul if (comp->type() == DRM_COMPOSITION_TYPE_EMPTY || 113573554106db499d323bea12ff00363b1816f8c8aSean Paul comp->type() == DRM_COMPOSITION_TYPE_MODESET) 1142e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul continue; 1152e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul 1162e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul DrmCrtc *crtc = drm_->GetCrtcForDisplay(display); 1172e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul if (!crtc) { 1182e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul ALOGE("Failed to find crtc for display %d", display); 1192e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul continue; 1202e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul } 1212e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul 1222e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul for (std::vector<DrmPlane *>::iterator iter = primary_planes_.begin(); 1232e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul iter != primary_planes_.end(); ++iter) { 1242e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul if ((*iter)->GetCrtcSupported(*crtc)) { 1252e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul comp->AddPlaneDisable(*iter); 1262e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul primary_planes_.erase(iter); 1272e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul break; 1282e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul } 1292e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul } 1302e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul for (std::vector<DrmPlane *>::iterator iter = overlay_planes_.begin(); 1312e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul iter != overlay_planes_.end();) { 1322e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul if ((*iter)->GetCrtcSupported(*crtc)) { 1332e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul comp->AddPlaneDisable(*iter); 1342e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul iter = overlay_planes_.erase(iter); 1352e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul } else { 1362e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul iter++; 1372e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul } 1382e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul } 1392e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul } 1402e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul return 0; 1412e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul} 1422e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul 1432e46fbd90b1aae158ec0437f564dd610e7392f7aSean PaulDrmDisplayComposition *DrmComposition::GetDisplayComposition(int display) { 1442e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul return composition_map_[display].get(); 1452e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul} 146b386f1b1b3716c06831d82493e9ba5a156094701Sean Paul} 147