aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
Diffstat (limited to 'backends')
-rw-r--r--backends/graphics/dispmanxsdl/dispmanxsdl-graphics.cpp100
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);
}