1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "hwc-drm-compositor"
18
19#include "drmcompositor.h"
20#include "drmdisplaycompositor.h"
21#include "drmresources.h"
22#include "platform.h"
23
24#include <sstream>
25#include <stdlib.h>
26
27#include <cutils/log.h>
28
29namespace android {
30
31DrmCompositor::DrmCompositor(DrmResources *drm) : drm_(drm), frame_no_(0) {
32}
33
34DrmCompositor::~DrmCompositor() {
35}
36
37int DrmCompositor::Init() {
38  for (auto &conn : drm_->connectors()) {
39    int display = conn->display();
40    int ret = compositor_map_[display].Init(drm_, display);
41    if (ret) {
42      ALOGE("Failed to initialize display compositor for %d", display);
43      return ret;
44    }
45  }
46  planner_ = Planner::CreateInstance(drm_);
47  if (!planner_) {
48    ALOGE("Failed to create planner instance for composition");
49    return -ENOMEM;
50  }
51
52  return 0;
53}
54
55std::unique_ptr<DrmComposition> DrmCompositor::CreateComposition(
56    Importer *importer) {
57  std::unique_ptr<DrmComposition> composition(
58      new DrmComposition(drm_, importer, planner_.get()));
59  int ret = composition->Init(++frame_no_);
60  if (ret) {
61    ALOGE("Failed to initialize drm composition %d", ret);
62    return nullptr;
63  }
64  return composition;
65}
66
67int DrmCompositor::QueueComposition(
68    std::unique_ptr<DrmComposition> composition) {
69  int ret;
70
71  ret = composition->Plan(compositor_map_);
72  if (ret)
73    return ret;
74
75  ret = composition->DisableUnusedPlanes();
76  if (ret)
77    return ret;
78
79  for (auto &conn : drm_->connectors()) {
80    int display = conn->display();
81    int ret = compositor_map_[display].QueueComposition(
82        composition->TakeDisplayComposition(display));
83    if (ret) {
84      ALOGE("Failed to queue composition for display %d (%d)", display, ret);
85      return ret;
86    }
87  }
88
89  return 0;
90}
91
92int DrmCompositor::Composite() {
93  /*
94   * This shouldn't be called, we should be calling Composite() on the display
95   * compositors directly.
96   */
97  ALOGE("Calling base drm compositor Composite() function");
98  return -EINVAL;
99}
100
101void DrmCompositor::Dump(std::ostringstream *out) const {
102  *out << "DrmCompositor stats:\n";
103  for (auto &conn : drm_->connectors())
104    compositor_map_[conn->display()].Dump(out);
105}
106}
107