198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul/* 298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul * Copyright (C) 2015 The Android Open Source Project 398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul * 498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul * Licensed under the Apache License, Version 2.0 (the "License"); 598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul * you may not use this file except in compliance with the License. 698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul * You may obtain a copy of the License at 798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul * 898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul * http://www.apache.org/licenses/LICENSE-2.0 998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul * 1098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul * Unless required by applicable law or agreed to in writing, software 1198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul * distributed under the License is distributed on an "AS IS" BASIS, 1298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul * See the License for the specific language governing permissions and 1498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul * limitations under the License. 1598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul */ 1698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 1798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul#define ATRACE_TAG ATRACE_TAG_GRAPHICS 1898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul#define LOG_TAG "hwc-drm-display-compositor" 1998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 2098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul#include "drmdisplaycompositor.h" 2198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 2298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul#include <pthread.h> 23d410f04ec8db892eb37758ddd230223ccab801bcZach Reizner#include <sched.h> 2498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul#include <stdlib.h> 2598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul#include <time.h> 26bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner#include <sstream> 2798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul#include <vector> 2898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 2998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul#include <cutils/log.h> 30bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner#include <drm/drm_mode.h> 3198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul#include <sync/sync.h> 3298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul#include <utils/Trace.h> 3398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 34bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner#include "autolock.h" 35bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner#include "drmcrtc.h" 36bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner#include "drmplane.h" 37bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner#include "drmresources.h" 38bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner#include "glworker.h" 39bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 40dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi#define DRM_DISPLAY_COMPOSITOR_MAX_QUEUE_DEPTH 2 41d410f04ec8db892eb37758ddd230223ccab801bcZach Reizner 4298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paulnamespace android { 4398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 4492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reiznervoid SquashState::Init(DrmHwcLayer *layers, size_t num_layers) { 4592f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner generation_number_++; 4692f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner valid_history_ = 0; 4792f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner regions_.clear(); 4892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner last_handles_.clear(); 4992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 5092f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner std::vector<DrmHwcRect<int>> in_rects; 5192f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner for (size_t i = 0; i < num_layers; i++) { 5292f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner DrmHwcLayer *layer = &layers[i]; 5392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner in_rects.emplace_back(layer->display_frame); 5492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner last_handles_.push_back(layer->sf_handle); 5592f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner } 5692f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 57aa2f4a5eec7f4117b9487a415739634007254822Haixia Shi std::vector<separate_rects::RectSet<uint64_t, int>> out_regions; 58aa2f4a5eec7f4117b9487a415739634007254822Haixia Shi separate_rects::separate_rects_64(in_rects, &out_regions); 5992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 60aa2f4a5eec7f4117b9487a415739634007254822Haixia Shi for (const separate_rects::RectSet<uint64_t, int> &out_region : out_regions) { 6192f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner regions_.emplace_back(); 6292f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner Region ®ion = regions_.back(); 6392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner region.rect = out_region.rect; 6492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner region.layer_refs = out_region.id_set.getBits(); 6592f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner } 6692f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner} 6792f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 685757e82631820372382d3369c54cc3a1ffef812fZach Reiznervoid SquashState::GenerateHistory(DrmHwcLayer *layers, size_t num_layers, 6992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner std::vector<bool> &changed_regions) const { 705757e82631820372382d3369c54cc3a1ffef812fZach Reizner changed_regions.resize(regions_.size()); 715757e82631820372382d3369c54cc3a1ffef812fZach Reizner if (num_layers != last_handles_.size()) { 725757e82631820372382d3369c54cc3a1ffef812fZach Reizner ALOGE("SquashState::GenerateHistory expected %zu layers but got %zu layers", 735757e82631820372382d3369c54cc3a1ffef812fZach Reizner last_handles_.size(), num_layers); 745757e82631820372382d3369c54cc3a1ffef812fZach Reizner return; 755757e82631820372382d3369c54cc3a1ffef812fZach Reizner } 7692f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner std::bitset<kMaxLayers> changed_layers; 7792f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner for (size_t i = 0; i < last_handles_.size(); i++) { 7892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner DrmHwcLayer *layer = &layers[i]; 79db81fce67419d82d828eebec25e57284e90dd93aZach Reizner // Protected layers can't be squashed so we treat them as constantly 80db81fce67419d82d828eebec25e57284e90dd93aZach Reizner // changing. 81db81fce67419d82d828eebec25e57284e90dd93aZach Reizner if (layer->protected_usage() || last_handles_[i] != layer->sf_handle) 8292f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner changed_layers.set(i); 8392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner } 8492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 8592f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner for (size_t i = 0; i < regions_.size(); i++) { 8692f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner changed_regions[i] = (regions_[i].layer_refs & changed_layers).any(); 8792f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner } 8892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner} 8992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 9092f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reiznervoid SquashState::StableRegionsWithMarginalHistory( 9192f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner const std::vector<bool> &changed_regions, 9292f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner std::vector<bool> &stable_regions) const { 9392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner stable_regions.resize(regions_.size()); 9492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner for (size_t i = 0; i < regions_.size(); i++) { 9592f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner stable_regions[i] = !changed_regions[i] && is_stable(i); 9692f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner } 9792f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner} 9892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 995757e82631820372382d3369c54cc3a1ffef812fZach Reiznervoid SquashState::RecordHistory(DrmHwcLayer *layers, size_t num_layers, 10092f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner const std::vector<bool> &changed_regions) { 1015757e82631820372382d3369c54cc3a1ffef812fZach Reizner if (num_layers != last_handles_.size()) { 1025757e82631820372382d3369c54cc3a1ffef812fZach Reizner ALOGE("SquashState::RecordHistory expected %zu layers but got %zu layers", 1035757e82631820372382d3369c54cc3a1ffef812fZach Reizner last_handles_.size(), num_layers); 1045757e82631820372382d3369c54cc3a1ffef812fZach Reizner return; 1055757e82631820372382d3369c54cc3a1ffef812fZach Reizner } 1065757e82631820372382d3369c54cc3a1ffef812fZach Reizner if (changed_regions.size() != regions_.size()) { 1075757e82631820372382d3369c54cc3a1ffef812fZach Reizner ALOGE("SquashState::RecordHistory expected %zu regions but got %zu regions", 1085757e82631820372382d3369c54cc3a1ffef812fZach Reizner regions_.size(), changed_regions.size()); 1095757e82631820372382d3369c54cc3a1ffef812fZach Reizner return; 1105757e82631820372382d3369c54cc3a1ffef812fZach Reizner } 1115757e82631820372382d3369c54cc3a1ffef812fZach Reizner 11292f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner for (size_t i = 0; i < last_handles_.size(); i++) { 11392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner DrmHwcLayer *layer = &layers[i]; 11492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner last_handles_[i] = layer->sf_handle; 11592f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner } 11692f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 11792f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner for (size_t i = 0; i < regions_.size(); i++) { 11892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner regions_[i].change_history <<= 1; 11992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner regions_[i].change_history.set(/* LSB */ 0, changed_regions[i]); 12092f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner } 12192f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 12292f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner valid_history_++; 12392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner} 12492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 1255757e82631820372382d3369c54cc3a1ffef812fZach Reiznerbool SquashState::RecordAndCompareSquashed( 1265757e82631820372382d3369c54cc3a1ffef812fZach Reizner const std::vector<bool> &squashed_regions) { 1275757e82631820372382d3369c54cc3a1ffef812fZach Reizner if (squashed_regions.size() != regions_.size()) { 1285757e82631820372382d3369c54cc3a1ffef812fZach Reizner ALOGE( 1295757e82631820372382d3369c54cc3a1ffef812fZach Reizner "SquashState::RecordAndCompareSquashed expected %zu regions but got " 1305757e82631820372382d3369c54cc3a1ffef812fZach Reizner "%zu regions", 1315757e82631820372382d3369c54cc3a1ffef812fZach Reizner regions_.size(), squashed_regions.size()); 1325757e82631820372382d3369c54cc3a1ffef812fZach Reizner return false; 1335757e82631820372382d3369c54cc3a1ffef812fZach Reizner } 1345757e82631820372382d3369c54cc3a1ffef812fZach Reizner bool changed = false; 13592f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner for (size_t i = 0; i < regions_.size(); i++) { 1365757e82631820372382d3369c54cc3a1ffef812fZach Reizner if (regions_[i].squashed != squashed_regions[i]) { 1375757e82631820372382d3369c54cc3a1ffef812fZach Reizner regions_[i].squashed = squashed_regions[i]; 1385757e82631820372382d3369c54cc3a1ffef812fZach Reizner changed = true; 1395757e82631820372382d3369c54cc3a1ffef812fZach Reizner } 14092f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner } 1415757e82631820372382d3369c54cc3a1ffef812fZach Reizner return changed; 14292f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner} 14392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 144fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reiznervoid SquashState::Dump(std::ostringstream *out) const { 145fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner *out << "----SquashState generation=" << generation_number_ 146fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner << " history=" << valid_history_ << "\n" 147fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner << " Regions: count=" << regions_.size() << "\n"; 148fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner for (size_t i = 0; i < regions_.size(); i++) { 149fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner const Region ®ion = regions_[i]; 150fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner *out << " [" << i << "]" 151fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner << " history=" << region.change_history << " rect"; 152fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner region.rect.Dump(out); 153fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner *out << " layers=("; 154fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner bool first = true; 155fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner for (size_t layer_index = 0; layer_index < kMaxLayers; layer_index++) { 156fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner if ((region.layer_refs & 157fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner std::bitset<kMaxLayers>((size_t)1 << layer_index)) 158fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner .any()) { 159fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner if (!first) 160fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner *out << " "; 161fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner first = false; 162fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner *out << layer_index; 163fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner } 164fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner } 165fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner *out << ")"; 166fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner if (region.squashed) 167fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner *out << " squashed"; 168fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner *out << "\n"; 169fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner } 170fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner} 171fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner 1725757e82631820372382d3369c54cc3a1ffef812fZach Reiznerstatic bool UsesSquash(const std::vector<DrmCompositionPlane> &comp_planes) { 1735757e82631820372382d3369c54cc3a1ffef812fZach Reizner return std::any_of(comp_planes.begin(), comp_planes.end(), 1745757e82631820372382d3369c54cc3a1ffef812fZach Reizner [](const DrmCompositionPlane &plane) { 1757379ecd4c3ebb25e3ce730e4b2e51d2ad46d3a51Sean Paul return plane.type() == DrmCompositionPlane::Type::kSquash; 17607aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul }); 1775757e82631820372382d3369c54cc3a1ffef812fZach Reizner} 1785757e82631820372382d3369c54cc3a1ffef812fZach Reizner 179dda2fabb6a8010768e199210b934a6326c891c2dHaixia ShiDrmDisplayCompositor::FrameWorker::FrameWorker(DrmDisplayCompositor *compositor) 180dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi : Worker("frame-worker", HAL_PRIORITY_URGENT_DISPLAY), 181dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi compositor_(compositor) { 182dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi} 183dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 184dda2fabb6a8010768e199210b934a6326c891c2dHaixia ShiDrmDisplayCompositor::FrameWorker::~FrameWorker() { 185dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi} 186dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 187dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shiint DrmDisplayCompositor::FrameWorker::Init() { 188dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi return InitWorker(); 189dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi} 190dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 191dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shivoid DrmDisplayCompositor::FrameWorker::QueueFrame( 192dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi std::unique_ptr<DrmDisplayComposition> composition, int status) { 193dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi Lock(); 194ff717ff5b00180242041c0bd74d4e26dcfb2d260Adrian Salido 195ff717ff5b00180242041c0bd74d4e26dcfb2d260Adrian Salido // Block queue if it gets too large. Otherwise composition will 196ff717ff5b00180242041c0bd74d4e26dcfb2d260Adrian Salido // start stacking up and eat limited resources (file descriptors) 197ff717ff5b00180242041c0bd74d4e26dcfb2d260Adrian Salido // allocated for these. 198ff717ff5b00180242041c0bd74d4e26dcfb2d260Adrian Salido while (frame_queue_.size() >= DRM_DISPLAY_COMPOSITOR_MAX_QUEUE_DEPTH) { 199ff717ff5b00180242041c0bd74d4e26dcfb2d260Adrian Salido Unlock(); 200ff717ff5b00180242041c0bd74d4e26dcfb2d260Adrian Salido sched_yield(); 201ff717ff5b00180242041c0bd74d4e26dcfb2d260Adrian Salido Lock(); 202ff717ff5b00180242041c0bd74d4e26dcfb2d260Adrian Salido } 203ff717ff5b00180242041c0bd74d4e26dcfb2d260Adrian Salido 204dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi FrameState frame; 205dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi frame.composition = std::move(composition); 206dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi frame.status = status; 207dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi frame_queue_.push(std::move(frame)); 208dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi SignalLocked(); 209dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi Unlock(); 210dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi} 211dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 212dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shivoid DrmDisplayCompositor::FrameWorker::Routine() { 213dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi int ret = Lock(); 214dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi if (ret) { 215dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi ALOGE("Failed to lock worker, %d", ret); 216dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi return; 217dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi } 218dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 219dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi int wait_ret = 0; 220dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi if (frame_queue_.empty()) { 221dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi wait_ret = WaitForSignalOrExitLocked(); 222dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi } 223dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 224dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi FrameState frame; 225dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi if (!frame_queue_.empty()) { 226dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi frame = std::move(frame_queue_.front()); 227dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi frame_queue_.pop(); 228dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi } 229dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 230dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi ret = Unlock(); 231dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi if (ret) { 232dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi ALOGE("Failed to unlock worker, %d", ret); 233dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi return; 234dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi } 235dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 236dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi if (wait_ret == -EINTR) { 237dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi return; 238dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi } else if (wait_ret) { 239dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi ALOGE("Failed to wait for signal, %d", wait_ret); 240dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi return; 241dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi } 242dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 243dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi compositor_->ApplyFrame(std::move(frame.composition), frame.status); 244dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi} 245dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 24698e73c89a683a92f44c99fb8dc85e51bdda243baSean PaulDrmDisplayCompositor::DrmDisplayCompositor() 24798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul : drm_(NULL), 24898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul display_(-1), 24998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul worker_(this), 250dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi frame_worker_(this), 25198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul initialized_(false), 252db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul active_(false), 2536c18b3b67e50e12f77f76108363493162ff36340Sean Paul use_hw_overlays_(true), 254713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner framebuffer_index_(0), 2555757e82631820372382d3369c54cc3a1ffef812fZach Reizner squash_framebuffer_index_(0), 25698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul dump_frames_composited_(0), 25798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul dump_last_timestamp_ns_(0) { 25898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul struct timespec ts; 25998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (clock_gettime(CLOCK_MONOTONIC, &ts)) 26098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return; 26198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul dump_last_timestamp_ns_ = ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec; 26298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul} 26398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 26498e73c89a683a92f44c99fb8dc85e51bdda243baSean PaulDrmDisplayCompositor::~DrmDisplayCompositor() { 26598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (!initialized_) 26698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return; 26798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 26898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul worker_.Exit(); 269dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi frame_worker_.Exit(); 27098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 27198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul int ret = pthread_mutex_lock(&lock_); 27298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (ret) 27398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ALOGE("Failed to acquire compositor lock %d", ret); 27498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 27535301f498c372f3ad2bbbc969acda39056131b26Sean Paul if (mode_.blob_id) 27635301f498c372f3ad2bbbc969acda39056131b26Sean Paul drm_->DestroyPropertyBlob(mode_.blob_id); 27735301f498c372f3ad2bbbc969acda39056131b26Sean Paul if (mode_.old_blob_id) 27835301f498c372f3ad2bbbc969acda39056131b26Sean Paul drm_->DestroyPropertyBlob(mode_.old_blob_id); 27935301f498c372f3ad2bbbc969acda39056131b26Sean Paul 28098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul while (!composite_queue_.empty()) { 28198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul composite_queue_.front().reset(); 28298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul composite_queue_.pop(); 28398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 28498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul active_composition_.reset(); 28598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 28698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ret = pthread_mutex_unlock(&lock_); 28798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (ret) 28898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ALOGE("Failed to acquire compositor lock %d", ret); 28998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 29098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul pthread_mutex_destroy(&lock_); 29198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul} 29298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 29398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paulint DrmDisplayCompositor::Init(DrmResources *drm, int display) { 29498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul drm_ = drm; 29598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul display_ = display; 29698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 29798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul int ret = pthread_mutex_init(&lock_, NULL); 29898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (ret) { 29998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ALOGE("Failed to initialize drm compositor lock %d\n", ret); 30098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return ret; 30198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 30298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ret = worker_.Init(); 30398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (ret) { 30498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul pthread_mutex_destroy(&lock_); 30598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ALOGE("Failed to initialize compositor worker %d\n", ret); 30698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return ret; 30798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 308dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi ret = frame_worker_.Init(); 309dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi if (ret) { 310dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi pthread_mutex_destroy(&lock_); 311dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi ALOGE("Failed to initialize frame worker %d\n", ret); 312dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi return ret; 313dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi } 31498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 31598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul initialized_ = true; 31698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return 0; 31798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul} 31898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 31992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reiznerstd::unique_ptr<DrmDisplayComposition> DrmDisplayCompositor::CreateComposition() 32092f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner const { 32192f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner return std::unique_ptr<DrmDisplayComposition>(new DrmDisplayComposition()); 32292f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner} 32392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 32498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paulint DrmDisplayCompositor::QueueComposition( 32598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul std::unique_ptr<DrmDisplayComposition> composition) { 326acb2a4494e79f0026f8615acc561257276a71062Sean Paul switch (composition->type()) { 327b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner case DRM_COMPOSITION_TYPE_FRAME: 328b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner if (!active_) 329b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner return -ENODEV; 330b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner break; 331b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner case DRM_COMPOSITION_TYPE_DPMS: 332b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner /* 333b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner * Update the state as soon as we get it so we can start/stop queuing 334b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner * frames asap. 335b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner */ 336b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner active_ = (composition->dpms_mode() == DRM_MODE_DPMS_ON); 337b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner break; 338573554106db499d323bea12ff00363b1816f8c8aSean Paul case DRM_COMPOSITION_TYPE_MODESET: 339573554106db499d323bea12ff00363b1816f8c8aSean Paul break; 340b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner case DRM_COMPOSITION_TYPE_EMPTY: 341b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner return 0; 342b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner default: 343b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner ALOGE("Unknown composition type %d/%d", composition->type(), display_); 344b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner return -ENOENT; 345acb2a4494e79f0026f8615acc561257276a71062Sean Paul } 34698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 34798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul int ret = pthread_mutex_lock(&lock_); 34898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (ret) { 34998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ALOGE("Failed to acquire compositor lock %d", ret); 35098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return ret; 35198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 35298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 353d410f04ec8db892eb37758ddd230223ccab801bcZach Reizner // Block the queue if it gets too large. Otherwise, SurfaceFlinger will start 354d410f04ec8db892eb37758ddd230223ccab801bcZach Reizner // to eat our buffer handles when we get about 1 second behind. 355d410f04ec8db892eb37758ddd230223ccab801bcZach Reizner while (composite_queue_.size() >= DRM_DISPLAY_COMPOSITOR_MAX_QUEUE_DEPTH) { 356d410f04ec8db892eb37758ddd230223ccab801bcZach Reizner pthread_mutex_unlock(&lock_); 357d410f04ec8db892eb37758ddd230223ccab801bcZach Reizner sched_yield(); 358d410f04ec8db892eb37758ddd230223ccab801bcZach Reizner pthread_mutex_lock(&lock_); 359d410f04ec8db892eb37758ddd230223ccab801bcZach Reizner } 360d410f04ec8db892eb37758ddd230223ccab801bcZach Reizner 36198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul composite_queue_.push(std::move(composition)); 36298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 36398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ret = pthread_mutex_unlock(&lock_); 36498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (ret) { 36598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ALOGE("Failed to release compositor lock %d", ret); 36698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return ret; 36798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 36898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 36998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul worker_.Signal(); 37098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return 0; 37198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul} 37298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 37392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reiznerstd::tuple<uint32_t, uint32_t, int> 37492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach ReiznerDrmDisplayCompositor::GetActiveModeResolution() { 375713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner DrmConnector *connector = drm_->GetConnectorForDisplay(display_); 376713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner if (connector == NULL) { 377713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner ALOGE("Failed to determine display mode: no connector for display %d", 378713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner display_); 37992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner return std::make_tuple(0, 0, -ENODEV); 380713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner } 381713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner 382713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner const DrmMode &mode = connector->active_mode(); 38392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner return std::make_tuple(mode.h_display(), mode.v_display(), 0); 38492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner} 38592f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 38692f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reiznerint DrmDisplayCompositor::PrepareFramebuffer( 38792f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner DrmFramebuffer &fb, DrmDisplayComposition *display_comp) { 38892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner int ret = fb.WaitReleased(-1); 389713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner if (ret) { 390713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner ALOGE("Failed to wait for framebuffer release %d", ret); 391713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner return ret; 392713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner } 39392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner uint32_t width, height; 39492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner std::tie(width, height, ret) = GetActiveModeResolution(); 39592f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner if (ret) { 39692f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner ALOGE( 39792f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner "Failed to allocate framebuffer because the display resolution could " 39892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner "not be determined %d", 39992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner ret); 40092f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner return ret; 40192f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner } 40292f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 403713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner fb.set_release_fence_fd(-1); 40492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner if (!fb.Allocate(width, height)) { 40592f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner ALOGE("Failed to allocate framebuffer with size %dx%d", width, height); 406713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner return -ENOMEM; 407713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner } 408713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner 40992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner display_comp->layers().emplace_back(); 41092f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner DrmHwcLayer &pre_comp_layer = display_comp->layers().back(); 41192f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner pre_comp_layer.sf_handle = fb.buffer()->handle; 4120c7da1e236c3a31a5bc171aac4d5f2a1033f10e1Haixia Shi pre_comp_layer.blending = DrmHwcBlending::kPreMult; 41392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner pre_comp_layer.source_crop = DrmHwcRect<float>(0, 0, width, height); 41492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner pre_comp_layer.display_frame = DrmHwcRect<int>(0, 0, width, height); 41592f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner ret = pre_comp_layer.buffer.ImportBuffer(fb.buffer()->handle, 41692f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner display_comp->importer()); 41792f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner if (ret) { 41892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner ALOGE("Failed to import framebuffer for display %d", ret); 41992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner return ret; 420b44fd10aef978ff4f77258803f86d76244349333Zach Reizner } 421b44fd10aef978ff4f77258803f86d76244349333Zach Reizner 42292f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner return ret; 42392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner} 42492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 4255757e82631820372382d3369c54cc3a1ffef812fZach Reiznerint DrmDisplayCompositor::ApplySquash(DrmDisplayComposition *display_comp) { 4265757e82631820372382d3369c54cc3a1ffef812fZach Reizner int ret = 0; 4275757e82631820372382d3369c54cc3a1ffef812fZach Reizner 4285757e82631820372382d3369c54cc3a1ffef812fZach Reizner DrmFramebuffer &fb = squash_framebuffers_[squash_framebuffer_index_]; 4295757e82631820372382d3369c54cc3a1ffef812fZach Reizner ret = PrepareFramebuffer(fb, display_comp); 4305757e82631820372382d3369c54cc3a1ffef812fZach Reizner if (ret) { 4315757e82631820372382d3369c54cc3a1ffef812fZach Reizner ALOGE("Failed to prepare framebuffer for squash %d", ret); 4325757e82631820372382d3369c54cc3a1ffef812fZach Reizner return ret; 4335757e82631820372382d3369c54cc3a1ffef812fZach Reizner } 4345757e82631820372382d3369c54cc3a1ffef812fZach Reizner 4355757e82631820372382d3369c54cc3a1ffef812fZach Reizner std::vector<DrmCompositionRegion> ®ions = display_comp->squash_regions(); 4365757e82631820372382d3369c54cc3a1ffef812fZach Reizner ret = pre_compositor_->Composite(display_comp->layers().data(), 4375757e82631820372382d3369c54cc3a1ffef812fZach Reizner regions.data(), regions.size(), fb.buffer()); 4385757e82631820372382d3369c54cc3a1ffef812fZach Reizner pre_compositor_->Finish(); 4395757e82631820372382d3369c54cc3a1ffef812fZach Reizner 4405757e82631820372382d3369c54cc3a1ffef812fZach Reizner if (ret) { 4415757e82631820372382d3369c54cc3a1ffef812fZach Reizner ALOGE("Failed to squash layers"); 4425757e82631820372382d3369c54cc3a1ffef812fZach Reizner return ret; 4435757e82631820372382d3369c54cc3a1ffef812fZach Reizner } 4445757e82631820372382d3369c54cc3a1ffef812fZach Reizner 4455757e82631820372382d3369c54cc3a1ffef812fZach Reizner ret = display_comp->CreateNextTimelineFence(); 4465757e82631820372382d3369c54cc3a1ffef812fZach Reizner if (ret <= 0) { 4475757e82631820372382d3369c54cc3a1ffef812fZach Reizner ALOGE("Failed to create squash framebuffer release fence %d", ret); 4485757e82631820372382d3369c54cc3a1ffef812fZach Reizner return ret; 4495757e82631820372382d3369c54cc3a1ffef812fZach Reizner } 4505757e82631820372382d3369c54cc3a1ffef812fZach Reizner 4515757e82631820372382d3369c54cc3a1ffef812fZach Reizner fb.set_release_fence_fd(ret); 4525757e82631820372382d3369c54cc3a1ffef812fZach Reizner display_comp->SignalSquashDone(); 4535757e82631820372382d3369c54cc3a1ffef812fZach Reizner 4545757e82631820372382d3369c54cc3a1ffef812fZach Reizner return 0; 4555757e82631820372382d3369c54cc3a1ffef812fZach Reizner} 4565757e82631820372382d3369c54cc3a1ffef812fZach Reizner 45792f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reiznerint DrmDisplayCompositor::ApplyPreComposite( 45892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner DrmDisplayComposition *display_comp) { 45992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner int ret = 0; 46092f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 46192f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner DrmFramebuffer &fb = framebuffers_[framebuffer_index_]; 46292f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner ret = PrepareFramebuffer(fb, display_comp); 46392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner if (ret) { 4645757e82631820372382d3369c54cc3a1ffef812fZach Reizner ALOGE("Failed to prepare framebuffer for pre-composite %d", ret); 46592f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner return ret; 46692f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner } 46792f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 46892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner std::vector<DrmCompositionRegion> ®ions = display_comp->pre_comp_regions(); 46992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner ret = pre_compositor_->Composite(display_comp->layers().data(), 47092f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner regions.data(), regions.size(), fb.buffer()); 4718d63e7fde00f5830480cd2225954f70e6b681d8bZach Reizner pre_compositor_->Finish(); 472b44fd10aef978ff4f77258803f86d76244349333Zach Reizner 473713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner if (ret) { 4745757e82631820372382d3369c54cc3a1ffef812fZach Reizner ALOGE("Failed to pre-composite layers"); 475713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner return ret; 476713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner } 477713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner 47892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner ret = display_comp->CreateNextTimelineFence(); 47992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner if (ret <= 0) { 4805757e82631820372382d3369c54cc3a1ffef812fZach Reizner ALOGE("Failed to create pre-composite framebuffer release fence %d", ret); 481098070590ae648ede5f2ef846298de178ccd3637Zach Reizner return ret; 482098070590ae648ede5f2ef846298de178ccd3637Zach Reizner } 4834a253659cef3d82bfb0b25b3ff4c7b073d7a0460Zach Reizner 48492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner fb.set_release_fence_fd(ret); 48592f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner display_comp->SignalPreCompDone(); 486713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner 48792f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner return 0; 488713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner} 489713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner 4907b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paulint DrmDisplayCompositor::DisablePlanes(DrmDisplayComposition *display_comp) { 491b02d858190cc779875d02195631483096024d6caRob Herring drmModeAtomicReqPtr pset = drmModeAtomicAlloc(); 4927b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul if (!pset) { 4937b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul ALOGE("Failed to allocate property set"); 4947b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul return -ENOMEM; 4957b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul } 4967b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul 4977b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul int ret; 49892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner std::vector<DrmCompositionPlane> &comp_planes = 49992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner display_comp->composition_planes(); 50092f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner for (DrmCompositionPlane &comp_plane : comp_planes) { 5019b70717071da6b5c098d2363a350d1f0f2333423Sean Paul DrmPlane *plane = comp_plane.plane(); 502b02d858190cc779875d02195631483096024d6caRob Herring ret = drmModeAtomicAddProperty(pset, plane->id(), 503b02d858190cc779875d02195631483096024d6caRob Herring plane->crtc_property().id(), 0) < 0 || 504b02d858190cc779875d02195631483096024d6caRob Herring drmModeAtomicAddProperty(pset, plane->id(), plane->fb_property().id(), 505b02d858190cc779875d02195631483096024d6caRob Herring 0) < 0; 5067b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul if (ret) { 5077b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul ALOGE("Failed to add plane %d disable to pset", plane->id()); 508b02d858190cc779875d02195631483096024d6caRob Herring drmModeAtomicFree(pset); 5097b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul return ret; 5107b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul } 5117b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul } 5127b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul 513b02d858190cc779875d02195631483096024d6caRob Herring ret = drmModeAtomicCommit(drm_->fd(), pset, 0, drm_); 5147b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul if (ret) { 5157b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul ALOGE("Failed to commit pset ret=%d\n", ret); 516b02d858190cc779875d02195631483096024d6caRob Herring drmModeAtomicFree(pset); 5177b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul return ret; 5187b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul } 5197b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul 520b02d858190cc779875d02195631483096024d6caRob Herring drmModeAtomicFree(pset); 5217b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul return 0; 5227b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul} 5237b1e4bc9186b3920cf67bab4f84af59b93118319Sean Paul 524dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shiint DrmDisplayCompositor::PrepareFrame(DrmDisplayComposition *display_comp) { 52598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul int ret = 0; 52698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 52792f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner std::vector<DrmHwcLayer> &layers = display_comp->layers(); 52892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner std::vector<DrmCompositionPlane> &comp_planes = 52992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner display_comp->composition_planes(); 5305757e82631820372382d3369c54cc3a1ffef812fZach Reizner std::vector<DrmCompositionRegion> &squash_regions = 5315757e82631820372382d3369c54cc3a1ffef812fZach Reizner display_comp->squash_regions(); 53292f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner std::vector<DrmCompositionRegion> &pre_comp_regions = 53392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner display_comp->pre_comp_regions(); 53492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 5355757e82631820372382d3369c54cc3a1ffef812fZach Reizner int squash_layer_index = -1; 5365757e82631820372382d3369c54cc3a1ffef812fZach Reizner if (squash_regions.size() > 0) { 5375757e82631820372382d3369c54cc3a1ffef812fZach Reizner squash_framebuffer_index_ = (squash_framebuffer_index_ + 1) % 2; 5385757e82631820372382d3369c54cc3a1ffef812fZach Reizner ret = ApplySquash(display_comp); 5395757e82631820372382d3369c54cc3a1ffef812fZach Reizner if (ret) 5405757e82631820372382d3369c54cc3a1ffef812fZach Reizner return ret; 5415757e82631820372382d3369c54cc3a1ffef812fZach Reizner 5425757e82631820372382d3369c54cc3a1ffef812fZach Reizner squash_layer_index = layers.size() - 1; 5435757e82631820372382d3369c54cc3a1ffef812fZach Reizner } else { 5445757e82631820372382d3369c54cc3a1ffef812fZach Reizner if (UsesSquash(comp_planes)) { 5455757e82631820372382d3369c54cc3a1ffef812fZach Reizner DrmFramebuffer &fb = squash_framebuffers_[squash_framebuffer_index_]; 5465757e82631820372382d3369c54cc3a1ffef812fZach Reizner layers.emplace_back(); 5475757e82631820372382d3369c54cc3a1ffef812fZach Reizner squash_layer_index = layers.size() - 1; 5485757e82631820372382d3369c54cc3a1ffef812fZach Reizner DrmHwcLayer &squash_layer = layers.back(); 5495757e82631820372382d3369c54cc3a1ffef812fZach Reizner ret = squash_layer.buffer.ImportBuffer(fb.buffer()->handle, 5505757e82631820372382d3369c54cc3a1ffef812fZach Reizner display_comp->importer()); 5515757e82631820372382d3369c54cc3a1ffef812fZach Reizner if (ret) { 5525757e82631820372382d3369c54cc3a1ffef812fZach Reizner ALOGE("Failed to import old squashed framebuffer %d", ret); 5535757e82631820372382d3369c54cc3a1ffef812fZach Reizner return ret; 5545757e82631820372382d3369c54cc3a1ffef812fZach Reizner } 5555757e82631820372382d3369c54cc3a1ffef812fZach Reizner squash_layer.sf_handle = fb.buffer()->handle; 5560c7da1e236c3a31a5bc171aac4d5f2a1033f10e1Haixia Shi squash_layer.blending = DrmHwcBlending::kPreMult; 5575757e82631820372382d3369c54cc3a1ffef812fZach Reizner squash_layer.source_crop = DrmHwcRect<float>( 5585757e82631820372382d3369c54cc3a1ffef812fZach Reizner 0, 0, squash_layer.buffer->width, squash_layer.buffer->height); 5595757e82631820372382d3369c54cc3a1ffef812fZach Reizner squash_layer.display_frame = DrmHwcRect<int>( 5605757e82631820372382d3369c54cc3a1ffef812fZach Reizner 0, 0, squash_layer.buffer->width, squash_layer.buffer->height); 5615757e82631820372382d3369c54cc3a1ffef812fZach Reizner ret = display_comp->CreateNextTimelineFence(); 5625757e82631820372382d3369c54cc3a1ffef812fZach Reizner 5635757e82631820372382d3369c54cc3a1ffef812fZach Reizner if (ret <= 0) { 5645757e82631820372382d3369c54cc3a1ffef812fZach Reizner ALOGE("Failed to create squash framebuffer release fence %d", ret); 5655757e82631820372382d3369c54cc3a1ffef812fZach Reizner return ret; 5665757e82631820372382d3369c54cc3a1ffef812fZach Reizner } 5675757e82631820372382d3369c54cc3a1ffef812fZach Reizner 5685757e82631820372382d3369c54cc3a1ffef812fZach Reizner fb.set_release_fence_fd(ret); 5695757e82631820372382d3369c54cc3a1ffef812fZach Reizner ret = 0; 5705757e82631820372382d3369c54cc3a1ffef812fZach Reizner } 5715757e82631820372382d3369c54cc3a1ffef812fZach Reizner } 5725757e82631820372382d3369c54cc3a1ffef812fZach Reizner 57392f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner bool do_pre_comp = pre_comp_regions.size() > 0; 57492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner int pre_comp_layer_index = -1; 57592f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner if (do_pre_comp) { 576713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner ret = ApplyPreComposite(display_comp); 577713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner if (ret) 578713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner return ret; 57992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 58092f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner pre_comp_layer_index = layers.size() - 1; 58192f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner framebuffer_index_ = (framebuffer_index_ + 1) % DRM_DISPLAY_BUFFERS; 582713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner } 583713a6788528d4cc4cd477b2f546c8b922beb6ddeZach Reizner 584dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi for (DrmCompositionPlane &comp_plane : comp_planes) { 5859b70717071da6b5c098d2363a350d1f0f2333423Sean Paul std::vector<size_t> &source_layers = comp_plane.source_layers(); 5869b70717071da6b5c098d2363a350d1f0f2333423Sean Paul switch (comp_plane.type()) { 5877379ecd4c3ebb25e3ce730e4b2e51d2ad46d3a51Sean Paul case DrmCompositionPlane::Type::kSquash: 5889b70717071da6b5c098d2363a350d1f0f2333423Sean Paul if (source_layers.size()) 5899b70717071da6b5c098d2363a350d1f0f2333423Sean Paul ALOGE("Squash source_layers is expected to be empty (%zu/%d)", 5909b70717071da6b5c098d2363a350d1f0f2333423Sean Paul source_layers[0], squash_layer_index); 5919b70717071da6b5c098d2363a350d1f0f2333423Sean Paul source_layers.push_back(squash_layer_index); 592dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi break; 5937379ecd4c3ebb25e3ce730e4b2e51d2ad46d3a51Sean Paul case DrmCompositionPlane::Type::kPrecomp: 594dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi if (!do_pre_comp) { 595dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi ALOGE( 596dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi "Can not use pre composite framebuffer with no pre composite " 597dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi "regions"); 598dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi return -EINVAL; 599dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi } 6009b70717071da6b5c098d2363a350d1f0f2333423Sean Paul // Replace source_layers with the output of the precomposite 6019b70717071da6b5c098d2363a350d1f0f2333423Sean Paul source_layers.clear(); 6029b70717071da6b5c098d2363a350d1f0f2333423Sean Paul source_layers.push_back(pre_comp_layer_index); 603dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi break; 604dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi default: 605dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi break; 606dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi } 607dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi } 608dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 609dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi return ret; 610dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi} 611dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 612c07b21121553f981a1888bb855c987138879c267Sean Paulint DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, 613c07b21121553f981a1888bb855c987138879c267Sean Paul bool test_only) { 6143979f7d252b4b054417b59a5dac84281eeaa8435Haixia Shi ATRACE_CALL(); 6153979f7d252b4b054417b59a5dac84281eeaa8435Haixia Shi 616dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi int ret = 0; 617dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 618dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi std::vector<DrmHwcLayer> &layers = display_comp->layers(); 619dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi std::vector<DrmCompositionPlane> &comp_planes = 620dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi display_comp->composition_planes(); 621dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi std::vector<DrmCompositionRegion> &pre_comp_regions = 622dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi display_comp->pre_comp_regions(); 623dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 624573554106db499d323bea12ff00363b1816f8c8aSean Paul DrmConnector *connector = drm_->GetConnectorForDisplay(display_); 625573554106db499d323bea12ff00363b1816f8c8aSean Paul if (!connector) { 626573554106db499d323bea12ff00363b1816f8c8aSean Paul ALOGE("Could not locate connector for display %d", display_); 627573554106db499d323bea12ff00363b1816f8c8aSean Paul return -ENODEV; 628573554106db499d323bea12ff00363b1816f8c8aSean Paul } 629573554106db499d323bea12ff00363b1816f8c8aSean Paul DrmCrtc *crtc = drm_->GetCrtcForDisplay(display_); 630573554106db499d323bea12ff00363b1816f8c8aSean Paul if (!crtc) { 631573554106db499d323bea12ff00363b1816f8c8aSean Paul ALOGE("Could not locate crtc for display %d", display_); 632573554106db499d323bea12ff00363b1816f8c8aSean Paul return -ENODEV; 633573554106db499d323bea12ff00363b1816f8c8aSean Paul } 634573554106db499d323bea12ff00363b1816f8c8aSean Paul 635b02d858190cc779875d02195631483096024d6caRob Herring drmModeAtomicReqPtr pset = drmModeAtomicAlloc(); 63698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (!pset) { 63798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ALOGE("Failed to allocate property set"); 63898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return -ENOMEM; 63998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 64098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 64135301f498c372f3ad2bbbc969acda39056131b26Sean Paul if (mode_.needs_modeset) { 642b02d858190cc779875d02195631483096024d6caRob Herring ret = drmModeAtomicAddProperty(pset, crtc->id(), crtc->mode_property().id(), 643b02d858190cc779875d02195631483096024d6caRob Herring mode_.blob_id) < 0 || 644b02d858190cc779875d02195631483096024d6caRob Herring drmModeAtomicAddProperty(pset, connector->id(), 645b02d858190cc779875d02195631483096024d6caRob Herring connector->crtc_id_property().id(), 646b02d858190cc779875d02195631483096024d6caRob Herring crtc->id()) < 0; 647573554106db499d323bea12ff00363b1816f8c8aSean Paul if (ret) { 64835301f498c372f3ad2bbbc969acda39056131b26Sean Paul ALOGE("Failed to add blob %d to pset", mode_.blob_id); 649b02d858190cc779875d02195631483096024d6caRob Herring drmModeAtomicFree(pset); 650573554106db499d323bea12ff00363b1816f8c8aSean Paul return ret; 651573554106db499d323bea12ff00363b1816f8c8aSean Paul } 652573554106db499d323bea12ff00363b1816f8c8aSean Paul } 653573554106db499d323bea12ff00363b1816f8c8aSean Paul 65492f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner for (DrmCompositionPlane &comp_plane : comp_planes) { 6559b70717071da6b5c098d2363a350d1f0f2333423Sean Paul DrmPlane *plane = comp_plane.plane(); 6569b70717071da6b5c098d2363a350d1f0f2333423Sean Paul DrmCrtc *crtc = comp_plane.crtc(); 6579b70717071da6b5c098d2363a350d1f0f2333423Sean Paul std::vector<size_t> &source_layers = comp_plane.source_layers(); 65892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner 65992f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner int fb_id = -1; 66092f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner DrmHwcRect<int> display_frame; 66192f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner DrmHwcRect<float> source_crop; 66292f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner uint64_t rotation = 0; 663d8aefb635a854c36b0cf2eb36ecdf9070ddc7151Sean Paul uint64_t alpha = 0xFF; 66407aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul 6657379ecd4c3ebb25e3ce730e4b2e51d2ad46d3a51Sean Paul if (comp_plane.type() != DrmCompositionPlane::Type::kDisable) { 6669b70717071da6b5c098d2363a350d1f0f2333423Sean Paul if (source_layers.size() > 1) { 6679b70717071da6b5c098d2363a350d1f0f2333423Sean Paul ALOGE("Can't handle more than one source layer sz=%zu type=%d", 6689b70717071da6b5c098d2363a350d1f0f2333423Sean Paul source_layers.size(), comp_plane.type()); 6699b70717071da6b5c098d2363a350d1f0f2333423Sean Paul continue; 6709b70717071da6b5c098d2363a350d1f0f2333423Sean Paul } 6719b70717071da6b5c098d2363a350d1f0f2333423Sean Paul 6729b70717071da6b5c098d2363a350d1f0f2333423Sean Paul if (source_layers.empty() || source_layers.front() >= layers.size()) { 6739b70717071da6b5c098d2363a350d1f0f2333423Sean Paul ALOGE("Source layer index %zu out of bounds %zu type=%d", 6749b70717071da6b5c098d2363a350d1f0f2333423Sean Paul source_layers.front(), layers.size(), comp_plane.type()); 675d75d8d2bf2f53511b1826452c2a8547b6a338cc7Zach Reizner break; 67607aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul } 6779b70717071da6b5c098d2363a350d1f0f2333423Sean Paul DrmHwcLayer &layer = layers[source_layers.front()]; 67807aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul if (!test_only && layer.acquire_fence.get() >= 0) { 67907aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul int acquire_fence = layer.acquire_fence.get(); 68007aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul int total_fence_timeout = 0; 68107aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul for (int i = 0; i < kAcquireWaitTries; ++i) { 68207aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul int fence_timeout = kAcquireWaitTimeoutMs * (1 << i); 68307aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul total_fence_timeout += fence_timeout; 68407aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul ret = sync_wait(acquire_fence, fence_timeout); 68507aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul if (ret) 68607aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul ALOGW("Acquire fence %d wait %d failed (%d). Total time %d", 68707aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul acquire_fence, i, ret, total_fence_timeout); 68892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner } 68907aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul if (ret) { 69007aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul ALOGE("Failed to wait for acquire %d/%d", acquire_fence, ret); 69192f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner break; 69292f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner } 69307aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul layer.acquire_fence.Close(); 69498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 69507aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul if (!layer.buffer) { 69607aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul ALOGE("Expected a valid framebuffer for pset"); 69707aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul break; 69807aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul } 69907aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul fb_id = layer.buffer->fb_id; 70007aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul display_frame = layer.display_frame; 70107aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul source_crop = layer.source_crop; 70207aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul if (layer.blending == DrmHwcBlending::kPreMult) 70307aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul alpha = layer.alpha; 70407aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul 70507aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul rotation = 0; 70607aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul if (layer.transform & DrmHwcTransform::kFlipH) 70707aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul rotation |= 1 << DRM_REFLECT_X; 70807aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul if (layer.transform & DrmHwcTransform::kFlipV) 70907aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul rotation |= 1 << DRM_REFLECT_Y; 71007aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul if (layer.transform & DrmHwcTransform::kRotate90) 71107aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul rotation |= 1 << DRM_ROTATE_90; 71207aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul else if (layer.transform & DrmHwcTransform::kRotate180) 71307aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul rotation |= 1 << DRM_ROTATE_180; 71407aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul else if (layer.transform & DrmHwcTransform::kRotate270) 71507aa8cc9f7a3905e62f71b0be8e0129c69ef81e0Sean Paul rotation |= 1 << DRM_ROTATE_270; 71698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 71792f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner // Disable the plane if there's no framebuffer 71892f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reizner if (fb_id < 0) { 719b02d858190cc779875d02195631483096024d6caRob Herring ret = drmModeAtomicAddProperty(pset, plane->id(), 720b02d858190cc779875d02195631483096024d6caRob Herring plane->crtc_property().id(), 0) < 0 || 721b02d858190cc779875d02195631483096024d6caRob Herring drmModeAtomicAddProperty(pset, plane->id(), 722b02d858190cc779875d02195631483096024d6caRob Herring plane->fb_property().id(), 0) < 0; 7232e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul if (ret) { 7242e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul ALOGE("Failed to add plane %d disable to pset", plane->id()); 7252e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul break; 7262e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul } 7272e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul continue; 7282e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul } 7292e46fbd90b1aae158ec0437f564dd610e7392f7aSean Paul 7301c4c32635df1f45bbcf63c8c1a76207ca90402e5Sean Paul // TODO: Once we have atomic test, this should fall back to GL 7311c4c32635df1f45bbcf63c8c1a76207ca90402e5Sean Paul if (rotation && plane->rotation_property().id() == 0) { 7321c4c32635df1f45bbcf63c8c1a76207ca90402e5Sean Paul ALOGE("Rotation is not supported on plane %d", plane->id()); 7331c4c32635df1f45bbcf63c8c1a76207ca90402e5Sean Paul ret = -EINVAL; 7341c4c32635df1f45bbcf63c8c1a76207ca90402e5Sean Paul break; 7351c4c32635df1f45bbcf63c8c1a76207ca90402e5Sean Paul } 7361c4c32635df1f45bbcf63c8c1a76207ca90402e5Sean Paul 737d8aefb635a854c36b0cf2eb36ecdf9070ddc7151Sean Paul // TODO: Once we have atomic test, this should fall back to GL 738d8aefb635a854c36b0cf2eb36ecdf9070ddc7151Sean Paul if (alpha != 0xFF && plane->alpha_property().id() == 0) { 739d8aefb635a854c36b0cf2eb36ecdf9070ddc7151Sean Paul ALOGE("Alpha is not supported on plane %d", plane->id()); 740d8aefb635a854c36b0cf2eb36ecdf9070ddc7151Sean Paul ret = -EINVAL; 741d8aefb635a854c36b0cf2eb36ecdf9070ddc7151Sean Paul break; 742d8aefb635a854c36b0cf2eb36ecdf9070ddc7151Sean Paul } 743d8aefb635a854c36b0cf2eb36ecdf9070ddc7151Sean Paul 744b02d858190cc779875d02195631483096024d6caRob Herring ret = drmModeAtomicAddProperty(pset, plane->id(), 745b02d858190cc779875d02195631483096024d6caRob Herring plane->crtc_property().id(), crtc->id()) < 0; 746b02d858190cc779875d02195631483096024d6caRob Herring ret |= drmModeAtomicAddProperty(pset, plane->id(), 747b02d858190cc779875d02195631483096024d6caRob Herring plane->fb_property().id(), fb_id) < 0; 748b02d858190cc779875d02195631483096024d6caRob Herring ret |= drmModeAtomicAddProperty(pset, plane->id(), 749b02d858190cc779875d02195631483096024d6caRob Herring plane->crtc_x_property().id(), 750b02d858190cc779875d02195631483096024d6caRob Herring display_frame.left) < 0; 751b02d858190cc779875d02195631483096024d6caRob Herring ret |= drmModeAtomicAddProperty(pset, plane->id(), 752b02d858190cc779875d02195631483096024d6caRob Herring plane->crtc_y_property().id(), 753b02d858190cc779875d02195631483096024d6caRob Herring display_frame.top) < 0; 754b02d858190cc779875d02195631483096024d6caRob Herring ret |= drmModeAtomicAddProperty( 755b02d858190cc779875d02195631483096024d6caRob Herring pset, plane->id(), plane->crtc_w_property().id(), 756b02d858190cc779875d02195631483096024d6caRob Herring display_frame.right - display_frame.left) < 0; 757b02d858190cc779875d02195631483096024d6caRob Herring ret |= drmModeAtomicAddProperty( 758b02d858190cc779875d02195631483096024d6caRob Herring pset, plane->id(), plane->crtc_h_property().id(), 759b02d858190cc779875d02195631483096024d6caRob Herring display_frame.bottom - display_frame.top) < 0; 760b02d858190cc779875d02195631483096024d6caRob Herring ret |= drmModeAtomicAddProperty(pset, plane->id(), 761b02d858190cc779875d02195631483096024d6caRob Herring plane->src_x_property().id(), 762b02d858190cc779875d02195631483096024d6caRob Herring (int)(source_crop.left) << 16) < 0; 763b02d858190cc779875d02195631483096024d6caRob Herring ret |= drmModeAtomicAddProperty(pset, plane->id(), 764b02d858190cc779875d02195631483096024d6caRob Herring plane->src_y_property().id(), 765b02d858190cc779875d02195631483096024d6caRob Herring (int)(source_crop.top) << 16) < 0; 766b02d858190cc779875d02195631483096024d6caRob Herring ret |= drmModeAtomicAddProperty( 767b02d858190cc779875d02195631483096024d6caRob Herring pset, plane->id(), plane->src_w_property().id(), 768b02d858190cc779875d02195631483096024d6caRob Herring (int)(source_crop.right - source_crop.left) << 16) < 0; 769b02d858190cc779875d02195631483096024d6caRob Herring ret |= drmModeAtomicAddProperty( 770b02d858190cc779875d02195631483096024d6caRob Herring pset, plane->id(), plane->src_h_property().id(), 771b02d858190cc779875d02195631483096024d6caRob Herring (int)(source_crop.bottom - source_crop.top) << 16) < 0; 77298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (ret) { 77398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ALOGE("Failed to add plane %d to set", plane->id()); 77498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul break; 77598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 7761c4c32635df1f45bbcf63c8c1a76207ca90402e5Sean Paul 7771c4c32635df1f45bbcf63c8c1a76207ca90402e5Sean Paul if (plane->rotation_property().id()) { 778b02d858190cc779875d02195631483096024d6caRob Herring ret = drmModeAtomicAddProperty(pset, plane->id(), 779b02d858190cc779875d02195631483096024d6caRob Herring plane->rotation_property().id(), 780b02d858190cc779875d02195631483096024d6caRob Herring rotation) < 0; 7811c4c32635df1f45bbcf63c8c1a76207ca90402e5Sean Paul if (ret) { 7821c4c32635df1f45bbcf63c8c1a76207ca90402e5Sean Paul ALOGE("Failed to add rotation property %d to plane %d", 7831c4c32635df1f45bbcf63c8c1a76207ca90402e5Sean Paul plane->rotation_property().id(), plane->id()); 7841c4c32635df1f45bbcf63c8c1a76207ca90402e5Sean Paul break; 7851c4c32635df1f45bbcf63c8c1a76207ca90402e5Sean Paul } 7861c4c32635df1f45bbcf63c8c1a76207ca90402e5Sean Paul } 787d8aefb635a854c36b0cf2eb36ecdf9070ddc7151Sean Paul 788d8aefb635a854c36b0cf2eb36ecdf9070ddc7151Sean Paul if (plane->alpha_property().id()) { 789b02d858190cc779875d02195631483096024d6caRob Herring ret = drmModeAtomicAddProperty(pset, plane->id(), 790b02d858190cc779875d02195631483096024d6caRob Herring plane->alpha_property().id(), 791b02d858190cc779875d02195631483096024d6caRob Herring alpha) < 0; 792d8aefb635a854c36b0cf2eb36ecdf9070ddc7151Sean Paul if (ret) { 793d8aefb635a854c36b0cf2eb36ecdf9070ddc7151Sean Paul ALOGE("Failed to add alpha property %d to plane %d", 794d8aefb635a854c36b0cf2eb36ecdf9070ddc7151Sean Paul plane->alpha_property().id(), plane->id()); 795d8aefb635a854c36b0cf2eb36ecdf9070ddc7151Sean Paul break; 796d8aefb635a854c36b0cf2eb36ecdf9070ddc7151Sean Paul } 797d8aefb635a854c36b0cf2eb36ecdf9070ddc7151Sean Paul } 79898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 79998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 80092f8e6399c0829c6ba6db77d5ea1bbd22f510bb1Zach Reiznerout: 80198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (!ret) { 802c07b21121553f981a1888bb855c987138879c267Sean Paul uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET; 803c07b21121553f981a1888bb855c987138879c267Sean Paul if (test_only) 804c07b21121553f981a1888bb855c987138879c267Sean Paul flags |= DRM_MODE_ATOMIC_TEST_ONLY; 805c07b21121553f981a1888bb855c987138879c267Sean Paul 806b02d858190cc779875d02195631483096024d6caRob Herring ret = drmModeAtomicCommit(drm_->fd(), pset, flags, drm_); 807573554106db499d323bea12ff00363b1816f8c8aSean Paul if (ret) { 808c07b21121553f981a1888bb855c987138879c267Sean Paul if (test_only) 809c07b21121553f981a1888bb855c987138879c267Sean Paul ALOGI("Commit test pset failed ret=%d\n", ret); 810c07b21121553f981a1888bb855c987138879c267Sean Paul else 811c07b21121553f981a1888bb855c987138879c267Sean Paul ALOGE("Failed to commit pset ret=%d\n", ret); 812b02d858190cc779875d02195631483096024d6caRob Herring drmModeAtomicFree(pset); 813573554106db499d323bea12ff00363b1816f8c8aSean Paul return ret; 814573554106db499d323bea12ff00363b1816f8c8aSean Paul } 81598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 81698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (pset) 817b02d858190cc779875d02195631483096024d6caRob Herring drmModeAtomicFree(pset); 81898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 819c07b21121553f981a1888bb855c987138879c267Sean Paul if (!test_only && mode_.needs_modeset) { 82035301f498c372f3ad2bbbc969acda39056131b26Sean Paul ret = drm_->DestroyPropertyBlob(mode_.old_blob_id); 821573554106db499d323bea12ff00363b1816f8c8aSean Paul if (ret) { 822717a44be8f9f9282e6708b78cb3f2bbc8de7cb3aSean Paul ALOGE("Failed to destroy old mode property blob %" PRIu32 "/%d", 82335301f498c372f3ad2bbbc969acda39056131b26Sean Paul mode_.old_blob_id, ret); 824573554106db499d323bea12ff00363b1816f8c8aSean Paul return ret; 825573554106db499d323bea12ff00363b1816f8c8aSean Paul } 826573554106db499d323bea12ff00363b1816f8c8aSean Paul 827573554106db499d323bea12ff00363b1816f8c8aSean Paul /* TODO: Add dpms to the pset when the kernel supports it */ 828573554106db499d323bea12ff00363b1816f8c8aSean Paul ret = ApplyDpms(display_comp); 829573554106db499d323bea12ff00363b1816f8c8aSean Paul if (ret) { 830573554106db499d323bea12ff00363b1816f8c8aSean Paul ALOGE("Failed to apply DPMS after modeset %d\n", ret); 831573554106db499d323bea12ff00363b1816f8c8aSean Paul return ret; 832573554106db499d323bea12ff00363b1816f8c8aSean Paul } 833573554106db499d323bea12ff00363b1816f8c8aSean Paul 83435301f498c372f3ad2bbbc969acda39056131b26Sean Paul connector->set_active_mode(mode_.mode); 83535301f498c372f3ad2bbbc969acda39056131b26Sean Paul mode_.old_blob_id = mode_.blob_id; 83635301f498c372f3ad2bbbc969acda39056131b26Sean Paul mode_.blob_id = 0; 83735301f498c372f3ad2bbbc969acda39056131b26Sean Paul mode_.needs_modeset = false; 838573554106db499d323bea12ff00363b1816f8c8aSean Paul } 839573554106db499d323bea12ff00363b1816f8c8aSean Paul 84098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return ret; 84198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul} 84298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 843db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paulint DrmDisplayCompositor::ApplyDpms(DrmDisplayComposition *display_comp) { 844db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul DrmConnector *conn = drm_->GetConnectorForDisplay(display_); 845db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul if (!conn) { 846db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul ALOGE("Failed to get DrmConnector for display %d", display_); 847db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul return -ENODEV; 848db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul } 849db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul 850db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul const DrmProperty &prop = conn->dpms_property(); 851db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul int ret = drmModeConnectorSetProperty(drm_->fd(), conn->id(), prop.id(), 852db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul display_comp->dpms_mode()); 853db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul if (ret) { 854db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul ALOGE("Failed to set DPMS property for connector %d", conn->id()); 855db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul return ret; 856db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul } 857db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul return 0; 858db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul} 859db7a17d28ca48f81be3091e99564e47fa0503e9eSean Paul 86035301f498c372f3ad2bbbc969acda39056131b26Sean Paulstd::tuple<int, uint32_t> DrmDisplayCompositor::CreateModeBlob( 86135301f498c372f3ad2bbbc969acda39056131b26Sean Paul const DrmMode &mode) { 86235301f498c372f3ad2bbbc969acda39056131b26Sean Paul struct drm_mode_modeinfo drm_mode; 86335301f498c372f3ad2bbbc969acda39056131b26Sean Paul memset(&drm_mode, 0, sizeof(drm_mode)); 86435301f498c372f3ad2bbbc969acda39056131b26Sean Paul mode.ToDrmModeModeInfo(&drm_mode); 86535301f498c372f3ad2bbbc969acda39056131b26Sean Paul 86635301f498c372f3ad2bbbc969acda39056131b26Sean Paul uint32_t id = 0; 86735301f498c372f3ad2bbbc969acda39056131b26Sean Paul int ret = drm_->CreatePropertyBlob(&drm_mode, 86835301f498c372f3ad2bbbc969acda39056131b26Sean Paul sizeof(struct drm_mode_modeinfo), &id); 86935301f498c372f3ad2bbbc969acda39056131b26Sean Paul if (ret) { 87035301f498c372f3ad2bbbc969acda39056131b26Sean Paul ALOGE("Failed to create mode property blob %d", ret); 87135301f498c372f3ad2bbbc969acda39056131b26Sean Paul return std::make_tuple(ret, 0); 87235301f498c372f3ad2bbbc969acda39056131b26Sean Paul } 873717a44be8f9f9282e6708b78cb3f2bbc8de7cb3aSean Paul ALOGE("Create blob_id %" PRIu32 "\n", id); 87435301f498c372f3ad2bbbc969acda39056131b26Sean Paul return std::make_tuple(ret, id); 87535301f498c372f3ad2bbbc969acda39056131b26Sean Paul} 87635301f498c372f3ad2bbbc969acda39056131b26Sean Paul 877b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paulvoid DrmDisplayCompositor::ClearDisplay() { 878b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul AutoLock lock(&lock_, "compositor"); 879b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul int ret = lock.Lock(); 880b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul if (ret) 881b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul return; 882b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul 883b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul if (!active_composition_) 884b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul return; 885b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul 886b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul if (DisablePlanes(active_composition_.get())) 887b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul return; 888b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul 889b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul active_composition_->SignalCompositionDone(); 890b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul 891b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul active_composition_.reset(NULL); 892b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul} 893b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul 894dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shivoid DrmDisplayCompositor::ApplyFrame( 895dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi std::unique_ptr<DrmDisplayComposition> composition, int status) { 896dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi int ret = status; 897dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 898dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi if (!ret) 899c07b21121553f981a1888bb855c987138879c267Sean Paul ret = CommitFrame(composition.get(), false); 900dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 901dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi if (ret) { 902dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi ALOGE("Composite failed for display %d", display_); 903dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi // Disable the hw used by the last active composition. This allows us to 904dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi // signal the release fences from that composition to avoid hanging. 905b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul ClearDisplay(); 906b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul return; 907dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi } 908dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi ++dump_frames_composited_; 909dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 910dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi if (active_composition_) 911dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi active_composition_->SignalCompositionDone(); 912dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 913dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi ret = pthread_mutex_lock(&lock_); 914dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi if (ret) 915dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi ALOGE("Failed to acquire lock for active_composition swap"); 916dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 917dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi active_composition_.swap(composition); 918dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 919dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi if (!ret) 920dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi ret = pthread_mutex_unlock(&lock_); 921dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi if (ret) 922dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi ALOGE("Failed to release lock for active_composition swap"); 923dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi} 924dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi 92598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paulint DrmDisplayCompositor::Composite() { 92698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ATRACE_CALL(); 927098070590ae648ede5f2ef846298de178ccd3637Zach Reizner 928098070590ae648ede5f2ef846298de178ccd3637Zach Reizner if (!pre_compositor_) { 929098070590ae648ede5f2ef846298de178ccd3637Zach Reizner pre_compositor_.reset(new GLWorkerCompositor()); 930098070590ae648ede5f2ef846298de178ccd3637Zach Reizner int ret = pre_compositor_->Init(); 931098070590ae648ede5f2ef846298de178ccd3637Zach Reizner if (ret) { 932098070590ae648ede5f2ef846298de178ccd3637Zach Reizner ALOGE("Failed to initialize OpenGL compositor %d", ret); 933098070590ae648ede5f2ef846298de178ccd3637Zach Reizner return ret; 934098070590ae648ede5f2ef846298de178ccd3637Zach Reizner } 935098070590ae648ede5f2ef846298de178ccd3637Zach Reizner } 936098070590ae648ede5f2ef846298de178ccd3637Zach Reizner 93798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul int ret = pthread_mutex_lock(&lock_); 93898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (ret) { 93998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ALOGE("Failed to acquire compositor lock %d", ret); 94098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return ret; 94198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 94298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (composite_queue_.empty()) { 94398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ret = pthread_mutex_unlock(&lock_); 94498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (ret) 94598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ALOGE("Failed to release compositor lock %d", ret); 94698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return ret; 94798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 94898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 94998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul std::unique_ptr<DrmDisplayComposition> composition( 95098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul std::move(composite_queue_.front())); 9514a253659cef3d82bfb0b25b3ff4c7b073d7a0460Zach Reizner 95298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul composite_queue_.pop(); 95398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 95498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ret = pthread_mutex_unlock(&lock_); 95598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (ret) { 95698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ALOGE("Failed to release compositor lock %d", ret); 95798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return ret; 95898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 95998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 960acb2a4494e79f0026f8615acc561257276a71062Sean Paul switch (composition->type()) { 961b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner case DRM_COMPOSITION_TYPE_FRAME: 962e3141c6fa66806f55fed65c83ed0c2c0201490e0Sean Paul ret = PrepareFrame(composition.get()); 963e3141c6fa66806f55fed65c83ed0c2c0201490e0Sean Paul if (ret) { 964e3141c6fa66806f55fed65c83ed0c2c0201490e0Sean Paul ALOGE("Failed to prepare frame for display %d", display_); 965e3141c6fa66806f55fed65c83ed0c2c0201490e0Sean Paul return ret; 966647beb27af04c33d415c75149c4c93d767693cafSean Paul } 9676afbb6aef0c89b8e737624c4baa1208aaec6f48eHaixia Shi if (composition->geometry_changed()) { 9686afbb6aef0c89b8e737624c4baa1208aaec6f48eHaixia Shi // Send the composition to the kernel to ensure we can commit it. This 9696afbb6aef0c89b8e737624c4baa1208aaec6f48eHaixia Shi // is just a test, it won't actually commit the frame. If rejected, 9706afbb6aef0c89b8e737624c4baa1208aaec6f48eHaixia Shi // squash the frame into one layer and use the squashed composition 9716afbb6aef0c89b8e737624c4baa1208aaec6f48eHaixia Shi ret = CommitFrame(composition.get(), true); 9726c18b3b67e50e12f77f76108363493162ff36340Sean Paul if (ret) 9736afbb6aef0c89b8e737624c4baa1208aaec6f48eHaixia Shi ALOGI("Commit test failed, squashing frame for display %d", display_); 9746c18b3b67e50e12f77f76108363493162ff36340Sean Paul use_hw_overlays_ = !ret; 9756c18b3b67e50e12f77f76108363493162ff36340Sean Paul } 9766c18b3b67e50e12f77f76108363493162ff36340Sean Paul 9776c18b3b67e50e12f77f76108363493162ff36340Sean Paul // If use_hw_overlays_ is false, we can't use hardware to composite the 9786c18b3b67e50e12f77f76108363493162ff36340Sean Paul // frame. So squash all layers into a single composition and queue that 9796c18b3b67e50e12f77f76108363493162ff36340Sean Paul // instead. 9806c18b3b67e50e12f77f76108363493162ff36340Sean Paul if (!use_hw_overlays_) { 9816c18b3b67e50e12f77f76108363493162ff36340Sean Paul std::unique_ptr<DrmDisplayComposition> squashed = CreateComposition(); 9826c18b3b67e50e12f77f76108363493162ff36340Sean Paul ret = SquashFrame(composition.get(), squashed.get()); 9836c18b3b67e50e12f77f76108363493162ff36340Sean Paul if (!ret) { 9846c18b3b67e50e12f77f76108363493162ff36340Sean Paul composition = std::move(squashed); 9856c18b3b67e50e12f77f76108363493162ff36340Sean Paul } else { 9866c18b3b67e50e12f77f76108363493162ff36340Sean Paul ALOGE("Failed to squash frame for display %d", display_); 987b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul // Disable the hw used by the last active composition. This allows us 988b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul // to signal the release fences from that composition to avoid 989b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul // hanging. 990b4cf01b8eab70b554b3ddcad10cade7b6f0ffe0fSean Paul ClearDisplay(); 9916c18b3b67e50e12f77f76108363493162ff36340Sean Paul return ret; 992647beb27af04c33d415c75149c4c93d767693cafSean Paul } 993647beb27af04c33d415c75149c4c93d767693cafSean Paul } 994dda2fabb6a8010768e199210b934a6326c891c2dHaixia Shi frame_worker_.QueueFrame(std::move(composition), ret); 995b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner break; 996b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner case DRM_COMPOSITION_TYPE_DPMS: 997b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner ret = ApplyDpms(composition.get()); 998b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner if (ret) 999b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner ALOGE("Failed to apply dpms for display %d", display_); 1000acb2a4494e79f0026f8615acc561257276a71062Sean Paul return ret; 1001573554106db499d323bea12ff00363b1816f8c8aSean Paul case DRM_COMPOSITION_TYPE_MODESET: 100235301f498c372f3ad2bbbc969acda39056131b26Sean Paul mode_.mode = composition->display_mode(); 100335301f498c372f3ad2bbbc969acda39056131b26Sean Paul if (mode_.blob_id) 100435301f498c372f3ad2bbbc969acda39056131b26Sean Paul drm_->DestroyPropertyBlob(mode_.blob_id); 100535301f498c372f3ad2bbbc969acda39056131b26Sean Paul std::tie(ret, mode_.blob_id) = CreateModeBlob(mode_.mode); 100635301f498c372f3ad2bbbc969acda39056131b26Sean Paul if (ret) { 100735301f498c372f3ad2bbbc969acda39056131b26Sean Paul ALOGE("Failed to create mode blob for display %d", display_); 100835301f498c372f3ad2bbbc969acda39056131b26Sean Paul return ret; 100935301f498c372f3ad2bbbc969acda39056131b26Sean Paul } 101035301f498c372f3ad2bbbc969acda39056131b26Sean Paul mode_.needs_modeset = true; 1011573554106db499d323bea12ff00363b1816f8c8aSean Paul return 0; 1012b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner default: 1013b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner ALOGE("Unknown composition type %d", composition->type()); 1014b4a9aeff843e2a834335a4db0fef388ae37b423dZach Reizner return -EINVAL; 101598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 101698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 101798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return ret; 101898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul} 101998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 102098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paulbool DrmDisplayCompositor::HaveQueuedComposites() const { 102198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul int ret = pthread_mutex_lock(&lock_); 102298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (ret) { 102398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ALOGE("Failed to acquire compositor lock %d", ret); 102498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return false; 102598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 102698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 102798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul bool empty_ret = !composite_queue_.empty(); 102898e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 102998e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ret = pthread_mutex_unlock(&lock_); 103098e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul if (ret) { 103198e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul ALOGE("Failed to release compositor lock %d", ret); 103298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return false; 103398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul } 103498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 103598e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul return empty_ret; 103698e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul} 103798e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul 1038bff33ac0e677875eb4b462a45ad90429b6484181Zach Reiznerint DrmDisplayCompositor::SquashAll() { 1039bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner AutoLock lock(&lock_, "compositor"); 1040bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner int ret = lock.Lock(); 1041bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner if (ret) 1042bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner return ret; 1043bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 1044bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner if (!active_composition_) 1045bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner return 0; 1046bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 1047d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul std::unique_ptr<DrmDisplayComposition> comp = CreateComposition(); 1048d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul ret = SquashFrame(active_composition_.get(), comp.get()); 1049d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul 1050d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul // ApplyFrame needs the lock 1051d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul lock.Unlock(); 1052d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul 1053d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul if (!ret) 1054d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul ApplyFrame(std::move(comp), 0); 1055d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul 1056d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul return ret; 1057d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul} 1058bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 1059d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul// Returns: 1060d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul// - 0 if src is successfully squashed into dst 1061d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul// - -EALREADY if the src is already squashed 1062d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul// - Appropriate error if the squash fails 1063d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paulint DrmDisplayCompositor::SquashFrame(DrmDisplayComposition *src, 1064d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul DrmDisplayComposition *dst) { 1065d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul if (src->type() != DRM_COMPOSITION_TYPE_FRAME) 1066d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul return -ENOTSUP; 1067d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul 1068d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul std::vector<DrmCompositionPlane> &src_planes = src->composition_planes(); 1069d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul std::vector<DrmHwcLayer> &src_layers = src->layers(); 1070bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 1071bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner // Make sure there is more than one layer to squash. 1072d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul size_t src_planes_with_layer = std::count_if( 1073d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul src_planes.begin(), src_planes.end(), [](DrmCompositionPlane &p) { 1074c74c8b9339cb5fd4f00d1be6b857c6e60ba5fc49Sean Paul return p.type() != DrmCompositionPlane::Type::kDisable; 1075bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner }); 1076d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul if (src_planes_with_layer <= 1) 1077d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul return -EALREADY; 1078bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 1079bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner int pre_comp_layer_index; 1080bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 10818cc4e2a2de3c0cf932226a5a6042de5d830fa24aSean Paul int ret = dst->Init(drm_, src->crtc(), src->importer(), src->planner(), 10828cc4e2a2de3c0cf932226a5a6042de5d830fa24aSean Paul src->frame_no()); 1083bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner if (ret) { 1084bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner ALOGE("Failed to init squash all composition %d", ret); 1085bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner return ret; 1086bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner } 1087bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 10888eb85ff7d7704a4783cbb97eec480ae2c93d7f3bSean Paul DrmCompositionPlane squashed_comp(DrmCompositionPlane::Type::kPrecomp, NULL, 10898eb85ff7d7704a4783cbb97eec480ae2c93d7f3bSean Paul src->crtc()); 1090d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul std::vector<DrmHwcLayer> dst_layers; 1091d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul for (DrmCompositionPlane &comp_plane : src_planes) { 1092bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner // Composition planes without DRM planes should never happen 10939b70717071da6b5c098d2363a350d1f0f2333423Sean Paul if (comp_plane.plane() == NULL) { 1094bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner ALOGE("Skipping squash all because of NULL plane"); 1095d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul ret = -EINVAL; 1096bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner goto move_layers_back; 1097bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner } 1098bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 10998cc4e2a2de3c0cf932226a5a6042de5d830fa24aSean Paul if (comp_plane.type() == DrmCompositionPlane::Type::kDisable) { 11008cc4e2a2de3c0cf932226a5a6042de5d830fa24aSean Paul dst->AddPlaneDisable(comp_plane.plane()); 11012b4b1eea6b7075efe356af8bb2e948201635c5c2Zach Reizner continue; 11028cc4e2a2de3c0cf932226a5a6042de5d830fa24aSean Paul } 11032b4b1eea6b7075efe356af8bb2e948201635c5c2Zach Reizner 11049b70717071da6b5c098d2363a350d1f0f2333423Sean Paul for (auto i : comp_plane.source_layers()) { 11059b70717071da6b5c098d2363a350d1f0f2333423Sean Paul DrmHwcLayer &layer = src_layers[i]; 1106bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 11079b70717071da6b5c098d2363a350d1f0f2333423Sean Paul // Squashing protected layers is impossible. 11089b70717071da6b5c098d2363a350d1f0f2333423Sean Paul if (layer.protected_usage()) { 11099b70717071da6b5c098d2363a350d1f0f2333423Sean Paul ret = -ENOTSUP; 11109b70717071da6b5c098d2363a350d1f0f2333423Sean Paul goto move_layers_back; 11119b70717071da6b5c098d2363a350d1f0f2333423Sean Paul } 1112bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 11139b70717071da6b5c098d2363a350d1f0f2333423Sean Paul // The OutputFds point to freed memory after hwc_set returns. They are 11149b70717071da6b5c098d2363a350d1f0f2333423Sean Paul // returned to the default to prevent DrmDisplayComposition::Plan from 11159b70717071da6b5c098d2363a350d1f0f2333423Sean Paul // filling the OutputFds. 11169b70717071da6b5c098d2363a350d1f0f2333423Sean Paul layer.release_fence = OutputFd(); 11179b70717071da6b5c098d2363a350d1f0f2333423Sean Paul dst_layers.emplace_back(std::move(layer)); 11188eb85ff7d7704a4783cbb97eec480ae2c93d7f3bSean Paul squashed_comp.source_layers().push_back( 11198eb85ff7d7704a4783cbb97eec480ae2c93d7f3bSean Paul squashed_comp.source_layers().size()); 11209b70717071da6b5c098d2363a350d1f0f2333423Sean Paul } 1121bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 11228eb85ff7d7704a4783cbb97eec480ae2c93d7f3bSean Paul if (comp_plane.plane()->type() == DRM_PLANE_TYPE_PRIMARY) 11238eb85ff7d7704a4783cbb97eec480ae2c93d7f3bSean Paul squashed_comp.set_plane(comp_plane.plane()); 1124bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner else 11259b70717071da6b5c098d2363a350d1f0f2333423Sean Paul dst->AddPlaneDisable(comp_plane.plane()); 1126bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner } 1127bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 1128d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul ret = dst->SetLayers(dst_layers.data(), dst_layers.size(), false); 1129bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner if (ret) { 1130bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner ALOGE("Failed to set layers for squash all composition %d", ret); 1131bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner goto move_layers_back; 1132bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner } 1133bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 11348eb85ff7d7704a4783cbb97eec480ae2c93d7f3bSean Paul ret = dst->AddPlaneComposition(std::move(squashed_comp)); 11358eb85ff7d7704a4783cbb97eec480ae2c93d7f3bSean Paul if (ret) { 11368eb85ff7d7704a4783cbb97eec480ae2c93d7f3bSean Paul ALOGE("Failed to add squashed plane composition %d", ret); 11378eb85ff7d7704a4783cbb97eec480ae2c93d7f3bSean Paul goto move_layers_back; 11388eb85ff7d7704a4783cbb97eec480ae2c93d7f3bSean Paul } 11398eb85ff7d7704a4783cbb97eec480ae2c93d7f3bSean Paul 11408eb85ff7d7704a4783cbb97eec480ae2c93d7f3bSean Paul ret = dst->FinalizeComposition(); 1141bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner if (ret) { 1142bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner ALOGE("Failed to plan for squash all composition %d", ret); 1143bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner goto move_layers_back; 1144bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner } 1145bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 1146d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul ret = ApplyPreComposite(dst); 1147bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner if (ret) { 1148bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner ALOGE("Failed to pre-composite for squash all composition %d", ret); 1149bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner goto move_layers_back; 1150bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner } 1151bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 1152d51c7617d590c806c53ca3fdbc9428c03261dac1Sean Paul pre_comp_layer_index = dst->layers().size() - 1; 1153bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner framebuffer_index_ = (framebuffer_index_ + 1) % DRM_DISPLAY_BUFFERS; 1154bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 11559b70717071da6b5c098d2363a350d1f0f2333423Sean Paul for (DrmCompositionPlane &plane : dst->composition_planes()) { 11567379ecd4c3ebb25e3ce730e4b2e51d2ad46d3a51Sean Paul if (plane.type() == DrmCompositionPlane::Type::kPrecomp) { 11579b70717071da6b5c098d2363a350d1f0f2333423Sean Paul // Replace source_layers with the output of the precomposite 11589b70717071da6b5c098d2363a350d1f0f2333423Sean Paul plane.source_layers().clear(); 11599b70717071da6b5c098d2363a350d1f0f2333423Sean Paul plane.source_layers().push_back(pre_comp_layer_index); 11609b70717071da6b5c098d2363a350d1f0f2333423Sean Paul break; 11619b70717071da6b5c098d2363a350d1f0f2333423Sean Paul } 11629b70717071da6b5c098d2363a350d1f0f2333423Sean Paul } 1163bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 1164bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner return 0; 1165bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 1166bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner// TODO(zachr): think of a better way to transfer ownership back to the active 1167bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner// composition. 1168bff33ac0e677875eb4b462a45ad90429b6484181Zach Reiznermove_layers_back: 1169bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner for (size_t plane_index = 0; 11709b70717071da6b5c098d2363a350d1f0f2333423Sean Paul plane_index < src_planes.size() && plane_index < dst_layers.size();) { 11719b70717071da6b5c098d2363a350d1f0f2333423Sean Paul if (src_planes[plane_index].source_layers().empty()) { 11729b70717071da6b5c098d2363a350d1f0f2333423Sean Paul plane_index++; 11739b70717071da6b5c098d2363a350d1f0f2333423Sean Paul continue; 11749b70717071da6b5c098d2363a350d1f0f2333423Sean Paul } 11759b70717071da6b5c098d2363a350d1f0f2333423Sean Paul for (auto i : src_planes[plane_index].source_layers()) 11769b70717071da6b5c098d2363a350d1f0f2333423Sean Paul src_layers[i] = std::move(dst_layers[plane_index++]); 1177bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner } 1178bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 1179bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner return ret; 1180bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner} 1181bff33ac0e677875eb4b462a45ad90429b6484181Zach Reizner 118298e73c89a683a92f44c99fb8dc85e51bdda243baSean Paulvoid DrmDisplayCompositor::Dump(std::ostringstream *out) const { 1183fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner int ret = pthread_mutex_lock(&lock_); 1184fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner if (ret) 1185fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner return; 1186fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner 1187fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner uint64_t num_frames = dump_frames_composited_; 1188fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner dump_frames_composited_ = 0; 1189fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner 1190fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner struct timespec ts; 1191fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner ret = clock_gettime(CLOCK_MONOTONIC, &ts); 1192fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner if (ret) { 1193fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner pthread_mutex_unlock(&lock_); 1194fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner return; 1195fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner } 1196fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner 1197fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner uint64_t cur_ts = ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec; 1198fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner uint64_t num_ms = (cur_ts - dump_last_timestamp_ns_) / (1000 * 1000); 1199fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner float fps = num_ms ? (num_frames * 1000.0f) / (num_ms) : 0.0f; 1200fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner 1201fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner *out << "--DrmDisplayCompositor[" << display_ 1202fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner << "]: num_frames=" << num_frames << " num_ms=" << num_ms 1203fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner << " fps=" << fps << "\n"; 1204fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner 1205fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner dump_last_timestamp_ns_ = cur_ts; 1206fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner 1207fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner if (active_composition_) 1208fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner active_composition_->Dump(out); 1209fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner 12105757e82631820372382d3369c54cc3a1ffef812fZach Reizner squash_state_.Dump(out); 12115757e82631820372382d3369c54cc3a1ffef812fZach Reizner 1212fd6dc339551e5aa041daec7abffc3ff8eaeca138Zach Reizner pthread_mutex_unlock(&lock_); 121398e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul} 121498e73c89a683a92f44c99fb8dc85e51bdda243baSean Paul} 1215