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