1 /*
2 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *     * Redistributions of source code must retain the above copyright
8 *       notice, this list of conditions and the following disclaimer.
9 *     * Redistributions in binary form must reproduce the above
10 *       copyright notice, this list of conditions and the following
11 *       disclaimer in the documentation and/or other materials provided
12 *       with the distribution.
13 *     * Neither the name of The Linux Foundation nor the names of its
14 *       contributors may be used to endorse or promote products derived
15 *       from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 
30 #include <vector>
31 #include "QtiComposer.h"
32 
33 namespace vendor {
34 namespace qti {
35 namespace hardware {
36 namespace display {
37 namespace composer {
38 namespace V3_0 {
39 namespace implementation {
40 
41 QtiComposerClient* QtiComposerClient::qti_composerclient_instance_ = nullptr;
42 
QtiComposer()43 QtiComposer::QtiComposer() {
44   hwc_session_ = HWCSession::GetInstance();
45 }
46 
~QtiComposer()47 QtiComposer::~QtiComposer() {
48   hwc_session_->Deinit();
49 }
50 
51 // Methods from ::android::hardware::graphics::composer::V2_1::IComposer follow.
getCapabilities(getCapabilities_cb _hidl_cb)52 Return<void> QtiComposer::getCapabilities(getCapabilities_cb _hidl_cb) {
53   const std::array<IComposer::Capability, 3> all_caps = {{
54     IComposer::Capability::SIDEBAND_STREAM,
55     IComposer::Capability::SKIP_CLIENT_COLOR_TRANSFORM,
56     IComposer::Capability::PRESENT_FENCE_IS_NOT_RELIABLE,
57   }};
58 
59   uint32_t count = 0;
60   hwc_session_->GetCapabilities(&count, nullptr);
61 
62   std::vector<int32_t> composer_caps(count);
63   hwc_session_->GetCapabilities(&count, composer_caps.data());
64   composer_caps.resize(count);
65 
66   std::unordered_set<hwc2_capability_t> Capabilities;
67   Capabilities.reserve(count);
68   for (auto cap : composer_caps) {
69     Capabilities.insert(static_cast<hwc2_capability_t>(cap));
70   }
71 
72   std::vector<IComposer::Capability> caps;
73   for (auto cap : all_caps) {
74     if (Capabilities.count(static_cast<hwc2_capability_t>(cap)) > 0) {
75      caps.push_back(cap);
76     }
77   }
78 
79   hidl_vec<IComposer::Capability> caps_reply;
80   caps_reply.setToExternal(caps.data(), caps.size());
81 
82   _hidl_cb(caps_reply);
83   return Void();
84 }
85 
dumpDebugInfo(dumpDebugInfo_cb _hidl_cb)86 Return<void> QtiComposer::dumpDebugInfo(dumpDebugInfo_cb _hidl_cb) {
87   uint32_t len;
88   hwc_session_->Dump(&len, nullptr);
89 
90   std::vector<char> buf(len + 1);
91   hwc_session_->Dump(&len, buf.data());
92 
93   buf.resize(len + 1);
94   buf[len] = '\0';
95   hidl_string buf_reply;
96   buf_reply.setToExternal(buf.data(), len);
97 
98   _hidl_cb(buf_reply);
99   return Void();
100 }
101 
createClient(createClient_cb _hidl_cb)102 Return<void> QtiComposer::createClient(createClient_cb _hidl_cb) {
103   // TODO(user): Implement combinedly w.r.t createClient_2_3
104   sp<QtiComposerClient> composer_client = QtiComposerClient::CreateQtiComposerClientInstance();
105   if (!composer_client) {
106     _hidl_cb(Error::NO_RESOURCES, nullptr);
107     return Void();
108   }
109 
110   _hidl_cb(Error::NONE, composer_client);
111   return Void();
112 }
113 
114 
115 // Methods from ::android::hardware::graphics::composer::V2_3::IComposer follow.
createClient_2_3(createClient_2_3_cb _hidl_cb)116 Return<void> QtiComposer::createClient_2_3(createClient_2_3_cb _hidl_cb) {
117   sp<QtiComposerClient> composer_client = QtiComposerClient::CreateQtiComposerClientInstance();
118   if (!composer_client) {
119     _hidl_cb(Error::NO_RESOURCES, nullptr);
120     return Void();
121   }
122 
123   _hidl_cb(Error::NONE, composer_client);
124   return Void();
125 }
126 
127 // Methods from ::android::hardware::graphics::composer::V2_4::IComposer follow.
createClient_2_4(createClient_2_4_cb _hidl_cb)128 Return<void> QtiComposer::createClient_2_4(createClient_2_4_cb _hidl_cb) {
129   sp<QtiComposerClient> composer_client = QtiComposerClient::CreateQtiComposerClientInstance();
130   if (!composer_client) {
131     _hidl_cb(composer_V2_4::Error::NO_RESOURCES, nullptr);
132     return Void();
133   }
134 
135   _hidl_cb(composer_V2_4::Error::NONE, composer_client);
136   return Void();
137 }
138 
initialize()139 QtiComposer *QtiComposer::initialize() {
140   auto error = HWCSession::GetInstance()->Init();
141   if (error) {
142     ALOGE("failed to get hwcomposer instance");
143     return nullptr;
144   }
145 
146   return new QtiComposer();
147 }
148 
149 // Methods from ::android::hidl::base::V1_0::IBase follow.
150 
HIDL_FETCH_IQtiComposer(const char *)151 IQtiComposer* HIDL_FETCH_IQtiComposer(const char* /* name */) {
152   return new QtiComposer();
153 }
154 
155 }  // namespace implementation
156 }  // namespace V3_0
157 }  // namespace composer
158 }  // namespace display
159 }  // namespace hardware
160 }  // namespace qti
161 }  // namespace vendor
162