diff options
Diffstat (limited to 'backends')
-rw-r--r-- | backends/graphics/dispmanxsdl/dispmanxsdl-graphics.cpp | 100 |
1 files changed, 53 insertions, 47 deletions
diff --git a/backends/graphics/dispmanxsdl/dispmanxsdl-graphics.cpp b/backends/graphics/dispmanxsdl/dispmanxsdl-graphics.cpp index d2615ad99f..d67cb90f65 100644 --- a/backends/graphics/dispmanxsdl/dispmanxsdl-graphics.cpp +++ b/backends/graphics/dispmanxsdl/dispmanxsdl-graphics.cpp @@ -34,11 +34,13 @@ #include <bcm_host.h> +#define numpages 2 + struct dispvarsStruct { DISPMANX_DISPLAY_HANDLE_T display; DISPMANX_MODEINFO_T amode; DISPMANX_UPDATE_HANDLE_T update; - DISPMANX_RESOURCE_HANDLE_T resources[3]; + DISPMANX_RESOURCE_HANDLE_T resources[numpages]; DISPMANX_ELEMENT_HANDLE_T element; VC_IMAGE_TYPE_T pixFormat; VC_DISPMANX_ALPHA_T *alpha; @@ -56,17 +58,17 @@ struct dispvarsStruct { struct dispmanxPage *currentPage; int pageflipPending; - pthread_cond_t vsync_condition; - pthread_mutex_t pending_mutex; - pthread_mutex_t page_use_mutex; + pthread_cond_t vsyncCondition; + pthread_mutex_t pendingMutex; // Mutex to isolate the vsync condition signaling - pthread_mutex_t vsync_cond_mutex; + pthread_mutex_t vsyncCondMutex; }; struct dispmanxPage { unsigned int numpage; struct dispvarsStruct *dispvars; + pthread_mutex_t pageUseMutex; bool used; }; @@ -85,23 +87,26 @@ DispmanXSdlGraphicsManager::~DispmanXSdlGraphicsManager() void DispmanXSdlGraphicsManager::DispmanXInit () { _dispvars->screen = 0; _dispvars->vcImagePtr = 0; - _dispvars->pages = (struct dispmanxPage*)calloc(3, sizeof(struct dispmanxPage)); + _dispvars->pages = (struct dispmanxPage*)calloc(numpages, sizeof(struct dispmanxPage)); _dispvars->pageflipPending = 0; _dispvars->currentPage = NULL; // Initialize mutex and condition variable objects - pthread_mutex_init(&_dispvars->pending_mutex, NULL); - pthread_mutex_init(&_dispvars->page_use_mutex, NULL); - pthread_mutex_init(&_dispvars->vsync_cond_mutex, NULL); - pthread_cond_init(&_dispvars->vsync_condition, NULL); + pthread_mutex_init(&_dispvars->pendingMutex, NULL); + pthread_mutex_init(&_dispvars->vsyncCondMutex, NULL); + pthread_cond_init(&_dispvars->vsyncCondition, NULL); int i; - for (i = 0; i < 3; i++) { + for (i = 0; i < numpages; i++) { _dispvars->pages[i].numpage = i; _dispvars->pages[i].used = false; _dispvars->pages[i].dispvars = _dispvars; } + for (i = 0; i < numpages; i++) { + pthread_mutex_init(&_dispvars->pages[i].pageUseMutex, NULL); + } + // Before we call any vc_* function, we need to call this one. bcm_host_init(); @@ -142,15 +147,11 @@ void DispmanXSdlGraphicsManager::DispmanXSetup (int width, int height, int bpp) vc_dispmanx_rect_set(&(_dispvars->bmpRect), 0, 0, width, height); vc_dispmanx_rect_set(&(_dispvars->srcRect), 0, 0, width << 16, height << 16); - // We create three resources for triple buffering - _dispvars->resources[0] = vc_dispmanx_resource_create(_dispvars->pixFormat, width, height, - &(_dispvars->vcImagePtr)); - - _dispvars->resources[1] = vc_dispmanx_resource_create(_dispvars->pixFormat, width, height, - &(_dispvars->vcImagePtr)); - - _dispvars->resources[2] = vc_dispmanx_resource_create(_dispvars->pixFormat, width, height, - &(_dispvars->vcImagePtr)); + // We create the resources for multiple buffering + int i; + for (i = 0; i < numpages; i++) + _dispvars->resources[i] = vc_dispmanx_resource_create(_dispvars->pixFormat, width, height, + &(_dispvars->vcImagePtr)); // Add element _dispvars->update = vc_dispmanx_update_start(0); @@ -169,7 +170,7 @@ struct dispmanxPage *DispmanXSdlGraphicsManager::DispmanXGetFreePage() unsigned i; while (page == NULL) { // Try to find a free page - for (i = 0; i < 3; ++i) { + for (i = 0; i < numpages; ++i) { if (!_dispvars->pages[i].used) { page = (_dispvars->pages) + i; break; @@ -177,14 +178,14 @@ struct dispmanxPage *DispmanXSdlGraphicsManager::DispmanXGetFreePage() } // If no page is free ATM, wait until a free page is freed by vsync CB if (page == NULL) { - pthread_mutex_lock(&_dispvars->vsync_cond_mutex); - pthread_cond_wait(&_dispvars->vsync_condition, &_dispvars->vsync_cond_mutex); - pthread_mutex_unlock(&_dispvars->vsync_cond_mutex); + pthread_mutex_lock(&_dispvars->vsyncCondMutex); + pthread_cond_wait(&_dispvars->vsyncCondition, &_dispvars->vsyncCondMutex); + pthread_mutex_unlock(&_dispvars->vsyncCondMutex); } } - pthread_mutex_lock(&_dispvars->page_use_mutex); + pthread_mutex_lock(&page->pageUseMutex); page->used = true; - pthread_mutex_unlock(&_dispvars->page_use_mutex); + pthread_mutex_unlock(&page->pageUseMutex); return page; } @@ -205,19 +206,19 @@ void DispmanXVSyncCallback (DISPMANX_UPDATE_HANDLE_T u, void * arg){ struct dispmanxPage *page = (struct dispmanxPage *) arg; // We signal the vsync condition, just in case we're waiting for it somewhere (no free pages, etc) - pthread_mutex_lock(&page->dispvars->vsync_cond_mutex); - pthread_cond_signal(&page->dispvars->vsync_condition); - pthread_mutex_unlock(&page->dispvars->vsync_cond_mutex); + pthread_mutex_lock(&page->dispvars->vsyncCondMutex); + pthread_cond_signal(&page->dispvars->vsyncCondition); + pthread_mutex_unlock(&page->dispvars->vsyncCondMutex); - pthread_mutex_lock(&page->dispvars->pending_mutex); + pthread_mutex_lock(&page->dispvars->pendingMutex); page->dispvars->pageflipPending--; - pthread_mutex_unlock(&page->dispvars->pending_mutex); + pthread_mutex_unlock(&page->dispvars->pendingMutex); // We mark as free the page that was visible until now if (page->dispvars->currentPage != NULL) { - pthread_mutex_lock(&page->dispvars->page_use_mutex); + pthread_mutex_lock(&page->pageUseMutex); page->dispvars->currentPage->used = false; - pthread_mutex_unlock(&page->dispvars->page_use_mutex); + pthread_mutex_unlock(&page->pageUseMutex); } // The page on which we just issued the flip that caused this callback becomes the visible one @@ -225,11 +226,11 @@ void DispmanXVSyncCallback (DISPMANX_UPDATE_HANDLE_T u, void * arg){ } void DispmanXSdlGraphicsManager::DispmanXFlip (struct dispmanxPage *page) { - // We don't queue multiple page flips. + // We don't queue multiple page flips because dispmanx doesn't support it. if (_dispvars->pageflipPending > 0) { - pthread_mutex_lock(&_dispvars->vsync_cond_mutex); - pthread_cond_wait(&_dispvars->vsync_condition, &_dispvars->vsync_cond_mutex); - pthread_mutex_unlock(&_dispvars->vsync_cond_mutex); + pthread_mutex_lock(&_dispvars->vsyncCondMutex); + pthread_cond_wait(&_dispvars->vsyncCondition, &_dispvars->vsyncCondMutex); + pthread_mutex_unlock(&_dispvars->vsyncCondMutex); } // Issue a page flip at the next vblank interval (will be done at vsync anyway). @@ -239,17 +240,18 @@ void DispmanXSdlGraphicsManager::DispmanXFlip (struct dispmanxPage *page) { _dispvars->resources[page->numpage]); vc_dispmanx_update_submit(_dispvars->update, &DispmanXVSyncCallback, page); - pthread_mutex_lock(&_dispvars->pending_mutex); + pthread_mutex_lock(&_dispvars->pendingMutex); _dispvars->pageflipPending++; - pthread_mutex_unlock(&_dispvars->pending_mutex); + pthread_mutex_unlock(&_dispvars->pendingMutex); } void DispmanXSdlGraphicsManager::DispmanXFreeResources(void) { + int i; _dispvars->update = vc_dispmanx_update_start(0); - vc_dispmanx_resource_delete(_dispvars->resources[0]); - vc_dispmanx_resource_delete(_dispvars->resources[1]); - vc_dispmanx_resource_delete(_dispvars->resources[2]); + for (i = 0; i < numpages; i++) + vc_dispmanx_resource_delete(_dispvars->resources[i]); + vc_dispmanx_element_remove(_dispvars->update, _dispvars->element); vc_dispmanx_update_submit_sync(_dispvars->update); @@ -262,11 +264,15 @@ void DispmanXSdlGraphicsManager::DispmanXVideoQuit() { bcm_host_deinit(); // Destroy mutexes and conditions - pthread_mutex_destroy(&_dispvars->pending_mutex); - pthread_mutex_destroy(&_dispvars->page_use_mutex); - pthread_mutex_destroy(&_dispvars->vsync_cond_mutex); - pthread_cond_destroy(&_dispvars->vsync_condition); - + pthread_mutex_destroy(&_dispvars->pendingMutex); + pthread_mutex_destroy(&_dispvars->vsyncCondMutex); + pthread_cond_destroy(&_dispvars->vsyncCondition); + + int i; + for (i = 0; i < numpages; i++) { + pthread_mutex_destroy(&_dispvars->pages[i].pageUseMutex); + } + free(_dispvars->pages); } |