summaryrefslogtreecommitdiffstats
path: root/minui/graphics_adf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'minui/graphics_adf.cpp')
-rw-r--r--minui/graphics_adf.cpp46
1 files changed, 35 insertions, 11 deletions
diff --git a/minui/graphics_adf.cpp b/minui/graphics_adf.cpp
index 5d0867f58..9e262b044 100644
--- a/minui/graphics_adf.cpp
+++ b/minui/graphics_adf.cpp
@@ -26,11 +26,13 @@
#include <sys/mman.h>
#include <adf/adf.h>
+#include <sync/sync.h>
#include "graphics.h"
struct adf_surface_pdata {
GRSurface base;
+ int fence_fd;
int fd;
__u32 offset;
__u32 pitch;
@@ -42,6 +44,8 @@ struct adf_pdata {
adf_id_t eng_id;
__u32 format;
+ adf_device dev;
+
unsigned int current_surface;
unsigned int n_surfaces;
adf_surface_pdata surfaces[2];
@@ -53,6 +57,7 @@ static void adf_blank(minui_backend *backend, bool blank);
static int adf_surface_init(adf_pdata *pdata, drm_mode_modeinfo *mode, adf_surface_pdata *surf) {
memset(surf, 0, sizeof(*surf));
+ surf->fence_fd = -1;
surf->fd = adf_interface_simple_buffer_alloc(pdata->intf_fd, mode->hdisplay,
mode->vdisplay, pdata->format, &surf->offset, &surf->pitch);
if (surf->fd < 0)
@@ -63,9 +68,9 @@ static int adf_surface_init(adf_pdata *pdata, drm_mode_modeinfo *mode, adf_surfa
surf->base.row_bytes = surf->pitch;
surf->base.pixel_bytes = (pdata->format == DRM_FORMAT_RGB565) ? 2 : 4;
- surf->base.data = reinterpret_cast<uint8_t*>(mmap(NULL,
- surf->pitch * surf->base.height, PROT_WRITE,
- MAP_SHARED, surf->fd, surf->offset));
+ surf->base.data = static_cast<uint8_t*>(mmap(NULL,
+ surf->pitch * surf->base.height, PROT_WRITE,
+ MAP_SHARED, surf->fd, surf->offset));
if (surf->base.data == MAP_FAILED) {
close(surf->fd);
return -errno;
@@ -163,21 +168,20 @@ static GRSurface* adf_init(minui_backend *backend)
pdata->intf_fd = -1;
for (i = 0; i < n_dev_ids && pdata->intf_fd < 0; i++) {
- adf_device dev;
- int err = adf_device_open(dev_ids[i], O_RDWR, &dev);
+ int err = adf_device_open(dev_ids[i], O_RDWR, &pdata->dev);
if (err < 0) {
fprintf(stderr, "opening adf device %u failed: %s\n", dev_ids[i],
strerror(-err));
continue;
}
- err = adf_device_init(pdata, &dev);
- if (err < 0)
+ err = adf_device_init(pdata, &pdata->dev);
+ if (err < 0) {
fprintf(stderr, "initializing adf device %u failed: %s\n",
dev_ids[i], strerror(-err));
-
- adf_device_close(&dev);
+ adf_device_close(&pdata->dev);
+ }
}
free(dev_ids);
@@ -193,6 +197,23 @@ static GRSurface* adf_init(minui_backend *backend)
return ret;
}
+static void adf_sync(adf_surface_pdata *surf)
+{
+ unsigned int warningTimeout = 3000;
+
+ if (surf == NULL)
+ return;
+
+ if (surf->fence_fd >= 0){
+ int err = sync_wait(surf->fence_fd, warningTimeout);
+ if (err < 0)
+ perror("adf sync fence wait error\n");
+
+ close(surf->fence_fd);
+ surf->fence_fd = -1;
+ }
+}
+
static GRSurface* adf_flip(minui_backend *backend)
{
adf_pdata *pdata = (adf_pdata *)backend;
@@ -202,9 +223,10 @@ static GRSurface* adf_flip(minui_backend *backend)
surf->base.width, surf->base.height, pdata->format, surf->fd,
surf->offset, surf->pitch, -1);
if (fence_fd >= 0)
- close(fence_fd);
+ surf->fence_fd = fence_fd;
pdata->current_surface = (pdata->current_surface + 1) % pdata->n_surfaces;
+ adf_sync(&pdata->surfaces[pdata->current_surface]);
return &pdata->surfaces[pdata->current_surface].base;
}
@@ -218,6 +240,7 @@ static void adf_blank(minui_backend *backend, bool blank)
static void adf_surface_destroy(adf_surface_pdata *surf)
{
munmap(surf->base.data, surf->pitch * surf->base.height);
+ close(surf->fence_fd);
close(surf->fd);
}
@@ -226,6 +249,7 @@ static void adf_exit(minui_backend *backend)
adf_pdata *pdata = (adf_pdata *)backend;
unsigned int i;
+ adf_device_close(&pdata->dev);
for (i = 0; i < pdata->n_surfaces; i++)
adf_surface_destroy(&pdata->surfaces[i]);
if (pdata->intf_fd >= 0)
@@ -235,7 +259,7 @@ static void adf_exit(minui_backend *backend)
minui_backend *open_adf()
{
- adf_pdata* pdata = reinterpret_cast<adf_pdata*>(calloc(1, sizeof(*pdata)));
+ adf_pdata* pdata = static_cast<adf_pdata*>(calloc(1, sizeof(*pdata)));
if (!pdata) {
perror("allocating adf backend failed");
return NULL;