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