1 /*
2 // Copyright (c) 2014 Intel Corporation
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 #include <common/utils/HwcTrace.h>
18 #include <hardware/hwcomposer.h>
19 #include <BufferManager.h>
20 #include <DrmConfig.h>
21
22 namespace android {
23 namespace intel {
24
BufferManager()25 BufferManager::BufferManager()
26 : mGrallocModule(NULL),
27 mAllocDev(NULL),
28 mFrameBuffers(),
29 mBufferPool(NULL),
30 mDataBuffer(NULL),
31 mDataBufferLock(),
32 mInitialized(false)
33 {
34 CTRACE();
35 }
36
~BufferManager()37 BufferManager::~BufferManager()
38 {
39 WARN_IF_NOT_DEINIT();
40 }
41
initCheck() const42 bool BufferManager::initCheck() const
43 {
44 return mInitialized;
45 }
46
initialize()47 bool BufferManager::initialize()
48 {
49 CTRACE();
50
51 // create buffer pool
52 mBufferPool = new BufferCache(DEFAULT_BUFFER_POOL_SIZE);
53 if (!mBufferPool) {
54 ELOGTRACE("failed to create gralloc buffer cache");
55 return false;
56 }
57
58 // init gralloc module
59 hw_module_t const* module;
60 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module)) {
61 DEINIT_AND_RETURN_FALSE("failed to get gralloc module");
62 }
63 mGrallocModule = (gralloc_module_t const*)module;
64
65 gralloc_open(module, &mAllocDev);
66 if (!mAllocDev) {
67 WLOGTRACE("failed to open alloc device");
68 }
69
70 // create a dummy data buffer
71 mDataBuffer = createDataBuffer(0);
72 if (!mDataBuffer) {
73 DEINIT_AND_RETURN_FALSE("failed to create data buffer");
74 }
75
76 mInitialized = true;
77 return true;
78 }
79
deinitialize()80 void BufferManager::deinitialize()
81 {
82 mInitialized = false;
83
84 if (mBufferPool) {
85 // unmap & delete all cached buffer mappers
86 for (size_t i = 0; i < mBufferPool->getCacheSize(); i++) {
87 BufferMapper *mapper = mBufferPool->getMapper(i);
88 mapper->unmap();
89 delete mapper;
90 }
91
92 delete mBufferPool;
93 mBufferPool = NULL;
94 }
95
96 for (size_t j = 0; j < mFrameBuffers.size(); j++) {
97 BufferMapper *mapper = mFrameBuffers.valueAt(j);
98 mapper->unmap();
99 delete mapper;
100 }
101 mFrameBuffers.clear();
102
103 if (mAllocDev) {
104 gralloc_close(mAllocDev);
105 mAllocDev = NULL;
106 }
107
108 if (mDataBuffer) {
109 delete mDataBuffer;
110 mDataBuffer = NULL;
111 }
112 }
113
dump(Dump & d)114 void BufferManager::dump(Dump& d)
115 {
116 d.append("Buffer Manager status: pool size %d\n", mBufferPool->getCacheSize());
117 d.append("-------------------------------------------------------------\n");
118 for (size_t i = 0; i < mBufferPool->getCacheSize(); i++) {
119 BufferMapper *mapper = mBufferPool->getMapper(i);
120 d.append("Buffer %d: handle %#x, (%dx%d), format %d, refCount %d\n",
121 i,
122 mapper->getHandle(),
123 mapper->getWidth(),
124 mapper->getHeight(),
125 mapper->getFormat(),
126 mapper->getRef());
127 }
128 return;
129 }
130
lockDataBuffer(uint32_t handle)131 DataBuffer* BufferManager::lockDataBuffer(uint32_t handle)
132 {
133 mDataBufferLock.lock();
134 mDataBuffer->resetBuffer(handle);
135 return mDataBuffer;
136 }
137
unlockDataBuffer(DataBuffer *)138 void BufferManager::unlockDataBuffer(DataBuffer * /* buffer */)
139 {
140 mDataBufferLock.unlock();
141 }
142
get(uint32_t handle)143 DataBuffer* BufferManager::get(uint32_t handle)
144 {
145 return createDataBuffer(handle);
146 }
147
put(DataBuffer * buffer)148 void BufferManager::put(DataBuffer *buffer)
149 {
150 delete buffer;
151 }
152
map(DataBuffer & buffer)153 BufferMapper* BufferManager::map(DataBuffer& buffer)
154 {
155 bool ret;
156 BufferMapper* mapper;
157
158 CTRACE();
159 Mutex::Autolock _l(mLock);
160 //try to get mapper from pool
161 mapper = mBufferPool->getMapper(buffer.getKey());
162 if (mapper) {
163 // increase mapper ref count
164 mapper->incRef();
165 return mapper;
166 }
167
168 // create a new buffer mapper and add it to pool
169 do {
170 VLOGTRACE("new buffer, will add it");
171 mapper = createBufferMapper(buffer);
172 if (!mapper) {
173 ELOGTRACE("failed to allocate mapper");
174 break;
175 }
176 ret = mapper->map();
177 if (!ret) {
178 ELOGTRACE("failed to map");
179 delete mapper;
180 mapper = NULL;
181 break;
182 }
183 ret = mBufferPool->addMapper(buffer.getKey(), mapper);
184 if (!ret) {
185 ELOGTRACE("failed to add mapper");
186 break;
187 }
188 // increase mapper ref count
189 mapper->incRef();
190 return mapper;
191 } while (0);
192
193 // error handling
194 if (mapper) {
195 mapper->unmap();
196 delete mapper;
197 }
198 return NULL;
199 }
200
unmap(BufferMapper * mapper)201 void BufferManager::unmap(BufferMapper *mapper)
202 {
203 Mutex::Autolock _l(mLock);
204 if (!mapper) {
205 ELOGTRACE("invalid mapper");
206 return;
207 }
208
209 // unmap & remove this mapper from buffer when refCount = 0
210 int refCount = mapper->decRef();
211 if (refCount < 0) {
212 ELOGTRACE("invalid ref count");
213 } else if (!refCount) {
214 // remove mapper from buffer pool
215 mBufferPool->removeMapper(mapper);
216 mapper->unmap();
217 delete mapper;
218 }
219 }
220
allocFrameBuffer(int width,int height,int * stride)221 uint32_t BufferManager::allocFrameBuffer(int width, int height, int *stride)
222 {
223 RETURN_NULL_IF_NOT_INIT();
224
225 if (!mAllocDev) {
226 WLOGTRACE("Alloc device is not available");
227 return 0;
228 }
229
230 if (!width || !height || !stride) {
231 ELOGTRACE("invalid input parameter");
232 return 0;
233 }
234
235 ILOGTRACE("size of frame buffer to create: %dx%d", width, height);
236 uint32_t handle = 0;
237 status_t err = mAllocDev->alloc(
238 mAllocDev,
239 width,
240 height,
241 DrmConfig::getFrameBufferFormat(),
242 0, // GRALLOC_USAGE_HW_FB
243 (buffer_handle_t *)&handle,
244 stride);
245
246 if (err != 0) {
247 ELOGTRACE("failed to allocate frame buffer, error = %d", err);
248 return 0;
249 }
250
251 DataBuffer *buffer = NULL;
252 BufferMapper *mapper = NULL;
253
254 do {
255 buffer = lockDataBuffer(handle);
256 if (!buffer) {
257 ELOGTRACE("failed to get data buffer, handle = %#x", handle);
258 break;
259 }
260
261 mapper = createBufferMapper(*buffer);
262 if (!mapper) {
263 ELOGTRACE("failed to create buffer mapper");
264 break;
265 }
266
267 uint32_t fbHandle;
268 if (!(fbHandle = mapper->getFbHandle(0))) {
269 ELOGTRACE("failed to get Fb handle");
270 break;
271 }
272
273 mFrameBuffers.add(fbHandle, mapper);
274 unlockDataBuffer(buffer);
275 return fbHandle;
276 } while (0);
277
278 // error handling, release all allocated resources
279 if (buffer) {
280 unlockDataBuffer(buffer);
281 }
282 if (mapper) {
283 delete mapper;
284 }
285 mAllocDev->free(mAllocDev, (buffer_handle_t)handle);
286 return 0;
287 }
288
freeFrameBuffer(uint32_t fbHandle)289 void BufferManager::freeFrameBuffer(uint32_t fbHandle)
290 {
291 RETURN_VOID_IF_NOT_INIT();
292
293 if (!mAllocDev) {
294 WLOGTRACE("Alloc device is not available");
295 return;
296 }
297
298 ssize_t index = mFrameBuffers.indexOfKey(fbHandle);
299 if (index < 0) {
300 ELOGTRACE("invalid kernel handle");
301 return;
302 }
303
304 BufferMapper *mapper = mFrameBuffers.valueAt(index);
305 uint32_t handle = mapper->getHandle();
306 mapper->putFbHandle();
307 delete mapper;
308 mFrameBuffers.removeItem(fbHandle);
309 mAllocDev->free(mAllocDev, (buffer_handle_t)handle);
310 }
311
allocGrallocBuffer(uint32_t width,uint32_t height,uint32_t format,uint32_t usage)312 uint32_t BufferManager::allocGrallocBuffer(uint32_t width, uint32_t height, uint32_t format, uint32_t usage)
313 {
314 RETURN_NULL_IF_NOT_INIT();
315
316 if (!mAllocDev) {
317 WLOGTRACE("Alloc device is not available");
318 return 0;
319 }
320
321 if (!width || !height) {
322 ELOGTRACE("invalid input parameter");
323 return 0;
324 }
325
326 ILOGTRACE("size of graphic buffer to create: %dx%d", width, height);
327 uint32_t handle = 0;
328 int stride;
329 status_t err = mAllocDev->alloc(
330 mAllocDev,
331 width,
332 height,
333 format,
334 usage,
335 (buffer_handle_t *)&handle,
336 &stride);
337 if (err != 0) {
338 ELOGTRACE("failed to allocate gralloc buffer, error = %d", err);
339 return 0;
340 }
341
342 return handle;
343 }
344
freeGrallocBuffer(uint32_t handle)345 void BufferManager::freeGrallocBuffer(uint32_t handle)
346 {
347 RETURN_VOID_IF_NOT_INIT();
348 if (!mAllocDev) {
349 WLOGTRACE("Alloc device is not available");
350 return;
351 }
352
353 if (handle)
354 mAllocDev->free(mAllocDev, (buffer_handle_t)handle);
355 }
356
357 } // namespace intel
358 } // namespace android
359