• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
19 #include <stdint.h>
20 #ifdef HAVE_ANDROID_OS      // just want PAGE_SIZE define
21 # include <asm/page.h>
22 #else
23 # include <sys/user.h>
24 #endif
25 #include <errno.h>
26 #include <sys/mman.h>
27 
28 #include <cutils/ashmem.h>
29 
30 #include <utils/Errors.h>
31 #include <utils/Log.h>
32 
33 #include <ui/GraphicBufferMapper.h>
34 #include <ui/Rect.h>
35 
36 #include <hardware/gralloc.h>
37 
38 #include <private/ui/sw_gralloc_handle.h>
39 
40 
41 namespace android {
42 // ---------------------------------------------------------------------------
43 
ANDROID_SINGLETON_STATIC_INSTANCE(GraphicBufferMapper)44 ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper )
45 
46 GraphicBufferMapper::GraphicBufferMapper()
47     : mAllocMod(0)
48 {
49     hw_module_t const* module;
50     int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
51     LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
52     if (err == 0) {
53         mAllocMod = (gralloc_module_t const *)module;
54     }
55 }
56 
registerBuffer(buffer_handle_t handle)57 status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle)
58 {
59     status_t err;
60     if (sw_gralloc_handle_t::validate(handle) < 0) {
61         err = mAllocMod->registerBuffer(mAllocMod, handle);
62     } else {
63         err = sw_gralloc_handle_t::registerBuffer((sw_gralloc_handle_t*)handle);
64     }
65     LOGW_IF(err, "registerBuffer(%p) failed %d (%s)",
66             handle, err, strerror(-err));
67     return err;
68 }
69 
unregisterBuffer(buffer_handle_t handle)70 status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle)
71 {
72     status_t err;
73     if (sw_gralloc_handle_t::validate(handle) < 0) {
74         err = mAllocMod->unregisterBuffer(mAllocMod, handle);
75     } else {
76         err = sw_gralloc_handle_t::unregisterBuffer((sw_gralloc_handle_t*)handle);
77     }
78     LOGW_IF(err, "unregisterBuffer(%p) failed %d (%s)",
79             handle, err, strerror(-err));
80     return err;
81 }
82 
lock(buffer_handle_t handle,int usage,const Rect & bounds,void ** vaddr)83 status_t GraphicBufferMapper::lock(buffer_handle_t handle,
84         int usage, const Rect& bounds, void** vaddr)
85 {
86     status_t err;
87     if (sw_gralloc_handle_t::validate(handle) < 0) {
88         err = mAllocMod->lock(mAllocMod, handle, usage,
89                 bounds.left, bounds.top, bounds.width(), bounds.height(),
90                 vaddr);
91     } else {
92         err = sw_gralloc_handle_t::lock((sw_gralloc_handle_t*)handle, usage,
93                 bounds.left, bounds.top, bounds.width(), bounds.height(),
94                 vaddr);
95     }
96     LOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err));
97     return err;
98 }
99 
unlock(buffer_handle_t handle)100 status_t GraphicBufferMapper::unlock(buffer_handle_t handle)
101 {
102     status_t err;
103     if (sw_gralloc_handle_t::validate(handle) < 0) {
104         err = mAllocMod->unlock(mAllocMod, handle);
105     } else {
106         err = sw_gralloc_handle_t::unlock((sw_gralloc_handle_t*)handle);
107     }
108     LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err));
109     return err;
110 }
111 
112 // ---------------------------------------------------------------------------
113 
alloc(uint32_t w,uint32_t h,int format,int usage,buffer_handle_t * pHandle,int32_t * pStride)114 status_t sw_gralloc_handle_t::alloc(uint32_t w, uint32_t h, int format,
115         int usage, buffer_handle_t* pHandle, int32_t* pStride)
116 {
117     int align = 4;
118     int bpp = 0;
119     switch (format) {
120         case HAL_PIXEL_FORMAT_RGBA_8888:
121         case HAL_PIXEL_FORMAT_RGBX_8888:
122         case HAL_PIXEL_FORMAT_BGRA_8888:
123             bpp = 4;
124             break;
125         case HAL_PIXEL_FORMAT_RGB_888:
126             bpp = 3;
127             break;
128         case HAL_PIXEL_FORMAT_RGB_565:
129         case HAL_PIXEL_FORMAT_RGBA_5551:
130         case HAL_PIXEL_FORMAT_RGBA_4444:
131             bpp = 2;
132             break;
133         default:
134             return -EINVAL;
135     }
136     size_t bpr = (w*bpp + (align-1)) & ~(align-1);
137     size_t size = bpr * h;
138     size_t stride = bpr / bpp;
139     size = (size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
140 
141     int fd = ashmem_create_region("sw-gralloc-buffer", size);
142     if (fd < 0) {
143         LOGE("ashmem_create_region(size=%d) failed (%s)",
144                 size, strerror(-errno));
145         return -errno;
146     }
147 
148     int prot = PROT_READ;
149     if (usage & GRALLOC_USAGE_SW_WRITE_MASK)
150         prot |= PROT_WRITE;
151 
152     if (ashmem_set_prot_region(fd, prot) < 0) {
153         LOGE("ashmem_set_prot_region(fd=%d, prot=%x) failed (%s)",
154                 fd, prot, strerror(-errno));
155         close(fd);
156         return -errno;
157     }
158 
159     void* base = mmap(0, size, prot, MAP_SHARED, fd, 0);
160     if (base == MAP_FAILED) {
161         LOGE("alloc mmap(fd=%d, size=%d, prot=%x) failed (%s)",
162                 fd, size, prot, strerror(-errno));
163         close(fd);
164         return -errno;
165     }
166 
167     sw_gralloc_handle_t* hnd = new sw_gralloc_handle_t();
168     hnd->fd = fd;
169     hnd->size = size;
170     hnd->base = intptr_t(base);
171     hnd->prot = prot;
172     *pStride = stride;
173     *pHandle = hnd;
174 
175     return NO_ERROR;
176 }
177 
free(sw_gralloc_handle_t * hnd)178 status_t sw_gralloc_handle_t::free(sw_gralloc_handle_t* hnd)
179 {
180     if (hnd->base) {
181         munmap((void*)hnd->base, hnd->size);
182     }
183     if (hnd->fd >= 0) {
184         close(hnd->fd);
185     }
186     delete hnd;
187     return NO_ERROR;
188 }
189 
registerBuffer(sw_gralloc_handle_t * hnd)190 status_t sw_gralloc_handle_t::registerBuffer(sw_gralloc_handle_t* hnd)
191 {
192     if (hnd->pid != getpid()) {
193         void* base = mmap(0, hnd->size, hnd->prot, MAP_SHARED, hnd->fd, 0);
194         if (base == MAP_FAILED) {
195             LOGE("registerBuffer mmap(fd=%d, size=%d, prot=%x) failed (%s)",
196                     hnd->fd, hnd->size, hnd->prot, strerror(-errno));
197             return -errno;
198         }
199         hnd->base = intptr_t(base);
200     }
201     return NO_ERROR;
202 }
203 
unregisterBuffer(sw_gralloc_handle_t * hnd)204 status_t sw_gralloc_handle_t::unregisterBuffer(sw_gralloc_handle_t* hnd)
205 {
206     if (hnd->pid != getpid()) {
207         if (hnd->base) {
208             munmap((void*)hnd->base, hnd->size);
209         }
210         hnd->base = 0;
211     }
212     return NO_ERROR;
213 }
214 
lock(sw_gralloc_handle_t * hnd,int usage,int l,int t,int w,int h,void ** vaddr)215 status_t sw_gralloc_handle_t::lock(sw_gralloc_handle_t* hnd, int usage,
216         int l, int t, int w, int h, void** vaddr)
217 {
218     *vaddr = (void*)hnd->base;
219     return NO_ERROR;
220 }
221 
unlock(sw_gralloc_handle_t * hnd)222 status_t sw_gralloc_handle_t::unlock(sw_gralloc_handle_t* hnd)
223 {
224     return NO_ERROR;
225 }
226 
227 // ---------------------------------------------------------------------------
228 }; // namespace android
229