blob: c7e439c3c9684775080bafa578b4df47109d6141 [file] [log] [blame]
Mathias Agopian076b1cc2009-04-10 14:24:30 -07001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "BufferMapper"
18
19#include <stdint.h>
20#include <unistd.h>
21#include <fcntl.h>
22#include <errno.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25
26#include <utils/Errors.h>
27#include <utils/threads.h>
28#include <utils/Log.h>
29
30#include <ui/BufferMapper.h>
31#include <ui/Rect.h>
32
33#include <EGL/android_natives.h>
34
35#include <hardware/gralloc.h>
36
Mathias Agopian8b765b72009-04-10 20:34:46 -070037// ---------------------------------------------------------------------------
38// enable mapping debugging
39#define DEBUG_MAPPINGS 1
40// never remove mappings from the list
41#define DEBUG_MAPPINGS_KEEP_ALL 1
42// ---------------------------------------------------------------------------
43
Mathias Agopian076b1cc2009-04-10 14:24:30 -070044namespace android {
45// ---------------------------------------------------------------------------
46
47BufferMapper::BufferMapper()
48 : mAllocMod(0)
49{
50 hw_module_t const* module;
51 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
52 LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
53 if (err == 0) {
54 mAllocMod = (gralloc_module_t const *)module;
55 }
56}
57
58status_t BufferMapper::map(buffer_handle_t handle, void** addr)
59{
60 Mutex::Autolock _l(mLock);
61 status_t err = mAllocMod->map(mAllocMod, handle, addr);
62 LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err));
Mathias Agopian8b765b72009-04-10 20:34:46 -070063#if DEBUG_MAPPINGS
64 if (err == NO_ERROR)
65 logMapLocked(handle);
66#endif
Mathias Agopian076b1cc2009-04-10 14:24:30 -070067 return err;
68}
69
70status_t BufferMapper::unmap(buffer_handle_t handle)
71{
72 Mutex::Autolock _l(mLock);
73 status_t err = mAllocMod->unmap(mAllocMod, handle);
74 LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err));
Mathias Agopian8b765b72009-04-10 20:34:46 -070075#if DEBUG_MAPPINGS
76 if (err == NO_ERROR)
77 logUnmapLocked(handle);
78#endif
Mathias Agopian076b1cc2009-04-10 14:24:30 -070079 return err;
80}
81
82status_t BufferMapper::lock(buffer_handle_t handle, int usage, const Rect& bounds)
83{
84 status_t err = mAllocMod->lock(mAllocMod, handle, usage,
85 bounds.left, bounds.top, bounds.width(), bounds.height());
86 LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err));
87 return err;
88}
89
90status_t BufferMapper::unlock(buffer_handle_t handle)
91{
92 status_t err = mAllocMod->unlock(mAllocMod, handle);
93 LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err));
94 return err;
95}
96
Mathias Agopian8b765b72009-04-10 20:34:46 -070097void BufferMapper::logMapLocked(buffer_handle_t handle)
98{
99 CallStack stack;
100 stack.update(2);
101
102 map_info_t info;
103 ssize_t index = mMapInfo.indexOfKey(handle);
104 if (index >= 0) {
105 info = mMapInfo.valueAt(index);
106 }
107
108 ssize_t stackIndex = info.callstacks.indexOfKey(stack);
109 if (stackIndex >= 0) {
110 info.callstacks.editValueAt(stackIndex) += 1;
111 } else {
112 info.callstacks.add(stack, 1);
113 }
114
115 if (index < 0) {
116 info.count = 1;
117 mMapInfo.add(handle, info);
118 } else {
119 info.count++;
120 mMapInfo.replaceValueAt(index, info);
121 }
122}
123
124void BufferMapper::logUnmapLocked(buffer_handle_t handle)
125{
126 ssize_t index = mMapInfo.indexOfKey(handle);
127 if (index < 0) {
128 LOGE("unmapping %p which doesn't exist!", handle);
129 return;
130 }
131
132 map_info_t& info = mMapInfo.editValueAt(index);
133 info.count--;
134 if (info.count == 0) {
135#if DEBUG_MAPPINGS_KEEP_ALL
136 info.callstacks.clear();
137#else
138 mMapInfo.removeItemsAt(index, 1);
139#endif
140 }
141}
142
143void BufferMapper::dump(buffer_handle_t handle)
144{
145 Mutex::Autolock _l(mLock);
146 ssize_t index = mMapInfo.indexOfKey(handle);
147 if (index < 0) {
148 LOGD("handle %p is not mapped through BufferMapper", handle);
149 return;
150 }
151
152 const map_info_t& info = mMapInfo.valueAt(index);
153 LOGD("dumping buffer_handle_t %p mappings (count=%d)", handle, info.count);
154 for (size_t i=0 ; i<info.callstacks.size() ; i++) {
155 LOGD("#%d, count=%d", i, info.callstacks.valueAt(i));
156 info.callstacks.keyAt(i).dump();
157 }
158}
159
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700160// ---------------------------------------------------------------------------
161}; // namespace android