#ifndef __libdrmToDMD_H__
#define __libdrmToDMD_H__
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <time.h>
#include <unistd.h>
#include <png.h>
#include "xf86drm.h"
#include "xf86drmMode.h"
#define uint32_t unsigned int
struct framebuffer{
uint32_t size;
uint32_t handle;
uint32_t fb_id;
char *vaddr;
};
struct drmbuffer{
drmModeConnector *connector;
drmModeRes *resources;
png_structp png_ptr;
uint32_t conn_id;
uint32_t crtc_id;
struct framebuffer buf;
};
struct drmbuffer get_drm_info(int fd);
int read_png_framebuffer(char *fileName, struct framebuffer *png);
void release_fb(int fd, struct framebuffer *buf);
int libdrminit();
#endif
#include "libdrmToDMD.h"
int read_png_framebuffer(char *fileName, struct framebuffer *framebuf)
{
FILE* file = fopen(fileName, "rb");
if(file == NULL )
return -1;
png_bytepp row_pointers;
png_infop info_ptr;
png_structp png_ptr;
int width;
int height;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
info_ptr = png_create_info_struct(png_ptr);
if(png_ptr == NULL || info_ptr == NULL )
return -1;
if(setjmp(png_jmpbuf(png_ptr)))
return -1;
png_init_io(png_ptr, file);
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0);
width = png_get_image_width(png_ptr, info_ptr);
height = png_get_image_height(png_ptr, info_ptr);
row_pointers = png_get_rows(png_ptr, info_ptr);
int temp = (3 * width);
for(int i = 0; i < height; i++)
{
for(int j = 0; j < temp; j += 3)
{
framebuf->vaddr[i*temp+j+0] = row_pointers[i][j];
framebuf->vaddr[i*temp+j+1] = row_pointers[i][j+1];
framebuf->vaddr[i*temp+j+2] = row_pointers[i][j+2];
}
}
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(file);
return 0;
}
void release_fb(int fd, struct framebuffer *buf)
{
struct drm_mode_destroy_dumb destroy = {};
destroy.handle = buf->handle;
drmModeRmFB(fd, buf->fb_id);
munmap(buf->vaddr, buf->size);
drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy);
}
struct drmbuffer get_drm_info(int fd)
{
uint32_t fb_id;
struct drm_mode_create_dumb create = {};
struct drm_mode_map_dumb map = {};
struct drmbuffer drm= {};
drm.resources = drmModeGetResources(fd);
drm.crtc_id = drm.resources->crtcs[0];
drm.conn_id = drm.resources->connectors[0];
drm.connector = drmModeGetConnector(fd, drm.conn_id);
printf("hdisplay:%d vdisplay:%d\n",drm.connector->modes[0].hdisplay,drm.connector->modes[0].vdisplay);
create.width =drm.connector->modes[0].hdisplay;
create.height = drm.connector->modes[0].vdisplay;
create.bpp = 24;
drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);
drmModeAddFB(fd, create.width, create.height, 24, 24, create.pitch,create.handle, &fb_id);
map.handle = create.handle;
drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map);
drm.buf.vaddr = mmap(0, create.size, PROT_READ | PROT_WRITE,MAP_SHARED, fd, map.offset);
printf("size:%d width:%d height:%d pitch:%d handle:%d offset:%d\n",create.size, create.width,create.height,create.pitch,create.handle,map.offset);
drm.buf.handle=create.handle;
drm.buf.size=create.size;
drm.buf.fb_id=fb_id;
return drm;
}
int libdrminit()
{
int fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
struct drmbuffer drm= get_drm_info(fd);
printf("hdisplay:%d vdisplay:%d\n",drm.connector->modes[0].hdisplay,drm.connector->modes[0].vdisplay);
char PicPath4[100] = "/home/linaro/build-T2D3-QTforARM-Debug/bmp_3840";
char PicPath5[100] ;
for (int i = 2;i<10;i++)
{
char s[10]="/slice";
char d[10]=".PNG";
char temp1[10];
sprintf(temp1,"%d",i);
memset(PicPath5,0,100);
strcpy(PicPath5,PicPath4);
strcat(s,temp1);
strcat(s,d);
strcat(PicPath5,s);
printf("<<< PicPath5:%s\n",PicPath5);
read_png_framebuffer(PicPath5,&drm.buf);
printf("<<%d\n",i);
drmModeSetCrtc(fd, drm.crtc_id, drm.buf.fb_id,0, 0, &drm.conn_id, 1, &drm.connector->modes[0]);
sleep(5);
}
release_fb(fd, & drm.buf);
drmModeFreeConnector(drm.connector);
drmModeFreeResources(drm.resources);
close(fd);
return 0;
}