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 "Gralloc0Hal.h included without LOG_TAG" 20 #endif 21 22 #include <inttypes.h> 23 24 #include <hardware/gralloc.h> 25 #include <log/log.h> 26 #include <mapper-hal/2.0/MapperHal.h> 27 #include <mapper-passthrough/2.0/GrallocBufferDescriptor.h> 28 #include <sync/sync.h> 29 30 namespace android { 31 namespace hardware { 32 namespace graphics { 33 namespace mapper { 34 namespace V2_0 { 35 namespace passthrough { 36 37 namespace detail { 38 39 using common::V1_0::BufferUsage; 40 41 // Gralloc0HalImpl implements V2_*::hal::MapperHal on top of gralloc0 42 template <typename Hal> 43 class Gralloc0HalImpl : public Hal { 44 public: initWithModule(const hw_module_t * module)45 bool initWithModule(const hw_module_t* module) { 46 mModule = reinterpret_cast<const gralloc_module_t*>(module); 47 mMinor = module->module_api_version & 0xff; 48 return true; 49 } 50 createDescriptor(const IMapper::BufferDescriptorInfo & descriptorInfo,BufferDescriptor * outDescriptor)51 Error createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo, 52 BufferDescriptor* outDescriptor) override { 53 if (!descriptorInfo.width || !descriptorInfo.height || !descriptorInfo.layerCount) { 54 return Error::BAD_VALUE; 55 } 56 57 if (descriptorInfo.layerCount != 1) { 58 return Error::UNSUPPORTED; 59 } 60 61 if (descriptorInfo.format == static_cast<PixelFormat>(0)) { 62 return Error::BAD_VALUE; 63 } 64 65 const uint64_t validUsageBits = getValidBufferUsageMask(); 66 if (descriptorInfo.usage & ~validUsageBits) { 67 ALOGW("buffer descriptor with invalid usage bits 0x%" PRIx64, 68 descriptorInfo.usage & ~validUsageBits); 69 } 70 71 *outDescriptor = grallocEncodeBufferDescriptor(descriptorInfo); 72 73 return Error::NONE; 74 } 75 importBuffer(const native_handle_t * rawHandle,native_handle_t ** outBufferHandle)76 Error importBuffer(const native_handle_t* rawHandle, 77 native_handle_t** outBufferHandle) override { 78 native_handle_t* bufferHandle = native_handle_clone(rawHandle); 79 if (!bufferHandle) { 80 return Error::NO_RESOURCES; 81 } 82 83 if (mModule->registerBuffer(mModule, bufferHandle)) { 84 native_handle_close(bufferHandle); 85 native_handle_delete(bufferHandle); 86 return Error::BAD_BUFFER; 87 } 88 89 *outBufferHandle = bufferHandle; 90 91 return Error::NONE; 92 } 93 freeBuffer(native_handle_t * bufferHandle)94 Error freeBuffer(native_handle_t* bufferHandle) override { 95 if (mModule->unregisterBuffer(mModule, bufferHandle)) { 96 return Error::BAD_BUFFER; 97 } 98 99 native_handle_close(bufferHandle); 100 native_handle_delete(bufferHandle); 101 return Error::NONE; 102 } 103 lock(const native_handle_t * bufferHandle,uint64_t cpuUsage,const IMapper::Rect & accessRegion,base::unique_fd fenceFd,void ** outData)104 Error lock(const native_handle_t* bufferHandle, uint64_t cpuUsage, 105 const IMapper::Rect& accessRegion, base::unique_fd fenceFd, 106 void** outData) override { 107 int result; 108 void* data = nullptr; 109 if (mMinor >= 3 && mModule->lockAsync) { 110 result = mModule->lockAsync(mModule, bufferHandle, cpuUsage, accessRegion.left, 111 accessRegion.top, accessRegion.width, accessRegion.height, 112 &data, fenceFd.release()); 113 } else { 114 waitFenceFd(fenceFd, "Gralloc0Hal::lock"); 115 116 result = 117 mModule->lock(mModule, bufferHandle, cpuUsage, accessRegion.left, accessRegion.top, 118 accessRegion.width, accessRegion.height, &data); 119 } 120 121 if (result) { 122 return Error::BAD_VALUE; 123 } 124 125 *outData = data; 126 return Error::NONE; 127 } 128 lockYCbCr(const native_handle_t * bufferHandle,uint64_t cpuUsage,const IMapper::Rect & accessRegion,base::unique_fd fenceFd,YCbCrLayout * outLayout)129 Error lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage, 130 const IMapper::Rect& accessRegion, base::unique_fd fenceFd, 131 YCbCrLayout* outLayout) override { 132 int result; 133 android_ycbcr ycbcr = {}; 134 if (mMinor >= 3 && mModule->lockAsync_ycbcr) { 135 result = mModule->lockAsync_ycbcr(mModule, bufferHandle, cpuUsage, accessRegion.left, 136 accessRegion.top, accessRegion.width, 137 accessRegion.height, &ycbcr, fenceFd.release()); 138 } else { 139 waitFenceFd(fenceFd, "Gralloc0Hal::lockYCbCr"); 140 141 if (mModule->lock_ycbcr) { 142 result = mModule->lock_ycbcr(mModule, bufferHandle, cpuUsage, accessRegion.left, 143 accessRegion.top, accessRegion.width, 144 accessRegion.height, &ycbcr); 145 } else { 146 result = -EINVAL; 147 } 148 } 149 150 if (result) { 151 return Error::BAD_VALUE; 152 } 153 154 outLayout->y = ycbcr.y; 155 outLayout->cb = ycbcr.cb; 156 outLayout->cr = ycbcr.cr; 157 outLayout->yStride = ycbcr.ystride; 158 outLayout->cStride = ycbcr.cstride; 159 outLayout->chromaStep = ycbcr.chroma_step; 160 return Error::NONE; 161 } 162 unlock(const native_handle_t * bufferHandle,base::unique_fd * outFenceFd)163 Error unlock(const native_handle_t* bufferHandle, base::unique_fd* outFenceFd) override { 164 int result; 165 int fenceFd = -1; 166 if (mMinor >= 3 && mModule->unlockAsync) { 167 result = mModule->unlockAsync(mModule, bufferHandle, &fenceFd); 168 } else { 169 result = mModule->unlock(mModule, bufferHandle); 170 } 171 172 // we always own the fenceFd even when unlock failed 173 outFenceFd->reset(fenceFd); 174 return result ? Error::BAD_VALUE : Error::NONE; 175 } 176 177 protected: getValidBufferUsageMask()178 virtual uint64_t getValidBufferUsageMask() const { 179 return BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK | BufferUsage::GPU_TEXTURE | 180 BufferUsage::GPU_RENDER_TARGET | BufferUsage::COMPOSER_OVERLAY | 181 BufferUsage::COMPOSER_CLIENT_TARGET | BufferUsage::PROTECTED | 182 BufferUsage::COMPOSER_CURSOR | BufferUsage::VIDEO_ENCODER | 183 BufferUsage::CAMERA_OUTPUT | BufferUsage::CAMERA_INPUT | BufferUsage::RENDERSCRIPT | 184 BufferUsage::VIDEO_DECODER | BufferUsage::SENSOR_DIRECT_DATA | 185 BufferUsage::GPU_DATA_BUFFER | BufferUsage::VENDOR_MASK; 186 } 187 waitFenceFd(const base::unique_fd & fenceFd,const char * logname)188 static void waitFenceFd(const base::unique_fd& fenceFd, const char* logname) { 189 if (fenceFd < 0) { 190 return; 191 } 192 193 const int warningTimeout = 3500; 194 const int error = sync_wait(fenceFd, warningTimeout); 195 if (error < 0 && errno == ETIME) { 196 ALOGE("%s: fence %d didn't signal in %u ms", logname, fenceFd.get(), warningTimeout); 197 sync_wait(fenceFd, -1); 198 } 199 } 200 201 const gralloc_module_t* mModule = nullptr; 202 uint8_t mMinor = 0; 203 }; 204 205 } // namespace detail 206 207 using Gralloc0Hal = detail::Gralloc0HalImpl<hal::MapperHal>; 208 209 } // namespace passthrough 210 } // namespace V2_0 211 } // namespace mapper 212 } // namespace graphics 213 } // namespace hardware 214 } // namespace android 215