• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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