1 /*
2  * Copyright (c) 2019, The Linux Foundation. All rights reserved.
3  * Not a Contribution.
4  *
5  * Copyright (C) 2017 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #include <log/log.h>
21 
22 #include "QtiComposerHandleImporter.h"
23 
24 namespace vendor {
25 namespace qti {
26 namespace hardware {
27 namespace display {
28 namespace composer {
29 namespace V3_0 {
30 
31 using MapperV2Error = android::hardware::graphics::mapper::V2_0::Error;
32 using MapperV3Error = android::hardware::graphics::mapper::V3_0::Error;
33 
ComposerHandleImporter()34 ComposerHandleImporter::ComposerHandleImporter() : mInitialized(false) {}
35 
initialize()36 void ComposerHandleImporter::initialize() {
37     // allow only one client
38   if (mInitialized) {
39     return;
40   }
41 
42   mMapper_V3 = IMapperV3::getService();
43   if (mMapper_V3 == nullptr) {
44     mMapper_V2 = IMapperV2::getService();
45     if (mMapper_V2 == nullptr) {
46       ALOGE("%s: cannnot acccess graphics mapper HAL!", __FUNCTION__);
47       return;
48     }
49   }
50 
51   mInitialized = true;
52   return;
53 }
54 
cleanup()55 void ComposerHandleImporter::cleanup() {
56   if (mMapper_V3 != nullptr) {
57     mMapper_V3.clear();
58   } else {
59     mMapper_V2.clear();
60   }
61   mInitialized = false;
62 }
63 
64 // In IComposer, any buffer_handle_t is owned by the caller and we need to
65 // make a clone for hwcomposer2.  We also need to translate empty handle
66 // to nullptr.  This function does that, in-place.
importBuffer(buffer_handle_t & handle)67 bool ComposerHandleImporter::importBuffer(buffer_handle_t& handle) {
68   if (!handle) {
69     return true;
70   }
71 
72   if (!handle->numFds && !handle->numInts) {
73     handle = nullptr;
74     return true;
75   }
76 
77   Mutex::Autolock lock(mLock);
78   if (!mInitialized) {
79     initialize();
80   }
81 
82   if (mMapper_V3 == nullptr && mMapper_V2 == nullptr) {
83     ALOGE("%s: mMapper is null!", __FUNCTION__);
84     return false;
85   }
86 
87   if (mMapper_V3 != nullptr) {
88     MapperV3Error error;
89     buffer_handle_t importedHandle;
90 
91     auto ret = mMapper_V3->importBuffer(
92         hidl_handle(handle),
93         [&](const auto &tmpError, const auto &tmpBufferHandle) {
94           error = tmpError;
95           importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
96         });
97 
98     if (!ret.isOk()) {
99       ALOGE("%s: mapper importBuffer failed: %s", __FUNCTION__, ret.description().c_str());
100       return false;
101     }
102 
103     if (error != MapperV3Error::NONE) {
104       return false;
105     }
106 
107     handle = importedHandle;
108   } else {
109     MapperV2Error error;
110     buffer_handle_t importedHandle;
111 
112     auto ret = mMapper_V2->importBuffer(
113         hidl_handle(handle),
114         [&](const auto &tmpError, const auto &tmpBufferHandle) {
115           error = tmpError;
116           importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
117         });
118 
119     if (!ret.isOk()) {
120       ALOGE("%s: mapper importBuffer failed: %s", __FUNCTION__, ret.description().c_str());
121       return false;
122     }
123 
124     if (error != MapperV2Error::NONE) {
125       return false;
126     }
127 
128     handle = importedHandle;
129   }
130 
131   return true;
132 }
133 
freeBuffer(buffer_handle_t handle)134 void ComposerHandleImporter::freeBuffer(buffer_handle_t handle) {
135   if (!handle) {
136     return;
137   }
138 
139   Mutex::Autolock lock(mLock);
140 
141   if (mMapper_V3 == nullptr && mMapper_V2 == nullptr) {
142     ALOGE("%s: mMapper is null!", __FUNCTION__);
143     return;
144   }
145 
146   if (mMapper_V3 != nullptr) {
147     auto ret = mMapper_V3->freeBuffer(const_cast<native_handle_t *>(handle));
148     if (!ret.isOk()) {
149       ALOGE("%s: mapper freeBuffer failed: %s", __FUNCTION__, ret.description().c_str());
150     }
151   } else {
152     auto ret = mMapper_V2->freeBuffer(const_cast<native_handle_t *>(handle));
153     if (!ret.isOk()) {
154       ALOGE("%s: mapper freeBuffer failed: %s", __FUNCTION__, ret.description().c_str()); }
155   }
156 }
157 
158 }  // namespace V3_0
159 }  // namespace composer
160 }  // namespace display
161 }  // namespace hardware
162 }  // namespace qti
163 }  // namespace vendor
164