Android P图形架构之FrameBuffer测试Demo

本文详细介绍了一个在Android系统中进行FrameBuffer测试的例子,通过直接操作FrameBuffer设备,绕过SurfaceFlinger,实现图像的直接绘制。代码示例展示了如何打开、读取和写入FrameBuffer,以及如何使用mmap映射设备内存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android FrameBuffer测试记录。

SurfaceFlinger是一个服务,主要是负责合成各窗口的Surface,然后通过OpenGLES显示到FrameBuffer上。

参考资料:
https://android.googlesource.com/platform/system/extras/+/donut-release/tests/framebuffer/fb_test.c

源码:
framebuffer_test.c

#include <unistd.h>  
#include <stdio.h>  
#include <fcntl.h>  
#include <linux/fb.h>  
#include <sys/mman.h>  
#include <stdlib.h>
#include "yellow_face.zif"
int main()  
{  
    int fbfd = 0;  
    struct fb_var_screeninfo vinfo;  
    struct fb_fix_screeninfo finfo;  
    //struct fb_cmap cmapinfo;  
    long int screensize = 0;  
    char *fbp = 0;  
    int x = 0, y = 0;  
    //long int location = 0;  
    //int b,g,r;  
    // Open the file for reading and writing  
    fbfd = open("/dev/graphics/fb0", O_RDWR,0); // 打开Frame Buffer设备  
    if (fbfd < 0) {  
        printf("Error: cannot open framebuffer device.%x\n",fbfd);  
        exit(1);  
    }  
    printf("The framebuffer device was opened successfully.\n"); 
    // Get fixed screen information  
    if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) { // 获取设备固有信息  
        printf("Error reading fixed information.\n");  
        exit(2);  
    }  
    printf("\ntype:0x%x\n", finfo.type ); // FrameBuffer 类型,如0为象素  
    printf("visual:%d\n", finfo.visual ); // 视觉类型:如真彩2,伪彩3   
    printf("line_length:%d\n", finfo.line_length ); // 每行长度  
    printf("\nsmem_start:0x%lx,smem_len:%u\n", finfo.smem_start, finfo.smem_len ); // 映象RAM的参数  
    printf("mmio_start:0x%lx ,mmio_len:%u\n", finfo.mmio_start, finfo.mmio_len );  
      
    // Get variable screen information  
    if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) { // 获取设备可变信息  
        printf("Error reading variable information.\n");  
        exit(3);  
    }  
    printf("%dx%d, %dbpp,xres_virtual=%d,yres_virtual=%dvinfo.xoffset=%d,vinfo.yoffset=%d\n", 
    vinfo.xres, vinfo.yres, vinfo.bits_per_pixel,
    vinfo.xres_virtual,vinfo.yres_virtual,vinfo.xoffset,vinfo.yoffset);  

	screensize = finfo.line_length * vinfo.yres_virtual;
    // Map the device to memory 通过mmap系统调用将framebuffer内存映射到用户空间,并返回映射后的起始地址  
    fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,fbfd, 0);  
    if ((int)fbp == -1) {  
        printf("Error: failed to map framebuffer device to memory.\n");  
        exit(4);  
    }  
    printf("The framebuffer device was mapped to memory successfully.\n");  

    /*****************exampel********************/		
 	unsigned char *pTemp = (unsigned char *)fbp;
	int i, j;
	//起始坐标(x,y),终点坐标(right,bottom)
	x = 0;
	y = 0;
	int right = 480;//vinfo.xres;
	int bottom = 1708;//vinfo.yres;
	//计算偏移量.例如在(x,y)位置写入颜色 pixel值.
	//offset = (x + y * screen_width) * 4; // (4个字节) 
	for(i=y; i< bottom; i++)
	{
		for(j=x; j<right; j++)
		{
			unsigned short data = yellow_face_data[(((i-y)  % 128) * 128) + ((j-x) %128)];
			// *((uint32_t *)(fbp + offset)) = pixel;
			pTemp[i*finfo.line_length + (j*4) + 2] = (unsigned char)((data & 0xF800) >> 11 << 3);
			pTemp[i*finfo.line_length + (j*4) + 1] = (unsigned char)((data & 0x7E0) >> 5 << 2);
			pTemp[i*finfo.line_length + (j*4) + 0] = (unsigned char)((data & 0x1F) << 3);
		}
	} 
    /*****************FBIOPAN_DISPLAY********************/	
    //note:vinfo.xoffset =0 vinfo.yoffset =0 否则FBIOPAN_DISPLAY不成功
	if (ioctl(fbfd, FBIOPAN_DISPLAY, &vinfo)) {    
        printf("Error FBIOPAN_DISPLAY information.\n");  
        exit(5);  
    }  
	sleep(10);
	//finfo.smem_len == screensize == finfo.line_length * vinfo.yres_virtual 
	munmap(fbp,finfo.smem_len);
    close(fbfd);  
    return 0;  
}

mk编译文件源码:
Android.mk

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng
LOCAL_SRC_FILES:=framebuffer_test.c
LOCAL_MODULE:=framebuffer_test
LOCAL_CPPFLAGS += -DANDROID
LOCAL_SHARED_LIBRARIES:=libc
LOCAL_C_INCLUDES += $(LOCAL_PATH) $(LOCAL_PATH)/$(KERNEL_DIR)/include
include $(BUILD_EXECUTABLE)

1、mm编译system\bin目录下生成framebuffer_test文件
2、拷贝到机器system/bin目录下
3、执行:stop surfaceflinger,关闭surfaceflinger
4、执行:./framebuffer_test,运行framebuffer_test程序
5、显示图像,执行成功。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunxiaolin2016

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值