GraphicBufferMapper.cpp revision 4243e666213029a293935987c979831093fb0779
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
394243e666213029a293935987c979831093fb0779Mathias Agopian#define DEBUG_MAPPINGS           0
408b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian// never remove mappings from the list
414243e666213029a293935987c979831093fb0779Mathias Agopian#define DEBUG_MAPPINGS_KEEP_ALL  0
428b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian// ---------------------------------------------------------------------------
438b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian
44076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiannamespace android {
45076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------
46076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
474243e666213029a293935987c979831093fb0779Mathias Agopiantemplate<class BufferMapper> Mutex Singleton<BufferMapper>::sLock;
484243e666213029a293935987c979831093fb0779Mathias Agopiantemplate<> BufferMapper* Singleton<BufferMapper>::sInstance(0);
494243e666213029a293935987c979831093fb0779Mathias Agopian
50076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianBufferMapper::BufferMapper()
51076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    : mAllocMod(0)
52076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
53076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    hw_module_t const* module;
54076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
55076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
56076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err == 0) {
57076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        mAllocMod = (gralloc_module_t const *)module;
58076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
59076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
60076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
614243e666213029a293935987c979831093fb0779Mathias Agopianstatus_t BufferMapper::map(buffer_handle_t handle, void** addr, const void* id)
62076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
63076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Mutex::Autolock _l(mLock);
64076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = mAllocMod->map(mAllocMod, handle, addr);
65076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err));
668b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian#if DEBUG_MAPPINGS
678b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    if (err == NO_ERROR)
684243e666213029a293935987c979831093fb0779Mathias Agopian        logMapLocked(handle, id);
698b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian#endif
70076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
71076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
72076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
734243e666213029a293935987c979831093fb0779Mathias Agopianstatus_t BufferMapper::unmap(buffer_handle_t handle, const void* id)
74076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
75076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Mutex::Autolock _l(mLock);
76076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = mAllocMod->unmap(mAllocMod, handle);
77076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err));
788b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian#if DEBUG_MAPPINGS
798b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    if (err == NO_ERROR)
804243e666213029a293935987c979831093fb0779Mathias Agopian        logUnmapLocked(handle, id);
818b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian#endif
82076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
83076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
84076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
85076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t BufferMapper::lock(buffer_handle_t handle, int usage, const Rect& bounds)
86076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
87076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = mAllocMod->lock(mAllocMod, handle, usage,
88076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            bounds.left, bounds.top, bounds.width(), bounds.height());
89076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err));
90076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
91076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
92076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
93076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t BufferMapper::unlock(buffer_handle_t handle)
94076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
95076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = mAllocMod->unlock(mAllocMod, handle);
96076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err));
97076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
98076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
99076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1004243e666213029a293935987c979831093fb0779Mathias Agopianvoid BufferMapper::logMapLocked(buffer_handle_t handle, const void* id)
1018b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian{
1028b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    CallStack stack;
1038b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    stack.update(2);
1048b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian
1058b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    map_info_t info;
1064243e666213029a293935987c979831093fb0779Mathias Agopian    info.id = id;
1074243e666213029a293935987c979831093fb0779Mathias Agopian    info.stack = stack;
1084243e666213029a293935987c979831093fb0779Mathias Agopian
1098b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    ssize_t index = mMapInfo.indexOfKey(handle);
1108b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    if (index >= 0) {
1114243e666213029a293935987c979831093fb0779Mathias Agopian        Vector<map_info_t>& infos = mMapInfo.editValueAt(index);
1124243e666213029a293935987c979831093fb0779Mathias Agopian        infos.add(info);
1138b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    } else {
1144243e666213029a293935987c979831093fb0779Mathias Agopian        Vector<map_info_t> infos;
1154243e666213029a293935987c979831093fb0779Mathias Agopian        infos.add(info);
1164243e666213029a293935987c979831093fb0779Mathias Agopian        mMapInfo.add(handle, infos);
1178b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    }
1188b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian}
1198b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian
1204243e666213029a293935987c979831093fb0779Mathias Agopianvoid BufferMapper::logUnmapLocked(buffer_handle_t handle, const void* id)
1218b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian{
1228b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    ssize_t index = mMapInfo.indexOfKey(handle);
1238b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    if (index < 0) {
1244243e666213029a293935987c979831093fb0779Mathias Agopian        LOGE("unmapping %p which doesn't exist in our map!", handle);
1258b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        return;
1268b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    }
1278b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian
1284243e666213029a293935987c979831093fb0779Mathias Agopian    Vector<map_info_t>& infos = mMapInfo.editValueAt(index);
1294243e666213029a293935987c979831093fb0779Mathias Agopian    ssize_t count = infos.size();
1304243e666213029a293935987c979831093fb0779Mathias Agopian    for (int i=0 ; i<count ; ) {
1314243e666213029a293935987c979831093fb0779Mathias Agopian        if (infos[i].id == id) {
1324243e666213029a293935987c979831093fb0779Mathias Agopian            infos.removeAt(i);
1334243e666213029a293935987c979831093fb0779Mathias Agopian            --count;
1344243e666213029a293935987c979831093fb0779Mathias Agopian        } else {
1354243e666213029a293935987c979831093fb0779Mathias Agopian            ++i;
1364243e666213029a293935987c979831093fb0779Mathias Agopian        }
1374243e666213029a293935987c979831093fb0779Mathias Agopian    }
1384243e666213029a293935987c979831093fb0779Mathias Agopian    if (count == 0) {
1398b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian        mMapInfo.removeItemsAt(index, 1);
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
1524243e666213029a293935987c979831093fb0779Mathias Agopian    const Vector<map_info_t>& infos = mMapInfo.valueAt(index);
1534243e666213029a293935987c979831093fb0779Mathias Agopian    ssize_t count = infos.size();
1544243e666213029a293935987c979831093fb0779Mathias Agopian    for (int i=0 ; i<count ; i++) {
1554243e666213029a293935987c979831093fb0779Mathias Agopian        LOGD("#%d", i);
1564243e666213029a293935987c979831093fb0779Mathias Agopian        infos[i].stack.dump();
1578b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian    }
1588b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian}
1598b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian
160076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------
161076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}; // namespace android
162