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 &region = 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 &region = 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> &regions = 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> &regions = 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