1 /* 2 * Copyright 2016 The Android Open Source Project 3 * * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #pragma once 17 18 #ifndef LOG_TAG 19 #warning "Gralloc1Hal.h included without LOG_TAG" 20 #endif 21 22 #include <inttypes.h> 23 24 #include <vector> 25 26 #include <hardware/gralloc1.h> 27 #include <log/log.h> 28 #include <mapper-hal/2.0/MapperHal.h> 29 #include <mapper-passthrough/2.0/GrallocBufferDescriptor.h> 30 31 namespace android { 32 namespace hardware { 33 namespace graphics { 34 namespace mapper { 35 namespace V2_0 { 36 namespace passthrough { 37 38 namespace detail { 39 40 using common::V1_0::BufferUsage; 41 42 // Gralloc1HalImpl implements V2_*::hal::MapperHal on top of gralloc1 43 template <typename Hal> 44 class Gralloc1HalImpl : public Hal { 45 public: ~Gralloc1HalImpl()46 ~Gralloc1HalImpl() { 47 if (mDevice) { 48 gralloc1_close(mDevice); 49 } 50 } 51 initWithModule(const hw_module_t * module)52 bool initWithModule(const hw_module_t* module) { 53 int result = gralloc1_open(module, &mDevice); 54 if (result) { 55 ALOGE("failed to open gralloc1 device: %s", strerror(-result)); 56 mDevice = nullptr; 57 return false; 58 } 59 60 initCapabilities(); 61 62 if (!initDispatch()) { 63 gralloc1_close(mDevice); 64 mDevice = nullptr; 65 return false; 66 } 67 68 return true; 69 } 70 createDescriptor(const IMapper::BufferDescriptorInfo & descriptorInfo,BufferDescriptor * outDescriptor)71 Error createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo, 72 BufferDescriptor* outDescriptor) override { 73 if (!descriptorInfo.width || !descriptorInfo.height || !descriptorInfo.layerCount) { 74 return Error::BAD_VALUE; 75 } 76 77 if (!mCapabilities.layeredBuffers && descriptorInfo.layerCount != 1) { 78 return Error::UNSUPPORTED; 79 } 80 81 if (descriptorInfo.format == static_cast<PixelFormat>(0)) { 82 return Error::BAD_VALUE; 83 } 84 85 const uint64_t validUsageBits = getValidBufferUsageMask(); 86 if (descriptorInfo.usage & ~validUsageBits) { 87 ALOGW("buffer descriptor with invalid usage bits 0x%" PRIx64, 88 descriptorInfo.usage & ~validUsageBits); 89 } 90 91 *outDescriptor = grallocEncodeBufferDescriptor(descriptorInfo); 92 93 return Error::NONE; 94 } 95 importBuffer(const native_handle_t * rawHandle,native_handle_t ** outBufferHandle)96 Error importBuffer(const native_handle_t* rawHandle, 97 native_handle_t** outBufferHandle) override { 98 native_handle_t* bufferHandle = native_handle_clone(rawHandle); 99 if (!bufferHandle) { 100 return Error::NO_RESOURCES; 101 } 102 103 int32_t error = mDispatch.retain(mDevice, bufferHandle); 104 if (error != GRALLOC1_ERROR_NONE) { 105 native_handle_close(bufferHandle); 106 native_handle_delete(bufferHandle); 107 return toError(error); 108 } 109 110 *outBufferHandle = bufferHandle; 111 112 return Error::NONE; 113 } 114 freeBuffer(native_handle_t * bufferHandle)115 Error freeBuffer(native_handle_t* bufferHandle) override { 116 int32_t error = mDispatch.release(mDevice, bufferHandle); 117 if (error == GRALLOC1_ERROR_NONE && !mCapabilities.releaseImplyDelete) { 118 native_handle_close(bufferHandle); 119 native_handle_delete(bufferHandle); 120 } 121 return toError(error); 122 } 123 lock(const native_handle_t * bufferHandle,uint64_t cpuUsage,const IMapper::Rect & accessRegion,base::unique_fd fenceFd,void ** outData)124 Error lock(const native_handle_t* bufferHandle, uint64_t cpuUsage, 125 const IMapper::Rect& accessRegion, base::unique_fd fenceFd, 126 void** outData) override { 127 const uint64_t consumerUsage = 128 cpuUsage & ~static_cast<uint64_t>(BufferUsage::CPU_WRITE_MASK); 129 const auto accessRect = asGralloc1Rect(accessRegion); 130 void* data = nullptr; 131 int32_t error = mDispatch.lock(mDevice, bufferHandle, cpuUsage, consumerUsage, &accessRect, 132 &data, fenceFd.release()); 133 if (error == GRALLOC1_ERROR_NONE) { 134 *outData = data; 135 } 136 137 return toError(error); 138 } 139 lockYCbCr(const native_handle_t * bufferHandle,uint64_t cpuUsage,const IMapper::Rect & accessRegion,base::unique_fd fenceFd,YCbCrLayout * outLayout)140 Error lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage, 141 const IMapper::Rect& accessRegion, base::unique_fd fenceFd, 142 YCbCrLayout* outLayout) override { 143 // prepare flex layout 144 android_flex_layout flex = {}; 145 int32_t error = mDispatch.getNumFlexPlanes(mDevice, bufferHandle, &flex.num_planes); 146 if (error != GRALLOC1_ERROR_NONE) { 147 return toError(error); 148 } 149 std::vector<android_flex_plane_t> flexPlanes(flex.num_planes); 150 flex.planes = flexPlanes.data(); 151 152 const uint64_t consumerUsage = 153 cpuUsage & ~static_cast<uint64_t>(BufferUsage::CPU_WRITE_MASK); 154 const auto accessRect = asGralloc1Rect(accessRegion); 155 error = mDispatch.lockFlex(mDevice, bufferHandle, cpuUsage, consumerUsage, &accessRect, 156 &flex, fenceFd.release()); 157 if (error == GRALLOC1_ERROR_NONE && !toYCbCrLayout(flex, outLayout)) { 158 ALOGD("unable to convert android_flex_layout to YCbCrLayout"); 159 // undo the lock 160 unlock(bufferHandle, &fenceFd); 161 error = GRALLOC1_ERROR_BAD_HANDLE; 162 } 163 164 return toError(error); 165 } 166 unlock(const native_handle_t * bufferHandle,base::unique_fd * outFenceFd)167 Error unlock(const native_handle_t* bufferHandle, base::unique_fd* outFenceFd) override { 168 int fenceFd = -1; 169 int32_t error = mDispatch.unlock(mDevice, bufferHandle, &fenceFd); 170 171 // we always own the fenceFd even when unlock failed 172 outFenceFd->reset(fenceFd); 173 return toError(error); 174 } 175 176 protected: initCapabilities()177 virtual void initCapabilities() { 178 uint32_t count = 0; 179 mDevice->getCapabilities(mDevice, &count, nullptr); 180 181 std::vector<int32_t> capabilities(count); 182 mDevice->getCapabilities(mDevice, &count, capabilities.data()); 183 capabilities.resize(count); 184 185 for (auto capability : capabilities) { 186 switch (capability) { 187 case GRALLOC1_CAPABILITY_LAYERED_BUFFERS: 188 mCapabilities.layeredBuffers = true; 189 break; 190 case GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE: 191 mCapabilities.releaseImplyDelete = true; 192 break; 193 } 194 } 195 } 196 197 template <typename T> initDispatch(gralloc1_function_descriptor_t desc,T * outPfn)198 bool initDispatch(gralloc1_function_descriptor_t desc, T* outPfn) { 199 auto pfn = mDevice->getFunction(mDevice, desc); 200 if (pfn) { 201 *outPfn = reinterpret_cast<T>(pfn); 202 return true; 203 } else { 204 ALOGE("failed to get gralloc1 function %d", desc); 205 return false; 206 } 207 } 208 initDispatch()209 virtual bool initDispatch() { 210 if (!initDispatch(GRALLOC1_FUNCTION_RETAIN, &mDispatch.retain) || 211 !initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release) || 212 !initDispatch(GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES, &mDispatch.getNumFlexPlanes) || 213 !initDispatch(GRALLOC1_FUNCTION_LOCK, &mDispatch.lock) || 214 !initDispatch(GRALLOC1_FUNCTION_LOCK_FLEX, &mDispatch.lockFlex) || 215 !initDispatch(GRALLOC1_FUNCTION_UNLOCK, &mDispatch.unlock)) { 216 return false; 217 } 218 219 return true; 220 } 221 getValidBufferUsageMask()222 virtual uint64_t getValidBufferUsageMask() const { 223 return BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK | BufferUsage::GPU_TEXTURE | 224 BufferUsage::GPU_RENDER_TARGET | BufferUsage::COMPOSER_OVERLAY | 225 BufferUsage::COMPOSER_CLIENT_TARGET | BufferUsage::PROTECTED | 226 BufferUsage::COMPOSER_CURSOR | BufferUsage::VIDEO_ENCODER | 227 BufferUsage::CAMERA_OUTPUT | BufferUsage::CAMERA_INPUT | BufferUsage::RENDERSCRIPT | 228 BufferUsage::VIDEO_DECODER | BufferUsage::SENSOR_DIRECT_DATA | 229 BufferUsage::GPU_DATA_BUFFER | BufferUsage::VENDOR_MASK | 230 BufferUsage::VENDOR_MASK_HI; 231 } 232 toError(int32_t error)233 static Error toError(int32_t error) { 234 switch (error) { 235 case GRALLOC1_ERROR_NONE: 236 return Error::NONE; 237 case GRALLOC1_ERROR_BAD_DESCRIPTOR: 238 return Error::BAD_DESCRIPTOR; 239 case GRALLOC1_ERROR_BAD_HANDLE: 240 return Error::BAD_BUFFER; 241 case GRALLOC1_ERROR_BAD_VALUE: 242 return Error::BAD_VALUE; 243 case GRALLOC1_ERROR_NOT_SHARED: 244 return Error::NONE; // this is fine 245 case GRALLOC1_ERROR_NO_RESOURCES: 246 return Error::NO_RESOURCES; 247 case GRALLOC1_ERROR_UNDEFINED: 248 case GRALLOC1_ERROR_UNSUPPORTED: 249 default: 250 return Error::UNSUPPORTED; 251 } 252 } 253 toYCbCrLayout(const android_flex_layout & flex,YCbCrLayout * outLayout)254 static bool toYCbCrLayout(const android_flex_layout& flex, YCbCrLayout* outLayout) { 255 // must be YCbCr 256 if (flex.format != FLEX_FORMAT_YCbCr || flex.num_planes < 3) { 257 return false; 258 } 259 260 for (int i = 0; i < 3; i++) { 261 const auto& plane = flex.planes[i]; 262 // must have 8-bit depth 263 if (plane.bits_per_component != 8 || plane.bits_used != 8) { 264 return false; 265 } 266 267 if (plane.component == FLEX_COMPONENT_Y) { 268 // Y must not be interleaved 269 if (plane.h_increment != 1) { 270 return false; 271 } 272 } else { 273 // Cb and Cr can be interleaved 274 if (plane.h_increment != 1 && plane.h_increment != 2) { 275 return false; 276 } 277 } 278 279 if (!plane.v_increment) { 280 return false; 281 } 282 } 283 284 if (flex.planes[0].component != FLEX_COMPONENT_Y || 285 flex.planes[1].component != FLEX_COMPONENT_Cb || 286 flex.planes[2].component != FLEX_COMPONENT_Cr) { 287 return false; 288 } 289 290 const auto& y = flex.planes[0]; 291 const auto& cb = flex.planes[1]; 292 const auto& cr = flex.planes[2]; 293 294 if (cb.h_increment != cr.h_increment || cb.v_increment != cr.v_increment) { 295 return false; 296 } 297 298 outLayout->y = y.top_left; 299 outLayout->cb = cb.top_left; 300 outLayout->cr = cr.top_left; 301 outLayout->yStride = y.v_increment; 302 outLayout->cStride = cb.v_increment; 303 outLayout->chromaStep = cb.h_increment; 304 305 return true; 306 } 307 asGralloc1Rect(const IMapper::Rect & rect)308 static gralloc1_rect_t asGralloc1Rect(const IMapper::Rect& rect) { 309 return gralloc1_rect_t{rect.left, rect.top, rect.width, rect.height}; 310 } 311 312 gralloc1_device_t* mDevice = nullptr; 313 314 struct { 315 bool layeredBuffers; 316 bool releaseImplyDelete; 317 } mCapabilities = {}; 318 319 struct { 320 GRALLOC1_PFN_RETAIN retain; 321 GRALLOC1_PFN_RELEASE release; 322 GRALLOC1_PFN_GET_NUM_FLEX_PLANES getNumFlexPlanes; 323 GRALLOC1_PFN_LOCK lock; 324 GRALLOC1_PFN_LOCK_FLEX lockFlex; 325 GRALLOC1_PFN_UNLOCK unlock; 326 } mDispatch = {}; 327 }; 328 329 } // namespace detail 330 331 using Gralloc1Hal = detail::Gralloc1HalImpl<hal::MapperHal>; 332 333 } // namespace passthrough 334 } // namespace V2_0 335 } // namespace mapper 336 } // namespace graphics 337 } // namespace hardware 338 } // namespace android 339