mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-03-16 04:23:42 +00:00
v4p: dpms
This commit is contained in:
@@ -46,10 +46,12 @@
|
|||||||
|
|
||||||
static void _drm_vsync_callback(int fd, uint n_frame, uint sec, uint usec, void *v_buf);
|
static void _drm_vsync_callback(int fd, uint n_frame, uint sec, uint usec, void *v_buf);
|
||||||
static int _drm_check_status(us_drm_s *drm);
|
static int _drm_check_status(us_drm_s *drm);
|
||||||
|
static void _drm_ensure_dpms_power(us_drm_s *drm, bool on);
|
||||||
static int _drm_init_buffers(us_drm_s *drm, const us_device_s *dev);
|
static int _drm_init_buffers(us_drm_s *drm, const us_device_s *dev);
|
||||||
static int _drm_find_sink(us_drm_s *drm, uint width, uint height, float hz);
|
static int _drm_find_sink(us_drm_s *drm, uint width, uint height, float hz);
|
||||||
|
|
||||||
static drmModeModeInfo *_find_best_mode(drmModeConnector *conn, uint width, uint height, float hz);
|
static drmModeModeInfo *_find_best_mode(drmModeConnector *conn, uint width, uint height, float hz);
|
||||||
|
static u32 _find_dpms(int fd, drmModeConnector *conn);
|
||||||
static u32 _find_crtc(int fd, drmModeRes *res, drmModeConnector *conn, u32 *taken_crtcs);
|
static u32 _find_crtc(int fd, drmModeRes *res, drmModeConnector *conn, u32 *taken_crtcs);
|
||||||
static const char *_connector_type_to_string(u32 type);
|
static const char *_connector_type_to_string(u32 type);
|
||||||
static float _get_refresh_rate(const drmModeModeInfo *mode);
|
static float _get_refresh_rate(const drmModeModeInfo *mode);
|
||||||
@@ -68,6 +70,7 @@ us_drm_s *us_drm_init(void) {
|
|||||||
run->fd = -1;
|
run->fd = -1;
|
||||||
run->status_fd = -1;
|
run->status_fd = -1;
|
||||||
run->has_vsync = true;
|
run->has_vsync = true;
|
||||||
|
run->dpms_state = -1;
|
||||||
run->ft = us_frametext_init();
|
run->ft = us_frametext_init();
|
||||||
|
|
||||||
us_drm_s *drm;
|
us_drm_s *drm;
|
||||||
@@ -219,6 +222,7 @@ void us_drm_close(us_drm_s *drm) {
|
|||||||
|
|
||||||
run->crtc_id = 0;
|
run->crtc_id = 0;
|
||||||
run->has_vsync = true;
|
run->has_vsync = true;
|
||||||
|
run->dpms_state = -1;
|
||||||
run->stub_n_buf = 0;
|
run->stub_n_buf = 0;
|
||||||
|
|
||||||
if (say) {
|
if (say) {
|
||||||
@@ -226,6 +230,17 @@ void us_drm_close(us_drm_s *drm) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int us_drm_dpms_power_off(us_drm_s *drm) {
|
||||||
|
assert(drm->run->fd >= 0);
|
||||||
|
switch (_drm_check_status(drm)) {
|
||||||
|
case 0: break;
|
||||||
|
case -2: return -2;
|
||||||
|
default: return -1;
|
||||||
|
}
|
||||||
|
_drm_ensure_dpms_power(drm, false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int us_drm_wait_for_vsync(us_drm_s *drm) {
|
int us_drm_wait_for_vsync(us_drm_s *drm) {
|
||||||
us_drm_runtime_s *const run = drm->run;
|
us_drm_runtime_s *const run = drm->run;
|
||||||
|
|
||||||
@@ -236,6 +251,7 @@ int us_drm_wait_for_vsync(us_drm_s *drm) {
|
|||||||
case -2: return -2;
|
case -2: return -2;
|
||||||
default: return -1;
|
default: return -1;
|
||||||
}
|
}
|
||||||
|
_drm_ensure_dpms_power(drm, true);
|
||||||
|
|
||||||
if (run->has_vsync) {
|
if (run->has_vsync) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -289,6 +305,7 @@ int us_drm_expose_stub(us_drm_s *drm, us_drm_stub_e stub, const us_device_s *dev
|
|||||||
case -2: return -2;
|
case -2: return -2;
|
||||||
default: return -1;
|
default: return -1;
|
||||||
}
|
}
|
||||||
|
_drm_ensure_dpms_power(drm, true);
|
||||||
|
|
||||||
# define DRAW_MSG(x_msg) us_frametext_draw(run->ft, (x_msg), run->mode.hdisplay, run->mode.vdisplay)
|
# define DRAW_MSG(x_msg) us_frametext_draw(run->ft, (x_msg), run->mode.hdisplay, run->mode.vdisplay)
|
||||||
switch (stub) {
|
switch (stub) {
|
||||||
@@ -357,6 +374,7 @@ int us_drm_expose_dma(us_drm_s *drm, const us_hw_buffer_s *hw) {
|
|||||||
case -2: return -2;
|
case -2: return -2;
|
||||||
default: return -1;
|
default: return -1;
|
||||||
}
|
}
|
||||||
|
_drm_ensure_dpms_power(drm, true);
|
||||||
|
|
||||||
run->has_vsync = false;
|
run->has_vsync = false;
|
||||||
|
|
||||||
@@ -412,6 +430,20 @@ error:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _drm_ensure_dpms_power(us_drm_s *drm, bool on) {
|
||||||
|
us_drm_runtime_s *const run = drm->run;
|
||||||
|
if (run->dpms_id > 0 && run->dpms_state != (int)on) {
|
||||||
|
_D_LOG_INFO("Changing DPMS power mode: %d -> %u ...", run->dpms_state, on);
|
||||||
|
if (drmModeConnectorSetProperty(
|
||||||
|
run->fd, run->conn_id, run->dpms_id,
|
||||||
|
(on ? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF)
|
||||||
|
) < 0) {
|
||||||
|
_D_LOG_PERROR("Can't set DPMS power=%u (ignored)", on);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run->dpms_state = (int)on;
|
||||||
|
}
|
||||||
|
|
||||||
static int _drm_init_buffers(us_drm_s *drm, const us_device_s *dev) {
|
static int _drm_init_buffers(us_drm_s *drm, const us_device_s *dev) {
|
||||||
us_drm_runtime_s *const run = drm->run;
|
us_drm_runtime_s *const run = drm->run;
|
||||||
|
|
||||||
@@ -517,7 +549,7 @@ static int _drm_find_sink(us_drm_s *drm, uint width, uint height, float hz) {
|
|||||||
drmModeFreeConnector(conn);
|
drmModeFreeConnector(conn);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
_D_LOG_DEBUG("Found connector for port %s: conn_type=%d, conn_type_id=%d",
|
_D_LOG_INFO("Using connector %s: conn_type=%d, conn_type_id=%d",
|
||||||
drm->port, conn->connector_type, conn->connector_type_id);
|
drm->port, conn->connector_type, conn->connector_type_id);
|
||||||
|
|
||||||
if (conn->connection != DRM_MODE_CONNECTED) {
|
if (conn->connection != DRM_MODE_CONNECTED) {
|
||||||
@@ -532,18 +564,23 @@ static int _drm_find_sink(us_drm_s *drm, uint width, uint height, float hz) {
|
|||||||
drmModeFreeConnector(conn);
|
drmModeFreeConnector(conn);
|
||||||
goto unplugged;
|
goto unplugged;
|
||||||
}
|
}
|
||||||
assert(best->hdisplay > 0);
|
_D_LOG_INFO("Using best mode: %ux%up%.02f",
|
||||||
assert(best->vdisplay > 0);
|
|
||||||
|
|
||||||
_D_LOG_INFO("The best display mode is: %ux%up%.02f",
|
|
||||||
best->hdisplay, best->vdisplay, _get_refresh_rate(best));
|
best->hdisplay, best->vdisplay, _get_refresh_rate(best));
|
||||||
|
|
||||||
|
if ((run->dpms_id = _find_dpms(run->fd, conn)) > 0) {
|
||||||
|
_D_LOG_INFO("Using DPMS: id=%u", run->dpms_id);
|
||||||
|
} else {
|
||||||
|
_D_LOG_INFO("Using DPMS: None");
|
||||||
|
}
|
||||||
|
|
||||||
u32 taken_crtcs = 0; // Unused here
|
u32 taken_crtcs = 0; // Unused here
|
||||||
if ((run->crtc_id = _find_crtc(run->fd, res, conn, &taken_crtcs)) == 0) {
|
if ((run->crtc_id = _find_crtc(run->fd, res, conn, &taken_crtcs)) == 0) {
|
||||||
_D_LOG_ERROR("Can't find CRTC");
|
_D_LOG_ERROR("Can't find CRTC");
|
||||||
drmModeFreeConnector(conn);
|
drmModeFreeConnector(conn);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
_D_LOG_INFO("Using CRTC: id=%u", run->crtc_id);
|
||||||
|
|
||||||
run->conn_id = conn->connector_id;
|
run->conn_id = conn->connector_id;
|
||||||
memcpy(&run->mode, best, sizeof(drmModeModeInfo));
|
memcpy(&run->mode, best, sizeof(drmModeModeInfo));
|
||||||
|
|
||||||
@@ -596,9 +633,26 @@ static drmModeModeInfo *_find_best_mode(drmModeConnector *conn, uint width, uint
|
|||||||
if (best == NULL) {
|
if (best == NULL) {
|
||||||
best = (conn->count_modes > 0 ? &conn->modes[0] : NULL);
|
best = (conn->count_modes > 0 ? &conn->modes[0] : NULL);
|
||||||
}
|
}
|
||||||
|
assert(best == NULL || best->hdisplay > 0);
|
||||||
|
assert(best == NULL || best->vdisplay > 0);
|
||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 _find_dpms(int fd, drmModeConnector *conn) {
|
||||||
|
for (int pi = 0; pi < conn->count_props; pi++) {
|
||||||
|
drmModePropertyPtr prop = drmModeGetProperty(fd, conn->props[pi]);
|
||||||
|
if (prop != NULL) {
|
||||||
|
if (!strcmp(prop->name, "DPMS")) {
|
||||||
|
const u32 id = prop->prop_id;
|
||||||
|
drmModeFreeProperty(prop);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
drmModeFreeProperty(prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static u32 _find_crtc(int fd, drmModeRes *res, drmModeConnector *conn, u32 *taken_crtcs) {
|
static u32 _find_crtc(int fd, drmModeRes *res, drmModeConnector *conn, u32 *taken_crtcs) {
|
||||||
for (int ei = 0; ei < conn->count_encoders; ++ei) {
|
for (int ei = 0; ei < conn->count_encoders; ++ei) {
|
||||||
drmModeEncoder *enc = drmModeGetEncoder(fd, conn->encoders[ei]);
|
drmModeEncoder *enc = drmModeGetEncoder(fd, conn->encoders[ei]);
|
||||||
|
|||||||
@@ -56,13 +56,15 @@ typedef struct {
|
|||||||
int fd;
|
int fd;
|
||||||
u32 crtc_id;
|
u32 crtc_id;
|
||||||
u32 conn_id;
|
u32 conn_id;
|
||||||
|
u32 dpms_id;
|
||||||
drmModeModeInfo mode;
|
drmModeModeInfo mode;
|
||||||
us_drm_buffer_s *bufs;
|
us_drm_buffer_s *bufs;
|
||||||
uint n_bufs;
|
uint n_bufs;
|
||||||
drmModeCrtc *saved_crtc;
|
drmModeCrtc *saved_crtc;
|
||||||
|
int dpms_state;
|
||||||
bool has_vsync;
|
bool has_vsync;
|
||||||
bool stub;
|
|
||||||
uint stub_n_buf;
|
uint stub_n_buf;
|
||||||
|
bool stub;
|
||||||
us_frametext_s *ft;
|
us_frametext_s *ft;
|
||||||
bool unplugged_reported;
|
bool unplugged_reported;
|
||||||
} us_drm_runtime_s;
|
} us_drm_runtime_s;
|
||||||
@@ -82,6 +84,7 @@ void us_drm_destroy(us_drm_s *drm);
|
|||||||
int us_drm_open(us_drm_s *drm, const us_device_s *dev);
|
int us_drm_open(us_drm_s *drm, const us_device_s *dev);
|
||||||
void us_drm_close(us_drm_s *drm);
|
void us_drm_close(us_drm_s *drm);
|
||||||
|
|
||||||
|
int us_drm_dpms_power_off(us_drm_s *drm);
|
||||||
|
int us_drm_wait_for_vsync(us_drm_s *drm);
|
||||||
int us_drm_expose_stub(us_drm_s *drm, us_drm_stub_e stub, const us_device_s *dev);
|
int us_drm_expose_stub(us_drm_s *drm, us_drm_stub_e stub, const us_device_s *dev);
|
||||||
int us_drm_expose_dma(us_drm_s *drm, const us_hw_buffer_s *hw);
|
int us_drm_expose_dma(us_drm_s *drm, const us_hw_buffer_s *hw);
|
||||||
int us_drm_wait_for_vsync(us_drm_s *drm);
|
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ static void _main_loop(void) {
|
|||||||
assert(drm_opened > 0);
|
assert(drm_opened > 0);
|
||||||
|
|
||||||
if (atomic_load(&_g_ustreamer_online)) {
|
if (atomic_load(&_g_ustreamer_online)) {
|
||||||
US_ONCE({ US_LOG_ERROR("DRM: Online stream is active"); });
|
US_ONCE({ US_LOG_ERROR("DRM: Online stream is active, stopping capture ..."); });
|
||||||
if (us_drm_wait_for_vsync(drm) < 0) {
|
if (us_drm_wait_for_vsync(drm) < 0) {
|
||||||
goto close;
|
goto close;
|
||||||
}
|
}
|
||||||
@@ -194,11 +194,14 @@ static void _main_loop(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (us_device_open(dev) < 0) {
|
if (us_device_open(dev) < 0) {
|
||||||
if (us_drm_wait_for_vsync(drm) < 0) {
|
/*if (us_drm_wait_for_vsync(drm) < 0) {
|
||||||
goto close;
|
goto close;
|
||||||
}
|
}
|
||||||
if (us_drm_expose_stub(drm, US_DRM_STUB_NO_SIGNAL, NULL) < 0) {
|
if (us_drm_expose_stub(drm, US_DRM_STUB_NO_SIGNAL, NULL) < 0) {
|
||||||
goto close;
|
goto close;
|
||||||
|
}*/
|
||||||
|
if (us_drm_dpms_power_off(drm) < 0) {
|
||||||
|
goto close;
|
||||||
}
|
}
|
||||||
_slowdown();
|
_slowdown();
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user