xref: /aosp_15_r20/hardware/interfaces/camera/common/default/HandleImporter.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
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