Home | History | Annotate | Download | only in framebuffer
      1 /*
      2  * Copyright (C) 2007 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <stdlib.h>
     18 #include <unistd.h>
     19 #include <fcntl.h>
     20 #include <stdio.h>
     21 #include <sys/ioctl.h>
     22 #include <sys/mman.h>
     23 #include <sys/stat.h>
     24 #include <sys/types.h>
     25 
     26 #include <linux/fb.h>
     27 #include <linux/msm_mdp.h>
     28 
     29 static struct fb_var_screeninfo vi;
     30 
     31 static int open_file(char *name, int *fd, int *len, int *fmt)
     32 {
     33     struct stat stat;
     34     char *type, *fn;
     35 
     36     type = name;
     37     fn = strchr(name, ':');
     38     if (!fn)
     39         return -1;
     40     *(fn++) = '\0';
     41 
     42     if (!strncmp(type, "yuv420", 6))
     43         *fmt = MDP_Y_CBCR_H2V2;
     44     else if (!strncmp(type, "rgb565", 6))
     45         *fmt = MDP_RGB_565;
     46     else {
     47         fprintf(stderr, "Unsupported image type: %s\n", type);
     48         return -1;
     49     }
     50 
     51     *fd = open(fn, O_RDONLY);
     52     if (*fd < 0) {
     53         perror("cannot open file");
     54         return -1;
     55     }
     56 
     57     if (fstat(*fd, &stat) < 0) {
     58         perror("cannot fstat file");
     59         goto err;
     60     }
     61 
     62     *len = stat.st_size;
     63 
     64     printf("Successfully opened file %s (fmt=%d len=%d fd=%d)\n", fn, *fmt,
     65            *len, *fd);
     66     return 0;
     67 
     68 err:
     69     close(*fd);
     70     return -1;
     71 }
     72 
     73 static int get_pmem(int *fd, void **data, int sz)
     74 {
     75     *fd = open("/dev/pmem", O_RDWR | O_NONBLOCK | O_SYNC);
     76     if (*fd < 0) {
     77         perror("cannot open /dev/pmem");
     78         return -1;
     79     }
     80 
     81     sz = (sz + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
     82     *data = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
     83     if (*data == MAP_FAILED) {
     84         perror("pmem mmap");
     85         goto err_pmem_mmap;
     86     }
     87 
     88     return 0;
     89 
     90 err_pmem_mmap:
     91    close(*fd);
     92    return -1;
     93 }
     94 
     95 static int get_framebuffer(int *fd, char **fb, int *width, int *height)
     96 {
     97     struct fb_fix_screeninfo fi;
     98     void *bits;
     99 
    100     *fd = open("/dev/graphics/fb0", O_RDWR);
    101     if(*fd < 0) {
    102         perror("cannot open fb0");
    103         return -1;
    104     }
    105 
    106     if(ioctl(*fd, FBIOGET_FSCREENINFO, &fi) < 0) {
    107         perror("failed to get fb0 info");
    108         return -1;
    109     }
    110 
    111     if(ioctl(*fd, FBIOGET_VSCREENINFO, &vi) < 0) {
    112         perror("failed to get fb0 info");
    113         return -1;
    114     }
    115 
    116     bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
    117     if(bits == MAP_FAILED) {
    118         perror("failed to mmap framebuffer");
    119         return -1;
    120     }
    121 
    122     *width = vi.xres;
    123     *height = vi.yres;
    124     *fb = bits;
    125     return 0;
    126 }
    127 
    128 static void set_active_framebuffer(int fd, unsigned n)
    129 {
    130 
    131     if(n > 1) return;
    132     vi.yres_virtual = vi.yres * 2;
    133     vi.yoffset = n * vi.yres;
    134     if(ioctl(fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
    135         fprintf(stderr,"active fb swap failed!\n");
    136     }
    137 }
    138 
    139 /* geometry: WxH+X+Y */
    140 int parse_geometry(char *geom, int *w, int *h, int *x, int *y)
    141 {
    142     char *ptr;
    143 
    144     *w = *h = 0;
    145 
    146     if (!(ptr = strchr(geom, 'x')))
    147         return -1;
    148     *ptr = '\0';
    149     *w = atoi(geom);
    150     geom = ptr + 1;
    151 
    152     ptr = strchr(geom, '+');
    153     if (ptr)
    154         *ptr = '\0';
    155     *h = atoi(geom);
    156     if (!ptr)
    157         return 0;
    158 
    159     geom = ptr + 1;
    160 
    161     if (!x || !y || !(ptr = strchr(geom, '+')))
    162         return -1;
    163     *ptr = '\0';
    164     *x = atoi(geom);
    165     geom = ptr + 1;
    166 
    167     *y = atoi(geom);
    168 
    169     return 0;
    170 }
    171 
    172 int main(int argc, const char *argv[])
    173 {
    174     int fb_fd, width, height;
    175     char* fb;
    176     struct mdp_blit_req_list *req_list;
    177     struct mdp_blit_req *req;
    178     int opt;
    179     int srcw = 0, srch = 0, dstw = 0, dsth = 0;
    180     int srcx = 0; int srcy = 0;
    181     int dstx = 10; int dsty = 10;
    182     int src_imgw = 0, src_imgh = 0, dst_imgw = 0, dst_imgh = 0;
    183     int from;
    184     int src_fmt;
    185     int dst_fmt = MDP_RGB_565;
    186     int src_fd = -1;
    187     void *src_data;
    188 
    189     req_list = malloc(sizeof(struct mdp_blit_req_list) +
    190                       sizeof(struct mdp_blit_req));
    191     req_list->count = 1;
    192     req = req_list->req;
    193 
    194 
    195     while ((opt = getopt(argc, argv, "s:d:f:t:u:v:")) != -1) {
    196         switch (opt) {
    197         case 's':
    198             if (parse_geometry(optarg, &srcw, &srch, &srcx, &srcy)) {
    199                 fprintf(stderr, "Can't parse source\n");
    200                 exit(-1);
    201             }
    202             printf("Got source: w=%d h=%d x=%d y=%d\n", srcw, srch, srcx, srcy);
    203             break;
    204 
    205         case 'd':
    206             if (parse_geometry(optarg, &dstw, &dsth, &dstx, &dsty)) {
    207                 fprintf(stderr, "Can't parse dest\n");
    208                 exit(-1);
    209             }
    210             printf("Got dest: w=%d h=%d x=%d y=%d\n", dstw, dsth, dstx, dsty);
    211             break;
    212 
    213         case 'u':
    214             if (parse_geometry(optarg, &src_imgw, &src_imgh, NULL, NULL)) {
    215                 fprintf(stderr, "Can't parse src image size\n");
    216                 exit(-1);
    217             }
    218             printf("Got src img sz: w=%d h=%d\n", src_imgw, src_imgh);
    219             break;
    220 
    221         case 'v':
    222             if (parse_geometry(optarg, &dst_imgw, &dst_imgh, NULL, NULL)) {
    223                 fprintf(stderr, "Can't parse dst image size\n");
    224                 exit(-1);
    225             }
    226             printf("Got dst img sz: w=%d h=%d\n", dst_imgw, dst_imgh);
    227             break;
    228 
    229         case 'f':
    230             {
    231                 int file_fd;
    232                 int file_len;
    233                 int bytes;
    234                 void *ptr;
    235                 if (open_file(optarg, &file_fd, &file_len, &src_fmt) < 0) {
    236                     fprintf(stderr, "Can't open source file\n");
    237                     exit(-1);
    238                 }
    239 
    240                 if (get_pmem(&src_fd, &src_data, file_len) < 0) {
    241                     close(file_fd);
    242                     exit(-1);
    243                 }
    244 
    245                 ptr = src_data;
    246                 while (file_len) {
    247                     bytes = read(file_fd, ptr, file_len);
    248                     if (bytes < 0) {
    249                         perror("Could not read data from file");
    250                         exit(-1);
    251                     }
    252                     file_len -= bytes;
    253                     ptr += bytes;
    254                 }
    255             }
    256             break;
    257 
    258         case 't':
    259             if (!strncmp(optarg, "yuv420", 6))
    260                 dst_fmt = MDP_Y_CBCR_H2V2;
    261 #if 0
    262             else if (!strncmp(optarg, "rgb565", 6))
    263                 dst_fmt = MDP_RGB_565;
    264 #endif
    265             break;
    266 
    267         default:
    268             fprintf(stderr, "Usage: %s -s source -d dest\n", argv[0]);
    269             exit(-1);
    270         }
    271     }
    272 
    273     if (get_framebuffer(&fb_fd, &fb, &width, &height)) {
    274         printf("couldnt' get fb\n");
    275         return -1;
    276     }
    277 
    278     set_active_framebuffer(fb_fd, 0);
    279 
    280     if (!src_imgw || !src_imgh) {
    281         src_imgw = width;
    282         src_imgh = height;
    283     }
    284 
    285     if (!dst_imgw || !dst_imgh) {
    286         dst_imgw = width;
    287         dst_imgh = height;
    288     }
    289 
    290     if (src_fd < 0) {
    291         src_fd = fb_fd;
    292         src_fmt = MDP_RGB_565;
    293     }
    294 
    295     req->src.width = src_imgw;
    296     req->src.height = src_imgh;
    297     req->src.format = src_fmt;
    298     req->src.offset = 0;
    299     req->src.memory_id = src_fd;
    300     req->src_rect.x = srcx;
    301     req->src_rect.y = srcy;
    302     req->src_rect.w = srcw;
    303     req->src_rect.h = srch;
    304 
    305     req->dst.width = dst_imgw;
    306     req->dst.height = dst_imgh;
    307     req->dst.format = dst_fmt;
    308     req->dst.offset = 0;
    309     req->dst.memory_id = fb_fd;
    310     req->dst_rect.x = dstx;
    311     req->dst_rect.y = dsty;
    312     req->dst_rect.w = dstw;
    313     req->dst_rect.h = dsth;
    314     req->alpha = MDP_ALPHA_NOP;
    315     req->transp_mask = MDP_TRANSP_NOP;
    316 //    req->flags = MDP_ROT_90;
    317     req->flags = MDP_ROT_NOP;
    318 
    319     if(ioctl(fb_fd, MSMFB_BLIT, req_list))
    320         fprintf(stderr, "crap, failed blit\n");
    321 
    322     printf("Done\n");
    323     return 0;
    324 }
    325