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