source: titan/titan/fb.h @ 26471

Last change on this file since 26471 was 26471, checked in by obi, 9 years ago

mipsel optimize framebuffer and enable double buffering

File size: 11.0 KB
Line 
1#ifndef FB_H
2#define FB_H
3
4struct fb* getfb(char *name)
5{
6        struct fb *node = fb;
7
8        while(node != NULL)
9        {
10                if(ostrstr(node->name, name) != NULL)
11                        return node;
12
13                node = node->next;
14        }
15        debug(100, "framebuffer not found (%s)", name);
16        return NULL;
17}
18
19long getfbsize(int dev)
20{
21        struct fb* node = fb;
22        unsigned long fbmemcount = 0;
23        struct fb_fix_screeninfo fix_screeninfo;
24
25        if(fb == NULL)
26        {
27                err("NULL dedect");
28                return 0;
29        }
30
31#ifndef NOFB
32        if(ioctl(fb->fd, FBIOGET_FSCREENINFO, &fix_screeninfo) == -1)
33        {
34                perr("ioctl FBIOGET_FSCREENINFO failed");
35                return 0;
36        }
37#else
38        fix_screeninfo.smem_len = 16*1024*1024;
39#endif
40
41        while(node != NULL)
42        {
43                if(node->dev == dev)
44                        fbmemcount = fbmemcount + node->varfbsize;
45                node = node->next;
46        }
47       
48        return fix_screeninfo.smem_len - fbmemcount;
49}
50
51struct fb* addfb(char *fbname, int dev, int width, int height, int colbytes, int fd, unsigned char* mmapfb, unsigned long fixfbsize)
52{
53        struct fb *newnode = NULL, *node = fb;
54        char *name = NULL;
55        long ret = 0;
56
57        name = ostrcat(fbname, NULL, 0, 0);
58        if(name == NULL)
59        {
60                err("no memory");
61                return NULL;
62        }
63
64        newnode = (struct fb*)malloc(sizeof(struct fb));       
65        if(newnode == NULL)
66        {
67                err("no memory");
68                free(name);
69                return NULL;
70        }
71
72        memset(newnode, 0, sizeof(struct fb));
73        newnode->name = name;
74        newnode->dev = dev;
75        newnode->width = width;
76        newnode->height = height;
77        newnode->colbytes = colbytes;
78        newnode->pitch = newnode->width * newnode->colbytes;
79        newnode->fb = mmapfb;
80        newnode->fblong = (unsigned long*)newnode->fb;
81        newnode->fd = fd;
82        newnode->fixfbsize = fixfbsize;
83       
84        if(ostrcmp(name, FB) == 0)
85                setfbvarsize(newnode);
86        else if(ostrcmp(name, FB1) == 0)
87                newnode->varfbsize = 720 * 576 * newnode->colbytes;
88        else
89                newnode->varfbsize = width * height * newnode->colbytes;
90       
91        if(node != NULL)
92        {
93                while(node->next != NULL)
94                        node = node->next;
95                node->next = newnode;
96        }
97        else
98                fb = newnode;
99               
100        /*eigener Buffer zB fuer LCD*/
101        if(dev == 999)
102                return newnode;
103
104        ret = getfbsize(dev);
105        if(ret < 0)
106        {
107                err("framebuffermem (%s) to small, needed = %ld", name, ret * -1);
108                free(name);
109                free(newnode);
110                if(newnode == fb) fb = NULL;
111                return NULL;
112        }
113
114        debug(100, "fbname=%s, fbwidth=%d, fbheight=%d, fbcol=%d, fbsize=%ld", newnode->name, newnode->width, newnode->height, newnode->colbytes, newnode->varfbsize);
115        return newnode;
116}
117
118void fb2png_thread()
119{
120        while (writeFBfile.buf1 != NULL || writeFBfile.buf2 != NULL) {
121                if(writeFBfile.buf1 != NULL) {
122                        writeFBfile.ActBuf = writeFBfile.buf1;
123                        fb2png(writeFBfile.buf1, 320, 240, "/tmp/titanlcd.png");
124                        free(writeFBfile.buf1); writeFBfile.buf1 = NULL;
125                        if(writeFBfile.buf2 != NULL)
126                                usleep(500000);
127                }
128                if(writeFBfile.buf2 != NULL) {
129                        writeFBfile.ActBuf = writeFBfile.buf2;
130                        fb2png(writeFBfile.buf2, 320, 240, "/tmp/titanlcd.png");
131                        free(writeFBfile.buf2); writeFBfile.buf2 = NULL;
132                        if(writeFBfile.buf1 != NULL)
133                                usleep(500000);
134                }
135        }
136        writeFBfile.ActBuf = NULL;
137}
138
139void delfb(char *name)
140{
141        struct fb *node = fb, *prev = fb;
142
143        while(node != NULL)
144        {
145                if(ostrcmp(node->name, name) == 0)
146                {
147                        if(node == fb)
148                                fb = node->next;
149                        else
150                                prev->next = node->next;
151
152                        free(node->name);
153                        node->name = NULL;
154
155                        free(node);
156                        node = NULL;
157                        break;
158                }
159
160                prev = node;
161                node = node->next;
162        }
163}
164
165void freefb()
166{
167        struct fb *node = fb, *prev = fb;
168
169        while(node != NULL)
170        {
171                prev = node;
172                node = node->next;
173                if(prev != NULL)
174                        delfb(prev->name);
175        }
176}
177
178struct fb* openfb(char *fbdev, int devnr)
179{
180        int fd = -1;
181        unsigned char *mmapfb = NULL;
182        struct fb_var_screeninfo var_screeninfo;
183        struct fb_fix_screeninfo fix_screeninfo;
184        struct fb* node = NULL;
185
186        if(fbdev == NULL)
187        {
188                err("failed to find fbdev in config file");
189                return NULL;
190        }
191
192#ifndef NOFB
193        fd = open(fbdev, O_RDWR);
194
195        // blinking work start
196        if(checkbox("ATEMIO5000") == 1)
197        {
198                if (fd < 0)
199                {
200                        perror(fbdev);
201                        goto nolfb;
202                }
203        }
204        // blinking work end
205               
206        if(fd == -1)
207        {
208                perr("failed to open %s", fbdev);
209                return NULL;
210        }
211        closeonexec(fd);
212       
213        if(ioctl(fd, FBIOGET_VSCREENINFO, &var_screeninfo) == -1)
214        {
215                perr("ioctl FBIOGET_VSCREENINFO failed");
216                close(fd);
217                return NULL;
218        }
219
220        if(ioctl(fd, FBIOGET_FSCREENINFO, &fix_screeninfo) == -1)
221        {
222                perr("ioctl FBIOGET_FSCREENINFO failed");
223                close(fd);
224                return NULL;
225        }
226
227        if(!(mmapfb = (unsigned char*)mmap(0, fix_screeninfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)))
228        {
229                perr("mmap framebuffer");
230                close(fd);
231                return NULL;
232        }
233
234        debug(100, "%dk video mem", fix_screeninfo.smem_len/1024);
235
236        lfb = (unsigned char*)mmap(0, fix_screeninfo.smem_len, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
237        if (!lfb)
238        {
239                perror("mmap");
240                goto nolfb;
241        }
242
243        if (checkbox("ATEMIO5000") == 1 && var_screeninfo.bits_per_pixel != 32)
244        {
245                debug(100, "Only 32 bit per pixel supported. Framebuffer currently use %d", var_screeninfo.bits_per_pixel);
246                closefb();
247                return 0;
248        }
249
250
251        if(devnr == 0)
252                node = addfb(FB, devnr, var_screeninfo.xres, var_screeninfo.yres, var_screeninfo.bits_per_pixel / 8, fd, mmapfb, fix_screeninfo.smem_len);
253        if(devnr == 1)
254                node = addfb(FB1, devnr, var_screeninfo.xres, var_screeninfo.yres, var_screeninfo.bits_per_pixel / 8, fd, mmapfb, fix_screeninfo.smem_len);
255
256#else
257        mmapfb = malloc(16 * 1024 * 1024);
258        if(devnr == 0)
259                node = addfb(FB, devnr, getconfigint("skinfbwidth", NULL), getconfigint("skinfbheight", NULL), 4, -1, mmapfb, 16*1024*1024);
260        if(devnr == 1)
261                node = addfb(FB1, devnr, getconfigint("skinfbwidth", NULL), getconfigint("skinfbheight", NULL), 4, -1, mmapfb, 16*1024*1024);
262
263#endif
264
265        return node;
266
267// blinking work start
268nolfb:
269        if (fd >= 0)
270        {
271                close(fd);
272                fd = -1;
273        }
274
275        debug(100, "framebuffer not available.");
276
277        return 0;
278// blinking work end
279}
280
281void closefb()
282{
283        if(checkbox("ATEMIO5000") == 1)
284        {
285                if(lfb)
286                {
287                        debug(100, "ms_sync");
288                        msync(lfb, fix_screeninfo.smem_len, MS_SYNC);
289                        munmap(lfb, fix_screeninfo.smem_len);
290                }
291                if(fb->fd >= 0)
292                {
293                        debug(100, "close");
294                        disablemanualblit();
295                        close(fb->fd);
296                        fb->fd = -1;
297                }
298        }
299
300        if(fb != NULL)
301        {
302                if(fb->fb != NULL)
303                        munmap(fb->fb, fb->fixfbsize);
304                if(fb->fd != -1)
305                        close(fb->fd);
306#ifdef NOFB
307                free(fb->fb);
308#endif
309        }
310}
311
312void clearfball()
313{
314        if(fb != NULL && fb->fb != NULL)
315                memset(fb->fb, 0, fb->fixfbsize);
316}
317
318void clearfb(struct fb *node)
319{
320        if(node != NULL)
321                memset(node->fb, 0, node->varfbsize);
322}
323
324void blitfb(int flag)
325{
326        blitfb2(skinfb, flag);
327}
328
329void blitfb1()
330{
331        blitfb2(skinfb, 0);
332}
333
334//flag 0: del skinfb
335//flag 1: don't del skinfb
336void changefbresolution(char *value, int flag)
337{
338        debug(100, "fb->colbytes: %d", fb->colbytes);
339        if(checkbox("ATEMIO5000") == 1) return;
340
341        if(ostrcmp("pal", value) == 0)
342        {
343                fb->width = 720;
344                fb->height = 576;
345                fb->pitch = fb->width * fb->colbytes;
346        }
347        else if(ostrncmp("576", value, 3) == 0)
348        {
349                fb->width = 720;
350                fb->height = 576;
351                fb->pitch = fb->width * fb->colbytes;
352        }
353        else if(ostrncmp("720", value, 3) == 0)
354        {
355                fb->width = 1280;
356                fb->height = 720;
357                fb->pitch = fb->width * fb->colbytes;
358        }
359        else if(ostrncmp("1080", value, 4) == 0)
360        {
361                fb->width = 1920;
362                fb->height = 1080;
363                fb->pitch = fb->width * fb->colbytes;
364        }
365        if(skinfb == fb)
366        {
367                skin->width = skinfb->width;
368                skin->height = skinfb->height;
369                skin->iwidth = skinfb->width;
370                skin->iheight = skinfb->height;
371                skin->rwidth = skinfb->width;
372                skin->rheight = skinfb->height;
373        }
374        clearfb(fb);
375        if(flag == 0) clearfb(skinfb);
376}
377
378static void write_PNG(unsigned char *outbuffer, char *filename,
379                                int width, int height, int interlace)
380{
381        int i;
382        int bit_depth=0, color_type;
383        png_bytep row_pointers[height];
384        png_structp png_ptr;
385        png_infop info_ptr;
386        FILE *outfile = fopen(filename, "wb");
387
388        for (i=0; i<height; i++)
389                row_pointers[i] = outbuffer + i * 4 * width;
390               
391        if (!outfile)
392        {
393                fprintf (stderr, "Error: Couldn't fopen %s.\n", filename);
394                exit(EXIT_FAILURE);
395        }
396   
397        png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
398        (png_voidp) NULL, (png_error_ptr) NULL, (png_error_ptr) NULL);
399   
400        if (!png_ptr)
401                err("Error: Couldn't create PNG write struct.");
402   
403        info_ptr = png_create_info_struct(png_ptr);
404        if (!info_ptr)
405        {
406                png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
407                err("Error: Couldn't create PNG info struct.");
408        }
409   
410        png_init_io(png_ptr, outfile);
411   
412        png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
413   
414        bit_depth = 8;
415        color_type = PNG_COLOR_TYPE_RGB_ALPHA;
416        //color_type = PNG_COLOR_TYPE_RGB;
417        png_set_invert_alpha(png_ptr);
418        png_set_bgr(png_ptr);
419
420        png_set_IHDR(png_ptr, info_ptr, width, height,
421        bit_depth, color_type, interlace,
422        PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
423   
424        png_write_info(png_ptr, info_ptr);
425   
426        printf ("Now writing PNG file\n");
427   
428        png_write_image(png_ptr, row_pointers);
429   
430        png_write_end(png_ptr, info_ptr);
431        /* puh, done, now freeing memory... */
432        png_destroy_write_struct(&png_ptr, &info_ptr);
433   
434        if (outfile != NULL)
435                (void) fclose(outfile);
436}
437
438static void convert_and_write(unsigned char *inbuffer, char *filename,
439                                int width, int height, int bits, int interlace)
440{
441        size_t bufsize = (size_t) width * height * 4;
442
443        unsigned char *outbuffer = malloc(bufsize);
444
445        if (outbuffer == NULL)
446                err("Not enough memory");
447       
448        memset(outbuffer, 0, bufsize);
449        write_PNG(inbuffer, filename, width, height, interlace);
450        (void) free(outbuffer);
451}
452
453int fb2png(unsigned char *buf_p, int width, int height, char *outfile)
454{
455        int interlace = PNG_INTERLACE_ADAM7;
456        int bitdepth = 32;
457               
458        size_t help = 0;
459        while(help <= (width * height * 4))
460        {
461                buf_p[help+3] = 0x00;
462                help = help + 4;
463        }
464               
465        convert_and_write(buf_p, outfile, width, height, bitdepth, interlace);
466
467        return 0;
468}
469
470void pngforlcd(unsigned char *fbuffer, int width, int height)
471{
472        fb2png(fbuffer, width, height, "/tmp/titanlcd.png");
473}
474
475void write_FB_to_JPEG_file(unsigned char *inbuffer, int image_width, int image_height, char * filename, int quality)
476{               
477        size_t helpb = 0;
478        size_t help = 0;
479        unsigned char *helpbuffer = malloc(image_width*image_height*3);
480       
481        //delete alpha byte
482        while(help <= (image_width*image_height*4))
483        {
484                helpbuffer[helpb+0] = inbuffer[help+2];
485                helpbuffer[helpb+1] = inbuffer[help+1];
486                helpbuffer[helpb+2] = inbuffer[help+0];
487                help = help + 4;
488                helpb = helpb + 3;
489        }
490       
491        JSAMPLE *image_buffer = helpbuffer;
492        struct jpeg_compress_struct cinfo;
493        struct jpeg_error_mgr jerr;
494        FILE * outfile;
495       
496        JSAMPROW row_pointer[1];
497        int row_stride;
498       
499        cinfo.err = jpeg_std_error(&jerr);
500        jpeg_create_compress(&cinfo);
501        if ((outfile = fopen(filename, "wb")) == NULL) {
502                fprintf(stderr, "can't open %s\n", filename);
503                exit(1);
504        }
505        jpeg_stdio_dest(&cinfo, outfile);
506        cinfo.image_width = image_width;        /* image width and height, in pixels */
507        cinfo.image_height = image_height;
508        cinfo.input_components = 3;             /* # of color components per pixel */
509        cinfo.in_color_space = JCS_RGB;
510
511        jpeg_set_defaults(&cinfo);
512        jpeg_set_quality(&cinfo, quality, TRUE);
513
514        jpeg_start_compress(&cinfo, TRUE);
515        row_stride = image_width * 3;
516
517        while (cinfo.next_scanline < cinfo.image_height) {
518                row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
519                (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
520        }
521
522        jpeg_finish_compress(&cinfo);
523        fclose(outfile);
524        jpeg_destroy_compress(&cinfo);
525   
526        free(helpbuffer);
527}
528
529#endif
Note: See TracBrowser for help on using the repository browser.