1/* 2 * Copyright 2018 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#pragma once 18 19#ifndef LOG_TAG 20#warning "Mapper.h included without LOG_TAG" 21#endif 22 23#include <memory> 24 25#include <android/hardware/graphics/mapper/2.0/IMapper.h> 26#include <log/log.h> 27#include <mapper-hal/2.0/MapperHal.h> 28 29namespace android { 30namespace hardware { 31namespace graphics { 32namespace mapper { 33namespace V2_0 { 34namespace hal { 35 36namespace detail { 37 38// MapperImpl implements V2_*::IMapper on top of V2_*::hal::MapperHal 39template <typename Interface, typename Hal> 40class MapperImpl : public Interface { 41 public: 42 bool init(std::unique_ptr<Hal> hal) { 43 mHal = std::move(hal); 44 return true; 45 } 46 47 // IMapper 2.0 interface 48 49 Return<void> createDescriptor(const V2_0::IMapper::BufferDescriptorInfo& descriptorInfo, 50 IMapper::createDescriptor_cb hidl_cb) override { 51 BufferDescriptor descriptor; 52 Error error = mHal->createDescriptor(descriptorInfo, &descriptor); 53 hidl_cb(error, descriptor); 54 return Void(); 55 } 56 57 Return<void> importBuffer(const hidl_handle& rawHandle, 58 IMapper::importBuffer_cb hidl_cb) override { 59 if (!rawHandle.getNativeHandle()) { 60 hidl_cb(Error::BAD_BUFFER, nullptr); 61 return Void(); 62 } 63 64 native_handle_t* bufferHandle = nullptr; 65 Error error = mHal->importBuffer(rawHandle.getNativeHandle(), &bufferHandle); 66 if (error != Error::NONE) { 67 hidl_cb(error, nullptr); 68 return Void(); 69 } 70 71 void* buffer = addImportedBuffer(bufferHandle); 72 if (!buffer) { 73 mHal->freeBuffer(bufferHandle); 74 hidl_cb(Error::NO_RESOURCES, nullptr); 75 return Void(); 76 } 77 78 hidl_cb(error, buffer); 79 return Void(); 80 } 81 82 Return<Error> freeBuffer(void* buffer) override { 83 native_handle_t* bufferHandle = removeImportedBuffer(buffer); 84 if (!bufferHandle) { 85 return Error::BAD_BUFFER; 86 } 87 88 return mHal->freeBuffer(bufferHandle); 89 } 90 91 Return<void> lock(void* buffer, uint64_t cpuUsage, const V2_0::IMapper::Rect& accessRegion, 92 const hidl_handle& acquireFence, IMapper::lock_cb hidl_cb) override { 93 const native_handle_t* bufferHandle = getImportedBuffer(buffer); 94 if (!bufferHandle) { 95 hidl_cb(Error::BAD_BUFFER, nullptr); 96 return Void(); 97 } 98 99 base::unique_fd fenceFd; 100 Error error = getFenceFd(acquireFence, &fenceFd); 101 if (error != Error::NONE) { 102 hidl_cb(error, nullptr); 103 return Void(); 104 } 105 106 void* data = nullptr; 107 error = mHal->lock(bufferHandle, cpuUsage, accessRegion, std::move(fenceFd), &data); 108 hidl_cb(error, data); 109 return Void(); 110 } 111 112 Return<void> lockYCbCr(void* buffer, uint64_t cpuUsage, const V2_0::IMapper::Rect& accessRegion, 113 const hidl_handle& acquireFence, 114 IMapper::lockYCbCr_cb hidl_cb) override { 115 const native_handle_t* bufferHandle = getImportedBuffer(buffer); 116 if (!bufferHandle) { 117 hidl_cb(Error::BAD_BUFFER, YCbCrLayout{}); 118 return Void(); 119 } 120 121 base::unique_fd fenceFd; 122 Error error = getFenceFd(acquireFence, &fenceFd); 123 if (error != Error::NONE) { 124 hidl_cb(error, YCbCrLayout{}); 125 return Void(); 126 } 127 128 YCbCrLayout layout{}; 129 error = mHal->lockYCbCr(bufferHandle, cpuUsage, accessRegion, std::move(fenceFd), &layout); 130 hidl_cb(error, layout); 131 return Void(); 132 } 133 134 Return<void> unlock(void* buffer, IMapper::unlock_cb hidl_cb) override { 135 const native_handle_t* bufferHandle = getImportedBuffer(buffer); 136 if (!bufferHandle) { 137 hidl_cb(Error::BAD_BUFFER, nullptr); 138 return Void(); 139 } 140 141 base::unique_fd fenceFd; 142 Error error = mHal->unlock(bufferHandle, &fenceFd); 143 if (error != Error::NONE) { 144 hidl_cb(error, nullptr); 145 return Void(); 146 } 147 148 NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0); 149 hidl_cb(error, getFenceHandle(fenceFd, fenceStorage)); 150 return Void(); 151 } 152 153 protected: 154 // these functions can be overriden to do true imported buffer management 155 virtual void* addImportedBuffer(native_handle_t* bufferHandle) { 156 return static_cast<void*>(bufferHandle); 157 } 158 159 virtual native_handle_t* removeImportedBuffer(void* buffer) { 160 return static_cast<native_handle_t*>(buffer); 161 } 162 163 virtual const native_handle_t* getImportedBuffer(void* buffer) const { 164 return static_cast<const native_handle_t*>(buffer); 165 } 166 167 // convert fenceFd to or from hidl_handle 168 static Error getFenceFd(const hidl_handle& fenceHandle, base::unique_fd* outFenceFd) { 169 auto handle = fenceHandle.getNativeHandle(); 170 if (handle && handle->numFds > 1) { 171 ALOGE("invalid fence handle with %d fds", handle->numFds); 172 return Error::BAD_VALUE; 173 } 174 175 int fenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1; 176 if (fenceFd >= 0) { 177 fenceFd = dup(fenceFd); 178 if (fenceFd < 0) { 179 return Error::NO_RESOURCES; 180 } 181 } 182 183 outFenceFd->reset(fenceFd); 184 185 return Error::NONE; 186 } 187 188 static hidl_handle getFenceHandle(const base::unique_fd& fenceFd, char* handleStorage) { 189 native_handle_t* handle = nullptr; 190 if (fenceFd >= 0) { 191 handle = native_handle_init(handleStorage, 1, 0); 192 handle->data[0] = fenceFd; 193 } 194 195 return hidl_handle(handle); 196 } 197 198 std::unique_ptr<Hal> mHal; 199}; 200 201} // namespace detail 202 203using Mapper = detail::MapperImpl<IMapper, MapperHal>; 204 205} // namespace hal 206} // namespace V2_0 207} // namespace mapper 208} // namespace graphics 209} // namespace hardware 210} // namespace android 211