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 { |
