source: titan/titan/fb.h @ 42987

Last change on this file since 42987 was 40672, checked in by gost, 7 years ago

fix sh4 compiler error

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