Mercurial > public > ostc4
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 { |