minuitwrp graphics: derived commits for DRM graphics

minui: add ARGB_8888 format

Minui currently really only supports composing in 2 different formats
(see gr_color()) with ALPHA always as MSB. However, some devices
interpret PixelFormat as either Big Endian (i.e. ARGB has alpha at MSB)
or Little Endian (i.e. BGRA has alpha at MSB).

This change attempts to give multiple options to specify the same format
depending on device interpretation, while keeping just 2 different
composition formats supported by minui.
* ARGB + BGRA: Pixels have (A)lpha at MSB and (B)lue at LSB
* RGBX + ABGR: Pixels have (A)lpha at MSB and (R)ed at LSB

With this in mind, limiting the use of png_set_bgr() to happen only for
(ARGB/BGRA) combination while leaving (RGBX/ABGR) unchanged.

Bug: 143480444
Test: Boot device with TARGET_RECOVERY_PIXEL_FORMAT := <<all>>
Change-Id: Ia0f94ccbc564b8def7c9416483712ff1abbbf49a

minui: Cleanup GRSurfaceDrm and MinuiBackendDrm.

This CL adds a dtor to GRSurfaceDrm that handles the resource
deallocation. It also manages MinuiBackendDrm::GRSurfaceDrms with smart
pointers.

Test: Build and boot into recovery on blueline. `Run graphics test`.
Change-Id: Iff7bbdddbc0b5ab16483d00870794fca9f832bd5
diff --git a/minuitwrp/graphics_drm.cpp b/minuitwrp/graphics_drm.cpp
index 2b94dda..a02613f 100644
--- a/minuitwrp/graphics_drm.cpp
+++ b/minuitwrp/graphics_drm.cpp
@@ -16,6 +16,7 @@
 
 #include <drm_fourcc.h>
 #include <fcntl.h>
+#include <poll.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -117,6 +118,7 @@
         case DRM_FORMAT_ABGR8888:
         case DRM_FORMAT_BGRA8888:
         case DRM_FORMAT_RGBX8888:
+        case DRM_FORMAT_RGBA8888:
         case DRM_FORMAT_BGRX8888:
         case DRM_FORMAT_XBGR8888:
         case DRM_FORMAT_ARGB8888:
@@ -480,18 +482,48 @@
     return draw_buf;
 }
 
+static void page_flip_complete(__unused int fd,
+                               __unused unsigned int sequence,
+                               __unused unsigned int tv_sec,
+                               __unused unsigned int tv_usec,
+                               void *user_data) {
+  *static_cast<bool*>(user_data) = false;
+}
+
 static GRSurface* drm_flip(minui_backend* backend __unused) {
-    int ret;
+    bool ongoing_flip = true;
     memcpy(drm_surfaces[current_buffer]->base.data,
             draw_buf->data, draw_buf->height * draw_buf->row_bytes);
 
 
-    ret = drmModePageFlip(drm_fd, main_monitor_crtc->crtc_id,
-                          drm_surfaces[current_buffer]->fb_id, 0, NULL);
-    if (ret < 0) {
-        printf("drmModePageFlip failed ret=%d\n", ret);
-        return NULL;
+    if (drmModePageFlip(drm_fd, main_monitor_crtc->crtc_id,
+                          drm_surfaces[current_buffer]->fb_id, DRM_MODE_PAGE_FLIP_EVENT, &ongoing_flip)) {
+        printf("Failed to drmModePageFlip");
+        return nullptr;
     }
+
+    while (ongoing_flip) {
+        struct pollfd fds = {
+            .fd = drm_fd,
+            .events = POLLIN
+        };
+
+        if (poll(&fds, 1, -1) == -1 || !(fds.revents & POLLIN)) {
+            perror("Failed to poll() on drm fd");
+            break;
+        }
+
+        drmEventContext evctx = {
+            .version = DRM_EVENT_CONTEXT_VERSION,
+            .page_flip_handler = page_flip_complete
+        };
+
+        if (drmHandleEvent(drm_fd, &evctx) != 0) {
+            perror("Failed to drmHandleEvent");
+            break;
+        }
+    }
+
     current_buffer = 1 - current_buffer;
     return draw_buf;
 }