source: titan/titan/fb.h @ 40613

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

[titan] next fix FB

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