GraphicBufferMapper.cpp revision 8b765b7f5ea7f56963ea0e3141d043d20944dbcc
1076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian/*
2076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * Copyright (C) 2007 The Android Open Source Project
3076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian *
4076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
5076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * you may not use this file except in compliance with the License.
6076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * You may obtain a copy of the License at
7076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian *
8076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
9076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian *
10076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * Unless required by applicable law or agreed to in writing, software
11076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
12076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * See the License for the specific language governing permissions and
14076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * limitations under the License.
15076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian */
16076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
17076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#define LOG_TAG "BufferMapper"
18076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
19076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <stdint.h>
20076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <unistd.h>
21076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <fcntl.h>
22076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <errno.h>
23076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <sys/types.h>
24076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <sys/stat.h>
25076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
26076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <utils/Errors.h>
27076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <utils/threads.h>
28076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <utils/Log.h>
29076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
30076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/BufferMapper.h>
31076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/Rect.h>
32076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
33076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <EGL/android_natives.h>
34076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
35076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <hardware/gralloc.h>
36076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
378b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian// ---------------------------------------------------------------------------
388b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian// enable mapping debugging
398b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian#define DEBUG_MAPPINGS           1
408b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian// never remove mappings from the list
418b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian#define DEBUG_MAPPINGS_KEEP_ALL  1
428b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian// ---------------------------------------------------------------------------
438b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian
44076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiannamespace android {
45076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------
46076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
47076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianBufferMapper::BufferMapper()
48076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    : mAllocMod(0)
49076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
50076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    hw_module_t const* module;
51076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
52076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
53076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err == 0) {
54076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mAllocMod = (gralloc_module_t const *)module;
55076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
56076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
57076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
58076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t BufferMapper::map(buffer_handle_t handle, void** addr)
59076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
60076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Mutex::Autolock _l(mLock);
61076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = mAllocMod->map(mAllocMod, handle, addr);
62076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err));
638b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian#if DEBUG_MAPPINGS
648b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    if (err == NO_ERROR)
658b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        logMapLocked(handle);
668b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian#endif
67076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
68076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
69076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
70076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t BufferMapper::unmap(buffer_handle_t handle)
71076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
72076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Mutex::Autolock _l(mLock);
73076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = mAllocMod->unmap(mAllocMod, handle);
74076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err));
758b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian#if DEBUG_MAPPINGS
768b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    if (err == NO_ERROR)
778b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        logUnmapLocked(handle);
788b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian#endif
79076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
80076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
81076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
82076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t BufferMapper::lock(buffer_handle_t handle, int usage, const Rect& bounds)
83076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
84076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = mAllocMod->lock(mAllocMod, handle, usage,
85076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            bounds.left, bounds.top, bounds.width(), bounds.height());
86076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err));
87076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
88076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
89076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
90076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t BufferMapper::unlock(buffer_handle_t handle)
91076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
92076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = mAllocMod->unlock(mAllocMod, handle);
93076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err));
94076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
95076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
96076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
978b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopianvoid BufferMapper::logMapLocked(buffer_handle_t handle)
988b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian{
998b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    CallStack stack;
1008b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    stack.update(2);
1018b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian
1028b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    map_info_t info;
1038b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    ssize_t index = mMapInfo.indexOfKey(handle);
1048b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    if (index >= 0) {
1058b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        info = mMapInfo.valueAt(index);
1068b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    }
1078b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian
1088b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    ssize_t stackIndex = info.callstacks.indexOfKey(stack);
1098b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    if (stackIndex >= 0) {
1108b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        info.callstacks.editValueAt(stackIndex) += 1;
1118b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    } else {
1128b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        info.callstacks.add(stack, 1);
1138b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    }
1148b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian
1158b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    if (index < 0) {
1168b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        info.count = 1;
1178b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        mMapInfo.add(handle, info);
1188b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    } else {
1198b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        info.count++;
1208b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        mMapInfo.replaceValueAt(index, info);
1218b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    }
1228b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian}
1238b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian
1248b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopianvoid BufferMapper::logUnmapLocked(buffer_handle_t handle)
1258b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian{
1268b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    ssize_t index = mMapInfo.indexOfKey(handle);
1278b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    if (index < 0) {
1288b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        LOGE("unmapping %p which doesn't exist!", handle);
1298b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        return;
1308b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    }
1318b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian
1328b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    map_info_t& info = mMapInfo.editValueAt(index);
1338b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    info.count--;
1348b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    if (info.count == 0) {
1358b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian#if DEBUG_MAPPINGS_KEEP_ALL
1368b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        info.callstacks.clear();
1378b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian#else
1388b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        mMapInfo.removeItemsAt(index, 1);
1398b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian#endif
1408b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    }
1418b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian}
1428b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian
1438b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopianvoid BufferMapper::dump(buffer_handle_t handle)
1448b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian{
1458b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    Mutex::Autolock _l(mLock);
1468b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    ssize_t index = mMapInfo.indexOfKey(handle);
1478b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    if (index < 0) {
1488b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        LOGD("handle %p is not mapped through BufferMapper", handle);
1498b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        return;
1508b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    }
1518b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian
1528b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    const map_info_t& info = mMapInfo.valueAt(index);
1538b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    LOGD("dumping buffer_handle_t %p mappings (count=%d)", handle, info.count);
1548b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    for (size_t i=0 ; i<info.callstacks.size() ; i++) {
1558b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        LOGD("#%d, count=%d", i, info.callstacks.valueAt(i));
1568b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        info.callstacks.keyAt(i).dump();
1578b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    }
1588b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian}
1598b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian
160076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------
161076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}; // namespace android
162