1 /* 2 * Copyright (C) 2010-2017 ARM Limited. All rights reserved. 3 * 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 <log/log.h> 27 #include <cutils/atomic.h> 28 #include <hardware/hardware.h> 29 #include <hardware/fb.h> 30 31 #include <GLES/gl.h> 32 33 #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" 42 #include "gralloc_helper.h" 43 #include "gralloc_vsync.h" 44 #include "mali_gralloc_bufferaccess.h" 45 #include "mali_gralloc_ion.h" 46 47 #define STANDARD_LINUX_SCREEN 48 49 // numbers of buffers for page flipping 50 #define NUM_BUFFERS NUM_FB_BUFFERS 51 52 enum 53 { 54 PAGE_FLIP = 0x00000001, 55 }; 56 57 static int fb_set_swap_interval(struct framebuffer_device_t *dev, int interval) 58 { 59 if (interval < dev->minSwapInterval) 60 { 61 interval = dev->minSwapInterval; 62 } 63 else if (interval > dev->maxSwapInterval) 64 { 65 interval = dev->maxSwapInterval; 66 } 67 68 private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module); 69 m->swapInterval = interval; 70 71 if (0 == interval) 72 { 73 gralloc_vsync_disable(dev); 74 } 75 else 76 { 77 gralloc_vsync_enable(dev); 78 } 79 80 return 0; 81 } 82 83 static int fb_post(struct framebuffer_device_t *dev, buffer_handle_t buffer) 84 { 85 if (private_handle_t::validate(buffer) < 0) 86 { 87 return -EINVAL; 88 } 89 90 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); 92 93 if (m->currentBuffer) 94 { 95 mali_gralloc_unlock(m, m->currentBuffer); 96 m->currentBuffer = 0; 97 } 98 99 if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) 100 { 101 mali_gralloc_lock(m, buffer, private_module_t::PRIV_USAGE_LOCKED_FOR_POST, -1, -1, -1, -1, NULL); 102 103 int interrupt; 104 m->info.activate = FB_ACTIVATE_VBL; 105 m->info.yoffset = hnd->offset / m->finfo.line_length; 106 107 #ifdef STANDARD_LINUX_SCREEN 108 109 if (ioctl(m->framebuffer->fd, FBIOPAN_DISPLAY, &m->info) == -1) 110 { 111 AERR("FBIOPAN_DISPLAY failed for fd: %d", m->framebuffer->fd); 112 mali_gralloc_unlock(m, buffer); 113 return -errno; 114 } 115 116 #else /*Standard Android way*/ 117 118 if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) 119 { 120 AERR("FBIOPUT_VSCREENINFO failed for fd: %d", m->framebuffer->fd); 121 mali_gralloc_unlock(m, buffer); 122 return -errno; 123 } 124 125 #endif 126 127 if (0 != gralloc_wait_for_vsync(dev)) 128 { 129 AERR("Gralloc wait for vsync failed for fd: %d", m->framebuffer->fd); 130 mali_gralloc_unlock(m, buffer); 131 return -errno; 132 } 133 134 m->currentBuffer = buffer; 135 } 136 else 137 { 138 void *fb_vaddr; 139 void *buffer_vaddr; 140 141 mali_gralloc_lock(m, m->framebuffer, GRALLOC_USAGE_SW_WRITE_RARELY, -1, -1, -1, -1, &fb_vaddr); 142 143 mali_gralloc_lock(m, buffer, GRALLOC_USAGE_SW_READ_RARELY, -1, -1, -1, -1, &buffer_vaddr); 144 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. 147 if (hnd->byte_stride == (int)m->finfo.line_length) 148 { 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 { 159 memcpy((void *)((uintptr_t)fb_vaddr + fb_offset), (void *)((uintptr_t)buffer_vaddr + buffer_offset), 160 m->finfo.line_length); 161 162 fb_offset += m->finfo.line_length; 163 buffer_offset += hnd->byte_stride; 164 } 165 } 166 167 mali_gralloc_unlock(m, buffer); 168 mali_gralloc_unlock(m, m->framebuffer); 169 } 170 171 return 0; 172 } 173 174 static int init_frame_buffer_locked(struct private_module_t *module) 175 { 176 if (module->framebuffer) 177 { 178 return 0; // Nothing to do, already initialized 179 } 180 181 char const *const device_template[] = { "/dev/graphics/fb%u", "/dev/fb%u", NULL }; 182 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; 200 201 if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) 202 { 203 return -errno; 204 } 205 206 struct fb_var_screeninfo info; 207 208 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; 225 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; 233 #else 234 /* 235 * Explicitly request 8/8/8 236 */ 237 info.bits_per_pixel = 32; 238 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; 246 #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; 254 255 if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) 256 { 257 info.yres_virtual = info.yres; 258 flags &= ~PAGE_FLIP; 259 AWAR("FBIOPUT_VSCREENINFO failed, page flipping not supported fd: %d", fd); 260 } 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; 267 AWAR("page flipping not supported (yres_virtual=%d, requested=%d)", info.yres_virtual, info.yres * 2); 268 } 269 270 if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) 271 { 272 return -errno; 273 } 274 275 int refreshRate = 0; 276 277 if (info.pixclock > 0) 278 { 279 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); 282 } 283 else 284 { 285 AWAR("fbdev pixclock is zero for fd: %d", fd); 286 } 287 288 if (refreshRate == 0) 289 { 290 refreshRate = 60 * 1000; // 60 Hz 291 } 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 297 info.width = ((info.xres * 25.4f) / 160.0f + 0.5f); 298 info.height = ((info.yres * 25.4f) / 160.0f + 0.5f); 299 } 300 301 float xdpi = (info.xres * 25.4f) / info.width; 302 float ydpi = (info.yres * 25.4f) / info.height; 303 float fps = refreshRate / 1000.0f; 304 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", 315 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); 317 318 AINF("width = %d mm (%f dpi)\n" 319 "height = %d mm (%f dpi)\n" 320 "refresh rate = %.2f Hz\n", 321 info.width, xdpi, info.height, ydpi, fps); 322 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 } 331 else if (0 == strncmp(finfo.id, "ARM HDLCD Control", 16)) 332 { 333 module->dpy_type = MALI_DPY_TYPE_HDLCD; 334 } 335 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); 362 void *vaddr = mmap(0, fbSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 363 364 if (vaddr == MAP_FAILED) 365 { 366 AERR("Error mapping the framebuffer (%s)", strerror(errno)); 367 return -errno; 368 } 369 370 memset(vaddr, 0, fbSize); 371 372 // Create a "fake" buffer object for the entire frame buffer memory, and store it in the module 373 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); 375 376 module->numBuffers = info.yres_virtual / info.yres; 377 module->bufferMask = 0; 378 379 return 0; 380 } 381 382 static int init_frame_buffer(struct private_module_t *module) 383 { 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 390 static int fb_close(struct hw_device_t *device) 391 { 392 framebuffer_device_t *dev = reinterpret_cast<framebuffer_device_t *>(device); 393 394 if (dev) 395 { 396 free(dev); 397 } 398 399 return 0; 400 } 401 402 static 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 422 static 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 440 static 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 524 int 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 533 int compositionComplete(struct framebuffer_device_t *dev) 534 { 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. 545 However this "bad" behaviour by SurfaceFlinger should not affect performance, 546 since the Applications that render the SourceBuffers (Layers) still get the 547 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 549 is normally faster even if it does everyhing synchronous and serial. 550 */ 551 return 0; 552 } 553 554 int framebuffer_device_open(hw_module_t const *module, const char *name, hw_device_t **device) 555 { 556 int status = -EINVAL; 557 558 GRALLOC_UNUSED(name); 559 560 #if GRALLOC_USE_GRALLOC1_API == 1 561 gralloc1_device_t *gralloc_device; 562 #else 563 alloc_device_t *gralloc_device; 564 #endif 565 566 #if DISABLE_FRAMEBUFFER_HAL == 1 567 AERR("Framebuffer HAL not support/disabled %s", 568 #ifdef MALI_DISPLAY_VERSION 569 "with MALI display enable"); 570 #else 571 ""); 572 #endif 573 return -ENODEV; 574 #endif 575 576 #if GRALLOC_USE_GRALLOC1_API == 1 577 status = gralloc1_open(module, &gralloc_device); 578 #else 579 status = gralloc_open(module, &gralloc_device); 580 #endif 581 582 if (status < 0) 583 { 584 return status; 585 } 586 587 private_module_t *m = (private_module_t *)module; 588 status = init_frame_buffer(m); 589 590 /* malloc is used instead of 'new' to instantiate the struct framebuffer_device_t 591 * C++11 spec specifies that if a class/struct has a const member,default constructor 592 * 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 594 * it will still try to use the base class constructor to initialize the members, resulting 595 * in error 'deleted constructor'. 596 * This leaves two options 597 * 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 600 * Option 2: use malloc instead of 'new' to allocate the class/struct and initialize the members in code. 601 * This is the only maintainable option available. 602 */ 603 604 framebuffer_device_t *dev = reinterpret_cast<framebuffer_device_t *>(malloc(sizeof(framebuffer_device_t))); 605 606 /* if either or both of init_frame_buffer() and malloc failed */ 607 if ((status < 0) || (!dev)) 608 { 609 #if GRALLOC_USE_GRALLOC1_API == 1 610 gralloc1_close(gralloc_device); 611 #else 612 gralloc_close(gralloc_device); 613 #endif 614 (!dev) ? (void)(status = -ENOMEM) : free(dev); 615 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; 623 dev->common.module = const_cast<hw_module_t *>(module); 624 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); 631 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; 635 #ifdef GRALLOC_16_BITS 636 const_cast<int &>(dev->format) = HAL_PIXEL_FORMAT_RGB_565; 637 #else 638 const_cast<int &>(dev->format) = HAL_PIXEL_FORMAT_BGRA_8888; 639 #endif 640 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; 645 *device = &dev->common; 646 647 gralloc_vsync_enable(dev); 648 649 return status; 650 } 651