10235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin/*
20235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin * Copyright (C) 2008 The Android Open Source Project
30235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin *
40235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin * Licensed under the Apache License, Version 2.0 (the "License");
50235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin * you may not use this file except in compliance with the License.
60235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin * You may obtain a copy of the License at
70235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin *
80235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin *      http://www.apache.org/licenses/LICENSE-2.0
90235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin *
100235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin * Unless required by applicable law or agreed to in writing, software
110235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin * distributed under the License is distributed on an "AS IS" BASIS,
120235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin * See the License for the specific language governing permissions and
140235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin * limitations under the License.
150235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin */
160235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
170235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin#include <limits.h>
180235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin#include <errno.h>
190235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin#include <pthread.h>
200235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin#include <unistd.h>
2179c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian#include <string.h>
2287ea1dfa60cf130fafdbab8e94cb2ce9ff8d0975Mathias Agopian#include <stdarg.h>
230235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
240235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin#include <sys/mman.h>
250235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin#include <sys/stat.h>
260235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin#include <sys/types.h>
2741adb7ff4125dbba2b156258935bb3943241bd1eMathias Agopian#include <sys/ioctl.h>
280235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
290235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin#include <cutils/log.h>
300235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin#include <cutils/atomic.h>
310235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
320235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin#include <hardware/hardware.h>
330235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin#include <hardware/gralloc.h>
340235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
3541adb7ff4125dbba2b156258935bb3943241bd1eMathias Agopian#include <linux/android_pmem.h>
3641adb7ff4125dbba2b156258935bb3943241bd1eMathias Agopian
370235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin#include "gralloc_priv.h"
380235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
390235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
400235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin// we need this for now because pmem cannot mmap at an offset
410235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin#define PMEM_HACK   1
420235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
4379c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian/* desktop Linux needs a little help with gettid() */
4479c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian#if defined(ARCH_X86) && !defined(HAVE_ANDROID_OS)
4579c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian#define __KERNEL__
4679c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian# include <linux/unistd.h>
4779c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopianpid_t gettid() { return syscall(__NR_gettid);}
4879c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian#undef __KERNEL__
4979c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian#endif
5079c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian
510235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin/*****************************************************************************/
520235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
530235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavinstatic int gralloc_map(gralloc_module_t const* module,
540235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        buffer_handle_t handle,
550235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        void** vaddr)
560235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin{
570235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    private_handle_t* hnd = (private_handle_t*)handle;
580235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
590235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        size_t size = hnd->size;
600235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin#if PMEM_HACK
610235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        size += hnd->offset;
620235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin#endif
630235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        void* mappedAddress = mmap(0, size,
640235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin                PROT_READ|PROT_WRITE, MAP_SHARED, hnd->fd, 0);
650235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        if (mappedAddress == MAP_FAILED) {
66c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block            ALOGE("Could not mmap handle %p, fd=%d (%s)",
6779c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian                    handle, hnd->fd, strerror(errno));
6879c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian            hnd->base = 0;
690235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            return -errno;
700235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        }
710235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        hnd->base = intptr_t(mappedAddress) + hnd->offset;
72f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block        //ALOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
730235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        //        hnd->fd, hnd->offset, hnd->size, mappedAddress);
740235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    }
750235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    *vaddr = (void*)hnd->base;
760235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    return 0;
770235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin}
780235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
790235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavinstatic int gralloc_unmap(gralloc_module_t const* module,
800235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        buffer_handle_t handle)
810235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin{
820235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    private_handle_t* hnd = (private_handle_t*)handle;
830235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
8479c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian        void* base = (void*)hnd->base;
8579c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian        size_t size = hnd->size;
8679c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian#if PMEM_HACK
8779c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian        base = (void*)(intptr_t(base) - hnd->offset);
8879c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian        size += hnd->offset;
8979c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian#endif
90f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block        //ALOGD("unmapping from %p, size=%d", base, size);
9179c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian        if (munmap(base, size) < 0) {
92c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block            ALOGE("Could not unmap %s", strerror(errno));
930235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        }
940235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    }
950235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    hnd->base = 0;
960235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    return 0;
970235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin}
980235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
990235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin/*****************************************************************************/
1000235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
1010235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavinstatic pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER;
1020235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
1030235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin/*****************************************************************************/
1040235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
1050235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavinint gralloc_register_buffer(gralloc_module_t const* module,
1060235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        buffer_handle_t handle)
1070235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin{
1080235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    if (private_handle_t::validate(handle) < 0)
1090235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        return -EINVAL;
1100235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
1110235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    // In this implementation, we don't need to do anything here
1120235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
1130235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    /* NOTE: we need to initialize the buffer as not mapped/not locked
1140235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin     * because it shouldn't when this function is called the first time
1150235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin     * in a new process. Ideally these flags shouldn't be part of the
1160235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin     * handle, but instead maintained in the kernel or at least
1170235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin     * out-of-line
1180235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin     */
1190235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
1200235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    // if this handle was created in this process, then we keep it as is.
1210235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    private_handle_t* hnd = (private_handle_t*)handle;
1220235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    if (hnd->pid != getpid()) {
1230235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        hnd->base = 0;
1240235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        hnd->lockState  = 0;
1250235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        hnd->writeOwner = 0;
1260235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    }
1270235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    return 0;
1280235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin}
1290235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
1300235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavinint gralloc_unregister_buffer(gralloc_module_t const* module,
1310235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        buffer_handle_t handle)
1320235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin{
1330235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    if (private_handle_t::validate(handle) < 0)
1340235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        return -EINVAL;
1350235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
1360235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    /*
1370235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin     * If the buffer has been mapped during a lock operation, it's time
1380235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin     * to un-map it. It's an error to be here with a locked buffer.
1390235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin     * NOTE: the framebuffer is handled differently and is never unmapped.
1400235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin     */
1410235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
1420235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    private_handle_t* hnd = (private_handle_t*)handle;
1430235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
144c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block    ALOGE_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK,
14579c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian            "[unregister] handle %p still locked (state=%08x)",
1460235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            hnd, hnd->lockState);
1470235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
1480235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    // never unmap buffers that were created in this process
1490235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    if (hnd->pid != getpid()) {
1500235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        if (hnd->lockState & private_handle_t::LOCK_STATE_MAPPED) {
1510235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            gralloc_unmap(module, handle);
1520235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        }
1530235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        hnd->base = 0;
1540235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        hnd->lockState  = 0;
1550235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        hnd->writeOwner = 0;
1560235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    }
1570235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    return 0;
1580235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin}
1590235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
16079c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopianint terminateBuffer(gralloc_module_t const* module,
16179c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian        private_handle_t* hnd)
16279c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian{
16379c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian    /*
16479c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian     * If the buffer has been mapped during a lock operation, it's time
16579c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian     * to un-map it. It's an error to be here with a locked buffer.
16679c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian     */
16779c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian
168c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block    ALOGE_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK,
16979c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian            "[terminate] handle %p still locked (state=%08x)",
17079c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian            hnd, hnd->lockState);
17179c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian
17279c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian    if (hnd->lockState & private_handle_t::LOCK_STATE_MAPPED) {
17379c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian        // this buffer was mapped, unmap it now
174f5a83a9c024dee0617dbc3dab98cd307e8d54665Jamie Gennis        if ((hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM) ||
175f5a83a9c024dee0617dbc3dab98cd307e8d54665Jamie Gennis            (hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP)) {
17679c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian            if (hnd->pid != getpid()) {
17779c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian                // ... unless it's a "master" pmem buffer, that is a buffer
17879c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian                // mapped in the process it's been allocated.
17979c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian                // (see gralloc_alloc_buffer())
18079c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian                gralloc_unmap(module, hnd);
18179c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian            }
18279c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian        } else {
18379c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian            gralloc_unmap(module, hnd);
18479c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian        }
18579c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian    }
18679c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian
18779c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian    return 0;
18879c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian}
18979c9ceea6ec3ac708ec7e27ab3af54ffdaf9338fMathias Agopian
1900235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavinint gralloc_lock(gralloc_module_t const* module,
1910235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        buffer_handle_t handle, int usage,
1920235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        int l, int t, int w, int h,
1930235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        void** vaddr)
1940235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin{
1950235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    if (private_handle_t::validate(handle) < 0)
1960235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        return -EINVAL;
1970235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
1980235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    int err = 0;
1990235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    private_handle_t* hnd = (private_handle_t*)handle;
2000235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    int32_t current_value, new_value;
2010235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    int retry;
2020235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
2030235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    do {
2040235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        current_value = hnd->lockState;
2050235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        new_value = current_value;
2060235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
2070235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        if (current_value & private_handle_t::LOCK_STATE_WRITE) {
2080235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            // already locked for write
209c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block            ALOGE("handle %p already locked for write", handle);
2100235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            return -EBUSY;
2110235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        } else if (current_value & private_handle_t::LOCK_STATE_READ_MASK) {
2120235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            // already locked for read
2130235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            if (usage & (GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_HW_RENDER)) {
214c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block                ALOGE("handle %p already locked for read", handle);
2150235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin                return -EBUSY;
2160235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            } else {
2170235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin                // this is not an error
218f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block                //ALOGD("%p already locked for read... count = %d",
2190235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin                //        handle, (current_value & ~(1<<31)));
2200235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            }
2210235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        }
2220235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
2230235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        // not currently locked
2240235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        if (usage & (GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_HW_RENDER)) {
2250235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            // locking for write
2260235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            new_value |= private_handle_t::LOCK_STATE_WRITE;
2270235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        }
2280235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        new_value++;
2290235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
2300235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        retry = android_atomic_cmpxchg(current_value, new_value,
2310235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin                (volatile int32_t*)&hnd->lockState);
2320235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    } while (retry);
2330235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
2340235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    if (new_value & private_handle_t::LOCK_STATE_WRITE) {
2350235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        // locking for write, store the tid
2360235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        hnd->writeOwner = gettid();
2370235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    }
2380235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
239dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin    // if requesting sw write for non-framebuffer handles, flag for
240dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin    // flushing at unlock
241a91a220ae435832209702ec59040036d276b63caMathias Agopian
242a91a220ae435832209702ec59040036d276b63caMathias Agopian    const uint32_t pmemMask =
243a91a220ae435832209702ec59040036d276b63caMathias Agopian            private_handle_t::PRIV_FLAGS_USES_PMEM |
244a91a220ae435832209702ec59040036d276b63caMathias Agopian            private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP;
245a91a220ae435832209702ec59040036d276b63caMathias Agopian
246dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin    if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) &&
247a91a220ae435832209702ec59040036d276b63caMathias Agopian            (hnd->flags & pmemMask) &&
248a91a220ae435832209702ec59040036d276b63caMathias Agopian            !(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
249dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin        hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
250dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin    }
251dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin
2520235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
2530235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        if (!(current_value & private_handle_t::LOCK_STATE_MAPPED)) {
2540235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            // we need to map for real
2550235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            pthread_mutex_t* const lock = &sMapLock;
2560235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            pthread_mutex_lock(lock);
2570235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            if (!(hnd->lockState & private_handle_t::LOCK_STATE_MAPPED)) {
2580235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin                err = gralloc_map(module, handle, vaddr);
2590235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin                if (err == 0) {
2600235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin                    android_atomic_or(private_handle_t::LOCK_STATE_MAPPED,
2610235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin                            (volatile int32_t*)&(hnd->lockState));
2620235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin                }
2630235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            }
2640235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            pthread_mutex_unlock(lock);
2650235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        }
2660235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        *vaddr = (void*)hnd->base;
2670235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    }
2680235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
2690235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    return err;
2700235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin}
2710235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
2720235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavinint gralloc_unlock(gralloc_module_t const* module,
2730235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        buffer_handle_t handle)
2740235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin{
2750235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    if (private_handle_t::validate(handle) < 0)
2760235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        return -EINVAL;
2770235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
2780235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    private_handle_t* hnd = (private_handle_t*)handle;
2790235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    int32_t current_value, new_value;
2800235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
281dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin    if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
282dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin        struct pmem_region region;
283dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin        int err;
284dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin
285dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin        region.offset = hnd->offset;
286dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin        region.len = hnd->size;
287dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin        err = ioctl(hnd->fd, PMEM_CACHE_FLUSH, &region);
288c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block        ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%x)\n",
289dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin                hnd, hnd->offset, hnd->size);
290dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin        hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
291dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin    }
292dce2c212be4bc4af3230790ca4d18826a8cab8efDima Zavin
2930235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    do {
2940235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        current_value = hnd->lockState;
2950235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        new_value = current_value;
2960235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
2970235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        if (current_value & private_handle_t::LOCK_STATE_WRITE) {
2980235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            // locked for write
2990235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            if (hnd->writeOwner == gettid()) {
3000235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin                hnd->writeOwner = 0;
3010235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin                new_value &= ~private_handle_t::LOCK_STATE_WRITE;
3020235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            }
3030235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        }
3040235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
3050235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        if ((new_value & private_handle_t::LOCK_STATE_READ_MASK) == 0) {
306c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block            ALOGE("handle %p not locked", handle);
3070235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            return -EINVAL;
3080235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        }
3090235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
3100235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin        new_value--;
3110235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
3120235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    } while (android_atomic_cmpxchg(current_value, new_value,
3130235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin            (volatile int32_t*)&hnd->lockState));
3140235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin
3150235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin    return 0;
3160235ebcc09fe10371788dfcefa4e3f12de3783e4Dima Zavin}
31787ea1dfa60cf130fafdbab8e94cb2ce9ff8d0975Mathias Agopian
31887ea1dfa60cf130fafdbab8e94cb2ce9ff8d0975Mathias Agopian/*****************************************************************************/
31987ea1dfa60cf130fafdbab8e94cb2ce9ff8d0975Mathias Agopian
32087ea1dfa60cf130fafdbab8e94cb2ce9ff8d0975Mathias Agopianint gralloc_perform(struct gralloc_module_t const* module,
32187ea1dfa60cf130fafdbab8e94cb2ce9ff8d0975Mathias Agopian        int operation, ... )
32287ea1dfa60cf130fafdbab8e94cb2ce9ff8d0975Mathias Agopian{
32387ea1dfa60cf130fafdbab8e94cb2ce9ff8d0975Mathias Agopian    int res = -EINVAL;
32487ea1dfa60cf130fafdbab8e94cb2ce9ff8d0975Mathias Agopian    return res;
32587ea1dfa60cf130fafdbab8e94cb2ce9ff8d0975Mathias Agopian}
326