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#include <linux/fb.h> 37878081087a3175f08d89452ac5af23609183e883Mathias Agopian#include <linux/msm_mdp.h> 3863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 3963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#include "gralloc_priv.h" 40f882f8e29b6dca40cf93da467120e31b97e27d91Mathias Agopian#include "gr.h" 4163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 4263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian/*****************************************************************************/ 4363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 4463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian// numbers of buffers for page flipping 4563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian#define NUM_BUFFERS 2 4663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 4763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 4863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianenum { 4963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian PAGE_FLIP = 0x00000001, 5063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian LOCKED = 0x00000002 5163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian}; 5263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 5363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianstruct fb_context_t { 5463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian framebuffer_device_t device; 5563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian}; 5663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 5763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian/*****************************************************************************/ 5863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 59878081087a3175f08d89452ac5af23609183e883Mathias Agopianstatic void 60878081087a3175f08d89452ac5af23609183e883Mathias Agopianmsm_copy_buffer(buffer_handle_t handle, int fd, int width, int height, 61878081087a3175f08d89452ac5af23609183e883Mathias Agopian int x, int y, int w, int h); 62878081087a3175f08d89452ac5af23609183e883Mathias Agopian 6363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianstatic int fb_setSwapInterval(struct framebuffer_device_t* dev, 6463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int interval) 6563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian{ 6663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian fb_context_t* ctx = (fb_context_t*)dev; 6763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (interval < dev->minSwapInterval || interval > dev->maxSwapInterval) 6863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -EINVAL; 6963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian // FIXME: implement fb_setSwapInterval 7063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return 0; 7163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian} 7263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 7363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianstatic int fb_setUpdateRect(struct framebuffer_device_t* dev, 7463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int l, int t, int w, int h) 7563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian{ 7663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (((w|h) <= 0) || ((l|t)<0)) 7763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -EINVAL; 7863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 7963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian fb_context_t* ctx = (fb_context_t*)dev; 8063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian private_module_t* m = reinterpret_cast<private_module_t*>( 8163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->common.module); 8263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->info.reserved[0] = 0x54445055; // "UPDT"; 8363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->info.reserved[1] = (uint16_t)l | ((uint32_t)t << 16); 8463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->info.reserved[2] = (uint16_t)(l+w) | ((uint32_t)(t+h) << 16); 8563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return 0; 8663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian} 8763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 8863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianstatic int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer) 8963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian{ 9063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (private_handle_t::validate(buffer) < 0) 9163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -EINVAL; 9263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 9363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian fb_context_t* ctx = (fb_context_t*)dev; 9463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 9563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(buffer); 9663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian private_module_t* m = reinterpret_cast<private_module_t*>( 9763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->common.module); 9863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 9963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) { 10063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const size_t offset = hnd->base - m->framebuffer->base; 10163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->info.activate = FB_ACTIVATE_VBL; 10263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->info.yoffset = offset / m->finfo.line_length; 10363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) { 104c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("FBIOPUT_VSCREENINFO failed"); 10563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->base.unlock(&m->base, buffer); 10663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -errno; 10763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 10863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->currentBuffer = buffer; 10963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 11063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } else { 11163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian // If we can't do the page_flip, just copy the buffer to the front 11263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian // FIXME: use copybit HAL instead of memcpy 11363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 11463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian void* fb_vaddr; 11563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian void* buffer_vaddr; 11663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 11763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->base.lock(&m->base, m->framebuffer, 11863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian GRALLOC_USAGE_SW_WRITE_RARELY, 11963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 0, 0, m->info.xres, m->info.yres, 12063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian &fb_vaddr); 12163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 12263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->base.lock(&m->base, buffer, 12363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian GRALLOC_USAGE_SW_READ_RARELY, 12463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 0, 0, m->info.xres, m->info.yres, 12563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian &buffer_vaddr); 12663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 127878081087a3175f08d89452ac5af23609183e883Mathias Agopian //memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres); 128878081087a3175f08d89452ac5af23609183e883Mathias Agopian 129878081087a3175f08d89452ac5af23609183e883Mathias Agopian msm_copy_buffer(m->framebuffer, m->framebuffer->fd, 130878081087a3175f08d89452ac5af23609183e883Mathias Agopian m->info.xres, m->info.yres, 131878081087a3175f08d89452ac5af23609183e883Mathias Agopian m->info.xoffset, m->info.yoffset, 132878081087a3175f08d89452ac5af23609183e883Mathias Agopian m->info.width, m->info.height); 13363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 13463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->base.unlock(&m->base, buffer); 13563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian m->base.unlock(&m->base, m->framebuffer); 13663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 13763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 13863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return 0; 13963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian} 14063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 14163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian/*****************************************************************************/ 14263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 14363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianint mapFrameBufferLocked(struct private_module_t* module) 14463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian{ 14563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian // already initialized... 14663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (module->framebuffer) { 14763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return 0; 14863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 14963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 15063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian char const * const device_template[] = { 15163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "/dev/graphics/fb%u", 15263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "/dev/fb%u", 15363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 0 }; 15463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 15563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int fd = -1; 15663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int i=0; 15763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian char name[64]; 15863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 15963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian while ((fd==-1) && device_template[i]) { 16063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian snprintf(name, 64, device_template[i], 0); 16163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian fd = open(name, O_RDWR, 0); 16263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian i++; 16363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 16463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (fd < 0) 16563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -errno; 16663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 16763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian struct fb_fix_screeninfo finfo; 16863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) 16963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -errno; 17063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 17163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian struct fb_var_screeninfo info; 17263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) 17363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -errno; 17463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 17563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.reserved[0] = 0; 17663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.reserved[1] = 0; 17763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.reserved[2] = 0; 17863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.xoffset = 0; 17963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.yoffset = 0; 18063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.activate = FB_ACTIVATE_NOW; 18163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 18263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian /* 18363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * Explicitly request 5/6/5 18463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian */ 18563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.bits_per_pixel = 16; 18663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.red.offset = 11; 18763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.red.length = 5; 18863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.green.offset = 5; 18963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.green.length = 6; 19063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.blue.offset = 0; 19163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.blue.length = 5; 19263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.transp.offset = 0; 19363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.transp.length = 0; 19463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 19563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian /* 19663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * Request NUM_BUFFERS screens (at lest 2 for page flipping) 19763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian */ 19863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.yres_virtual = info.yres * NUM_BUFFERS; 19963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 20063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 20163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian uint32_t flags = PAGE_FLIP; 20263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) { 20363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.yres_virtual = info.yres; 20463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian flags &= ~PAGE_FLIP; 2053fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported"); 20663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 20763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 20863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (info.yres_virtual < info.yres * 2) { 20963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian // we need at least 2 for page-flipping 21063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.yres_virtual = info.yres; 21163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian flags &= ~PAGE_FLIP; 2123fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("page flipping not supported (yres_virtual=%d, requested=%d)", 21363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.yres_virtual, info.yres*2); 21463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 21563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 21663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) 21763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -errno; 21863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 21963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int refreshRate = 1000000000000000LLU / 22063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian ( 22163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian uint64_t( info.upper_margin + info.lower_margin + info.yres ) 22263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * ( info.left_margin + info.right_margin + info.xres ) 22363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * info.pixclock 22463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian ); 22563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 22663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (refreshRate == 0) { 22763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian // bleagh, bad info from the driver 22863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian refreshRate = 60*1000; // 60 Hz 22963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 23063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 23163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (int(info.width) <= 0 || int(info.height) <= 0) { 23263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian // the driver doesn't return that information 23363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian // default to 160 dpi 23463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.width = ((info.xres * 25.4f)/160.0f + 0.5f); 23563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.height = ((info.yres * 25.4f)/160.0f + 0.5f); 23663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 23763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 23863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian float xdpi = (info.xres * 25.4f) / info.width; 23963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian float ydpi = (info.yres * 25.4f) / info.height; 24063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian float fps = refreshRate / 1000.0f; 24163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 2425a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI( "using (fd=%d)\n" 24363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "id = %s\n" 24463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "xres = %d px\n" 24563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "yres = %d px\n" 24663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "xres_virtual = %d px\n" 24763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "yres_virtual = %d px\n" 24863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "bpp = %d\n" 24963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "r = %2u:%u\n" 25063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "g = %2u:%u\n" 25163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "b = %2u:%u\n", 25263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian fd, 25363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian finfo.id, 25463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.xres, 25563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.yres, 25663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.xres_virtual, 25763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.yres_virtual, 25863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.bits_per_pixel, 25963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.red.offset, info.red.length, 26063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.green.offset, info.green.length, 26163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.blue.offset, info.blue.length 26263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian ); 26363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 2645a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI( "width = %d mm (%f dpi)\n" 26563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "height = %d mm (%f dpi)\n" 26663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian "refresh rate = %.2f Hz\n", 26763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.width, xdpi, 26863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian info.height, ydpi, 26963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian fps 27063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian ); 27163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 27263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 27363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) 27463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -errno; 27563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 27663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (finfo.smem_len <= 0) 27763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -errno; 27863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 27963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 28063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->flags = flags; 28163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->info = info; 28263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->finfo = finfo; 28363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->xdpi = xdpi; 28463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->ydpi = ydpi; 28563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->fps = fps; 28663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 28763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian /* 28863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian * map the framebuffer 28963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian */ 29063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 29163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int err; 29263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian size_t fbSize = roundUpToPageSize(finfo.line_length * info.yres_virtual); 29363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->framebuffer = new private_handle_t(dup(fd), fbSize, 29463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian private_handle_t::PRIV_FLAGS_USES_PMEM); 29563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 29663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->numBuffers = info.yres_virtual / info.yres; 29763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->bufferMask = 0; 29863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 29963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 30063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (vaddr == MAP_FAILED) { 301c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Error mapping the framebuffer (%s)", strerror(errno)); 30263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return -errno; 30363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 30463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian module->framebuffer->base = intptr_t(vaddr); 305878081087a3175f08d89452ac5af23609183e883Mathias Agopian 30663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian memset(vaddr, 0, fbSize); 30763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return 0; 30863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian} 30963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 31063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianstatic int mapFrameBuffer(struct private_module_t* module) 31163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian{ 31263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian pthread_mutex_lock(&module->lock); 31363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int err = mapFrameBufferLocked(module); 31463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian pthread_mutex_unlock(&module->lock); 31563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return err; 31663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian} 31763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 31863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian/*****************************************************************************/ 31963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 32063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianstatic int fb_close(struct hw_device_t *dev) 32163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian{ 32263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian fb_context_t* ctx = (fb_context_t*)dev; 32363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (ctx) { 32463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian free(ctx); 32563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 32663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return 0; 32763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian} 32863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 32963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopianint fb_device_open(hw_module_t const* module, const char* name, 33063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian hw_device_t** device) 33163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian{ 33263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int status = -EINVAL; 33363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (!strcmp(name, GRALLOC_HARDWARE_FB0)) { 33463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian alloc_device_t* gralloc_device; 33563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian status = gralloc_open(module, &gralloc_device); 33663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (status < 0) 33763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return status; 33863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 33963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian /* initialize our state here */ 34063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev)); 34163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian memset(dev, 0, sizeof(*dev)); 34263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 34363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian /* initialize the procs */ 34463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->device.common.tag = HARDWARE_DEVICE_TAG; 34563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->device.common.version = 0; 34663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->device.common.module = const_cast<hw_module_t*>(module); 34763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->device.common.close = fb_close; 34863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->device.setSwapInterval = fb_setSwapInterval; 34963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->device.post = fb_post; 35063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian dev->device.setUpdateRect = 0; 35163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian 35263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian private_module_t* m = (private_module_t*)module; 35363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian status = mapFrameBuffer(m); 35463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian if (status >= 0) { 35563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3); 35663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<uint32_t&>(dev->device.flags) = 0; 35763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<uint32_t&>(dev->device.width) = m->info.xres; 35863b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<uint32_t&>(dev->device.height) = m->info.yres; 35963b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<int&>(dev->device.stride) = stride; 36063b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<int&>(dev->device.format) = HAL_PIXEL_FORMAT_RGB_565; 36163b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<float&>(dev->device.xdpi) = m->xdpi; 36263b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<float&>(dev->device.ydpi) = m->ydpi; 36363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<float&>(dev->device.fps) = m->fps; 36463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<int&>(dev->device.minSwapInterval) = 1; 36563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian const_cast<int&>(dev->device.maxSwapInterval) = 1; 366ad641e7dda01a1fc787ee55e868344dce2c26fdbMathias Agopian 367ad641e7dda01a1fc787ee55e868344dce2c26fdbMathias Agopian if (m->finfo.reserved[0] == 0x5444 && 368ad641e7dda01a1fc787ee55e868344dce2c26fdbMathias Agopian m->finfo.reserved[1] == 0x5055) { 369ad641e7dda01a1fc787ee55e868344dce2c26fdbMathias Agopian dev->device.setUpdateRect = fb_setUpdateRect; 370f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("UPDATE_ON_DEMAND supported"); 371ad641e7dda01a1fc787ee55e868344dce2c26fdbMathias Agopian } 372ad641e7dda01a1fc787ee55e868344dce2c26fdbMathias Agopian 37363b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian *device = &dev->device.common; 37463b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 37563b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian } 37663b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian return status; 37763b00f9573354b80cf6483139766b478bfe2e995Mathias Agopian} 378878081087a3175f08d89452ac5af23609183e883Mathias Agopian 379878081087a3175f08d89452ac5af23609183e883Mathias Agopian/* Copy a pmem buffer to the framebuffer */ 380878081087a3175f08d89452ac5af23609183e883Mathias Agopian 381878081087a3175f08d89452ac5af23609183e883Mathias Agopianstatic void 382878081087a3175f08d89452ac5af23609183e883Mathias Agopianmsm_copy_buffer(buffer_handle_t handle, int fd, int width, int height, 383878081087a3175f08d89452ac5af23609183e883Mathias Agopian int x, int y, int w, int h) 384878081087a3175f08d89452ac5af23609183e883Mathias Agopian{ 385878081087a3175f08d89452ac5af23609183e883Mathias Agopian struct { 386878081087a3175f08d89452ac5af23609183e883Mathias Agopian unsigned int count; 387878081087a3175f08d89452ac5af23609183e883Mathias Agopian mdp_blit_req req; 388878081087a3175f08d89452ac5af23609183e883Mathias Agopian } blit; 389878081087a3175f08d89452ac5af23609183e883Mathias Agopian private_handle_t *priv = (private_handle_t*) handle; 390878081087a3175f08d89452ac5af23609183e883Mathias Agopian 391878081087a3175f08d89452ac5af23609183e883Mathias Agopian memset(&blit, 0, sizeof(blit)); 392878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.count = 1; 393878081087a3175f08d89452ac5af23609183e883Mathias Agopian 394878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.req.flags = 0; 395878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.req.alpha = 0xff; 396878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.req.transp_mask = 0xffffffff; 397878081087a3175f08d89452ac5af23609183e883Mathias Agopian 398878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.req.src.width = width; 399878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.req.src.height = height; 400878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.req.src.offset = 0; 401878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.req.src.memory_id = priv->fd; 402878081087a3175f08d89452ac5af23609183e883Mathias Agopian 403878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.req.dst.width = width; 404878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.req.dst.height = height; 405878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.req.dst.offset = 0; 406878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.req.dst.memory_id = fd; 407878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.req.dst.format = MDP_RGB_565; 408878081087a3175f08d89452ac5af23609183e883Mathias Agopian 409878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.req.src_rect.x = blit.req.dst_rect.x = x; 410878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.req.src_rect.y = blit.req.dst_rect.y = y; 411878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.req.src_rect.w = blit.req.dst_rect.w = w; 412878081087a3175f08d89452ac5af23609183e883Mathias Agopian blit.req.src_rect.h = blit.req.dst_rect.h = h; 413878081087a3175f08d89452ac5af23609183e883Mathias Agopian 414878081087a3175f08d89452ac5af23609183e883Mathias Agopian if (ioctl(fd, MSMFB_BLIT, &blit)) 415c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("MSMFB_BLIT failed = %d", -errno); 416878081087a3175f08d89452ac5af23609183e883Mathias Agopian} 417