1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker *
4*4d7e907cSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker *
8*4d7e907cSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker *
10*4d7e907cSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker */
16*4d7e907cSAndroid Build Coastguard Worker
17*4d7e907cSAndroid Build Coastguard Worker #define LOG_TAG "HandleImporter"
18*4d7e907cSAndroid Build Coastguard Worker #include "HandleImporter.h"
19*4d7e907cSAndroid Build Coastguard Worker
20*4d7e907cSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/common/Smpte2086.h>
21*4d7e907cSAndroid Build Coastguard Worker #include <gralloctypes/Gralloc4.h>
22*4d7e907cSAndroid Build Coastguard Worker #include <log/log.h>
23*4d7e907cSAndroid Build Coastguard Worker #include <ui/GraphicBufferMapper.h>
24*4d7e907cSAndroid Build Coastguard Worker
25*4d7e907cSAndroid Build Coastguard Worker namespace android {
26*4d7e907cSAndroid Build Coastguard Worker namespace hardware {
27*4d7e907cSAndroid Build Coastguard Worker namespace camera {
28*4d7e907cSAndroid Build Coastguard Worker namespace common {
29*4d7e907cSAndroid Build Coastguard Worker namespace helper {
30*4d7e907cSAndroid Build Coastguard Worker
31*4d7e907cSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::common::PlaneLayout;
32*4d7e907cSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
33*4d7e907cSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
34*4d7e907cSAndroid Build Coastguard Worker using aidl::android::hardware::graphics::common::Smpte2086;
35*4d7e907cSAndroid Build Coastguard Worker
HandleImporter()36*4d7e907cSAndroid Build Coastguard Worker HandleImporter::HandleImporter() : mInitialized(false) {}
37*4d7e907cSAndroid Build Coastguard Worker
initializeLocked()38*4d7e907cSAndroid Build Coastguard Worker void HandleImporter::initializeLocked() {
39*4d7e907cSAndroid Build Coastguard Worker if (mInitialized) {
40*4d7e907cSAndroid Build Coastguard Worker return;
41*4d7e907cSAndroid Build Coastguard Worker }
42*4d7e907cSAndroid Build Coastguard Worker
43*4d7e907cSAndroid Build Coastguard Worker GraphicBufferMapper::preloadHal();
44*4d7e907cSAndroid Build Coastguard Worker mInitialized = true;
45*4d7e907cSAndroid Build Coastguard Worker return;
46*4d7e907cSAndroid Build Coastguard Worker }
47*4d7e907cSAndroid Build Coastguard Worker
cleanup()48*4d7e907cSAndroid Build Coastguard Worker void HandleImporter::cleanup() {
49*4d7e907cSAndroid Build Coastguard Worker mInitialized = false;
50*4d7e907cSAndroid Build Coastguard Worker }
51*4d7e907cSAndroid Build Coastguard Worker
importBufferInternal(buffer_handle_t & handle)52*4d7e907cSAndroid Build Coastguard Worker bool HandleImporter::importBufferInternal(buffer_handle_t& handle) {
53*4d7e907cSAndroid Build Coastguard Worker buffer_handle_t importedHandle;
54*4d7e907cSAndroid Build Coastguard Worker auto status = GraphicBufferMapper::get().importBufferNoValidate(handle, &importedHandle);
55*4d7e907cSAndroid Build Coastguard Worker if (status != OK) {
56*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: mapper importBuffer failed: %d", __FUNCTION__, status);
57*4d7e907cSAndroid Build Coastguard Worker return false;
58*4d7e907cSAndroid Build Coastguard Worker }
59*4d7e907cSAndroid Build Coastguard Worker
60*4d7e907cSAndroid Build Coastguard Worker handle = importedHandle;
61*4d7e907cSAndroid Build Coastguard Worker return true;
62*4d7e907cSAndroid Build Coastguard Worker }
63*4d7e907cSAndroid Build Coastguard Worker
lockYCbCr(buffer_handle_t & buf,uint64_t cpuUsage,const android::Rect & accessRegion)64*4d7e907cSAndroid Build Coastguard Worker android_ycbcr HandleImporter::lockYCbCr(buffer_handle_t& buf, uint64_t cpuUsage,
65*4d7e907cSAndroid Build Coastguard Worker const android::Rect& accessRegion) {
66*4d7e907cSAndroid Build Coastguard Worker Mutex::Autolock lock(mLock);
67*4d7e907cSAndroid Build Coastguard Worker
68*4d7e907cSAndroid Build Coastguard Worker if (!mInitialized) {
69*4d7e907cSAndroid Build Coastguard Worker initializeLocked();
70*4d7e907cSAndroid Build Coastguard Worker }
71*4d7e907cSAndroid Build Coastguard Worker android_ycbcr layout;
72*4d7e907cSAndroid Build Coastguard Worker
73*4d7e907cSAndroid Build Coastguard Worker status_t status = GraphicBufferMapper::get().lockYCbCr(buf, cpuUsage, accessRegion, &layout);
74*4d7e907cSAndroid Build Coastguard Worker
75*4d7e907cSAndroid Build Coastguard Worker if (status != OK) {
76*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: failed to lockYCbCr error %d!", __FUNCTION__, status);
77*4d7e907cSAndroid Build Coastguard Worker }
78*4d7e907cSAndroid Build Coastguard Worker
79*4d7e907cSAndroid Build Coastguard Worker return layout;
80*4d7e907cSAndroid Build Coastguard Worker }
81*4d7e907cSAndroid Build Coastguard Worker
getPlaneLayouts(buffer_handle_t & buf)82*4d7e907cSAndroid Build Coastguard Worker std::vector<PlaneLayout> getPlaneLayouts(buffer_handle_t& buf) {
83*4d7e907cSAndroid Build Coastguard Worker std::vector<PlaneLayout> planeLayouts;
84*4d7e907cSAndroid Build Coastguard Worker status_t status = GraphicBufferMapper::get().getPlaneLayouts(buf, &planeLayouts);
85*4d7e907cSAndroid Build Coastguard Worker if (status != OK) {
86*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: failed to get PlaneLayouts! Status %d", __FUNCTION__, status);
87*4d7e907cSAndroid Build Coastguard Worker }
88*4d7e907cSAndroid Build Coastguard Worker
89*4d7e907cSAndroid Build Coastguard Worker return planeLayouts;
90*4d7e907cSAndroid Build Coastguard Worker }
91*4d7e907cSAndroid Build Coastguard Worker
92*4d7e907cSAndroid Build Coastguard Worker // In IComposer, any buffer_handle_t is owned by the caller and we need to
93*4d7e907cSAndroid Build Coastguard Worker // make a clone for hwcomposer2. We also need to translate empty handle
94*4d7e907cSAndroid Build Coastguard Worker // to nullptr. This function does that, in-place.
importBuffer(buffer_handle_t & handle)95*4d7e907cSAndroid Build Coastguard Worker bool HandleImporter::importBuffer(buffer_handle_t& handle) {
96*4d7e907cSAndroid Build Coastguard Worker if (!handle->numFds && !handle->numInts) {
97*4d7e907cSAndroid Build Coastguard Worker handle = nullptr;
98*4d7e907cSAndroid Build Coastguard Worker return true;
99*4d7e907cSAndroid Build Coastguard Worker }
100*4d7e907cSAndroid Build Coastguard Worker
101*4d7e907cSAndroid Build Coastguard Worker Mutex::Autolock lock(mLock);
102*4d7e907cSAndroid Build Coastguard Worker if (!mInitialized) {
103*4d7e907cSAndroid Build Coastguard Worker initializeLocked();
104*4d7e907cSAndroid Build Coastguard Worker }
105*4d7e907cSAndroid Build Coastguard Worker
106*4d7e907cSAndroid Build Coastguard Worker return importBufferInternal(handle);
107*4d7e907cSAndroid Build Coastguard Worker }
108*4d7e907cSAndroid Build Coastguard Worker
freeBuffer(buffer_handle_t handle)109*4d7e907cSAndroid Build Coastguard Worker void HandleImporter::freeBuffer(buffer_handle_t handle) {
110*4d7e907cSAndroid Build Coastguard Worker if (!handle) {
111*4d7e907cSAndroid Build Coastguard Worker return;
112*4d7e907cSAndroid Build Coastguard Worker }
113*4d7e907cSAndroid Build Coastguard Worker
114*4d7e907cSAndroid Build Coastguard Worker Mutex::Autolock lock(mLock);
115*4d7e907cSAndroid Build Coastguard Worker if (!mInitialized) {
116*4d7e907cSAndroid Build Coastguard Worker initializeLocked();
117*4d7e907cSAndroid Build Coastguard Worker }
118*4d7e907cSAndroid Build Coastguard Worker
119*4d7e907cSAndroid Build Coastguard Worker status_t status = GraphicBufferMapper::get().freeBuffer(handle);
120*4d7e907cSAndroid Build Coastguard Worker if (status != OK) {
121*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: mapper freeBuffer failed. Status %d", __FUNCTION__, status);
122*4d7e907cSAndroid Build Coastguard Worker }
123*4d7e907cSAndroid Build Coastguard Worker }
124*4d7e907cSAndroid Build Coastguard Worker
importFence(const native_handle_t * handle,int & fd) const125*4d7e907cSAndroid Build Coastguard Worker bool HandleImporter::importFence(const native_handle_t* handle, int& fd) const {
126*4d7e907cSAndroid Build Coastguard Worker if (handle == nullptr || handle->numFds == 0) {
127*4d7e907cSAndroid Build Coastguard Worker fd = -1;
128*4d7e907cSAndroid Build Coastguard Worker } else if (handle->numFds == 1) {
129*4d7e907cSAndroid Build Coastguard Worker fd = dup(handle->data[0]);
130*4d7e907cSAndroid Build Coastguard Worker if (fd < 0) {
131*4d7e907cSAndroid Build Coastguard Worker ALOGE("failed to dup fence fd %d", handle->data[0]);
132*4d7e907cSAndroid Build Coastguard Worker return false;
133*4d7e907cSAndroid Build Coastguard Worker }
134*4d7e907cSAndroid Build Coastguard Worker } else {
135*4d7e907cSAndroid Build Coastguard Worker ALOGE("invalid fence handle with %d file descriptors", handle->numFds);
136*4d7e907cSAndroid Build Coastguard Worker return false;
137*4d7e907cSAndroid Build Coastguard Worker }
138*4d7e907cSAndroid Build Coastguard Worker
139*4d7e907cSAndroid Build Coastguard Worker return true;
140*4d7e907cSAndroid Build Coastguard Worker }
141*4d7e907cSAndroid Build Coastguard Worker
closeFence(int fd) const142*4d7e907cSAndroid Build Coastguard Worker void HandleImporter::closeFence(int fd) const {
143*4d7e907cSAndroid Build Coastguard Worker if (fd >= 0) {
144*4d7e907cSAndroid Build Coastguard Worker close(fd);
145*4d7e907cSAndroid Build Coastguard Worker }
146*4d7e907cSAndroid Build Coastguard Worker }
147*4d7e907cSAndroid Build Coastguard Worker
lock(buffer_handle_t & buf,uint64_t cpuUsage,size_t size)148*4d7e907cSAndroid Build Coastguard Worker void* HandleImporter::lock(buffer_handle_t& buf, uint64_t cpuUsage, size_t size) {
149*4d7e907cSAndroid Build Coastguard Worker android::Rect accessRegion{0, 0, static_cast<int>(size), 1};
150*4d7e907cSAndroid Build Coastguard Worker return lock(buf, cpuUsage, accessRegion);
151*4d7e907cSAndroid Build Coastguard Worker }
152*4d7e907cSAndroid Build Coastguard Worker
lock(buffer_handle_t & buf,uint64_t cpuUsage,const android::Rect & accessRegion)153*4d7e907cSAndroid Build Coastguard Worker void* HandleImporter::lock(buffer_handle_t& buf, uint64_t cpuUsage,
154*4d7e907cSAndroid Build Coastguard Worker const android::Rect& accessRegion) {
155*4d7e907cSAndroid Build Coastguard Worker Mutex::Autolock lock(mLock);
156*4d7e907cSAndroid Build Coastguard Worker
157*4d7e907cSAndroid Build Coastguard Worker if (!mInitialized) {
158*4d7e907cSAndroid Build Coastguard Worker initializeLocked();
159*4d7e907cSAndroid Build Coastguard Worker }
160*4d7e907cSAndroid Build Coastguard Worker
161*4d7e907cSAndroid Build Coastguard Worker void* ret = nullptr;
162*4d7e907cSAndroid Build Coastguard Worker status_t status = GraphicBufferMapper::get().lock(buf, cpuUsage, accessRegion, &ret);
163*4d7e907cSAndroid Build Coastguard Worker if (status != OK) {
164*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: failed to lock error %d!", __FUNCTION__, status);
165*4d7e907cSAndroid Build Coastguard Worker }
166*4d7e907cSAndroid Build Coastguard Worker
167*4d7e907cSAndroid Build Coastguard Worker ALOGV("%s: ptr %p accessRegion.top: %d accessRegion.left: %d accessRegion.width: %d "
168*4d7e907cSAndroid Build Coastguard Worker "accessRegion.height: %d",
169*4d7e907cSAndroid Build Coastguard Worker __FUNCTION__, ret, accessRegion.top, accessRegion.left, accessRegion.width(),
170*4d7e907cSAndroid Build Coastguard Worker accessRegion.height());
171*4d7e907cSAndroid Build Coastguard Worker return ret;
172*4d7e907cSAndroid Build Coastguard Worker }
173*4d7e907cSAndroid Build Coastguard Worker
getMonoPlanarStrideBytes(buffer_handle_t & buf,uint32_t * stride)174*4d7e907cSAndroid Build Coastguard Worker status_t HandleImporter::getMonoPlanarStrideBytes(buffer_handle_t& buf, uint32_t* stride /*out*/) {
175*4d7e907cSAndroid Build Coastguard Worker if (stride == nullptr) {
176*4d7e907cSAndroid Build Coastguard Worker return BAD_VALUE;
177*4d7e907cSAndroid Build Coastguard Worker }
178*4d7e907cSAndroid Build Coastguard Worker
179*4d7e907cSAndroid Build Coastguard Worker Mutex::Autolock lock(mLock);
180*4d7e907cSAndroid Build Coastguard Worker
181*4d7e907cSAndroid Build Coastguard Worker if (!mInitialized) {
182*4d7e907cSAndroid Build Coastguard Worker initializeLocked();
183*4d7e907cSAndroid Build Coastguard Worker }
184*4d7e907cSAndroid Build Coastguard Worker
185*4d7e907cSAndroid Build Coastguard Worker std::vector<PlaneLayout> planeLayouts = getPlaneLayouts(buf);
186*4d7e907cSAndroid Build Coastguard Worker if (planeLayouts.size() != 1) {
187*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: Unexpected number of planes %zu!", __FUNCTION__, planeLayouts.size());
188*4d7e907cSAndroid Build Coastguard Worker return BAD_VALUE;
189*4d7e907cSAndroid Build Coastguard Worker }
190*4d7e907cSAndroid Build Coastguard Worker
191*4d7e907cSAndroid Build Coastguard Worker *stride = planeLayouts[0].strideInBytes;
192*4d7e907cSAndroid Build Coastguard Worker
193*4d7e907cSAndroid Build Coastguard Worker return OK;
194*4d7e907cSAndroid Build Coastguard Worker }
195*4d7e907cSAndroid Build Coastguard Worker
unlock(buffer_handle_t & buf)196*4d7e907cSAndroid Build Coastguard Worker int HandleImporter::unlock(buffer_handle_t& buf) {
197*4d7e907cSAndroid Build Coastguard Worker int releaseFence = -1;
198*4d7e907cSAndroid Build Coastguard Worker
199*4d7e907cSAndroid Build Coastguard Worker status_t status = GraphicBufferMapper::get().unlockAsync(buf, &releaseFence);
200*4d7e907cSAndroid Build Coastguard Worker if (status != OK) {
201*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: failed to unlock error %d!", __FUNCTION__, status);
202*4d7e907cSAndroid Build Coastguard Worker }
203*4d7e907cSAndroid Build Coastguard Worker
204*4d7e907cSAndroid Build Coastguard Worker return releaseFence;
205*4d7e907cSAndroid Build Coastguard Worker }
206*4d7e907cSAndroid Build Coastguard Worker
isSmpte2086Present(const buffer_handle_t & buf)207*4d7e907cSAndroid Build Coastguard Worker bool HandleImporter::isSmpte2086Present(const buffer_handle_t& buf) {
208*4d7e907cSAndroid Build Coastguard Worker Mutex::Autolock lock(mLock);
209*4d7e907cSAndroid Build Coastguard Worker
210*4d7e907cSAndroid Build Coastguard Worker if (!mInitialized) {
211*4d7e907cSAndroid Build Coastguard Worker initializeLocked();
212*4d7e907cSAndroid Build Coastguard Worker }
213*4d7e907cSAndroid Build Coastguard Worker std::optional<ui::Smpte2086> metadata;
214*4d7e907cSAndroid Build Coastguard Worker status_t status = GraphicBufferMapper::get().getSmpte2086(buf, &metadata);
215*4d7e907cSAndroid Build Coastguard Worker if (status != OK) {
216*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: Mapper failed to get Smpte2094_40 metadata! Status: %d", __FUNCTION__, status);
217*4d7e907cSAndroid Build Coastguard Worker return false;
218*4d7e907cSAndroid Build Coastguard Worker }
219*4d7e907cSAndroid Build Coastguard Worker
220*4d7e907cSAndroid Build Coastguard Worker return metadata.has_value();
221*4d7e907cSAndroid Build Coastguard Worker }
222*4d7e907cSAndroid Build Coastguard Worker
isSmpte2094_10Present(const buffer_handle_t & buf)223*4d7e907cSAndroid Build Coastguard Worker bool HandleImporter::isSmpte2094_10Present(const buffer_handle_t& buf) {
224*4d7e907cSAndroid Build Coastguard Worker Mutex::Autolock lock(mLock);
225*4d7e907cSAndroid Build Coastguard Worker
226*4d7e907cSAndroid Build Coastguard Worker if (!mInitialized) {
227*4d7e907cSAndroid Build Coastguard Worker initializeLocked();
228*4d7e907cSAndroid Build Coastguard Worker }
229*4d7e907cSAndroid Build Coastguard Worker
230*4d7e907cSAndroid Build Coastguard Worker std::optional<std::vector<uint8_t>> metadata;
231*4d7e907cSAndroid Build Coastguard Worker status_t status = GraphicBufferMapper::get().getSmpte2094_10(buf, &metadata);
232*4d7e907cSAndroid Build Coastguard Worker if (status != OK) {
233*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: Mapper failed to get Smpte2094_40 metadata! Status: %d", __FUNCTION__, status);
234*4d7e907cSAndroid Build Coastguard Worker return false;
235*4d7e907cSAndroid Build Coastguard Worker }
236*4d7e907cSAndroid Build Coastguard Worker
237*4d7e907cSAndroid Build Coastguard Worker return metadata.has_value();
238*4d7e907cSAndroid Build Coastguard Worker }
239*4d7e907cSAndroid Build Coastguard Worker
isSmpte2094_40Present(const buffer_handle_t & buf)240*4d7e907cSAndroid Build Coastguard Worker bool HandleImporter::isSmpte2094_40Present(const buffer_handle_t& buf) {
241*4d7e907cSAndroid Build Coastguard Worker Mutex::Autolock lock(mLock);
242*4d7e907cSAndroid Build Coastguard Worker
243*4d7e907cSAndroid Build Coastguard Worker if (!mInitialized) {
244*4d7e907cSAndroid Build Coastguard Worker initializeLocked();
245*4d7e907cSAndroid Build Coastguard Worker }
246*4d7e907cSAndroid Build Coastguard Worker
247*4d7e907cSAndroid Build Coastguard Worker std::optional<std::vector<uint8_t>> metadata;
248*4d7e907cSAndroid Build Coastguard Worker status_t status = GraphicBufferMapper::get().getSmpte2094_40(buf, &metadata);
249*4d7e907cSAndroid Build Coastguard Worker if (status != OK) {
250*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: Mapper failed to get Smpte2094_40 metadata! Status: %d", __FUNCTION__, status);
251*4d7e907cSAndroid Build Coastguard Worker return false;
252*4d7e907cSAndroid Build Coastguard Worker }
253*4d7e907cSAndroid Build Coastguard Worker
254*4d7e907cSAndroid Build Coastguard Worker return metadata.has_value();
255*4d7e907cSAndroid Build Coastguard Worker }
256*4d7e907cSAndroid Build Coastguard Worker
257*4d7e907cSAndroid Build Coastguard Worker } // namespace helper
258*4d7e907cSAndroid Build Coastguard Worker } // namespace common
259*4d7e907cSAndroid Build Coastguard Worker } // namespace camera
260*4d7e907cSAndroid Build Coastguard Worker } // namespace hardware
261*4d7e907cSAndroid Build Coastguard Worker } // namespace android
262