mdp_test.c revision 0ac334cf3b71724451641a44553252a44a43b1f8
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
29static struct fb_var_screeninfo vi;
30
31static 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
68err:
69    close(*fd);
70    return -1;
71}
72
73static 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
90err_pmem_mmap:
91   close(*fd);
92   return -1;
93}
94
95static 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
128static 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 */
140int 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
172int 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