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, ®ion); 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