mapper.cpp revision 54df445a5148c4c03c5079ab97f29a31a1185f2d
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#include <limits.h>
19#include <errno.h>
20#include <pthread.h>
21#include <unistd.h>
22#include <string.h>
23#include <stdarg.h>
24
25#include <sys/mman.h>
26#include <sys/stat.h>
27#include <sys/types.h>
28#include <sys/ioctl.h>
29
30#include <cutils/log.h>
31#include <cutils/atomic.h>
32
33#include <hardware/hardware.h>
34#include <hardware/gralloc.h>
35
36#include "gralloc_priv.h"
37#include "gr.h"
38#include "alloc_controller.h"
39#include "memalloc.h"
40#include <qdMetaData.h>
41
42using namespace gralloc;
43/*****************************************************************************/
44
45// Return the type of allocator -
46// these are used for mapping/unmapping
47static IMemAlloc* getAllocator(int flags)
48{
49    IMemAlloc* memalloc;
50    IAllocController* alloc_ctrl = IAllocController::getInstance();
51    memalloc = alloc_ctrl->getAllocator(flags);
52    return memalloc;
53}
54
55static int gralloc_map(gralloc_module_t const* module,
56                       buffer_handle_t handle,
57                       void** vaddr)
58{
59    private_handle_t* hnd = (private_handle_t*)handle;
60    void *mappedAddress;
61    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
62        !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) {
63        size_t size = hnd->size;
64        IMemAlloc* memalloc = getAllocator(hnd->flags) ;
65        int err = memalloc->map_buffer(&mappedAddress, size,
66                                       hnd->offset, hnd->fd);
67        if(err || mappedAddress == MAP_FAILED) {
68            ALOGE("Could not mmap handle %p, fd=%d (%s)",
69                  handle, hnd->fd, strerror(errno));
70            hnd->base = 0;
71            return -errno;
72        }
73
74        hnd->base = intptr_t(mappedAddress) + hnd->offset;
75        //LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
76        //        hnd->fd, hnd->offset, hnd->size, mappedAddress);
77        mappedAddress = MAP_FAILED;
78        size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
79        err = memalloc->map_buffer(&mappedAddress, size,
80                                       hnd->offset_metadata, hnd->fd_metadata);
81        if(err || mappedAddress == MAP_FAILED) {
82            ALOGE("Could not mmap handle %p, fd=%d (%s)",
83                  handle, hnd->fd_metadata, strerror(errno));
84            hnd->base_metadata = 0;
85            return -errno;
86        }
87        hnd->base_metadata = intptr_t(mappedAddress) + hnd->offset_metadata;
88    }
89    *vaddr = (void*)hnd->base;
90    return 0;
91}
92
93static int gralloc_unmap(gralloc_module_t const* module,
94                         buffer_handle_t handle)
95{
96    private_handle_t* hnd = (private_handle_t*)handle;
97    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
98        int err = -EINVAL;
99        void* base = (void*)hnd->base;
100        size_t size = hnd->size;
101        IMemAlloc* memalloc = getAllocator(hnd->flags) ;
102        if(memalloc != NULL) {
103            err = memalloc->unmap_buffer(base, size, hnd->offset);
104            if (err) {
105                ALOGE("Could not unmap memory at address %p", base);
106            }
107            base = (void*)hnd->base_metadata;
108            size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
109            err = memalloc->unmap_buffer(base, size, hnd->offset_metadata);
110            if (err) {
111                ALOGE("Could not unmap memory at address %p", base);
112            }
113        }
114    }
115    /* need to initialize the pointer to NULL otherwise unmapping for that
116     * buffer happens twice which leads to crash */
117    hnd->base = 0;
118    hnd->base_metadata = 0;
119    return 0;
120}
121
122/*****************************************************************************/
123
124static pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER;
125
126/*****************************************************************************/
127
128int gralloc_register_buffer(gralloc_module_t const* module,
129                            buffer_handle_t handle)
130{
131    if (private_handle_t::validate(handle) < 0)
132        return -EINVAL;
133
134    // In this implementation, we don't need to do anything here
135
136    /* NOTE: we need to initialize the buffer as not mapped/not locked
137     * because it shouldn't when this function is called the first time
138     * in a new process. Ideally these flags shouldn't be part of the
139     * handle, but instead maintained in the kernel or at least
140     * out-of-line
141     */
142
143    private_handle_t* hnd = (private_handle_t*)handle;
144    hnd->base = 0;
145    hnd->base_metadata = 0;
146    void *vaddr;
147    int err = gralloc_map(module, handle, &vaddr);
148    if (err) {
149        ALOGE("%s: gralloc_map failed", __FUNCTION__);
150        return err;
151    }
152
153    return 0;
154}
155
156int gralloc_unregister_buffer(gralloc_module_t const* module,
157                              buffer_handle_t handle)
158{
159    if (private_handle_t::validate(handle) < 0)
160        return -EINVAL;
161
162    /*
163     * If the buffer has been mapped during a lock operation, it's time
164     * to un-map it. It's an error to be here with a locked buffer.
165     * NOTE: the framebuffer is handled differently and is never unmapped.
166     */
167
168    private_handle_t* hnd = (private_handle_t*)handle;
169
170    if (hnd->base != 0) {
171        gralloc_unmap(module, handle);
172    }
173    hnd->base = 0;
174    hnd->base_metadata = 0;
175    return 0;
176}
177
178int terminateBuffer(gralloc_module_t const* module,
179                    private_handle_t* hnd)
180{
181    /*
182     * If the buffer has been mapped during a lock operation, it's time
183     * to un-map it. It's an error to be here with a locked buffer.
184     */
185
186    if (hnd->base != 0) {
187        // this buffer was mapped, unmap it now
188        if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
189                          private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP |
190                          private_handle_t::PRIV_FLAGS_USES_ASHMEM |
191                          private_handle_t::PRIV_FLAGS_USES_ION)) {
192                gralloc_unmap(module, hnd);
193        } else {
194            ALOGE("terminateBuffer: unmapping a non pmem/ashmem buffer flags = 0x%x",
195                  hnd->flags);
196            gralloc_unmap(module, hnd);
197        }
198    }
199
200    return 0;
201}
202
203int gralloc_lock(gralloc_module_t const* module,
204                 buffer_handle_t handle, int usage,
205                 int l, int t, int w, int h,
206                 void** vaddr)
207{
208    if (private_handle_t::validate(handle) < 0)
209        return -EINVAL;
210
211    int err = 0;
212    private_handle_t* hnd = (private_handle_t*)handle;
213    if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
214        if (hnd->base == 0) {
215            // we need to map for real
216            pthread_mutex_t* const lock = &sMapLock;
217            pthread_mutex_lock(lock);
218            err = gralloc_map(module, handle, vaddr);
219            pthread_mutex_unlock(lock);
220        }
221        *vaddr = (void*)hnd->base;
222        if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) {
223            //Invalidate if reading in software. No need to do this for the
224            //metadata buffer as it is only read/written in software.
225            IMemAlloc* memalloc = getAllocator(hnd->flags) ;
226            err = memalloc->clean_buffer((void*)hnd->base,
227                                         hnd->size, hnd->offset, hnd->fd,
228                                         CACHE_INVALIDATE);
229            if (usage & GRALLOC_USAGE_SW_WRITE_MASK) {
230                // Mark the buffer to be flushed after cpu read/write
231                hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
232            }
233        }
234    } else {
235        hnd->flags |= private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
236    }
237    return err;
238}
239
240int gralloc_unlock(gralloc_module_t const* module,
241                   buffer_handle_t handle)
242{
243    if (private_handle_t::validate(handle) < 0)
244        return -EINVAL;
245    int err = 0;
246    private_handle_t* hnd = (private_handle_t*)handle;
247
248    if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) {
249        IMemAlloc* memalloc = getAllocator(hnd->flags);
250        if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
251            err = memalloc->clean_buffer((void*)hnd->base,
252                                         hnd->size, hnd->offset, hnd->fd,
253                                         CACHE_CLEAN_AND_INVALIDATE);
254            hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
255        } else if(hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) {
256            hnd->flags &= ~private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
257        } else {
258            //Probably a round about way to do this, but this avoids adding new
259            //flags
260            err = memalloc->clean_buffer((void*)hnd->base,
261                                         hnd->size, hnd->offset, hnd->fd,
262                                         CACHE_INVALIDATE);
263        }
264    }
265
266    return err;
267}
268
269/*****************************************************************************/
270
271int gralloc_perform(struct gralloc_module_t const* module,
272                    int operation, ... )
273{
274    int res = -EINVAL;
275    va_list args;
276    va_start(args, operation);
277    switch (operation) {
278        case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER:
279            {
280                int fd = va_arg(args, int);
281                size_t size = va_arg(args, size_t);
282                size_t offset = va_arg(args, size_t);
283                void* base = va_arg(args, void*);
284                int width = va_arg(args, int);
285                int height = va_arg(args, int);
286                int format = va_arg(args, int);
287
288                native_handle_t** handle = va_arg(args, native_handle_t**);
289                int memoryFlags = va_arg(args, int);
290                private_handle_t* hnd = (private_handle_t*)native_handle_create(
291                    private_handle_t::sNumFds, private_handle_t::sNumInts);
292                hnd->magic = private_handle_t::sMagic;
293                hnd->fd = fd;
294                hnd->flags =  private_handle_t::PRIV_FLAGS_USES_ION;
295                hnd->size = size;
296                hnd->offset = offset;
297                hnd->base = intptr_t(base) + offset;
298                hnd->gpuaddr = 0;
299                hnd->width = width;
300                hnd->height = height;
301                hnd->format = format;
302                *handle = (native_handle_t *)hnd;
303                res = 0;
304                break;
305
306            }
307#ifdef QCOM_BSP
308        case GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_GEOMETRY:
309            {
310                int width = va_arg(args, int);
311                int height = va_arg(args, int);
312                int format = va_arg(args, int);
313                private_handle_t* hnd =  va_arg(args, private_handle_t*);
314                if (private_handle_t::validate(hnd)) {
315                    return res;
316                }
317                hnd->width = width;
318                hnd->height = height;
319                hnd->format = format;
320                res = 0;
321            }
322            break;
323#endif
324        case GRALLOC_MODULE_PERFORM_GET_STRIDE:
325            {
326                int width   = va_arg(args, int);
327                int format  = va_arg(args, int);
328                int *stride = va_arg(args, int *);
329                int alignedw = 0, alignedh = 0;
330                AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
331                        0, format, false, alignedw, alignedh);
332                *stride = alignedw;
333                res = 0;
334            } break;
335
336        case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE:
337            {
338                private_handle_t* hnd =  va_arg(args, private_handle_t*);
339                int *stride = va_arg(args, int *);
340                if (private_handle_t::validate(hnd)) {
341                    return res;
342                }
343                MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
344                if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
345                    *stride = metadata->bufferDim.sliceWidth;
346                } else {
347                    *stride = hnd->width;
348                }
349                res = 0;
350            } break;
351
352        case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES:
353            {
354                int width   = va_arg(args, int);
355                int height  = va_arg(args, int);
356                int format  = va_arg(args, int);
357                int usage   = va_arg(args, int);
358                int *alignedWidth = va_arg(args, int *);
359                int *alignedHeight = va_arg(args, int *);
360                int *tileEnabled = va_arg(args,int *);
361                *tileEnabled = isMacroTileEnabled(format, usage);
362                AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
363                        height, format, *tileEnabled, *alignedWidth,
364                        *alignedHeight);
365                res = 0;
366            } break;
367
368        case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE:
369            {
370                private_handle_t* hnd =  va_arg(args, private_handle_t*);
371                int *color_space = va_arg(args, int *);
372                if (private_handle_t::validate(hnd)) {
373                    return res;
374                }
375                MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
376                if(metadata && metadata->operation & UPDATE_COLOR_SPACE) {
377                    *color_space = metadata->colorSpace;
378                    res = 0;
379                }
380            } break;
381        default:
382            break;
383    }
384    va_end(args);
385    return res;
386}
387