blob: 44c469549312546c8766f89f773c6e013d2fef54 [file] [log] [blame]
John Stultz16100f62017-05-03 11:12:18 -07001/*
John Stultz18814f62018-02-22 16:02:49 -08002 * Copyright (C) 2010-2017 ARM Limited. All rights reserved.
John Stultz16100f62017-05-03 11:12:18 -07003 *
4 * Copyright (C) 2008 The Android Open Source Project
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#include <string.h>
20#include <errno.h>
21#include <fcntl.h>
22#include <stdlib.h>
23#include <sys/ioctl.h>
24#include <linux/fb.h>
25
26#include <cutils/log.h>
27#include <cutils/atomic.h>
28#include <hardware/hardware.h>
John Stultz18814f62018-02-22 16:02:49 -080029#include <hardware/fb.h>
John Stultz16100f62017-05-03 11:12:18 -070030
31#include <GLES/gl.h>
32
John Stultz18814f62018-02-22 16:02:49 -080033#if GRALLOC_USE_GRALLOC1_API == 1
34#include <hardware/gralloc1.h>
35#else
36#include <hardware/gralloc.h>
37#endif
38
39#include "mali_gralloc_module.h"
40#include "mali_gralloc_private_interface_types.h"
41#include "mali_gralloc_buffer.h"
John Stultz16100f62017-05-03 11:12:18 -070042#include "gralloc_helper.h"
43#include "gralloc_vsync.h"
John Stultz18814f62018-02-22 16:02:49 -080044#include "mali_gralloc_bufferaccess.h"
45#include "mali_gralloc_ion.h"
John Stultz16100f62017-05-03 11:12:18 -070046
47#define STANDARD_LINUX_SCREEN
48
49// numbers of buffers for page flipping
John Stultz18814f62018-02-22 16:02:49 -080050#define NUM_BUFFERS NUM_FB_BUFFERS
John Stultz16100f62017-05-03 11:12:18 -070051
52enum
53{
54 PAGE_FLIP = 0x00000001,
55};
56
John Stultz18814f62018-02-22 16:02:49 -080057static int fb_set_swap_interval(struct framebuffer_device_t *dev, int interval)
John Stultz16100f62017-05-03 11:12:18 -070058{
59 if (interval < dev->minSwapInterval)
60 {
61 interval = dev->minSwapInterval;
62 }
63 else if (interval > dev->maxSwapInterval)
64 {
65 interval = dev->maxSwapInterval;
66 }
67
John Stultz18814f62018-02-22 16:02:49 -080068 private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
John Stultz16100f62017-05-03 11:12:18 -070069 m->swapInterval = interval;
70
John Stultz18814f62018-02-22 16:02:49 -080071 if (0 == interval)
72 {
73 gralloc_vsync_disable(dev);
74 }
75 else
76 {
77 gralloc_vsync_enable(dev);
78 }
John Stultz16100f62017-05-03 11:12:18 -070079
80 return 0;
81}
82
John Stultz18814f62018-02-22 16:02:49 -080083static int fb_post(struct framebuffer_device_t *dev, buffer_handle_t buffer)
John Stultz16100f62017-05-03 11:12:18 -070084{
85 if (private_handle_t::validate(buffer) < 0)
86 {
87 return -EINVAL;
88 }
89
John Stultz18814f62018-02-22 16:02:49 -080090 private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(buffer);
91 private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
John Stultz16100f62017-05-03 11:12:18 -070092
93 if (m->currentBuffer)
94 {
John Stultz18814f62018-02-22 16:02:49 -080095 mali_gralloc_unlock(m, m->currentBuffer);
John Stultz16100f62017-05-03 11:12:18 -070096 m->currentBuffer = 0;
97 }
98
99 if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
100 {
John Stultz18814f62018-02-22 16:02:49 -0800101 mali_gralloc_lock(m, buffer, private_module_t::PRIV_USAGE_LOCKED_FOR_POST, -1, -1, -1, -1, NULL);
John Stultz16100f62017-05-03 11:12:18 -0700102
John Stultz16100f62017-05-03 11:12:18 -0700103 int interrupt;
104 m->info.activate = FB_ACTIVATE_VBL;
John Stultz18814f62018-02-22 16:02:49 -0800105 m->info.yoffset = hnd->offset / m->finfo.line_length;
John Stultz16100f62017-05-03 11:12:18 -0700106
107#ifdef STANDARD_LINUX_SCREEN
John Stultz18814f62018-02-22 16:02:49 -0800108
109 if (ioctl(m->framebuffer->fd, FBIOPAN_DISPLAY, &m->info) == -1)
John Stultz16100f62017-05-03 11:12:18 -0700110 {
John Stultz18814f62018-02-22 16:02:49 -0800111 AERR("FBIOPAN_DISPLAY failed for fd: %d", m->framebuffer->fd);
112 mali_gralloc_unlock(m, buffer);
John Stultz16100f62017-05-03 11:12:18 -0700113 return -errno;
114 }
John Stultz18814f62018-02-22 16:02:49 -0800115
John Stultz16100f62017-05-03 11:12:18 -0700116#else /*Standard Android way*/
John Stultz18814f62018-02-22 16:02:49 -0800117
118 if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1)
John Stultz16100f62017-05-03 11:12:18 -0700119 {
John Stultz18814f62018-02-22 16:02:49 -0800120 AERR("FBIOPUT_VSCREENINFO failed for fd: %d", m->framebuffer->fd);
121 mali_gralloc_unlock(m, buffer);
John Stultz16100f62017-05-03 11:12:18 -0700122 return -errno;
123 }
John Stultz18814f62018-02-22 16:02:49 -0800124
John Stultz16100f62017-05-03 11:12:18 -0700125#endif
John Stultz18814f62018-02-22 16:02:49 -0800126
127 if (0 != gralloc_wait_for_vsync(dev))
John Stultz16100f62017-05-03 11:12:18 -0700128 {
John Stultz18814f62018-02-22 16:02:49 -0800129 AERR("Gralloc wait for vsync failed for fd: %d", m->framebuffer->fd);
130 mali_gralloc_unlock(m, buffer);
John Stultz16100f62017-05-03 11:12:18 -0700131 return -errno;
132 }
John Stultz18814f62018-02-22 16:02:49 -0800133
John Stultz16100f62017-05-03 11:12:18 -0700134 m->currentBuffer = buffer;
John Stultz18814f62018-02-22 16:02:49 -0800135 }
John Stultz16100f62017-05-03 11:12:18 -0700136 else
137 {
John Stultz18814f62018-02-22 16:02:49 -0800138 void *fb_vaddr;
139 void *buffer_vaddr;
John Stultz16100f62017-05-03 11:12:18 -0700140
John Stultz18814f62018-02-22 16:02:49 -0800141 mali_gralloc_lock(m, m->framebuffer, GRALLOC_USAGE_SW_WRITE_RARELY, -1, -1, -1, -1, &fb_vaddr);
John Stultz16100f62017-05-03 11:12:18 -0700142
John Stultz18814f62018-02-22 16:02:49 -0800143 mali_gralloc_lock(m, buffer, GRALLOC_USAGE_SW_READ_RARELY, -1, -1, -1, -1, &buffer_vaddr);
John Stultz16100f62017-05-03 11:12:18 -0700144
145 // If buffer's alignment match framebuffer alignment we can do a direct copy.
146 // If not we must fallback to do an aligned copy of each line.
John Stultz18814f62018-02-22 16:02:49 -0800147 if (hnd->byte_stride == (int)m->finfo.line_length)
John Stultz16100f62017-05-03 11:12:18 -0700148 {
149 memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres);
150 }
151 else
152 {
153 uintptr_t fb_offset = 0;
154 uintptr_t buffer_offset = 0;
155 unsigned int i;
156
157 for (i = 0; i < m->info.yres; i++)
158 {
John Stultz18814f62018-02-22 16:02:49 -0800159 memcpy((void *)((uintptr_t)fb_vaddr + fb_offset), (void *)((uintptr_t)buffer_vaddr + buffer_offset),
160 m->finfo.line_length);
John Stultz16100f62017-05-03 11:12:18 -0700161
162 fb_offset += m->finfo.line_length;
163 buffer_offset += hnd->byte_stride;
164 }
165 }
John Stultz18814f62018-02-22 16:02:49 -0800166
167 mali_gralloc_unlock(m, buffer);
168 mali_gralloc_unlock(m, m->framebuffer);
John Stultz16100f62017-05-03 11:12:18 -0700169 }
170
171 return 0;
172}
173
John Stultz18814f62018-02-22 16:02:49 -0800174static int init_frame_buffer_locked(struct private_module_t *module)
John Stultz16100f62017-05-03 11:12:18 -0700175{
176 if (module->framebuffer)
177 {
178 return 0; // Nothing to do, already initialized
179 }
John Stultz18814f62018-02-22 16:02:49 -0800180
181 char const *const device_template[] = { "/dev/graphics/fb%u", "/dev/fb%u", NULL };
John Stultz16100f62017-05-03 11:12:18 -0700182
183 int fd = -1;
184 int i = 0;
185 char name[64];
186
187 while ((fd == -1) && device_template[i])
188 {
189 snprintf(name, 64, device_template[i], 0);
190 fd = open(name, O_RDWR, 0);
191 i++;
192 }
193
194 if (fd < 0)
195 {
196 return -errno;
197 }
198
199 struct fb_fix_screeninfo finfo;
John Stultz18814f62018-02-22 16:02:49 -0800200
John Stultz16100f62017-05-03 11:12:18 -0700201 if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
202 {
203 return -errno;
204 }
205
206 struct fb_var_screeninfo info;
John Stultz18814f62018-02-22 16:02:49 -0800207
John Stultz16100f62017-05-03 11:12:18 -0700208 if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
209 {
210 return -errno;
211 }
212
213 info.reserved[0] = 0;
214 info.reserved[1] = 0;
215 info.reserved[2] = 0;
216 info.xoffset = 0;
217 info.yoffset = 0;
218 info.activate = FB_ACTIVATE_NOW;
219
220#ifdef GRALLOC_16_BITS
221 /*
222 * Explicitly request 5/6/5
223 */
224 info.bits_per_pixel = 16;
John Stultz18814f62018-02-22 16:02:49 -0800225 info.red.offset = 11;
226 info.red.length = 5;
227 info.green.offset = 5;
228 info.green.length = 6;
229 info.blue.offset = 0;
230 info.blue.length = 5;
231 info.transp.offset = 0;
232 info.transp.length = 0;
John Stultz16100f62017-05-03 11:12:18 -0700233#else
234 /*
235 * Explicitly request 8/8/8
236 */
237 info.bits_per_pixel = 32;
John Stultz18814f62018-02-22 16:02:49 -0800238 info.red.offset = 16;
239 info.red.length = 8;
240 info.green.offset = 8;
241 info.green.length = 8;
242 info.blue.offset = 0;
243 info.blue.length = 8;
244 info.transp.offset = 0;
245 info.transp.length = 0;
John Stultz16100f62017-05-03 11:12:18 -0700246#endif
247
248 /*
249 * Request NUM_BUFFERS screens (at lest 2 for page flipping)
250 */
251 info.yres_virtual = info.yres * NUM_BUFFERS;
252
253 uint32_t flags = PAGE_FLIP;
John Stultz18814f62018-02-22 16:02:49 -0800254
John Stultz16100f62017-05-03 11:12:18 -0700255 if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1)
256 {
257 info.yres_virtual = info.yres;
258 flags &= ~PAGE_FLIP;
John Stultz18814f62018-02-22 16:02:49 -0800259 AWAR("FBIOPUT_VSCREENINFO failed, page flipping not supported fd: %d", fd);
John Stultz16100f62017-05-03 11:12:18 -0700260 }
261
262 if (info.yres_virtual < info.yres * 2)
263 {
264 // we need at least 2 for page-flipping
265 info.yres_virtual = info.yres;
266 flags &= ~PAGE_FLIP;
John Stultz18814f62018-02-22 16:02:49 -0800267 AWAR("page flipping not supported (yres_virtual=%d, requested=%d)", info.yres_virtual, info.yres * 2);
John Stultz16100f62017-05-03 11:12:18 -0700268 }
269
270 if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
271 {
272 return -errno;
273 }
274
275 int refreshRate = 0;
John Stultz18814f62018-02-22 16:02:49 -0800276
277 if (info.pixclock > 0)
John Stultz16100f62017-05-03 11:12:18 -0700278 {
John Stultz18814f62018-02-22 16:02:49 -0800279 refreshRate =
280 1000000000000000LLU / (uint64_t(info.upper_margin + info.lower_margin + info.yres + info.hsync_len) *
281 (info.left_margin + info.right_margin + info.xres + info.vsync_len) * info.pixclock);
John Stultz16100f62017-05-03 11:12:18 -0700282 }
283 else
284 {
John Stultz18814f62018-02-22 16:02:49 -0800285 AWAR("fbdev pixclock is zero for fd: %d", fd);
John Stultz16100f62017-05-03 11:12:18 -0700286 }
287
288 if (refreshRate == 0)
289 {
John Stultz18814f62018-02-22 16:02:49 -0800290 refreshRate = 60 * 1000; // 60 Hz
John Stultz16100f62017-05-03 11:12:18 -0700291 }
292
293 if (int(info.width) <= 0 || int(info.height) <= 0)
294 {
295 // the driver doesn't return that information
296 // default to 160 dpi
John Stultz18814f62018-02-22 16:02:49 -0800297 info.width = ((info.xres * 25.4f) / 160.0f + 0.5f);
298 info.height = ((info.yres * 25.4f) / 160.0f + 0.5f);
John Stultz16100f62017-05-03 11:12:18 -0700299 }
300
301 float xdpi = (info.xres * 25.4f) / info.width;
302 float ydpi = (info.yres * 25.4f) / info.height;
John Stultz18814f62018-02-22 16:02:49 -0800303 float fps = refreshRate / 1000.0f;
John Stultz16100f62017-05-03 11:12:18 -0700304
305 AINF("using (fd=%d)\n"
306 "id = %s\n"
307 "xres = %d px\n"
308 "yres = %d px\n"
309 "xres_virtual = %d px\n"
310 "yres_virtual = %d px\n"
311 "bpp = %d\n"
312 "r = %2u:%u\n"
313 "g = %2u:%u\n"
314 "b = %2u:%u\n",
John Stultz18814f62018-02-22 16:02:49 -0800315 fd, finfo.id, info.xres, info.yres, info.xres_virtual, info.yres_virtual, info.bits_per_pixel, info.red.offset,
316 info.red.length, info.green.offset, info.green.length, info.blue.offset, info.blue.length);
John Stultz16100f62017-05-03 11:12:18 -0700317
318 AINF("width = %d mm (%f dpi)\n"
319 "height = %d mm (%f dpi)\n"
320 "refresh rate = %.2f Hz\n",
John Stultz18814f62018-02-22 16:02:49 -0800321 info.width, xdpi, info.height, ydpi, fps);
John Stultz16100f62017-05-03 11:12:18 -0700322
323 if (0 == strncmp(finfo.id, "CLCD FB", 7))
324 {
325 module->dpy_type = MALI_DPY_TYPE_CLCD;
326 }
327 else if (0 == strncmp(finfo.id, "ARM Mali HDLCD", 14))
328 {
329 module->dpy_type = MALI_DPY_TYPE_HDLCD;
330 }
John Stultz18814f62018-02-22 16:02:49 -0800331 else if (0 == strncmp(finfo.id, "ARM HDLCD Control", 16))
332 {
333 module->dpy_type = MALI_DPY_TYPE_HDLCD;
334 }
John Stultz16100f62017-05-03 11:12:18 -0700335 else
336 {
337 module->dpy_type = MALI_DPY_TYPE_UNKNOWN;
338 }
339
340 if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
341 {
342 return -errno;
343 }
344
345 if (finfo.smem_len <= 0)
346 {
347 return -errno;
348 }
349
350 module->flags = flags;
351 module->info = info;
352 module->finfo = finfo;
353 module->xdpi = xdpi;
354 module->ydpi = ydpi;
355 module->fps = fps;
356 module->swapInterval = 1;
357
358 /*
359 * map the framebuffer
360 */
361 size_t fbSize = round_up_to_page_size(finfo.line_length * info.yres_virtual);
John Stultz18814f62018-02-22 16:02:49 -0800362 void *vaddr = mmap(0, fbSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
363
364 if (vaddr == MAP_FAILED)
John Stultz16100f62017-05-03 11:12:18 -0700365 {
John Stultz18814f62018-02-22 16:02:49 -0800366 AERR("Error mapping the framebuffer (%s)", strerror(errno));
John Stultz16100f62017-05-03 11:12:18 -0700367 return -errno;
368 }
369
370 memset(vaddr, 0, fbSize);
371
John Stultz16100f62017-05-03 11:12:18 -0700372 // Create a "fake" buffer object for the entire frame buffer memory, and store it in the module
John Stultz18814f62018-02-22 16:02:49 -0800373 module->framebuffer = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, fbSize, vaddr,
374 GRALLOC_USAGE_HW_FB, GRALLOC_USAGE_HW_FB, dup(fd), 0);
John Stultz16100f62017-05-03 11:12:18 -0700375
376 module->numBuffers = info.yres_virtual / info.yres;
377 module->bufferMask = 0;
378
379 return 0;
380}
381
John Stultz18814f62018-02-22 16:02:49 -0800382static int init_frame_buffer(struct private_module_t *module)
John Stultz16100f62017-05-03 11:12:18 -0700383{
384 pthread_mutex_lock(&module->lock);
385 int err = init_frame_buffer_locked(module);
386 pthread_mutex_unlock(&module->lock);
387 return err;
388}
389
390static int fb_close(struct hw_device_t *device)
391{
John Stultz18814f62018-02-22 16:02:49 -0800392 framebuffer_device_t *dev = reinterpret_cast<framebuffer_device_t *>(device);
393
John Stultz16100f62017-05-03 11:12:18 -0700394 if (dev)
395 {
396 free(dev);
397 }
John Stultz18814f62018-02-22 16:02:49 -0800398
John Stultz16100f62017-05-03 11:12:18 -0700399 return 0;
400}
401
John Stultz18814f62018-02-22 16:02:49 -0800402static int fb_alloc_framebuffer_dmabuf(private_module_t *m, private_handle_t *hnd)
403{
404 struct fb_dmabuf_export fb_dma_buf;
405 int res;
406 res = ioctl(m->framebuffer->fd, FBIOGET_DMABUF, &fb_dma_buf);
407
408 if (res == 0)
409 {
410 hnd->share_fd = fb_dma_buf.fd;
411 return 0;
412 }
413 else
414 {
415 AINF("FBIOGET_DMABUF ioctl failed(%d). See gralloc_priv.h and the integration manual for vendor framebuffer "
416 "integration",
417 res);
418 return -1;
419 }
420}
421
422static int fb_alloc_from_ion_module(mali_gralloc_module *m, size_t buffer_size, uint64_t consumer_usage,
423 uint64_t producer_usage, buffer_handle_t *pHandle)
424{
425 buffer_descriptor_t fb_buffer_descriptor;
426 gralloc_buffer_descriptor_t gralloc_buffer_descriptor[1];
427 bool shared = false;
428 int err = 0;
429
430 fb_buffer_descriptor.size = buffer_size;
431 fb_buffer_descriptor.consumer_usage = consumer_usage;
432 fb_buffer_descriptor.producer_usage = producer_usage;
433 gralloc_buffer_descriptor[0] = (gralloc_buffer_descriptor_t)(&fb_buffer_descriptor);
434
435 err = mali_gralloc_ion_allocate(m, gralloc_buffer_descriptor, 1, pHandle, &shared);
436
437 return err;
438}
439
440static int fb_alloc_framebuffer_locked(mali_gralloc_module *m, uint64_t consumer_usage, uint64_t producer_usage,
441 buffer_handle_t *pHandle, int *stride, int *byte_stride)
442{
443 // allocate the framebuffer
444 if (m->framebuffer == NULL)
445 {
446 // initialize the framebuffer, the framebuffer is mapped once and forever.
447 int err = init_frame_buffer_locked(m);
448
449 if (err < 0)
450 {
451 return err;
452 }
453 }
454
455 uint32_t bufferMask = m->bufferMask;
456 const uint32_t numBuffers = m->numBuffers;
457 /* framebufferSize is used for allocating the handle to the framebuffer and refers
458 * to the size of the actual framebuffer.
459 * alignedFramebufferSize is used for allocating a possible internal buffer and
460 * thus need to consider internal alignment requirements. */
461 const size_t framebufferSize = m->finfo.line_length * m->info.yres;
462 const size_t alignedFramebufferSize = GRALLOC_ALIGN(m->finfo.line_length, 64) * m->info.yres;
463
464 *stride = m->info.xres;
465
466 if (numBuffers == 1)
467 {
468 // If we have only one buffer, we never use page-flipping. Instead,
469 // we return a regular buffer which will be memcpy'ed to the main
470 // screen when post is called.
471 uint64_t newConsumerUsage = (consumer_usage & ~GRALLOC_USAGE_HW_FB);
472 uint64_t newProducerUsage = (producer_usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
473 AWAR("fallback to single buffering. Virtual Y-res too small %d", m->info.yres);
474 *byte_stride = GRALLOC_ALIGN(m->finfo.line_length, 64);
475 return fb_alloc_from_ion_module(m, alignedFramebufferSize, newConsumerUsage, newProducerUsage, pHandle);
476 }
477
478 if (bufferMask >= ((1LU << numBuffers) - 1))
479 {
480 // We ran out of buffers, reset bufferMask
481 bufferMask = 0;
482 m->bufferMask = 0;
483 }
484
485 uintptr_t framebufferVaddr = (uintptr_t)m->framebuffer->base;
486
487 // find a free slot
488 for (uint32_t i = 0; i < numBuffers; i++)
489 {
490 if ((bufferMask & (1LU << i)) == 0)
491 {
492 m->bufferMask |= (1LU << i);
493 break;
494 }
495
496 framebufferVaddr += framebufferSize;
497 }
498
499 // The entire framebuffer memory is already mapped, now create a buffer object for parts of this memory
500 private_handle_t *hnd = new private_handle_t(
501 private_handle_t::PRIV_FLAGS_FRAMEBUFFER, framebufferSize, (void *)framebufferVaddr, consumer_usage,
502 producer_usage, dup(m->framebuffer->fd), (framebufferVaddr - (uintptr_t)m->framebuffer->base));
503
504 /*
505 * Perform allocator specific actions. If these fail we fall back to a regular buffer
506 * which will be memcpy'ed to the main screen when fb_post is called.
507 */
508 if (fb_alloc_framebuffer_dmabuf(m, hnd) == -1)
509 {
510 delete hnd;
511 uint64_t newConsumerUsage = (consumer_usage & ~GRALLOC_USAGE_HW_FB);
512 uint64_t newProducerUsage = (producer_usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
513 AERR("Fallback to single buffering. Unable to map framebuffer memory to handle:%p", hnd);
514 *byte_stride = GRALLOC_ALIGN(m->finfo.line_length, 64);
515 return fb_alloc_from_ion_module(m, alignedFramebufferSize, newConsumerUsage, newProducerUsage, pHandle);
516 }
517
518 *pHandle = hnd;
519 *byte_stride = m->finfo.line_length;
520
521 return 0;
522}
523
524int fb_alloc_framebuffer(mali_gralloc_module *m, uint64_t consumer_usage, uint64_t producer_usage,
525 buffer_handle_t *pHandle, int *stride, int *byte_stride)
526{
527 pthread_mutex_lock(&m->lock);
528 int err = fb_alloc_framebuffer_locked(m, consumer_usage, producer_usage, pHandle, stride, byte_stride);
529 pthread_mutex_unlock(&m->lock);
530 return err;
531}
532
533int compositionComplete(struct framebuffer_device_t *dev)
John Stultz16100f62017-05-03 11:12:18 -0700534{
535 GRALLOC_UNUSED(dev);
536
537 /* By doing a finish here we force the GL driver to start rendering
538 all the drawcalls up to this point, and to wait for the rendering to be complete.*/
539 glFinish();
540 /* The rendering of the backbuffer is now completed.
541 When SurfaceFlinger later does a call to eglSwapBuffer(), the swap will be done
542 synchronously in the same thread, and not asynchronoulsy in a background thread later.
543 The SurfaceFlinger requires this behaviour since it releases the lock on all the
544 SourceBuffers (Layers) after the compositionComplete() function returns.
John Stultz18814f62018-02-22 16:02:49 -0800545 However this "bad" behaviour by SurfaceFlinger should not affect performance,
546 since the Applications that render the SourceBuffers (Layers) still get the
John Stultz16100f62017-05-03 11:12:18 -0700547 full renderpipeline using asynchronous rendering. So they perform at maximum speed,
548 and because of their complexity compared to the Surface flinger jobs, the Surface flinger
John Stultz18814f62018-02-22 16:02:49 -0800549 is normally faster even if it does everyhing synchronous and serial.
John Stultz16100f62017-05-03 11:12:18 -0700550 */
551 return 0;
552}
553
John Stultz18814f62018-02-22 16:02:49 -0800554int framebuffer_device_open(hw_module_t const *module, const char *name, hw_device_t **device)
John Stultz16100f62017-05-03 11:12:18 -0700555{
556 int status = -EINVAL;
557
558 GRALLOC_UNUSED(name);
559
John Stultz18814f62018-02-22 16:02:49 -0800560#if GRALLOC_USE_GRALLOC1_API == 1
561 gralloc1_device_t *gralloc_device;
562#else
563 alloc_device_t *gralloc_device;
564#endif
565
John Stultz16100f62017-05-03 11:12:18 -0700566#if DISABLE_FRAMEBUFFER_HAL == 1
567 AERR("Framebuffer HAL not support/disabled %s",
568#ifdef MALI_DISPLAY_VERSION
John Stultz18814f62018-02-22 16:02:49 -0800569 "with MALI display enable");
John Stultz16100f62017-05-03 11:12:18 -0700570#else
John Stultz18814f62018-02-22 16:02:49 -0800571 "");
John Stultz16100f62017-05-03 11:12:18 -0700572#endif
573 return -ENODEV;
574#endif
John Stultz18814f62018-02-22 16:02:49 -0800575
576#if GRALLOC_USE_GRALLOC1_API == 1
577 status = gralloc1_open(module, &gralloc_device);
578#else
John Stultz16100f62017-05-03 11:12:18 -0700579 status = gralloc_open(module, &gralloc_device);
John Stultz18814f62018-02-22 16:02:49 -0800580#endif
581
John Stultz16100f62017-05-03 11:12:18 -0700582 if (status < 0)
583 {
584 return status;
585 }
586
John Stultz18814f62018-02-22 16:02:49 -0800587 private_module_t *m = (private_module_t *)module;
John Stultz16100f62017-05-03 11:12:18 -0700588 status = init_frame_buffer(m);
589
590 /* malloc is used instead of 'new' to instantiate the struct framebuffer_device_t
John Stultz18814f62018-02-22 16:02:49 -0800591 * C++11 spec specifies that if a class/struct has a const member,default constructor
John Stultz16100f62017-05-03 11:12:18 -0700592 * is deleted. So, if 'new' is used to instantiate the class/struct, it will throw
593 * error complaining about deleted constructor. Even if the struct is wrapped in a class
John Stultz18814f62018-02-22 16:02:49 -0800594 * it will still try to use the base class constructor to initialize the members, resulting
John Stultz16100f62017-05-03 11:12:18 -0700595 * in error 'deleted constructor'.
John Stultz18814f62018-02-22 16:02:49 -0800596 * This leaves two options
John Stultz16100f62017-05-03 11:12:18 -0700597 * Option 1: initialize the const members at the instantiation time. With {value1, value2 ..}
598 * Which relies on the order of the members, and if members are reordered or a new member is introduced
599 * it will end up assiging wrong value to members. Designated assignment as well has been removed in C++11
John Stultz18814f62018-02-22 16:02:49 -0800600 * Option 2: use malloc instead of 'new' to allocate the class/struct and initialize the members in code.
John Stultz16100f62017-05-03 11:12:18 -0700601 * This is the only maintainable option available.
602 */
603
John Stultz18814f62018-02-22 16:02:49 -0800604 framebuffer_device_t *dev = reinterpret_cast<framebuffer_device_t *>(malloc(sizeof(framebuffer_device_t)));
John Stultz16100f62017-05-03 11:12:18 -0700605
606 /* if either or both of init_frame_buffer() and malloc failed */
607 if ((status < 0) || (!dev))
608 {
John Stultz18814f62018-02-22 16:02:49 -0800609#if GRALLOC_USE_GRALLOC1_API == 1
610 gralloc1_close(gralloc_device);
611#else
John Stultz16100f62017-05-03 11:12:18 -0700612 gralloc_close(gralloc_device);
John Stultz18814f62018-02-22 16:02:49 -0800613#endif
614 (!dev) ? (void)(status = -ENOMEM) : free(dev);
John Stultz16100f62017-05-03 11:12:18 -0700615 return status;
616 }
617
618 memset(dev, 0, sizeof(*dev));
619
620 /* initialize the procs */
621 dev->common.tag = HARDWARE_DEVICE_TAG;
622 dev->common.version = 0;
John Stultz18814f62018-02-22 16:02:49 -0800623 dev->common.module = const_cast<hw_module_t *>(module);
John Stultz16100f62017-05-03 11:12:18 -0700624 dev->common.close = fb_close;
625 dev->setSwapInterval = fb_set_swap_interval;
626 dev->post = fb_post;
627 dev->setUpdateRect = 0;
628 dev->compositionComplete = &compositionComplete;
629
630 int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);
John Stultz18814f62018-02-22 16:02:49 -0800631 const_cast<uint32_t &>(dev->flags) = 0;
632 const_cast<uint32_t &>(dev->width) = m->info.xres;
633 const_cast<uint32_t &>(dev->height) = m->info.yres;
634 const_cast<int &>(dev->stride) = stride;
John Stultz16100f62017-05-03 11:12:18 -0700635#ifdef GRALLOC_16_BITS
John Stultz18814f62018-02-22 16:02:49 -0800636 const_cast<int &>(dev->format) = HAL_PIXEL_FORMAT_RGB_565;
John Stultz16100f62017-05-03 11:12:18 -0700637#else
John Stultz18814f62018-02-22 16:02:49 -0800638 const_cast<int &>(dev->format) = HAL_PIXEL_FORMAT_BGRA_8888;
John Stultz16100f62017-05-03 11:12:18 -0700639#endif
John Stultz18814f62018-02-22 16:02:49 -0800640 const_cast<float &>(dev->xdpi) = m->xdpi;
641 const_cast<float &>(dev->ydpi) = m->ydpi;
642 const_cast<float &>(dev->fps) = m->fps;
643 const_cast<int &>(dev->minSwapInterval) = 0;
644 const_cast<int &>(dev->maxSwapInterval) = 1;
John Stultz16100f62017-05-03 11:12:18 -0700645 *device = &dev->common;
646
647 gralloc_vsync_enable(dev);
648
649 return status;
650}