1 /*
2  * Copyright (C) 2007 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 #define LOG_TAG "GraphicBufferMapper"
18 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
19 
20 #include <stdint.h>
21 #include <errno.h>
22 
23 // We would eliminate the non-conforming zero-length array, but we can't since
24 // this is effectively included from the Linux kernel
25 #pragma clang diagnostic push
26 #pragma clang diagnostic ignored "-Wzero-length-array"
27 #include <sync/sync.h>
28 #pragma clang diagnostic pop
29 
30 #include <utils/Errors.h>
31 #include <utils/Log.h>
32 #include <utils/Trace.h>
33 
34 #include <ui/GraphicBufferMapper.h>
35 #include <ui/Rect.h>
36 
37 #include <hardware/gralloc.h>
38 
39 
40 namespace android {
41 // ---------------------------------------------------------------------------
42 
ANDROID_SINGLETON_STATIC_INSTANCE(GraphicBufferMapper)43 ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper )
44 
45 GraphicBufferMapper::GraphicBufferMapper()
46     : mAllocMod(0)
47 {
48     hw_module_t const* module;
49     int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
50     ALOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
51     if (err == 0) {
52         mAllocMod = reinterpret_cast<gralloc_module_t const *>(module);
53     }
54 }
55 
registerBuffer(buffer_handle_t handle)56 status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle)
57 {
58     ATRACE_CALL();
59     status_t err;
60 
61     err = mAllocMod->registerBuffer(mAllocMod, handle);
62 
63     ALOGW_IF(err, "registerBuffer(%p) failed %d (%s)",
64             handle, err, strerror(-err));
65     return err;
66 }
67 
unregisterBuffer(buffer_handle_t handle)68 status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle)
69 {
70     ATRACE_CALL();
71     status_t err;
72 
73     err = mAllocMod->unregisterBuffer(mAllocMod, handle);
74 
75     ALOGW_IF(err, "unregisterBuffer(%p) failed %d (%s)",
76             handle, err, strerror(-err));
77     return err;
78 }
79 
lock(buffer_handle_t handle,uint32_t usage,const Rect & bounds,void ** vaddr)80 status_t GraphicBufferMapper::lock(buffer_handle_t handle,
81         uint32_t usage, const Rect& bounds, void** vaddr)
82 {
83     ATRACE_CALL();
84     status_t err;
85 
86     err = mAllocMod->lock(mAllocMod, handle, static_cast<int>(usage),
87             bounds.left, bounds.top, bounds.width(), bounds.height(),
88             vaddr);
89 
90     ALOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err));
91     return err;
92 }
93 
lockYCbCr(buffer_handle_t handle,uint32_t usage,const Rect & bounds,android_ycbcr * ycbcr)94 status_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle,
95         uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr)
96 {
97     ATRACE_CALL();
98     status_t err;
99 
100     if (mAllocMod->lock_ycbcr == NULL) {
101         return -EINVAL; // do not log failure
102     }
103 
104     err = mAllocMod->lock_ycbcr(mAllocMod, handle, static_cast<int>(usage),
105             bounds.left, bounds.top, bounds.width(), bounds.height(),
106             ycbcr);
107 
108     ALOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err));
109     return err;
110 }
111 
unlock(buffer_handle_t handle)112 status_t GraphicBufferMapper::unlock(buffer_handle_t handle)
113 {
114     ATRACE_CALL();
115     status_t err;
116 
117     err = mAllocMod->unlock(mAllocMod, handle);
118 
119     ALOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err));
120     return err;
121 }
122 
lockAsync(buffer_handle_t handle,uint32_t usage,const Rect & bounds,void ** vaddr,int fenceFd)123 status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
124         uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd)
125 {
126     ATRACE_CALL();
127     status_t err;
128 
129     if (mAllocMod->common.module_api_version >= GRALLOC_MODULE_API_VERSION_0_3) {
130         err = mAllocMod->lockAsync(mAllocMod, handle, static_cast<int>(usage),
131                 bounds.left, bounds.top, bounds.width(), bounds.height(),
132                 vaddr, fenceFd);
133     } else {
134         if (fenceFd >= 0) {
135             sync_wait(fenceFd, -1);
136             close(fenceFd);
137         }
138         err = mAllocMod->lock(mAllocMod, handle, static_cast<int>(usage),
139                 bounds.left, bounds.top, bounds.width(), bounds.height(),
140                 vaddr);
141     }
142 
143     ALOGW_IF(err, "lockAsync(...) failed %d (%s)", err, strerror(-err));
144     return err;
145 }
146 
lockAsyncYCbCr(buffer_handle_t handle,uint32_t usage,const Rect & bounds,android_ycbcr * ycbcr,int fenceFd)147 status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle,
148         uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr, int fenceFd)
149 {
150     ATRACE_CALL();
151     status_t err;
152 
153     if (mAllocMod->common.module_api_version >= GRALLOC_MODULE_API_VERSION_0_3
154             && mAllocMod->lockAsync_ycbcr != NULL) {
155         err = mAllocMod->lockAsync_ycbcr(mAllocMod, handle,
156                 static_cast<int>(usage), bounds.left, bounds.top,
157                 bounds.width(), bounds.height(), ycbcr, fenceFd);
158     } else if (mAllocMod->lock_ycbcr != NULL) {
159         if (fenceFd >= 0) {
160             sync_wait(fenceFd, -1);
161             close(fenceFd);
162         }
163         err = mAllocMod->lock_ycbcr(mAllocMod, handle, static_cast<int>(usage),
164                 bounds.left, bounds.top, bounds.width(), bounds.height(),
165                 ycbcr);
166     } else {
167         if (fenceFd >= 0) {
168             close(fenceFd);
169         }
170         return -EINVAL; // do not log failure
171     }
172 
173     ALOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err));
174     return err;
175 }
176 
unlockAsync(buffer_handle_t handle,int * fenceFd)177 status_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd)
178 {
179     ATRACE_CALL();
180     status_t err;
181 
182     if (mAllocMod->common.module_api_version >= GRALLOC_MODULE_API_VERSION_0_3) {
183         err = mAllocMod->unlockAsync(mAllocMod, handle, fenceFd);
184     } else {
185         *fenceFd = -1;
186         err = mAllocMod->unlock(mAllocMod, handle);
187     }
188 
189     ALOGW_IF(err, "unlockAsync(...) failed %d (%s)", err, strerror(-err));
190     return err;
191 }
192 
193 // ---------------------------------------------------------------------------
194 }; // namespace android
195