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 
29 namespace android {
30 
DrmCompositor(DrmResources * drm)31 DrmCompositor::DrmCompositor(DrmResources *drm) : drm_(drm), frame_no_(0) {
32 }
33 
~DrmCompositor()34 DrmCompositor::~DrmCompositor() {
35 }
36 
Init()37 int 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 
CreateComposition(Importer * importer)55 std::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 
QueueComposition(std::unique_ptr<DrmComposition> composition)67 int 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 
Composite()92 int 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 
Dump(std::ostringstream * out) const101 void 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