1 /* 2 * Copyright 2019 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 #include <cutils/native_handle.h> 18 #include <ui/BufferQueueDefs.h> 19 #include <types.h> 20 #include <system/window.h> 21 #include <vndk/hardware_buffer.h> 22 23 namespace android { 24 namespace hardware { 25 namespace graphics { 26 namespace bufferqueue { 27 namespace V2_0 { 28 namespace utils { 29 30 // TODO: move this into ui/BufferQueueDefs.h so that we don't need 31 // to include headers from libgui. 32 enum { 33 // The API number used to indicate the currently connected producer 34 CURRENTLY_CONNECTED_API = -1, 35 // The API number used to indicate that no producer is connected 36 NO_CONNECTED_API = 0, 37 }; 38 39 // Status 40 // ====== 41 42 bool b2h(status_t from, HStatus* to, 43 bool* bufferNeedsReallocation, bool* releaseAllBuffers) { 44 switch (from) { 45 case OK: 46 *to = HStatus::OK; break; 47 case NO_MEMORY: 48 *to = HStatus::NO_MEMORY; break; 49 case NO_INIT: 50 *to = HStatus::NO_INIT; break; 51 case BAD_VALUE: 52 *to = HStatus::BAD_VALUE; break; 53 case DEAD_OBJECT: 54 *to = HStatus::DEAD_OBJECT; break; 55 case INVALID_OPERATION: 56 *to = HStatus::INVALID_OPERATION; break; 57 case TIMED_OUT: 58 *to = HStatus::TIMED_OUT; break; 59 case WOULD_BLOCK: 60 *to = HStatus::WOULD_BLOCK; break; 61 case UNKNOWN_ERROR: 62 *to = HStatus::UNKNOWN_ERROR; break; 63 default: 64 status_t mask = 65 (bufferNeedsReallocation ? BufferQueueDefs::BUFFER_NEEDS_REALLOCATION : 0) 66 | (releaseAllBuffers ? BufferQueueDefs::RELEASE_ALL_BUFFERS : 0); 67 if (from & ~mask) { 68 *to = static_cast<HStatus>(from); 69 } else { 70 *to = HStatus::OK; 71 if (bufferNeedsReallocation) { 72 *bufferNeedsReallocation = from & BufferQueueDefs::BUFFER_NEEDS_REALLOCATION; 73 } 74 if (releaseAllBuffers) { 75 *releaseAllBuffers = from & BufferQueueDefs::RELEASE_ALL_BUFFERS; 76 } 77 } 78 } 79 return true; 80 } 81 82 bool h2b(HStatus from, status_t* to) { 83 switch (from) { 84 case HStatus::OK: 85 *to = OK; break; 86 case HStatus::NO_MEMORY: 87 *to = NO_MEMORY; break; 88 case HStatus::NO_INIT: 89 *to = NO_INIT; break; 90 case HStatus::BAD_VALUE: 91 *to = BAD_VALUE; break; 92 case HStatus::DEAD_OBJECT: 93 *to = DEAD_OBJECT; break; 94 case HStatus::INVALID_OPERATION: 95 *to = INVALID_OPERATION; break; 96 case HStatus::TIMED_OUT: 97 *to = TIMED_OUT; break; 98 case HStatus::WOULD_BLOCK: 99 *to = WOULD_BLOCK; break; 100 case HStatus::UNKNOWN_ERROR: 101 *to = UNKNOWN_ERROR; break; 102 default: 103 *to = static_cast<status_t>(from); 104 } 105 return true; 106 } 107 108 // Fence 109 // ===== 110 111 HFenceWrapper::HFenceWrapper(native_handle_t* h) : mHandle{h} { 112 } 113 114 HFenceWrapper::~HFenceWrapper() { 115 native_handle_delete(mHandle); 116 } 117 118 HFenceWrapper& HFenceWrapper::set(native_handle_t* h) { 119 native_handle_delete(mHandle); 120 mHandle = h; 121 return *this; 122 } 123 124 HFenceWrapper& HFenceWrapper::operator=(native_handle_t* h) { 125 return set(h); 126 } 127 128 hidl_handle HFenceWrapper::getHandle() const { 129 return hidl_handle{mHandle}; 130 } 131 132 HFenceWrapper::operator hidl_handle() const { 133 return getHandle(); 134 } 135 136 bool b2h(sp<BFence> const& from, HFenceWrapper* to) { 137 if (!from) { 138 to->set(nullptr); 139 return true; 140 } 141 int fenceFd = from->get(); 142 if (fenceFd == -1) { 143 to->set(nullptr); 144 return true; 145 } 146 native_handle_t* nh = native_handle_create(1, 0); 147 if (!nh) { 148 return false; 149 } 150 nh->data[0] = fenceFd; 151 to->set(nh); 152 return true; 153 } 154 155 bool h2b(native_handle_t const* from, sp<BFence>* to) { 156 if (!from || from->numFds == 0) { 157 *to = new ::android::Fence(); 158 return true; 159 } 160 if (from->numFds != 1 || from->numInts != 0) { 161 return false; 162 } 163 *to = new BFence(dup(from->data[0])); 164 return true; 165 } 166 167 // ConnectionType 168 // ============== 169 170 bool b2h(int from, HConnectionType* to) { 171 *to = static_cast<HConnectionType>(from); 172 switch (from) { 173 case CURRENTLY_CONNECTED_API: 174 *to = HConnectionType::CURRENTLY_CONNECTED; break; 175 case NATIVE_WINDOW_API_EGL: 176 *to = HConnectionType::EGL; break; 177 case NATIVE_WINDOW_API_CPU: 178 *to = HConnectionType::CPU; break; 179 case NATIVE_WINDOW_API_MEDIA: 180 *to = HConnectionType::MEDIA; break; 181 case NATIVE_WINDOW_API_CAMERA: 182 *to = HConnectionType::CAMERA; break; 183 } 184 return true; 185 } 186 187 bool h2b(HConnectionType from, int* to) { 188 *to = static_cast<int>(from); 189 switch (from) { 190 case HConnectionType::CURRENTLY_CONNECTED: 191 *to = CURRENTLY_CONNECTED_API; break; 192 case HConnectionType::EGL: 193 *to = NATIVE_WINDOW_API_EGL; break; 194 case HConnectionType::CPU: 195 *to = NATIVE_WINDOW_API_CPU; break; 196 case HConnectionType::MEDIA: 197 *to = NATIVE_WINDOW_API_MEDIA; break; 198 case HConnectionType::CAMERA: 199 *to = NATIVE_WINDOW_API_CAMERA; break; 200 } 201 return true; 202 } 203 204 // Rect 205 // ==== 206 207 bool b2h(BRect const& from, HRect* to) { 208 BRect* dst = reinterpret_cast<BRect*>(to->data()); 209 dst->left = from.left; 210 dst->top = from.top; 211 dst->right = from.right; 212 dst->bottom = from.bottom; 213 return true; 214 } 215 216 bool h2b(HRect const& from, BRect* to) { 217 BRect const* src = reinterpret_cast<BRect const*>(from.data()); 218 to->left = src->left; 219 to->top = src->top; 220 to->right = src->right; 221 to->bottom = src->bottom; 222 return true; 223 } 224 225 // Region 226 // ====== 227 228 bool b2h(BRegion const& from, HRegion* to) { 229 size_t numRects; 230 BRect const* rectArray = from.getArray(&numRects); 231 to->resize(numRects); 232 for (size_t i = 0; i < numRects; ++i) { 233 if (!b2h(rectArray[i], &(*to)[i])) { 234 return false; 235 } 236 } 237 return true; 238 } 239 240 bool h2b(HRegion const& from, BRegion* to) { 241 if (from.size() > 0) { 242 BRect bRect; 243 if (!h2b(from[0], &bRect)) { 244 return false; 245 } 246 to->set(bRect); 247 for (size_t i = 1; i < from.size(); ++i) { 248 if (!h2b(from[i], &bRect)) { 249 return false; 250 } 251 to->addRectUnchecked( 252 static_cast<int>(bRect.left), 253 static_cast<int>(bRect.top), 254 static_cast<int>(bRect.right), 255 static_cast<int>(bRect.bottom)); 256 } 257 } else { 258 to->clear(); 259 } 260 return true; 261 } 262 263 // GraphicBuffer 264 // ============= 265 266 // The handle is not cloned. Its lifetime is tied to the original GraphicBuffer. 267 bool b2h(sp<GraphicBuffer> const& from, HardwareBuffer* to, 268 uint32_t* toGenerationNumber) { 269 if (!from) { 270 return false; 271 } 272 AHardwareBuffer* hwBuffer = from->toAHardwareBuffer(); 273 to->nativeHandle.setTo( 274 const_cast<native_handle_t*>( 275 AHardwareBuffer_getNativeHandle(hwBuffer)), 276 false); 277 AHardwareBuffer_describe( 278 hwBuffer, 279 reinterpret_cast<AHardwareBuffer_Desc*>(to->description.data())); 280 if (toGenerationNumber) { 281 *toGenerationNumber = from->getGenerationNumber(); 282 } 283 return true; 284 } 285 286 // The handle is cloned. 287 bool h2b(HardwareBuffer const& from, sp<GraphicBuffer>* to) { 288 AHardwareBuffer_Desc const* desc = 289 reinterpret_cast<AHardwareBuffer_Desc const*>( 290 from.description.data()); 291 native_handle_t const* handle = from.nativeHandle; 292 AHardwareBuffer* hwBuffer; 293 if (AHardwareBuffer_createFromHandle( 294 desc, handle, AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE, 295 &hwBuffer) != OK) { 296 return false; 297 } 298 *to = GraphicBuffer::fromAHardwareBuffer(hwBuffer); 299 AHardwareBuffer_release(hwBuffer); 300 return true; 301 } 302 303 } // namespace utils 304 } // namespace V2_0 305 } // namespace bufferqueue 306 } // namespace graphics 307 } // namespace hardware 308 } // namespace android 309 310