• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
open_file(char * name,int * fd,int * len,int * fmt)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 
get_pmem(int * fd,void ** data,int sz)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 
get_framebuffer(int * fd,char ** fb,int * width,int * height)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 
set_active_framebuffer(int fd,unsigned n)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 */
parse_geometry(char * geom,int * w,int * h,int * x,int * 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 
main(int argc,const char * argv[])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