Loading minui/graphics.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -450,6 +450,10 @@ void gr_fb_blank(bool blank) { gr_backend->Blank(blank); } void gr_fb_blank(bool blank, int index) { gr_backend->Blank(blank, static_cast<MinuiBackend::DrmConnector>(index)); } void gr_rotate(GRRotation rot) { rotation = rot; } minui/graphics.h +10 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,12 @@ class MinuiBackend { public: enum DrmConnector { DRM_MAIN = 0, DRM_SEC, DRM_MAX, }; // Initializes the backend and returns a GRSurface* to draw into. virtual GRSurface* Init() = 0; Loading @@ -28,9 +34,12 @@ class MinuiBackend { // be displayed, and returns a new drawing surface. virtual GRSurface* Flip() = 0; // Blank (or unblank) the screen. // Blank (or unblank) the default screen. virtual void Blank(bool) = 0; // Blank (or unblank) the specific screen. virtual void Blank(bool blank, DrmConnector index) = 0; // Device cleanup when drawing is done. virtual ~MinuiBackend() {}; }; Loading minui/graphics_drm.cpp +120 −69 Original line number Diff line number Diff line Loading @@ -153,22 +153,50 @@ void MinuiBackendDrm::DrmDisableCrtc(int drm_fd, drmModeCrtc* crtc) { } bool MinuiBackendDrm::DrmEnableCrtc(int drm_fd, drmModeCrtc* crtc, const std::unique_ptr<GRSurfaceDrm>& surface) { const std::unique_ptr<GRSurfaceDrm>& surface, uint32_t* connector_id) { 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"); connector_id, 1, // connector_count &crtc->mode) != 0) { fprintf(stderr, "Failed to drmModeSetCrtc(%d)\n", *connector_id); return false; } return true; } void MinuiBackendDrm::Blank(bool blank) { Blank(blank, DRM_MAIN); } void MinuiBackendDrm::Blank(bool blank, DrmConnector index) { const auto* drmInterface = &drm[DRM_MAIN]; switch (index) { case DRM_MAIN: drmInterface = &drm[DRM_MAIN]; break; case DRM_SEC: drmInterface = &drm[DRM_SEC]; break; default: fprintf(stderr, "Invalid index: %d\n", index); return; } if (!drmInterface->monitor_connector) { fprintf(stderr, "Unsupported. index = %d\n", index); return; } if (blank) { DrmDisableCrtc(drm_fd, main_monitor_crtc); DrmDisableCrtc(drm_fd, drmInterface->monitor_crtc); } else { DrmEnableCrtc(drm_fd, main_monitor_crtc, GRSurfaceDrms[current_buffer]); DrmEnableCrtc(drm_fd, drmInterface->monitor_crtc, drmInterface->GRSurfaceDrms[drmInterface->current_buffer], &drmInterface->monitor_connector->connector_id); active_display = index; } } Loading Loading @@ -210,18 +238,21 @@ static drmModeCrtc* find_crtc_for_connector(int fd, drmModeRes* resources, return nullptr; } static drmModeConnector* find_used_connector_by_type(int fd, drmModeRes* resources, unsigned type) { std::vector<drmModeConnector*> find_used_connector_by_type(int fd, drmModeRes* resources, unsigned type) { std::vector<drmModeConnector*> drmConnectors; for (int i = 0; i < resources->count_connectors; i++) { drmModeConnector* connector = drmModeGetConnector(fd, resources->connectors[i]); if (connector) { if ((connector->connector_type == type) && (connector->connection == DRM_MODE_CONNECTED) && (connector->count_modes > 0)) { return connector; } drmConnectors.push_back(connector); } else { drmModeFreeConnector(connector); } } return nullptr; } return drmConnectors; } static drmModeConnector* find_first_connected_connector(int fd, drmModeRes* resources) { Loading @@ -239,8 +270,7 @@ static drmModeConnector* find_first_connected_connector(int fd, drmModeRes* reso return nullptr; } drmModeConnector* MinuiBackendDrm::FindMainMonitor(int fd, drmModeRes* resources, uint32_t* mode_index) { bool MinuiBackendDrm::FindAndSetMonitor(int fd, drmModeRes* resources) { /* Look for LVDS/eDP/DSI connectors. Those are the main screens. */ static constexpr unsigned kConnectorPriority[] = { DRM_MODE_CONNECTOR_LVDS, Loading @@ -248,37 +278,41 @@ drmModeConnector* MinuiBackendDrm::FindMainMonitor(int fd, drmModeRes* resources DRM_MODE_CONNECTOR_DSI, }; drmModeConnector* main_monitor_connector = nullptr; unsigned i = 0; do { main_monitor_connector = find_used_connector_by_type(fd, resources, kConnectorPriority[i]); i++; } while (!main_monitor_connector && i < arraysize(kConnectorPriority)); std::vector<drmModeConnector*> drmConnectors; for (int i = 0; i < arraysize(kConnectorPriority) && drmConnectors.size() < DRM_MAX; i++) { auto connectors = find_used_connector_by_type(fd, resources, kConnectorPriority[i]); for (auto connector : connectors) { drmConnectors.push_back(connector); if (drmConnectors.size() >= DRM_MAX) break; } } /* If we didn't find a connector, grab the first one that is connected. */ if (!main_monitor_connector) { main_monitor_connector = find_first_connected_connector(fd, resources); if (drmConnectors.empty()) { drmModeConnector* connector = find_first_connected_connector(fd, resources); if (connector) { drmConnectors.push_back(connector); } } /* If we still didn't find a connector, give up and return. */ if (!main_monitor_connector) return nullptr; for (int drm_index = 0; drm_index < drmConnectors.size(); drm_index++) { drm[drm_index].monitor_connector = drmConnectors[drm_index]; for (int modes = 0; modes < main_monitor_connector->count_modes; modes++) { drm[drm_index].selected_mode = 0; for (int modes = 0; modes < drmConnectors[drm_index]->count_modes; modes++) { printf("Display Mode %d resolution: %d x %d @ %d FPS\n", modes, main_monitor_connector->modes[modes].hdisplay, main_monitor_connector->modes[modes].vdisplay, main_monitor_connector->modes[modes].vrefresh); } *mode_index = 0; for (int modes = 0; modes < main_monitor_connector->count_modes; modes++) { if (main_monitor_connector->modes[modes].type & DRM_MODE_TYPE_PREFERRED) { drmConnectors[drm_index]->modes[modes].hdisplay, drmConnectors[drm_index]->modes[modes].vdisplay, drmConnectors[drm_index]->modes[modes].vrefresh); if (drmConnectors[drm_index]->modes[modes].type & DRM_MODE_TYPE_PREFERRED) { printf("Choosing display mode #%d\n", modes); *mode_index = modes; drm[drm_index].selected_mode = modes; break; } } } return main_monitor_connector; return drmConnectors.size() > 0; } void MinuiBackendDrm::DisableNonMainCrtcs(int fd, drmModeRes* resources, drmModeCrtc* main_crtc) { Loading Loading @@ -329,46 +363,49 @@ GRSurface* MinuiBackendDrm::Init() { return nullptr; } uint32_t selected_mode; main_monitor_connector = FindMainMonitor(drm_fd, res, &selected_mode); if (!main_monitor_connector) { fprintf(stderr, "Failed to find main_monitor_connector\n"); if (!FindAndSetMonitor(drm_fd, res)) { fprintf(stderr, "Failed to find main monitor_connector\n"); drmModeFreeResources(res); close(drm_fd); return nullptr; } main_monitor_crtc = find_crtc_for_connector(drm_fd, res, main_monitor_connector); if (!main_monitor_crtc) { fprintf(stderr, "Failed to find main_monitor_crtc\n"); for (int i = 0; i < DRM_MAX; i++) { if (drm[i].monitor_connector) { drm[i].monitor_crtc = find_crtc_for_connector(drm_fd, res, drm[i].monitor_connector); if (!drm[i].monitor_crtc) { fprintf(stderr, "Failed to find monitor_crtc, drm index=%d\n", i); drmModeFreeResources(res); close(drm_fd); return nullptr; } DisableNonMainCrtcs(drm_fd, res, main_monitor_crtc); drm[i].monitor_crtc->mode = drm[i].monitor_connector->modes[drm[i].selected_mode]; main_monitor_crtc->mode = main_monitor_connector->modes[selected_mode]; int width = main_monitor_crtc->mode.hdisplay; int height = main_monitor_crtc->mode.vdisplay; int width = drm[i].monitor_crtc->mode.hdisplay; int height = drm[i].monitor_crtc->mode.vdisplay; drm[i].GRSurfaceDrms[0] = GRSurfaceDrm::Create(drm_fd, width, height); drm[i].GRSurfaceDrms[1] = GRSurfaceDrm::Create(drm_fd, width, height); if (!drm[i].GRSurfaceDrms[0] || !drm[i].GRSurfaceDrms[1]) { fprintf(stderr, "Failed to create GRSurfaceDrm, drm index=%d\n", i); drmModeFreeResources(res); GRSurfaceDrms[0] = GRSurfaceDrm::Create(drm_fd, width, height); GRSurfaceDrms[1] = GRSurfaceDrm::Create(drm_fd, width, height); if (!GRSurfaceDrms[0] || !GRSurfaceDrms[1]) { return nullptr; } current_buffer = 0; drm[i].current_buffer = 0; } } DisableNonMainCrtcs(drm_fd, res, drm[DRM_MAIN].monitor_crtc); drmModeFreeResources(res); // We will likely encounter errors in the backend functions (i.e. Flip) if EnableCrtc fails. if (!DrmEnableCrtc(drm_fd, main_monitor_crtc, GRSurfaceDrms[1])) { if (!DrmEnableCrtc(drm_fd, drm[DRM_MAIN].monitor_crtc, drm[DRM_MAIN].GRSurfaceDrms[1], &drm[DRM_MAIN].monitor_connector->connector_id)) { return nullptr; } return GRSurfaceDrms[0].get(); return drm[DRM_MAIN].GRSurfaceDrms[0].get(); } static void page_flip_complete(__unused int fd, Loading @@ -380,10 +417,19 @@ static void page_flip_complete(__unused int fd, } GRSurface* MinuiBackendDrm::Flip() { GRSurface* surface = NULL; DrmInterface* current_drm = &drm[active_display]; bool ongoing_flip = true; if (drmModePageFlip(drm_fd, main_monitor_crtc->crtc_id, GRSurfaceDrms[current_buffer]->fb_id, if (!current_drm->monitor_connector) { fprintf(stderr, "Unsupported. active_display = %d\n", active_display); return nullptr; } if (drmModePageFlip(drm_fd, current_drm->monitor_crtc->crtc_id, current_drm->GRSurfaceDrms[current_drm->current_buffer]->fb_id, DRM_MODE_PAGE_FLIP_EVENT, &ongoing_flip) != 0) { perror("Failed to drmModePageFlip"); fprintf(stderr, "Failed to drmModePageFlip, active_display=%d", active_display); return nullptr; } Loading @@ -409,14 +455,19 @@ GRSurface* MinuiBackendDrm::Flip() { } } current_buffer = 1 - current_buffer; return GRSurfaceDrms[current_buffer].get(); current_drm->current_buffer = 1 - current_drm->current_buffer; surface = current_drm->GRSurfaceDrms[current_drm->current_buffer].get(); return surface; } MinuiBackendDrm::~MinuiBackendDrm() { DrmDisableCrtc(drm_fd, main_monitor_crtc); drmModeFreeCrtc(main_monitor_crtc); drmModeFreeConnector(main_monitor_connector); for (int i = 0; i < DRM_MAX; i++) { if (drm[i].monitor_connector) { DrmDisableCrtc(drm_fd, drm[i].monitor_crtc); drmModeFreeCrtc(drm[i].monitor_crtc); drmModeFreeConnector(drm[i].monitor_connector); } } close(drm_fd); drm_fd = -1; } minui/graphics_drm.h +13 −6 Original line number Diff line number Diff line Loading @@ -59,16 +59,23 @@ class MinuiBackendDrm : public MinuiBackend { GRSurface* Init() override; GRSurface* Flip() override; void Blank(bool) override; void Blank(bool blank, DrmConnector index) override; private: void DrmDisableCrtc(int drm_fd, drmModeCrtc* crtc); bool DrmEnableCrtc(int drm_fd, drmModeCrtc* crtc, const std::unique_ptr<GRSurfaceDrm>& surface); bool DrmEnableCrtc(int drm_fd, drmModeCrtc* crtc, const std::unique_ptr<GRSurfaceDrm>& surface, uint32_t* conntcors); void DisableNonMainCrtcs(int fd, drmModeRes* resources, drmModeCrtc* main_crtc); drmModeConnector* FindMainMonitor(int fd, drmModeRes* resources, uint32_t* mode_index); bool FindAndSetMonitor(int fd, drmModeRes* resources); struct DrmInterface { std::unique_ptr<GRSurfaceDrm> GRSurfaceDrms[2]; int current_buffer{ 0 }; drmModeCrtc* main_monitor_crtc{ nullptr }; drmModeConnector* main_monitor_connector{ nullptr }; drmModeCrtc* monitor_crtc{ nullptr }; drmModeConnector* monitor_connector{ nullptr }; uint32_t selected_mode{ 0 }; } drm[DRM_MAX]; int drm_fd{ -1 }; DrmConnector active_display = DRM_MAIN; }; minui/graphics_fbdev.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,10 @@ void MinuiBackendFbdev::Blank(bool blank) { if (ret < 0) perror("ioctl(): blank"); } void MinuiBackendFbdev::Blank(bool blank, DrmConnector index) { fprintf(stderr, "Unsupported multiple connectors, blank = %d, index = %d\n", blank, index); } void MinuiBackendFbdev::SetDisplayedFramebuffer(size_t n) { if (n > 1 || !double_buffered) return; Loading Loading
minui/graphics.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -450,6 +450,10 @@ void gr_fb_blank(bool blank) { gr_backend->Blank(blank); } void gr_fb_blank(bool blank, int index) { gr_backend->Blank(blank, static_cast<MinuiBackend::DrmConnector>(index)); } void gr_rotate(GRRotation rot) { rotation = rot; }
minui/graphics.h +10 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,12 @@ class MinuiBackend { public: enum DrmConnector { DRM_MAIN = 0, DRM_SEC, DRM_MAX, }; // Initializes the backend and returns a GRSurface* to draw into. virtual GRSurface* Init() = 0; Loading @@ -28,9 +34,12 @@ class MinuiBackend { // be displayed, and returns a new drawing surface. virtual GRSurface* Flip() = 0; // Blank (or unblank) the screen. // Blank (or unblank) the default screen. virtual void Blank(bool) = 0; // Blank (or unblank) the specific screen. virtual void Blank(bool blank, DrmConnector index) = 0; // Device cleanup when drawing is done. virtual ~MinuiBackend() {}; }; Loading
minui/graphics_drm.cpp +120 −69 Original line number Diff line number Diff line Loading @@ -153,22 +153,50 @@ void MinuiBackendDrm::DrmDisableCrtc(int drm_fd, drmModeCrtc* crtc) { } bool MinuiBackendDrm::DrmEnableCrtc(int drm_fd, drmModeCrtc* crtc, const std::unique_ptr<GRSurfaceDrm>& surface) { const std::unique_ptr<GRSurfaceDrm>& surface, uint32_t* connector_id) { 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"); connector_id, 1, // connector_count &crtc->mode) != 0) { fprintf(stderr, "Failed to drmModeSetCrtc(%d)\n", *connector_id); return false; } return true; } void MinuiBackendDrm::Blank(bool blank) { Blank(blank, DRM_MAIN); } void MinuiBackendDrm::Blank(bool blank, DrmConnector index) { const auto* drmInterface = &drm[DRM_MAIN]; switch (index) { case DRM_MAIN: drmInterface = &drm[DRM_MAIN]; break; case DRM_SEC: drmInterface = &drm[DRM_SEC]; break; default: fprintf(stderr, "Invalid index: %d\n", index); return; } if (!drmInterface->monitor_connector) { fprintf(stderr, "Unsupported. index = %d\n", index); return; } if (blank) { DrmDisableCrtc(drm_fd, main_monitor_crtc); DrmDisableCrtc(drm_fd, drmInterface->monitor_crtc); } else { DrmEnableCrtc(drm_fd, main_monitor_crtc, GRSurfaceDrms[current_buffer]); DrmEnableCrtc(drm_fd, drmInterface->monitor_crtc, drmInterface->GRSurfaceDrms[drmInterface->current_buffer], &drmInterface->monitor_connector->connector_id); active_display = index; } } Loading Loading @@ -210,18 +238,21 @@ static drmModeCrtc* find_crtc_for_connector(int fd, drmModeRes* resources, return nullptr; } static drmModeConnector* find_used_connector_by_type(int fd, drmModeRes* resources, unsigned type) { std::vector<drmModeConnector*> find_used_connector_by_type(int fd, drmModeRes* resources, unsigned type) { std::vector<drmModeConnector*> drmConnectors; for (int i = 0; i < resources->count_connectors; i++) { drmModeConnector* connector = drmModeGetConnector(fd, resources->connectors[i]); if (connector) { if ((connector->connector_type == type) && (connector->connection == DRM_MODE_CONNECTED) && (connector->count_modes > 0)) { return connector; } drmConnectors.push_back(connector); } else { drmModeFreeConnector(connector); } } return nullptr; } return drmConnectors; } static drmModeConnector* find_first_connected_connector(int fd, drmModeRes* resources) { Loading @@ -239,8 +270,7 @@ static drmModeConnector* find_first_connected_connector(int fd, drmModeRes* reso return nullptr; } drmModeConnector* MinuiBackendDrm::FindMainMonitor(int fd, drmModeRes* resources, uint32_t* mode_index) { bool MinuiBackendDrm::FindAndSetMonitor(int fd, drmModeRes* resources) { /* Look for LVDS/eDP/DSI connectors. Those are the main screens. */ static constexpr unsigned kConnectorPriority[] = { DRM_MODE_CONNECTOR_LVDS, Loading @@ -248,37 +278,41 @@ drmModeConnector* MinuiBackendDrm::FindMainMonitor(int fd, drmModeRes* resources DRM_MODE_CONNECTOR_DSI, }; drmModeConnector* main_monitor_connector = nullptr; unsigned i = 0; do { main_monitor_connector = find_used_connector_by_type(fd, resources, kConnectorPriority[i]); i++; } while (!main_monitor_connector && i < arraysize(kConnectorPriority)); std::vector<drmModeConnector*> drmConnectors; for (int i = 0; i < arraysize(kConnectorPriority) && drmConnectors.size() < DRM_MAX; i++) { auto connectors = find_used_connector_by_type(fd, resources, kConnectorPriority[i]); for (auto connector : connectors) { drmConnectors.push_back(connector); if (drmConnectors.size() >= DRM_MAX) break; } } /* If we didn't find a connector, grab the first one that is connected. */ if (!main_monitor_connector) { main_monitor_connector = find_first_connected_connector(fd, resources); if (drmConnectors.empty()) { drmModeConnector* connector = find_first_connected_connector(fd, resources); if (connector) { drmConnectors.push_back(connector); } } /* If we still didn't find a connector, give up and return. */ if (!main_monitor_connector) return nullptr; for (int drm_index = 0; drm_index < drmConnectors.size(); drm_index++) { drm[drm_index].monitor_connector = drmConnectors[drm_index]; for (int modes = 0; modes < main_monitor_connector->count_modes; modes++) { drm[drm_index].selected_mode = 0; for (int modes = 0; modes < drmConnectors[drm_index]->count_modes; modes++) { printf("Display Mode %d resolution: %d x %d @ %d FPS\n", modes, main_monitor_connector->modes[modes].hdisplay, main_monitor_connector->modes[modes].vdisplay, main_monitor_connector->modes[modes].vrefresh); } *mode_index = 0; for (int modes = 0; modes < main_monitor_connector->count_modes; modes++) { if (main_monitor_connector->modes[modes].type & DRM_MODE_TYPE_PREFERRED) { drmConnectors[drm_index]->modes[modes].hdisplay, drmConnectors[drm_index]->modes[modes].vdisplay, drmConnectors[drm_index]->modes[modes].vrefresh); if (drmConnectors[drm_index]->modes[modes].type & DRM_MODE_TYPE_PREFERRED) { printf("Choosing display mode #%d\n", modes); *mode_index = modes; drm[drm_index].selected_mode = modes; break; } } } return main_monitor_connector; return drmConnectors.size() > 0; } void MinuiBackendDrm::DisableNonMainCrtcs(int fd, drmModeRes* resources, drmModeCrtc* main_crtc) { Loading Loading @@ -329,46 +363,49 @@ GRSurface* MinuiBackendDrm::Init() { return nullptr; } uint32_t selected_mode; main_monitor_connector = FindMainMonitor(drm_fd, res, &selected_mode); if (!main_monitor_connector) { fprintf(stderr, "Failed to find main_monitor_connector\n"); if (!FindAndSetMonitor(drm_fd, res)) { fprintf(stderr, "Failed to find main monitor_connector\n"); drmModeFreeResources(res); close(drm_fd); return nullptr; } main_monitor_crtc = find_crtc_for_connector(drm_fd, res, main_monitor_connector); if (!main_monitor_crtc) { fprintf(stderr, "Failed to find main_monitor_crtc\n"); for (int i = 0; i < DRM_MAX; i++) { if (drm[i].monitor_connector) { drm[i].monitor_crtc = find_crtc_for_connector(drm_fd, res, drm[i].monitor_connector); if (!drm[i].monitor_crtc) { fprintf(stderr, "Failed to find monitor_crtc, drm index=%d\n", i); drmModeFreeResources(res); close(drm_fd); return nullptr; } DisableNonMainCrtcs(drm_fd, res, main_monitor_crtc); drm[i].monitor_crtc->mode = drm[i].monitor_connector->modes[drm[i].selected_mode]; main_monitor_crtc->mode = main_monitor_connector->modes[selected_mode]; int width = main_monitor_crtc->mode.hdisplay; int height = main_monitor_crtc->mode.vdisplay; int width = drm[i].monitor_crtc->mode.hdisplay; int height = drm[i].monitor_crtc->mode.vdisplay; drm[i].GRSurfaceDrms[0] = GRSurfaceDrm::Create(drm_fd, width, height); drm[i].GRSurfaceDrms[1] = GRSurfaceDrm::Create(drm_fd, width, height); if (!drm[i].GRSurfaceDrms[0] || !drm[i].GRSurfaceDrms[1]) { fprintf(stderr, "Failed to create GRSurfaceDrm, drm index=%d\n", i); drmModeFreeResources(res); GRSurfaceDrms[0] = GRSurfaceDrm::Create(drm_fd, width, height); GRSurfaceDrms[1] = GRSurfaceDrm::Create(drm_fd, width, height); if (!GRSurfaceDrms[0] || !GRSurfaceDrms[1]) { return nullptr; } current_buffer = 0; drm[i].current_buffer = 0; } } DisableNonMainCrtcs(drm_fd, res, drm[DRM_MAIN].monitor_crtc); drmModeFreeResources(res); // We will likely encounter errors in the backend functions (i.e. Flip) if EnableCrtc fails. if (!DrmEnableCrtc(drm_fd, main_monitor_crtc, GRSurfaceDrms[1])) { if (!DrmEnableCrtc(drm_fd, drm[DRM_MAIN].monitor_crtc, drm[DRM_MAIN].GRSurfaceDrms[1], &drm[DRM_MAIN].monitor_connector->connector_id)) { return nullptr; } return GRSurfaceDrms[0].get(); return drm[DRM_MAIN].GRSurfaceDrms[0].get(); } static void page_flip_complete(__unused int fd, Loading @@ -380,10 +417,19 @@ static void page_flip_complete(__unused int fd, } GRSurface* MinuiBackendDrm::Flip() { GRSurface* surface = NULL; DrmInterface* current_drm = &drm[active_display]; bool ongoing_flip = true; if (drmModePageFlip(drm_fd, main_monitor_crtc->crtc_id, GRSurfaceDrms[current_buffer]->fb_id, if (!current_drm->monitor_connector) { fprintf(stderr, "Unsupported. active_display = %d\n", active_display); return nullptr; } if (drmModePageFlip(drm_fd, current_drm->monitor_crtc->crtc_id, current_drm->GRSurfaceDrms[current_drm->current_buffer]->fb_id, DRM_MODE_PAGE_FLIP_EVENT, &ongoing_flip) != 0) { perror("Failed to drmModePageFlip"); fprintf(stderr, "Failed to drmModePageFlip, active_display=%d", active_display); return nullptr; } Loading @@ -409,14 +455,19 @@ GRSurface* MinuiBackendDrm::Flip() { } } current_buffer = 1 - current_buffer; return GRSurfaceDrms[current_buffer].get(); current_drm->current_buffer = 1 - current_drm->current_buffer; surface = current_drm->GRSurfaceDrms[current_drm->current_buffer].get(); return surface; } MinuiBackendDrm::~MinuiBackendDrm() { DrmDisableCrtc(drm_fd, main_monitor_crtc); drmModeFreeCrtc(main_monitor_crtc); drmModeFreeConnector(main_monitor_connector); for (int i = 0; i < DRM_MAX; i++) { if (drm[i].monitor_connector) { DrmDisableCrtc(drm_fd, drm[i].monitor_crtc); drmModeFreeCrtc(drm[i].monitor_crtc); drmModeFreeConnector(drm[i].monitor_connector); } } close(drm_fd); drm_fd = -1; }
minui/graphics_drm.h +13 −6 Original line number Diff line number Diff line Loading @@ -59,16 +59,23 @@ class MinuiBackendDrm : public MinuiBackend { GRSurface* Init() override; GRSurface* Flip() override; void Blank(bool) override; void Blank(bool blank, DrmConnector index) override; private: void DrmDisableCrtc(int drm_fd, drmModeCrtc* crtc); bool DrmEnableCrtc(int drm_fd, drmModeCrtc* crtc, const std::unique_ptr<GRSurfaceDrm>& surface); bool DrmEnableCrtc(int drm_fd, drmModeCrtc* crtc, const std::unique_ptr<GRSurfaceDrm>& surface, uint32_t* conntcors); void DisableNonMainCrtcs(int fd, drmModeRes* resources, drmModeCrtc* main_crtc); drmModeConnector* FindMainMonitor(int fd, drmModeRes* resources, uint32_t* mode_index); bool FindAndSetMonitor(int fd, drmModeRes* resources); struct DrmInterface { std::unique_ptr<GRSurfaceDrm> GRSurfaceDrms[2]; int current_buffer{ 0 }; drmModeCrtc* main_monitor_crtc{ nullptr }; drmModeConnector* main_monitor_connector{ nullptr }; drmModeCrtc* monitor_crtc{ nullptr }; drmModeConnector* monitor_connector{ nullptr }; uint32_t selected_mode{ 0 }; } drm[DRM_MAX]; int drm_fd{ -1 }; DrmConnector active_display = DRM_MAIN; };
minui/graphics_fbdev.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,10 @@ void MinuiBackendFbdev::Blank(bool blank) { if (ret < 0) perror("ioctl(): blank"); } void MinuiBackendFbdev::Blank(bool blank, DrmConnector index) { fprintf(stderr, "Unsupported multiple connectors, blank = %d, index = %d\n", blank, index); } void MinuiBackendFbdev::SetDisplayedFramebuffer(size_t n) { if (n > 1 || !double_buffered) return; Loading