summaryrefslogtreecommitdiff
path: root/minui/graphics_drm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'minui/graphics_drm.cpp')
-rw-r--r--minui/graphics_drm.cpp499
1 files changed, 438 insertions, 61 deletions
diff --git a/minui/graphics_drm.cpp b/minui/graphics_drm.cpp
index 95759e38..17ab00af 100644
--- a/minui/graphics_drm.cpp
+++ b/minui/graphics_drm.cpp
@@ -14,8 +14,35 @@
* limitations under the License.
*/
+/*
+ * DRM based mode setting test program
+ * Copyright 2008 Tungsten Graphics
+ * Jakob Bornecrantz <jakob@tungstengraphics.com>
+ * Copyright 2008 Intel Corporation
+ * Jesse Barnes <jesse.barnes@intel.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
#include "graphics_drm.h"
+#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
@@ -29,12 +56,256 @@
#include <android-base/macros.h>
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
+#include <string>
#include <drm_fourcc.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
+#include <sstream>
#include "minui/minui.h"
+#define find_prop_id(_res, type, Type, obj_id, prop_name, prop_id) \
+ do { \
+ int j = 0; \
+ int prop_count = 0; \
+ struct Type *obj = NULL; \
+ obj = (_res); \
+ if (!obj || main_monitor_##type->type##_id != (obj_id)){ \
+ prop_id = 0; \
+ break; \
+ } \
+ prop_count = (int)obj->props->count_props; \
+ for (j = 0; j < prop_count; ++j) \
+ if (!strcmp(obj->props_info[j]->name, (prop_name))) \
+ break; \
+ (prop_id) = (j == prop_count)? \
+ 0 : obj->props_info[j]->prop_id; \
+ } while (0)
+
+#define add_prop(res, type, Type, id, id_name, id_val) \
+ find_prop_id(res, type, Type, id, id_name, prop_id); \
+ if (prop_id) \
+ drmModeAtomicAddProperty(atomic_req, id, prop_id, id_val);
+
+/**
+ * enum sde_rm_topology_name - HW resource use case in use by connector
+ * @SDE_RM_TOPOLOGY_NONE: No topology in use currently
+ * @SDE_RM_TOPOLOGY_SINGLEPIPE: 1 LM, 1 PP, 1 INTF/WB
+ * @SDE_RM_TOPOLOGY_SINGLEPIPE_DSC: 1 LM, 1 DSC, 1 PP, 1 INTF/WB
+ * @SDE_RM_TOPOLOGY_SINGLEPIPE_VDC: 1 LM, 1 VDC, 1 PP, 1 INTF/WB
+ * @SDE_RM_TOPOLOGY_DUALPIPE: 2 LM, 2 PP, 2 INTF/WB
+ * @SDE_RM_TOPOLOGY_DUALPIPE_DSC: 2 LM, 2 DSC, 2 PP, 2 INTF/WB
+ * @SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE: 2 LM, 2 PP, 3DMux, 1 INTF/WB
+ * @SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC: 2 LM, 2 PP, 3DMux, 1 DSC, 1 INTF/WB
+ * @SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_VDC: 2 LM, 2 PP, 3DMux, 1 VDC, 1 INTF/WB
+ * @SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE: 2 LM, 2 PP, 2 DSC Merge, 1 INTF/WB
+ * @SDE_RM_TOPOLOGY_PPSPLIT: 1 LM, 2 PPs, 2 INTF/WB
+ * @SDE_RM_TOPOLOGY_QUADPIPE_3DMERGE 4 LM, 4 PP, 3DMux, 2 INTF
+ * @SDE_RM_TOPOLOGY_QUADPIPE_3DMERGE_DSC 4 LM, 4 PP, 3DMux, 3 DSC, 2 INTF
+ * @SDE_RM_TOPOLOGY_QUADPIPE_DSCMERE 4 LM, 4 PP, 4 DSC Merge, 2 INTF
+ * @SDE_RM_TOPOLOGY_QUADPIPE_DSC4HSMERGE 4 LM, 4 PP, 4 DSC Merge, 1 INTF
+ */
+
+static uint32_t get_lm_number(const std::string &topology) {
+ if (topology == "sde_singlepipe") return 1;
+ if (topology == "sde_singlepipe_dsc") return 1;
+ if (topology == "sde_singlepipe_vdc") return 1;
+ if (topology == "sde_dualpipe") return 2;
+ if (topology == "sde_dualpipe_dsc") return 2;
+ if (topology == "sde_dualpipe_vdc") return 2;
+ if (topology == "sde_dualpipemerge") return 2;
+ if (topology == "sde_dualpipemerge_dsc") return 2;
+ if (topology == "sde_dualpipemerge_vdc") return 2;
+ if (topology == "sde_dualpipe_dscmerge") return 2;
+ if (topology == "sde_ppsplit") return 1;
+ if (topology == "sde_quadpipemerge") return 4;
+ if (topology == "sde_quadpipe_3dmerge_dsc") return 4;
+ if (topology == "sde_quadpipe_dscmerge") return 4;
+ if (topology == "sde_quadpipe_dsc4hsmerge") return 4;
+ return DEFAULT_NUM_LMS;
+}
+
+static uint32_t get_topology_lm_number(int fd, uint32_t blob_id) {
+ uint32_t num_lm = DEFAULT_NUM_LMS;
+
+ drmModePropertyBlobRes *blob = drmModeGetPropertyBlob(fd, blob_id);
+ if (!blob) {
+ return num_lm;
+ }
+
+ const char *fmt_str = (const char *)(blob->data);
+ std::stringstream stream(fmt_str);
+ std::string line = {};
+ const std::string topology = "topology=";
+
+ while (std::getline(stream, line)) {
+ if (line.find(topology) != std::string::npos) {
+ num_lm = get_lm_number(std::string(line, topology.length()));
+ break;
+ }
+ }
+
+ drmModeFreePropertyBlob(blob);
+ return num_lm;
+}
+
+static int find_plane_prop_id(uint32_t obj_id, const char *prop_name,
+ Plane *plane_res) {
+ int i, j = 0;
+ int prop_count = 0;
+ struct Plane *obj = NULL;
+
+ for (i = 0; i < NUM_PLANES; ++i) {
+ obj = &plane_res[i];
+ if (!obj || obj->plane->plane_id != obj_id)
+ continue;
+ prop_count = (int)obj->props->count_props;
+ for (j = 0; j < prop_count; ++j)
+ if (!strcmp(obj->props_info[j]->name, prop_name))
+ return obj->props_info[j]->prop_id;
+ break;
+ }
+
+ return 0;
+}
+
+static int atomic_add_prop_to_plane(Plane *plane_res, drmModeAtomicReq *req,
+ uint32_t obj_id, const char *prop_name,
+ uint64_t value) {
+ uint32_t prop_id;
+
+ prop_id = find_plane_prop_id(obj_id, prop_name, plane_res);
+ if (prop_id == 0) {
+ printf("Could not find obj_id = %d\n", obj_id);
+ return -EINVAL;
+ }
+
+ if (drmModeAtomicAddProperty(req, obj_id, prop_id, value) < 0) {
+ printf("Could not add prop_id = %d for obj_id %d\n",
+ prop_id, obj_id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int MinuiBackendDrm::AtomicPopulatePlane(int plane, drmModeAtomicReqPtr atomic_req) {
+ uint32_t src_x, src_y, src_w, src_h;
+ uint32_t crtc_x, crtc_y, crtc_w, crtc_h;
+ int width = main_monitor_crtc->mode.hdisplay;
+ int height = main_monitor_crtc->mode.vdisplay;
+ int zpos = 0;
+
+ src_y = 0;
+ src_w = width/number_of_lms;
+ src_h = height;
+ crtc_y = 0;
+ crtc_w = width/number_of_lms;
+ crtc_h = height;
+ src_x = (width/number_of_lms) * plane;
+ crtc_x = (width/number_of_lms) * plane;
+
+ /* populate z-order property required for 4 layer mixer */
+ if (number_of_lms == 4)
+ zpos = plane >> 1;
+
+ atomic_add_prop_to_plane(plane_res, atomic_req,
+ plane_res[plane].plane->plane_id, "zpos", zpos);
+
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
+ plane_res[plane].plane->plane_id, "FB_ID",
+ GRSurfaceDrms[current_buffer]->fb_id))
+ return -EINVAL;
+
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
+ plane_res[plane].plane->plane_id, "SRC_X", src_x << 16))
+ return -EINVAL;
+
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
+ plane_res[plane].plane->plane_id, "SRC_Y", src_y << 16))
+ return -EINVAL;
+
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
+ plane_res[plane].plane->plane_id, "SRC_W", src_w << 16))
+ return -EINVAL;
+
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
+ plane_res[plane].plane->plane_id, "SRC_H", src_h << 16))
+ return -EINVAL;
+
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
+ plane_res[plane].plane->plane_id, "CRTC_X", crtc_x))
+ return -EINVAL;
+
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
+ plane_res[plane].plane->plane_id, "CRTC_Y", crtc_y))
+ return -EINVAL;
+
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
+ plane_res[plane].plane->plane_id, "CRTC_W", crtc_w))
+ return -EINVAL;
+
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
+ plane_res[plane].plane->plane_id, "CRTC_H", crtc_h))
+ return -EINVAL;
+
+ if (atomic_add_prop_to_plane(plane_res, atomic_req,
+ plane_res[plane].plane->plane_id, "CRTC_ID",
+ main_monitor_crtc->crtc_id))
+ return -EINVAL;
+
+ return 0;
+}
+
+int MinuiBackendDrm::TeardownPipeline(drmModeAtomicReqPtr atomic_req) {
+ uint32_t i, prop_id;
+ int ret;
+
+ /* During suspend, tear down pipeline */
+ add_prop(&conn_res, connector, Connector, main_monitor_connector->connector_id, "CRTC_ID", 0);
+ add_prop(&crtc_res, crtc, Crtc, main_monitor_crtc->crtc_id, "MODE_ID", 0);
+ add_prop(&crtc_res, crtc, Crtc, main_monitor_crtc->crtc_id, "ACTIVE", 0);
+
+ for(i = 0; i < number_of_lms; i++) {
+ ret = atomic_add_prop_to_plane(plane_res, atomic_req,
+ plane_res[i].plane->plane_id, "CRTC_ID", 0);
+ if (ret < 0) {
+ printf("Failed to tear down plane %d\n", i);
+ return ret;
+ }
+
+ if (drmModeAtomicAddProperty(atomic_req, plane_res[i].plane->plane_id, fb_prop_id, 0) < 0) {
+ printf("Failed to add property for plane_id=%d\n", plane_res[i].plane->plane_id);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+int MinuiBackendDrm::SetupPipeline(drmModeAtomicReqPtr atomic_req) {
+ uint32_t i, prop_id;
+ int ret;
+
+ for(i = 0; i < number_of_lms; i++) {
+ add_prop(&conn_res, connector, Connector, main_monitor_connector->connector_id,
+ "CRTC_ID", main_monitor_crtc->crtc_id);
+ add_prop(&crtc_res, crtc, Crtc, main_monitor_crtc->crtc_id, "MODE_ID", crtc_res.mode_blob_id);
+ add_prop(&crtc_res, crtc, Crtc, main_monitor_crtc->crtc_id, "ACTIVE", 1);
+ }
+
+ /* Setup planes */
+ for(i = 0; i < number_of_lms; i++) {
+ ret = AtomicPopulatePlane(i, atomic_req);
+ if (ret < 0) {
+ printf("Error populating plane_id = %d\n", plane_res[i].plane->plane_id);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
GRSurfaceDrm::~GRSurfaceDrm() {
if (mmapped_buffer_) {
munmap(mmapped_buffer_, row_bytes * height);
@@ -138,35 +409,40 @@ std::unique_ptr<GRSurfaceDrm> GRSurfaceDrm::Create(int drm_fd, int width, int he
return surface;
}
-void MinuiBackendDrm::DrmDisableCrtc(int drm_fd, drmModeCrtc* crtc) {
- if (crtc) {
- drmModeSetCrtc(drm_fd, crtc->crtc_id,
- 0, // fb_id
- 0, 0, // x,y
- nullptr, // connectors
- 0, // connector_count
- nullptr); // mode
- }
+int MinuiBackendDrm::DrmDisableCrtc(drmModeAtomicReqPtr atomic_req) {
+ return TeardownPipeline(atomic_req);
}
-bool MinuiBackendDrm::DrmEnableCrtc(int drm_fd, drmModeCrtc* crtc,
- const std::unique_ptr<GRSurfaceDrm>& surface) {
- if (drmModeSetCrtc(drm_fd, crtc->crtc_id, surface->fb_id, 0, 0, // x,y
- &main_monitor_connector->connector_id,
- 1, // connector_count
- &main_monitor_crtc->mode) != 0) {
- perror("Failed to drmModeSetCrtc");
- return false;
- }
- return true;
+int MinuiBackendDrm::DrmEnableCrtc(drmModeAtomicReqPtr atomic_req){
+ return SetupPipeline(atomic_req);
}
void MinuiBackendDrm::Blank(bool blank) {
- if (blank) {
- DrmDisableCrtc(drm_fd, main_monitor_crtc);
- } else {
- DrmEnableCrtc(drm_fd, main_monitor_crtc, GRSurfaceDrms[current_buffer]);
+ int ret = 0;
+
+ if (blank == current_blank_state)
+ return;
+
+ drmModeAtomicReqPtr atomic_req = drmModeAtomicAlloc();
+ if (!atomic_req) {
+ printf("Atomic Alloc failed\n");
+ return;
+ }
+
+ if (blank)
+ ret = DrmDisableCrtc(atomic_req);
+ else
+ ret = DrmEnableCrtc(atomic_req);
+
+ if (!ret)
+ ret = drmModeAtomicCommit(drm_fd, atomic_req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+ if (!ret) {
+ printf("Atomic Commit failed, rc = %d\n", ret);
+ current_blank_state = blank;
}
+
+ drmModeAtomicFree(atomic_req);
}
static drmModeCrtc* find_crtc_for_connector(int fd, drmModeRes* resources,
@@ -272,20 +548,68 @@ drmModeConnector* MinuiBackendDrm::FindMainMonitor(int fd, drmModeRes* resources
}
void MinuiBackendDrm::DisableNonMainCrtcs(int fd, drmModeRes* resources, drmModeCrtc* main_crtc) {
+ uint32_t prop_id;
+ drmModeAtomicReqPtr atomic_req = drmModeAtomicAlloc();
+
for (int i = 0; i < resources->count_connectors; i++) {
drmModeConnector* connector = drmModeGetConnector(fd, resources->connectors[i]);
drmModeCrtc* crtc = find_crtc_for_connector(fd, resources, connector);
if (crtc->crtc_id != main_crtc->crtc_id) {
- DrmDisableCrtc(fd, crtc);
+ // Switching to atomic commit. Given only crtc, we can only set ACTIVE = 0
+ // to disable any Nonmain CRTCs
+ find_prop_id(&crtc_res, crtc, Crtc, crtc->crtc_id, "ACTIVE", prop_id);
+ if (prop_id == 0)
+ return;
+
+ if (drmModeAtomicAddProperty(atomic_req, main_monitor_crtc->crtc_id, prop_id, 0) < 0)
+ return;
}
drmModeFreeCrtc(crtc);
}
+
+ if (!drmModeAtomicCommit(drm_fd, atomic_req,DRM_MODE_ATOMIC_ALLOW_MODESET, NULL))
+ printf("Atomic Commit failed in DisableNonMainCrtcs\n");
+
+ drmModeAtomicFree(atomic_req);
+}
+
+void MinuiBackendDrm::UpdatePlaneFB() {
+ uint32_t i, prop_id;
+
+ /* Set atomic req */
+ drmModeAtomicReqPtr atomic_req = drmModeAtomicAlloc();
+ if (!atomic_req) {
+ printf("Atomic Alloc failed. Could not update fb_id\n");
+ return;
+ }
+
+ /* Add conn-crtc association property required
+ * for driver to recognize quadpipe topology.
+ */
+ add_prop(&conn_res, connector, Connector, main_monitor_connector->connector_id,
+ "CRTC_ID", main_monitor_crtc->crtc_id);
+
+ /* Add property */
+ for(i = 0; i < number_of_lms; i++)
+ drmModeAtomicAddProperty(atomic_req, plane_res[i].plane->plane_id,
+ fb_prop_id, GRSurfaceDrms[current_buffer]->fb_id);
+
+ /* Commit changes */
+ int32_t ret;
+ ret = drmModeAtomicCommit(drm_fd, atomic_req,
+ DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+ drmModeAtomicFree(atomic_req);
+
+ if (ret)
+ printf("Atomic commit failed ret=%d\n", ret);
}
GRSurface* MinuiBackendDrm::Init() {
drmModeRes* res = nullptr;
drm_fd = -1;
+ number_of_lms = DEFAULT_NUM_LMS;
/* Consider DRM devices in order. */
for (int i = 0; i < DRM_MAX_MINOR; i++) {
auto dev_name = android::base::StringPrintf(DRM_DEV_NAME, DRM_DIR_NAME, i);
@@ -353,58 +677,111 @@ GRSurface* MinuiBackendDrm::Init() {
current_buffer = 0;
- // We will likely encounter errors in the backend functions (i.e. Flip) if EnableCrtc fails.
- if (!DrmEnableCrtc(drm_fd, main_monitor_crtc, GRSurfaceDrms[1])) {
- return nullptr;
+ drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
+ drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1);
+
+ /* Get possible plane_ids */
+ drmModePlaneRes *plane_options = drmModeGetPlaneResources(drm_fd);
+ if (!plane_options || !plane_options->planes || (plane_options->count_planes < number_of_lms))
+ return NULL;
+
+ /* Set crtc resources */
+ crtc_res.props = drmModeObjectGetProperties(drm_fd,
+ main_monitor_crtc->crtc_id,
+ DRM_MODE_OBJECT_CRTC);
+ if (!crtc_res.props)
+ return NULL;
+
+ crtc_res.props_info = static_cast<drmModePropertyRes **>
+ (calloc(crtc_res.props->count_props,
+ sizeof(crtc_res.props_info)));
+ if (!crtc_res.props_info)
+ return NULL;
+ else
+ for (int j = 0; j < (int)crtc_res.props->count_props; ++j)
+ crtc_res.props_info[j] = drmModeGetProperty(drm_fd,
+ crtc_res.props->props[j]);
+
+ /* Set connector resources */
+ conn_res.props = drmModeObjectGetProperties(drm_fd,
+ main_monitor_connector->connector_id,
+ DRM_MODE_OBJECT_CONNECTOR);
+ if (!conn_res.props)
+ return NULL;
+
+ conn_res.props_info = static_cast<drmModePropertyRes **>
+ (calloc(conn_res.props->count_props,
+ sizeof(conn_res.props_info)));
+ if (!conn_res.props_info)
+ return NULL;
+ else {
+ for (int j = 0; j < (int)conn_res.props->count_props; ++j) {
+
+ conn_res.props_info[j] = drmModeGetProperty(drm_fd,
+ conn_res.props->props[j]);
+
+ /* Get preferred mode information and extract the
+ * number of layer mixers needed from the topology name.
+ */
+ if (!strcmp(conn_res.props_info[j]->name, "mode_properties")) {
+ number_of_lms = get_topology_lm_number(drm_fd, conn_res.props->prop_values[j]);
+ printf("number of lms in topology %d\n", number_of_lms);
+ }
+ }
}
- return GRSurfaceDrms[0].get();
-}
+ /* Set plane resources */
+ for(uint32_t i = 0; i < number_of_lms; ++i) {
+ plane_res[i].plane = drmModeGetPlane(drm_fd, plane_options->planes[i]);
+ if (!plane_res[i].plane)
+ return NULL;
+ }
-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;
-}
+ for (uint32_t i = 0; i < number_of_lms; ++i) {
+ struct Plane *obj = &plane_res[i];
+ unsigned int j;
+ obj->props = drmModeObjectGetProperties(drm_fd, obj->plane->plane_id,
+ DRM_MODE_OBJECT_PLANE);
+ if (!obj->props)
+ continue;
+ obj->props_info = static_cast<drmModePropertyRes **>
+ (calloc(obj->props->count_props, sizeof(*obj->props_info)));
+ if (!obj->props_info)
+ continue;
+ for (j = 0; j < obj->props->count_props; ++j)
+ obj->props_info[j] = drmModeGetProperty(drm_fd, obj->props->props[j]);
+ }
-GRSurface* MinuiBackendDrm::Flip() {
- bool ongoing_flip = true;
- if (drmModePageFlip(drm_fd, main_monitor_crtc->crtc_id, GRSurfaceDrms[current_buffer]->fb_id,
- DRM_MODE_PAGE_FLIP_EVENT, &ongoing_flip) != 0) {
- perror("Failed to drmModePageFlip");
- return nullptr;
+ drmModeFreePlaneResources(plane_options);
+ plane_options = NULL;
+
+ /* Setup pipe and blob_id */
+ if (drmModeCreatePropertyBlob(drm_fd, &main_monitor_crtc->mode, sizeof(drmModeModeInfo),
+ &crtc_res.mode_blob_id)) {
+ printf("failed to create mode blob\n");
+ return NULL;
}
- while (ongoing_flip) {
- struct pollfd fds = {
- .fd = drm_fd,
- .events = POLLIN
- };
+ /* Save fb_prop_id*/
+ uint32_t prop_id;
+ prop_id = find_plane_prop_id(plane_res[0].plane->plane_id, "FB_ID", plane_res);
+ fb_prop_id = prop_id;
- if (poll(&fds, 1, -1) == -1 || !(fds.revents & POLLIN)) {
- perror("Failed to poll() on drm fd");
- break;
- }
+ Blank(false);
- drmEventContext evctx = {
- .version = DRM_EVENT_CONTEXT_VERSION,
- .page_flip_handler = page_flip_complete
- };
+ return GRSurfaceDrms[0].get();
+}
- if (drmHandleEvent(drm_fd, &evctx) != 0) {
- perror("Failed to drmHandleEvent");
- break;
- }
- }
+GRSurface* MinuiBackendDrm::Flip() {
+ UpdatePlaneFB();
current_buffer = 1 - current_buffer;
return GRSurfaceDrms[current_buffer].get();
}
MinuiBackendDrm::~MinuiBackendDrm() {
- DrmDisableCrtc(drm_fd, main_monitor_crtc);
+ Blank(true);
+ drmModeDestroyPropertyBlob(drm_fd, crtc_res.mode_blob_id);
drmModeFreeCrtc(main_monitor_crtc);
drmModeFreeConnector(main_monitor_connector);
close(drm_fd);