43
43
44
44
#define __FB_SUP_RESIZE 1
45
45
#define __FB_WAIT_VSYNC 1
46
- #define __FB_ASYNC_SWAP 0
47
-
48
- #if __FB_ASYNC_SWAP
49
- static tk_thread_t * s_t_fbswap = NULL ;
50
- static tk_semaphore_t * s_sem_spare = NULL ;
51
- static tk_semaphore_t * s_sem_ready = NULL ;
52
- static tk_mutex_t * s_lck_fblist = NULL ;
53
- static bool_t s_app_quited = FALSE;
54
- #endif
55
46
56
47
static fb_info_t s_fb ;
57
48
static int s_ttyfd = -1 ;
@@ -86,44 +77,13 @@ static void lcd_linux_fb_close(fb_info_t* fb) {
86
77
87
78
static void on_app_exit (void ) {
88
79
fb_info_t * fb = & s_fb ;
89
-
90
- #if __FB_ASYNC_SWAP
91
- s_app_quited = TRUE;
92
- tk_semaphore_post (s_sem_spare );
93
- tk_semaphore_post (s_sem_ready );
94
- sleep_ms (200 );
95
-
96
- if (s_t_fbswap ) {
97
- tk_thread_join (s_t_fbswap );
98
- tk_thread_destroy (s_t_fbswap );
99
- }
100
-
101
- if (s_sem_spare ) {
102
- tk_semaphore_destroy (s_sem_spare );
103
- }
104
-
105
- if (s_sem_ready ) {
106
- tk_semaphore_destroy (s_sem_ready );
107
- }
108
-
109
- if (s_lck_fblist ) {
110
- tk_mutex_destroy (s_lck_fblist );
111
- }
112
- #endif
113
-
114
80
lcd_linux_fb_close (fb );
115
-
116
81
log_debug ("on_app_exit\n" );
117
82
}
118
83
119
84
#if __FB_SUP_RESIZE
120
85
static ret_t (* lcd_mem_linux_resize_default )(lcd_t * lcd , wh_t w , wh_t h , uint32_t line_length );
121
86
static ret_t lcd_mem_linux_resize (lcd_t * lcd , wh_t w , wh_t h , uint32_t line_length ) {
122
- #if __FB_ASYNC_SWAP
123
- log_debug ("linuxfb async swap mode not support fb resize.\n" );
124
- return RET_FAIL ;
125
- #endif
126
-
127
87
ret_t ret = RET_OK ;
128
88
fb_info_t * fb = & s_fb ;
129
89
return_value_if_fail (lcd != NULL , RET_BAD_PARAMS );
@@ -141,76 +101,6 @@ static ret_t lcd_mem_linux_resize(lcd_t* lcd, wh_t w, wh_t h, uint32_t line_leng
141
101
}
142
102
#endif
143
103
144
- static ret_t lcd_linux_init_drawing_fb (lcd_mem_t * mem , bitmap_t * fb ) {
145
- return_value_if_fail (mem != NULL && fb != NULL , RET_BAD_PARAMS );
146
-
147
- * fb = * mem -> fb_bitmaps [0 ];
148
- fb -> w = lcd_get_physical_width ((lcd_t * )mem );
149
- fb -> h = lcd_get_physical_height ((lcd_t * )mem );
150
-
151
- return RET_OK ;
152
- }
153
-
154
- static ret_t lcd_linux_init_online_fb (lcd_mem_t * mem , bitmap_t * fb , uint8_t * buff , uint32_t w , uint32_t h , uint32_t line_length ) {
155
- return_value_if_fail (mem != NULL && fb != NULL && buff != NULL , RET_BAD_PARAMS );
156
-
157
- * fb = * mem -> fb_bitmaps [1 ];
158
- fb -> w = w ;
159
- fb -> h = h ;
160
-
161
- return RET_OK ;
162
- }
163
-
164
- static ret_t lcd_linux_flush (lcd_t * base , int fbid ) {
165
- //printf("==========lcd_linux_flush fbid=%d\n", fbid);//###DEBUG###
166
-
167
- uint8_t * buff = NULL ;
168
- fb_info_t * fb = & s_fb ;
169
- int fb_nr = fb_number (fb );
170
- uint32_t size = fb_size (fb );
171
- lcd_mem_t * lcd = (lcd_mem_t * )base ;
172
- const dirty_rects_t * dirty_rects = NULL ;
173
- lcd_orientation_t o = system_info ()-> lcd_orientation ;
174
-
175
- return_value_if_fail (lcd != NULL && fb != NULL && fbid < fb_nr , RET_BAD_PARAMS );
176
-
177
- buff = fb -> fbmem0 + size * fbid ;
178
-
179
- bitmap_t online_fb ;
180
- bitmap_t offline_fb ;
181
- lcd_linux_init_drawing_fb (lcd , & offline_fb );
182
- lcd_linux_init_online_fb (lcd , & online_fb , buff , fb_width (fb ), fb_height (fb ), fb_line_length (fb ));
183
-
184
- // add current online buff to the dirty manager, and notify all managed buff update/merge with the base dirty rect
185
- lcd_fb_dirty_rects_add_fb_info (& (lcd -> fb_dirty_rects_list ), buff );
186
- lcd_fb_dirty_rects_update_all_fb_dirty_rects (& (lcd -> fb_dirty_rects_list ), base -> dirty_rects );
187
-
188
- // get the merged dirty rects of current online buff, and then copy each small rects from offline fb
189
- dirty_rects = lcd_fb_dirty_rects_get_dirty_rects_by_fb (& (lcd -> fb_dirty_rects_list ), buff );
190
- if (dirty_rects != NULL && dirty_rects -> nr > 0 ) {
191
- for (int i = 0 ; i < dirty_rects -> nr ; i ++ ) {
192
- const rect_t * dr = (const rect_t * )dirty_rects -> rects + i ;
193
- #ifdef WITH_FAST_LCD_PORTRAIT
194
- if (system_info ()-> flags & SYSTEM_INFO_FLAG_FAST_LCD_PORTRAIT ) {
195
- rect_t rr = lcd_orientation_rect_rotate_by_anticlockwise (dr , o , lcd_get_width (base ), lcd_get_height (base ));
196
- image_copy (& online_fb , & offline_fb , & rr , rr .x , rr .y );
197
- } else
198
- #endif
199
- {
200
- if (o == LCD_ORIENTATION_0 ) {
201
- image_copy (& online_fb , & offline_fb , dr , dr -> x , dr -> y );
202
- } else {
203
- image_rotate (& online_fb , & offline_fb , dr , o );
204
- }
205
- }
206
- }
207
- }
208
-
209
- // reset current online buff dirty rect to empty, because all new contnet has copyed from offline fb
210
- lcd_fb_dirty_rects_reset_dirty_rects_by_fb (& (lcd -> fb_dirty_rects_list ), buff );
211
- return RET_OK ;
212
- }
213
-
214
104
static void on_signal_int (int sig ) {
215
105
tk_quit ();
216
106
}
@@ -219,14 +109,18 @@ static ret_t (*lcd_mem_linux_flush_default)(lcd_t* lcd);
219
109
static ret_t lcd_mem_linux_flush (lcd_t * lcd ) {
220
110
#if __FB_WAIT_VSYNC
221
111
fb_info_t * fb = & s_fb ;
222
- fb_sync (fb );
112
+ if (!fb_is_1fb (fb )) {
113
+ struct fb_var_screeninfo vi = (fb -> var );
114
+ vi .yoffset = 0 ;
115
+ ioctl (fb -> fd , FBIOPAN_DISPLAY , & vi );
116
+ }
117
+ int dummy = 0 ;
118
+ ioctl (fb -> fd , FBIO_WAITFORVSYNC , & dummy );
223
119
#endif
224
120
225
121
if (lcd_mem_linux_flush_default ) {
226
122
lcd_mem_linux_flush_default (lcd );
227
123
}
228
-
229
- //printf("---------lcd_mem_linux_flush VSYNC=%d, ASWAP=%d\n", __FB_WAIT_VSYNC, __FB_ASYNC_SWAP);//###DEBUG###
230
124
return RET_OK ;
231
125
}
232
126
@@ -282,238 +176,9 @@ static lcd_t* lcd_linux_create_flushable(fb_info_t* fb) {
282
176
return lcd ;
283
177
}
284
178
285
- enum {
286
- FB_TAG_UND = 0 ,
287
- FB_TAG_SPARE ,
288
- FB_TAG_READY ,
289
- FB_TAG_BUSY
290
- };
291
- typedef struct fb_taged {
292
- int fbid ;
293
- int tags ;
294
- } fb_taged_t ;
295
-
296
- #define FB_LIST_NUM 3
297
- static fb_taged_t s_fblist [FB_LIST_NUM ];
298
- static void init_fblist (int num ) {
299
- memset (s_fblist , 0 , sizeof (s_fblist ));
300
- for (int i = 0 ; i < num && i < FB_LIST_NUM ; i ++ ) {
301
- s_fblist [i ].fbid = i ;
302
- s_fblist [i ].tags = FB_TAG_SPARE ;
303
- }
304
- }
305
- static fb_taged_t * get_spare_fb () {
306
- for (int i = 0 ; i < FB_LIST_NUM ; i ++ ) {
307
- if (s_fblist [i ].tags == FB_TAG_SPARE ) {
308
- return & s_fblist [i ];
309
- }
310
- }
311
- return NULL ;
312
- }
313
- static fb_taged_t * get_busy_fb () {
314
- for (int i = 0 ; i < FB_LIST_NUM ; i ++ ) {
315
- if (s_fblist [i ].tags == FB_TAG_BUSY ) {
316
- return & s_fblist [i ];
317
- }
318
- }
319
- return NULL ;
320
- }
321
- inline static fb_taged_t * get_ready_fb () {
322
- fb_taged_t * last_busy_fb = get_busy_fb ();
323
-
324
- if (last_busy_fb ) {
325
- // get the first ready slot next to the busy one
326
- for (int i = 1 ; i < FB_LIST_NUM ; i ++ ) {
327
- int next_ready_fbid = (last_busy_fb -> fbid + i ) % FB_LIST_NUM ;
328
-
329
- if (s_fblist [next_ready_fbid ].tags == FB_TAG_READY ) {
330
- return & s_fblist [next_ready_fbid ];
331
- }
332
- }
333
- } else {
334
- // no last busy, get the first ready one
335
- for (int i = 0 ; i < FB_LIST_NUM ; i ++ ) {
336
- if (s_fblist [i ].tags == FB_TAG_READY ) {
337
- return & s_fblist [i ];
338
- }
339
- }
340
- }
341
- return NULL ;
342
- }
343
-
344
- #if __FB_ASYNC_SWAP
345
-
346
- static ret_t lcd_mem_linux_write_buff (lcd_t * lcd ) {
347
- ret_t ret = RET_OK ;
348
- if (s_app_quited ) {
349
- return ret ;
350
- }
351
-
352
- if (lcd -> draw_mode != LCD_DRAW_OFFLINE ) {
353
- tk_semaphore_wait (s_sem_spare , -1 );
354
- if (s_app_quited ) {
355
- return ret ;
356
- }
357
-
358
- tk_mutex_lock (s_lck_fblist );
359
- fb_taged_t * spare_fb = get_spare_fb ();
360
- assert (spare_fb );
361
- tk_mutex_unlock (s_lck_fblist );
362
-
363
- ret = lcd_linux_flush (lcd , spare_fb -> fbid );
364
-
365
- tk_mutex_lock (s_lck_fblist );
366
- spare_fb -> tags = FB_TAG_READY ;
367
- tk_semaphore_post (s_sem_ready );
368
- tk_mutex_unlock (s_lck_fblist );
369
-
370
- int sched_yield (void );
371
- sched_yield ();
372
-
373
- //printf("==========lcd_mem_linux_write_buff VSYNC=%d, ASWAP=%d\n", __FB_WAIT_VSYNC, __FB_ASYNC_SWAP);//###DEBUG###
374
- }
375
-
376
- return ret ;
377
- }
378
-
379
- static void * fbswap_thread (void * ctx ) {
380
- fb_info_t * fb = & s_fb ;
381
- struct fb_var_screeninfo vi = (fb -> var );
382
-
383
- log_info ("display_thread start\n" );
384
-
385
- while (!s_app_quited ) {
386
- tk_semaphore_wait (s_sem_ready , -1 );
387
- if (s_app_quited ) {
388
- break ;
389
- }
390
-
391
- tk_mutex_lock (s_lck_fblist );
392
- fb_taged_t * ready_fb = get_ready_fb ();
393
- assert (ready_fb );
394
- int ready_fbid = ready_fb -> fbid ;
395
- tk_mutex_unlock (s_lck_fblist );
396
-
397
- vi .yoffset = ready_fbid * fb_height (fb );
398
- ioctl (fb -> fd , FBIOPAN_DISPLAY , & vi );
399
-
400
- #if __FB_WAIT_VSYNC
401
- int dummy = 0 ;
402
- ioctl (fb -> fd , FBIO_WAITFORVSYNC , & dummy );
403
- #endif
404
-
405
- tk_mutex_lock (s_lck_fblist );
406
- fb_taged_t * last_busy_fb = get_busy_fb ();
407
- if (last_busy_fb ) {
408
- last_busy_fb -> tags = FB_TAG_SPARE ;
409
- tk_semaphore_post (s_sem_spare );
410
- }
411
- ready_fb -> tags = FB_TAG_BUSY ;
412
- tk_mutex_unlock (s_lck_fblist );
413
- }
414
-
415
- log_info ("display_thread end\n" );
416
- return NULL ;
417
- }
418
- #else // __FB_ASYNC_SWAP
419
-
420
- static ret_t lcd_mem_linux_write_buff (lcd_t * lcd ) {
421
- ret_t ret = RET_OK ;
422
- fb_info_t * fb = & s_fb ;
423
- struct fb_var_screeninfo vi = (fb -> var );
424
-
425
- if (lcd -> draw_mode != LCD_DRAW_OFFLINE ) {
426
- fb_taged_t * spare_fb = get_spare_fb ();
427
- ret = lcd_linux_flush (lcd , spare_fb -> fbid );
428
-
429
- vi .yoffset = spare_fb -> fbid * fb_height (fb );
430
- ioctl (fb -> fd , FBIOPAN_DISPLAY , & vi );
431
-
432
- #if __FB_WAIT_VSYNC
433
- int dummy = 0 ;
434
- ioctl (fb -> fd , FBIO_WAITFORVSYNC , & dummy );
435
- #endif
436
-
437
- fb_taged_t * last_busy_fb = get_busy_fb ();
438
- if (last_busy_fb ) {
439
- last_busy_fb -> tags = FB_TAG_SPARE ;
440
- }
441
- spare_fb -> tags = FB_TAG_BUSY ;
442
-
443
- //printf("==========lcd_mem_linux_write_buff VSYNC=%d, ASWAP=%d\n", __FB_WAIT_VSYNC, __FB_ASYNC_SWAP);//###DEBUG###
444
- }
445
-
446
- return ret ;
447
- }
448
- #endif // __FB_ASYNC_SWAP
449
-
450
- static lcd_t * lcd_linux_create_swappable (fb_info_t * fb ) {
451
- lcd_t * lcd = NULL ;
452
- int bpp = fb_bpp (fb );
453
- int line_length = fb_line_length (fb );
454
-
455
- bitmap_t * offline_fb = fb -> offline_fb ;
456
- return_value_if_fail (offline_fb != NULL , NULL );
457
-
458
- if (bpp == 16 ) {
459
- if (fb_is_bgr565 (fb )) {
460
- lcd = lcd_mem_bgr565_create_single_fb_bitmap (offline_fb );
461
- } else if (fb_is_rgb565 (fb )) {
462
- lcd = lcd_mem_rgb565_create_single_fb_bitmap (offline_fb );
463
- } else {
464
- assert (!"not supported framebuffer format." );
465
- }
466
- } else if (bpp == 32 ) {
467
- if (fb_is_bgra8888 (fb )) {
468
- lcd = lcd_mem_bgra8888_create_single_fb_bitmap (offline_fb );
469
- } else if (fb_is_rgba8888 (fb )) {
470
- lcd = lcd_mem_rgba8888_create_single_fb_bitmap (offline_fb );
471
- } else {
472
- assert (!"not supported framebuffer format." );
473
- }
474
- } else if (bpp == 24 ) {
475
- if (fb_is_bgr888 (fb )) {
476
- lcd = lcd_mem_bgr888_create_single_fb_bitmap (offline_fb );
477
- } else if (fb_is_rgb888 (fb )) {
478
- lcd = lcd_mem_rgb888_create_single_fb_bitmap (offline_fb );
479
- } else {
480
- assert (!"not supported framebuffer format." );
481
- }
482
- } else {
483
- assert (!"not supported framebuffer format." );
484
- }
485
-
486
- if (lcd != NULL ) {
487
- lcd -> swap = lcd_mem_linux_write_buff ;
488
- lcd -> flush = lcd_mem_linux_write_buff ;
489
- lcd_mem_set_line_length (lcd , line_length );
490
-
491
- #if __FB_SUP_RESIZE
492
- lcd_mem_linux_resize_default = lcd -> resize ;
493
- lcd -> resize = lcd_mem_linux_resize ;
494
- #endif
495
-
496
- #if __FB_ASYNC_SWAP
497
- s_lck_fblist = tk_mutex_create ();
498
- s_sem_spare = tk_semaphore_create (fb_number (fb ), NULL );
499
- s_sem_ready = tk_semaphore_create (0 , NULL );
500
- s_t_fbswap = tk_thread_create (fbswap_thread , lcd );
501
- tk_thread_start (s_t_fbswap );
502
- #endif
503
- }
504
-
505
- return lcd ;
506
- }
507
-
508
179
static lcd_t * lcd_linux_create (fb_info_t * fb ) {
509
- init_fblist (fb_number (fb ));
510
180
printf ("=========fb_number=%d\n" , fb_number (fb ));
511
-
512
- if (fb_is_1fb (fb )) {
513
- return lcd_linux_create_flushable (fb );
514
- } else {
515
- return lcd_linux_create_swappable (fb );
516
- }
181
+ return lcd_linux_create_flushable (fb );
517
182
}
518
183
519
184
lcd_t * lcd_linux_fb_create (const char * filename ) {
0 commit comments