comparison Discovery/Src/gfx_engine.c @ 623:ba83a8ef9bad

Improvment frame Handling: In previous version, especially during fast menu operations, from time to time a flicker (in case of cyclic updated views) or corrupted menus appeared. Possible root cause is a interferance in the chain: refresh display (~100ms) => release frame (in parallel to) provide frame (~45ms) => clear frame (~45ms). to improve the behaviour the clear frame loop is not iterated until all bufferes are cleared (before one buffer every~45ms). getFrame() does now iterate through all frame buffers instead reusing the first possible (to avoid ghoust views and to provide more time to housekeeping function for cleanup)
author Ideenmodellierer
date Sun, 07 Feb 2021 22:04:43 +0100
parents 8f78faf88fc5
children 60162a939c06
comparison
equal deleted inserted replaced
622:8f78faf88fc5 623:ba83a8ef9bad
3373 return SDRAM_DOUBLE_BUFFER_TWO; 3373 return SDRAM_DOUBLE_BUFFER_TWO;
3374 } 3374 }
3375 3375
3376 uint32_t getFrame(uint8_t callerId) 3376 uint32_t getFrame(uint8_t callerId)
3377 { 3377 {
3378 static uint8_t lastFrameProvided = 0;
3378 uint8_t i; 3379 uint8_t i;
3379 3380
3380 i = 0; 3381 /* first iteration: look for a clear frame */
3381 while((i < MAXFRAMES) && (frame[i].status != CLEAR)) 3382 i = lastFrameProvided;
3383 do
3384 {
3382 i++; 3385 i++;
3386 if(i == MAXFRAMES)
3387 {
3388 i = 0;
3389 }
3390 } while((i != lastFrameProvided) && (frame[i].status != CLEAR));
3383 3391
3384 if((i < MAXFRAMES) && (frame[i].status == CLEAR)) 3392 if((i < MAXFRAMES) && (frame[i].status == CLEAR))
3385 { 3393 {
3386 frame[i].status = BLOCKED; 3394 frame[i].status = BLOCKED;
3387 frame[i].caller = callerId; 3395 frame[i].caller = callerId;
3396 lastFrameProvided = i;
3388 return frame[i].StartAddress; 3397 return frame[i].StartAddress;
3389 } 3398 }
3390 3399
3391 i = 0; 3400 /* second iteration: look for a frame which may be reused after clearing */
3392 while((i < MAXFRAMES) && (frame[i].status != RELEASED)) 3401 i = lastFrameProvided;
3402 do
3403 {
3393 i++; 3404 i++;
3405 if(i == MAXFRAMES)
3406 {
3407 i = 0;
3408 }
3409 }while((i < MAXFRAMES) && (frame[i].status != RELEASED));
3410
3394 3411
3395 if((i < MAXFRAMES) && (frame[i].status == RELEASED)) 3412 if((i < MAXFRAMES) && (frame[i].status == RELEASED))
3396 { 3413 {
3397 GFX_clear_frame_immediately(frame[i].StartAddress); 3414 GFX_clear_frame_immediately(frame[i].StartAddress);
3398 frame[i].status = BLOCKED; 3415 frame[i].status = BLOCKED;
3416 lastFrameProvided = i;
3399 return frame[i].StartAddress; 3417 return frame[i].StartAddress;
3400 } 3418 }
3401 return 0; 3419 return 0;
3402 } 3420 }
3403 3421
3456 3474
3457 return count; 3475 return count;
3458 } 3476 }
3459 3477
3460 3478
3461 void housekeepingFrame(void) 3479 uint8_t housekeepingFrame(void)
3462 { 3480 {
3463 static uint8_t countLogClear = 0; 3481 static uint8_t countLogClear = 0;
3464 3482 uint8_t i;
3465 if(DMA2D_at_work != 255) 3483 uint8_t retVal = 1;
3466 return; 3484
3467 3485 if(DMA2D_at_work == 255)
3468 /* new for debug hw 151202 */ 3486 {
3469 for(int i=1;i<MAXFRAMECOUNTER;i++) 3487 /* new for debug hw 151202 */
3470 { 3488 for(i=1;i<MAXFRAMECOUNTER;i++)
3471 frameCounter[i] = 0; 3489 {
3472 } 3490 frameCounter[i] = 0;
3473 for(int i=1;i<MAXFRAMES;i++) 3491 }
3474 { 3492 for(int i=1;i<MAXFRAMES;i++)
3475 if(frame[i].status == BLOCKED) 3493 {
3476 { 3494 if(frame[i].status == BLOCKED)
3477 if(frame[i].caller < (MAXFRAMECOUNTER - 2)) 3495 {
3478 frameCounter[frame[i].caller]++; 3496 if(frame[i].caller < (MAXFRAMECOUNTER - 2))
3497 frameCounter[frame[i].caller]++;
3498 else
3499 frameCounter[MAXFRAMECOUNTER-3]++;
3500 }
3479 else 3501 else
3480 frameCounter[MAXFRAMECOUNTER-3]++; 3502 if(frame[i].status == RELEASED)
3503 frameCounter[MAXFRAMECOUNTER-2]++;
3504 else
3505 frameCounter[MAXFRAMECOUNTER-1]++;
3506 }
3507
3508 i = 0;
3509 /* skip frame cleaning for actual frames which have not yet been replaced by new top/bottom frames */
3510 while((i < MAXFRAMES) && ((frame[i].status != RELEASED) || (frame[i].StartAddress == GFX_get_pActualFrameTop()) || (frame[i].StartAddress == GFX_get_pActualFrameBottom())))
3511 i++;
3512
3513 if((i < MAXFRAMES) && (frame[i].status == RELEASED))
3514 {
3515 if(frame[i].caller == 15)
3516 countLogClear++;
3517 GFX_clear_frame_dma2d(i);
3481 } 3518 }
3482 else 3519 else
3483 if(frame[i].status == RELEASED) 3520 {
3484 frameCounter[MAXFRAMECOUNTER-2]++; 3521 retVal = 0; /* no more frame to be cleaned found */
3485 else 3522 }
3486 frameCounter[MAXFRAMECOUNTER-1]++; 3523 }
3487 } 3524 return retVal;
3488
3489
3490 uint8_t i;
3491
3492 i = 0;
3493 while((i < MAXFRAMES) && ((frame[i].status != RELEASED) || (frame[i].StartAddress == GFX_get_pActualFrameTop()) || (frame[i].StartAddress == GFX_get_pActualFrameBottom())))
3494 i++;
3495
3496 if((i < MAXFRAMES) && (frame[i].status == RELEASED))
3497 {
3498 if(frame[i].caller == 15)
3499 countLogClear++;
3500 GFX_clear_frame_dma2d(i);
3501 }
3502 } 3525 }
3503 3526
3504 3527
3505 static void GFX_Dma2d_TransferComplete(DMA2D_HandleTypeDef* Dma2dHandle) 3528 static void GFX_Dma2d_TransferComplete(DMA2D_HandleTypeDef* Dma2dHandle)
3506 { 3529 {