framebuffer.cpp revision 63b00f9573354b80cf6483139766b478bfe2e995
163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian/* 263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * Copyright (C) 2008 The Android Open Source Project 363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * 463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * you may not use this file except in compliance with the License. 663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * You may obtain a copy of the License at 763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * 863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * 1063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * Unless required by applicable law or agreed to in writing, software 1163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 1263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * See the License for the specific language governing permissions and 1463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * limitations under the License. 1563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian */ 1663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 1763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#include <sys/mman.h> 1863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 1963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#include <dlfcn.h> 2063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 2163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#include <cutils/ashmem.h> 2263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#include <cutils/log.h> 2363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 2463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#include <hardware/hardware.h> 2563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#include <hardware/gralloc.h> 2663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 2763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#include <fcntl.h> 2863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#include <errno.h> 2963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#include <sys/ioctl.h> 3063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#include <string.h> 3163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#include <stdlib.h> 3263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 3363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#include <cutils/log.h> 3463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#include <cutils/atomic.h> 3563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 3663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#if HAVE_ANDROID_OS 3763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#include <linux/fb.h> 3863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#endif 3963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 4063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#include "gralloc_priv.h" 4163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 4263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian/*****************************************************************************/ 4363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 4463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian// should be a build option 4563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#define SUPPORTS_UPDATE_ON_DEMAND 1 4663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 4763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian// numbers of buffers for page flipping 4863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#define NUM_BUFFERS 2 4963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 5063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 5163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianenum { 5263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian PAGE_FLIP = 0x00000001, 5363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian LOCKED = 0x00000002 5463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian}; 5563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 5663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianstruct fb_context_t { 5763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian framebuffer_device_t device; 5863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian}; 5963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 6063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian/*****************************************************************************/ 6163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 6263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianstatic int fb_setSwapInterval(struct framebuffer_device_t* dev, 6363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int interval) 6463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian{ 6563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian fb_context_t* ctx = (fb_context_t*)dev; 6663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (interval < dev->minSwapInterval || interval > dev->maxSwapInterval) 6763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -EINVAL; 6863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian // FIXME: implement fb_setSwapInterval 6963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return 0; 7063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian} 7163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 7263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianstatic int fb_setUpdateRect(struct framebuffer_device_t* dev, 7363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int l, int t, int w, int h) 7463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian{ 7563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (((w|h) <= 0) || ((l|t)<0)) 7663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -EINVAL; 7763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 7863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian fb_context_t* ctx = (fb_context_t*)dev; 7963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian private_module_t* m = reinterpret_cast<private_module_t*>( 8063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->common.module); 8163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->info.reserved[0] = 0x54445055; // "UPDT"; 8263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->info.reserved[1] = (uint16_t)l | ((uint32_t)t << 16); 8363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->info.reserved[2] = (uint16_t)(l+w) | ((uint32_t)(t+h) << 16); 8463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return 0; 8563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian} 8663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 8763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianstatic int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer) 8863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian{ 8963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (private_handle_t::validate(buffer) < 0) 9063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -EINVAL; 9163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 9263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian fb_context_t* ctx = (fb_context_t*)dev; 9363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 9463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(buffer); 9563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian private_module_t* m = reinterpret_cast<private_module_t*>( 9663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->common.module); 9763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 9863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (m->currentBuffer) { 9963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->base.unlock(&m->base, m->currentBuffer); 10063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->currentBuffer = 0; 10163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 10263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 10363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) { 10463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 10563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->base.lock(&m->base, buffer, 10663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian private_module_t::PRIV_USAGE_LOCKED_FOR_POST, 10763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 0, 0, m->info.xres, m->info.yres, NULL); 10863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 10963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const size_t offset = hnd->base - m->framebuffer->base; 11063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->info.activate = FB_ACTIVATE_VBL; 11163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->info.yoffset = offset / m->finfo.line_length; 11263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) { 11363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian LOGE("FBIOPUT_VSCREENINFO failed"); 11463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->base.unlock(&m->base, buffer); 11563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -errno; 11663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 11763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->currentBuffer = buffer; 11863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 11963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } else { 12063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian // If we can't do the page_flip, just copy the buffer to the front 12163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian // FIXME: use copybit HAL instead of memcpy 12263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 12363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian void* fb_vaddr; 12463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian void* buffer_vaddr; 12563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 12663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->base.lock(&m->base, m->framebuffer, 12763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian GRALLOC_USAGE_SW_WRITE_RARELY, 12863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 0, 0, m->info.xres, m->info.yres, 12963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian &fb_vaddr); 13063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 13163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->base.lock(&m->base, buffer, 13263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian GRALLOC_USAGE_SW_READ_RARELY, 13363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 0, 0, m->info.xres, m->info.yres, 13463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian &buffer_vaddr); 13563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 13663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres); 13763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 13863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->base.unlock(&m->base, buffer); 13963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->base.unlock(&m->base, m->framebuffer); 14063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 14163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 14263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return 0; 14363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian} 14463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 14563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian/*****************************************************************************/ 14663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 14763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianint mapFrameBufferLocked(struct private_module_t* module) 14863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian{ 14963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian // already initialized... 15063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (module->framebuffer) { 15163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return 0; 15263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 15363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 15463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian char const * const device_template[] = { 15563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "/dev/graphics/fb%u", 15663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "/dev/fb%u", 15763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 0 }; 15863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 15963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int fd = -1; 16063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int i=0; 16163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian char name[64]; 16263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 16363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian while ((fd==-1) && device_template[i]) { 16463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian snprintf(name, 64, device_template[i], 0); 16563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian fd = open(name, O_RDWR, 0); 16663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian i++; 16763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 16863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (fd < 0) 16963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -errno; 17063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 17163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian struct fb_fix_screeninfo finfo; 17263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) 17363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -errno; 17463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 17563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian struct fb_var_screeninfo info; 17663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) 17763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -errno; 17863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 17963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.reserved[0] = 0; 18063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.reserved[1] = 0; 18163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.reserved[2] = 0; 18263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.xoffset = 0; 18363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.yoffset = 0; 18463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.activate = FB_ACTIVATE_NOW; 18563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 18663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian /* 18763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * Explicitly request 5/6/5 18863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian */ 18963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.bits_per_pixel = 16; 19063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.red.offset = 11; 19163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.red.length = 5; 19263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.green.offset = 5; 19363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.green.length = 6; 19463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.blue.offset = 0; 19563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.blue.length = 5; 19663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.transp.offset = 0; 19763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.transp.length = 0; 19863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 19963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian /* 20063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * Request NUM_BUFFERS screens (at lest 2 for page flipping) 20163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian */ 20263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.yres_virtual = info.yres * NUM_BUFFERS; 20363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 20463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 20563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian uint32_t flags = PAGE_FLIP; 20663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) { 20763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.yres_virtual = info.yres; 20863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian flags &= ~PAGE_FLIP; 20963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian LOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported"); 21063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 21163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 21263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (info.yres_virtual < info.yres * 2) { 21363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian // we need at least 2 for page-flipping 21463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.yres_virtual = info.yres; 21563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian flags &= ~PAGE_FLIP; 21663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian LOGW("page flipping not supported (yres_virtual=%d, requested=%d)", 21763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.yres_virtual, info.yres*2); 21863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 21963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 22063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) 22163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -errno; 22263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 22363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int refreshRate = 1000000000000000LLU / 22463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian ( 22563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian uint64_t( info.upper_margin + info.lower_margin + info.yres ) 22663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * ( info.left_margin + info.right_margin + info.xres ) 22763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * info.pixclock 22863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian ); 22963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 23063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (refreshRate == 0) { 23163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian // bleagh, bad info from the driver 23263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian refreshRate = 60*1000; // 60 Hz 23363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 23463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 23563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (int(info.width) <= 0 || int(info.height) <= 0) { 23663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian // the driver doesn't return that information 23763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian // default to 160 dpi 23863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.width = ((info.xres * 25.4f)/160.0f + 0.5f); 23963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.height = ((info.yres * 25.4f)/160.0f + 0.5f); 24063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 24163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 24263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian float xdpi = (info.xres * 25.4f) / info.width; 24363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian float ydpi = (info.yres * 25.4f) / info.height; 24463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian float fps = refreshRate / 1000.0f; 24563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 24663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian LOGI( "using (fd=%d)\n" 24763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "id = %s\n" 24863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "xres = %d px\n" 24963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "yres = %d px\n" 25063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "xres_virtual = %d px\n" 25163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "yres_virtual = %d px\n" 25263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "bpp = %d\n" 25363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "r = %2u:%u\n" 25463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "g = %2u:%u\n" 25563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "b = %2u:%u\n", 25663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian fd, 25763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian finfo.id, 25863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.xres, 25963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.yres, 26063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.xres_virtual, 26163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.yres_virtual, 26263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.bits_per_pixel, 26363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.red.offset, info.red.length, 26463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.green.offset, info.green.length, 26563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.blue.offset, info.blue.length 26663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian ); 26763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 26863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian LOGI( "width = %d mm (%f dpi)\n" 26963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "height = %d mm (%f dpi)\n" 27063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "refresh rate = %.2f Hz\n", 27163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.width, xdpi, 27263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.height, ydpi, 27363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian fps 27463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian ); 27563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 27663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 27763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) 27863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -errno; 27963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 28063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (finfo.smem_len <= 0) 28163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -errno; 28263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 28363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 28463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->flags = flags; 28563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->info = info; 28663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->finfo = finfo; 28763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->xdpi = xdpi; 28863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->ydpi = ydpi; 28963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->fps = fps; 29063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 29163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian /* 29263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * map the framebuffer 29363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian */ 29463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 29563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int err; 29663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian size_t fbSize = roundUpToPageSize(finfo.line_length * info.yres_virtual); 29763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->framebuffer = new private_handle_t(dup(fd), fbSize, 29863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian private_handle_t::PRIV_FLAGS_USES_PMEM); 29963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 30063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->numBuffers = info.yres_virtual / info.yres; 30163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->bufferMask = 0; 30263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 30363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 30463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (vaddr == MAP_FAILED) { 30563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian LOGE("Error mapping the framebuffer (%s)", strerror(errno)); 30663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -errno; 30763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 30863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->framebuffer->base = intptr_t(vaddr); 30963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian memset(vaddr, 0, fbSize); 31063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return 0; 31163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian} 31263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 31363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianstatic int mapFrameBuffer(struct private_module_t* module) 31463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian{ 31563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian pthread_mutex_lock(&module->lock); 31663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int err = mapFrameBufferLocked(module); 31763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian pthread_mutex_unlock(&module->lock); 31863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return err; 31963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian} 32063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 32163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian/*****************************************************************************/ 32263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 32363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianstatic int fb_close(struct hw_device_t *dev) 32463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian{ 32563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian fb_context_t* ctx = (fb_context_t*)dev; 32663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (ctx) { 32763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian free(ctx); 32863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 32963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return 0; 33063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian} 33163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 33263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianint fb_device_open(hw_module_t const* module, const char* name, 33363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian hw_device_t** device) 33463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian{ 33563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int status = -EINVAL; 33663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (!strcmp(name, GRALLOC_HARDWARE_FB0)) { 33763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 33863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian alloc_device_t* gralloc_device; 33963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian status = gralloc_open(module, &gralloc_device); 34063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (status < 0) 34163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return status; 34263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 34363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian /* initialize our state here */ 34463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev)); 34563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian memset(dev, 0, sizeof(*dev)); 34663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 34763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian /* initialize the procs */ 34863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->device.common.tag = HARDWARE_DEVICE_TAG; 34963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->device.common.version = 0; 35063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->device.common.module = const_cast<hw_module_t*>(module); 35163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->device.common.close = fb_close; 35263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->device.setSwapInterval = fb_setSwapInterval; 35363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->device.post = fb_post; 35463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->device.setUpdateRect = 0; 35563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 35663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian private_module_t* m = (private_module_t*)module; 35763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian status = mapFrameBuffer(m); 35863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (status >= 0) { 35963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3); 36063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<uint32_t&>(dev->device.flags) = 0; 36163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<uint32_t&>(dev->device.width) = m->info.xres; 36263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<uint32_t&>(dev->device.height) = m->info.yres; 36363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<int&>(dev->device.stride) = stride; 36463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<int&>(dev->device.format) = HAL_PIXEL_FORMAT_RGB_565; 36563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<float&>(dev->device.xdpi) = m->xdpi; 36663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<float&>(dev->device.ydpi) = m->ydpi; 36763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<float&>(dev->device.fps) = m->fps; 36863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<int&>(dev->device.minSwapInterval) = 1; 36963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<int&>(dev->device.maxSwapInterval) = 1; 37063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 37163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#if SUPPORTS_UPDATE_ON_DEMAND 37263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (m->finfo.reserved[0] == 0x5444 && 37363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->finfo.reserved[1] == 0x5055) { 37463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->device.setUpdateRect = fb_setUpdateRect; 37563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian LOGD("UPDATE_ON_DEMAND supported"); 37663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 37763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#endif 37863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 37963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian *device = &dev->device.common; 38063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 38163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 38263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return status; 38363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian} 384